blob: 4265b502c64ef55946fa215ea192f3b3872c21be [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
Colin Crosse84e4f72015-03-18 14:01:19 -070017#if !defined(__clang__)
18// Clang 3.4 fails to build the goto interpreter implementation.
19
Igor Murashkin6918bf12015-09-27 19:19:06 -070020
21#include "base/stl_util.h" // MakeUnique
Sebastien Hertz8ece0502013-08-07 11:26:41 +020022#include "interpreter_common.h"
Ian Rogersf72a11d2014-10-30 15:41:08 -070023#include "safe_math.h"
Sebastien Hertz8ece0502013-08-07 11:26:41 +020024
Igor Murashkin6918bf12015-09-27 19:19:06 -070025#include <memory> // std::unique_ptr
26
Sebastien Hertz8ece0502013-08-07 11:26:41 +020027namespace art {
28namespace interpreter {
29
30// In the following macros, we expect the following local variables exist:
31// - "self": the current Thread*.
32// - "inst" : the current Instruction*.
Sebastien Hertz3b588e02013-09-11 14:33:18 +020033// - "inst_data" : the current instruction's first 16 bits.
Sebastien Hertz8ece0502013-08-07 11:26:41 +020034// - "dex_pc": the current pc.
35// - "shadow_frame": the current shadow frame.
Sebastien Hertz8ece0502013-08-07 11:26:41 +020036// - "currentHandlersTable": the current table of pointer to each instruction handler.
37
38// Advance to the next instruction and updates interpreter state.
Sebastien Hertz8ece0502013-08-07 11:26:41 +020039#define ADVANCE(_offset) \
40 do { \
41 int32_t disp = static_cast<int32_t>(_offset); \
42 inst = inst->RelativeAt(disp); \
43 dex_pc = static_cast<uint32_t>(static_cast<int32_t>(dex_pc) + disp); \
44 shadow_frame.SetDexPC(dex_pc); \
Ian Rogerse94652f2014-12-02 11:13:19 -080045 TraceExecution(shadow_frame, inst, dex_pc); \
Sebastien Hertz3b588e02013-09-11 14:33:18 +020046 inst_data = inst->Fetch16(0); \
47 goto *currentHandlersTable[inst->Opcode(inst_data)]; \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020048 } while (false)
49
50#define HANDLE_PENDING_EXCEPTION() goto exception_pending_label
51
52#define POSSIBLY_HANDLE_PENDING_EXCEPTION(_is_exception_pending, _offset) \
53 do { \
54 if (UNLIKELY(_is_exception_pending)) { \
55 HANDLE_PENDING_EXCEPTION(); \
56 } else { \
57 ADVANCE(_offset); \
58 } \
59 } while (false)
60
Sebastien Hertzee1997a2013-09-19 14:47:09 +020061#define UPDATE_HANDLER_TABLE() \
Mathieu Chartier2cebb242015-04-21 16:50:40 -070062 currentHandlersTable = handlersTable[ \
63 Runtime::Current()->GetInstrumentation()->GetInterpreterHandlerTable()]
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +020064
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080065#define BACKWARD_BRANCH_INSTRUMENTATION(offset) \
66 do { \
67 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation(); \
68 instrumentation->BackwardBranch(self, shadow_frame.GetMethod(), offset); \
69 } while (false)
70
Sebastien Hertz8ece0502013-08-07 11:26:41 +020071#define UNREACHABLE_CODE_CHECK() \
72 do { \
73 if (kIsDebugBuild) { \
74 LOG(FATAL) << "We should not be here !"; \
Ian Rogerse94652f2014-12-02 11:13:19 -080075 UNREACHABLE(); \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020076 } \
77 } while (false)
78
79#define HANDLE_INSTRUCTION_START(opcode) op_##opcode: // NOLINT(whitespace/labels)
80#define HANDLE_INSTRUCTION_END() UNREACHABLE_CODE_CHECK()
81
Igor Murashkin158f35c2015-06-10 15:55:30 -070082// Use with instructions labeled with kExperimental flag:
83#define HANDLE_EXPERIMENTAL_INSTRUCTION_START(opcode) \
84 HANDLE_INSTRUCTION_START(opcode); \
85 DCHECK(inst->IsExperimental()); \
86 if (Runtime::Current()->AreExperimentalLambdasEnabled()) {
87#define HANDLE_EXPERIMENTAL_INSTRUCTION_END() \
88 } else { \
89 UnexpectedOpcode(inst, shadow_frame); \
90 } HANDLE_INSTRUCTION_END();
91
Andreas Gampe03ec9302015-08-27 17:41:47 -070092#define HANDLE_MONITOR_CHECKS() \
93 if (!shadow_frame.GetLockCountData(). \
94 CheckAllMonitorsReleasedOrThrow<do_assignability_check>(self)) { \
95 HANDLE_PENDING_EXCEPTION(); \
96 }
Igor Murashkin158f35c2015-06-10 15:55:30 -070097
Sebastien Hertzee1997a2013-09-19 14:47:09 +020098/**
99 * Interpreter based on computed goto tables.
100 *
101 * Each instruction is associated to a handler. This handler is responsible for executing the
102 * instruction and jump to the next instruction's handler.
103 * In order to limit the cost of instrumentation, we have two handler tables:
104 * - the "main" handler table: it contains handlers for normal execution of each instruction without
105 * handling of instrumentation.
106 * - the "alternative" handler table: it contains alternative handlers which first handle
107 * instrumentation before jumping to the corresponding "normal" instruction's handler.
108 *
109 * When instrumentation is active, the interpreter uses the "alternative" handler table. Otherwise
110 * it uses the "main" handler table.
111 *
112 * The current handler table is the handler table being used by the interpreter. It is updated:
113 * - on backward branch (goto, if and switch instructions)
114 * - after invoke
115 * - when an exception is thrown.
116 * This allows to support an attaching debugger to an already running application for instance.
117 *
118 * For a fast handler table update, handler tables are stored in an array of handler tables. Each
119 * handler table is represented by the InterpreterHandlerTable enum which allows to associate it
120 * to an index in this array of handler tables ((see Instrumentation::GetInterpreterHandlerTable).
121 *
122 * Here's the current layout of this array of handler tables:
123 *
124 * ---------------------+---------------+
125 * | NOP | (handler for NOP instruction)
126 * +---------------+
127 * "main" | MOVE | (handler for MOVE instruction)
128 * handler table +---------------+
129 * | ... |
130 * +---------------+
131 * | UNUSED_FF | (handler for UNUSED_FF instruction)
132 * ---------------------+---------------+
133 * | NOP | (alternative handler for NOP instruction)
134 * +---------------+
135 * "alternative" | MOVE | (alternative handler for MOVE instruction)
136 * handler table +---------------+
137 * | ... |
138 * +---------------+
139 * | UNUSED_FF | (alternative handler for UNUSED_FF instruction)
140 * ---------------------+---------------+
141 *
142 */
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100143template<bool do_access_check, bool transaction_active>
Ian Rogerse94652f2014-12-02 11:13:19 -0800144JValue ExecuteGotoImpl(Thread* self, const DexFile::CodeItem* code_item, ShadowFrame& shadow_frame,
145 JValue result_register) {
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200146 // Define handler tables:
147 // - The main handler table contains execution handlers for each instruction.
148 // - The alternative handler table contains prelude handlers which check for thread suspend and
149 // manage instrumentation before jumping to the execution handler.
150 static const void* const handlersTable[instrumentation::kNumHandlerTables][kNumPackedOpcodes] = {
151 {
152 // Main handler table.
153#define INSTRUCTION_HANDLER(o, code, n, f, r, i, a, v) &&op_##code,
154#include "dex_instruction_list.h"
155 DEX_INSTRUCTION_LIST(INSTRUCTION_HANDLER)
156#undef DEX_INSTRUCTION_LIST
157#undef INSTRUCTION_HANDLER
158 }, {
159 // Alternative handler table.
160#define INSTRUCTION_HANDLER(o, code, n, f, r, i, a, v) &&alt_op_##code,
161#include "dex_instruction_list.h"
162 DEX_INSTRUCTION_LIST(INSTRUCTION_HANDLER)
163#undef DEX_INSTRUCTION_LIST
164#undef INSTRUCTION_HANDLER
165 }
166 };
167
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800168 constexpr bool do_assignability_check = do_access_check;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200169 if (UNLIKELY(!shadow_frame.HasReferenceArray())) {
170 LOG(FATAL) << "Invalid shadow frame for interpreter use";
171 return JValue();
172 }
173 self->VerifyStack();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200174
175 uint32_t dex_pc = shadow_frame.GetDexPC();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200176 const Instruction* inst = Instruction::At(code_item->insns_ + dex_pc);
177 uint16_t inst_data;
178 const void* const* currentHandlersTable;
179 UPDATE_HANDLER_TABLE();
Sebastien Hertz270a0e12015-01-16 19:49:09 +0100180 if (LIKELY(dex_pc == 0)) { // We are entering the method as opposed to deoptimizing.
181 if (kIsDebugBuild) {
182 self->AssertNoPendingException();
183 }
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200184 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200185 if (UNLIKELY(instrumentation->HasMethodEntryListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200186 instrumentation->MethodEnterEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200187 shadow_frame.GetMethod(), 0);
188 }
189 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200190
Igor Murashkin6918bf12015-09-27 19:19:06 -0700191 std::unique_ptr<lambda::ClosureBuilder> lambda_closure_builder;
192 size_t lambda_captured_variable_index = 0;
193
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200194 // Jump to first instruction.
195 ADVANCE(0);
196 UNREACHABLE_CODE_CHECK();
197
198 HANDLE_INSTRUCTION_START(NOP)
199 ADVANCE(1);
200 HANDLE_INSTRUCTION_END();
201
202 HANDLE_INSTRUCTION_START(MOVE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200203 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
204 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200205 ADVANCE(1);
206 HANDLE_INSTRUCTION_END();
207
208 HANDLE_INSTRUCTION_START(MOVE_FROM16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200209 shadow_frame.SetVReg(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200210 shadow_frame.GetVReg(inst->VRegB_22x()));
211 ADVANCE(2);
212 HANDLE_INSTRUCTION_END();
213
214 HANDLE_INSTRUCTION_START(MOVE_16)
215 shadow_frame.SetVReg(inst->VRegA_32x(),
216 shadow_frame.GetVReg(inst->VRegB_32x()));
217 ADVANCE(3);
218 HANDLE_INSTRUCTION_END();
219
220 HANDLE_INSTRUCTION_START(MOVE_WIDE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200221 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
222 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200223 ADVANCE(1);
224 HANDLE_INSTRUCTION_END();
225
226 HANDLE_INSTRUCTION_START(MOVE_WIDE_FROM16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200227 shadow_frame.SetVRegLong(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200228 shadow_frame.GetVRegLong(inst->VRegB_22x()));
229 ADVANCE(2);
230 HANDLE_INSTRUCTION_END();
231
232 HANDLE_INSTRUCTION_START(MOVE_WIDE_16)
233 shadow_frame.SetVRegLong(inst->VRegA_32x(),
234 shadow_frame.GetVRegLong(inst->VRegB_32x()));
235 ADVANCE(3);
236 HANDLE_INSTRUCTION_END();
237
238 HANDLE_INSTRUCTION_START(MOVE_OBJECT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200239 shadow_frame.SetVRegReference(inst->VRegA_12x(inst_data),
240 shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200241 ADVANCE(1);
242 HANDLE_INSTRUCTION_END();
243
244 HANDLE_INSTRUCTION_START(MOVE_OBJECT_FROM16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200245 shadow_frame.SetVRegReference(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200246 shadow_frame.GetVRegReference(inst->VRegB_22x()));
247 ADVANCE(2);
248 HANDLE_INSTRUCTION_END();
249
250 HANDLE_INSTRUCTION_START(MOVE_OBJECT_16)
251 shadow_frame.SetVRegReference(inst->VRegA_32x(),
252 shadow_frame.GetVRegReference(inst->VRegB_32x()));
253 ADVANCE(3);
254 HANDLE_INSTRUCTION_END();
255
256 HANDLE_INSTRUCTION_START(MOVE_RESULT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200257 shadow_frame.SetVReg(inst->VRegA_11x(inst_data), result_register.GetI());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200258 ADVANCE(1);
259 HANDLE_INSTRUCTION_END();
260
261 HANDLE_INSTRUCTION_START(MOVE_RESULT_WIDE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200262 shadow_frame.SetVRegLong(inst->VRegA_11x(inst_data), result_register.GetJ());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200263 ADVANCE(1);
264 HANDLE_INSTRUCTION_END();
265
266 HANDLE_INSTRUCTION_START(MOVE_RESULT_OBJECT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200267 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), result_register.GetL());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200268 ADVANCE(1);
269 HANDLE_INSTRUCTION_END();
270
271 HANDLE_INSTRUCTION_START(MOVE_EXCEPTION) {
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000272 Throwable* exception = self->GetException();
Sebastien Hertz270a0e12015-01-16 19:49:09 +0100273 DCHECK(exception != nullptr) << "No pending exception on MOVE_EXCEPTION instruction";
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200274 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), exception);
Sebastien Hertz5c004902014-05-21 10:07:42 +0200275 self->ClearException();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200276 ADVANCE(1);
277 }
278 HANDLE_INSTRUCTION_END();
279
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700280 HANDLE_INSTRUCTION_START(RETURN_VOID_NO_BARRIER) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200281 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700282 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700283 HANDLE_MONITOR_CHECKS();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200284 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200285 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200286 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200287 shadow_frame.GetMethod(), dex_pc,
288 result);
289 }
290 return result;
291 }
292 HANDLE_INSTRUCTION_END();
293
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700294 HANDLE_INSTRUCTION_START(RETURN_VOID) {
Hans Boehm30359612014-05-21 17:46:23 -0700295 QuasiAtomic::ThreadFenceForConstructor();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200296 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700297 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700298 HANDLE_MONITOR_CHECKS();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200299 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200300 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200301 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200302 shadow_frame.GetMethod(), dex_pc,
303 result);
304 }
305 return result;
306 }
307 HANDLE_INSTRUCTION_END();
308
309 HANDLE_INSTRUCTION_START(RETURN) {
310 JValue result;
311 result.SetJ(0);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200312 result.SetI(shadow_frame.GetVReg(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700313 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700314 HANDLE_MONITOR_CHECKS();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200315 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200316 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200317 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200318 shadow_frame.GetMethod(), dex_pc,
319 result);
320 }
321 return result;
322 }
323 HANDLE_INSTRUCTION_END();
324
325 HANDLE_INSTRUCTION_START(RETURN_WIDE) {
326 JValue result;
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200327 result.SetJ(shadow_frame.GetVRegLong(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700328 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700329 HANDLE_MONITOR_CHECKS();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200330 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200331 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200332 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200333 shadow_frame.GetMethod(), dex_pc,
334 result);
335 }
336 return result;
337 }
338 HANDLE_INSTRUCTION_END();
339
340 HANDLE_INSTRUCTION_START(RETURN_OBJECT) {
341 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700342 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700343 HANDLE_MONITOR_CHECKS();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700344 const uint8_t vreg_index = inst->VRegA_11x(inst_data);
345 Object* obj_result = shadow_frame.GetVRegReference(vreg_index);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700346 if (do_assignability_check && obj_result != nullptr) {
Vladimir Marko05792b92015-08-03 11:56:49 +0100347 size_t pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
348 Class* return_type = shadow_frame.GetMethod()->GetReturnType(true /* resolve */,
349 pointer_size);
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700350 obj_result = shadow_frame.GetVRegReference(vreg_index);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700351 if (return_type == nullptr) {
Jeff Haoa3faaf42013-09-03 19:07:00 -0700352 // Return the pending exception.
353 HANDLE_PENDING_EXCEPTION();
354 }
355 if (!obj_result->VerifierInstanceOf(return_type)) {
356 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700357 std::string temp1, temp2;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000358 self->ThrowNewExceptionF("Ljava/lang/VirtualMachineError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700359 "Returning '%s' that is not instance of return type '%s'",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700360 obj_result->GetClass()->GetDescriptor(&temp1),
361 return_type->GetDescriptor(&temp2));
Jeff Haoa3faaf42013-09-03 19:07:00 -0700362 HANDLE_PENDING_EXCEPTION();
363 }
364 }
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700365 result.SetL(obj_result);
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200366 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200367 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200368 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200369 shadow_frame.GetMethod(), dex_pc,
370 result);
371 }
372 return result;
373 }
374 HANDLE_INSTRUCTION_END();
375
376 HANDLE_INSTRUCTION_START(CONST_4) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200377 uint32_t dst = inst->VRegA_11n(inst_data);
378 int32_t val = inst->VRegB_11n(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200379 shadow_frame.SetVReg(dst, val);
380 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700381 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200382 }
383 ADVANCE(1);
384 }
385 HANDLE_INSTRUCTION_END();
386
387 HANDLE_INSTRUCTION_START(CONST_16) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200388 uint32_t dst = inst->VRegA_21s(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200389 int32_t val = inst->VRegB_21s();
390 shadow_frame.SetVReg(dst, val);
391 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700392 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200393 }
394 ADVANCE(2);
395 }
396 HANDLE_INSTRUCTION_END();
397
398 HANDLE_INSTRUCTION_START(CONST) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200399 uint32_t dst = inst->VRegA_31i(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200400 int32_t val = inst->VRegB_31i();
401 shadow_frame.SetVReg(dst, val);
402 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700403 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200404 }
405 ADVANCE(3);
406 }
407 HANDLE_INSTRUCTION_END();
408
409 HANDLE_INSTRUCTION_START(CONST_HIGH16) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200410 uint32_t dst = inst->VRegA_21h(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200411 int32_t val = static_cast<int32_t>(inst->VRegB_21h() << 16);
412 shadow_frame.SetVReg(dst, val);
413 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700414 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200415 }
416 ADVANCE(2);
417 }
418 HANDLE_INSTRUCTION_END();
419
420 HANDLE_INSTRUCTION_START(CONST_WIDE_16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200421 shadow_frame.SetVRegLong(inst->VRegA_21s(inst_data), inst->VRegB_21s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200422 ADVANCE(2);
423 HANDLE_INSTRUCTION_END();
424
425 HANDLE_INSTRUCTION_START(CONST_WIDE_32)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200426 shadow_frame.SetVRegLong(inst->VRegA_31i(inst_data), inst->VRegB_31i());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200427 ADVANCE(3);
428 HANDLE_INSTRUCTION_END();
429
430 HANDLE_INSTRUCTION_START(CONST_WIDE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200431 shadow_frame.SetVRegLong(inst->VRegA_51l(inst_data), inst->VRegB_51l());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200432 ADVANCE(5);
433 HANDLE_INSTRUCTION_END();
434
435 HANDLE_INSTRUCTION_START(CONST_WIDE_HIGH16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200436 shadow_frame.SetVRegLong(inst->VRegA_21h(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200437 static_cast<uint64_t>(inst->VRegB_21h()) << 48);
438 ADVANCE(2);
439 HANDLE_INSTRUCTION_END();
440
441 HANDLE_INSTRUCTION_START(CONST_STRING) {
Ian Rogers6786a582014-10-28 12:49:06 -0700442 String* s = ResolveString(self, shadow_frame, inst->VRegB_21c());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700443 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200444 HANDLE_PENDING_EXCEPTION();
445 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200446 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200447 ADVANCE(2);
448 }
449 }
450 HANDLE_INSTRUCTION_END();
451
452 HANDLE_INSTRUCTION_START(CONST_STRING_JUMBO) {
Ian Rogers6786a582014-10-28 12:49:06 -0700453 String* s = ResolveString(self, shadow_frame, inst->VRegB_31c());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700454 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200455 HANDLE_PENDING_EXCEPTION();
456 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200457 shadow_frame.SetVRegReference(inst->VRegA_31c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200458 ADVANCE(3);
459 }
460 }
461 HANDLE_INSTRUCTION_END();
462
463 HANDLE_INSTRUCTION_START(CONST_CLASS) {
464 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
465 self, false, do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700466 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200467 HANDLE_PENDING_EXCEPTION();
468 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200469 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), c);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200470 ADVANCE(2);
471 }
472 }
473 HANDLE_INSTRUCTION_END();
474
475 HANDLE_INSTRUCTION_START(MONITOR_ENTER) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200476 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700477 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000478 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200479 HANDLE_PENDING_EXCEPTION();
480 } else {
Andreas Gampe03ec9302015-08-27 17:41:47 -0700481 DoMonitorEnter<do_access_check>(self, &shadow_frame, obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200482 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), 1);
483 }
484 }
485 HANDLE_INSTRUCTION_END();
486
487 HANDLE_INSTRUCTION_START(MONITOR_EXIT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200488 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700489 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000490 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200491 HANDLE_PENDING_EXCEPTION();
492 } else {
Andreas Gampe03ec9302015-08-27 17:41:47 -0700493 DoMonitorExit<do_access_check>(self, &shadow_frame, obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200494 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), 1);
495 }
496 }
497 HANDLE_INSTRUCTION_END();
498
499 HANDLE_INSTRUCTION_START(CHECK_CAST) {
500 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
501 self, false, do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700502 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200503 HANDLE_PENDING_EXCEPTION();
504 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200505 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_21c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700506 if (UNLIKELY(obj != nullptr && !obj->InstanceOf(c))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200507 ThrowClassCastException(c, obj->GetClass());
508 HANDLE_PENDING_EXCEPTION();
509 } else {
510 ADVANCE(2);
511 }
512 }
513 }
514 HANDLE_INSTRUCTION_END();
515
516 HANDLE_INSTRUCTION_START(INSTANCE_OF) {
517 Class* c = ResolveVerifyAndClinit(inst->VRegC_22c(), shadow_frame.GetMethod(),
518 self, false, do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700519 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200520 HANDLE_PENDING_EXCEPTION();
521 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200522 Object* obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700523 shadow_frame.SetVReg(inst->VRegA_22c(inst_data), (obj != nullptr && obj->InstanceOf(c)) ? 1 : 0);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200524 ADVANCE(2);
525 }
526 }
527 HANDLE_INSTRUCTION_END();
528
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700529 HANDLE_INSTRUCTION_START(ARRAY_LENGTH) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200530 Object* array = shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700531 if (UNLIKELY(array == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000532 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200533 HANDLE_PENDING_EXCEPTION();
534 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200535 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), array->AsArray()->GetLength());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200536 ADVANCE(1);
537 }
538 }
539 HANDLE_INSTRUCTION_END();
540
541 HANDLE_INSTRUCTION_START(NEW_INSTANCE) {
Jeff Hao848f70a2014-01-15 13:49:50 -0800542 Object* obj = nullptr;
543 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
544 self, false, do_access_check);
545 if (LIKELY(c != nullptr)) {
546 if (UNLIKELY(c->IsStringClass())) {
547 gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
548 mirror::SetStringCountVisitor visitor(0);
549 obj = String::Alloc<true>(self, 0, allocator_type, visitor);
550 } else {
551 obj = AllocObjectFromCode<do_access_check, true>(
552 inst->VRegB_21c(), shadow_frame.GetMethod(), self,
553 Runtime::Current()->GetHeap()->GetCurrentAllocator());
554 }
555 }
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700556 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200557 HANDLE_PENDING_EXCEPTION();
558 } else {
Sebastien Hertz4e99b3d2014-06-24 14:35:40 +0200559 obj->GetClass()->AssertInitializedOrInitializingInThread(self);
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700560 // Don't allow finalizable objects to be allocated during a transaction since these can't be
561 // finalized without a started runtime.
562 if (transaction_active && obj->GetClass()->IsFinalizable()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +0200563 AbortTransactionF(self, "Allocating finalizable object in transaction: %s",
564 PrettyTypeOf(obj).c_str());
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700565 HANDLE_PENDING_EXCEPTION();
566 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200567 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200568 ADVANCE(2);
569 }
570 }
571 HANDLE_INSTRUCTION_END();
572
573 HANDLE_INSTRUCTION_START(NEW_ARRAY) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200574 int32_t length = shadow_frame.GetVReg(inst->VRegB_22c(inst_data));
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800575 Object* obj = AllocArrayFromCode<do_access_check, true>(
Andreas Gampe1cc7dba2014-12-17 18:43:01 -0800576 inst->VRegC_22c(), length, shadow_frame.GetMethod(), self,
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800577 Runtime::Current()->GetHeap()->GetCurrentAllocator());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700578 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200579 HANDLE_PENDING_EXCEPTION();
580 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200581 shadow_frame.SetVRegReference(inst->VRegA_22c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200582 ADVANCE(2);
583 }
584 }
585 HANDLE_INSTRUCTION_END();
586
587 HANDLE_INSTRUCTION_START(FILLED_NEW_ARRAY) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100588 bool success =
589 DoFilledNewArray<false, do_access_check, transaction_active>(inst, shadow_frame,
590 self, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200591 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
592 }
593 HANDLE_INSTRUCTION_END();
594
595 HANDLE_INSTRUCTION_START(FILLED_NEW_ARRAY_RANGE) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100596 bool success =
597 DoFilledNewArray<true, do_access_check, transaction_active>(inst, shadow_frame,
598 self, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200599 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
600 }
601 HANDLE_INSTRUCTION_END();
602
603 HANDLE_INSTRUCTION_START(FILL_ARRAY_DATA) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200604 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_31t(inst_data));
Ian Rogers832336b2014-10-08 15:35:22 -0700605 const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t();
606 const Instruction::ArrayDataPayload* payload =
607 reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr);
608 bool success = FillArrayData(obj, payload);
609 if (transaction_active && success) {
610 RecordArrayElementsInTransaction(obj->AsArray(), payload->element_count);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200611 }
Ian Rogers832336b2014-10-08 15:35:22 -0700612 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200613 }
614 HANDLE_INSTRUCTION_END();
615
616 HANDLE_INSTRUCTION_START(THROW) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200617 Object* exception = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700618 if (UNLIKELY(exception == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000619 ThrowNullPointerException("throw with null exception");
Jeff Haoa3faaf42013-09-03 19:07:00 -0700620 } else if (do_assignability_check && !exception->GetClass()->IsThrowableClass()) {
621 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700622 std::string temp;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000623 self->ThrowNewExceptionF("Ljava/lang/VirtualMachineError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700624 "Throwing '%s' that is not instance of Throwable",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700625 exception->GetClass()->GetDescriptor(&temp));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200626 } else {
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000627 self->SetException(exception->AsThrowable());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200628 }
629 HANDLE_PENDING_EXCEPTION();
630 }
631 HANDLE_INSTRUCTION_END();
632
633 HANDLE_INSTRUCTION_START(GOTO) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200634 int8_t offset = inst->VRegA_10t(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200635 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800636 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200637 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700638 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200639 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200640 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200641 }
642 ADVANCE(offset);
643 }
644 HANDLE_INSTRUCTION_END();
645
646 HANDLE_INSTRUCTION_START(GOTO_16) {
647 int16_t offset = inst->VRegA_20t();
648 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800649 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200650 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700651 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200652 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200653 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200654 }
655 ADVANCE(offset);
656 }
657 HANDLE_INSTRUCTION_END();
658
659 HANDLE_INSTRUCTION_START(GOTO_32) {
660 int32_t offset = inst->VRegA_30t();
661 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800662 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200663 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700664 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200665 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200666 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200667 }
668 ADVANCE(offset);
669 }
670 HANDLE_INSTRUCTION_END();
671
672 HANDLE_INSTRUCTION_START(PACKED_SWITCH) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200673 int32_t offset = DoPackedSwitch(inst, shadow_frame, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200674 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800675 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200676 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700677 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200678 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200679 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200680 }
681 ADVANCE(offset);
682 }
683 HANDLE_INSTRUCTION_END();
684
685 HANDLE_INSTRUCTION_START(SPARSE_SWITCH) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200686 int32_t offset = DoSparseSwitch(inst, shadow_frame, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200687 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800688 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200689 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700690 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200691 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200692 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200693 }
694 ADVANCE(offset);
695 }
696 HANDLE_INSTRUCTION_END();
697
Ian Rogers647b1a82014-10-10 11:02:11 -0700698#if defined(__clang__)
699#pragma clang diagnostic push
700#pragma clang diagnostic ignored "-Wfloat-equal"
701#endif
702
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200703 HANDLE_INSTRUCTION_START(CMPL_FLOAT) {
704 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
705 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
706 int32_t result;
707 if (val1 > val2) {
708 result = 1;
709 } else if (val1 == val2) {
710 result = 0;
711 } else {
712 result = -1;
713 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200714 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200715 ADVANCE(2);
716 }
717 HANDLE_INSTRUCTION_END();
718
719 HANDLE_INSTRUCTION_START(CMPG_FLOAT) {
720 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
721 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
722 int32_t result;
723 if (val1 < val2) {
724 result = -1;
725 } else if (val1 == val2) {
726 result = 0;
727 } else {
728 result = 1;
729 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200730 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200731 ADVANCE(2);
732 }
733 HANDLE_INSTRUCTION_END();
734
735 HANDLE_INSTRUCTION_START(CMPL_DOUBLE) {
736 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
737 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
738 int32_t result;
739 if (val1 > val2) {
740 result = 1;
741 } else if (val1 == val2) {
742 result = 0;
743 } else {
744 result = -1;
745 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200746 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200747 ADVANCE(2);
748 }
749 HANDLE_INSTRUCTION_END();
750
751 HANDLE_INSTRUCTION_START(CMPG_DOUBLE) {
752 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
753 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
754 int32_t result;
755 if (val1 < val2) {
756 result = -1;
757 } else if (val1 == val2) {
758 result = 0;
759 } else {
760 result = 1;
761 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200762 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200763 ADVANCE(2);
764 }
765 HANDLE_INSTRUCTION_END();
766
Ian Rogers647b1a82014-10-10 11:02:11 -0700767#if defined(__clang__)
768#pragma clang diagnostic pop
769#endif
770
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200771 HANDLE_INSTRUCTION_START(CMP_LONG) {
772 int64_t val1 = shadow_frame.GetVRegLong(inst->VRegB_23x());
773 int64_t val2 = shadow_frame.GetVRegLong(inst->VRegC_23x());
774 int32_t result;
775 if (val1 > val2) {
776 result = 1;
777 } else if (val1 == val2) {
778 result = 0;
779 } else {
780 result = -1;
781 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200782 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200783 ADVANCE(2);
784 }
785 HANDLE_INSTRUCTION_END();
786
787 HANDLE_INSTRUCTION_START(IF_EQ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200788 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) == shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200789 int16_t offset = inst->VRegC_22t();
790 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800791 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200792 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700793 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200794 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200795 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200796 }
797 ADVANCE(offset);
798 } else {
799 ADVANCE(2);
800 }
801 }
802 HANDLE_INSTRUCTION_END();
803
804 HANDLE_INSTRUCTION_START(IF_NE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700805 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) !=
806 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200807 int16_t offset = inst->VRegC_22t();
808 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800809 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200810 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700811 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200812 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200813 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200814 }
815 ADVANCE(offset);
816 } else {
817 ADVANCE(2);
818 }
819 }
820 HANDLE_INSTRUCTION_END();
821
822 HANDLE_INSTRUCTION_START(IF_LT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700823 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <
824 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200825 int16_t offset = inst->VRegC_22t();
826 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800827 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200828 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700829 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200830 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200831 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200832 }
833 ADVANCE(offset);
834 } else {
835 ADVANCE(2);
836 }
837 }
838 HANDLE_INSTRUCTION_END();
839
840 HANDLE_INSTRUCTION_START(IF_GE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700841 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >=
842 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200843 int16_t offset = inst->VRegC_22t();
844 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800845 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200846 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700847 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200848 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200849 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200850 }
851 ADVANCE(offset);
852 } else {
853 ADVANCE(2);
854 }
855 }
856 HANDLE_INSTRUCTION_END();
857
858 HANDLE_INSTRUCTION_START(IF_GT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700859 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >
860 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200861 int16_t offset = inst->VRegC_22t();
862 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800863 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200864 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700865 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200866 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200867 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200868 }
869 ADVANCE(offset);
870 } else {
871 ADVANCE(2);
872 }
873 }
874 HANDLE_INSTRUCTION_END();
875
876 HANDLE_INSTRUCTION_START(IF_LE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700877 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <=
878 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200879 int16_t offset = inst->VRegC_22t();
880 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800881 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200882 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700883 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200884 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200885 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200886 }
887 ADVANCE(offset);
888 } else {
889 ADVANCE(2);
890 }
891 }
892 HANDLE_INSTRUCTION_END();
893
894 HANDLE_INSTRUCTION_START(IF_EQZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200895 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) == 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200896 int16_t offset = inst->VRegB_21t();
897 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800898 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200899 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700900 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200901 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200902 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200903 }
904 ADVANCE(offset);
905 } else {
906 ADVANCE(2);
907 }
908 }
909 HANDLE_INSTRUCTION_END();
910
911 HANDLE_INSTRUCTION_START(IF_NEZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200912 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) != 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200913 int16_t offset = inst->VRegB_21t();
914 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800915 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200916 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700917 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200918 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200919 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200920 }
921 ADVANCE(offset);
922 } else {
923 ADVANCE(2);
924 }
925 }
926 HANDLE_INSTRUCTION_END();
927
928 HANDLE_INSTRUCTION_START(IF_LTZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200929 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) < 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200930 int16_t offset = inst->VRegB_21t();
931 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800932 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200933 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700934 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200935 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200936 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200937 }
938 ADVANCE(offset);
939 } else {
940 ADVANCE(2);
941 }
942 }
943 HANDLE_INSTRUCTION_END();
944
945 HANDLE_INSTRUCTION_START(IF_GEZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200946 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) >= 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200947 int16_t offset = inst->VRegB_21t();
948 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800949 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200950 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700951 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200952 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200953 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200954 }
955 ADVANCE(offset);
956 } else {
957 ADVANCE(2);
958 }
959 }
960 HANDLE_INSTRUCTION_END();
961
962 HANDLE_INSTRUCTION_START(IF_GTZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200963 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) > 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200964 int16_t offset = inst->VRegB_21t();
965 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800966 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200967 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700968 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200969 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200970 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200971 }
972 ADVANCE(offset);
973 } else {
974 ADVANCE(2);
975 }
976 }
977 HANDLE_INSTRUCTION_END();
978
979 HANDLE_INSTRUCTION_START(IF_LEZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200980 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) <= 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200981 int16_t offset = inst->VRegB_21t();
982 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800983 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200984 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700985 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200986 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200987 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200988 }
989 ADVANCE(offset);
990 } else {
991 ADVANCE(2);
992 }
993 }
994 HANDLE_INSTRUCTION_END();
995
996 HANDLE_INSTRUCTION_START(AGET_BOOLEAN) {
997 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700998 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000999 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001000 HANDLE_PENDING_EXCEPTION();
1001 } else {
1002 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1003 BooleanArray* array = a->AsBooleanArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001004 if (LIKELY(array->CheckIsValidIndex(index))) {
1005 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001006 ADVANCE(2);
1007 } else {
1008 HANDLE_PENDING_EXCEPTION();
1009 }
1010 }
1011 }
1012 HANDLE_INSTRUCTION_END();
1013
1014 HANDLE_INSTRUCTION_START(AGET_BYTE) {
1015 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001016 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001017 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001018 HANDLE_PENDING_EXCEPTION();
1019 } else {
1020 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1021 ByteArray* array = a->AsByteArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001022 if (LIKELY(array->CheckIsValidIndex(index))) {
1023 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001024 ADVANCE(2);
1025 } else {
1026 HANDLE_PENDING_EXCEPTION();
1027 }
1028 }
1029 }
1030 HANDLE_INSTRUCTION_END();
1031
1032 HANDLE_INSTRUCTION_START(AGET_CHAR) {
1033 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001034 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001035 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001036 HANDLE_PENDING_EXCEPTION();
1037 } else {
1038 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1039 CharArray* array = a->AsCharArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001040 if (LIKELY(array->CheckIsValidIndex(index))) {
1041 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001042 ADVANCE(2);
1043 } else {
1044 HANDLE_PENDING_EXCEPTION();
1045 }
1046 }
1047 }
1048 HANDLE_INSTRUCTION_END();
1049
1050 HANDLE_INSTRUCTION_START(AGET_SHORT) {
1051 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001052 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001053 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001054 HANDLE_PENDING_EXCEPTION();
1055 } else {
1056 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1057 ShortArray* array = a->AsShortArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001058 if (LIKELY(array->CheckIsValidIndex(index))) {
1059 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001060 ADVANCE(2);
1061 } else {
1062 HANDLE_PENDING_EXCEPTION();
1063 }
1064 }
1065 }
1066 HANDLE_INSTRUCTION_END();
1067
1068 HANDLE_INSTRUCTION_START(AGET) {
1069 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001070 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001071 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001072 HANDLE_PENDING_EXCEPTION();
1073 } else {
1074 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001075 DCHECK(a->IsIntArray() || a->IsFloatArray()) << PrettyTypeOf(a);
1076 auto* array = down_cast<IntArray*>(a);
Sebastien Hertzabff6432014-01-27 18:01:39 +01001077 if (LIKELY(array->CheckIsValidIndex(index))) {
1078 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001079 ADVANCE(2);
1080 } else {
1081 HANDLE_PENDING_EXCEPTION();
1082 }
1083 }
1084 }
1085 HANDLE_INSTRUCTION_END();
1086
1087 HANDLE_INSTRUCTION_START(AGET_WIDE) {
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 } else {
1093 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001094 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << PrettyTypeOf(a);
1095 auto* array = down_cast<LongArray*>(a);
Sebastien Hertzabff6432014-01-27 18:01:39 +01001096 if (LIKELY(array->CheckIsValidIndex(index))) {
1097 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001098 ADVANCE(2);
1099 } else {
1100 HANDLE_PENDING_EXCEPTION();
1101 }
1102 }
1103 }
1104 HANDLE_INSTRUCTION_END();
1105
1106 HANDLE_INSTRUCTION_START(AGET_OBJECT) {
1107 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001108 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001109 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001110 HANDLE_PENDING_EXCEPTION();
1111 } else {
1112 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1113 ObjectArray<Object>* array = a->AsObjectArray<Object>();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001114 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001115 shadow_frame.SetVRegReference(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001116 ADVANCE(2);
1117 } else {
1118 HANDLE_PENDING_EXCEPTION();
1119 }
1120 }
1121 }
1122 HANDLE_INSTRUCTION_END();
1123
1124 HANDLE_INSTRUCTION_START(APUT_BOOLEAN) {
1125 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001126 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001127 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001128 HANDLE_PENDING_EXCEPTION();
1129 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001130 uint8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001131 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1132 BooleanArray* array = a->AsBooleanArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001133 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001134 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001135 ADVANCE(2);
1136 } else {
1137 HANDLE_PENDING_EXCEPTION();
1138 }
1139 }
1140 }
1141 HANDLE_INSTRUCTION_END();
1142
1143 HANDLE_INSTRUCTION_START(APUT_BYTE) {
1144 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001145 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001146 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001147 HANDLE_PENDING_EXCEPTION();
1148 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001149 int8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001150 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1151 ByteArray* array = a->AsByteArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001152 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001153 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001154 ADVANCE(2);
1155 } else {
1156 HANDLE_PENDING_EXCEPTION();
1157 }
1158 }
1159 }
1160 HANDLE_INSTRUCTION_END();
1161
1162 HANDLE_INSTRUCTION_START(APUT_CHAR) {
1163 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001164 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001165 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001166 HANDLE_PENDING_EXCEPTION();
1167 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001168 uint16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001169 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1170 CharArray* array = a->AsCharArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001171 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001172 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001173 ADVANCE(2);
1174 } else {
1175 HANDLE_PENDING_EXCEPTION();
1176 }
1177 }
1178 }
1179 HANDLE_INSTRUCTION_END();
1180
1181 HANDLE_INSTRUCTION_START(APUT_SHORT) {
1182 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001183 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001184 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001185 HANDLE_PENDING_EXCEPTION();
1186 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001187 int16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001188 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1189 ShortArray* array = a->AsShortArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001190 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001191 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001192 ADVANCE(2);
1193 } else {
1194 HANDLE_PENDING_EXCEPTION();
1195 }
1196 }
1197 }
1198 HANDLE_INSTRUCTION_END();
1199
1200 HANDLE_INSTRUCTION_START(APUT) {
1201 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001202 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001203 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001204 HANDLE_PENDING_EXCEPTION();
1205 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001206 int32_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001207 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001208 DCHECK(a->IsIntArray() || a->IsFloatArray()) << PrettyTypeOf(a);
1209 auto* array = down_cast<IntArray*>(a);
Sebastien Hertzabff6432014-01-27 18:01:39 +01001210 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001211 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001212 ADVANCE(2);
1213 } else {
1214 HANDLE_PENDING_EXCEPTION();
1215 }
1216 }
1217 }
1218 HANDLE_INSTRUCTION_END();
1219
1220 HANDLE_INSTRUCTION_START(APUT_WIDE) {
1221 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001222 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001223 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001224 HANDLE_PENDING_EXCEPTION();
1225 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001226 int64_t val = shadow_frame.GetVRegLong(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001227 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001228 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << PrettyTypeOf(a);
1229 auto* array = down_cast<LongArray*>(a);
Sebastien Hertzabff6432014-01-27 18:01:39 +01001230 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001231 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001232 ADVANCE(2);
1233 } else {
1234 HANDLE_PENDING_EXCEPTION();
1235 }
1236 }
1237 }
1238 HANDLE_INSTRUCTION_END();
1239
1240 HANDLE_INSTRUCTION_START(APUT_OBJECT) {
1241 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001242 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001243 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001244 HANDLE_PENDING_EXCEPTION();
1245 } else {
1246 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001247 Object* val = shadow_frame.GetVRegReference(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001248 ObjectArray<Object>* array = a->AsObjectArray<Object>();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001249 if (LIKELY(array->CheckIsValidIndex(index) && array->CheckAssignable(val))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001250 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001251 ADVANCE(2);
1252 } else {
1253 HANDLE_PENDING_EXCEPTION();
1254 }
1255 }
1256 }
1257 HANDLE_INSTRUCTION_END();
1258
1259 HANDLE_INSTRUCTION_START(IGET_BOOLEAN) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001260 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimBoolean, do_access_check>(
1261 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001262 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1263 }
1264 HANDLE_INSTRUCTION_END();
1265
1266 HANDLE_INSTRUCTION_START(IGET_BYTE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001267 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimByte, do_access_check>(
1268 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001269 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1270 }
1271 HANDLE_INSTRUCTION_END();
1272
1273 HANDLE_INSTRUCTION_START(IGET_CHAR) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001274 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimChar, do_access_check>(
1275 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001276 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1277 }
1278 HANDLE_INSTRUCTION_END();
1279
1280 HANDLE_INSTRUCTION_START(IGET_SHORT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001281 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimShort, do_access_check>(
1282 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001283 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1284 }
1285 HANDLE_INSTRUCTION_END();
1286
1287 HANDLE_INSTRUCTION_START(IGET) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001288 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimInt, do_access_check>(
1289 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001290 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1291 }
1292 HANDLE_INSTRUCTION_END();
1293
1294 HANDLE_INSTRUCTION_START(IGET_WIDE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001295 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimLong, do_access_check>(
1296 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001297 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1298 }
1299 HANDLE_INSTRUCTION_END();
1300
1301 HANDLE_INSTRUCTION_START(IGET_OBJECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001302 bool success = DoFieldGet<InstanceObjectRead, Primitive::kPrimNot, do_access_check>(
1303 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001304 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1305 }
1306 HANDLE_INSTRUCTION_END();
1307
1308 HANDLE_INSTRUCTION_START(IGET_QUICK) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001309 bool success = DoIGetQuick<Primitive::kPrimInt>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001310 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1311 }
1312 HANDLE_INSTRUCTION_END();
1313
Mathieu Chartierffc605c2014-12-10 10:35:44 -08001314 HANDLE_INSTRUCTION_START(IGET_BOOLEAN_QUICK) {
1315 bool success = DoIGetQuick<Primitive::kPrimBoolean>(shadow_frame, inst, inst_data);
1316 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1317 }
1318 HANDLE_INSTRUCTION_END();
1319
1320 HANDLE_INSTRUCTION_START(IGET_BYTE_QUICK) {
1321 bool success = DoIGetQuick<Primitive::kPrimByte>(shadow_frame, inst, inst_data);
1322 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1323 }
1324 HANDLE_INSTRUCTION_END();
1325
1326 HANDLE_INSTRUCTION_START(IGET_CHAR_QUICK) {
1327 bool success = DoIGetQuick<Primitive::kPrimChar>(shadow_frame, inst, inst_data);
1328 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1329 }
1330 HANDLE_INSTRUCTION_END();
1331
1332 HANDLE_INSTRUCTION_START(IGET_SHORT_QUICK) {
1333 bool success = DoIGetQuick<Primitive::kPrimShort>(shadow_frame, inst, inst_data);
1334 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1335 }
1336 HANDLE_INSTRUCTION_END();
1337
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001338 HANDLE_INSTRUCTION_START(IGET_WIDE_QUICK) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001339 bool success = DoIGetQuick<Primitive::kPrimLong>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001340 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1341 }
1342 HANDLE_INSTRUCTION_END();
1343
1344 HANDLE_INSTRUCTION_START(IGET_OBJECT_QUICK) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001345 bool success = DoIGetQuick<Primitive::kPrimNot>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001346 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1347 }
1348 HANDLE_INSTRUCTION_END();
1349
1350 HANDLE_INSTRUCTION_START(SGET_BOOLEAN) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001351 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimBoolean, do_access_check>(
1352 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001353 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1354 }
1355 HANDLE_INSTRUCTION_END();
1356
1357 HANDLE_INSTRUCTION_START(SGET_BYTE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001358 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimByte, do_access_check>(
1359 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001360 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1361 }
1362 HANDLE_INSTRUCTION_END();
1363
1364 HANDLE_INSTRUCTION_START(SGET_CHAR) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001365 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimChar, do_access_check>(
1366 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001367 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1368 }
1369 HANDLE_INSTRUCTION_END();
1370
1371 HANDLE_INSTRUCTION_START(SGET_SHORT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001372 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimShort, do_access_check>(
1373 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001374 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1375 }
1376 HANDLE_INSTRUCTION_END();
1377
1378 HANDLE_INSTRUCTION_START(SGET) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001379 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimInt, do_access_check>(
1380 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001381 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1382 }
1383 HANDLE_INSTRUCTION_END();
1384
1385 HANDLE_INSTRUCTION_START(SGET_WIDE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001386 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimLong, do_access_check>(
1387 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001388 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1389 }
1390 HANDLE_INSTRUCTION_END();
1391
1392 HANDLE_INSTRUCTION_START(SGET_OBJECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001393 bool success = DoFieldGet<StaticObjectRead, Primitive::kPrimNot, do_access_check>(
1394 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001395 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1396 }
1397 HANDLE_INSTRUCTION_END();
1398
1399 HANDLE_INSTRUCTION_START(IPUT_BOOLEAN) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001400 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1401 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001402 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1403 }
1404 HANDLE_INSTRUCTION_END();
1405
1406 HANDLE_INSTRUCTION_START(IPUT_BYTE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001407 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimByte, do_access_check,
1408 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001409 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1410 }
1411 HANDLE_INSTRUCTION_END();
1412
1413 HANDLE_INSTRUCTION_START(IPUT_CHAR) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001414 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimChar, do_access_check,
1415 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001416 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1417 }
1418 HANDLE_INSTRUCTION_END();
1419
1420 HANDLE_INSTRUCTION_START(IPUT_SHORT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001421 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimShort, do_access_check,
1422 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001423 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1424 }
1425 HANDLE_INSTRUCTION_END();
1426
1427 HANDLE_INSTRUCTION_START(IPUT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001428 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimInt, do_access_check,
1429 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001430 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1431 }
1432 HANDLE_INSTRUCTION_END();
1433
1434 HANDLE_INSTRUCTION_START(IPUT_WIDE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001435 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimLong, do_access_check,
1436 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001437 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1438 }
1439 HANDLE_INSTRUCTION_END();
1440
1441 HANDLE_INSTRUCTION_START(IPUT_OBJECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001442 bool success = DoFieldPut<InstanceObjectWrite, Primitive::kPrimNot, do_access_check,
1443 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001444 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1445 }
1446 HANDLE_INSTRUCTION_END();
1447
1448 HANDLE_INSTRUCTION_START(IPUT_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001449 bool success = DoIPutQuick<Primitive::kPrimInt, transaction_active>(
1450 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001451 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1452 }
1453 HANDLE_INSTRUCTION_END();
1454
Fred Shih37f05ef2014-07-16 18:38:08 -07001455 HANDLE_INSTRUCTION_START(IPUT_BOOLEAN_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001456 bool success = DoIPutQuick<Primitive::kPrimBoolean, transaction_active>(
1457 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001458 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1459 }
1460 HANDLE_INSTRUCTION_END();
1461
1462 HANDLE_INSTRUCTION_START(IPUT_BYTE_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001463 bool success = DoIPutQuick<Primitive::kPrimByte, transaction_active>(
1464 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001465 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1466 }
1467 HANDLE_INSTRUCTION_END();
1468
1469 HANDLE_INSTRUCTION_START(IPUT_CHAR_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001470 bool success = DoIPutQuick<Primitive::kPrimChar, transaction_active>(
1471 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001472 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1473 }
1474 HANDLE_INSTRUCTION_END();
1475
1476 HANDLE_INSTRUCTION_START(IPUT_SHORT_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001477 bool success = DoIPutQuick<Primitive::kPrimShort, transaction_active>(
1478 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001479 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1480 }
1481 HANDLE_INSTRUCTION_END();
1482
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001483 HANDLE_INSTRUCTION_START(IPUT_WIDE_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001484 bool success = DoIPutQuick<Primitive::kPrimLong, transaction_active>(
1485 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001486 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1487 }
1488 HANDLE_INSTRUCTION_END();
1489
1490 HANDLE_INSTRUCTION_START(IPUT_OBJECT_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001491 bool success = DoIPutQuick<Primitive::kPrimNot, transaction_active>(
1492 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001493 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1494 }
1495 HANDLE_INSTRUCTION_END();
1496
1497 HANDLE_INSTRUCTION_START(SPUT_BOOLEAN) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001498 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1499 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001500 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1501 }
1502 HANDLE_INSTRUCTION_END();
1503
1504 HANDLE_INSTRUCTION_START(SPUT_BYTE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001505 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimByte, do_access_check,
1506 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001507 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1508 }
1509 HANDLE_INSTRUCTION_END();
1510
1511 HANDLE_INSTRUCTION_START(SPUT_CHAR) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001512 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimChar, do_access_check,
1513 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001514 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1515 }
1516 HANDLE_INSTRUCTION_END();
1517
1518 HANDLE_INSTRUCTION_START(SPUT_SHORT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001519 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimShort, do_access_check,
1520 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001521 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1522 }
1523 HANDLE_INSTRUCTION_END();
1524
1525 HANDLE_INSTRUCTION_START(SPUT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001526 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimInt, do_access_check,
1527 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001528 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1529 }
1530 HANDLE_INSTRUCTION_END();
1531
1532 HANDLE_INSTRUCTION_START(SPUT_WIDE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001533 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimLong, do_access_check,
1534 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001535 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1536 }
1537 HANDLE_INSTRUCTION_END();
1538
1539 HANDLE_INSTRUCTION_START(SPUT_OBJECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001540 bool success = DoFieldPut<StaticObjectWrite, Primitive::kPrimNot, do_access_check,
1541 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001542 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1543 }
1544 HANDLE_INSTRUCTION_END();
1545
1546 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001547 bool success = DoInvoke<kVirtual, false, do_access_check>(
1548 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001549 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001550 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1551 }
1552 HANDLE_INSTRUCTION_END();
1553
1554 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001555 bool success = DoInvoke<kVirtual, true, do_access_check>(
1556 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001557 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001558 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1559 }
1560 HANDLE_INSTRUCTION_END();
1561
1562 HANDLE_INSTRUCTION_START(INVOKE_SUPER) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001563 bool success = DoInvoke<kSuper, false, do_access_check>(
1564 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001565 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001566 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1567 }
1568 HANDLE_INSTRUCTION_END();
1569
1570 HANDLE_INSTRUCTION_START(INVOKE_SUPER_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001571 bool success = DoInvoke<kSuper, true, do_access_check>(
1572 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001573 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001574 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1575 }
1576 HANDLE_INSTRUCTION_END();
1577
1578 HANDLE_INSTRUCTION_START(INVOKE_DIRECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001579 bool success = DoInvoke<kDirect, false, do_access_check>(
1580 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001581 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001582 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1583 }
1584 HANDLE_INSTRUCTION_END();
1585
1586 HANDLE_INSTRUCTION_START(INVOKE_DIRECT_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001587 bool success = DoInvoke<kDirect, true, do_access_check>(
1588 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001589 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001590 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1591 }
1592 HANDLE_INSTRUCTION_END();
1593
1594 HANDLE_INSTRUCTION_START(INVOKE_INTERFACE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001595 bool success = DoInvoke<kInterface, false, do_access_check>(
1596 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001597 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001598 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1599 }
1600 HANDLE_INSTRUCTION_END();
1601
1602 HANDLE_INSTRUCTION_START(INVOKE_INTERFACE_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001603 bool success = DoInvoke<kInterface, true, do_access_check>(
1604 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001605 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001606 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1607 }
1608 HANDLE_INSTRUCTION_END();
1609
1610 HANDLE_INSTRUCTION_START(INVOKE_STATIC) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001611 bool success = DoInvoke<kStatic, false, do_access_check>(
1612 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001613 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001614 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1615 }
1616 HANDLE_INSTRUCTION_END();
1617
1618 HANDLE_INSTRUCTION_START(INVOKE_STATIC_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001619 bool success = DoInvoke<kStatic, true, do_access_check>(
1620 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001621 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001622 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1623 }
1624 HANDLE_INSTRUCTION_END();
1625
1626 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001627 bool success = DoInvokeVirtualQuick<false>(
1628 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001629 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001630 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1631 }
1632 HANDLE_INSTRUCTION_END();
1633
1634 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_RANGE_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001635 bool success = DoInvokeVirtualQuick<true>(
1636 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001637 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001638 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1639 }
1640 HANDLE_INSTRUCTION_END();
1641
Igor Murashkin158f35c2015-06-10 15:55:30 -07001642 HANDLE_EXPERIMENTAL_INSTRUCTION_START(INVOKE_LAMBDA) {
1643 bool success = DoInvokeLambda<do_access_check>(self, shadow_frame, inst, inst_data,
1644 &result_register);
1645 UPDATE_HANDLER_TABLE();
1646 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1647 }
1648 HANDLE_EXPERIMENTAL_INSTRUCTION_END();
1649
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001650 HANDLE_INSTRUCTION_START(NEG_INT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001651 shadow_frame.SetVReg(
1652 inst->VRegA_12x(inst_data), -shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001653 ADVANCE(1);
1654 HANDLE_INSTRUCTION_END();
1655
1656 HANDLE_INSTRUCTION_START(NOT_INT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001657 shadow_frame.SetVReg(
1658 inst->VRegA_12x(inst_data), ~shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001659 ADVANCE(1);
1660 HANDLE_INSTRUCTION_END();
1661
1662 HANDLE_INSTRUCTION_START(NEG_LONG)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001663 shadow_frame.SetVRegLong(
1664 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001665 ADVANCE(1);
1666 HANDLE_INSTRUCTION_END();
1667
1668 HANDLE_INSTRUCTION_START(NOT_LONG)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001669 shadow_frame.SetVRegLong(
1670 inst->VRegA_12x(inst_data), ~shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001671 ADVANCE(1);
1672 HANDLE_INSTRUCTION_END();
1673
1674 HANDLE_INSTRUCTION_START(NEG_FLOAT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001675 shadow_frame.SetVRegFloat(
1676 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001677 ADVANCE(1);
1678 HANDLE_INSTRUCTION_END();
1679
1680 HANDLE_INSTRUCTION_START(NEG_DOUBLE)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001681 shadow_frame.SetVRegDouble(
1682 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001683 ADVANCE(1);
1684 HANDLE_INSTRUCTION_END();
1685
1686 HANDLE_INSTRUCTION_START(INT_TO_LONG)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001687 shadow_frame.SetVRegLong(
1688 inst->VRegA_12x(inst_data), shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001689 ADVANCE(1);
1690 HANDLE_INSTRUCTION_END();
1691
1692 HANDLE_INSTRUCTION_START(INT_TO_FLOAT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001693 shadow_frame.SetVRegFloat(
1694 inst->VRegA_12x(inst_data), shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001695 ADVANCE(1);
1696 HANDLE_INSTRUCTION_END();
1697
1698 HANDLE_INSTRUCTION_START(INT_TO_DOUBLE)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001699 shadow_frame.SetVRegDouble(
1700 inst->VRegA_12x(inst_data), shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001701 ADVANCE(1);
1702 HANDLE_INSTRUCTION_END();
1703
1704 HANDLE_INSTRUCTION_START(LONG_TO_INT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001705 shadow_frame.SetVReg(
1706 inst->VRegA_12x(inst_data), shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001707 ADVANCE(1);
1708 HANDLE_INSTRUCTION_END();
1709
1710 HANDLE_INSTRUCTION_START(LONG_TO_FLOAT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001711 shadow_frame.SetVRegFloat(
1712 inst->VRegA_12x(inst_data), shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001713 ADVANCE(1);
1714 HANDLE_INSTRUCTION_END();
1715
1716 HANDLE_INSTRUCTION_START(LONG_TO_DOUBLE)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001717 shadow_frame.SetVRegDouble(
1718 inst->VRegA_12x(inst_data), shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001719 ADVANCE(1);
1720 HANDLE_INSTRUCTION_END();
1721
1722 HANDLE_INSTRUCTION_START(FLOAT_TO_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001723 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001724 int32_t result = art_float_to_integral<int32_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001725 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001726 ADVANCE(1);
1727 }
1728 HANDLE_INSTRUCTION_END();
1729
1730 HANDLE_INSTRUCTION_START(FLOAT_TO_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001731 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001732 int64_t result = art_float_to_integral<int64_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001733 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001734 ADVANCE(1);
1735 }
1736 HANDLE_INSTRUCTION_END();
1737
1738 HANDLE_INSTRUCTION_START(FLOAT_TO_DOUBLE)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001739 shadow_frame.SetVRegDouble(
1740 inst->VRegA_12x(inst_data), shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001741 ADVANCE(1);
1742 HANDLE_INSTRUCTION_END();
1743
1744 HANDLE_INSTRUCTION_START(DOUBLE_TO_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001745 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001746 int32_t result = art_float_to_integral<int32_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001747 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001748 ADVANCE(1);
1749 }
1750 HANDLE_INSTRUCTION_END();
1751
1752 HANDLE_INSTRUCTION_START(DOUBLE_TO_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001753 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001754 int64_t result = art_float_to_integral<int64_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001755 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001756 ADVANCE(1);
1757 }
1758 HANDLE_INSTRUCTION_END();
1759
1760 HANDLE_INSTRUCTION_START(DOUBLE_TO_FLOAT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001761 shadow_frame.SetVRegFloat(
1762 inst->VRegA_12x(inst_data), shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001763 ADVANCE(1);
1764 HANDLE_INSTRUCTION_END();
1765
1766 HANDLE_INSTRUCTION_START(INT_TO_BYTE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001767 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1768 static_cast<int8_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001769 ADVANCE(1);
1770 HANDLE_INSTRUCTION_END();
1771
1772 HANDLE_INSTRUCTION_START(INT_TO_CHAR)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001773 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1774 static_cast<uint16_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001775 ADVANCE(1);
1776 HANDLE_INSTRUCTION_END();
1777
1778 HANDLE_INSTRUCTION_START(INT_TO_SHORT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001779 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1780 static_cast<int16_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001781 ADVANCE(1);
1782 HANDLE_INSTRUCTION_END();
1783
1784 HANDLE_INSTRUCTION_START(ADD_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001785 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001786 SafeAdd(shadow_frame.GetVReg(inst->VRegB_23x()),
1787 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001788 ADVANCE(2);
1789 HANDLE_INSTRUCTION_END();
1790
1791 HANDLE_INSTRUCTION_START(SUB_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001792 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001793 SafeSub(shadow_frame.GetVReg(inst->VRegB_23x()),
1794 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001795 ADVANCE(2);
1796 HANDLE_INSTRUCTION_END();
1797
1798 HANDLE_INSTRUCTION_START(MUL_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001799 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001800 SafeMul(shadow_frame.GetVReg(inst->VRegB_23x()),
1801 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001802 ADVANCE(2);
1803 HANDLE_INSTRUCTION_END();
1804
1805 HANDLE_INSTRUCTION_START(DIV_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001806 bool success = DoIntDivide(shadow_frame, inst->VRegA_23x(inst_data),
1807 shadow_frame.GetVReg(inst->VRegB_23x()),
1808 shadow_frame.GetVReg(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001809 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1810 }
1811 HANDLE_INSTRUCTION_END();
1812
1813 HANDLE_INSTRUCTION_START(REM_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001814 bool success = DoIntRemainder(shadow_frame, inst->VRegA_23x(inst_data),
1815 shadow_frame.GetVReg(inst->VRegB_23x()),
1816 shadow_frame.GetVReg(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001817 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1818 }
1819 HANDLE_INSTRUCTION_END();
1820
1821 HANDLE_INSTRUCTION_START(SHL_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001822 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001823 shadow_frame.GetVReg(inst->VRegB_23x()) <<
1824 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1825 ADVANCE(2);
1826 HANDLE_INSTRUCTION_END();
1827
1828 HANDLE_INSTRUCTION_START(SHR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001829 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001830 shadow_frame.GetVReg(inst->VRegB_23x()) >>
1831 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1832 ADVANCE(2);
1833 HANDLE_INSTRUCTION_END();
1834
1835 HANDLE_INSTRUCTION_START(USHR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001836 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001837 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_23x())) >>
1838 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1839 ADVANCE(2);
1840 HANDLE_INSTRUCTION_END();
1841
1842 HANDLE_INSTRUCTION_START(AND_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001843 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001844 shadow_frame.GetVReg(inst->VRegB_23x()) &
1845 shadow_frame.GetVReg(inst->VRegC_23x()));
1846 ADVANCE(2);
1847 HANDLE_INSTRUCTION_END();
1848
1849 HANDLE_INSTRUCTION_START(OR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001850 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001851 shadow_frame.GetVReg(inst->VRegB_23x()) |
1852 shadow_frame.GetVReg(inst->VRegC_23x()));
1853 ADVANCE(2);
1854 HANDLE_INSTRUCTION_END();
1855
1856 HANDLE_INSTRUCTION_START(XOR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001857 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001858 shadow_frame.GetVReg(inst->VRegB_23x()) ^
1859 shadow_frame.GetVReg(inst->VRegC_23x()));
1860 ADVANCE(2);
1861 HANDLE_INSTRUCTION_END();
1862
1863 HANDLE_INSTRUCTION_START(ADD_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001864 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001865 SafeAdd(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1866 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001867 ADVANCE(2);
1868 HANDLE_INSTRUCTION_END();
1869
1870 HANDLE_INSTRUCTION_START(SUB_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001871 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001872 SafeSub(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1873 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001874 ADVANCE(2);
1875 HANDLE_INSTRUCTION_END();
1876
1877 HANDLE_INSTRUCTION_START(MUL_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001878 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001879 SafeMul(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1880 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001881 ADVANCE(2);
1882 HANDLE_INSTRUCTION_END();
1883
1884 HANDLE_INSTRUCTION_START(DIV_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001885 bool success = DoLongDivide(shadow_frame, inst->VRegA_23x(inst_data),
1886 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1887 shadow_frame.GetVRegLong(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001888 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1889 }
1890 HANDLE_INSTRUCTION_END();
1891
1892 HANDLE_INSTRUCTION_START(REM_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001893 bool success = DoLongRemainder(shadow_frame, inst->VRegA_23x(inst_data),
1894 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1895 shadow_frame.GetVRegLong(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001896 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1897 }
1898 HANDLE_INSTRUCTION_END();
1899
1900 HANDLE_INSTRUCTION_START(AND_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001901 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001902 shadow_frame.GetVRegLong(inst->VRegB_23x()) &
1903 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1904 ADVANCE(2);
1905 HANDLE_INSTRUCTION_END();
1906
1907 HANDLE_INSTRUCTION_START(OR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001908 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001909 shadow_frame.GetVRegLong(inst->VRegB_23x()) |
1910 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1911 ADVANCE(2);
1912 HANDLE_INSTRUCTION_END();
1913
1914 HANDLE_INSTRUCTION_START(XOR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001915 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001916 shadow_frame.GetVRegLong(inst->VRegB_23x()) ^
1917 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1918 ADVANCE(2);
1919 HANDLE_INSTRUCTION_END();
1920
1921 HANDLE_INSTRUCTION_START(SHL_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001922 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001923 shadow_frame.GetVRegLong(inst->VRegB_23x()) <<
1924 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1925 ADVANCE(2);
1926 HANDLE_INSTRUCTION_END();
1927
1928 HANDLE_INSTRUCTION_START(SHR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001929 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001930 shadow_frame.GetVRegLong(inst->VRegB_23x()) >>
1931 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1932 ADVANCE(2);
1933 HANDLE_INSTRUCTION_END();
1934
1935 HANDLE_INSTRUCTION_START(USHR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001936 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001937 static_cast<uint64_t>(shadow_frame.GetVRegLong(inst->VRegB_23x())) >>
1938 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1939 ADVANCE(2);
1940 HANDLE_INSTRUCTION_END();
1941
1942 HANDLE_INSTRUCTION_START(ADD_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001943 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001944 shadow_frame.GetVRegFloat(inst->VRegB_23x()) +
1945 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1946 ADVANCE(2);
1947 HANDLE_INSTRUCTION_END();
1948
1949 HANDLE_INSTRUCTION_START(SUB_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001950 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001951 shadow_frame.GetVRegFloat(inst->VRegB_23x()) -
1952 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1953 ADVANCE(2);
1954 HANDLE_INSTRUCTION_END();
1955
1956 HANDLE_INSTRUCTION_START(MUL_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001957 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001958 shadow_frame.GetVRegFloat(inst->VRegB_23x()) *
1959 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1960 ADVANCE(2);
1961 HANDLE_INSTRUCTION_END();
1962
1963 HANDLE_INSTRUCTION_START(DIV_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001964 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001965 shadow_frame.GetVRegFloat(inst->VRegB_23x()) /
1966 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1967 ADVANCE(2);
1968 HANDLE_INSTRUCTION_END();
1969
1970 HANDLE_INSTRUCTION_START(REM_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001971 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001972 fmodf(shadow_frame.GetVRegFloat(inst->VRegB_23x()),
1973 shadow_frame.GetVRegFloat(inst->VRegC_23x())));
1974 ADVANCE(2);
1975 HANDLE_INSTRUCTION_END();
1976
1977 HANDLE_INSTRUCTION_START(ADD_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001978 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001979 shadow_frame.GetVRegDouble(inst->VRegB_23x()) +
1980 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1981 ADVANCE(2);
1982 HANDLE_INSTRUCTION_END();
1983
1984 HANDLE_INSTRUCTION_START(SUB_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001985 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001986 shadow_frame.GetVRegDouble(inst->VRegB_23x()) -
1987 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1988 ADVANCE(2);
1989 HANDLE_INSTRUCTION_END();
1990
1991 HANDLE_INSTRUCTION_START(MUL_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001992 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001993 shadow_frame.GetVRegDouble(inst->VRegB_23x()) *
1994 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1995 ADVANCE(2);
1996 HANDLE_INSTRUCTION_END();
1997
1998 HANDLE_INSTRUCTION_START(DIV_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001999 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002000 shadow_frame.GetVRegDouble(inst->VRegB_23x()) /
2001 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
2002 ADVANCE(2);
2003 HANDLE_INSTRUCTION_END();
2004
2005 HANDLE_INSTRUCTION_START(REM_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002006 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002007 fmod(shadow_frame.GetVRegDouble(inst->VRegB_23x()),
2008 shadow_frame.GetVRegDouble(inst->VRegC_23x())));
2009 ADVANCE(2);
2010 HANDLE_INSTRUCTION_END();
2011
2012 HANDLE_INSTRUCTION_START(ADD_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002013 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002014 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002015 SafeAdd(shadow_frame.GetVReg(vregA),
2016 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002017 ADVANCE(1);
2018 }
2019 HANDLE_INSTRUCTION_END();
2020
2021 HANDLE_INSTRUCTION_START(SUB_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002022 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002023 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002024 SafeSub(shadow_frame.GetVReg(vregA),
2025 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002026 ADVANCE(1);
2027 }
2028 HANDLE_INSTRUCTION_END();
2029
2030 HANDLE_INSTRUCTION_START(MUL_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002031 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002032 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002033 SafeMul(shadow_frame.GetVReg(vregA),
2034 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002035 ADVANCE(1);
2036 }
2037 HANDLE_INSTRUCTION_END();
2038
2039 HANDLE_INSTRUCTION_START(DIV_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002040 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002041 bool success = DoIntDivide(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002042 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002043 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2044 }
2045 HANDLE_INSTRUCTION_END();
2046
2047 HANDLE_INSTRUCTION_START(REM_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002048 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002049 bool success = DoIntRemainder(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002050 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002051 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2052 }
2053 HANDLE_INSTRUCTION_END();
2054
2055 HANDLE_INSTRUCTION_START(SHL_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002056 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002057 shadow_frame.SetVReg(vregA,
2058 shadow_frame.GetVReg(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002059 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002060 ADVANCE(1);
2061 }
2062 HANDLE_INSTRUCTION_END();
2063
2064 HANDLE_INSTRUCTION_START(SHR_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002065 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002066 shadow_frame.SetVReg(vregA,
2067 shadow_frame.GetVReg(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002068 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002069 ADVANCE(1);
2070 }
2071 HANDLE_INSTRUCTION_END();
2072
2073 HANDLE_INSTRUCTION_START(USHR_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002074 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002075 shadow_frame.SetVReg(vregA,
2076 static_cast<uint32_t>(shadow_frame.GetVReg(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002077 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002078 ADVANCE(1);
2079 }
2080 HANDLE_INSTRUCTION_END();
2081
2082 HANDLE_INSTRUCTION_START(AND_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002083 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002084 shadow_frame.SetVReg(vregA,
2085 shadow_frame.GetVReg(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002086 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002087 ADVANCE(1);
2088 }
2089 HANDLE_INSTRUCTION_END();
2090
2091 HANDLE_INSTRUCTION_START(OR_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002092 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002093 shadow_frame.SetVReg(vregA,
2094 shadow_frame.GetVReg(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002095 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002096 ADVANCE(1);
2097 }
2098 HANDLE_INSTRUCTION_END();
2099
2100 HANDLE_INSTRUCTION_START(XOR_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002101 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002102 shadow_frame.SetVReg(vregA,
2103 shadow_frame.GetVReg(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002104 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002105 ADVANCE(1);
2106 }
2107 HANDLE_INSTRUCTION_END();
2108
2109 HANDLE_INSTRUCTION_START(ADD_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002110 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002111 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002112 SafeAdd(shadow_frame.GetVRegLong(vregA),
2113 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002114 ADVANCE(1);
2115 }
2116 HANDLE_INSTRUCTION_END();
2117
2118 HANDLE_INSTRUCTION_START(SUB_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002119 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002120 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002121 SafeSub(shadow_frame.GetVRegLong(vregA),
2122 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002123 ADVANCE(1);
2124 }
2125 HANDLE_INSTRUCTION_END();
2126
2127 HANDLE_INSTRUCTION_START(MUL_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002128 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002129 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002130 SafeMul(shadow_frame.GetVRegLong(vregA),
2131 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002132 ADVANCE(1);
2133 }
2134 HANDLE_INSTRUCTION_END();
2135
2136 HANDLE_INSTRUCTION_START(DIV_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002137 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002138 bool success = DoLongDivide(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002139 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002140 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2141 }
2142 HANDLE_INSTRUCTION_END();
2143
2144 HANDLE_INSTRUCTION_START(REM_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002145 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002146 bool success = DoLongRemainder(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002147 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002148 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2149 }
2150 HANDLE_INSTRUCTION_END();
2151
2152 HANDLE_INSTRUCTION_START(AND_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002153 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002154 shadow_frame.SetVRegLong(vregA,
2155 shadow_frame.GetVRegLong(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002156 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002157 ADVANCE(1);
2158 }
2159 HANDLE_INSTRUCTION_END();
2160
2161 HANDLE_INSTRUCTION_START(OR_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002162 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002163 shadow_frame.SetVRegLong(vregA,
2164 shadow_frame.GetVRegLong(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002165 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002166 ADVANCE(1);
2167 }
2168 HANDLE_INSTRUCTION_END();
2169
2170 HANDLE_INSTRUCTION_START(XOR_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002171 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002172 shadow_frame.SetVRegLong(vregA,
2173 shadow_frame.GetVRegLong(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002174 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002175 ADVANCE(1);
2176 }
2177 HANDLE_INSTRUCTION_END();
2178
2179 HANDLE_INSTRUCTION_START(SHL_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002180 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002181 shadow_frame.SetVRegLong(vregA,
2182 shadow_frame.GetVRegLong(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002183 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002184 ADVANCE(1);
2185 }
2186 HANDLE_INSTRUCTION_END();
2187
2188 HANDLE_INSTRUCTION_START(SHR_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002189 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002190 shadow_frame.SetVRegLong(vregA,
2191 shadow_frame.GetVRegLong(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002192 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002193 ADVANCE(1);
2194 }
2195 HANDLE_INSTRUCTION_END();
2196
2197 HANDLE_INSTRUCTION_START(USHR_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002198 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002199 shadow_frame.SetVRegLong(vregA,
2200 static_cast<uint64_t>(shadow_frame.GetVRegLong(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002201 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002202 ADVANCE(1);
2203 }
2204 HANDLE_INSTRUCTION_END();
2205
2206 HANDLE_INSTRUCTION_START(ADD_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002207 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002208 shadow_frame.SetVRegFloat(vregA,
2209 shadow_frame.GetVRegFloat(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002210 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002211 ADVANCE(1);
2212 }
2213 HANDLE_INSTRUCTION_END();
2214
2215 HANDLE_INSTRUCTION_START(SUB_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002216 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002217 shadow_frame.SetVRegFloat(vregA,
2218 shadow_frame.GetVRegFloat(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002219 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002220 ADVANCE(1);
2221 }
2222 HANDLE_INSTRUCTION_END();
2223
2224 HANDLE_INSTRUCTION_START(MUL_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002225 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002226 shadow_frame.SetVRegFloat(vregA,
2227 shadow_frame.GetVRegFloat(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002228 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002229 ADVANCE(1);
2230 }
2231 HANDLE_INSTRUCTION_END();
2232
2233 HANDLE_INSTRUCTION_START(DIV_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002234 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002235 shadow_frame.SetVRegFloat(vregA,
2236 shadow_frame.GetVRegFloat(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002237 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002238 ADVANCE(1);
2239 }
2240 HANDLE_INSTRUCTION_END();
2241
2242 HANDLE_INSTRUCTION_START(REM_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002243 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002244 shadow_frame.SetVRegFloat(vregA,
2245 fmodf(shadow_frame.GetVRegFloat(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002246 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002247 ADVANCE(1);
2248 }
2249 HANDLE_INSTRUCTION_END();
2250
2251 HANDLE_INSTRUCTION_START(ADD_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002252 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002253 shadow_frame.SetVRegDouble(vregA,
2254 shadow_frame.GetVRegDouble(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002255 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002256 ADVANCE(1);
2257 }
2258 HANDLE_INSTRUCTION_END();
2259
2260 HANDLE_INSTRUCTION_START(SUB_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002261 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002262 shadow_frame.SetVRegDouble(vregA,
2263 shadow_frame.GetVRegDouble(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002264 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002265 ADVANCE(1);
2266 }
2267 HANDLE_INSTRUCTION_END();
2268
2269 HANDLE_INSTRUCTION_START(MUL_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002270 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002271 shadow_frame.SetVRegDouble(vregA,
2272 shadow_frame.GetVRegDouble(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002273 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002274 ADVANCE(1);
2275 }
2276 HANDLE_INSTRUCTION_END();
2277
2278 HANDLE_INSTRUCTION_START(DIV_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002279 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002280 shadow_frame.SetVRegDouble(vregA,
2281 shadow_frame.GetVRegDouble(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002282 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002283 ADVANCE(1);
2284 }
2285 HANDLE_INSTRUCTION_END();
2286
2287 HANDLE_INSTRUCTION_START(REM_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002288 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002289 shadow_frame.SetVRegDouble(vregA,
2290 fmod(shadow_frame.GetVRegDouble(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002291 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002292 ADVANCE(1);
2293 }
2294 HANDLE_INSTRUCTION_END();
2295
2296 HANDLE_INSTRUCTION_START(ADD_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002297 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002298 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2299 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002300 ADVANCE(2);
2301 HANDLE_INSTRUCTION_END();
2302
2303 HANDLE_INSTRUCTION_START(RSUB_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002304 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002305 SafeSub(inst->VRegC_22s(),
2306 shadow_frame.GetVReg(inst->VRegB_22s(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002307 ADVANCE(2);
2308 HANDLE_INSTRUCTION_END();
2309
2310 HANDLE_INSTRUCTION_START(MUL_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002311 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002312 SafeMul(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2313 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002314 ADVANCE(2);
2315 HANDLE_INSTRUCTION_END();
2316
2317 HANDLE_INSTRUCTION_START(DIV_INT_LIT16) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002318 bool success = DoIntDivide(
2319 shadow_frame, inst->VRegA_22s(inst_data), shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2320 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002321 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2322 }
2323 HANDLE_INSTRUCTION_END();
2324
2325 HANDLE_INSTRUCTION_START(REM_INT_LIT16) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002326 bool success = DoIntRemainder(
2327 shadow_frame, inst->VRegA_22s(inst_data), shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2328 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002329 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2330 }
2331 HANDLE_INSTRUCTION_END();
2332
2333 HANDLE_INSTRUCTION_START(AND_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002334 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2335 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) &
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002336 inst->VRegC_22s());
2337 ADVANCE(2);
2338 HANDLE_INSTRUCTION_END();
2339
2340 HANDLE_INSTRUCTION_START(OR_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002341 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2342 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) |
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002343 inst->VRegC_22s());
2344 ADVANCE(2);
2345 HANDLE_INSTRUCTION_END();
2346
2347 HANDLE_INSTRUCTION_START(XOR_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002348 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2349 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) ^
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002350 inst->VRegC_22s());
2351 ADVANCE(2);
2352 HANDLE_INSTRUCTION_END();
2353
2354 HANDLE_INSTRUCTION_START(ADD_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002355 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002356 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22b()),
2357 inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002358 ADVANCE(2);
2359 HANDLE_INSTRUCTION_END();
2360
2361 HANDLE_INSTRUCTION_START(RSUB_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002362 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002363 SafeSub(inst->VRegC_22b(),
2364 shadow_frame.GetVReg(inst->VRegB_22b())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002365 ADVANCE(2);
2366 HANDLE_INSTRUCTION_END();
2367
2368 HANDLE_INSTRUCTION_START(MUL_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002369 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002370 SafeMul(shadow_frame.GetVReg(inst->VRegB_22b()),
2371 inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002372 ADVANCE(2);
2373 HANDLE_INSTRUCTION_END();
2374
2375 HANDLE_INSTRUCTION_START(DIV_INT_LIT8) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002376 bool success = DoIntDivide(shadow_frame, inst->VRegA_22b(inst_data),
2377 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002378 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2379 }
2380 HANDLE_INSTRUCTION_END();
2381
2382 HANDLE_INSTRUCTION_START(REM_INT_LIT8) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002383 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22b(inst_data),
2384 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002385 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2386 }
2387 HANDLE_INSTRUCTION_END();
2388
2389 HANDLE_INSTRUCTION_START(AND_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002390 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002391 shadow_frame.GetVReg(inst->VRegB_22b()) &
2392 inst->VRegC_22b());
2393 ADVANCE(2);
2394 HANDLE_INSTRUCTION_END();
2395
2396 HANDLE_INSTRUCTION_START(OR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002397 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002398 shadow_frame.GetVReg(inst->VRegB_22b()) |
2399 inst->VRegC_22b());
2400 ADVANCE(2);
2401 HANDLE_INSTRUCTION_END();
2402
2403 HANDLE_INSTRUCTION_START(XOR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002404 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002405 shadow_frame.GetVReg(inst->VRegB_22b()) ^
2406 inst->VRegC_22b());
2407 ADVANCE(2);
2408 HANDLE_INSTRUCTION_END();
2409
2410 HANDLE_INSTRUCTION_START(SHL_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002411 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002412 shadow_frame.GetVReg(inst->VRegB_22b()) <<
2413 (inst->VRegC_22b() & 0x1f));
2414 ADVANCE(2);
2415 HANDLE_INSTRUCTION_END();
2416
2417 HANDLE_INSTRUCTION_START(SHR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002418 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002419 shadow_frame.GetVReg(inst->VRegB_22b()) >>
2420 (inst->VRegC_22b() & 0x1f));
2421 ADVANCE(2);
2422 HANDLE_INSTRUCTION_END();
2423
2424 HANDLE_INSTRUCTION_START(USHR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002425 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002426 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_22b())) >>
2427 (inst->VRegC_22b() & 0x1f));
2428 ADVANCE(2);
2429 HANDLE_INSTRUCTION_END();
2430
Igor Murashkin158f35c2015-06-10 15:55:30 -07002431 HANDLE_EXPERIMENTAL_INSTRUCTION_START(CREATE_LAMBDA) {
Igor Murashkin6918bf12015-09-27 19:19:06 -07002432 if (lambda_closure_builder == nullptr) {
2433 // DoCreateLambda always needs a ClosureBuilder, even if it has 0 captured variables.
2434 lambda_closure_builder = MakeUnique<lambda::ClosureBuilder>();
2435 }
2436
2437 // TODO: these allocations should not leak, and the lambda method should not be local.
2438 lambda::Closure* lambda_closure =
2439 reinterpret_cast<lambda::Closure*>(alloca(lambda_closure_builder->GetSize()));
2440 bool success = DoCreateLambda<do_access_check>(self,
2441 inst,
2442 /*inout*/shadow_frame,
2443 /*inout*/lambda_closure_builder.get(),
2444 /*inout*/lambda_closure);
2445 lambda_closure_builder.reset(nullptr); // reset state of variables captured
Igor Murashkin158f35c2015-06-10 15:55:30 -07002446 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2447 }
2448 HANDLE_EXPERIMENTAL_INSTRUCTION_END();
2449
Igor Murashkin2ee54e22015-06-18 10:05:11 -07002450 HANDLE_EXPERIMENTAL_INSTRUCTION_START(BOX_LAMBDA) {
2451 bool success = DoBoxLambda<do_access_check>(self, shadow_frame, inst, inst_data);
2452 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2453 }
2454 HANDLE_EXPERIMENTAL_INSTRUCTION_END();
2455
2456 HANDLE_EXPERIMENTAL_INSTRUCTION_START(UNBOX_LAMBDA) {
2457 bool success = DoUnboxLambda<do_access_check>(self, shadow_frame, inst, inst_data);
2458 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2459 }
2460 HANDLE_EXPERIMENTAL_INSTRUCTION_END();
2461
Igor Murashkin6918bf12015-09-27 19:19:06 -07002462 HANDLE_EXPERIMENTAL_INSTRUCTION_START(CAPTURE_VARIABLE) {
2463 if (lambda_closure_builder == nullptr) {
2464 lambda_closure_builder = MakeUnique<lambda::ClosureBuilder>();
2465 }
2466
2467 bool success = DoCaptureVariable<do_access_check>(self,
2468 inst,
2469 /*inout*/shadow_frame,
2470 /*inout*/lambda_closure_builder.get());
2471
2472 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2473 }
2474 HANDLE_EXPERIMENTAL_INSTRUCTION_END();
2475
2476 HANDLE_EXPERIMENTAL_INSTRUCTION_START(LIBERATE_VARIABLE) {
2477 bool success = DoLiberateVariable<do_access_check>(self,
2478 inst,
2479 lambda_captured_variable_index,
2480 /*inout*/shadow_frame);
2481 // Temporarily only allow sequences of 'liberate-variable, liberate-variable, ...'
2482 lambda_captured_variable_index++;
2483 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2484 }
2485 HANDLE_EXPERIMENTAL_INSTRUCTION_END();
2486
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002487 HANDLE_INSTRUCTION_START(UNUSED_3E)
Ian Rogerse94652f2014-12-02 11:13:19 -08002488 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002489 HANDLE_INSTRUCTION_END();
2490
2491 HANDLE_INSTRUCTION_START(UNUSED_3F)
Ian Rogerse94652f2014-12-02 11:13:19 -08002492 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002493 HANDLE_INSTRUCTION_END();
2494
2495 HANDLE_INSTRUCTION_START(UNUSED_40)
Ian Rogerse94652f2014-12-02 11:13:19 -08002496 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002497 HANDLE_INSTRUCTION_END();
2498
2499 HANDLE_INSTRUCTION_START(UNUSED_41)
Ian Rogerse94652f2014-12-02 11:13:19 -08002500 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002501 HANDLE_INSTRUCTION_END();
2502
2503 HANDLE_INSTRUCTION_START(UNUSED_42)
Ian Rogerse94652f2014-12-02 11:13:19 -08002504 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002505 HANDLE_INSTRUCTION_END();
2506
2507 HANDLE_INSTRUCTION_START(UNUSED_43)
Ian Rogerse94652f2014-12-02 11:13:19 -08002508 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002509 HANDLE_INSTRUCTION_END();
2510
2511 HANDLE_INSTRUCTION_START(UNUSED_79)
Ian Rogerse94652f2014-12-02 11:13:19 -08002512 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002513 HANDLE_INSTRUCTION_END();
2514
2515 HANDLE_INSTRUCTION_START(UNUSED_7A)
Ian Rogerse94652f2014-12-02 11:13:19 -08002516 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002517 HANDLE_INSTRUCTION_END();
2518
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002519 HANDLE_INSTRUCTION_START(UNUSED_F4)
Ian Rogerse94652f2014-12-02 11:13:19 -08002520 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002521 HANDLE_INSTRUCTION_END();
2522
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002523 HANDLE_INSTRUCTION_START(UNUSED_FA)
Ian Rogerse94652f2014-12-02 11:13:19 -08002524 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002525 HANDLE_INSTRUCTION_END();
2526
2527 HANDLE_INSTRUCTION_START(UNUSED_FB)
Ian Rogerse94652f2014-12-02 11:13:19 -08002528 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002529 HANDLE_INSTRUCTION_END();
2530
2531 HANDLE_INSTRUCTION_START(UNUSED_FC)
Ian Rogerse94652f2014-12-02 11:13:19 -08002532 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002533 HANDLE_INSTRUCTION_END();
2534
2535 HANDLE_INSTRUCTION_START(UNUSED_FD)
Ian Rogerse94652f2014-12-02 11:13:19 -08002536 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002537 HANDLE_INSTRUCTION_END();
2538
2539 HANDLE_INSTRUCTION_START(UNUSED_FE)
Ian Rogerse94652f2014-12-02 11:13:19 -08002540 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002541 HANDLE_INSTRUCTION_END();
2542
2543 HANDLE_INSTRUCTION_START(UNUSED_FF)
Ian Rogerse94652f2014-12-02 11:13:19 -08002544 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002545 HANDLE_INSTRUCTION_END();
2546
2547 exception_pending_label: {
2548 CHECK(self->IsExceptionPending());
Sebastien Hertz1eda2262013-09-09 16:53:14 +02002549 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -07002550 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +02002551 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +02002552 }
Sebastien Hertzee1997a2013-09-19 14:47:09 +02002553 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002554 uint32_t found_dex_pc = FindNextInstructionFollowingException(self, shadow_frame, dex_pc,
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002555 instrumentation);
2556 if (found_dex_pc == DexFile::kDexNoIndex) {
Andreas Gampe03ec9302015-08-27 17:41:47 -07002557 // Structured locking is to be enforced for abnormal termination, too.
2558 shadow_frame.GetLockCountData().CheckAllMonitorsReleasedOrThrow<do_assignability_check>(self);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002559 return JValue(); /* Handled in caller. */
2560 } else {
2561 int32_t displacement = static_cast<int32_t>(found_dex_pc) - static_cast<int32_t>(dex_pc);
2562 ADVANCE(displacement);
2563 }
2564 }
2565
Sebastien Hertz8379b222014-02-24 17:38:15 +01002566// Create alternative instruction handlers dedicated to instrumentation.
2567// Return instructions must not call Instrumentation::DexPcMovedEvent since they already call
2568// Instrumentation::MethodExited. This is to avoid posting debugger events twice for this location.
Sebastien Hertze713d932014-05-15 10:48:53 +02002569// Note: we do not use the kReturn instruction flag here (to test the instruction is a return). The
2570// compiler seems to not evaluate "(Instruction::FlagsOf(Instruction::code) & kReturn) != 0" to
2571// a constant condition that would remove the "if" statement so the test is free.
Sebastien Hertz9d6bf692015-04-10 12:12:33 +02002572#define INSTRUMENTATION_INSTRUCTION_HANDLER(o, code, n, f, r, i, a, v) \
2573 alt_op_##code: { \
2574 Runtime* const runtime = Runtime::Current(); \
2575 const instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation(); \
2576 if (UNLIKELY(instrumentation->HasDexPcListeners())) { \
2577 Object* this_object = shadow_frame.GetThisObject(code_item->ins_size_); \
2578 instrumentation->DexPcMovedEvent(self, this_object, shadow_frame.GetMethod(), dex_pc); \
2579 } \
2580 UPDATE_HANDLER_TABLE(); \
2581 goto *handlersTable[instrumentation::kMainHandlerTable][Instruction::code]; \
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002582 }
2583#include "dex_instruction_list.h"
2584 DEX_INSTRUCTION_LIST(INSTRUMENTATION_INSTRUCTION_HANDLER)
2585#undef DEX_INSTRUCTION_LIST
2586#undef INSTRUMENTATION_INSTRUCTION_HANDLER
2587} // NOLINT(readability/fn_size)
2588
2589// Explicit definitions of ExecuteGotoImpl.
Mathieu Chartier90443472015-07-16 20:32:27 -07002590template SHARED_REQUIRES(Locks::mutator_lock_) HOT_ATTR
Ian Rogerse94652f2014-12-02 11:13:19 -08002591JValue ExecuteGotoImpl<true, false>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002592 ShadowFrame& shadow_frame, JValue result_register);
Mathieu Chartier90443472015-07-16 20:32:27 -07002593template SHARED_REQUIRES(Locks::mutator_lock_) HOT_ATTR
Ian Rogerse94652f2014-12-02 11:13:19 -08002594JValue ExecuteGotoImpl<false, false>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002595 ShadowFrame& shadow_frame, JValue result_register);
Mathieu Chartier90443472015-07-16 20:32:27 -07002596template SHARED_REQUIRES(Locks::mutator_lock_)
Ian Rogerse94652f2014-12-02 11:13:19 -08002597JValue ExecuteGotoImpl<true, true>(Thread* self, const DexFile::CodeItem* code_item,
2598 ShadowFrame& shadow_frame, JValue result_register);
Mathieu Chartier90443472015-07-16 20:32:27 -07002599template SHARED_REQUIRES(Locks::mutator_lock_)
Ian Rogerse94652f2014-12-02 11:13:19 -08002600JValue ExecuteGotoImpl<false, true>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002601 ShadowFrame& shadow_frame, JValue result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002602
2603} // namespace interpreter
2604} // namespace art
Colin Crosse84e4f72015-03-18 14:01:19 -07002605
2606#endif