blob: 9677d79de3d09b200e759332dd1f76301b6b03a0 [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
92
Sebastien Hertzee1997a2013-09-19 14:47:09 +020093/**
94 * Interpreter based on computed goto tables.
95 *
96 * Each instruction is associated to a handler. This handler is responsible for executing the
97 * instruction and jump to the next instruction's handler.
98 * In order to limit the cost of instrumentation, we have two handler tables:
99 * - the "main" handler table: it contains handlers for normal execution of each instruction without
100 * handling of instrumentation.
101 * - the "alternative" handler table: it contains alternative handlers which first handle
102 * instrumentation before jumping to the corresponding "normal" instruction's handler.
103 *
104 * When instrumentation is active, the interpreter uses the "alternative" handler table. Otherwise
105 * it uses the "main" handler table.
106 *
107 * The current handler table is the handler table being used by the interpreter. It is updated:
108 * - on backward branch (goto, if and switch instructions)
109 * - after invoke
110 * - when an exception is thrown.
111 * This allows to support an attaching debugger to an already running application for instance.
112 *
113 * For a fast handler table update, handler tables are stored in an array of handler tables. Each
114 * handler table is represented by the InterpreterHandlerTable enum which allows to associate it
115 * to an index in this array of handler tables ((see Instrumentation::GetInterpreterHandlerTable).
116 *
117 * Here's the current layout of this array of handler tables:
118 *
119 * ---------------------+---------------+
120 * | NOP | (handler for NOP instruction)
121 * +---------------+
122 * "main" | MOVE | (handler for MOVE instruction)
123 * handler table +---------------+
124 * | ... |
125 * +---------------+
126 * | UNUSED_FF | (handler for UNUSED_FF instruction)
127 * ---------------------+---------------+
128 * | NOP | (alternative handler for NOP instruction)
129 * +---------------+
130 * "alternative" | MOVE | (alternative handler for MOVE instruction)
131 * handler table +---------------+
132 * | ... |
133 * +---------------+
134 * | UNUSED_FF | (alternative handler for UNUSED_FF instruction)
135 * ---------------------+---------------+
136 *
137 */
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100138template<bool do_access_check, bool transaction_active>
Ian Rogerse94652f2014-12-02 11:13:19 -0800139JValue ExecuteGotoImpl(Thread* self, const DexFile::CodeItem* code_item, ShadowFrame& shadow_frame,
140 JValue result_register) {
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200141 // Define handler tables:
142 // - The main handler table contains execution handlers for each instruction.
143 // - The alternative handler table contains prelude handlers which check for thread suspend and
144 // manage instrumentation before jumping to the execution handler.
145 static const void* const handlersTable[instrumentation::kNumHandlerTables][kNumPackedOpcodes] = {
146 {
147 // Main handler table.
148#define INSTRUCTION_HANDLER(o, code, n, f, r, i, a, v) &&op_##code,
149#include "dex_instruction_list.h"
150 DEX_INSTRUCTION_LIST(INSTRUCTION_HANDLER)
151#undef DEX_INSTRUCTION_LIST
152#undef INSTRUCTION_HANDLER
153 }, {
154 // Alternative handler table.
155#define INSTRUCTION_HANDLER(o, code, n, f, r, i, a, v) &&alt_op_##code,
156#include "dex_instruction_list.h"
157 DEX_INSTRUCTION_LIST(INSTRUCTION_HANDLER)
158#undef DEX_INSTRUCTION_LIST
159#undef INSTRUCTION_HANDLER
160 }
161 };
162
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800163 constexpr bool do_assignability_check = do_access_check;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200164 if (UNLIKELY(!shadow_frame.HasReferenceArray())) {
165 LOG(FATAL) << "Invalid shadow frame for interpreter use";
166 return JValue();
167 }
168 self->VerifyStack();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200169
170 uint32_t dex_pc = shadow_frame.GetDexPC();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200171 const Instruction* inst = Instruction::At(code_item->insns_ + dex_pc);
172 uint16_t inst_data;
173 const void* const* currentHandlersTable;
174 UPDATE_HANDLER_TABLE();
Sebastien Hertz270a0e12015-01-16 19:49:09 +0100175 if (LIKELY(dex_pc == 0)) { // We are entering the method as opposed to deoptimizing.
176 if (kIsDebugBuild) {
177 self->AssertNoPendingException();
178 }
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200179 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200180 if (UNLIKELY(instrumentation->HasMethodEntryListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200181 instrumentation->MethodEnterEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200182 shadow_frame.GetMethod(), 0);
183 }
184 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200185
Igor Murashkin6918bf12015-09-27 19:19:06 -0700186 std::unique_ptr<lambda::ClosureBuilder> lambda_closure_builder;
187 size_t lambda_captured_variable_index = 0;
188
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200189 // Jump to first instruction.
190 ADVANCE(0);
191 UNREACHABLE_CODE_CHECK();
192
193 HANDLE_INSTRUCTION_START(NOP)
194 ADVANCE(1);
195 HANDLE_INSTRUCTION_END();
196
197 HANDLE_INSTRUCTION_START(MOVE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200198 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
199 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200200 ADVANCE(1);
201 HANDLE_INSTRUCTION_END();
202
203 HANDLE_INSTRUCTION_START(MOVE_FROM16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200204 shadow_frame.SetVReg(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200205 shadow_frame.GetVReg(inst->VRegB_22x()));
206 ADVANCE(2);
207 HANDLE_INSTRUCTION_END();
208
209 HANDLE_INSTRUCTION_START(MOVE_16)
210 shadow_frame.SetVReg(inst->VRegA_32x(),
211 shadow_frame.GetVReg(inst->VRegB_32x()));
212 ADVANCE(3);
213 HANDLE_INSTRUCTION_END();
214
215 HANDLE_INSTRUCTION_START(MOVE_WIDE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200216 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
217 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200218 ADVANCE(1);
219 HANDLE_INSTRUCTION_END();
220
221 HANDLE_INSTRUCTION_START(MOVE_WIDE_FROM16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200222 shadow_frame.SetVRegLong(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200223 shadow_frame.GetVRegLong(inst->VRegB_22x()));
224 ADVANCE(2);
225 HANDLE_INSTRUCTION_END();
226
227 HANDLE_INSTRUCTION_START(MOVE_WIDE_16)
228 shadow_frame.SetVRegLong(inst->VRegA_32x(),
229 shadow_frame.GetVRegLong(inst->VRegB_32x()));
230 ADVANCE(3);
231 HANDLE_INSTRUCTION_END();
232
233 HANDLE_INSTRUCTION_START(MOVE_OBJECT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200234 shadow_frame.SetVRegReference(inst->VRegA_12x(inst_data),
235 shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200236 ADVANCE(1);
237 HANDLE_INSTRUCTION_END();
238
239 HANDLE_INSTRUCTION_START(MOVE_OBJECT_FROM16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200240 shadow_frame.SetVRegReference(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200241 shadow_frame.GetVRegReference(inst->VRegB_22x()));
242 ADVANCE(2);
243 HANDLE_INSTRUCTION_END();
244
245 HANDLE_INSTRUCTION_START(MOVE_OBJECT_16)
246 shadow_frame.SetVRegReference(inst->VRegA_32x(),
247 shadow_frame.GetVRegReference(inst->VRegB_32x()));
248 ADVANCE(3);
249 HANDLE_INSTRUCTION_END();
250
251 HANDLE_INSTRUCTION_START(MOVE_RESULT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200252 shadow_frame.SetVReg(inst->VRegA_11x(inst_data), result_register.GetI());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200253 ADVANCE(1);
254 HANDLE_INSTRUCTION_END();
255
256 HANDLE_INSTRUCTION_START(MOVE_RESULT_WIDE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200257 shadow_frame.SetVRegLong(inst->VRegA_11x(inst_data), result_register.GetJ());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200258 ADVANCE(1);
259 HANDLE_INSTRUCTION_END();
260
261 HANDLE_INSTRUCTION_START(MOVE_RESULT_OBJECT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200262 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), result_register.GetL());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200263 ADVANCE(1);
264 HANDLE_INSTRUCTION_END();
265
266 HANDLE_INSTRUCTION_START(MOVE_EXCEPTION) {
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000267 Throwable* exception = self->GetException();
Sebastien Hertz270a0e12015-01-16 19:49:09 +0100268 DCHECK(exception != nullptr) << "No pending exception on MOVE_EXCEPTION instruction";
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200269 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), exception);
Sebastien Hertz5c004902014-05-21 10:07:42 +0200270 self->ClearException();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200271 ADVANCE(1);
272 }
273 HANDLE_INSTRUCTION_END();
274
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700275 HANDLE_INSTRUCTION_START(RETURN_VOID_NO_BARRIER) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200276 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700277 self->AllowThreadSuspension();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200278 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200279 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200280 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200281 shadow_frame.GetMethod(), dex_pc,
282 result);
283 }
284 return result;
285 }
286 HANDLE_INSTRUCTION_END();
287
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700288 HANDLE_INSTRUCTION_START(RETURN_VOID) {
Hans Boehm30359612014-05-21 17:46:23 -0700289 QuasiAtomic::ThreadFenceForConstructor();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200290 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700291 self->AllowThreadSuspension();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200292 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200293 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200294 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200295 shadow_frame.GetMethod(), dex_pc,
296 result);
297 }
298 return result;
299 }
300 HANDLE_INSTRUCTION_END();
301
302 HANDLE_INSTRUCTION_START(RETURN) {
303 JValue result;
304 result.SetJ(0);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200305 result.SetI(shadow_frame.GetVReg(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700306 self->AllowThreadSuspension();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200307 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200308 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200309 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200310 shadow_frame.GetMethod(), dex_pc,
311 result);
312 }
313 return result;
314 }
315 HANDLE_INSTRUCTION_END();
316
317 HANDLE_INSTRUCTION_START(RETURN_WIDE) {
318 JValue result;
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200319 result.SetJ(shadow_frame.GetVRegLong(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700320 self->AllowThreadSuspension();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200321 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200322 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200323 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200324 shadow_frame.GetMethod(), dex_pc,
325 result);
326 }
327 return result;
328 }
329 HANDLE_INSTRUCTION_END();
330
331 HANDLE_INSTRUCTION_START(RETURN_OBJECT) {
332 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700333 self->AllowThreadSuspension();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700334 const uint8_t vreg_index = inst->VRegA_11x(inst_data);
335 Object* obj_result = shadow_frame.GetVRegReference(vreg_index);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700336 if (do_assignability_check && obj_result != nullptr) {
Vladimir Marko05792b92015-08-03 11:56:49 +0100337 size_t pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
338 Class* return_type = shadow_frame.GetMethod()->GetReturnType(true /* resolve */,
339 pointer_size);
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700340 obj_result = shadow_frame.GetVRegReference(vreg_index);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700341 if (return_type == nullptr) {
Jeff Haoa3faaf42013-09-03 19:07:00 -0700342 // Return the pending exception.
343 HANDLE_PENDING_EXCEPTION();
344 }
345 if (!obj_result->VerifierInstanceOf(return_type)) {
346 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700347 std::string temp1, temp2;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000348 self->ThrowNewExceptionF("Ljava/lang/VirtualMachineError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700349 "Returning '%s' that is not instance of return type '%s'",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700350 obj_result->GetClass()->GetDescriptor(&temp1),
351 return_type->GetDescriptor(&temp2));
Jeff Haoa3faaf42013-09-03 19:07:00 -0700352 HANDLE_PENDING_EXCEPTION();
353 }
354 }
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700355 result.SetL(obj_result);
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200356 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200357 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200358 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200359 shadow_frame.GetMethod(), dex_pc,
360 result);
361 }
362 return result;
363 }
364 HANDLE_INSTRUCTION_END();
365
366 HANDLE_INSTRUCTION_START(CONST_4) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200367 uint32_t dst = inst->VRegA_11n(inst_data);
368 int32_t val = inst->VRegB_11n(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200369 shadow_frame.SetVReg(dst, val);
370 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700371 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200372 }
373 ADVANCE(1);
374 }
375 HANDLE_INSTRUCTION_END();
376
377 HANDLE_INSTRUCTION_START(CONST_16) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200378 uint32_t dst = inst->VRegA_21s(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200379 int32_t val = inst->VRegB_21s();
380 shadow_frame.SetVReg(dst, val);
381 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700382 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200383 }
384 ADVANCE(2);
385 }
386 HANDLE_INSTRUCTION_END();
387
388 HANDLE_INSTRUCTION_START(CONST) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200389 uint32_t dst = inst->VRegA_31i(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200390 int32_t val = inst->VRegB_31i();
391 shadow_frame.SetVReg(dst, val);
392 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700393 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200394 }
395 ADVANCE(3);
396 }
397 HANDLE_INSTRUCTION_END();
398
399 HANDLE_INSTRUCTION_START(CONST_HIGH16) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200400 uint32_t dst = inst->VRegA_21h(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200401 int32_t val = static_cast<int32_t>(inst->VRegB_21h() << 16);
402 shadow_frame.SetVReg(dst, val);
403 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700404 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200405 }
406 ADVANCE(2);
407 }
408 HANDLE_INSTRUCTION_END();
409
410 HANDLE_INSTRUCTION_START(CONST_WIDE_16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200411 shadow_frame.SetVRegLong(inst->VRegA_21s(inst_data), inst->VRegB_21s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200412 ADVANCE(2);
413 HANDLE_INSTRUCTION_END();
414
415 HANDLE_INSTRUCTION_START(CONST_WIDE_32)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200416 shadow_frame.SetVRegLong(inst->VRegA_31i(inst_data), inst->VRegB_31i());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200417 ADVANCE(3);
418 HANDLE_INSTRUCTION_END();
419
420 HANDLE_INSTRUCTION_START(CONST_WIDE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200421 shadow_frame.SetVRegLong(inst->VRegA_51l(inst_data), inst->VRegB_51l());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200422 ADVANCE(5);
423 HANDLE_INSTRUCTION_END();
424
425 HANDLE_INSTRUCTION_START(CONST_WIDE_HIGH16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200426 shadow_frame.SetVRegLong(inst->VRegA_21h(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200427 static_cast<uint64_t>(inst->VRegB_21h()) << 48);
428 ADVANCE(2);
429 HANDLE_INSTRUCTION_END();
430
431 HANDLE_INSTRUCTION_START(CONST_STRING) {
Ian Rogers6786a582014-10-28 12:49:06 -0700432 String* s = ResolveString(self, shadow_frame, inst->VRegB_21c());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700433 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200434 HANDLE_PENDING_EXCEPTION();
435 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200436 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200437 ADVANCE(2);
438 }
439 }
440 HANDLE_INSTRUCTION_END();
441
442 HANDLE_INSTRUCTION_START(CONST_STRING_JUMBO) {
Ian Rogers6786a582014-10-28 12:49:06 -0700443 String* s = ResolveString(self, shadow_frame, inst->VRegB_31c());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700444 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200445 HANDLE_PENDING_EXCEPTION();
446 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200447 shadow_frame.SetVRegReference(inst->VRegA_31c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200448 ADVANCE(3);
449 }
450 }
451 HANDLE_INSTRUCTION_END();
452
453 HANDLE_INSTRUCTION_START(CONST_CLASS) {
454 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
455 self, false, do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700456 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200457 HANDLE_PENDING_EXCEPTION();
458 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200459 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), c);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200460 ADVANCE(2);
461 }
462 }
463 HANDLE_INSTRUCTION_END();
464
465 HANDLE_INSTRUCTION_START(MONITOR_ENTER) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200466 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700467 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000468 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200469 HANDLE_PENDING_EXCEPTION();
470 } else {
471 DoMonitorEnter(self, obj);
472 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), 1);
473 }
474 }
475 HANDLE_INSTRUCTION_END();
476
477 HANDLE_INSTRUCTION_START(MONITOR_EXIT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200478 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700479 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000480 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200481 HANDLE_PENDING_EXCEPTION();
482 } else {
483 DoMonitorExit(self, obj);
484 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), 1);
485 }
486 }
487 HANDLE_INSTRUCTION_END();
488
489 HANDLE_INSTRUCTION_START(CHECK_CAST) {
490 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
491 self, false, do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700492 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200493 HANDLE_PENDING_EXCEPTION();
494 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200495 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_21c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700496 if (UNLIKELY(obj != nullptr && !obj->InstanceOf(c))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200497 ThrowClassCastException(c, obj->GetClass());
498 HANDLE_PENDING_EXCEPTION();
499 } else {
500 ADVANCE(2);
501 }
502 }
503 }
504 HANDLE_INSTRUCTION_END();
505
506 HANDLE_INSTRUCTION_START(INSTANCE_OF) {
507 Class* c = ResolveVerifyAndClinit(inst->VRegC_22c(), shadow_frame.GetMethod(),
508 self, false, do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700509 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200510 HANDLE_PENDING_EXCEPTION();
511 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200512 Object* obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700513 shadow_frame.SetVReg(inst->VRegA_22c(inst_data), (obj != nullptr && obj->InstanceOf(c)) ? 1 : 0);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200514 ADVANCE(2);
515 }
516 }
517 HANDLE_INSTRUCTION_END();
518
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700519 HANDLE_INSTRUCTION_START(ARRAY_LENGTH) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200520 Object* array = shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700521 if (UNLIKELY(array == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000522 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200523 HANDLE_PENDING_EXCEPTION();
524 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200525 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), array->AsArray()->GetLength());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200526 ADVANCE(1);
527 }
528 }
529 HANDLE_INSTRUCTION_END();
530
531 HANDLE_INSTRUCTION_START(NEW_INSTANCE) {
Jeff Hao848f70a2014-01-15 13:49:50 -0800532 Object* obj = nullptr;
533 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
534 self, false, do_access_check);
535 if (LIKELY(c != nullptr)) {
536 if (UNLIKELY(c->IsStringClass())) {
537 gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
538 mirror::SetStringCountVisitor visitor(0);
539 obj = String::Alloc<true>(self, 0, allocator_type, visitor);
540 } else {
541 obj = AllocObjectFromCode<do_access_check, true>(
542 inst->VRegB_21c(), shadow_frame.GetMethod(), self,
543 Runtime::Current()->GetHeap()->GetCurrentAllocator());
544 }
545 }
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700546 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200547 HANDLE_PENDING_EXCEPTION();
548 } else {
Sebastien Hertz4e99b3d2014-06-24 14:35:40 +0200549 obj->GetClass()->AssertInitializedOrInitializingInThread(self);
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700550 // Don't allow finalizable objects to be allocated during a transaction since these can't be
551 // finalized without a started runtime.
552 if (transaction_active && obj->GetClass()->IsFinalizable()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +0200553 AbortTransactionF(self, "Allocating finalizable object in transaction: %s",
554 PrettyTypeOf(obj).c_str());
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700555 HANDLE_PENDING_EXCEPTION();
556 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200557 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200558 ADVANCE(2);
559 }
560 }
561 HANDLE_INSTRUCTION_END();
562
563 HANDLE_INSTRUCTION_START(NEW_ARRAY) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200564 int32_t length = shadow_frame.GetVReg(inst->VRegB_22c(inst_data));
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800565 Object* obj = AllocArrayFromCode<do_access_check, true>(
Andreas Gampe1cc7dba2014-12-17 18:43:01 -0800566 inst->VRegC_22c(), length, shadow_frame.GetMethod(), self,
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800567 Runtime::Current()->GetHeap()->GetCurrentAllocator());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700568 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200569 HANDLE_PENDING_EXCEPTION();
570 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200571 shadow_frame.SetVRegReference(inst->VRegA_22c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200572 ADVANCE(2);
573 }
574 }
575 HANDLE_INSTRUCTION_END();
576
577 HANDLE_INSTRUCTION_START(FILLED_NEW_ARRAY) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100578 bool success =
579 DoFilledNewArray<false, do_access_check, transaction_active>(inst, shadow_frame,
580 self, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200581 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
582 }
583 HANDLE_INSTRUCTION_END();
584
585 HANDLE_INSTRUCTION_START(FILLED_NEW_ARRAY_RANGE) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100586 bool success =
587 DoFilledNewArray<true, do_access_check, transaction_active>(inst, shadow_frame,
588 self, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200589 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
590 }
591 HANDLE_INSTRUCTION_END();
592
593 HANDLE_INSTRUCTION_START(FILL_ARRAY_DATA) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200594 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_31t(inst_data));
Ian Rogers832336b2014-10-08 15:35:22 -0700595 const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t();
596 const Instruction::ArrayDataPayload* payload =
597 reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr);
598 bool success = FillArrayData(obj, payload);
599 if (transaction_active && success) {
600 RecordArrayElementsInTransaction(obj->AsArray(), payload->element_count);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200601 }
Ian Rogers832336b2014-10-08 15:35:22 -0700602 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200603 }
604 HANDLE_INSTRUCTION_END();
605
606 HANDLE_INSTRUCTION_START(THROW) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200607 Object* exception = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700608 if (UNLIKELY(exception == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000609 ThrowNullPointerException("throw with null exception");
Jeff Haoa3faaf42013-09-03 19:07:00 -0700610 } else if (do_assignability_check && !exception->GetClass()->IsThrowableClass()) {
611 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700612 std::string temp;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000613 self->ThrowNewExceptionF("Ljava/lang/VirtualMachineError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700614 "Throwing '%s' that is not instance of Throwable",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700615 exception->GetClass()->GetDescriptor(&temp));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200616 } else {
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000617 self->SetException(exception->AsThrowable());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200618 }
619 HANDLE_PENDING_EXCEPTION();
620 }
621 HANDLE_INSTRUCTION_END();
622
623 HANDLE_INSTRUCTION_START(GOTO) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200624 int8_t offset = inst->VRegA_10t(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200625 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800626 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200627 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700628 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200629 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200630 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200631 }
632 ADVANCE(offset);
633 }
634 HANDLE_INSTRUCTION_END();
635
636 HANDLE_INSTRUCTION_START(GOTO_16) {
637 int16_t offset = inst->VRegA_20t();
638 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800639 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200640 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700641 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200642 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200643 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200644 }
645 ADVANCE(offset);
646 }
647 HANDLE_INSTRUCTION_END();
648
649 HANDLE_INSTRUCTION_START(GOTO_32) {
650 int32_t offset = inst->VRegA_30t();
651 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800652 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200653 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700654 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200655 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200656 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200657 }
658 ADVANCE(offset);
659 }
660 HANDLE_INSTRUCTION_END();
661
662 HANDLE_INSTRUCTION_START(PACKED_SWITCH) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200663 int32_t offset = DoPackedSwitch(inst, shadow_frame, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200664 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800665 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200666 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700667 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200668 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200669 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200670 }
671 ADVANCE(offset);
672 }
673 HANDLE_INSTRUCTION_END();
674
675 HANDLE_INSTRUCTION_START(SPARSE_SWITCH) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200676 int32_t offset = DoSparseSwitch(inst, shadow_frame, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200677 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800678 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200679 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700680 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200681 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200682 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200683 }
684 ADVANCE(offset);
685 }
686 HANDLE_INSTRUCTION_END();
687
Ian Rogers647b1a82014-10-10 11:02:11 -0700688#if defined(__clang__)
689#pragma clang diagnostic push
690#pragma clang diagnostic ignored "-Wfloat-equal"
691#endif
692
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200693 HANDLE_INSTRUCTION_START(CMPL_FLOAT) {
694 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
695 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
696 int32_t result;
697 if (val1 > val2) {
698 result = 1;
699 } else if (val1 == val2) {
700 result = 0;
701 } else {
702 result = -1;
703 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200704 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200705 ADVANCE(2);
706 }
707 HANDLE_INSTRUCTION_END();
708
709 HANDLE_INSTRUCTION_START(CMPG_FLOAT) {
710 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
711 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
712 int32_t result;
713 if (val1 < val2) {
714 result = -1;
715 } else if (val1 == val2) {
716 result = 0;
717 } else {
718 result = 1;
719 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200720 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200721 ADVANCE(2);
722 }
723 HANDLE_INSTRUCTION_END();
724
725 HANDLE_INSTRUCTION_START(CMPL_DOUBLE) {
726 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
727 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
728 int32_t result;
729 if (val1 > val2) {
730 result = 1;
731 } else if (val1 == val2) {
732 result = 0;
733 } else {
734 result = -1;
735 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200736 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200737 ADVANCE(2);
738 }
739 HANDLE_INSTRUCTION_END();
740
741 HANDLE_INSTRUCTION_START(CMPG_DOUBLE) {
742 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
743 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
744 int32_t result;
745 if (val1 < val2) {
746 result = -1;
747 } else if (val1 == val2) {
748 result = 0;
749 } else {
750 result = 1;
751 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200752 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200753 ADVANCE(2);
754 }
755 HANDLE_INSTRUCTION_END();
756
Ian Rogers647b1a82014-10-10 11:02:11 -0700757#if defined(__clang__)
758#pragma clang diagnostic pop
759#endif
760
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200761 HANDLE_INSTRUCTION_START(CMP_LONG) {
762 int64_t val1 = shadow_frame.GetVRegLong(inst->VRegB_23x());
763 int64_t val2 = shadow_frame.GetVRegLong(inst->VRegC_23x());
764 int32_t result;
765 if (val1 > val2) {
766 result = 1;
767 } else if (val1 == val2) {
768 result = 0;
769 } else {
770 result = -1;
771 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200772 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200773 ADVANCE(2);
774 }
775 HANDLE_INSTRUCTION_END();
776
777 HANDLE_INSTRUCTION_START(IF_EQ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200778 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) == shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200779 int16_t offset = inst->VRegC_22t();
780 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800781 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200782 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700783 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200784 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200785 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200786 }
787 ADVANCE(offset);
788 } else {
789 ADVANCE(2);
790 }
791 }
792 HANDLE_INSTRUCTION_END();
793
794 HANDLE_INSTRUCTION_START(IF_NE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700795 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) !=
796 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200797 int16_t offset = inst->VRegC_22t();
798 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800799 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200800 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700801 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200802 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200803 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200804 }
805 ADVANCE(offset);
806 } else {
807 ADVANCE(2);
808 }
809 }
810 HANDLE_INSTRUCTION_END();
811
812 HANDLE_INSTRUCTION_START(IF_LT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700813 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <
814 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200815 int16_t offset = inst->VRegC_22t();
816 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800817 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200818 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700819 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200820 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200821 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200822 }
823 ADVANCE(offset);
824 } else {
825 ADVANCE(2);
826 }
827 }
828 HANDLE_INSTRUCTION_END();
829
830 HANDLE_INSTRUCTION_START(IF_GE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700831 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >=
832 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200833 int16_t offset = inst->VRegC_22t();
834 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800835 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200836 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700837 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200838 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200839 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200840 }
841 ADVANCE(offset);
842 } else {
843 ADVANCE(2);
844 }
845 }
846 HANDLE_INSTRUCTION_END();
847
848 HANDLE_INSTRUCTION_START(IF_GT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700849 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >
850 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200851 int16_t offset = inst->VRegC_22t();
852 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800853 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200854 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700855 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200856 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200857 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200858 }
859 ADVANCE(offset);
860 } else {
861 ADVANCE(2);
862 }
863 }
864 HANDLE_INSTRUCTION_END();
865
866 HANDLE_INSTRUCTION_START(IF_LE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700867 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <=
868 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200869 int16_t offset = inst->VRegC_22t();
870 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800871 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200872 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700873 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200874 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200875 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200876 }
877 ADVANCE(offset);
878 } else {
879 ADVANCE(2);
880 }
881 }
882 HANDLE_INSTRUCTION_END();
883
884 HANDLE_INSTRUCTION_START(IF_EQZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200885 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) == 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200886 int16_t offset = inst->VRegB_21t();
887 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800888 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200889 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700890 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200891 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200892 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200893 }
894 ADVANCE(offset);
895 } else {
896 ADVANCE(2);
897 }
898 }
899 HANDLE_INSTRUCTION_END();
900
901 HANDLE_INSTRUCTION_START(IF_NEZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200902 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) != 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200903 int16_t offset = inst->VRegB_21t();
904 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800905 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200906 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700907 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200908 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200909 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200910 }
911 ADVANCE(offset);
912 } else {
913 ADVANCE(2);
914 }
915 }
916 HANDLE_INSTRUCTION_END();
917
918 HANDLE_INSTRUCTION_START(IF_LTZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200919 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) < 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200920 int16_t offset = inst->VRegB_21t();
921 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800922 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200923 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700924 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200925 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200926 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200927 }
928 ADVANCE(offset);
929 } else {
930 ADVANCE(2);
931 }
932 }
933 HANDLE_INSTRUCTION_END();
934
935 HANDLE_INSTRUCTION_START(IF_GEZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200936 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) >= 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200937 int16_t offset = inst->VRegB_21t();
938 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800939 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200940 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700941 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200942 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200943 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200944 }
945 ADVANCE(offset);
946 } else {
947 ADVANCE(2);
948 }
949 }
950 HANDLE_INSTRUCTION_END();
951
952 HANDLE_INSTRUCTION_START(IF_GTZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200953 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) > 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200954 int16_t offset = inst->VRegB_21t();
955 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800956 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200957 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700958 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200959 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200960 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200961 }
962 ADVANCE(offset);
963 } else {
964 ADVANCE(2);
965 }
966 }
967 HANDLE_INSTRUCTION_END();
968
969 HANDLE_INSTRUCTION_START(IF_LEZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200970 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) <= 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200971 int16_t offset = inst->VRegB_21t();
972 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800973 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200974 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700975 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200976 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200977 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200978 }
979 ADVANCE(offset);
980 } else {
981 ADVANCE(2);
982 }
983 }
984 HANDLE_INSTRUCTION_END();
985
986 HANDLE_INSTRUCTION_START(AGET_BOOLEAN) {
987 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700988 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000989 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200990 HANDLE_PENDING_EXCEPTION();
991 } else {
992 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
993 BooleanArray* array = a->AsBooleanArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +0100994 if (LIKELY(array->CheckIsValidIndex(index))) {
995 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200996 ADVANCE(2);
997 } else {
998 HANDLE_PENDING_EXCEPTION();
999 }
1000 }
1001 }
1002 HANDLE_INSTRUCTION_END();
1003
1004 HANDLE_INSTRUCTION_START(AGET_BYTE) {
1005 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001006 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001007 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001008 HANDLE_PENDING_EXCEPTION();
1009 } else {
1010 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1011 ByteArray* array = a->AsByteArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001012 if (LIKELY(array->CheckIsValidIndex(index))) {
1013 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001014 ADVANCE(2);
1015 } else {
1016 HANDLE_PENDING_EXCEPTION();
1017 }
1018 }
1019 }
1020 HANDLE_INSTRUCTION_END();
1021
1022 HANDLE_INSTRUCTION_START(AGET_CHAR) {
1023 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001024 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001025 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001026 HANDLE_PENDING_EXCEPTION();
1027 } else {
1028 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1029 CharArray* array = a->AsCharArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001030 if (LIKELY(array->CheckIsValidIndex(index))) {
1031 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001032 ADVANCE(2);
1033 } else {
1034 HANDLE_PENDING_EXCEPTION();
1035 }
1036 }
1037 }
1038 HANDLE_INSTRUCTION_END();
1039
1040 HANDLE_INSTRUCTION_START(AGET_SHORT) {
1041 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001042 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001043 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001044 HANDLE_PENDING_EXCEPTION();
1045 } else {
1046 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1047 ShortArray* array = a->AsShortArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001048 if (LIKELY(array->CheckIsValidIndex(index))) {
1049 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001050 ADVANCE(2);
1051 } else {
1052 HANDLE_PENDING_EXCEPTION();
1053 }
1054 }
1055 }
1056 HANDLE_INSTRUCTION_END();
1057
1058 HANDLE_INSTRUCTION_START(AGET) {
1059 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001060 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001061 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001062 HANDLE_PENDING_EXCEPTION();
1063 } else {
1064 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001065 DCHECK(a->IsIntArray() || a->IsFloatArray()) << PrettyTypeOf(a);
1066 auto* array = down_cast<IntArray*>(a);
Sebastien Hertzabff6432014-01-27 18:01:39 +01001067 if (LIKELY(array->CheckIsValidIndex(index))) {
1068 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001069 ADVANCE(2);
1070 } else {
1071 HANDLE_PENDING_EXCEPTION();
1072 }
1073 }
1074 }
1075 HANDLE_INSTRUCTION_END();
1076
1077 HANDLE_INSTRUCTION_START(AGET_WIDE) {
1078 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001079 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001080 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001081 HANDLE_PENDING_EXCEPTION();
1082 } else {
1083 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001084 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << PrettyTypeOf(a);
1085 auto* array = down_cast<LongArray*>(a);
Sebastien Hertzabff6432014-01-27 18:01:39 +01001086 if (LIKELY(array->CheckIsValidIndex(index))) {
1087 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001088 ADVANCE(2);
1089 } else {
1090 HANDLE_PENDING_EXCEPTION();
1091 }
1092 }
1093 }
1094 HANDLE_INSTRUCTION_END();
1095
1096 HANDLE_INSTRUCTION_START(AGET_OBJECT) {
1097 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001098 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001099 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001100 HANDLE_PENDING_EXCEPTION();
1101 } else {
1102 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1103 ObjectArray<Object>* array = a->AsObjectArray<Object>();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001104 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001105 shadow_frame.SetVRegReference(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001106 ADVANCE(2);
1107 } else {
1108 HANDLE_PENDING_EXCEPTION();
1109 }
1110 }
1111 }
1112 HANDLE_INSTRUCTION_END();
1113
1114 HANDLE_INSTRUCTION_START(APUT_BOOLEAN) {
1115 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001116 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001117 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001118 HANDLE_PENDING_EXCEPTION();
1119 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001120 uint8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001121 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1122 BooleanArray* array = a->AsBooleanArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001123 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001124 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001125 ADVANCE(2);
1126 } else {
1127 HANDLE_PENDING_EXCEPTION();
1128 }
1129 }
1130 }
1131 HANDLE_INSTRUCTION_END();
1132
1133 HANDLE_INSTRUCTION_START(APUT_BYTE) {
1134 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001135 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001136 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001137 HANDLE_PENDING_EXCEPTION();
1138 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001139 int8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001140 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1141 ByteArray* array = a->AsByteArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001142 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001143 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001144 ADVANCE(2);
1145 } else {
1146 HANDLE_PENDING_EXCEPTION();
1147 }
1148 }
1149 }
1150 HANDLE_INSTRUCTION_END();
1151
1152 HANDLE_INSTRUCTION_START(APUT_CHAR) {
1153 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001154 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001155 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001156 HANDLE_PENDING_EXCEPTION();
1157 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001158 uint16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001159 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1160 CharArray* array = a->AsCharArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001161 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001162 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001163 ADVANCE(2);
1164 } else {
1165 HANDLE_PENDING_EXCEPTION();
1166 }
1167 }
1168 }
1169 HANDLE_INSTRUCTION_END();
1170
1171 HANDLE_INSTRUCTION_START(APUT_SHORT) {
1172 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001173 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001174 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001175 HANDLE_PENDING_EXCEPTION();
1176 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001177 int16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001178 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1179 ShortArray* array = a->AsShortArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001180 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001181 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001182 ADVANCE(2);
1183 } else {
1184 HANDLE_PENDING_EXCEPTION();
1185 }
1186 }
1187 }
1188 HANDLE_INSTRUCTION_END();
1189
1190 HANDLE_INSTRUCTION_START(APUT) {
1191 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001192 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001193 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001194 HANDLE_PENDING_EXCEPTION();
1195 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001196 int32_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001197 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001198 DCHECK(a->IsIntArray() || a->IsFloatArray()) << PrettyTypeOf(a);
1199 auto* array = down_cast<IntArray*>(a);
Sebastien Hertzabff6432014-01-27 18:01:39 +01001200 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001201 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001202 ADVANCE(2);
1203 } else {
1204 HANDLE_PENDING_EXCEPTION();
1205 }
1206 }
1207 }
1208 HANDLE_INSTRUCTION_END();
1209
1210 HANDLE_INSTRUCTION_START(APUT_WIDE) {
1211 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001212 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001213 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001214 HANDLE_PENDING_EXCEPTION();
1215 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001216 int64_t val = shadow_frame.GetVRegLong(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001217 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001218 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << PrettyTypeOf(a);
1219 auto* array = down_cast<LongArray*>(a);
Sebastien Hertzabff6432014-01-27 18:01:39 +01001220 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001221 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001222 ADVANCE(2);
1223 } else {
1224 HANDLE_PENDING_EXCEPTION();
1225 }
1226 }
1227 }
1228 HANDLE_INSTRUCTION_END();
1229
1230 HANDLE_INSTRUCTION_START(APUT_OBJECT) {
1231 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001232 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001233 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001234 HANDLE_PENDING_EXCEPTION();
1235 } else {
1236 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001237 Object* val = shadow_frame.GetVRegReference(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001238 ObjectArray<Object>* array = a->AsObjectArray<Object>();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001239 if (LIKELY(array->CheckIsValidIndex(index) && array->CheckAssignable(val))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001240 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001241 ADVANCE(2);
1242 } else {
1243 HANDLE_PENDING_EXCEPTION();
1244 }
1245 }
1246 }
1247 HANDLE_INSTRUCTION_END();
1248
1249 HANDLE_INSTRUCTION_START(IGET_BOOLEAN) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001250 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimBoolean, do_access_check>(
1251 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001252 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1253 }
1254 HANDLE_INSTRUCTION_END();
1255
1256 HANDLE_INSTRUCTION_START(IGET_BYTE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001257 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimByte, do_access_check>(
1258 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001259 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1260 }
1261 HANDLE_INSTRUCTION_END();
1262
1263 HANDLE_INSTRUCTION_START(IGET_CHAR) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001264 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimChar, do_access_check>(
1265 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001266 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1267 }
1268 HANDLE_INSTRUCTION_END();
1269
1270 HANDLE_INSTRUCTION_START(IGET_SHORT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001271 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimShort, do_access_check>(
1272 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001273 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1274 }
1275 HANDLE_INSTRUCTION_END();
1276
1277 HANDLE_INSTRUCTION_START(IGET) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001278 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimInt, do_access_check>(
1279 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001280 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1281 }
1282 HANDLE_INSTRUCTION_END();
1283
1284 HANDLE_INSTRUCTION_START(IGET_WIDE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001285 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimLong, do_access_check>(
1286 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001287 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1288 }
1289 HANDLE_INSTRUCTION_END();
1290
1291 HANDLE_INSTRUCTION_START(IGET_OBJECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001292 bool success = DoFieldGet<InstanceObjectRead, Primitive::kPrimNot, do_access_check>(
1293 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001294 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1295 }
1296 HANDLE_INSTRUCTION_END();
1297
1298 HANDLE_INSTRUCTION_START(IGET_QUICK) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001299 bool success = DoIGetQuick<Primitive::kPrimInt>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001300 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1301 }
1302 HANDLE_INSTRUCTION_END();
1303
Mathieu Chartierffc605c2014-12-10 10:35:44 -08001304 HANDLE_INSTRUCTION_START(IGET_BOOLEAN_QUICK) {
1305 bool success = DoIGetQuick<Primitive::kPrimBoolean>(shadow_frame, inst, inst_data);
1306 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1307 }
1308 HANDLE_INSTRUCTION_END();
1309
1310 HANDLE_INSTRUCTION_START(IGET_BYTE_QUICK) {
1311 bool success = DoIGetQuick<Primitive::kPrimByte>(shadow_frame, inst, inst_data);
1312 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1313 }
1314 HANDLE_INSTRUCTION_END();
1315
1316 HANDLE_INSTRUCTION_START(IGET_CHAR_QUICK) {
1317 bool success = DoIGetQuick<Primitive::kPrimChar>(shadow_frame, inst, inst_data);
1318 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1319 }
1320 HANDLE_INSTRUCTION_END();
1321
1322 HANDLE_INSTRUCTION_START(IGET_SHORT_QUICK) {
1323 bool success = DoIGetQuick<Primitive::kPrimShort>(shadow_frame, inst, inst_data);
1324 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1325 }
1326 HANDLE_INSTRUCTION_END();
1327
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001328 HANDLE_INSTRUCTION_START(IGET_WIDE_QUICK) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001329 bool success = DoIGetQuick<Primitive::kPrimLong>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001330 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1331 }
1332 HANDLE_INSTRUCTION_END();
1333
1334 HANDLE_INSTRUCTION_START(IGET_OBJECT_QUICK) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001335 bool success = DoIGetQuick<Primitive::kPrimNot>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001336 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1337 }
1338 HANDLE_INSTRUCTION_END();
1339
1340 HANDLE_INSTRUCTION_START(SGET_BOOLEAN) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001341 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimBoolean, do_access_check>(
1342 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001343 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1344 }
1345 HANDLE_INSTRUCTION_END();
1346
1347 HANDLE_INSTRUCTION_START(SGET_BYTE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001348 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimByte, do_access_check>(
1349 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001350 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1351 }
1352 HANDLE_INSTRUCTION_END();
1353
1354 HANDLE_INSTRUCTION_START(SGET_CHAR) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001355 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimChar, do_access_check>(
1356 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001357 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1358 }
1359 HANDLE_INSTRUCTION_END();
1360
1361 HANDLE_INSTRUCTION_START(SGET_SHORT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001362 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimShort, do_access_check>(
1363 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001364 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1365 }
1366 HANDLE_INSTRUCTION_END();
1367
1368 HANDLE_INSTRUCTION_START(SGET) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001369 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimInt, do_access_check>(
1370 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001371 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1372 }
1373 HANDLE_INSTRUCTION_END();
1374
1375 HANDLE_INSTRUCTION_START(SGET_WIDE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001376 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimLong, do_access_check>(
1377 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001378 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1379 }
1380 HANDLE_INSTRUCTION_END();
1381
1382 HANDLE_INSTRUCTION_START(SGET_OBJECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001383 bool success = DoFieldGet<StaticObjectRead, Primitive::kPrimNot, do_access_check>(
1384 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001385 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1386 }
1387 HANDLE_INSTRUCTION_END();
1388
1389 HANDLE_INSTRUCTION_START(IPUT_BOOLEAN) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001390 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1391 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001392 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1393 }
1394 HANDLE_INSTRUCTION_END();
1395
1396 HANDLE_INSTRUCTION_START(IPUT_BYTE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001397 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimByte, do_access_check,
1398 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001399 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1400 }
1401 HANDLE_INSTRUCTION_END();
1402
1403 HANDLE_INSTRUCTION_START(IPUT_CHAR) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001404 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimChar, do_access_check,
1405 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001406 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1407 }
1408 HANDLE_INSTRUCTION_END();
1409
1410 HANDLE_INSTRUCTION_START(IPUT_SHORT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001411 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimShort, do_access_check,
1412 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001413 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1414 }
1415 HANDLE_INSTRUCTION_END();
1416
1417 HANDLE_INSTRUCTION_START(IPUT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001418 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimInt, do_access_check,
1419 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001420 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1421 }
1422 HANDLE_INSTRUCTION_END();
1423
1424 HANDLE_INSTRUCTION_START(IPUT_WIDE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001425 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimLong, do_access_check,
1426 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001427 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1428 }
1429 HANDLE_INSTRUCTION_END();
1430
1431 HANDLE_INSTRUCTION_START(IPUT_OBJECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001432 bool success = DoFieldPut<InstanceObjectWrite, Primitive::kPrimNot, do_access_check,
1433 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001434 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1435 }
1436 HANDLE_INSTRUCTION_END();
1437
1438 HANDLE_INSTRUCTION_START(IPUT_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001439 bool success = DoIPutQuick<Primitive::kPrimInt, transaction_active>(
1440 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001441 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1442 }
1443 HANDLE_INSTRUCTION_END();
1444
Fred Shih37f05ef2014-07-16 18:38:08 -07001445 HANDLE_INSTRUCTION_START(IPUT_BOOLEAN_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001446 bool success = DoIPutQuick<Primitive::kPrimBoolean, transaction_active>(
1447 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001448 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1449 }
1450 HANDLE_INSTRUCTION_END();
1451
1452 HANDLE_INSTRUCTION_START(IPUT_BYTE_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001453 bool success = DoIPutQuick<Primitive::kPrimByte, transaction_active>(
1454 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001455 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1456 }
1457 HANDLE_INSTRUCTION_END();
1458
1459 HANDLE_INSTRUCTION_START(IPUT_CHAR_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001460 bool success = DoIPutQuick<Primitive::kPrimChar, transaction_active>(
1461 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001462 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1463 }
1464 HANDLE_INSTRUCTION_END();
1465
1466 HANDLE_INSTRUCTION_START(IPUT_SHORT_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001467 bool success = DoIPutQuick<Primitive::kPrimShort, transaction_active>(
1468 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001469 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1470 }
1471 HANDLE_INSTRUCTION_END();
1472
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001473 HANDLE_INSTRUCTION_START(IPUT_WIDE_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001474 bool success = DoIPutQuick<Primitive::kPrimLong, transaction_active>(
1475 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001476 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1477 }
1478 HANDLE_INSTRUCTION_END();
1479
1480 HANDLE_INSTRUCTION_START(IPUT_OBJECT_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001481 bool success = DoIPutQuick<Primitive::kPrimNot, transaction_active>(
1482 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001483 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1484 }
1485 HANDLE_INSTRUCTION_END();
1486
1487 HANDLE_INSTRUCTION_START(SPUT_BOOLEAN) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001488 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1489 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001490 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1491 }
1492 HANDLE_INSTRUCTION_END();
1493
1494 HANDLE_INSTRUCTION_START(SPUT_BYTE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001495 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimByte, do_access_check,
1496 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001497 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1498 }
1499 HANDLE_INSTRUCTION_END();
1500
1501 HANDLE_INSTRUCTION_START(SPUT_CHAR) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001502 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimChar, do_access_check,
1503 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001504 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1505 }
1506 HANDLE_INSTRUCTION_END();
1507
1508 HANDLE_INSTRUCTION_START(SPUT_SHORT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001509 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimShort, do_access_check,
1510 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001511 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1512 }
1513 HANDLE_INSTRUCTION_END();
1514
1515 HANDLE_INSTRUCTION_START(SPUT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001516 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimInt, do_access_check,
1517 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001518 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1519 }
1520 HANDLE_INSTRUCTION_END();
1521
1522 HANDLE_INSTRUCTION_START(SPUT_WIDE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001523 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimLong, do_access_check,
1524 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001525 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1526 }
1527 HANDLE_INSTRUCTION_END();
1528
1529 HANDLE_INSTRUCTION_START(SPUT_OBJECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001530 bool success = DoFieldPut<StaticObjectWrite, Primitive::kPrimNot, do_access_check,
1531 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001532 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1533 }
1534 HANDLE_INSTRUCTION_END();
1535
1536 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001537 bool success = DoInvoke<kVirtual, false, do_access_check>(
1538 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001539 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001540 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1541 }
1542 HANDLE_INSTRUCTION_END();
1543
1544 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001545 bool success = DoInvoke<kVirtual, true, do_access_check>(
1546 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001547 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001548 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1549 }
1550 HANDLE_INSTRUCTION_END();
1551
1552 HANDLE_INSTRUCTION_START(INVOKE_SUPER) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001553 bool success = DoInvoke<kSuper, false, do_access_check>(
1554 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001555 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001556 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1557 }
1558 HANDLE_INSTRUCTION_END();
1559
1560 HANDLE_INSTRUCTION_START(INVOKE_SUPER_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001561 bool success = DoInvoke<kSuper, true, do_access_check>(
1562 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001563 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001564 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1565 }
1566 HANDLE_INSTRUCTION_END();
1567
1568 HANDLE_INSTRUCTION_START(INVOKE_DIRECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001569 bool success = DoInvoke<kDirect, false, do_access_check>(
1570 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001571 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001572 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1573 }
1574 HANDLE_INSTRUCTION_END();
1575
1576 HANDLE_INSTRUCTION_START(INVOKE_DIRECT_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001577 bool success = DoInvoke<kDirect, true, do_access_check>(
1578 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001579 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001580 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1581 }
1582 HANDLE_INSTRUCTION_END();
1583
1584 HANDLE_INSTRUCTION_START(INVOKE_INTERFACE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001585 bool success = DoInvoke<kInterface, false, do_access_check>(
1586 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001587 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001588 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1589 }
1590 HANDLE_INSTRUCTION_END();
1591
1592 HANDLE_INSTRUCTION_START(INVOKE_INTERFACE_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001593 bool success = DoInvoke<kInterface, true, do_access_check>(
1594 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001595 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001596 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1597 }
1598 HANDLE_INSTRUCTION_END();
1599
1600 HANDLE_INSTRUCTION_START(INVOKE_STATIC) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001601 bool success = DoInvoke<kStatic, false, do_access_check>(
1602 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001603 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001604 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1605 }
1606 HANDLE_INSTRUCTION_END();
1607
1608 HANDLE_INSTRUCTION_START(INVOKE_STATIC_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001609 bool success = DoInvoke<kStatic, true, do_access_check>(
1610 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001611 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001612 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1613 }
1614 HANDLE_INSTRUCTION_END();
1615
1616 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001617 bool success = DoInvokeVirtualQuick<false>(
1618 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001619 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001620 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1621 }
1622 HANDLE_INSTRUCTION_END();
1623
1624 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_RANGE_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001625 bool success = DoInvokeVirtualQuick<true>(
1626 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001627 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001628 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1629 }
1630 HANDLE_INSTRUCTION_END();
1631
Igor Murashkin158f35c2015-06-10 15:55:30 -07001632 HANDLE_EXPERIMENTAL_INSTRUCTION_START(INVOKE_LAMBDA) {
1633 bool success = DoInvokeLambda<do_access_check>(self, shadow_frame, inst, inst_data,
1634 &result_register);
1635 UPDATE_HANDLER_TABLE();
1636 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1637 }
1638 HANDLE_EXPERIMENTAL_INSTRUCTION_END();
1639
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001640 HANDLE_INSTRUCTION_START(NEG_INT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001641 shadow_frame.SetVReg(
1642 inst->VRegA_12x(inst_data), -shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001643 ADVANCE(1);
1644 HANDLE_INSTRUCTION_END();
1645
1646 HANDLE_INSTRUCTION_START(NOT_INT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001647 shadow_frame.SetVReg(
1648 inst->VRegA_12x(inst_data), ~shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001649 ADVANCE(1);
1650 HANDLE_INSTRUCTION_END();
1651
1652 HANDLE_INSTRUCTION_START(NEG_LONG)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001653 shadow_frame.SetVRegLong(
1654 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001655 ADVANCE(1);
1656 HANDLE_INSTRUCTION_END();
1657
1658 HANDLE_INSTRUCTION_START(NOT_LONG)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001659 shadow_frame.SetVRegLong(
1660 inst->VRegA_12x(inst_data), ~shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001661 ADVANCE(1);
1662 HANDLE_INSTRUCTION_END();
1663
1664 HANDLE_INSTRUCTION_START(NEG_FLOAT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001665 shadow_frame.SetVRegFloat(
1666 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001667 ADVANCE(1);
1668 HANDLE_INSTRUCTION_END();
1669
1670 HANDLE_INSTRUCTION_START(NEG_DOUBLE)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001671 shadow_frame.SetVRegDouble(
1672 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001673 ADVANCE(1);
1674 HANDLE_INSTRUCTION_END();
1675
1676 HANDLE_INSTRUCTION_START(INT_TO_LONG)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001677 shadow_frame.SetVRegLong(
1678 inst->VRegA_12x(inst_data), shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001679 ADVANCE(1);
1680 HANDLE_INSTRUCTION_END();
1681
1682 HANDLE_INSTRUCTION_START(INT_TO_FLOAT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001683 shadow_frame.SetVRegFloat(
1684 inst->VRegA_12x(inst_data), shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001685 ADVANCE(1);
1686 HANDLE_INSTRUCTION_END();
1687
1688 HANDLE_INSTRUCTION_START(INT_TO_DOUBLE)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001689 shadow_frame.SetVRegDouble(
1690 inst->VRegA_12x(inst_data), shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001691 ADVANCE(1);
1692 HANDLE_INSTRUCTION_END();
1693
1694 HANDLE_INSTRUCTION_START(LONG_TO_INT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001695 shadow_frame.SetVReg(
1696 inst->VRegA_12x(inst_data), shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001697 ADVANCE(1);
1698 HANDLE_INSTRUCTION_END();
1699
1700 HANDLE_INSTRUCTION_START(LONG_TO_FLOAT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001701 shadow_frame.SetVRegFloat(
1702 inst->VRegA_12x(inst_data), shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001703 ADVANCE(1);
1704 HANDLE_INSTRUCTION_END();
1705
1706 HANDLE_INSTRUCTION_START(LONG_TO_DOUBLE)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001707 shadow_frame.SetVRegDouble(
1708 inst->VRegA_12x(inst_data), shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001709 ADVANCE(1);
1710 HANDLE_INSTRUCTION_END();
1711
1712 HANDLE_INSTRUCTION_START(FLOAT_TO_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001713 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001714 int32_t result = art_float_to_integral<int32_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001715 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001716 ADVANCE(1);
1717 }
1718 HANDLE_INSTRUCTION_END();
1719
1720 HANDLE_INSTRUCTION_START(FLOAT_TO_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001721 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001722 int64_t result = art_float_to_integral<int64_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001723 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001724 ADVANCE(1);
1725 }
1726 HANDLE_INSTRUCTION_END();
1727
1728 HANDLE_INSTRUCTION_START(FLOAT_TO_DOUBLE)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001729 shadow_frame.SetVRegDouble(
1730 inst->VRegA_12x(inst_data), shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001731 ADVANCE(1);
1732 HANDLE_INSTRUCTION_END();
1733
1734 HANDLE_INSTRUCTION_START(DOUBLE_TO_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001735 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001736 int32_t result = art_float_to_integral<int32_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001737 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001738 ADVANCE(1);
1739 }
1740 HANDLE_INSTRUCTION_END();
1741
1742 HANDLE_INSTRUCTION_START(DOUBLE_TO_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001743 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001744 int64_t result = art_float_to_integral<int64_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001745 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001746 ADVANCE(1);
1747 }
1748 HANDLE_INSTRUCTION_END();
1749
1750 HANDLE_INSTRUCTION_START(DOUBLE_TO_FLOAT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001751 shadow_frame.SetVRegFloat(
1752 inst->VRegA_12x(inst_data), shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001753 ADVANCE(1);
1754 HANDLE_INSTRUCTION_END();
1755
1756 HANDLE_INSTRUCTION_START(INT_TO_BYTE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001757 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1758 static_cast<int8_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001759 ADVANCE(1);
1760 HANDLE_INSTRUCTION_END();
1761
1762 HANDLE_INSTRUCTION_START(INT_TO_CHAR)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001763 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1764 static_cast<uint16_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001765 ADVANCE(1);
1766 HANDLE_INSTRUCTION_END();
1767
1768 HANDLE_INSTRUCTION_START(INT_TO_SHORT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001769 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1770 static_cast<int16_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001771 ADVANCE(1);
1772 HANDLE_INSTRUCTION_END();
1773
1774 HANDLE_INSTRUCTION_START(ADD_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001775 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001776 SafeAdd(shadow_frame.GetVReg(inst->VRegB_23x()),
1777 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001778 ADVANCE(2);
1779 HANDLE_INSTRUCTION_END();
1780
1781 HANDLE_INSTRUCTION_START(SUB_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001782 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001783 SafeSub(shadow_frame.GetVReg(inst->VRegB_23x()),
1784 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001785 ADVANCE(2);
1786 HANDLE_INSTRUCTION_END();
1787
1788 HANDLE_INSTRUCTION_START(MUL_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001789 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001790 SafeMul(shadow_frame.GetVReg(inst->VRegB_23x()),
1791 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001792 ADVANCE(2);
1793 HANDLE_INSTRUCTION_END();
1794
1795 HANDLE_INSTRUCTION_START(DIV_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001796 bool success = DoIntDivide(shadow_frame, inst->VRegA_23x(inst_data),
1797 shadow_frame.GetVReg(inst->VRegB_23x()),
1798 shadow_frame.GetVReg(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001799 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1800 }
1801 HANDLE_INSTRUCTION_END();
1802
1803 HANDLE_INSTRUCTION_START(REM_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001804 bool success = DoIntRemainder(shadow_frame, inst->VRegA_23x(inst_data),
1805 shadow_frame.GetVReg(inst->VRegB_23x()),
1806 shadow_frame.GetVReg(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001807 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1808 }
1809 HANDLE_INSTRUCTION_END();
1810
1811 HANDLE_INSTRUCTION_START(SHL_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001812 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001813 shadow_frame.GetVReg(inst->VRegB_23x()) <<
1814 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1815 ADVANCE(2);
1816 HANDLE_INSTRUCTION_END();
1817
1818 HANDLE_INSTRUCTION_START(SHR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001819 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001820 shadow_frame.GetVReg(inst->VRegB_23x()) >>
1821 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1822 ADVANCE(2);
1823 HANDLE_INSTRUCTION_END();
1824
1825 HANDLE_INSTRUCTION_START(USHR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001826 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001827 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_23x())) >>
1828 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1829 ADVANCE(2);
1830 HANDLE_INSTRUCTION_END();
1831
1832 HANDLE_INSTRUCTION_START(AND_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001833 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001834 shadow_frame.GetVReg(inst->VRegB_23x()) &
1835 shadow_frame.GetVReg(inst->VRegC_23x()));
1836 ADVANCE(2);
1837 HANDLE_INSTRUCTION_END();
1838
1839 HANDLE_INSTRUCTION_START(OR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001840 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001841 shadow_frame.GetVReg(inst->VRegB_23x()) |
1842 shadow_frame.GetVReg(inst->VRegC_23x()));
1843 ADVANCE(2);
1844 HANDLE_INSTRUCTION_END();
1845
1846 HANDLE_INSTRUCTION_START(XOR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001847 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001848 shadow_frame.GetVReg(inst->VRegB_23x()) ^
1849 shadow_frame.GetVReg(inst->VRegC_23x()));
1850 ADVANCE(2);
1851 HANDLE_INSTRUCTION_END();
1852
1853 HANDLE_INSTRUCTION_START(ADD_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001854 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001855 SafeAdd(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1856 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001857 ADVANCE(2);
1858 HANDLE_INSTRUCTION_END();
1859
1860 HANDLE_INSTRUCTION_START(SUB_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001861 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001862 SafeSub(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1863 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001864 ADVANCE(2);
1865 HANDLE_INSTRUCTION_END();
1866
1867 HANDLE_INSTRUCTION_START(MUL_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001868 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001869 SafeMul(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1870 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001871 ADVANCE(2);
1872 HANDLE_INSTRUCTION_END();
1873
1874 HANDLE_INSTRUCTION_START(DIV_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001875 bool success = DoLongDivide(shadow_frame, inst->VRegA_23x(inst_data),
1876 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1877 shadow_frame.GetVRegLong(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001878 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1879 }
1880 HANDLE_INSTRUCTION_END();
1881
1882 HANDLE_INSTRUCTION_START(REM_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001883 bool success = DoLongRemainder(shadow_frame, inst->VRegA_23x(inst_data),
1884 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1885 shadow_frame.GetVRegLong(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001886 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1887 }
1888 HANDLE_INSTRUCTION_END();
1889
1890 HANDLE_INSTRUCTION_START(AND_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001891 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001892 shadow_frame.GetVRegLong(inst->VRegB_23x()) &
1893 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1894 ADVANCE(2);
1895 HANDLE_INSTRUCTION_END();
1896
1897 HANDLE_INSTRUCTION_START(OR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001898 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001899 shadow_frame.GetVRegLong(inst->VRegB_23x()) |
1900 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1901 ADVANCE(2);
1902 HANDLE_INSTRUCTION_END();
1903
1904 HANDLE_INSTRUCTION_START(XOR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001905 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001906 shadow_frame.GetVRegLong(inst->VRegB_23x()) ^
1907 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1908 ADVANCE(2);
1909 HANDLE_INSTRUCTION_END();
1910
1911 HANDLE_INSTRUCTION_START(SHL_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001912 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001913 shadow_frame.GetVRegLong(inst->VRegB_23x()) <<
1914 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1915 ADVANCE(2);
1916 HANDLE_INSTRUCTION_END();
1917
1918 HANDLE_INSTRUCTION_START(SHR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001919 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001920 shadow_frame.GetVRegLong(inst->VRegB_23x()) >>
1921 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1922 ADVANCE(2);
1923 HANDLE_INSTRUCTION_END();
1924
1925 HANDLE_INSTRUCTION_START(USHR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001926 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001927 static_cast<uint64_t>(shadow_frame.GetVRegLong(inst->VRegB_23x())) >>
1928 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1929 ADVANCE(2);
1930 HANDLE_INSTRUCTION_END();
1931
1932 HANDLE_INSTRUCTION_START(ADD_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001933 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001934 shadow_frame.GetVRegFloat(inst->VRegB_23x()) +
1935 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1936 ADVANCE(2);
1937 HANDLE_INSTRUCTION_END();
1938
1939 HANDLE_INSTRUCTION_START(SUB_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001940 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001941 shadow_frame.GetVRegFloat(inst->VRegB_23x()) -
1942 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1943 ADVANCE(2);
1944 HANDLE_INSTRUCTION_END();
1945
1946 HANDLE_INSTRUCTION_START(MUL_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001947 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001948 shadow_frame.GetVRegFloat(inst->VRegB_23x()) *
1949 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1950 ADVANCE(2);
1951 HANDLE_INSTRUCTION_END();
1952
1953 HANDLE_INSTRUCTION_START(DIV_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001954 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001955 shadow_frame.GetVRegFloat(inst->VRegB_23x()) /
1956 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1957 ADVANCE(2);
1958 HANDLE_INSTRUCTION_END();
1959
1960 HANDLE_INSTRUCTION_START(REM_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001961 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001962 fmodf(shadow_frame.GetVRegFloat(inst->VRegB_23x()),
1963 shadow_frame.GetVRegFloat(inst->VRegC_23x())));
1964 ADVANCE(2);
1965 HANDLE_INSTRUCTION_END();
1966
1967 HANDLE_INSTRUCTION_START(ADD_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001968 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001969 shadow_frame.GetVRegDouble(inst->VRegB_23x()) +
1970 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1971 ADVANCE(2);
1972 HANDLE_INSTRUCTION_END();
1973
1974 HANDLE_INSTRUCTION_START(SUB_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001975 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001976 shadow_frame.GetVRegDouble(inst->VRegB_23x()) -
1977 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1978 ADVANCE(2);
1979 HANDLE_INSTRUCTION_END();
1980
1981 HANDLE_INSTRUCTION_START(MUL_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001982 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001983 shadow_frame.GetVRegDouble(inst->VRegB_23x()) *
1984 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1985 ADVANCE(2);
1986 HANDLE_INSTRUCTION_END();
1987
1988 HANDLE_INSTRUCTION_START(DIV_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001989 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001990 shadow_frame.GetVRegDouble(inst->VRegB_23x()) /
1991 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1992 ADVANCE(2);
1993 HANDLE_INSTRUCTION_END();
1994
1995 HANDLE_INSTRUCTION_START(REM_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001996 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001997 fmod(shadow_frame.GetVRegDouble(inst->VRegB_23x()),
1998 shadow_frame.GetVRegDouble(inst->VRegC_23x())));
1999 ADVANCE(2);
2000 HANDLE_INSTRUCTION_END();
2001
2002 HANDLE_INSTRUCTION_START(ADD_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002003 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002004 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002005 SafeAdd(shadow_frame.GetVReg(vregA),
2006 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002007 ADVANCE(1);
2008 }
2009 HANDLE_INSTRUCTION_END();
2010
2011 HANDLE_INSTRUCTION_START(SUB_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002012 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002013 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002014 SafeSub(shadow_frame.GetVReg(vregA),
2015 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002016 ADVANCE(1);
2017 }
2018 HANDLE_INSTRUCTION_END();
2019
2020 HANDLE_INSTRUCTION_START(MUL_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002021 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002022 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002023 SafeMul(shadow_frame.GetVReg(vregA),
2024 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002025 ADVANCE(1);
2026 }
2027 HANDLE_INSTRUCTION_END();
2028
2029 HANDLE_INSTRUCTION_START(DIV_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002030 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002031 bool success = DoIntDivide(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002032 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002033 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2034 }
2035 HANDLE_INSTRUCTION_END();
2036
2037 HANDLE_INSTRUCTION_START(REM_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002038 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002039 bool success = DoIntRemainder(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002040 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002041 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2042 }
2043 HANDLE_INSTRUCTION_END();
2044
2045 HANDLE_INSTRUCTION_START(SHL_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002046 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002047 shadow_frame.SetVReg(vregA,
2048 shadow_frame.GetVReg(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002049 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002050 ADVANCE(1);
2051 }
2052 HANDLE_INSTRUCTION_END();
2053
2054 HANDLE_INSTRUCTION_START(SHR_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002055 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002056 shadow_frame.SetVReg(vregA,
2057 shadow_frame.GetVReg(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002058 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002059 ADVANCE(1);
2060 }
2061 HANDLE_INSTRUCTION_END();
2062
2063 HANDLE_INSTRUCTION_START(USHR_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002064 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002065 shadow_frame.SetVReg(vregA,
2066 static_cast<uint32_t>(shadow_frame.GetVReg(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002067 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002068 ADVANCE(1);
2069 }
2070 HANDLE_INSTRUCTION_END();
2071
2072 HANDLE_INSTRUCTION_START(AND_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002073 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002074 shadow_frame.SetVReg(vregA,
2075 shadow_frame.GetVReg(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002076 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002077 ADVANCE(1);
2078 }
2079 HANDLE_INSTRUCTION_END();
2080
2081 HANDLE_INSTRUCTION_START(OR_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002082 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002083 shadow_frame.SetVReg(vregA,
2084 shadow_frame.GetVReg(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002085 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002086 ADVANCE(1);
2087 }
2088 HANDLE_INSTRUCTION_END();
2089
2090 HANDLE_INSTRUCTION_START(XOR_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002091 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002092 shadow_frame.SetVReg(vregA,
2093 shadow_frame.GetVReg(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002094 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002095 ADVANCE(1);
2096 }
2097 HANDLE_INSTRUCTION_END();
2098
2099 HANDLE_INSTRUCTION_START(ADD_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002100 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002101 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002102 SafeAdd(shadow_frame.GetVRegLong(vregA),
2103 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002104 ADVANCE(1);
2105 }
2106 HANDLE_INSTRUCTION_END();
2107
2108 HANDLE_INSTRUCTION_START(SUB_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002109 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002110 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002111 SafeSub(shadow_frame.GetVRegLong(vregA),
2112 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002113 ADVANCE(1);
2114 }
2115 HANDLE_INSTRUCTION_END();
2116
2117 HANDLE_INSTRUCTION_START(MUL_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002118 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002119 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002120 SafeMul(shadow_frame.GetVRegLong(vregA),
2121 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002122 ADVANCE(1);
2123 }
2124 HANDLE_INSTRUCTION_END();
2125
2126 HANDLE_INSTRUCTION_START(DIV_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002127 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002128 bool success = DoLongDivide(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002129 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002130 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2131 }
2132 HANDLE_INSTRUCTION_END();
2133
2134 HANDLE_INSTRUCTION_START(REM_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002135 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002136 bool success = DoLongRemainder(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002137 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002138 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2139 }
2140 HANDLE_INSTRUCTION_END();
2141
2142 HANDLE_INSTRUCTION_START(AND_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002143 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002144 shadow_frame.SetVRegLong(vregA,
2145 shadow_frame.GetVRegLong(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002146 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002147 ADVANCE(1);
2148 }
2149 HANDLE_INSTRUCTION_END();
2150
2151 HANDLE_INSTRUCTION_START(OR_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002152 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002153 shadow_frame.SetVRegLong(vregA,
2154 shadow_frame.GetVRegLong(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002155 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002156 ADVANCE(1);
2157 }
2158 HANDLE_INSTRUCTION_END();
2159
2160 HANDLE_INSTRUCTION_START(XOR_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002161 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002162 shadow_frame.SetVRegLong(vregA,
2163 shadow_frame.GetVRegLong(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002164 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002165 ADVANCE(1);
2166 }
2167 HANDLE_INSTRUCTION_END();
2168
2169 HANDLE_INSTRUCTION_START(SHL_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002170 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002171 shadow_frame.SetVRegLong(vregA,
2172 shadow_frame.GetVRegLong(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002173 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002174 ADVANCE(1);
2175 }
2176 HANDLE_INSTRUCTION_END();
2177
2178 HANDLE_INSTRUCTION_START(SHR_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002179 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002180 shadow_frame.SetVRegLong(vregA,
2181 shadow_frame.GetVRegLong(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002182 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002183 ADVANCE(1);
2184 }
2185 HANDLE_INSTRUCTION_END();
2186
2187 HANDLE_INSTRUCTION_START(USHR_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002188 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002189 shadow_frame.SetVRegLong(vregA,
2190 static_cast<uint64_t>(shadow_frame.GetVRegLong(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002191 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002192 ADVANCE(1);
2193 }
2194 HANDLE_INSTRUCTION_END();
2195
2196 HANDLE_INSTRUCTION_START(ADD_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002197 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002198 shadow_frame.SetVRegFloat(vregA,
2199 shadow_frame.GetVRegFloat(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002200 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002201 ADVANCE(1);
2202 }
2203 HANDLE_INSTRUCTION_END();
2204
2205 HANDLE_INSTRUCTION_START(SUB_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002206 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002207 shadow_frame.SetVRegFloat(vregA,
2208 shadow_frame.GetVRegFloat(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002209 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002210 ADVANCE(1);
2211 }
2212 HANDLE_INSTRUCTION_END();
2213
2214 HANDLE_INSTRUCTION_START(MUL_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002215 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002216 shadow_frame.SetVRegFloat(vregA,
2217 shadow_frame.GetVRegFloat(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002218 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002219 ADVANCE(1);
2220 }
2221 HANDLE_INSTRUCTION_END();
2222
2223 HANDLE_INSTRUCTION_START(DIV_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002224 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002225 shadow_frame.SetVRegFloat(vregA,
2226 shadow_frame.GetVRegFloat(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002227 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002228 ADVANCE(1);
2229 }
2230 HANDLE_INSTRUCTION_END();
2231
2232 HANDLE_INSTRUCTION_START(REM_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002233 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002234 shadow_frame.SetVRegFloat(vregA,
2235 fmodf(shadow_frame.GetVRegFloat(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002236 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002237 ADVANCE(1);
2238 }
2239 HANDLE_INSTRUCTION_END();
2240
2241 HANDLE_INSTRUCTION_START(ADD_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002242 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002243 shadow_frame.SetVRegDouble(vregA,
2244 shadow_frame.GetVRegDouble(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002245 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002246 ADVANCE(1);
2247 }
2248 HANDLE_INSTRUCTION_END();
2249
2250 HANDLE_INSTRUCTION_START(SUB_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002251 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002252 shadow_frame.SetVRegDouble(vregA,
2253 shadow_frame.GetVRegDouble(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002254 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002255 ADVANCE(1);
2256 }
2257 HANDLE_INSTRUCTION_END();
2258
2259 HANDLE_INSTRUCTION_START(MUL_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002260 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002261 shadow_frame.SetVRegDouble(vregA,
2262 shadow_frame.GetVRegDouble(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002263 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002264 ADVANCE(1);
2265 }
2266 HANDLE_INSTRUCTION_END();
2267
2268 HANDLE_INSTRUCTION_START(DIV_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002269 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002270 shadow_frame.SetVRegDouble(vregA,
2271 shadow_frame.GetVRegDouble(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002272 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002273 ADVANCE(1);
2274 }
2275 HANDLE_INSTRUCTION_END();
2276
2277 HANDLE_INSTRUCTION_START(REM_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002278 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002279 shadow_frame.SetVRegDouble(vregA,
2280 fmod(shadow_frame.GetVRegDouble(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002281 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002282 ADVANCE(1);
2283 }
2284 HANDLE_INSTRUCTION_END();
2285
2286 HANDLE_INSTRUCTION_START(ADD_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002287 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002288 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2289 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002290 ADVANCE(2);
2291 HANDLE_INSTRUCTION_END();
2292
2293 HANDLE_INSTRUCTION_START(RSUB_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002294 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002295 SafeSub(inst->VRegC_22s(),
2296 shadow_frame.GetVReg(inst->VRegB_22s(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002297 ADVANCE(2);
2298 HANDLE_INSTRUCTION_END();
2299
2300 HANDLE_INSTRUCTION_START(MUL_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002301 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002302 SafeMul(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2303 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002304 ADVANCE(2);
2305 HANDLE_INSTRUCTION_END();
2306
2307 HANDLE_INSTRUCTION_START(DIV_INT_LIT16) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002308 bool success = DoIntDivide(
2309 shadow_frame, inst->VRegA_22s(inst_data), shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2310 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002311 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2312 }
2313 HANDLE_INSTRUCTION_END();
2314
2315 HANDLE_INSTRUCTION_START(REM_INT_LIT16) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002316 bool success = DoIntRemainder(
2317 shadow_frame, inst->VRegA_22s(inst_data), shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2318 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002319 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2320 }
2321 HANDLE_INSTRUCTION_END();
2322
2323 HANDLE_INSTRUCTION_START(AND_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002324 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2325 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) &
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002326 inst->VRegC_22s());
2327 ADVANCE(2);
2328 HANDLE_INSTRUCTION_END();
2329
2330 HANDLE_INSTRUCTION_START(OR_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002331 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2332 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) |
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002333 inst->VRegC_22s());
2334 ADVANCE(2);
2335 HANDLE_INSTRUCTION_END();
2336
2337 HANDLE_INSTRUCTION_START(XOR_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002338 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2339 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) ^
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002340 inst->VRegC_22s());
2341 ADVANCE(2);
2342 HANDLE_INSTRUCTION_END();
2343
2344 HANDLE_INSTRUCTION_START(ADD_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002345 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002346 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22b()),
2347 inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002348 ADVANCE(2);
2349 HANDLE_INSTRUCTION_END();
2350
2351 HANDLE_INSTRUCTION_START(RSUB_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002352 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002353 SafeSub(inst->VRegC_22b(),
2354 shadow_frame.GetVReg(inst->VRegB_22b())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002355 ADVANCE(2);
2356 HANDLE_INSTRUCTION_END();
2357
2358 HANDLE_INSTRUCTION_START(MUL_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002359 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002360 SafeMul(shadow_frame.GetVReg(inst->VRegB_22b()),
2361 inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002362 ADVANCE(2);
2363 HANDLE_INSTRUCTION_END();
2364
2365 HANDLE_INSTRUCTION_START(DIV_INT_LIT8) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002366 bool success = DoIntDivide(shadow_frame, inst->VRegA_22b(inst_data),
2367 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002368 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2369 }
2370 HANDLE_INSTRUCTION_END();
2371
2372 HANDLE_INSTRUCTION_START(REM_INT_LIT8) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002373 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22b(inst_data),
2374 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002375 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2376 }
2377 HANDLE_INSTRUCTION_END();
2378
2379 HANDLE_INSTRUCTION_START(AND_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002380 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002381 shadow_frame.GetVReg(inst->VRegB_22b()) &
2382 inst->VRegC_22b());
2383 ADVANCE(2);
2384 HANDLE_INSTRUCTION_END();
2385
2386 HANDLE_INSTRUCTION_START(OR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002387 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002388 shadow_frame.GetVReg(inst->VRegB_22b()) |
2389 inst->VRegC_22b());
2390 ADVANCE(2);
2391 HANDLE_INSTRUCTION_END();
2392
2393 HANDLE_INSTRUCTION_START(XOR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002394 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002395 shadow_frame.GetVReg(inst->VRegB_22b()) ^
2396 inst->VRegC_22b());
2397 ADVANCE(2);
2398 HANDLE_INSTRUCTION_END();
2399
2400 HANDLE_INSTRUCTION_START(SHL_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002401 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002402 shadow_frame.GetVReg(inst->VRegB_22b()) <<
2403 (inst->VRegC_22b() & 0x1f));
2404 ADVANCE(2);
2405 HANDLE_INSTRUCTION_END();
2406
2407 HANDLE_INSTRUCTION_START(SHR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002408 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002409 shadow_frame.GetVReg(inst->VRegB_22b()) >>
2410 (inst->VRegC_22b() & 0x1f));
2411 ADVANCE(2);
2412 HANDLE_INSTRUCTION_END();
2413
2414 HANDLE_INSTRUCTION_START(USHR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002415 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002416 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_22b())) >>
2417 (inst->VRegC_22b() & 0x1f));
2418 ADVANCE(2);
2419 HANDLE_INSTRUCTION_END();
2420
Igor Murashkin158f35c2015-06-10 15:55:30 -07002421 HANDLE_EXPERIMENTAL_INSTRUCTION_START(CREATE_LAMBDA) {
Igor Murashkin6918bf12015-09-27 19:19:06 -07002422 if (lambda_closure_builder == nullptr) {
2423 // DoCreateLambda always needs a ClosureBuilder, even if it has 0 captured variables.
2424 lambda_closure_builder = MakeUnique<lambda::ClosureBuilder>();
2425 }
2426
2427 // TODO: these allocations should not leak, and the lambda method should not be local.
2428 lambda::Closure* lambda_closure =
2429 reinterpret_cast<lambda::Closure*>(alloca(lambda_closure_builder->GetSize()));
2430 bool success = DoCreateLambda<do_access_check>(self,
2431 inst,
2432 /*inout*/shadow_frame,
2433 /*inout*/lambda_closure_builder.get(),
2434 /*inout*/lambda_closure);
2435 lambda_closure_builder.reset(nullptr); // reset state of variables captured
Igor Murashkin158f35c2015-06-10 15:55:30 -07002436 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2437 }
2438 HANDLE_EXPERIMENTAL_INSTRUCTION_END();
2439
Igor Murashkin2ee54e22015-06-18 10:05:11 -07002440 HANDLE_EXPERIMENTAL_INSTRUCTION_START(BOX_LAMBDA) {
2441 bool success = DoBoxLambda<do_access_check>(self, shadow_frame, inst, inst_data);
2442 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2443 }
2444 HANDLE_EXPERIMENTAL_INSTRUCTION_END();
2445
2446 HANDLE_EXPERIMENTAL_INSTRUCTION_START(UNBOX_LAMBDA) {
2447 bool success = DoUnboxLambda<do_access_check>(self, shadow_frame, inst, inst_data);
2448 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2449 }
2450 HANDLE_EXPERIMENTAL_INSTRUCTION_END();
2451
Igor Murashkin6918bf12015-09-27 19:19:06 -07002452 HANDLE_EXPERIMENTAL_INSTRUCTION_START(CAPTURE_VARIABLE) {
2453 if (lambda_closure_builder == nullptr) {
2454 lambda_closure_builder = MakeUnique<lambda::ClosureBuilder>();
2455 }
2456
2457 bool success = DoCaptureVariable<do_access_check>(self,
2458 inst,
2459 /*inout*/shadow_frame,
2460 /*inout*/lambda_closure_builder.get());
2461
2462 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2463 }
2464 HANDLE_EXPERIMENTAL_INSTRUCTION_END();
2465
2466 HANDLE_EXPERIMENTAL_INSTRUCTION_START(LIBERATE_VARIABLE) {
2467 bool success = DoLiberateVariable<do_access_check>(self,
2468 inst,
2469 lambda_captured_variable_index,
2470 /*inout*/shadow_frame);
2471 // Temporarily only allow sequences of 'liberate-variable, liberate-variable, ...'
2472 lambda_captured_variable_index++;
2473 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2474 }
2475 HANDLE_EXPERIMENTAL_INSTRUCTION_END();
2476
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002477 HANDLE_INSTRUCTION_START(UNUSED_3E)
Ian Rogerse94652f2014-12-02 11:13:19 -08002478 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002479 HANDLE_INSTRUCTION_END();
2480
2481 HANDLE_INSTRUCTION_START(UNUSED_3F)
Ian Rogerse94652f2014-12-02 11:13:19 -08002482 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002483 HANDLE_INSTRUCTION_END();
2484
2485 HANDLE_INSTRUCTION_START(UNUSED_40)
Ian Rogerse94652f2014-12-02 11:13:19 -08002486 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002487 HANDLE_INSTRUCTION_END();
2488
2489 HANDLE_INSTRUCTION_START(UNUSED_41)
Ian Rogerse94652f2014-12-02 11:13:19 -08002490 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002491 HANDLE_INSTRUCTION_END();
2492
2493 HANDLE_INSTRUCTION_START(UNUSED_42)
Ian Rogerse94652f2014-12-02 11:13:19 -08002494 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002495 HANDLE_INSTRUCTION_END();
2496
2497 HANDLE_INSTRUCTION_START(UNUSED_43)
Ian Rogerse94652f2014-12-02 11:13:19 -08002498 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002499 HANDLE_INSTRUCTION_END();
2500
2501 HANDLE_INSTRUCTION_START(UNUSED_79)
Ian Rogerse94652f2014-12-02 11:13:19 -08002502 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002503 HANDLE_INSTRUCTION_END();
2504
2505 HANDLE_INSTRUCTION_START(UNUSED_7A)
Ian Rogerse94652f2014-12-02 11:13:19 -08002506 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002507 HANDLE_INSTRUCTION_END();
2508
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002509 HANDLE_INSTRUCTION_START(UNUSED_F4)
Ian Rogerse94652f2014-12-02 11:13:19 -08002510 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002511 HANDLE_INSTRUCTION_END();
2512
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002513 HANDLE_INSTRUCTION_START(UNUSED_FA)
Ian Rogerse94652f2014-12-02 11:13:19 -08002514 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002515 HANDLE_INSTRUCTION_END();
2516
2517 HANDLE_INSTRUCTION_START(UNUSED_FB)
Ian Rogerse94652f2014-12-02 11:13:19 -08002518 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002519 HANDLE_INSTRUCTION_END();
2520
2521 HANDLE_INSTRUCTION_START(UNUSED_FC)
Ian Rogerse94652f2014-12-02 11:13:19 -08002522 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002523 HANDLE_INSTRUCTION_END();
2524
2525 HANDLE_INSTRUCTION_START(UNUSED_FD)
Ian Rogerse94652f2014-12-02 11:13:19 -08002526 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002527 HANDLE_INSTRUCTION_END();
2528
2529 HANDLE_INSTRUCTION_START(UNUSED_FE)
Ian Rogerse94652f2014-12-02 11:13:19 -08002530 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002531 HANDLE_INSTRUCTION_END();
2532
2533 HANDLE_INSTRUCTION_START(UNUSED_FF)
Ian Rogerse94652f2014-12-02 11:13:19 -08002534 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002535 HANDLE_INSTRUCTION_END();
2536
2537 exception_pending_label: {
2538 CHECK(self->IsExceptionPending());
Sebastien Hertz1eda2262013-09-09 16:53:14 +02002539 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -07002540 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +02002541 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +02002542 }
Sebastien Hertzee1997a2013-09-19 14:47:09 +02002543 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002544 uint32_t found_dex_pc = FindNextInstructionFollowingException(self, shadow_frame, dex_pc,
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002545 instrumentation);
2546 if (found_dex_pc == DexFile::kDexNoIndex) {
2547 return JValue(); /* Handled in caller. */
2548 } else {
2549 int32_t displacement = static_cast<int32_t>(found_dex_pc) - static_cast<int32_t>(dex_pc);
2550 ADVANCE(displacement);
2551 }
2552 }
2553
Sebastien Hertz8379b222014-02-24 17:38:15 +01002554// Create alternative instruction handlers dedicated to instrumentation.
2555// Return instructions must not call Instrumentation::DexPcMovedEvent since they already call
2556// Instrumentation::MethodExited. This is to avoid posting debugger events twice for this location.
Sebastien Hertze713d932014-05-15 10:48:53 +02002557// Note: we do not use the kReturn instruction flag here (to test the instruction is a return). The
2558// compiler seems to not evaluate "(Instruction::FlagsOf(Instruction::code) & kReturn) != 0" to
2559// a constant condition that would remove the "if" statement so the test is free.
Sebastien Hertz9d6bf692015-04-10 12:12:33 +02002560#define INSTRUMENTATION_INSTRUCTION_HANDLER(o, code, n, f, r, i, a, v) \
2561 alt_op_##code: { \
2562 Runtime* const runtime = Runtime::Current(); \
2563 const instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation(); \
2564 if (UNLIKELY(instrumentation->HasDexPcListeners())) { \
2565 Object* this_object = shadow_frame.GetThisObject(code_item->ins_size_); \
2566 instrumentation->DexPcMovedEvent(self, this_object, shadow_frame.GetMethod(), dex_pc); \
2567 } \
2568 UPDATE_HANDLER_TABLE(); \
2569 goto *handlersTable[instrumentation::kMainHandlerTable][Instruction::code]; \
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002570 }
2571#include "dex_instruction_list.h"
2572 DEX_INSTRUCTION_LIST(INSTRUMENTATION_INSTRUCTION_HANDLER)
2573#undef DEX_INSTRUCTION_LIST
2574#undef INSTRUMENTATION_INSTRUCTION_HANDLER
2575} // NOLINT(readability/fn_size)
2576
2577// Explicit definitions of ExecuteGotoImpl.
Mathieu Chartier90443472015-07-16 20:32:27 -07002578template SHARED_REQUIRES(Locks::mutator_lock_) HOT_ATTR
Ian Rogerse94652f2014-12-02 11:13:19 -08002579JValue ExecuteGotoImpl<true, false>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002580 ShadowFrame& shadow_frame, JValue result_register);
Mathieu Chartier90443472015-07-16 20:32:27 -07002581template SHARED_REQUIRES(Locks::mutator_lock_) HOT_ATTR
Ian Rogerse94652f2014-12-02 11:13:19 -08002582JValue ExecuteGotoImpl<false, false>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002583 ShadowFrame& shadow_frame, JValue result_register);
Mathieu Chartier90443472015-07-16 20:32:27 -07002584template SHARED_REQUIRES(Locks::mutator_lock_)
Ian Rogerse94652f2014-12-02 11:13:19 -08002585JValue ExecuteGotoImpl<true, true>(Thread* self, const DexFile::CodeItem* code_item,
2586 ShadowFrame& shadow_frame, JValue result_register);
Mathieu Chartier90443472015-07-16 20:32:27 -07002587template SHARED_REQUIRES(Locks::mutator_lock_)
Ian Rogerse94652f2014-12-02 11:13:19 -08002588JValue ExecuteGotoImpl<false, true>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002589 ShadowFrame& shadow_frame, JValue result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002590
2591} // namespace interpreter
2592} // namespace art
Colin Crosse84e4f72015-03-18 14:01:19 -07002593
2594#endif