blob: 11a8c2e636aab349423be1706c84096ddc67e46c [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
Igor Murashkin6918bf12015-09-27 19:19:06 -070017#include "base/stl_util.h" // MakeUnique
Alex Lighteb7c1442015-08-31 13:17:42 -070018#include "experimental_flags.h"
Sebastien Hertz8ece0502013-08-07 11:26:41 +020019#include "interpreter_common.h"
Ian Rogersf72a11d2014-10-30 15:41:08 -070020#include "safe_math.h"
Sebastien Hertz8ece0502013-08-07 11:26:41 +020021
Igor Murashkin6918bf12015-09-27 19:19:06 -070022#include <memory> // std::unique_ptr
23
Sebastien Hertz8ece0502013-08-07 11:26:41 +020024namespace art {
25namespace interpreter {
26
27#define HANDLE_PENDING_EXCEPTION() \
28 do { \
Sebastien Hertz82aeddb2014-05-20 20:09:45 +020029 DCHECK(self->IsExceptionPending()); \
Ian Rogers7b078e82014-09-10 14:44:24 -070030 self->AllowThreadSuspension(); \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020031 uint32_t found_dex_pc = FindNextInstructionFollowingException(self, shadow_frame, \
32 inst->GetDexPc(insns), \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020033 instrumentation); \
34 if (found_dex_pc == DexFile::kDexNoIndex) { \
Andreas Gampe03ec9302015-08-27 17:41:47 -070035 /* Structured locking is to be enforced for abnormal termination, too. */ \
36 shadow_frame.GetLockCountData(). \
37 CheckAllMonitorsReleasedOrThrow<do_assignability_check>(self); \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020038 return JValue(); /* Handled in caller. */ \
39 } else { \
40 int32_t displacement = static_cast<int32_t>(found_dex_pc) - static_cast<int32_t>(dex_pc); \
41 inst = inst->RelativeAt(displacement); \
42 } \
43 } while (false)
44
45#define POSSIBLY_HANDLE_PENDING_EXCEPTION(_is_exception_pending, _next_function) \
46 do { \
47 if (UNLIKELY(_is_exception_pending)) { \
48 HANDLE_PENDING_EXCEPTION(); \
49 } else { \
50 inst = inst->_next_function(); \
51 } \
52 } while (false)
53
Andreas Gampe03ec9302015-08-27 17:41:47 -070054#define HANDLE_MONITOR_CHECKS() \
55 if (!shadow_frame.GetLockCountData(). \
56 CheckAllMonitorsReleasedOrThrow<do_assignability_check>(self)) { \
57 HANDLE_PENDING_EXCEPTION(); \
58 }
59
Sebastien Hertz8ece0502013-08-07 11:26:41 +020060// Code to run before each dex instruction.
Sebastien Hertz8379b222014-02-24 17:38:15 +010061#define PREAMBLE() \
62 do { \
Sebastien Hertz9d6bf692015-04-10 12:12:33 +020063 if (UNLIKELY(instrumentation->HasDexPcListeners())) { \
Sebastien Hertz8379b222014-02-24 17:38:15 +010064 instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_), \
65 shadow_frame.GetMethod(), dex_pc); \
66 } \
67 } while (false)
Sebastien Hertz8ece0502013-08-07 11:26:41 +020068
Igor Murashkin158f35c2015-06-10 15:55:30 -070069static bool IsExperimentalInstructionEnabled(const Instruction *inst) {
70 DCHECK(inst->IsExperimental());
Alex Lighteb7c1442015-08-31 13:17:42 -070071 return Runtime::Current()->AreExperimentalFlagsEnabled(ExperimentalFlags::kLambdas);
Igor Murashkin158f35c2015-06-10 15:55:30 -070072}
73
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010074template<bool do_access_check, bool transaction_active>
Ian Rogerse94652f2014-12-02 11:13:19 -080075JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertz8379b222014-02-24 17:38:15 +010076 ShadowFrame& shadow_frame, JValue result_register) {
Igor Murashkinc449e8b2015-06-10 15:56:42 -070077 constexpr bool do_assignability_check = do_access_check;
Sebastien Hertz8ece0502013-08-07 11:26:41 +020078 if (UNLIKELY(!shadow_frame.HasReferenceArray())) {
79 LOG(FATAL) << "Invalid shadow frame for interpreter use";
80 return JValue();
81 }
82 self->VerifyStack();
Sebastien Hertz8ece0502013-08-07 11:26:41 +020083
84 uint32_t dex_pc = shadow_frame.GetDexPC();
Mathieu Chartier2cebb242015-04-21 16:50:40 -070085 const auto* const instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz270a0e12015-01-16 19:49:09 +010086 if (LIKELY(dex_pc == 0)) { // We are entering the method as opposed to deoptimizing.
87 if (kIsDebugBuild) {
88 self->AssertNoPendingException();
89 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +020090 if (UNLIKELY(instrumentation->HasMethodEntryListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +020091 instrumentation->MethodEnterEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +020092 shadow_frame.GetMethod(), 0);
93 }
94 }
95 const uint16_t* const insns = code_item->insns_;
96 const Instruction* inst = Instruction::At(insns + dex_pc);
Sebastien Hertz3b588e02013-09-11 14:33:18 +020097 uint16_t inst_data;
Igor Murashkin6918bf12015-09-27 19:19:06 -070098
99 // TODO: collapse capture-variable+create-lambda into one opcode, then we won't need
100 // to keep this live for the scope of the entire function call.
101 std::unique_ptr<lambda::ClosureBuilder> lambda_closure_builder;
102 size_t lambda_captured_variable_index = 0;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200103 while (true) {
104 dex_pc = inst->GetDexPc(insns);
Igor Murashkin457e8742015-10-22 17:37:50 -0700105 DCHECK_LE(dex_pc, code_item->insns_size_in_code_units_)
106 << "Dex PC overflowed code item size; missing return instruction?";
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200107 shadow_frame.SetDexPC(dex_pc);
Ian Rogerse94652f2014-12-02 11:13:19 -0800108 TraceExecution(shadow_frame, inst, dex_pc);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200109 inst_data = inst->Fetch16(0);
110 switch (inst->Opcode(inst_data)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200111 case Instruction::NOP:
112 PREAMBLE();
113 inst = inst->Next_1xx();
114 break;
115 case Instruction::MOVE:
116 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200117 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
118 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200119 inst = inst->Next_1xx();
120 break;
121 case Instruction::MOVE_FROM16:
122 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200123 shadow_frame.SetVReg(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200124 shadow_frame.GetVReg(inst->VRegB_22x()));
125 inst = inst->Next_2xx();
126 break;
127 case Instruction::MOVE_16:
128 PREAMBLE();
129 shadow_frame.SetVReg(inst->VRegA_32x(),
130 shadow_frame.GetVReg(inst->VRegB_32x()));
131 inst = inst->Next_3xx();
132 break;
133 case Instruction::MOVE_WIDE:
134 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200135 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
136 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200137 inst = inst->Next_1xx();
138 break;
139 case Instruction::MOVE_WIDE_FROM16:
140 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200141 shadow_frame.SetVRegLong(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200142 shadow_frame.GetVRegLong(inst->VRegB_22x()));
143 inst = inst->Next_2xx();
144 break;
145 case Instruction::MOVE_WIDE_16:
146 PREAMBLE();
147 shadow_frame.SetVRegLong(inst->VRegA_32x(),
148 shadow_frame.GetVRegLong(inst->VRegB_32x()));
149 inst = inst->Next_3xx();
150 break;
151 case Instruction::MOVE_OBJECT:
152 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200153 shadow_frame.SetVRegReference(inst->VRegA_12x(inst_data),
154 shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200155 inst = inst->Next_1xx();
156 break;
157 case Instruction::MOVE_OBJECT_FROM16:
158 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200159 shadow_frame.SetVRegReference(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200160 shadow_frame.GetVRegReference(inst->VRegB_22x()));
161 inst = inst->Next_2xx();
162 break;
163 case Instruction::MOVE_OBJECT_16:
164 PREAMBLE();
165 shadow_frame.SetVRegReference(inst->VRegA_32x(),
166 shadow_frame.GetVRegReference(inst->VRegB_32x()));
167 inst = inst->Next_3xx();
168 break;
169 case Instruction::MOVE_RESULT:
170 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200171 shadow_frame.SetVReg(inst->VRegA_11x(inst_data), result_register.GetI());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200172 inst = inst->Next_1xx();
173 break;
174 case Instruction::MOVE_RESULT_WIDE:
175 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200176 shadow_frame.SetVRegLong(inst->VRegA_11x(inst_data), result_register.GetJ());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200177 inst = inst->Next_1xx();
178 break;
179 case Instruction::MOVE_RESULT_OBJECT:
180 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200181 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), result_register.GetL());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200182 inst = inst->Next_1xx();
183 break;
184 case Instruction::MOVE_EXCEPTION: {
185 PREAMBLE();
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000186 Throwable* exception = self->GetException();
Sebastien Hertz270a0e12015-01-16 19:49:09 +0100187 DCHECK(exception != nullptr) << "No pending exception on MOVE_EXCEPTION instruction";
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200188 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), exception);
Sebastien Hertz5c004902014-05-21 10:07:42 +0200189 self->ClearException();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200190 inst = inst->Next_1xx();
191 break;
192 }
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700193 case Instruction::RETURN_VOID_NO_BARRIER: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200194 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200195 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700196 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700197 HANDLE_MONITOR_CHECKS();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200198 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200199 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200200 shadow_frame.GetMethod(), inst->GetDexPc(insns),
201 result);
202 }
203 return result;
204 }
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700205 case Instruction::RETURN_VOID: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200206 PREAMBLE();
Hans Boehm30359612014-05-21 17:46:23 -0700207 QuasiAtomic::ThreadFenceForConstructor();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200208 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700209 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700210 HANDLE_MONITOR_CHECKS();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200211 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200212 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200213 shadow_frame.GetMethod(), inst->GetDexPc(insns),
214 result);
215 }
216 return result;
217 }
218 case Instruction::RETURN: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200219 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200220 JValue result;
221 result.SetJ(0);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200222 result.SetI(shadow_frame.GetVReg(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700223 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700224 HANDLE_MONITOR_CHECKS();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200225 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200226 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200227 shadow_frame.GetMethod(), inst->GetDexPc(insns),
228 result);
229 }
230 return result;
231 }
232 case Instruction::RETURN_WIDE: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200233 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200234 JValue result;
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200235 result.SetJ(shadow_frame.GetVRegLong(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700236 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700237 HANDLE_MONITOR_CHECKS();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200238 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200239 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200240 shadow_frame.GetMethod(), inst->GetDexPc(insns),
241 result);
242 }
243 return result;
244 }
245 case Instruction::RETURN_OBJECT: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200246 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200247 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700248 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700249 HANDLE_MONITOR_CHECKS();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700250 const size_t ref_idx = inst->VRegA_11x(inst_data);
251 Object* obj_result = shadow_frame.GetVRegReference(ref_idx);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700252 if (do_assignability_check && obj_result != nullptr) {
Vladimir Marko05792b92015-08-03 11:56:49 +0100253 size_t pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
254 Class* return_type = shadow_frame.GetMethod()->GetReturnType(true /* resolve */,
255 pointer_size);
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700256 // Re-load since it might have moved.
257 obj_result = shadow_frame.GetVRegReference(ref_idx);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700258 if (return_type == nullptr) {
Jeff Haoa3faaf42013-09-03 19:07:00 -0700259 // Return the pending exception.
260 HANDLE_PENDING_EXCEPTION();
261 }
262 if (!obj_result->VerifierInstanceOf(return_type)) {
263 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700264 std::string temp1, temp2;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000265 self->ThrowNewExceptionF("Ljava/lang/VirtualMachineError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700266 "Returning '%s' that is not instance of return type '%s'",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700267 obj_result->GetClass()->GetDescriptor(&temp1),
268 return_type->GetDescriptor(&temp2));
Jeff Haoa3faaf42013-09-03 19:07:00 -0700269 HANDLE_PENDING_EXCEPTION();
270 }
271 }
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700272 result.SetL(obj_result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200273 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200274 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200275 shadow_frame.GetMethod(), inst->GetDexPc(insns),
276 result);
277 }
278 return result;
279 }
280 case Instruction::CONST_4: {
281 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200282 uint4_t dst = inst->VRegA_11n(inst_data);
283 int4_t val = inst->VRegB_11n(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200284 shadow_frame.SetVReg(dst, val);
285 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700286 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200287 }
288 inst = inst->Next_1xx();
289 break;
290 }
291 case Instruction::CONST_16: {
292 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200293 uint8_t dst = inst->VRegA_21s(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200294 int16_t val = inst->VRegB_21s();
295 shadow_frame.SetVReg(dst, val);
296 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700297 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200298 }
299 inst = inst->Next_2xx();
300 break;
301 }
302 case Instruction::CONST: {
303 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200304 uint8_t dst = inst->VRegA_31i(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200305 int32_t val = inst->VRegB_31i();
306 shadow_frame.SetVReg(dst, val);
307 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700308 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200309 }
310 inst = inst->Next_3xx();
311 break;
312 }
313 case Instruction::CONST_HIGH16: {
314 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200315 uint8_t dst = inst->VRegA_21h(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200316 int32_t val = static_cast<int32_t>(inst->VRegB_21h() << 16);
317 shadow_frame.SetVReg(dst, val);
318 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700319 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200320 }
321 inst = inst->Next_2xx();
322 break;
323 }
324 case Instruction::CONST_WIDE_16:
325 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200326 shadow_frame.SetVRegLong(inst->VRegA_21s(inst_data), inst->VRegB_21s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200327 inst = inst->Next_2xx();
328 break;
329 case Instruction::CONST_WIDE_32:
330 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200331 shadow_frame.SetVRegLong(inst->VRegA_31i(inst_data), inst->VRegB_31i());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200332 inst = inst->Next_3xx();
333 break;
334 case Instruction::CONST_WIDE:
335 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200336 shadow_frame.SetVRegLong(inst->VRegA_51l(inst_data), inst->VRegB_51l());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200337 inst = inst->Next_51l();
338 break;
339 case Instruction::CONST_WIDE_HIGH16:
Sebastien Hertz3c5aec12014-06-04 09:41:21 +0200340 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200341 shadow_frame.SetVRegLong(inst->VRegA_21h(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200342 static_cast<uint64_t>(inst->VRegB_21h()) << 48);
343 inst = inst->Next_2xx();
344 break;
345 case Instruction::CONST_STRING: {
346 PREAMBLE();
Ian Rogers6786a582014-10-28 12:49:06 -0700347 String* s = ResolveString(self, shadow_frame, inst->VRegB_21c());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700348 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200349 HANDLE_PENDING_EXCEPTION();
350 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200351 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200352 inst = inst->Next_2xx();
353 }
354 break;
355 }
356 case Instruction::CONST_STRING_JUMBO: {
357 PREAMBLE();
Ian Rogers6786a582014-10-28 12:49:06 -0700358 String* s = ResolveString(self, shadow_frame, inst->VRegB_31c());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700359 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200360 HANDLE_PENDING_EXCEPTION();
361 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200362 shadow_frame.SetVRegReference(inst->VRegA_31c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200363 inst = inst->Next_3xx();
364 }
365 break;
366 }
367 case Instruction::CONST_CLASS: {
368 PREAMBLE();
369 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
370 self, false, do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700371 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200372 HANDLE_PENDING_EXCEPTION();
373 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200374 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), c);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200375 inst = inst->Next_2xx();
376 }
377 break;
378 }
379 case Instruction::MONITOR_ENTER: {
380 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200381 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700382 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000383 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200384 HANDLE_PENDING_EXCEPTION();
385 } else {
Andreas Gampe03ec9302015-08-27 17:41:47 -0700386 DoMonitorEnter<do_assignability_check>(self, &shadow_frame, obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200387 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
388 }
389 break;
390 }
391 case Instruction::MONITOR_EXIT: {
392 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200393 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700394 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000395 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200396 HANDLE_PENDING_EXCEPTION();
397 } else {
Andreas Gampe03ec9302015-08-27 17:41:47 -0700398 DoMonitorExit<do_assignability_check>(self, &shadow_frame, obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200399 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
400 }
401 break;
402 }
403 case Instruction::CHECK_CAST: {
404 PREAMBLE();
405 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
406 self, false, do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700407 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200408 HANDLE_PENDING_EXCEPTION();
409 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200410 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_21c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700411 if (UNLIKELY(obj != nullptr && !obj->InstanceOf(c))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200412 ThrowClassCastException(c, obj->GetClass());
413 HANDLE_PENDING_EXCEPTION();
414 } else {
415 inst = inst->Next_2xx();
416 }
417 }
418 break;
419 }
420 case Instruction::INSTANCE_OF: {
421 PREAMBLE();
422 Class* c = ResolveVerifyAndClinit(inst->VRegC_22c(), shadow_frame.GetMethod(),
423 self, false, do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700424 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200425 HANDLE_PENDING_EXCEPTION();
426 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200427 Object* obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700428 shadow_frame.SetVReg(inst->VRegA_22c(inst_data),
429 (obj != nullptr && obj->InstanceOf(c)) ? 1 : 0);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200430 inst = inst->Next_2xx();
431 }
432 break;
433 }
434 case Instruction::ARRAY_LENGTH: {
435 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200436 Object* array = shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700437 if (UNLIKELY(array == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000438 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200439 HANDLE_PENDING_EXCEPTION();
440 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200441 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), array->AsArray()->GetLength());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200442 inst = inst->Next_1xx();
443 }
444 break;
445 }
446 case Instruction::NEW_INSTANCE: {
447 PREAMBLE();
Jeff Hao848f70a2014-01-15 13:49:50 -0800448 Object* obj = nullptr;
449 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
450 self, false, do_access_check);
451 if (LIKELY(c != nullptr)) {
452 if (UNLIKELY(c->IsStringClass())) {
453 gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
454 mirror::SetStringCountVisitor visitor(0);
455 obj = String::Alloc<true>(self, 0, allocator_type, visitor);
456 } else {
457 obj = AllocObjectFromCode<do_access_check, true>(
458 inst->VRegB_21c(), shadow_frame.GetMethod(), self,
459 Runtime::Current()->GetHeap()->GetCurrentAllocator());
460 }
461 }
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700462 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200463 HANDLE_PENDING_EXCEPTION();
464 } else {
Sebastien Hertz4e99b3d2014-06-24 14:35:40 +0200465 obj->GetClass()->AssertInitializedOrInitializingInThread(self);
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700466 // Don't allow finalizable objects to be allocated during a transaction since these can't
467 // be finalized without a started runtime.
468 if (transaction_active && obj->GetClass()->IsFinalizable()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +0200469 AbortTransactionF(self, "Allocating finalizable object in transaction: %s",
470 PrettyTypeOf(obj).c_str());
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700471 HANDLE_PENDING_EXCEPTION();
472 break;
473 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200474 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200475 inst = inst->Next_2xx();
476 }
477 break;
478 }
479 case Instruction::NEW_ARRAY: {
480 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200481 int32_t length = shadow_frame.GetVReg(inst->VRegB_22c(inst_data));
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800482 Object* obj = AllocArrayFromCode<do_access_check, true>(
Andreas Gampe1cc7dba2014-12-17 18:43:01 -0800483 inst->VRegC_22c(), length, shadow_frame.GetMethod(), self,
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800484 Runtime::Current()->GetHeap()->GetCurrentAllocator());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700485 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200486 HANDLE_PENDING_EXCEPTION();
487 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200488 shadow_frame.SetVRegReference(inst->VRegA_22c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200489 inst = inst->Next_2xx();
490 }
491 break;
492 }
493 case Instruction::FILLED_NEW_ARRAY: {
494 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100495 bool success =
496 DoFilledNewArray<false, do_access_check, transaction_active>(inst, shadow_frame, self,
497 &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200498 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
499 break;
500 }
501 case Instruction::FILLED_NEW_ARRAY_RANGE: {
502 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100503 bool success =
504 DoFilledNewArray<true, do_access_check, transaction_active>(inst, shadow_frame,
505 self, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200506 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
507 break;
508 }
509 case Instruction::FILL_ARRAY_DATA: {
510 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200511 const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t();
512 const Instruction::ArrayDataPayload* payload =
513 reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr);
Ian Rogers832336b2014-10-08 15:35:22 -0700514 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_31t(inst_data));
515 bool success = FillArrayData(obj, payload);
516 if (!success) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200517 HANDLE_PENDING_EXCEPTION();
518 break;
519 }
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100520 if (transaction_active) {
Ian Rogers832336b2014-10-08 15:35:22 -0700521 RecordArrayElementsInTransaction(obj->AsArray(), payload->element_count);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100522 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200523 inst = inst->Next_3xx();
524 break;
525 }
526 case Instruction::THROW: {
527 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200528 Object* exception = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700529 if (UNLIKELY(exception == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000530 ThrowNullPointerException("throw with null exception");
Jeff Haoa3faaf42013-09-03 19:07:00 -0700531 } else if (do_assignability_check && !exception->GetClass()->IsThrowableClass()) {
532 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700533 std::string temp;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000534 self->ThrowNewExceptionF("Ljava/lang/VirtualMachineError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700535 "Throwing '%s' that is not instance of Throwable",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700536 exception->GetClass()->GetDescriptor(&temp));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200537 } else {
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000538 self->SetException(exception->AsThrowable());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200539 }
540 HANDLE_PENDING_EXCEPTION();
541 break;
542 }
543 case Instruction::GOTO: {
544 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200545 int8_t offset = inst->VRegA_10t(inst_data);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200546 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700547 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200548 }
549 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200550 break;
551 }
552 case Instruction::GOTO_16: {
553 PREAMBLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200554 int16_t offset = inst->VRegA_20t();
555 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700556 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200557 }
558 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200559 break;
560 }
561 case Instruction::GOTO_32: {
562 PREAMBLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200563 int32_t offset = inst->VRegA_30t();
564 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700565 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200566 }
567 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200568 break;
569 }
570 case Instruction::PACKED_SWITCH: {
571 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200572 int32_t offset = DoPackedSwitch(inst, shadow_frame, inst_data);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200573 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700574 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200575 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200576 inst = inst->RelativeAt(offset);
577 break;
578 }
579 case Instruction::SPARSE_SWITCH: {
580 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200581 int32_t offset = DoSparseSwitch(inst, shadow_frame, inst_data);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200582 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700583 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200584 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200585 inst = inst->RelativeAt(offset);
586 break;
587 }
Ian Rogers647b1a82014-10-10 11:02:11 -0700588
589#if defined(__clang__)
590#pragma clang diagnostic push
591#pragma clang diagnostic ignored "-Wfloat-equal"
592#endif
593
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200594 case Instruction::CMPL_FLOAT: {
595 PREAMBLE();
596 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
597 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
598 int32_t result;
599 if (val1 > val2) {
600 result = 1;
601 } else if (val1 == val2) {
602 result = 0;
603 } else {
604 result = -1;
605 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200606 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200607 inst = inst->Next_2xx();
608 break;
609 }
610 case Instruction::CMPG_FLOAT: {
611 PREAMBLE();
612 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
613 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
614 int32_t result;
615 if (val1 < val2) {
616 result = -1;
617 } else if (val1 == val2) {
618 result = 0;
619 } else {
620 result = 1;
621 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200622 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200623 inst = inst->Next_2xx();
624 break;
625 }
626 case Instruction::CMPL_DOUBLE: {
627 PREAMBLE();
628 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
629 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
630 int32_t result;
631 if (val1 > val2) {
632 result = 1;
633 } else if (val1 == val2) {
634 result = 0;
635 } else {
636 result = -1;
637 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200638 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200639 inst = inst->Next_2xx();
640 break;
641 }
642
643 case Instruction::CMPG_DOUBLE: {
644 PREAMBLE();
645 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
646 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
647 int32_t result;
648 if (val1 < val2) {
649 result = -1;
650 } else if (val1 == val2) {
651 result = 0;
652 } else {
653 result = 1;
654 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200655 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200656 inst = inst->Next_2xx();
657 break;
658 }
Ian Rogers647b1a82014-10-10 11:02:11 -0700659
660#if defined(__clang__)
661#pragma clang diagnostic pop
662#endif
663
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200664 case Instruction::CMP_LONG: {
665 PREAMBLE();
666 int64_t val1 = shadow_frame.GetVRegLong(inst->VRegB_23x());
667 int64_t val2 = shadow_frame.GetVRegLong(inst->VRegC_23x());
668 int32_t result;
669 if (val1 > val2) {
670 result = 1;
671 } else if (val1 == val2) {
672 result = 0;
673 } else {
674 result = -1;
675 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200676 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200677 inst = inst->Next_2xx();
678 break;
679 }
680 case Instruction::IF_EQ: {
681 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700682 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) ==
683 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200684 int16_t offset = inst->VRegC_22t();
685 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700686 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200687 }
688 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200689 } else {
690 inst = inst->Next_2xx();
691 }
692 break;
693 }
694 case Instruction::IF_NE: {
695 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700696 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) !=
697 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200698 int16_t offset = inst->VRegC_22t();
699 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700700 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200701 }
702 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200703 } else {
704 inst = inst->Next_2xx();
705 }
706 break;
707 }
708 case Instruction::IF_LT: {
709 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700710 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <
711 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200712 int16_t offset = inst->VRegC_22t();
713 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700714 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200715 }
716 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200717 } else {
718 inst = inst->Next_2xx();
719 }
720 break;
721 }
722 case Instruction::IF_GE: {
723 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700724 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >=
725 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200726 int16_t offset = inst->VRegC_22t();
727 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700728 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200729 }
730 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200731 } else {
732 inst = inst->Next_2xx();
733 }
734 break;
735 }
736 case Instruction::IF_GT: {
737 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700738 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >
739 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200740 int16_t offset = inst->VRegC_22t();
741 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700742 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200743 }
744 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200745 } else {
746 inst = inst->Next_2xx();
747 }
748 break;
749 }
750 case Instruction::IF_LE: {
751 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700752 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <=
753 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200754 int16_t offset = inst->VRegC_22t();
755 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700756 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200757 }
758 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200759 } else {
760 inst = inst->Next_2xx();
761 }
762 break;
763 }
764 case Instruction::IF_EQZ: {
765 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200766 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) == 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200767 int16_t offset = inst->VRegB_21t();
768 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700769 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200770 }
771 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200772 } else {
773 inst = inst->Next_2xx();
774 }
775 break;
776 }
777 case Instruction::IF_NEZ: {
778 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200779 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) != 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200780 int16_t offset = inst->VRegB_21t();
781 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700782 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200783 }
784 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200785 } else {
786 inst = inst->Next_2xx();
787 }
788 break;
789 }
790 case Instruction::IF_LTZ: {
791 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200792 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) < 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200793 int16_t offset = inst->VRegB_21t();
794 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700795 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200796 }
797 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200798 } else {
799 inst = inst->Next_2xx();
800 }
801 break;
802 }
803 case Instruction::IF_GEZ: {
804 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200805 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) >= 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200806 int16_t offset = inst->VRegB_21t();
807 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700808 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200809 }
810 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200811 } else {
812 inst = inst->Next_2xx();
813 }
814 break;
815 }
816 case Instruction::IF_GTZ: {
817 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200818 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) > 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200819 int16_t offset = inst->VRegB_21t();
820 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700821 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200822 }
823 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200824 } else {
825 inst = inst->Next_2xx();
826 }
827 break;
828 }
829 case Instruction::IF_LEZ: {
830 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200831 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) <= 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200832 int16_t offset = inst->VRegB_21t();
833 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700834 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200835 }
836 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200837 } else {
838 inst = inst->Next_2xx();
839 }
840 break;
841 }
842 case Instruction::AGET_BOOLEAN: {
843 PREAMBLE();
844 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700845 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000846 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200847 HANDLE_PENDING_EXCEPTION();
848 break;
849 }
850 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
851 BooleanArray* array = a->AsBooleanArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700852 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100853 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200854 inst = inst->Next_2xx();
855 } else {
856 HANDLE_PENDING_EXCEPTION();
857 }
858 break;
859 }
860 case Instruction::AGET_BYTE: {
861 PREAMBLE();
862 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700863 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000864 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200865 HANDLE_PENDING_EXCEPTION();
866 break;
867 }
868 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
869 ByteArray* array = a->AsByteArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700870 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100871 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200872 inst = inst->Next_2xx();
873 } else {
874 HANDLE_PENDING_EXCEPTION();
875 }
876 break;
877 }
878 case Instruction::AGET_CHAR: {
879 PREAMBLE();
880 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700881 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000882 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200883 HANDLE_PENDING_EXCEPTION();
884 break;
885 }
886 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
887 CharArray* array = a->AsCharArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700888 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100889 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200890 inst = inst->Next_2xx();
891 } else {
892 HANDLE_PENDING_EXCEPTION();
893 }
894 break;
895 }
896 case Instruction::AGET_SHORT: {
897 PREAMBLE();
898 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700899 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000900 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200901 HANDLE_PENDING_EXCEPTION();
902 break;
903 }
904 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
905 ShortArray* array = a->AsShortArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700906 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100907 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200908 inst = inst->Next_2xx();
909 } else {
910 HANDLE_PENDING_EXCEPTION();
911 }
912 break;
913 }
914 case Instruction::AGET: {
915 PREAMBLE();
916 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 Chartiere401d142015-04-22 13:56:20 -0700923 DCHECK(a->IsIntArray() || a->IsFloatArray()) << PrettyTypeOf(a);
924 auto* array = down_cast<IntArray*>(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700925 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100926 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200927 inst = inst->Next_2xx();
928 } else {
929 HANDLE_PENDING_EXCEPTION();
930 }
931 break;
932 }
933 case Instruction::AGET_WIDE: {
934 PREAMBLE();
935 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700936 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000937 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200938 HANDLE_PENDING_EXCEPTION();
939 break;
940 }
941 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700942 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << PrettyTypeOf(a);
943 auto* array = down_cast<LongArray*>(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700944 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100945 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200946 inst = inst->Next_2xx();
947 } else {
948 HANDLE_PENDING_EXCEPTION();
949 }
950 break;
951 }
952 case Instruction::AGET_OBJECT: {
953 PREAMBLE();
954 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700955 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000956 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200957 HANDLE_PENDING_EXCEPTION();
958 break;
959 }
960 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
961 ObjectArray<Object>* array = a->AsObjectArray<Object>();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700962 if (array->CheckIsValidIndex(index)) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200963 shadow_frame.SetVRegReference(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200964 inst = inst->Next_2xx();
965 } else {
966 HANDLE_PENDING_EXCEPTION();
967 }
968 break;
969 }
970 case Instruction::APUT_BOOLEAN: {
971 PREAMBLE();
972 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700973 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000974 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200975 HANDLE_PENDING_EXCEPTION();
976 break;
977 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200978 uint8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200979 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
980 BooleanArray* array = a->AsBooleanArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700981 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100982 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200983 inst = inst->Next_2xx();
984 } else {
985 HANDLE_PENDING_EXCEPTION();
986 }
987 break;
988 }
989 case Instruction::APUT_BYTE: {
990 PREAMBLE();
991 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700992 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000993 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200994 HANDLE_PENDING_EXCEPTION();
995 break;
996 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200997 int8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200998 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
999 ByteArray* array = a->AsByteArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001000 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001001 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001002 inst = inst->Next_2xx();
1003 } else {
1004 HANDLE_PENDING_EXCEPTION();
1005 }
1006 break;
1007 }
1008 case Instruction::APUT_CHAR: {
1009 PREAMBLE();
1010 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001011 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001012 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001013 HANDLE_PENDING_EXCEPTION();
1014 break;
1015 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001016 uint16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001017 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1018 CharArray* array = a->AsCharArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001019 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001020 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001021 inst = inst->Next_2xx();
1022 } else {
1023 HANDLE_PENDING_EXCEPTION();
1024 }
1025 break;
1026 }
1027 case Instruction::APUT_SHORT: {
1028 PREAMBLE();
1029 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001030 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001031 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001032 HANDLE_PENDING_EXCEPTION();
1033 break;
1034 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001035 int16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001036 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1037 ShortArray* array = a->AsShortArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001038 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001039 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001040 inst = inst->Next_2xx();
1041 } else {
1042 HANDLE_PENDING_EXCEPTION();
1043 }
1044 break;
1045 }
1046 case Instruction::APUT: {
1047 PREAMBLE();
1048 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001049 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001050 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001051 HANDLE_PENDING_EXCEPTION();
1052 break;
1053 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001054 int32_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001055 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001056 DCHECK(a->IsIntArray() || a->IsFloatArray()) << PrettyTypeOf(a);
1057 auto* array = down_cast<IntArray*>(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001058 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001059 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001060 inst = inst->Next_2xx();
1061 } else {
1062 HANDLE_PENDING_EXCEPTION();
1063 }
1064 break;
1065 }
1066 case Instruction::APUT_WIDE: {
1067 PREAMBLE();
1068 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001069 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001070 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001071 HANDLE_PENDING_EXCEPTION();
1072 break;
1073 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001074 int64_t val = shadow_frame.GetVRegLong(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001075 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001076 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << PrettyTypeOf(a);
1077 LongArray* array = down_cast<LongArray*>(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001078 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001079 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001080 inst = inst->Next_2xx();
1081 } else {
1082 HANDLE_PENDING_EXCEPTION();
1083 }
1084 break;
1085 }
1086 case Instruction::APUT_OBJECT: {
1087 PREAMBLE();
1088 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001089 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001090 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001091 HANDLE_PENDING_EXCEPTION();
1092 break;
1093 }
1094 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001095 Object* val = shadow_frame.GetVRegReference(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001096 ObjectArray<Object>* array = a->AsObjectArray<Object>();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001097 if (array->CheckIsValidIndex(index) && array->CheckAssignable(val)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001098 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001099 inst = inst->Next_2xx();
1100 } else {
1101 HANDLE_PENDING_EXCEPTION();
1102 }
1103 break;
1104 }
1105 case Instruction::IGET_BOOLEAN: {
1106 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001107 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimBoolean, do_access_check>(
1108 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001109 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1110 break;
1111 }
1112 case Instruction::IGET_BYTE: {
1113 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001114 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimByte, do_access_check>(
1115 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001116 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1117 break;
1118 }
1119 case Instruction::IGET_CHAR: {
1120 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001121 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimChar, do_access_check>(
1122 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001123 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1124 break;
1125 }
1126 case Instruction::IGET_SHORT: {
1127 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001128 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimShort, do_access_check>(
1129 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001130 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1131 break;
1132 }
1133 case Instruction::IGET: {
1134 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001135 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimInt, do_access_check>(
1136 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001137 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1138 break;
1139 }
1140 case Instruction::IGET_WIDE: {
1141 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001142 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimLong, do_access_check>(
1143 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001144 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1145 break;
1146 }
1147 case Instruction::IGET_OBJECT: {
1148 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001149 bool success = DoFieldGet<InstanceObjectRead, Primitive::kPrimNot, do_access_check>(
1150 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001151 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1152 break;
1153 }
1154 case Instruction::IGET_QUICK: {
1155 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001156 bool success = DoIGetQuick<Primitive::kPrimInt>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001157 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1158 break;
1159 }
1160 case Instruction::IGET_WIDE_QUICK: {
1161 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001162 bool success = DoIGetQuick<Primitive::kPrimLong>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001163 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1164 break;
1165 }
1166 case Instruction::IGET_OBJECT_QUICK: {
1167 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001168 bool success = DoIGetQuick<Primitive::kPrimNot>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001169 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1170 break;
1171 }
Mathieu Chartierffc605c2014-12-10 10:35:44 -08001172 case Instruction::IGET_BOOLEAN_QUICK: {
1173 PREAMBLE();
1174 bool success = DoIGetQuick<Primitive::kPrimBoolean>(shadow_frame, inst, inst_data);
1175 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1176 break;
1177 }
1178 case Instruction::IGET_BYTE_QUICK: {
1179 PREAMBLE();
1180 bool success = DoIGetQuick<Primitive::kPrimByte>(shadow_frame, inst, inst_data);
1181 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1182 break;
1183 }
1184 case Instruction::IGET_CHAR_QUICK: {
1185 PREAMBLE();
1186 bool success = DoIGetQuick<Primitive::kPrimChar>(shadow_frame, inst, inst_data);
1187 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1188 break;
1189 }
1190 case Instruction::IGET_SHORT_QUICK: {
1191 PREAMBLE();
1192 bool success = DoIGetQuick<Primitive::kPrimShort>(shadow_frame, inst, inst_data);
1193 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1194 break;
1195 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001196 case Instruction::SGET_BOOLEAN: {
1197 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001198 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimBoolean, do_access_check>(
1199 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001200 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1201 break;
1202 }
1203 case Instruction::SGET_BYTE: {
1204 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001205 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimByte, do_access_check>(
1206 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001207 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1208 break;
1209 }
1210 case Instruction::SGET_CHAR: {
1211 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001212 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimChar, do_access_check>(
1213 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001214 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1215 break;
1216 }
1217 case Instruction::SGET_SHORT: {
1218 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001219 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimShort, do_access_check>(
1220 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001221 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1222 break;
1223 }
1224 case Instruction::SGET: {
1225 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001226 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimInt, do_access_check>(
1227 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001228 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1229 break;
1230 }
1231 case Instruction::SGET_WIDE: {
1232 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001233 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimLong, do_access_check>(
1234 self, 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::SGET_OBJECT: {
1239 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001240 bool success = DoFieldGet<StaticObjectRead, Primitive::kPrimNot, do_access_check>(
1241 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001242 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1243 break;
1244 }
1245 case Instruction::IPUT_BOOLEAN: {
1246 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001247 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1248 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001249 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1250 break;
1251 }
1252 case Instruction::IPUT_BYTE: {
1253 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001254 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimByte, do_access_check,
1255 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001256 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1257 break;
1258 }
1259 case Instruction::IPUT_CHAR: {
1260 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001261 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimChar, do_access_check,
1262 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001263 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1264 break;
1265 }
1266 case Instruction::IPUT_SHORT: {
1267 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001268 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimShort, do_access_check,
1269 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001270 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1271 break;
1272 }
1273 case Instruction::IPUT: {
1274 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001275 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimInt, do_access_check,
1276 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001277 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1278 break;
1279 }
1280 case Instruction::IPUT_WIDE: {
1281 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001282 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimLong, do_access_check,
1283 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001284 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1285 break;
1286 }
1287 case Instruction::IPUT_OBJECT: {
1288 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001289 bool success = DoFieldPut<InstanceObjectWrite, Primitive::kPrimNot, do_access_check,
1290 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001291 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1292 break;
1293 }
1294 case Instruction::IPUT_QUICK: {
1295 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001296 bool success = DoIPutQuick<Primitive::kPrimInt, transaction_active>(
1297 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001298 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1299 break;
1300 }
Fred Shih37f05ef2014-07-16 18:38:08 -07001301 case Instruction::IPUT_BOOLEAN_QUICK: {
1302 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001303 bool success = DoIPutQuick<Primitive::kPrimBoolean, transaction_active>(
1304 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001305 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1306 break;
1307 }
1308 case Instruction::IPUT_BYTE_QUICK: {
1309 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001310 bool success = DoIPutQuick<Primitive::kPrimByte, transaction_active>(
1311 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001312 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1313 break;
1314 }
1315 case Instruction::IPUT_CHAR_QUICK: {
1316 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001317 bool success = DoIPutQuick<Primitive::kPrimChar, transaction_active>(
1318 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001319 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1320 break;
1321 }
1322 case Instruction::IPUT_SHORT_QUICK: {
1323 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001324 bool success = DoIPutQuick<Primitive::kPrimShort, transaction_active>(
1325 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001326 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1327 break;
1328 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001329 case Instruction::IPUT_WIDE_QUICK: {
1330 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001331 bool success = DoIPutQuick<Primitive::kPrimLong, transaction_active>(
1332 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001333 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1334 break;
1335 }
1336 case Instruction::IPUT_OBJECT_QUICK: {
1337 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001338 bool success = DoIPutQuick<Primitive::kPrimNot, transaction_active>(
1339 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001340 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1341 break;
1342 }
1343 case Instruction::SPUT_BOOLEAN: {
1344 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001345 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1346 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001347 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1348 break;
1349 }
1350 case Instruction::SPUT_BYTE: {
1351 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001352 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimByte, do_access_check,
1353 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001354 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1355 break;
1356 }
1357 case Instruction::SPUT_CHAR: {
1358 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001359 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimChar, do_access_check,
1360 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001361 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1362 break;
1363 }
1364 case Instruction::SPUT_SHORT: {
1365 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001366 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimShort, do_access_check,
1367 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001368 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1369 break;
1370 }
1371 case Instruction::SPUT: {
1372 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001373 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimInt, do_access_check,
1374 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001375 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1376 break;
1377 }
1378 case Instruction::SPUT_WIDE: {
1379 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001380 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimLong, do_access_check,
1381 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001382 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1383 break;
1384 }
1385 case Instruction::SPUT_OBJECT: {
1386 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001387 bool success = DoFieldPut<StaticObjectWrite, Primitive::kPrimNot, do_access_check,
1388 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001389 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1390 break;
1391 }
1392 case Instruction::INVOKE_VIRTUAL: {
1393 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001394 bool success = DoInvoke<kVirtual, false, do_access_check>(
1395 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001396 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1397 break;
1398 }
1399 case Instruction::INVOKE_VIRTUAL_RANGE: {
1400 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001401 bool success = DoInvoke<kVirtual, true, do_access_check>(
1402 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001403 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1404 break;
1405 }
1406 case Instruction::INVOKE_SUPER: {
1407 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001408 bool success = DoInvoke<kSuper, false, do_access_check>(
1409 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001410 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1411 break;
1412 }
1413 case Instruction::INVOKE_SUPER_RANGE: {
1414 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001415 bool success = DoInvoke<kSuper, true, do_access_check>(
1416 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001417 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1418 break;
1419 }
1420 case Instruction::INVOKE_DIRECT: {
1421 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001422 bool success = DoInvoke<kDirect, false, do_access_check>(
1423 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001424 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1425 break;
1426 }
1427 case Instruction::INVOKE_DIRECT_RANGE: {
1428 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001429 bool success = DoInvoke<kDirect, true, do_access_check>(
1430 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001431 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1432 break;
1433 }
1434 case Instruction::INVOKE_INTERFACE: {
1435 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001436 bool success = DoInvoke<kInterface, false, do_access_check>(
1437 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001438 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1439 break;
1440 }
1441 case Instruction::INVOKE_INTERFACE_RANGE: {
1442 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001443 bool success = DoInvoke<kInterface, true, do_access_check>(
1444 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001445 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1446 break;
1447 }
1448 case Instruction::INVOKE_STATIC: {
1449 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001450 bool success = DoInvoke<kStatic, false, do_access_check>(
1451 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001452 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1453 break;
1454 }
1455 case Instruction::INVOKE_STATIC_RANGE: {
1456 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001457 bool success = DoInvoke<kStatic, true, do_access_check>(
1458 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001459 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1460 break;
1461 }
1462 case Instruction::INVOKE_VIRTUAL_QUICK: {
1463 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001464 bool success = DoInvokeVirtualQuick<false>(
1465 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001466 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1467 break;
1468 }
1469 case Instruction::INVOKE_VIRTUAL_RANGE_QUICK: {
1470 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001471 bool success = DoInvokeVirtualQuick<true>(
1472 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001473 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1474 break;
1475 }
1476 case Instruction::NEG_INT:
1477 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001478 shadow_frame.SetVReg(
1479 inst->VRegA_12x(inst_data), -shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001480 inst = inst->Next_1xx();
1481 break;
1482 case Instruction::NOT_INT:
1483 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001484 shadow_frame.SetVReg(
1485 inst->VRegA_12x(inst_data), ~shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001486 inst = inst->Next_1xx();
1487 break;
1488 case Instruction::NEG_LONG:
1489 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001490 shadow_frame.SetVRegLong(
1491 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001492 inst = inst->Next_1xx();
1493 break;
1494 case Instruction::NOT_LONG:
1495 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001496 shadow_frame.SetVRegLong(
1497 inst->VRegA_12x(inst_data), ~shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001498 inst = inst->Next_1xx();
1499 break;
1500 case Instruction::NEG_FLOAT:
1501 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001502 shadow_frame.SetVRegFloat(
1503 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001504 inst = inst->Next_1xx();
1505 break;
1506 case Instruction::NEG_DOUBLE:
1507 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001508 shadow_frame.SetVRegDouble(
1509 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001510 inst = inst->Next_1xx();
1511 break;
1512 case Instruction::INT_TO_LONG:
1513 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001514 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
1515 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001516 inst = inst->Next_1xx();
1517 break;
1518 case Instruction::INT_TO_FLOAT:
1519 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001520 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1521 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001522 inst = inst->Next_1xx();
1523 break;
1524 case Instruction::INT_TO_DOUBLE:
1525 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001526 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1527 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001528 inst = inst->Next_1xx();
1529 break;
1530 case Instruction::LONG_TO_INT:
1531 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001532 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1533 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001534 inst = inst->Next_1xx();
1535 break;
1536 case Instruction::LONG_TO_FLOAT:
1537 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001538 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1539 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001540 inst = inst->Next_1xx();
1541 break;
1542 case Instruction::LONG_TO_DOUBLE:
1543 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001544 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1545 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001546 inst = inst->Next_1xx();
1547 break;
1548 case Instruction::FLOAT_TO_INT: {
1549 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001550 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001551 int32_t result = art_float_to_integral<int32_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001552 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001553 inst = inst->Next_1xx();
1554 break;
1555 }
1556 case Instruction::FLOAT_TO_LONG: {
1557 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001558 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001559 int64_t result = art_float_to_integral<int64_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001560 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001561 inst = inst->Next_1xx();
1562 break;
1563 }
1564 case Instruction::FLOAT_TO_DOUBLE:
1565 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001566 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1567 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001568 inst = inst->Next_1xx();
1569 break;
1570 case Instruction::DOUBLE_TO_INT: {
1571 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001572 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001573 int32_t result = art_float_to_integral<int32_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001574 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001575 inst = inst->Next_1xx();
1576 break;
1577 }
1578 case Instruction::DOUBLE_TO_LONG: {
1579 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001580 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001581 int64_t result = art_float_to_integral<int64_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001582 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001583 inst = inst->Next_1xx();
1584 break;
1585 }
1586 case Instruction::DOUBLE_TO_FLOAT:
1587 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001588 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1589 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001590 inst = inst->Next_1xx();
1591 break;
1592 case Instruction::INT_TO_BYTE:
1593 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001594 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), static_cast<int8_t>(
1595 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001596 inst = inst->Next_1xx();
1597 break;
1598 case Instruction::INT_TO_CHAR:
1599 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001600 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), static_cast<uint16_t>(
1601 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001602 inst = inst->Next_1xx();
1603 break;
1604 case Instruction::INT_TO_SHORT:
1605 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001606 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), static_cast<int16_t>(
1607 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001608 inst = inst->Next_1xx();
1609 break;
Ian Rogersf72a11d2014-10-30 15:41:08 -07001610 case Instruction::ADD_INT: {
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001611 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001612 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001613 SafeAdd(shadow_frame.GetVReg(inst->VRegB_23x()),
1614 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001615 inst = inst->Next_2xx();
1616 break;
Ian Rogersf72a11d2014-10-30 15:41:08 -07001617 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001618 case Instruction::SUB_INT:
1619 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001620 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001621 SafeSub(shadow_frame.GetVReg(inst->VRegB_23x()),
1622 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001623 inst = inst->Next_2xx();
1624 break;
1625 case Instruction::MUL_INT:
1626 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001627 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001628 SafeMul(shadow_frame.GetVReg(inst->VRegB_23x()),
1629 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001630 inst = inst->Next_2xx();
1631 break;
1632 case Instruction::DIV_INT: {
1633 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001634 bool success = DoIntDivide(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001635 shadow_frame.GetVReg(inst->VRegB_23x()),
1636 shadow_frame.GetVReg(inst->VRegC_23x()));
1637 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1638 break;
1639 }
1640 case Instruction::REM_INT: {
1641 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001642 bool success = DoIntRemainder(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001643 shadow_frame.GetVReg(inst->VRegB_23x()),
1644 shadow_frame.GetVReg(inst->VRegC_23x()));
1645 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1646 break;
1647 }
1648 case Instruction::SHL_INT:
1649 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001650 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001651 shadow_frame.GetVReg(inst->VRegB_23x()) <<
1652 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1653 inst = inst->Next_2xx();
1654 break;
1655 case Instruction::SHR_INT:
1656 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001657 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001658 shadow_frame.GetVReg(inst->VRegB_23x()) >>
1659 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1660 inst = inst->Next_2xx();
1661 break;
1662 case Instruction::USHR_INT:
1663 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001664 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001665 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_23x())) >>
1666 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1667 inst = inst->Next_2xx();
1668 break;
1669 case Instruction::AND_INT:
1670 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001671 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001672 shadow_frame.GetVReg(inst->VRegB_23x()) &
1673 shadow_frame.GetVReg(inst->VRegC_23x()));
1674 inst = inst->Next_2xx();
1675 break;
1676 case Instruction::OR_INT:
1677 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001678 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001679 shadow_frame.GetVReg(inst->VRegB_23x()) |
1680 shadow_frame.GetVReg(inst->VRegC_23x()));
1681 inst = inst->Next_2xx();
1682 break;
1683 case Instruction::XOR_INT:
1684 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001685 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001686 shadow_frame.GetVReg(inst->VRegB_23x()) ^
1687 shadow_frame.GetVReg(inst->VRegC_23x()));
1688 inst = inst->Next_2xx();
1689 break;
1690 case Instruction::ADD_LONG:
1691 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001692 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001693 SafeAdd(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1694 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001695 inst = inst->Next_2xx();
1696 break;
1697 case Instruction::SUB_LONG:
1698 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001699 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001700 SafeSub(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1701 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001702 inst = inst->Next_2xx();
1703 break;
1704 case Instruction::MUL_LONG:
1705 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001706 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001707 SafeMul(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1708 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001709 inst = inst->Next_2xx();
1710 break;
1711 case Instruction::DIV_LONG:
1712 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001713 DoLongDivide(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001714 shadow_frame.GetVRegLong(inst->VRegB_23x()),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001715 shadow_frame.GetVRegLong(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001716 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
1717 break;
1718 case Instruction::REM_LONG:
1719 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001720 DoLongRemainder(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001721 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1722 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1723 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
1724 break;
1725 case Instruction::AND_LONG:
1726 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001727 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001728 shadow_frame.GetVRegLong(inst->VRegB_23x()) &
1729 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1730 inst = inst->Next_2xx();
1731 break;
1732 case Instruction::OR_LONG:
1733 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001734 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001735 shadow_frame.GetVRegLong(inst->VRegB_23x()) |
1736 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1737 inst = inst->Next_2xx();
1738 break;
1739 case Instruction::XOR_LONG:
1740 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001741 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001742 shadow_frame.GetVRegLong(inst->VRegB_23x()) ^
1743 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1744 inst = inst->Next_2xx();
1745 break;
1746 case Instruction::SHL_LONG:
1747 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001748 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001749 shadow_frame.GetVRegLong(inst->VRegB_23x()) <<
1750 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1751 inst = inst->Next_2xx();
1752 break;
1753 case Instruction::SHR_LONG:
1754 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001755 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001756 shadow_frame.GetVRegLong(inst->VRegB_23x()) >>
1757 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1758 inst = inst->Next_2xx();
1759 break;
1760 case Instruction::USHR_LONG:
1761 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001762 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001763 static_cast<uint64_t>(shadow_frame.GetVRegLong(inst->VRegB_23x())) >>
1764 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1765 inst = inst->Next_2xx();
1766 break;
1767 case Instruction::ADD_FLOAT:
1768 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001769 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001770 shadow_frame.GetVRegFloat(inst->VRegB_23x()) +
1771 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1772 inst = inst->Next_2xx();
1773 break;
1774 case Instruction::SUB_FLOAT:
1775 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001776 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001777 shadow_frame.GetVRegFloat(inst->VRegB_23x()) -
1778 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1779 inst = inst->Next_2xx();
1780 break;
1781 case Instruction::MUL_FLOAT:
1782 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001783 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001784 shadow_frame.GetVRegFloat(inst->VRegB_23x()) *
1785 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1786 inst = inst->Next_2xx();
1787 break;
1788 case Instruction::DIV_FLOAT:
1789 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001790 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001791 shadow_frame.GetVRegFloat(inst->VRegB_23x()) /
1792 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1793 inst = inst->Next_2xx();
1794 break;
1795 case Instruction::REM_FLOAT:
1796 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001797 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001798 fmodf(shadow_frame.GetVRegFloat(inst->VRegB_23x()),
1799 shadow_frame.GetVRegFloat(inst->VRegC_23x())));
1800 inst = inst->Next_2xx();
1801 break;
1802 case Instruction::ADD_DOUBLE:
1803 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001804 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001805 shadow_frame.GetVRegDouble(inst->VRegB_23x()) +
1806 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1807 inst = inst->Next_2xx();
1808 break;
1809 case Instruction::SUB_DOUBLE:
1810 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001811 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001812 shadow_frame.GetVRegDouble(inst->VRegB_23x()) -
1813 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1814 inst = inst->Next_2xx();
1815 break;
1816 case Instruction::MUL_DOUBLE:
1817 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001818 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001819 shadow_frame.GetVRegDouble(inst->VRegB_23x()) *
1820 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1821 inst = inst->Next_2xx();
1822 break;
1823 case Instruction::DIV_DOUBLE:
1824 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001825 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001826 shadow_frame.GetVRegDouble(inst->VRegB_23x()) /
1827 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1828 inst = inst->Next_2xx();
1829 break;
1830 case Instruction::REM_DOUBLE:
1831 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001832 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001833 fmod(shadow_frame.GetVRegDouble(inst->VRegB_23x()),
1834 shadow_frame.GetVRegDouble(inst->VRegC_23x())));
1835 inst = inst->Next_2xx();
1836 break;
1837 case Instruction::ADD_INT_2ADDR: {
1838 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001839 uint4_t vregA = inst->VRegA_12x(inst_data);
Ian Rogersf72a11d2014-10-30 15:41:08 -07001840 shadow_frame.SetVReg(vregA, SafeAdd(shadow_frame.GetVReg(vregA),
1841 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001842 inst = inst->Next_1xx();
1843 break;
1844 }
1845 case Instruction::SUB_INT_2ADDR: {
1846 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001847 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001848 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07001849 SafeSub(shadow_frame.GetVReg(vregA),
1850 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001851 inst = inst->Next_1xx();
1852 break;
1853 }
1854 case Instruction::MUL_INT_2ADDR: {
1855 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001856 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001857 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07001858 SafeMul(shadow_frame.GetVReg(vregA),
1859 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001860 inst = inst->Next_1xx();
1861 break;
1862 }
1863 case Instruction::DIV_INT_2ADDR: {
1864 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001865 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001866 bool success = DoIntDivide(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001867 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001868 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
1869 break;
1870 }
1871 case Instruction::REM_INT_2ADDR: {
1872 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001873 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001874 bool success = DoIntRemainder(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001875 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001876 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
1877 break;
1878 }
1879 case Instruction::SHL_INT_2ADDR: {
1880 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001881 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001882 shadow_frame.SetVReg(vregA,
1883 shadow_frame.GetVReg(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001884 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001885 inst = inst->Next_1xx();
1886 break;
1887 }
1888 case Instruction::SHR_INT_2ADDR: {
1889 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001890 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001891 shadow_frame.SetVReg(vregA,
1892 shadow_frame.GetVReg(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001893 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001894 inst = inst->Next_1xx();
1895 break;
1896 }
1897 case Instruction::USHR_INT_2ADDR: {
1898 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001899 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001900 shadow_frame.SetVReg(vregA,
1901 static_cast<uint32_t>(shadow_frame.GetVReg(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001902 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001903 inst = inst->Next_1xx();
1904 break;
1905 }
1906 case Instruction::AND_INT_2ADDR: {
1907 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001908 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001909 shadow_frame.SetVReg(vregA,
1910 shadow_frame.GetVReg(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001911 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001912 inst = inst->Next_1xx();
1913 break;
1914 }
1915 case Instruction::OR_INT_2ADDR: {
1916 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001917 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001918 shadow_frame.SetVReg(vregA,
1919 shadow_frame.GetVReg(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001920 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001921 inst = inst->Next_1xx();
1922 break;
1923 }
1924 case Instruction::XOR_INT_2ADDR: {
1925 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001926 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001927 shadow_frame.SetVReg(vregA,
1928 shadow_frame.GetVReg(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001929 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001930 inst = inst->Next_1xx();
1931 break;
1932 }
1933 case Instruction::ADD_LONG_2ADDR: {
1934 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001935 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001936 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07001937 SafeAdd(shadow_frame.GetVRegLong(vregA),
1938 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001939 inst = inst->Next_1xx();
1940 break;
1941 }
1942 case Instruction::SUB_LONG_2ADDR: {
1943 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001944 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001945 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07001946 SafeSub(shadow_frame.GetVRegLong(vregA),
1947 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001948 inst = inst->Next_1xx();
1949 break;
1950 }
1951 case Instruction::MUL_LONG_2ADDR: {
1952 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001953 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001954 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07001955 SafeMul(shadow_frame.GetVRegLong(vregA),
1956 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001957 inst = inst->Next_1xx();
1958 break;
1959 }
1960 case Instruction::DIV_LONG_2ADDR: {
1961 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001962 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001963 DoLongDivide(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001964 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001965 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
1966 break;
1967 }
1968 case Instruction::REM_LONG_2ADDR: {
1969 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001970 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001971 DoLongRemainder(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001972 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001973 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
1974 break;
1975 }
1976 case Instruction::AND_LONG_2ADDR: {
1977 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001978 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001979 shadow_frame.SetVRegLong(vregA,
1980 shadow_frame.GetVRegLong(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001981 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001982 inst = inst->Next_1xx();
1983 break;
1984 }
1985 case Instruction::OR_LONG_2ADDR: {
1986 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001987 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001988 shadow_frame.SetVRegLong(vregA,
1989 shadow_frame.GetVRegLong(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001990 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001991 inst = inst->Next_1xx();
1992 break;
1993 }
1994 case Instruction::XOR_LONG_2ADDR: {
1995 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001996 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001997 shadow_frame.SetVRegLong(vregA,
1998 shadow_frame.GetVRegLong(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001999 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002000 inst = inst->Next_1xx();
2001 break;
2002 }
2003 case Instruction::SHL_LONG_2ADDR: {
2004 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002005 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002006 shadow_frame.SetVRegLong(vregA,
2007 shadow_frame.GetVRegLong(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002008 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002009 inst = inst->Next_1xx();
2010 break;
2011 }
2012 case Instruction::SHR_LONG_2ADDR: {
2013 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002014 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002015 shadow_frame.SetVRegLong(vregA,
2016 shadow_frame.GetVRegLong(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002017 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002018 inst = inst->Next_1xx();
2019 break;
2020 }
2021 case Instruction::USHR_LONG_2ADDR: {
2022 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002023 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002024 shadow_frame.SetVRegLong(vregA,
2025 static_cast<uint64_t>(shadow_frame.GetVRegLong(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002026 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002027 inst = inst->Next_1xx();
2028 break;
2029 }
2030 case Instruction::ADD_FLOAT_2ADDR: {
2031 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002032 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002033 shadow_frame.SetVRegFloat(vregA,
2034 shadow_frame.GetVRegFloat(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002035 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002036 inst = inst->Next_1xx();
2037 break;
2038 }
2039 case Instruction::SUB_FLOAT_2ADDR: {
2040 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002041 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002042 shadow_frame.SetVRegFloat(vregA,
2043 shadow_frame.GetVRegFloat(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002044 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002045 inst = inst->Next_1xx();
2046 break;
2047 }
2048 case Instruction::MUL_FLOAT_2ADDR: {
2049 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002050 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002051 shadow_frame.SetVRegFloat(vregA,
2052 shadow_frame.GetVRegFloat(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002053 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002054 inst = inst->Next_1xx();
2055 break;
2056 }
2057 case Instruction::DIV_FLOAT_2ADDR: {
2058 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002059 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002060 shadow_frame.SetVRegFloat(vregA,
2061 shadow_frame.GetVRegFloat(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002062 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002063 inst = inst->Next_1xx();
2064 break;
2065 }
2066 case Instruction::REM_FLOAT_2ADDR: {
2067 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002068 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002069 shadow_frame.SetVRegFloat(vregA,
2070 fmodf(shadow_frame.GetVRegFloat(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002071 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002072 inst = inst->Next_1xx();
2073 break;
2074 }
2075 case Instruction::ADD_DOUBLE_2ADDR: {
2076 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002077 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002078 shadow_frame.SetVRegDouble(vregA,
2079 shadow_frame.GetVRegDouble(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002080 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002081 inst = inst->Next_1xx();
2082 break;
2083 }
2084 case Instruction::SUB_DOUBLE_2ADDR: {
2085 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002086 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002087 shadow_frame.SetVRegDouble(vregA,
2088 shadow_frame.GetVRegDouble(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002089 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002090 inst = inst->Next_1xx();
2091 break;
2092 }
2093 case Instruction::MUL_DOUBLE_2ADDR: {
2094 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002095 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002096 shadow_frame.SetVRegDouble(vregA,
2097 shadow_frame.GetVRegDouble(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002098 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002099 inst = inst->Next_1xx();
2100 break;
2101 }
2102 case Instruction::DIV_DOUBLE_2ADDR: {
2103 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002104 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002105 shadow_frame.SetVRegDouble(vregA,
2106 shadow_frame.GetVRegDouble(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002107 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002108 inst = inst->Next_1xx();
2109 break;
2110 }
2111 case Instruction::REM_DOUBLE_2ADDR: {
2112 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002113 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002114 shadow_frame.SetVRegDouble(vregA,
2115 fmod(shadow_frame.GetVRegDouble(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002116 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002117 inst = inst->Next_1xx();
2118 break;
2119 }
2120 case Instruction::ADD_INT_LIT16:
2121 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002122 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002123 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2124 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002125 inst = inst->Next_2xx();
2126 break;
Ian Rogersf72a11d2014-10-30 15:41:08 -07002127 case Instruction::RSUB_INT_LIT16:
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002128 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002129 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002130 SafeSub(inst->VRegC_22s(),
2131 shadow_frame.GetVReg(inst->VRegB_22s(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002132 inst = inst->Next_2xx();
2133 break;
2134 case Instruction::MUL_INT_LIT16:
2135 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002136 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002137 SafeMul(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2138 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002139 inst = inst->Next_2xx();
2140 break;
2141 case Instruction::DIV_INT_LIT16: {
2142 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002143 bool success = DoIntDivide(shadow_frame, inst->VRegA_22s(inst_data),
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002144 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2145 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002146 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2147 break;
2148 }
2149 case Instruction::REM_INT_LIT16: {
2150 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002151 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22s(inst_data),
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002152 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2153 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002154 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2155 break;
2156 }
2157 case Instruction::AND_INT_LIT16:
2158 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002159 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2160 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) &
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002161 inst->VRegC_22s());
2162 inst = inst->Next_2xx();
2163 break;
2164 case Instruction::OR_INT_LIT16:
2165 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002166 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2167 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) |
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002168 inst->VRegC_22s());
2169 inst = inst->Next_2xx();
2170 break;
2171 case Instruction::XOR_INT_LIT16:
2172 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002173 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2174 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) ^
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002175 inst->VRegC_22s());
2176 inst = inst->Next_2xx();
2177 break;
2178 case Instruction::ADD_INT_LIT8:
2179 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002180 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002181 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002182 inst = inst->Next_2xx();
2183 break;
2184 case Instruction::RSUB_INT_LIT8:
2185 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002186 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002187 SafeSub(inst->VRegC_22b(), shadow_frame.GetVReg(inst->VRegB_22b())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002188 inst = inst->Next_2xx();
2189 break;
2190 case Instruction::MUL_INT_LIT8:
2191 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002192 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002193 SafeMul(shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002194 inst = inst->Next_2xx();
2195 break;
2196 case Instruction::DIV_INT_LIT8: {
2197 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002198 bool success = DoIntDivide(shadow_frame, inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002199 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
2200 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2201 break;
2202 }
2203 case Instruction::REM_INT_LIT8: {
2204 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002205 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002206 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
2207 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2208 break;
2209 }
2210 case Instruction::AND_INT_LIT8:
2211 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002212 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002213 shadow_frame.GetVReg(inst->VRegB_22b()) &
2214 inst->VRegC_22b());
2215 inst = inst->Next_2xx();
2216 break;
2217 case Instruction::OR_INT_LIT8:
2218 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002219 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002220 shadow_frame.GetVReg(inst->VRegB_22b()) |
2221 inst->VRegC_22b());
2222 inst = inst->Next_2xx();
2223 break;
2224 case Instruction::XOR_INT_LIT8:
2225 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002226 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002227 shadow_frame.GetVReg(inst->VRegB_22b()) ^
2228 inst->VRegC_22b());
2229 inst = inst->Next_2xx();
2230 break;
2231 case Instruction::SHL_INT_LIT8:
2232 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002233 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002234 shadow_frame.GetVReg(inst->VRegB_22b()) <<
2235 (inst->VRegC_22b() & 0x1f));
2236 inst = inst->Next_2xx();
2237 break;
2238 case Instruction::SHR_INT_LIT8:
2239 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002240 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002241 shadow_frame.GetVReg(inst->VRegB_22b()) >>
2242 (inst->VRegC_22b() & 0x1f));
2243 inst = inst->Next_2xx();
2244 break;
2245 case Instruction::USHR_INT_LIT8:
2246 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002247 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002248 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_22b())) >>
2249 (inst->VRegC_22b() & 0x1f));
2250 inst = inst->Next_2xx();
2251 break;
Igor Murashkin158f35c2015-06-10 15:55:30 -07002252 case Instruction::INVOKE_LAMBDA: {
2253 if (!IsExperimentalInstructionEnabled(inst)) {
2254 UnexpectedOpcode(inst, shadow_frame);
2255 }
2256
2257 PREAMBLE();
2258 bool success = DoInvokeLambda<do_access_check>(self, shadow_frame, inst, inst_data,
2259 &result_register);
2260 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2261 break;
2262 }
Igor Murashkin6918bf12015-09-27 19:19:06 -07002263 case Instruction::CAPTURE_VARIABLE: {
2264 if (!IsExperimentalInstructionEnabled(inst)) {
2265 UnexpectedOpcode(inst, shadow_frame);
2266 }
2267
2268 if (lambda_closure_builder == nullptr) {
2269 lambda_closure_builder = MakeUnique<lambda::ClosureBuilder>();
2270 }
2271
2272 PREAMBLE();
2273 bool success = DoCaptureVariable<do_access_check>(self,
2274 inst,
2275 /*inout*/shadow_frame,
2276 /*inout*/lambda_closure_builder.get());
2277 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2278 break;
2279 }
Igor Murashkin158f35c2015-06-10 15:55:30 -07002280 case Instruction::CREATE_LAMBDA: {
2281 if (!IsExperimentalInstructionEnabled(inst)) {
2282 UnexpectedOpcode(inst, shadow_frame);
2283 }
2284
2285 PREAMBLE();
Igor Murashkin6918bf12015-09-27 19:19:06 -07002286
2287 if (lambda_closure_builder == nullptr) {
2288 // DoCreateLambda always needs a ClosureBuilder, even if it has 0 captured variables.
2289 lambda_closure_builder = MakeUnique<lambda::ClosureBuilder>();
2290 }
2291
2292 // TODO: these allocations should not leak, and the lambda method should not be local.
2293 lambda::Closure* lambda_closure =
2294 reinterpret_cast<lambda::Closure*>(alloca(lambda_closure_builder->GetSize()));
2295 bool success = DoCreateLambda<do_access_check>(self,
2296 inst,
2297 /*inout*/shadow_frame,
2298 /*inout*/lambda_closure_builder.get(),
2299 /*inout*/lambda_closure);
2300 lambda_closure_builder.reset(nullptr); // reset state of variables captured
Igor Murashkin158f35c2015-06-10 15:55:30 -07002301 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2302 break;
2303 }
Igor Murashkin6918bf12015-09-27 19:19:06 -07002304 case Instruction::LIBERATE_VARIABLE: {
2305 if (!IsExperimentalInstructionEnabled(inst)) {
2306 UnexpectedOpcode(inst, shadow_frame);
2307 }
2308
2309 PREAMBLE();
2310 bool success = DoLiberateVariable<do_access_check>(self,
2311 inst,
2312 lambda_captured_variable_index,
2313 /*inout*/shadow_frame);
2314 // Temporarily only allow sequences of 'liberate-variable, liberate-variable, ...'
2315 lambda_captured_variable_index++;
2316 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2317 break;
2318 }
2319 case Instruction::UNUSED_F4: {
Igor Murashkin158f35c2015-06-10 15:55:30 -07002320 if (!IsExperimentalInstructionEnabled(inst)) {
2321 UnexpectedOpcode(inst, shadow_frame);
2322 }
2323
2324 CHECK(false); // TODO(iam): Implement opcodes for lambdas
2325 break;
2326 }
Igor Murashkin2ee54e22015-06-18 10:05:11 -07002327 case Instruction::BOX_LAMBDA: {
2328 if (!IsExperimentalInstructionEnabled(inst)) {
2329 UnexpectedOpcode(inst, shadow_frame);
2330 }
2331
2332 PREAMBLE();
2333 bool success = DoBoxLambda<do_access_check>(self, shadow_frame, inst, inst_data);
2334 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2335 break;
2336 }
2337 case Instruction::UNBOX_LAMBDA: {
2338 if (!IsExperimentalInstructionEnabled(inst)) {
2339 UnexpectedOpcode(inst, shadow_frame);
2340 }
2341
2342 PREAMBLE();
2343 bool success = DoUnboxLambda<do_access_check>(self, shadow_frame, inst, inst_data);
2344 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2345 break;
2346 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002347 case Instruction::UNUSED_3E ... Instruction::UNUSED_43:
Igor Murashkin158f35c2015-06-10 15:55:30 -07002348 case Instruction::UNUSED_FA ... Instruction::UNUSED_FF:
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002349 case Instruction::UNUSED_79:
2350 case Instruction::UNUSED_7A:
Ian Rogerse94652f2014-12-02 11:13:19 -08002351 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002352 }
2353 }
2354} // NOLINT(readability/fn_size)
2355
2356// Explicit definitions of ExecuteSwitchImpl.
Mathieu Chartier90443472015-07-16 20:32:27 -07002357template SHARED_REQUIRES(Locks::mutator_lock_) HOT_ATTR
Ian Rogerse94652f2014-12-02 11:13:19 -08002358JValue ExecuteSwitchImpl<true, false>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002359 ShadowFrame& shadow_frame, JValue result_register);
Mathieu Chartier90443472015-07-16 20:32:27 -07002360template SHARED_REQUIRES(Locks::mutator_lock_) HOT_ATTR
Ian Rogerse94652f2014-12-02 11:13:19 -08002361JValue ExecuteSwitchImpl<false, false>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002362 ShadowFrame& shadow_frame, JValue result_register);
Mathieu Chartier90443472015-07-16 20:32:27 -07002363template SHARED_REQUIRES(Locks::mutator_lock_)
Ian Rogerse94652f2014-12-02 11:13:19 -08002364JValue ExecuteSwitchImpl<true, true>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002365 ShadowFrame& shadow_frame, JValue result_register);
Mathieu Chartier90443472015-07-16 20:32:27 -07002366template SHARED_REQUIRES(Locks::mutator_lock_)
Ian Rogerse94652f2014-12-02 11:13:19 -08002367JValue ExecuteSwitchImpl<false, true>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002368 ShadowFrame& shadow_frame, JValue result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002369
2370} // namespace interpreter
2371} // namespace art