blob: 7bc8c1562881cd9059cb774935cea5dd313bffeb [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
Sebastien Hertz8ece0502013-08-07 11:26:41 +020020#include "interpreter_common.h"
Ian Rogersf72a11d2014-10-30 15:41:08 -070021#include "safe_math.h"
Sebastien Hertz8ece0502013-08-07 11:26:41 +020022
23namespace art {
24namespace interpreter {
25
26// In the following macros, we expect the following local variables exist:
27// - "self": the current Thread*.
28// - "inst" : the current Instruction*.
Sebastien Hertz3b588e02013-09-11 14:33:18 +020029// - "inst_data" : the current instruction's first 16 bits.
Sebastien Hertz8ece0502013-08-07 11:26:41 +020030// - "dex_pc": the current pc.
31// - "shadow_frame": the current shadow frame.
Sebastien Hertz8ece0502013-08-07 11:26:41 +020032// - "currentHandlersTable": the current table of pointer to each instruction handler.
33
34// Advance to the next instruction and updates interpreter state.
Sebastien Hertz8ece0502013-08-07 11:26:41 +020035#define ADVANCE(_offset) \
36 do { \
37 int32_t disp = static_cast<int32_t>(_offset); \
38 inst = inst->RelativeAt(disp); \
39 dex_pc = static_cast<uint32_t>(static_cast<int32_t>(dex_pc) + disp); \
40 shadow_frame.SetDexPC(dex_pc); \
Ian Rogerse94652f2014-12-02 11:13:19 -080041 TraceExecution(shadow_frame, inst, dex_pc); \
Sebastien Hertz3b588e02013-09-11 14:33:18 +020042 inst_data = inst->Fetch16(0); \
43 goto *currentHandlersTable[inst->Opcode(inst_data)]; \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020044 } while (false)
45
46#define HANDLE_PENDING_EXCEPTION() goto exception_pending_label
47
48#define POSSIBLY_HANDLE_PENDING_EXCEPTION(_is_exception_pending, _offset) \
49 do { \
50 if (UNLIKELY(_is_exception_pending)) { \
51 HANDLE_PENDING_EXCEPTION(); \
52 } else { \
53 ADVANCE(_offset); \
54 } \
55 } while (false)
56
Sebastien Hertzee1997a2013-09-19 14:47:09 +020057#define UPDATE_HANDLER_TABLE() \
Mathieu Chartier2cebb242015-04-21 16:50:40 -070058 currentHandlersTable = handlersTable[ \
59 Runtime::Current()->GetInstrumentation()->GetInterpreterHandlerTable()]
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +020060
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080061#define BACKWARD_BRANCH_INSTRUMENTATION(offset) \
62 do { \
63 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation(); \
64 instrumentation->BackwardBranch(self, shadow_frame.GetMethod(), offset); \
65 } while (false)
66
Sebastien Hertz8ece0502013-08-07 11:26:41 +020067#define UNREACHABLE_CODE_CHECK() \
68 do { \
69 if (kIsDebugBuild) { \
70 LOG(FATAL) << "We should not be here !"; \
Ian Rogerse94652f2014-12-02 11:13:19 -080071 UNREACHABLE(); \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020072 } \
73 } while (false)
74
75#define HANDLE_INSTRUCTION_START(opcode) op_##opcode: // NOLINT(whitespace/labels)
76#define HANDLE_INSTRUCTION_END() UNREACHABLE_CODE_CHECK()
77
Igor Murashkin158f35c2015-06-10 15:55:30 -070078// Use with instructions labeled with kExperimental flag:
79#define HANDLE_EXPERIMENTAL_INSTRUCTION_START(opcode) \
80 HANDLE_INSTRUCTION_START(opcode); \
81 DCHECK(inst->IsExperimental()); \
82 if (Runtime::Current()->AreExperimentalLambdasEnabled()) {
83#define HANDLE_EXPERIMENTAL_INSTRUCTION_END() \
84 } else { \
85 UnexpectedOpcode(inst, shadow_frame); \
86 } HANDLE_INSTRUCTION_END();
87
88
Sebastien Hertzee1997a2013-09-19 14:47:09 +020089/**
90 * Interpreter based on computed goto tables.
91 *
92 * Each instruction is associated to a handler. This handler is responsible for executing the
93 * instruction and jump to the next instruction's handler.
94 * In order to limit the cost of instrumentation, we have two handler tables:
95 * - the "main" handler table: it contains handlers for normal execution of each instruction without
96 * handling of instrumentation.
97 * - the "alternative" handler table: it contains alternative handlers which first handle
98 * instrumentation before jumping to the corresponding "normal" instruction's handler.
99 *
100 * When instrumentation is active, the interpreter uses the "alternative" handler table. Otherwise
101 * it uses the "main" handler table.
102 *
103 * The current handler table is the handler table being used by the interpreter. It is updated:
104 * - on backward branch (goto, if and switch instructions)
105 * - after invoke
106 * - when an exception is thrown.
107 * This allows to support an attaching debugger to an already running application for instance.
108 *
109 * For a fast handler table update, handler tables are stored in an array of handler tables. Each
110 * handler table is represented by the InterpreterHandlerTable enum which allows to associate it
111 * to an index in this array of handler tables ((see Instrumentation::GetInterpreterHandlerTable).
112 *
113 * Here's the current layout of this array of handler tables:
114 *
115 * ---------------------+---------------+
116 * | NOP | (handler for NOP instruction)
117 * +---------------+
118 * "main" | MOVE | (handler for MOVE instruction)
119 * handler table +---------------+
120 * | ... |
121 * +---------------+
122 * | UNUSED_FF | (handler for UNUSED_FF instruction)
123 * ---------------------+---------------+
124 * | NOP | (alternative handler for NOP instruction)
125 * +---------------+
126 * "alternative" | MOVE | (alternative handler for MOVE instruction)
127 * handler table +---------------+
128 * | ... |
129 * +---------------+
130 * | UNUSED_FF | (alternative handler for UNUSED_FF instruction)
131 * ---------------------+---------------+
132 *
133 */
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100134template<bool do_access_check, bool transaction_active>
Ian Rogerse94652f2014-12-02 11:13:19 -0800135JValue ExecuteGotoImpl(Thread* self, const DexFile::CodeItem* code_item, ShadowFrame& shadow_frame,
136 JValue result_register) {
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200137 // Define handler tables:
138 // - The main handler table contains execution handlers for each instruction.
139 // - The alternative handler table contains prelude handlers which check for thread suspend and
140 // manage instrumentation before jumping to the execution handler.
141 static const void* const handlersTable[instrumentation::kNumHandlerTables][kNumPackedOpcodes] = {
142 {
143 // Main handler table.
144#define INSTRUCTION_HANDLER(o, code, n, f, r, i, a, v) &&op_##code,
145#include "dex_instruction_list.h"
146 DEX_INSTRUCTION_LIST(INSTRUCTION_HANDLER)
147#undef DEX_INSTRUCTION_LIST
148#undef INSTRUCTION_HANDLER
149 }, {
150 // Alternative handler table.
151#define INSTRUCTION_HANDLER(o, code, n, f, r, i, a, v) &&alt_op_##code,
152#include "dex_instruction_list.h"
153 DEX_INSTRUCTION_LIST(INSTRUCTION_HANDLER)
154#undef DEX_INSTRUCTION_LIST
155#undef INSTRUCTION_HANDLER
156 }
157 };
158
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800159 constexpr bool do_assignability_check = do_access_check;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200160 if (UNLIKELY(!shadow_frame.HasReferenceArray())) {
161 LOG(FATAL) << "Invalid shadow frame for interpreter use";
162 return JValue();
163 }
164 self->VerifyStack();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200165
166 uint32_t dex_pc = shadow_frame.GetDexPC();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200167 const Instruction* inst = Instruction::At(code_item->insns_ + dex_pc);
168 uint16_t inst_data;
169 const void* const* currentHandlersTable;
170 UPDATE_HANDLER_TABLE();
Sebastien Hertz270a0e12015-01-16 19:49:09 +0100171 if (LIKELY(dex_pc == 0)) { // We are entering the method as opposed to deoptimizing.
172 if (kIsDebugBuild) {
173 self->AssertNoPendingException();
174 }
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200175 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200176 if (UNLIKELY(instrumentation->HasMethodEntryListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200177 instrumentation->MethodEnterEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200178 shadow_frame.GetMethod(), 0);
179 }
180 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200181
182 // Jump to first instruction.
183 ADVANCE(0);
184 UNREACHABLE_CODE_CHECK();
185
186 HANDLE_INSTRUCTION_START(NOP)
187 ADVANCE(1);
188 HANDLE_INSTRUCTION_END();
189
190 HANDLE_INSTRUCTION_START(MOVE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200191 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
192 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200193 ADVANCE(1);
194 HANDLE_INSTRUCTION_END();
195
196 HANDLE_INSTRUCTION_START(MOVE_FROM16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200197 shadow_frame.SetVReg(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200198 shadow_frame.GetVReg(inst->VRegB_22x()));
199 ADVANCE(2);
200 HANDLE_INSTRUCTION_END();
201
202 HANDLE_INSTRUCTION_START(MOVE_16)
203 shadow_frame.SetVReg(inst->VRegA_32x(),
204 shadow_frame.GetVReg(inst->VRegB_32x()));
205 ADVANCE(3);
206 HANDLE_INSTRUCTION_END();
207
208 HANDLE_INSTRUCTION_START(MOVE_WIDE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200209 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
210 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200211 ADVANCE(1);
212 HANDLE_INSTRUCTION_END();
213
214 HANDLE_INSTRUCTION_START(MOVE_WIDE_FROM16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200215 shadow_frame.SetVRegLong(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200216 shadow_frame.GetVRegLong(inst->VRegB_22x()));
217 ADVANCE(2);
218 HANDLE_INSTRUCTION_END();
219
220 HANDLE_INSTRUCTION_START(MOVE_WIDE_16)
221 shadow_frame.SetVRegLong(inst->VRegA_32x(),
222 shadow_frame.GetVRegLong(inst->VRegB_32x()));
223 ADVANCE(3);
224 HANDLE_INSTRUCTION_END();
225
226 HANDLE_INSTRUCTION_START(MOVE_OBJECT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200227 shadow_frame.SetVRegReference(inst->VRegA_12x(inst_data),
228 shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200229 ADVANCE(1);
230 HANDLE_INSTRUCTION_END();
231
232 HANDLE_INSTRUCTION_START(MOVE_OBJECT_FROM16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200233 shadow_frame.SetVRegReference(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200234 shadow_frame.GetVRegReference(inst->VRegB_22x()));
235 ADVANCE(2);
236 HANDLE_INSTRUCTION_END();
237
238 HANDLE_INSTRUCTION_START(MOVE_OBJECT_16)
239 shadow_frame.SetVRegReference(inst->VRegA_32x(),
240 shadow_frame.GetVRegReference(inst->VRegB_32x()));
241 ADVANCE(3);
242 HANDLE_INSTRUCTION_END();
243
244 HANDLE_INSTRUCTION_START(MOVE_RESULT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200245 shadow_frame.SetVReg(inst->VRegA_11x(inst_data), result_register.GetI());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200246 ADVANCE(1);
247 HANDLE_INSTRUCTION_END();
248
249 HANDLE_INSTRUCTION_START(MOVE_RESULT_WIDE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200250 shadow_frame.SetVRegLong(inst->VRegA_11x(inst_data), result_register.GetJ());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200251 ADVANCE(1);
252 HANDLE_INSTRUCTION_END();
253
254 HANDLE_INSTRUCTION_START(MOVE_RESULT_OBJECT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200255 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), result_register.GetL());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200256 ADVANCE(1);
257 HANDLE_INSTRUCTION_END();
258
259 HANDLE_INSTRUCTION_START(MOVE_EXCEPTION) {
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000260 Throwable* exception = self->GetException();
Sebastien Hertz270a0e12015-01-16 19:49:09 +0100261 DCHECK(exception != nullptr) << "No pending exception on MOVE_EXCEPTION instruction";
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200262 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), exception);
Sebastien Hertz5c004902014-05-21 10:07:42 +0200263 self->ClearException();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200264 ADVANCE(1);
265 }
266 HANDLE_INSTRUCTION_END();
267
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700268 HANDLE_INSTRUCTION_START(RETURN_VOID_NO_BARRIER) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200269 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700270 self->AllowThreadSuspension();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200271 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200272 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200273 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200274 shadow_frame.GetMethod(), dex_pc,
275 result);
276 }
277 return result;
278 }
279 HANDLE_INSTRUCTION_END();
280
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700281 HANDLE_INSTRUCTION_START(RETURN_VOID) {
Hans Boehm30359612014-05-21 17:46:23 -0700282 QuasiAtomic::ThreadFenceForConstructor();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200283 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700284 self->AllowThreadSuspension();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200285 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200286 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200287 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200288 shadow_frame.GetMethod(), dex_pc,
289 result);
290 }
291 return result;
292 }
293 HANDLE_INSTRUCTION_END();
294
295 HANDLE_INSTRUCTION_START(RETURN) {
296 JValue result;
297 result.SetJ(0);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200298 result.SetI(shadow_frame.GetVReg(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700299 self->AllowThreadSuspension();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200300 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200301 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200302 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200303 shadow_frame.GetMethod(), dex_pc,
304 result);
305 }
306 return result;
307 }
308 HANDLE_INSTRUCTION_END();
309
310 HANDLE_INSTRUCTION_START(RETURN_WIDE) {
311 JValue result;
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200312 result.SetJ(shadow_frame.GetVRegLong(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700313 self->AllowThreadSuspension();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200314 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200315 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200316 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200317 shadow_frame.GetMethod(), dex_pc,
318 result);
319 }
320 return result;
321 }
322 HANDLE_INSTRUCTION_END();
323
324 HANDLE_INSTRUCTION_START(RETURN_OBJECT) {
325 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700326 self->AllowThreadSuspension();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700327 const uint8_t vreg_index = inst->VRegA_11x(inst_data);
328 Object* obj_result = shadow_frame.GetVRegReference(vreg_index);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700329 if (do_assignability_check && obj_result != nullptr) {
Ian Rogersded66a02014-10-28 18:12:55 -0700330 Class* return_type = shadow_frame.GetMethod()->GetReturnType();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700331 obj_result = shadow_frame.GetVRegReference(vreg_index);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700332 if (return_type == nullptr) {
Jeff Haoa3faaf42013-09-03 19:07:00 -0700333 // Return the pending exception.
334 HANDLE_PENDING_EXCEPTION();
335 }
336 if (!obj_result->VerifierInstanceOf(return_type)) {
337 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700338 std::string temp1, temp2;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000339 self->ThrowNewExceptionF("Ljava/lang/VirtualMachineError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700340 "Returning '%s' that is not instance of return type '%s'",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700341 obj_result->GetClass()->GetDescriptor(&temp1),
342 return_type->GetDescriptor(&temp2));
Jeff Haoa3faaf42013-09-03 19:07:00 -0700343 HANDLE_PENDING_EXCEPTION();
344 }
345 }
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700346 result.SetL(obj_result);
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200347 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200348 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200349 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200350 shadow_frame.GetMethod(), dex_pc,
351 result);
352 }
353 return result;
354 }
355 HANDLE_INSTRUCTION_END();
356
357 HANDLE_INSTRUCTION_START(CONST_4) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200358 uint32_t dst = inst->VRegA_11n(inst_data);
359 int32_t val = inst->VRegB_11n(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200360 shadow_frame.SetVReg(dst, val);
361 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700362 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200363 }
364 ADVANCE(1);
365 }
366 HANDLE_INSTRUCTION_END();
367
368 HANDLE_INSTRUCTION_START(CONST_16) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200369 uint32_t dst = inst->VRegA_21s(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200370 int32_t val = inst->VRegB_21s();
371 shadow_frame.SetVReg(dst, val);
372 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700373 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200374 }
375 ADVANCE(2);
376 }
377 HANDLE_INSTRUCTION_END();
378
379 HANDLE_INSTRUCTION_START(CONST) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200380 uint32_t dst = inst->VRegA_31i(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200381 int32_t val = inst->VRegB_31i();
382 shadow_frame.SetVReg(dst, val);
383 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700384 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200385 }
386 ADVANCE(3);
387 }
388 HANDLE_INSTRUCTION_END();
389
390 HANDLE_INSTRUCTION_START(CONST_HIGH16) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200391 uint32_t dst = inst->VRegA_21h(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200392 int32_t val = static_cast<int32_t>(inst->VRegB_21h() << 16);
393 shadow_frame.SetVReg(dst, val);
394 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700395 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200396 }
397 ADVANCE(2);
398 }
399 HANDLE_INSTRUCTION_END();
400
401 HANDLE_INSTRUCTION_START(CONST_WIDE_16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200402 shadow_frame.SetVRegLong(inst->VRegA_21s(inst_data), inst->VRegB_21s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200403 ADVANCE(2);
404 HANDLE_INSTRUCTION_END();
405
406 HANDLE_INSTRUCTION_START(CONST_WIDE_32)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200407 shadow_frame.SetVRegLong(inst->VRegA_31i(inst_data), inst->VRegB_31i());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200408 ADVANCE(3);
409 HANDLE_INSTRUCTION_END();
410
411 HANDLE_INSTRUCTION_START(CONST_WIDE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200412 shadow_frame.SetVRegLong(inst->VRegA_51l(inst_data), inst->VRegB_51l());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200413 ADVANCE(5);
414 HANDLE_INSTRUCTION_END();
415
416 HANDLE_INSTRUCTION_START(CONST_WIDE_HIGH16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200417 shadow_frame.SetVRegLong(inst->VRegA_21h(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200418 static_cast<uint64_t>(inst->VRegB_21h()) << 48);
419 ADVANCE(2);
420 HANDLE_INSTRUCTION_END();
421
422 HANDLE_INSTRUCTION_START(CONST_STRING) {
Ian Rogers6786a582014-10-28 12:49:06 -0700423 String* s = ResolveString(self, shadow_frame, inst->VRegB_21c());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700424 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200425 HANDLE_PENDING_EXCEPTION();
426 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200427 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200428 ADVANCE(2);
429 }
430 }
431 HANDLE_INSTRUCTION_END();
432
433 HANDLE_INSTRUCTION_START(CONST_STRING_JUMBO) {
Ian Rogers6786a582014-10-28 12:49:06 -0700434 String* s = ResolveString(self, shadow_frame, inst->VRegB_31c());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700435 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200436 HANDLE_PENDING_EXCEPTION();
437 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200438 shadow_frame.SetVRegReference(inst->VRegA_31c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200439 ADVANCE(3);
440 }
441 }
442 HANDLE_INSTRUCTION_END();
443
444 HANDLE_INSTRUCTION_START(CONST_CLASS) {
445 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
446 self, false, do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700447 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200448 HANDLE_PENDING_EXCEPTION();
449 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200450 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), c);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200451 ADVANCE(2);
452 }
453 }
454 HANDLE_INSTRUCTION_END();
455
456 HANDLE_INSTRUCTION_START(MONITOR_ENTER) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200457 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700458 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000459 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200460 HANDLE_PENDING_EXCEPTION();
461 } else {
462 DoMonitorEnter(self, obj);
463 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), 1);
464 }
465 }
466 HANDLE_INSTRUCTION_END();
467
468 HANDLE_INSTRUCTION_START(MONITOR_EXIT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200469 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700470 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000471 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200472 HANDLE_PENDING_EXCEPTION();
473 } else {
474 DoMonitorExit(self, obj);
475 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), 1);
476 }
477 }
478 HANDLE_INSTRUCTION_END();
479
480 HANDLE_INSTRUCTION_START(CHECK_CAST) {
481 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
482 self, false, do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700483 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200484 HANDLE_PENDING_EXCEPTION();
485 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200486 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_21c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700487 if (UNLIKELY(obj != nullptr && !obj->InstanceOf(c))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200488 ThrowClassCastException(c, obj->GetClass());
489 HANDLE_PENDING_EXCEPTION();
490 } else {
491 ADVANCE(2);
492 }
493 }
494 }
495 HANDLE_INSTRUCTION_END();
496
497 HANDLE_INSTRUCTION_START(INSTANCE_OF) {
498 Class* c = ResolveVerifyAndClinit(inst->VRegC_22c(), shadow_frame.GetMethod(),
499 self, false, do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700500 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200501 HANDLE_PENDING_EXCEPTION();
502 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200503 Object* obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700504 shadow_frame.SetVReg(inst->VRegA_22c(inst_data), (obj != nullptr && obj->InstanceOf(c)) ? 1 : 0);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200505 ADVANCE(2);
506 }
507 }
508 HANDLE_INSTRUCTION_END();
509
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700510 HANDLE_INSTRUCTION_START(ARRAY_LENGTH) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200511 Object* array = shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700512 if (UNLIKELY(array == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000513 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200514 HANDLE_PENDING_EXCEPTION();
515 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200516 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), array->AsArray()->GetLength());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200517 ADVANCE(1);
518 }
519 }
520 HANDLE_INSTRUCTION_END();
521
522 HANDLE_INSTRUCTION_START(NEW_INSTANCE) {
Jeff Hao848f70a2014-01-15 13:49:50 -0800523 Object* obj = nullptr;
524 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
525 self, false, do_access_check);
526 if (LIKELY(c != nullptr)) {
527 if (UNLIKELY(c->IsStringClass())) {
528 gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
529 mirror::SetStringCountVisitor visitor(0);
530 obj = String::Alloc<true>(self, 0, allocator_type, visitor);
531 } else {
532 obj = AllocObjectFromCode<do_access_check, true>(
533 inst->VRegB_21c(), shadow_frame.GetMethod(), self,
534 Runtime::Current()->GetHeap()->GetCurrentAllocator());
535 }
536 }
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700537 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200538 HANDLE_PENDING_EXCEPTION();
539 } else {
Sebastien Hertz4e99b3d2014-06-24 14:35:40 +0200540 obj->GetClass()->AssertInitializedOrInitializingInThread(self);
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700541 // Don't allow finalizable objects to be allocated during a transaction since these can't be
542 // finalized without a started runtime.
543 if (transaction_active && obj->GetClass()->IsFinalizable()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +0200544 AbortTransactionF(self, "Allocating finalizable object in transaction: %s",
545 PrettyTypeOf(obj).c_str());
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700546 HANDLE_PENDING_EXCEPTION();
547 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200548 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200549 ADVANCE(2);
550 }
551 }
552 HANDLE_INSTRUCTION_END();
553
554 HANDLE_INSTRUCTION_START(NEW_ARRAY) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200555 int32_t length = shadow_frame.GetVReg(inst->VRegB_22c(inst_data));
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800556 Object* obj = AllocArrayFromCode<do_access_check, true>(
Andreas Gampe1cc7dba2014-12-17 18:43:01 -0800557 inst->VRegC_22c(), length, shadow_frame.GetMethod(), self,
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800558 Runtime::Current()->GetHeap()->GetCurrentAllocator());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700559 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200560 HANDLE_PENDING_EXCEPTION();
561 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200562 shadow_frame.SetVRegReference(inst->VRegA_22c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200563 ADVANCE(2);
564 }
565 }
566 HANDLE_INSTRUCTION_END();
567
568 HANDLE_INSTRUCTION_START(FILLED_NEW_ARRAY) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100569 bool success =
570 DoFilledNewArray<false, do_access_check, transaction_active>(inst, shadow_frame,
571 self, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200572 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
573 }
574 HANDLE_INSTRUCTION_END();
575
576 HANDLE_INSTRUCTION_START(FILLED_NEW_ARRAY_RANGE) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100577 bool success =
578 DoFilledNewArray<true, do_access_check, transaction_active>(inst, shadow_frame,
579 self, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200580 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
581 }
582 HANDLE_INSTRUCTION_END();
583
584 HANDLE_INSTRUCTION_START(FILL_ARRAY_DATA) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200585 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_31t(inst_data));
Ian Rogers832336b2014-10-08 15:35:22 -0700586 const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t();
587 const Instruction::ArrayDataPayload* payload =
588 reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr);
589 bool success = FillArrayData(obj, payload);
590 if (transaction_active && success) {
591 RecordArrayElementsInTransaction(obj->AsArray(), payload->element_count);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200592 }
Ian Rogers832336b2014-10-08 15:35:22 -0700593 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200594 }
595 HANDLE_INSTRUCTION_END();
596
597 HANDLE_INSTRUCTION_START(THROW) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200598 Object* exception = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700599 if (UNLIKELY(exception == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000600 ThrowNullPointerException("throw with null exception");
Jeff Haoa3faaf42013-09-03 19:07:00 -0700601 } else if (do_assignability_check && !exception->GetClass()->IsThrowableClass()) {
602 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700603 std::string temp;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000604 self->ThrowNewExceptionF("Ljava/lang/VirtualMachineError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700605 "Throwing '%s' that is not instance of Throwable",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700606 exception->GetClass()->GetDescriptor(&temp));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200607 } else {
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000608 self->SetException(exception->AsThrowable());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200609 }
610 HANDLE_PENDING_EXCEPTION();
611 }
612 HANDLE_INSTRUCTION_END();
613
614 HANDLE_INSTRUCTION_START(GOTO) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200615 int8_t offset = inst->VRegA_10t(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200616 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800617 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200618 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700619 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200620 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200621 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200622 }
623 ADVANCE(offset);
624 }
625 HANDLE_INSTRUCTION_END();
626
627 HANDLE_INSTRUCTION_START(GOTO_16) {
628 int16_t offset = inst->VRegA_20t();
629 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800630 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200631 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700632 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200633 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200634 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200635 }
636 ADVANCE(offset);
637 }
638 HANDLE_INSTRUCTION_END();
639
640 HANDLE_INSTRUCTION_START(GOTO_32) {
641 int32_t offset = inst->VRegA_30t();
642 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800643 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200644 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700645 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200646 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200647 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200648 }
649 ADVANCE(offset);
650 }
651 HANDLE_INSTRUCTION_END();
652
653 HANDLE_INSTRUCTION_START(PACKED_SWITCH) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200654 int32_t offset = DoPackedSwitch(inst, shadow_frame, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200655 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800656 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200657 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700658 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200659 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200660 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200661 }
662 ADVANCE(offset);
663 }
664 HANDLE_INSTRUCTION_END();
665
666 HANDLE_INSTRUCTION_START(SPARSE_SWITCH) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200667 int32_t offset = DoSparseSwitch(inst, shadow_frame, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200668 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800669 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200670 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700671 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200672 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200673 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200674 }
675 ADVANCE(offset);
676 }
677 HANDLE_INSTRUCTION_END();
678
Ian Rogers647b1a82014-10-10 11:02:11 -0700679#if defined(__clang__)
680#pragma clang diagnostic push
681#pragma clang diagnostic ignored "-Wfloat-equal"
682#endif
683
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200684 HANDLE_INSTRUCTION_START(CMPL_FLOAT) {
685 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
686 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
687 int32_t result;
688 if (val1 > val2) {
689 result = 1;
690 } else if (val1 == val2) {
691 result = 0;
692 } else {
693 result = -1;
694 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200695 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200696 ADVANCE(2);
697 }
698 HANDLE_INSTRUCTION_END();
699
700 HANDLE_INSTRUCTION_START(CMPG_FLOAT) {
701 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
702 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
703 int32_t result;
704 if (val1 < val2) {
705 result = -1;
706 } else if (val1 == val2) {
707 result = 0;
708 } else {
709 result = 1;
710 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200711 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200712 ADVANCE(2);
713 }
714 HANDLE_INSTRUCTION_END();
715
716 HANDLE_INSTRUCTION_START(CMPL_DOUBLE) {
717 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
718 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
719 int32_t result;
720 if (val1 > val2) {
721 result = 1;
722 } else if (val1 == val2) {
723 result = 0;
724 } else {
725 result = -1;
726 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200727 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200728 ADVANCE(2);
729 }
730 HANDLE_INSTRUCTION_END();
731
732 HANDLE_INSTRUCTION_START(CMPG_DOUBLE) {
733 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
734 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
735 int32_t result;
736 if (val1 < val2) {
737 result = -1;
738 } else if (val1 == val2) {
739 result = 0;
740 } else {
741 result = 1;
742 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200743 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200744 ADVANCE(2);
745 }
746 HANDLE_INSTRUCTION_END();
747
Ian Rogers647b1a82014-10-10 11:02:11 -0700748#if defined(__clang__)
749#pragma clang diagnostic pop
750#endif
751
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200752 HANDLE_INSTRUCTION_START(CMP_LONG) {
753 int64_t val1 = shadow_frame.GetVRegLong(inst->VRegB_23x());
754 int64_t val2 = shadow_frame.GetVRegLong(inst->VRegC_23x());
755 int32_t result;
756 if (val1 > val2) {
757 result = 1;
758 } else if (val1 == val2) {
759 result = 0;
760 } else {
761 result = -1;
762 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200763 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200764 ADVANCE(2);
765 }
766 HANDLE_INSTRUCTION_END();
767
768 HANDLE_INSTRUCTION_START(IF_EQ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200769 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) == shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200770 int16_t offset = inst->VRegC_22t();
771 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800772 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200773 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700774 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200775 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200776 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200777 }
778 ADVANCE(offset);
779 } else {
780 ADVANCE(2);
781 }
782 }
783 HANDLE_INSTRUCTION_END();
784
785 HANDLE_INSTRUCTION_START(IF_NE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700786 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) !=
787 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200788 int16_t offset = inst->VRegC_22t();
789 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800790 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200791 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700792 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200793 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200794 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200795 }
796 ADVANCE(offset);
797 } else {
798 ADVANCE(2);
799 }
800 }
801 HANDLE_INSTRUCTION_END();
802
803 HANDLE_INSTRUCTION_START(IF_LT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700804 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <
805 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200806 int16_t offset = inst->VRegC_22t();
807 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800808 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200809 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700810 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200811 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200812 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200813 }
814 ADVANCE(offset);
815 } else {
816 ADVANCE(2);
817 }
818 }
819 HANDLE_INSTRUCTION_END();
820
821 HANDLE_INSTRUCTION_START(IF_GE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700822 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >=
823 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200824 int16_t offset = inst->VRegC_22t();
825 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800826 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200827 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700828 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200829 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200830 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200831 }
832 ADVANCE(offset);
833 } else {
834 ADVANCE(2);
835 }
836 }
837 HANDLE_INSTRUCTION_END();
838
839 HANDLE_INSTRUCTION_START(IF_GT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700840 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >
841 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200842 int16_t offset = inst->VRegC_22t();
843 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800844 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200845 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700846 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200847 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200848 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200849 }
850 ADVANCE(offset);
851 } else {
852 ADVANCE(2);
853 }
854 }
855 HANDLE_INSTRUCTION_END();
856
857 HANDLE_INSTRUCTION_START(IF_LE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700858 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <=
859 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200860 int16_t offset = inst->VRegC_22t();
861 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800862 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200863 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700864 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200865 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200866 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200867 }
868 ADVANCE(offset);
869 } else {
870 ADVANCE(2);
871 }
872 }
873 HANDLE_INSTRUCTION_END();
874
875 HANDLE_INSTRUCTION_START(IF_EQZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200876 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) == 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200877 int16_t offset = inst->VRegB_21t();
878 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800879 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200880 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700881 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200882 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200883 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200884 }
885 ADVANCE(offset);
886 } else {
887 ADVANCE(2);
888 }
889 }
890 HANDLE_INSTRUCTION_END();
891
892 HANDLE_INSTRUCTION_START(IF_NEZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200893 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) != 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200894 int16_t offset = inst->VRegB_21t();
895 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800896 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200897 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700898 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200899 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200900 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200901 }
902 ADVANCE(offset);
903 } else {
904 ADVANCE(2);
905 }
906 }
907 HANDLE_INSTRUCTION_END();
908
909 HANDLE_INSTRUCTION_START(IF_LTZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200910 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) < 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200911 int16_t offset = inst->VRegB_21t();
912 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800913 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200914 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700915 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200916 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200917 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200918 }
919 ADVANCE(offset);
920 } else {
921 ADVANCE(2);
922 }
923 }
924 HANDLE_INSTRUCTION_END();
925
926 HANDLE_INSTRUCTION_START(IF_GEZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200927 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) >= 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200928 int16_t offset = inst->VRegB_21t();
929 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800930 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200931 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700932 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200933 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200934 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200935 }
936 ADVANCE(offset);
937 } else {
938 ADVANCE(2);
939 }
940 }
941 HANDLE_INSTRUCTION_END();
942
943 HANDLE_INSTRUCTION_START(IF_GTZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200944 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) > 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200945 int16_t offset = inst->VRegB_21t();
946 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800947 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200948 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700949 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200950 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200951 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200952 }
953 ADVANCE(offset);
954 } else {
955 ADVANCE(2);
956 }
957 }
958 HANDLE_INSTRUCTION_END();
959
960 HANDLE_INSTRUCTION_START(IF_LEZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200961 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) <= 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200962 int16_t offset = inst->VRegB_21t();
963 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800964 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200965 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700966 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200967 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200968 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200969 }
970 ADVANCE(offset);
971 } else {
972 ADVANCE(2);
973 }
974 }
975 HANDLE_INSTRUCTION_END();
976
977 HANDLE_INSTRUCTION_START(AGET_BOOLEAN) {
978 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700979 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000980 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200981 HANDLE_PENDING_EXCEPTION();
982 } else {
983 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
984 BooleanArray* array = a->AsBooleanArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +0100985 if (LIKELY(array->CheckIsValidIndex(index))) {
986 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200987 ADVANCE(2);
988 } else {
989 HANDLE_PENDING_EXCEPTION();
990 }
991 }
992 }
993 HANDLE_INSTRUCTION_END();
994
995 HANDLE_INSTRUCTION_START(AGET_BYTE) {
996 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700997 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000998 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200999 HANDLE_PENDING_EXCEPTION();
1000 } else {
1001 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1002 ByteArray* array = a->AsByteArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001003 if (LIKELY(array->CheckIsValidIndex(index))) {
1004 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001005 ADVANCE(2);
1006 } else {
1007 HANDLE_PENDING_EXCEPTION();
1008 }
1009 }
1010 }
1011 HANDLE_INSTRUCTION_END();
1012
1013 HANDLE_INSTRUCTION_START(AGET_CHAR) {
1014 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001015 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001016 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001017 HANDLE_PENDING_EXCEPTION();
1018 } else {
1019 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1020 CharArray* array = a->AsCharArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001021 if (LIKELY(array->CheckIsValidIndex(index))) {
1022 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001023 ADVANCE(2);
1024 } else {
1025 HANDLE_PENDING_EXCEPTION();
1026 }
1027 }
1028 }
1029 HANDLE_INSTRUCTION_END();
1030
1031 HANDLE_INSTRUCTION_START(AGET_SHORT) {
1032 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001033 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001034 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001035 HANDLE_PENDING_EXCEPTION();
1036 } else {
1037 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1038 ShortArray* array = a->AsShortArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001039 if (LIKELY(array->CheckIsValidIndex(index))) {
1040 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001041 ADVANCE(2);
1042 } else {
1043 HANDLE_PENDING_EXCEPTION();
1044 }
1045 }
1046 }
1047 HANDLE_INSTRUCTION_END();
1048
1049 HANDLE_INSTRUCTION_START(AGET) {
1050 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001051 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001052 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001053 HANDLE_PENDING_EXCEPTION();
1054 } else {
1055 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001056 DCHECK(a->IsIntArray() || a->IsFloatArray()) << PrettyTypeOf(a);
1057 auto* array = down_cast<IntArray*>(a);
Sebastien Hertzabff6432014-01-27 18:01:39 +01001058 if (LIKELY(array->CheckIsValidIndex(index))) {
1059 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001060 ADVANCE(2);
1061 } else {
1062 HANDLE_PENDING_EXCEPTION();
1063 }
1064 }
1065 }
1066 HANDLE_INSTRUCTION_END();
1067
1068 HANDLE_INSTRUCTION_START(AGET_WIDE) {
1069 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001070 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001071 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001072 HANDLE_PENDING_EXCEPTION();
1073 } else {
1074 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001075 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << PrettyTypeOf(a);
1076 auto* array = down_cast<LongArray*>(a);
Sebastien Hertzabff6432014-01-27 18:01:39 +01001077 if (LIKELY(array->CheckIsValidIndex(index))) {
1078 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001079 ADVANCE(2);
1080 } else {
1081 HANDLE_PENDING_EXCEPTION();
1082 }
1083 }
1084 }
1085 HANDLE_INSTRUCTION_END();
1086
1087 HANDLE_INSTRUCTION_START(AGET_OBJECT) {
1088 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001089 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001090 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001091 HANDLE_PENDING_EXCEPTION();
1092 } else {
1093 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1094 ObjectArray<Object>* array = a->AsObjectArray<Object>();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001095 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001096 shadow_frame.SetVRegReference(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001097 ADVANCE(2);
1098 } else {
1099 HANDLE_PENDING_EXCEPTION();
1100 }
1101 }
1102 }
1103 HANDLE_INSTRUCTION_END();
1104
1105 HANDLE_INSTRUCTION_START(APUT_BOOLEAN) {
1106 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001107 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001108 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001109 HANDLE_PENDING_EXCEPTION();
1110 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001111 uint8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001112 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1113 BooleanArray* array = a->AsBooleanArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001114 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001115 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001116 ADVANCE(2);
1117 } else {
1118 HANDLE_PENDING_EXCEPTION();
1119 }
1120 }
1121 }
1122 HANDLE_INSTRUCTION_END();
1123
1124 HANDLE_INSTRUCTION_START(APUT_BYTE) {
1125 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001126 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001127 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001128 HANDLE_PENDING_EXCEPTION();
1129 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001130 int8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001131 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1132 ByteArray* array = a->AsByteArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001133 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001134 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001135 ADVANCE(2);
1136 } else {
1137 HANDLE_PENDING_EXCEPTION();
1138 }
1139 }
1140 }
1141 HANDLE_INSTRUCTION_END();
1142
1143 HANDLE_INSTRUCTION_START(APUT_CHAR) {
1144 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001145 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001146 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001147 HANDLE_PENDING_EXCEPTION();
1148 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001149 uint16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001150 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1151 CharArray* array = a->AsCharArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001152 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001153 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001154 ADVANCE(2);
1155 } else {
1156 HANDLE_PENDING_EXCEPTION();
1157 }
1158 }
1159 }
1160 HANDLE_INSTRUCTION_END();
1161
1162 HANDLE_INSTRUCTION_START(APUT_SHORT) {
1163 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001164 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001165 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001166 HANDLE_PENDING_EXCEPTION();
1167 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001168 int16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001169 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1170 ShortArray* array = a->AsShortArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001171 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001172 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001173 ADVANCE(2);
1174 } else {
1175 HANDLE_PENDING_EXCEPTION();
1176 }
1177 }
1178 }
1179 HANDLE_INSTRUCTION_END();
1180
1181 HANDLE_INSTRUCTION_START(APUT) {
1182 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001183 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001184 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001185 HANDLE_PENDING_EXCEPTION();
1186 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001187 int32_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001188 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001189 DCHECK(a->IsIntArray() || a->IsFloatArray()) << PrettyTypeOf(a);
1190 auto* array = down_cast<IntArray*>(a);
Sebastien Hertzabff6432014-01-27 18:01:39 +01001191 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001192 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001193 ADVANCE(2);
1194 } else {
1195 HANDLE_PENDING_EXCEPTION();
1196 }
1197 }
1198 }
1199 HANDLE_INSTRUCTION_END();
1200
1201 HANDLE_INSTRUCTION_START(APUT_WIDE) {
1202 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001203 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001204 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001205 HANDLE_PENDING_EXCEPTION();
1206 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001207 int64_t val = shadow_frame.GetVRegLong(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001208 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001209 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << PrettyTypeOf(a);
1210 auto* array = down_cast<LongArray*>(a);
Sebastien Hertzabff6432014-01-27 18:01:39 +01001211 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001212 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001213 ADVANCE(2);
1214 } else {
1215 HANDLE_PENDING_EXCEPTION();
1216 }
1217 }
1218 }
1219 HANDLE_INSTRUCTION_END();
1220
1221 HANDLE_INSTRUCTION_START(APUT_OBJECT) {
1222 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001223 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001224 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001225 HANDLE_PENDING_EXCEPTION();
1226 } else {
1227 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001228 Object* val = shadow_frame.GetVRegReference(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001229 ObjectArray<Object>* array = a->AsObjectArray<Object>();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001230 if (LIKELY(array->CheckIsValidIndex(index) && array->CheckAssignable(val))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001231 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001232 ADVANCE(2);
1233 } else {
1234 HANDLE_PENDING_EXCEPTION();
1235 }
1236 }
1237 }
1238 HANDLE_INSTRUCTION_END();
1239
1240 HANDLE_INSTRUCTION_START(IGET_BOOLEAN) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001241 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimBoolean, do_access_check>(
1242 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001243 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1244 }
1245 HANDLE_INSTRUCTION_END();
1246
1247 HANDLE_INSTRUCTION_START(IGET_BYTE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001248 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimByte, do_access_check>(
1249 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001250 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1251 }
1252 HANDLE_INSTRUCTION_END();
1253
1254 HANDLE_INSTRUCTION_START(IGET_CHAR) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001255 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimChar, do_access_check>(
1256 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001257 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1258 }
1259 HANDLE_INSTRUCTION_END();
1260
1261 HANDLE_INSTRUCTION_START(IGET_SHORT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001262 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimShort, do_access_check>(
1263 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001264 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1265 }
1266 HANDLE_INSTRUCTION_END();
1267
1268 HANDLE_INSTRUCTION_START(IGET) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001269 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimInt, do_access_check>(
1270 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001271 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1272 }
1273 HANDLE_INSTRUCTION_END();
1274
1275 HANDLE_INSTRUCTION_START(IGET_WIDE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001276 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimLong, do_access_check>(
1277 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001278 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1279 }
1280 HANDLE_INSTRUCTION_END();
1281
1282 HANDLE_INSTRUCTION_START(IGET_OBJECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001283 bool success = DoFieldGet<InstanceObjectRead, Primitive::kPrimNot, do_access_check>(
1284 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001285 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1286 }
1287 HANDLE_INSTRUCTION_END();
1288
1289 HANDLE_INSTRUCTION_START(IGET_QUICK) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001290 bool success = DoIGetQuick<Primitive::kPrimInt>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001291 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1292 }
1293 HANDLE_INSTRUCTION_END();
1294
Mathieu Chartierffc605c2014-12-10 10:35:44 -08001295 HANDLE_INSTRUCTION_START(IGET_BOOLEAN_QUICK) {
1296 bool success = DoIGetQuick<Primitive::kPrimBoolean>(shadow_frame, inst, inst_data);
1297 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1298 }
1299 HANDLE_INSTRUCTION_END();
1300
1301 HANDLE_INSTRUCTION_START(IGET_BYTE_QUICK) {
1302 bool success = DoIGetQuick<Primitive::kPrimByte>(shadow_frame, inst, inst_data);
1303 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1304 }
1305 HANDLE_INSTRUCTION_END();
1306
1307 HANDLE_INSTRUCTION_START(IGET_CHAR_QUICK) {
1308 bool success = DoIGetQuick<Primitive::kPrimChar>(shadow_frame, inst, inst_data);
1309 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1310 }
1311 HANDLE_INSTRUCTION_END();
1312
1313 HANDLE_INSTRUCTION_START(IGET_SHORT_QUICK) {
1314 bool success = DoIGetQuick<Primitive::kPrimShort>(shadow_frame, inst, inst_data);
1315 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1316 }
1317 HANDLE_INSTRUCTION_END();
1318
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001319 HANDLE_INSTRUCTION_START(IGET_WIDE_QUICK) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001320 bool success = DoIGetQuick<Primitive::kPrimLong>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001321 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1322 }
1323 HANDLE_INSTRUCTION_END();
1324
1325 HANDLE_INSTRUCTION_START(IGET_OBJECT_QUICK) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001326 bool success = DoIGetQuick<Primitive::kPrimNot>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001327 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1328 }
1329 HANDLE_INSTRUCTION_END();
1330
1331 HANDLE_INSTRUCTION_START(SGET_BOOLEAN) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001332 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimBoolean, do_access_check>(
1333 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001334 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1335 }
1336 HANDLE_INSTRUCTION_END();
1337
1338 HANDLE_INSTRUCTION_START(SGET_BYTE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001339 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimByte, do_access_check>(
1340 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001341 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1342 }
1343 HANDLE_INSTRUCTION_END();
1344
1345 HANDLE_INSTRUCTION_START(SGET_CHAR) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001346 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimChar, do_access_check>(
1347 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001348 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1349 }
1350 HANDLE_INSTRUCTION_END();
1351
1352 HANDLE_INSTRUCTION_START(SGET_SHORT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001353 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimShort, do_access_check>(
1354 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001355 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1356 }
1357 HANDLE_INSTRUCTION_END();
1358
1359 HANDLE_INSTRUCTION_START(SGET) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001360 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimInt, do_access_check>(
1361 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001362 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1363 }
1364 HANDLE_INSTRUCTION_END();
1365
1366 HANDLE_INSTRUCTION_START(SGET_WIDE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001367 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimLong, do_access_check>(
1368 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001369 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1370 }
1371 HANDLE_INSTRUCTION_END();
1372
1373 HANDLE_INSTRUCTION_START(SGET_OBJECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001374 bool success = DoFieldGet<StaticObjectRead, Primitive::kPrimNot, do_access_check>(
1375 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001376 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1377 }
1378 HANDLE_INSTRUCTION_END();
1379
1380 HANDLE_INSTRUCTION_START(IPUT_BOOLEAN) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001381 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1382 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001383 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1384 }
1385 HANDLE_INSTRUCTION_END();
1386
1387 HANDLE_INSTRUCTION_START(IPUT_BYTE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001388 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimByte, do_access_check,
1389 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001390 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1391 }
1392 HANDLE_INSTRUCTION_END();
1393
1394 HANDLE_INSTRUCTION_START(IPUT_CHAR) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001395 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimChar, do_access_check,
1396 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001397 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1398 }
1399 HANDLE_INSTRUCTION_END();
1400
1401 HANDLE_INSTRUCTION_START(IPUT_SHORT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001402 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimShort, do_access_check,
1403 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001404 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1405 }
1406 HANDLE_INSTRUCTION_END();
1407
1408 HANDLE_INSTRUCTION_START(IPUT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001409 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimInt, do_access_check,
1410 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001411 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1412 }
1413 HANDLE_INSTRUCTION_END();
1414
1415 HANDLE_INSTRUCTION_START(IPUT_WIDE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001416 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimLong, do_access_check,
1417 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001418 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1419 }
1420 HANDLE_INSTRUCTION_END();
1421
1422 HANDLE_INSTRUCTION_START(IPUT_OBJECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001423 bool success = DoFieldPut<InstanceObjectWrite, Primitive::kPrimNot, do_access_check,
1424 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001425 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1426 }
1427 HANDLE_INSTRUCTION_END();
1428
1429 HANDLE_INSTRUCTION_START(IPUT_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001430 bool success = DoIPutQuick<Primitive::kPrimInt, transaction_active>(
1431 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001432 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1433 }
1434 HANDLE_INSTRUCTION_END();
1435
Fred Shih37f05ef2014-07-16 18:38:08 -07001436 HANDLE_INSTRUCTION_START(IPUT_BOOLEAN_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001437 bool success = DoIPutQuick<Primitive::kPrimBoolean, transaction_active>(
1438 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001439 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1440 }
1441 HANDLE_INSTRUCTION_END();
1442
1443 HANDLE_INSTRUCTION_START(IPUT_BYTE_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001444 bool success = DoIPutQuick<Primitive::kPrimByte, transaction_active>(
1445 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001446 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1447 }
1448 HANDLE_INSTRUCTION_END();
1449
1450 HANDLE_INSTRUCTION_START(IPUT_CHAR_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001451 bool success = DoIPutQuick<Primitive::kPrimChar, transaction_active>(
1452 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001453 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1454 }
1455 HANDLE_INSTRUCTION_END();
1456
1457 HANDLE_INSTRUCTION_START(IPUT_SHORT_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001458 bool success = DoIPutQuick<Primitive::kPrimShort, transaction_active>(
1459 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001460 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1461 }
1462 HANDLE_INSTRUCTION_END();
1463
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001464 HANDLE_INSTRUCTION_START(IPUT_WIDE_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001465 bool success = DoIPutQuick<Primitive::kPrimLong, transaction_active>(
1466 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001467 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1468 }
1469 HANDLE_INSTRUCTION_END();
1470
1471 HANDLE_INSTRUCTION_START(IPUT_OBJECT_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001472 bool success = DoIPutQuick<Primitive::kPrimNot, transaction_active>(
1473 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001474 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1475 }
1476 HANDLE_INSTRUCTION_END();
1477
1478 HANDLE_INSTRUCTION_START(SPUT_BOOLEAN) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001479 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1480 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001481 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1482 }
1483 HANDLE_INSTRUCTION_END();
1484
1485 HANDLE_INSTRUCTION_START(SPUT_BYTE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001486 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimByte, do_access_check,
1487 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001488 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1489 }
1490 HANDLE_INSTRUCTION_END();
1491
1492 HANDLE_INSTRUCTION_START(SPUT_CHAR) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001493 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimChar, do_access_check,
1494 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001495 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1496 }
1497 HANDLE_INSTRUCTION_END();
1498
1499 HANDLE_INSTRUCTION_START(SPUT_SHORT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001500 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimShort, do_access_check,
1501 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001502 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1503 }
1504 HANDLE_INSTRUCTION_END();
1505
1506 HANDLE_INSTRUCTION_START(SPUT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001507 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimInt, do_access_check,
1508 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001509 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1510 }
1511 HANDLE_INSTRUCTION_END();
1512
1513 HANDLE_INSTRUCTION_START(SPUT_WIDE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001514 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimLong, do_access_check,
1515 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001516 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1517 }
1518 HANDLE_INSTRUCTION_END();
1519
1520 HANDLE_INSTRUCTION_START(SPUT_OBJECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001521 bool success = DoFieldPut<StaticObjectWrite, Primitive::kPrimNot, do_access_check,
1522 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001523 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1524 }
1525 HANDLE_INSTRUCTION_END();
1526
1527 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001528 bool success = DoInvoke<kVirtual, false, do_access_check>(
1529 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001530 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001531 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1532 }
1533 HANDLE_INSTRUCTION_END();
1534
1535 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001536 bool success = DoInvoke<kVirtual, true, do_access_check>(
1537 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001538 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001539 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1540 }
1541 HANDLE_INSTRUCTION_END();
1542
1543 HANDLE_INSTRUCTION_START(INVOKE_SUPER) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001544 bool success = DoInvoke<kSuper, false, do_access_check>(
1545 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001546 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001547 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1548 }
1549 HANDLE_INSTRUCTION_END();
1550
1551 HANDLE_INSTRUCTION_START(INVOKE_SUPER_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001552 bool success = DoInvoke<kSuper, true, do_access_check>(
1553 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001554 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001555 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1556 }
1557 HANDLE_INSTRUCTION_END();
1558
1559 HANDLE_INSTRUCTION_START(INVOKE_DIRECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001560 bool success = DoInvoke<kDirect, false, do_access_check>(
1561 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001562 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001563 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1564 }
1565 HANDLE_INSTRUCTION_END();
1566
1567 HANDLE_INSTRUCTION_START(INVOKE_DIRECT_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001568 bool success = DoInvoke<kDirect, true, do_access_check>(
1569 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001570 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001571 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1572 }
1573 HANDLE_INSTRUCTION_END();
1574
1575 HANDLE_INSTRUCTION_START(INVOKE_INTERFACE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001576 bool success = DoInvoke<kInterface, false, do_access_check>(
1577 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001578 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001579 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1580 }
1581 HANDLE_INSTRUCTION_END();
1582
1583 HANDLE_INSTRUCTION_START(INVOKE_INTERFACE_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001584 bool success = DoInvoke<kInterface, true, do_access_check>(
1585 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001586 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001587 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1588 }
1589 HANDLE_INSTRUCTION_END();
1590
1591 HANDLE_INSTRUCTION_START(INVOKE_STATIC) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001592 bool success = DoInvoke<kStatic, false, do_access_check>(
1593 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001594 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001595 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1596 }
1597 HANDLE_INSTRUCTION_END();
1598
1599 HANDLE_INSTRUCTION_START(INVOKE_STATIC_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001600 bool success = DoInvoke<kStatic, true, do_access_check>(
1601 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001602 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001603 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1604 }
1605 HANDLE_INSTRUCTION_END();
1606
1607 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001608 bool success = DoInvokeVirtualQuick<false>(
1609 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001610 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001611 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1612 }
1613 HANDLE_INSTRUCTION_END();
1614
1615 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_RANGE_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001616 bool success = DoInvokeVirtualQuick<true>(
1617 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001618 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001619 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1620 }
1621 HANDLE_INSTRUCTION_END();
1622
Igor Murashkin158f35c2015-06-10 15:55:30 -07001623 HANDLE_EXPERIMENTAL_INSTRUCTION_START(INVOKE_LAMBDA) {
1624 bool success = DoInvokeLambda<do_access_check>(self, shadow_frame, inst, inst_data,
1625 &result_register);
1626 UPDATE_HANDLER_TABLE();
1627 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1628 }
1629 HANDLE_EXPERIMENTAL_INSTRUCTION_END();
1630
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001631 HANDLE_INSTRUCTION_START(NEG_INT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001632 shadow_frame.SetVReg(
1633 inst->VRegA_12x(inst_data), -shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001634 ADVANCE(1);
1635 HANDLE_INSTRUCTION_END();
1636
1637 HANDLE_INSTRUCTION_START(NOT_INT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001638 shadow_frame.SetVReg(
1639 inst->VRegA_12x(inst_data), ~shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001640 ADVANCE(1);
1641 HANDLE_INSTRUCTION_END();
1642
1643 HANDLE_INSTRUCTION_START(NEG_LONG)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001644 shadow_frame.SetVRegLong(
1645 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001646 ADVANCE(1);
1647 HANDLE_INSTRUCTION_END();
1648
1649 HANDLE_INSTRUCTION_START(NOT_LONG)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001650 shadow_frame.SetVRegLong(
1651 inst->VRegA_12x(inst_data), ~shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001652 ADVANCE(1);
1653 HANDLE_INSTRUCTION_END();
1654
1655 HANDLE_INSTRUCTION_START(NEG_FLOAT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001656 shadow_frame.SetVRegFloat(
1657 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001658 ADVANCE(1);
1659 HANDLE_INSTRUCTION_END();
1660
1661 HANDLE_INSTRUCTION_START(NEG_DOUBLE)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001662 shadow_frame.SetVRegDouble(
1663 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001664 ADVANCE(1);
1665 HANDLE_INSTRUCTION_END();
1666
1667 HANDLE_INSTRUCTION_START(INT_TO_LONG)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001668 shadow_frame.SetVRegLong(
1669 inst->VRegA_12x(inst_data), shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001670 ADVANCE(1);
1671 HANDLE_INSTRUCTION_END();
1672
1673 HANDLE_INSTRUCTION_START(INT_TO_FLOAT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001674 shadow_frame.SetVRegFloat(
1675 inst->VRegA_12x(inst_data), shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001676 ADVANCE(1);
1677 HANDLE_INSTRUCTION_END();
1678
1679 HANDLE_INSTRUCTION_START(INT_TO_DOUBLE)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001680 shadow_frame.SetVRegDouble(
1681 inst->VRegA_12x(inst_data), shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001682 ADVANCE(1);
1683 HANDLE_INSTRUCTION_END();
1684
1685 HANDLE_INSTRUCTION_START(LONG_TO_INT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001686 shadow_frame.SetVReg(
1687 inst->VRegA_12x(inst_data), shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001688 ADVANCE(1);
1689 HANDLE_INSTRUCTION_END();
1690
1691 HANDLE_INSTRUCTION_START(LONG_TO_FLOAT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001692 shadow_frame.SetVRegFloat(
1693 inst->VRegA_12x(inst_data), shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001694 ADVANCE(1);
1695 HANDLE_INSTRUCTION_END();
1696
1697 HANDLE_INSTRUCTION_START(LONG_TO_DOUBLE)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001698 shadow_frame.SetVRegDouble(
1699 inst->VRegA_12x(inst_data), shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001700 ADVANCE(1);
1701 HANDLE_INSTRUCTION_END();
1702
1703 HANDLE_INSTRUCTION_START(FLOAT_TO_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001704 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001705 int32_t result = art_float_to_integral<int32_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001706 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001707 ADVANCE(1);
1708 }
1709 HANDLE_INSTRUCTION_END();
1710
1711 HANDLE_INSTRUCTION_START(FLOAT_TO_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001712 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001713 int64_t result = art_float_to_integral<int64_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001714 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001715 ADVANCE(1);
1716 }
1717 HANDLE_INSTRUCTION_END();
1718
1719 HANDLE_INSTRUCTION_START(FLOAT_TO_DOUBLE)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001720 shadow_frame.SetVRegDouble(
1721 inst->VRegA_12x(inst_data), shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001722 ADVANCE(1);
1723 HANDLE_INSTRUCTION_END();
1724
1725 HANDLE_INSTRUCTION_START(DOUBLE_TO_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001726 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001727 int32_t result = art_float_to_integral<int32_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001728 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001729 ADVANCE(1);
1730 }
1731 HANDLE_INSTRUCTION_END();
1732
1733 HANDLE_INSTRUCTION_START(DOUBLE_TO_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001734 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001735 int64_t result = art_float_to_integral<int64_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001736 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001737 ADVANCE(1);
1738 }
1739 HANDLE_INSTRUCTION_END();
1740
1741 HANDLE_INSTRUCTION_START(DOUBLE_TO_FLOAT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001742 shadow_frame.SetVRegFloat(
1743 inst->VRegA_12x(inst_data), shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001744 ADVANCE(1);
1745 HANDLE_INSTRUCTION_END();
1746
1747 HANDLE_INSTRUCTION_START(INT_TO_BYTE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001748 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1749 static_cast<int8_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001750 ADVANCE(1);
1751 HANDLE_INSTRUCTION_END();
1752
1753 HANDLE_INSTRUCTION_START(INT_TO_CHAR)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001754 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1755 static_cast<uint16_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001756 ADVANCE(1);
1757 HANDLE_INSTRUCTION_END();
1758
1759 HANDLE_INSTRUCTION_START(INT_TO_SHORT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001760 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1761 static_cast<int16_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001762 ADVANCE(1);
1763 HANDLE_INSTRUCTION_END();
1764
1765 HANDLE_INSTRUCTION_START(ADD_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001766 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001767 SafeAdd(shadow_frame.GetVReg(inst->VRegB_23x()),
1768 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001769 ADVANCE(2);
1770 HANDLE_INSTRUCTION_END();
1771
1772 HANDLE_INSTRUCTION_START(SUB_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001773 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001774 SafeSub(shadow_frame.GetVReg(inst->VRegB_23x()),
1775 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001776 ADVANCE(2);
1777 HANDLE_INSTRUCTION_END();
1778
1779 HANDLE_INSTRUCTION_START(MUL_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001780 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001781 SafeMul(shadow_frame.GetVReg(inst->VRegB_23x()),
1782 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001783 ADVANCE(2);
1784 HANDLE_INSTRUCTION_END();
1785
1786 HANDLE_INSTRUCTION_START(DIV_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001787 bool success = DoIntDivide(shadow_frame, inst->VRegA_23x(inst_data),
1788 shadow_frame.GetVReg(inst->VRegB_23x()),
1789 shadow_frame.GetVReg(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001790 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1791 }
1792 HANDLE_INSTRUCTION_END();
1793
1794 HANDLE_INSTRUCTION_START(REM_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001795 bool success = DoIntRemainder(shadow_frame, inst->VRegA_23x(inst_data),
1796 shadow_frame.GetVReg(inst->VRegB_23x()),
1797 shadow_frame.GetVReg(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001798 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1799 }
1800 HANDLE_INSTRUCTION_END();
1801
1802 HANDLE_INSTRUCTION_START(SHL_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001803 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001804 shadow_frame.GetVReg(inst->VRegB_23x()) <<
1805 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1806 ADVANCE(2);
1807 HANDLE_INSTRUCTION_END();
1808
1809 HANDLE_INSTRUCTION_START(SHR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001810 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001811 shadow_frame.GetVReg(inst->VRegB_23x()) >>
1812 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1813 ADVANCE(2);
1814 HANDLE_INSTRUCTION_END();
1815
1816 HANDLE_INSTRUCTION_START(USHR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001817 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001818 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_23x())) >>
1819 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1820 ADVANCE(2);
1821 HANDLE_INSTRUCTION_END();
1822
1823 HANDLE_INSTRUCTION_START(AND_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001824 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001825 shadow_frame.GetVReg(inst->VRegB_23x()) &
1826 shadow_frame.GetVReg(inst->VRegC_23x()));
1827 ADVANCE(2);
1828 HANDLE_INSTRUCTION_END();
1829
1830 HANDLE_INSTRUCTION_START(OR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001831 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001832 shadow_frame.GetVReg(inst->VRegB_23x()) |
1833 shadow_frame.GetVReg(inst->VRegC_23x()));
1834 ADVANCE(2);
1835 HANDLE_INSTRUCTION_END();
1836
1837 HANDLE_INSTRUCTION_START(XOR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001838 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001839 shadow_frame.GetVReg(inst->VRegB_23x()) ^
1840 shadow_frame.GetVReg(inst->VRegC_23x()));
1841 ADVANCE(2);
1842 HANDLE_INSTRUCTION_END();
1843
1844 HANDLE_INSTRUCTION_START(ADD_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001845 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001846 SafeAdd(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1847 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001848 ADVANCE(2);
1849 HANDLE_INSTRUCTION_END();
1850
1851 HANDLE_INSTRUCTION_START(SUB_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001852 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001853 SafeSub(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1854 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001855 ADVANCE(2);
1856 HANDLE_INSTRUCTION_END();
1857
1858 HANDLE_INSTRUCTION_START(MUL_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001859 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001860 SafeMul(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1861 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001862 ADVANCE(2);
1863 HANDLE_INSTRUCTION_END();
1864
1865 HANDLE_INSTRUCTION_START(DIV_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001866 bool success = DoLongDivide(shadow_frame, inst->VRegA_23x(inst_data),
1867 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1868 shadow_frame.GetVRegLong(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001869 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1870 }
1871 HANDLE_INSTRUCTION_END();
1872
1873 HANDLE_INSTRUCTION_START(REM_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001874 bool success = DoLongRemainder(shadow_frame, inst->VRegA_23x(inst_data),
1875 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1876 shadow_frame.GetVRegLong(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001877 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1878 }
1879 HANDLE_INSTRUCTION_END();
1880
1881 HANDLE_INSTRUCTION_START(AND_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001882 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001883 shadow_frame.GetVRegLong(inst->VRegB_23x()) &
1884 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1885 ADVANCE(2);
1886 HANDLE_INSTRUCTION_END();
1887
1888 HANDLE_INSTRUCTION_START(OR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001889 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001890 shadow_frame.GetVRegLong(inst->VRegB_23x()) |
1891 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1892 ADVANCE(2);
1893 HANDLE_INSTRUCTION_END();
1894
1895 HANDLE_INSTRUCTION_START(XOR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001896 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001897 shadow_frame.GetVRegLong(inst->VRegB_23x()) ^
1898 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1899 ADVANCE(2);
1900 HANDLE_INSTRUCTION_END();
1901
1902 HANDLE_INSTRUCTION_START(SHL_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001903 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001904 shadow_frame.GetVRegLong(inst->VRegB_23x()) <<
1905 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1906 ADVANCE(2);
1907 HANDLE_INSTRUCTION_END();
1908
1909 HANDLE_INSTRUCTION_START(SHR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001910 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001911 shadow_frame.GetVRegLong(inst->VRegB_23x()) >>
1912 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1913 ADVANCE(2);
1914 HANDLE_INSTRUCTION_END();
1915
1916 HANDLE_INSTRUCTION_START(USHR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001917 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001918 static_cast<uint64_t>(shadow_frame.GetVRegLong(inst->VRegB_23x())) >>
1919 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1920 ADVANCE(2);
1921 HANDLE_INSTRUCTION_END();
1922
1923 HANDLE_INSTRUCTION_START(ADD_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001924 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001925 shadow_frame.GetVRegFloat(inst->VRegB_23x()) +
1926 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1927 ADVANCE(2);
1928 HANDLE_INSTRUCTION_END();
1929
1930 HANDLE_INSTRUCTION_START(SUB_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001931 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001932 shadow_frame.GetVRegFloat(inst->VRegB_23x()) -
1933 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1934 ADVANCE(2);
1935 HANDLE_INSTRUCTION_END();
1936
1937 HANDLE_INSTRUCTION_START(MUL_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001938 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001939 shadow_frame.GetVRegFloat(inst->VRegB_23x()) *
1940 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1941 ADVANCE(2);
1942 HANDLE_INSTRUCTION_END();
1943
1944 HANDLE_INSTRUCTION_START(DIV_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001945 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001946 shadow_frame.GetVRegFloat(inst->VRegB_23x()) /
1947 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1948 ADVANCE(2);
1949 HANDLE_INSTRUCTION_END();
1950
1951 HANDLE_INSTRUCTION_START(REM_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001952 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001953 fmodf(shadow_frame.GetVRegFloat(inst->VRegB_23x()),
1954 shadow_frame.GetVRegFloat(inst->VRegC_23x())));
1955 ADVANCE(2);
1956 HANDLE_INSTRUCTION_END();
1957
1958 HANDLE_INSTRUCTION_START(ADD_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001959 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001960 shadow_frame.GetVRegDouble(inst->VRegB_23x()) +
1961 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1962 ADVANCE(2);
1963 HANDLE_INSTRUCTION_END();
1964
1965 HANDLE_INSTRUCTION_START(SUB_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001966 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001967 shadow_frame.GetVRegDouble(inst->VRegB_23x()) -
1968 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1969 ADVANCE(2);
1970 HANDLE_INSTRUCTION_END();
1971
1972 HANDLE_INSTRUCTION_START(MUL_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001973 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001974 shadow_frame.GetVRegDouble(inst->VRegB_23x()) *
1975 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1976 ADVANCE(2);
1977 HANDLE_INSTRUCTION_END();
1978
1979 HANDLE_INSTRUCTION_START(DIV_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001980 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001981 shadow_frame.GetVRegDouble(inst->VRegB_23x()) /
1982 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1983 ADVANCE(2);
1984 HANDLE_INSTRUCTION_END();
1985
1986 HANDLE_INSTRUCTION_START(REM_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001987 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001988 fmod(shadow_frame.GetVRegDouble(inst->VRegB_23x()),
1989 shadow_frame.GetVRegDouble(inst->VRegC_23x())));
1990 ADVANCE(2);
1991 HANDLE_INSTRUCTION_END();
1992
1993 HANDLE_INSTRUCTION_START(ADD_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001994 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001995 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07001996 SafeAdd(shadow_frame.GetVReg(vregA),
1997 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001998 ADVANCE(1);
1999 }
2000 HANDLE_INSTRUCTION_END();
2001
2002 HANDLE_INSTRUCTION_START(SUB_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 SafeSub(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(MUL_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 SafeMul(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(DIV_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 bool success = DoIntDivide(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002023 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002024 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2025 }
2026 HANDLE_INSTRUCTION_END();
2027
2028 HANDLE_INSTRUCTION_START(REM_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002029 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002030 bool success = DoIntRemainder(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002031 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002032 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2033 }
2034 HANDLE_INSTRUCTION_END();
2035
2036 HANDLE_INSTRUCTION_START(SHL_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002037 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002038 shadow_frame.SetVReg(vregA,
2039 shadow_frame.GetVReg(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002040 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002041 ADVANCE(1);
2042 }
2043 HANDLE_INSTRUCTION_END();
2044
2045 HANDLE_INSTRUCTION_START(SHR_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(USHR_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 static_cast<uint32_t>(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(AND_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 shadow_frame.GetVReg(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002067 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002068 ADVANCE(1);
2069 }
2070 HANDLE_INSTRUCTION_END();
2071
2072 HANDLE_INSTRUCTION_START(OR_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(XOR_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(ADD_LONG_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.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002093 SafeAdd(shadow_frame.GetVRegLong(vregA),
2094 shadow_frame.GetVRegLong(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(SUB_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 SafeSub(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(MUL_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 SafeMul(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(DIV_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 bool success = DoLongDivide(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002120 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002121 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2122 }
2123 HANDLE_INSTRUCTION_END();
2124
2125 HANDLE_INSTRUCTION_START(REM_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002126 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002127 bool success = DoLongRemainder(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002128 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002129 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2130 }
2131 HANDLE_INSTRUCTION_END();
2132
2133 HANDLE_INSTRUCTION_START(AND_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002134 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002135 shadow_frame.SetVRegLong(vregA,
2136 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 ADVANCE(1);
2139 }
2140 HANDLE_INSTRUCTION_END();
2141
2142 HANDLE_INSTRUCTION_START(OR_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(XOR_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(SHL_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.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002165 ADVANCE(1);
2166 }
2167 HANDLE_INSTRUCTION_END();
2168
2169 HANDLE_INSTRUCTION_START(SHR_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(USHR_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 static_cast<uint64_t>(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(ADD_FLOAT_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.SetVRegFloat(vregA,
2190 shadow_frame.GetVRegFloat(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002191 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002192 ADVANCE(1);
2193 }
2194 HANDLE_INSTRUCTION_END();
2195
2196 HANDLE_INSTRUCTION_START(SUB_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(MUL_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(DIV_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(REM_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 fmodf(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(ADD_DOUBLE_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.SetVRegDouble(vregA,
2235 shadow_frame.GetVRegDouble(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002236 shadow_frame.GetVRegDouble(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(SUB_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(MUL_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(DIV_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(REM_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 fmod(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(ADD_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002278 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002279 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2280 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002281 ADVANCE(2);
2282 HANDLE_INSTRUCTION_END();
2283
2284 HANDLE_INSTRUCTION_START(RSUB_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002285 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002286 SafeSub(inst->VRegC_22s(),
2287 shadow_frame.GetVReg(inst->VRegB_22s(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002288 ADVANCE(2);
2289 HANDLE_INSTRUCTION_END();
2290
2291 HANDLE_INSTRUCTION_START(MUL_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002292 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002293 SafeMul(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2294 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002295 ADVANCE(2);
2296 HANDLE_INSTRUCTION_END();
2297
2298 HANDLE_INSTRUCTION_START(DIV_INT_LIT16) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002299 bool success = DoIntDivide(
2300 shadow_frame, inst->VRegA_22s(inst_data), shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2301 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002302 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2303 }
2304 HANDLE_INSTRUCTION_END();
2305
2306 HANDLE_INSTRUCTION_START(REM_INT_LIT16) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002307 bool success = DoIntRemainder(
2308 shadow_frame, inst->VRegA_22s(inst_data), shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2309 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002310 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2311 }
2312 HANDLE_INSTRUCTION_END();
2313
2314 HANDLE_INSTRUCTION_START(AND_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002315 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2316 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) &
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002317 inst->VRegC_22s());
2318 ADVANCE(2);
2319 HANDLE_INSTRUCTION_END();
2320
2321 HANDLE_INSTRUCTION_START(OR_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002322 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2323 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) |
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002324 inst->VRegC_22s());
2325 ADVANCE(2);
2326 HANDLE_INSTRUCTION_END();
2327
2328 HANDLE_INSTRUCTION_START(XOR_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002329 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2330 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) ^
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002331 inst->VRegC_22s());
2332 ADVANCE(2);
2333 HANDLE_INSTRUCTION_END();
2334
2335 HANDLE_INSTRUCTION_START(ADD_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002336 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002337 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22b()),
2338 inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002339 ADVANCE(2);
2340 HANDLE_INSTRUCTION_END();
2341
2342 HANDLE_INSTRUCTION_START(RSUB_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002343 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002344 SafeSub(inst->VRegC_22b(),
2345 shadow_frame.GetVReg(inst->VRegB_22b())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002346 ADVANCE(2);
2347 HANDLE_INSTRUCTION_END();
2348
2349 HANDLE_INSTRUCTION_START(MUL_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002350 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002351 SafeMul(shadow_frame.GetVReg(inst->VRegB_22b()),
2352 inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002353 ADVANCE(2);
2354 HANDLE_INSTRUCTION_END();
2355
2356 HANDLE_INSTRUCTION_START(DIV_INT_LIT8) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002357 bool success = DoIntDivide(shadow_frame, inst->VRegA_22b(inst_data),
2358 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002359 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2360 }
2361 HANDLE_INSTRUCTION_END();
2362
2363 HANDLE_INSTRUCTION_START(REM_INT_LIT8) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002364 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22b(inst_data),
2365 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002366 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2367 }
2368 HANDLE_INSTRUCTION_END();
2369
2370 HANDLE_INSTRUCTION_START(AND_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002371 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002372 shadow_frame.GetVReg(inst->VRegB_22b()) &
2373 inst->VRegC_22b());
2374 ADVANCE(2);
2375 HANDLE_INSTRUCTION_END();
2376
2377 HANDLE_INSTRUCTION_START(OR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002378 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002379 shadow_frame.GetVReg(inst->VRegB_22b()) |
2380 inst->VRegC_22b());
2381 ADVANCE(2);
2382 HANDLE_INSTRUCTION_END();
2383
2384 HANDLE_INSTRUCTION_START(XOR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002385 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002386 shadow_frame.GetVReg(inst->VRegB_22b()) ^
2387 inst->VRegC_22b());
2388 ADVANCE(2);
2389 HANDLE_INSTRUCTION_END();
2390
2391 HANDLE_INSTRUCTION_START(SHL_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002392 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002393 shadow_frame.GetVReg(inst->VRegB_22b()) <<
2394 (inst->VRegC_22b() & 0x1f));
2395 ADVANCE(2);
2396 HANDLE_INSTRUCTION_END();
2397
2398 HANDLE_INSTRUCTION_START(SHR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002399 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002400 shadow_frame.GetVReg(inst->VRegB_22b()) >>
2401 (inst->VRegC_22b() & 0x1f));
2402 ADVANCE(2);
2403 HANDLE_INSTRUCTION_END();
2404
2405 HANDLE_INSTRUCTION_START(USHR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002406 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002407 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_22b())) >>
2408 (inst->VRegC_22b() & 0x1f));
2409 ADVANCE(2);
2410 HANDLE_INSTRUCTION_END();
2411
Igor Murashkin158f35c2015-06-10 15:55:30 -07002412 HANDLE_EXPERIMENTAL_INSTRUCTION_START(CREATE_LAMBDA) {
2413 bool success = DoCreateLambda<true>(self, shadow_frame, inst);
2414 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2415 }
2416 HANDLE_EXPERIMENTAL_INSTRUCTION_END();
2417
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002418 HANDLE_INSTRUCTION_START(UNUSED_3E)
Ian Rogerse94652f2014-12-02 11:13:19 -08002419 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002420 HANDLE_INSTRUCTION_END();
2421
2422 HANDLE_INSTRUCTION_START(UNUSED_3F)
Ian Rogerse94652f2014-12-02 11:13:19 -08002423 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002424 HANDLE_INSTRUCTION_END();
2425
2426 HANDLE_INSTRUCTION_START(UNUSED_40)
Ian Rogerse94652f2014-12-02 11:13:19 -08002427 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002428 HANDLE_INSTRUCTION_END();
2429
2430 HANDLE_INSTRUCTION_START(UNUSED_41)
Ian Rogerse94652f2014-12-02 11:13:19 -08002431 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002432 HANDLE_INSTRUCTION_END();
2433
2434 HANDLE_INSTRUCTION_START(UNUSED_42)
Ian Rogerse94652f2014-12-02 11:13:19 -08002435 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002436 HANDLE_INSTRUCTION_END();
2437
2438 HANDLE_INSTRUCTION_START(UNUSED_43)
Ian Rogerse94652f2014-12-02 11:13:19 -08002439 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002440 HANDLE_INSTRUCTION_END();
2441
2442 HANDLE_INSTRUCTION_START(UNUSED_79)
Ian Rogerse94652f2014-12-02 11:13:19 -08002443 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002444 HANDLE_INSTRUCTION_END();
2445
2446 HANDLE_INSTRUCTION_START(UNUSED_7A)
Ian Rogerse94652f2014-12-02 11:13:19 -08002447 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002448 HANDLE_INSTRUCTION_END();
2449
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002450 HANDLE_INSTRUCTION_START(UNUSED_F4)
Ian Rogerse94652f2014-12-02 11:13:19 -08002451 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002452 HANDLE_INSTRUCTION_END();
2453
2454 HANDLE_INSTRUCTION_START(UNUSED_F5)
Ian Rogerse94652f2014-12-02 11:13:19 -08002455 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002456 HANDLE_INSTRUCTION_END();
2457
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002458 HANDLE_INSTRUCTION_START(UNUSED_F7)
Ian Rogerse94652f2014-12-02 11:13:19 -08002459 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002460 HANDLE_INSTRUCTION_END();
2461
2462 HANDLE_INSTRUCTION_START(UNUSED_F8)
Ian Rogerse94652f2014-12-02 11:13:19 -08002463 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002464 HANDLE_INSTRUCTION_END();
2465
2466 HANDLE_INSTRUCTION_START(UNUSED_F9)
Ian Rogerse94652f2014-12-02 11:13:19 -08002467 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002468 HANDLE_INSTRUCTION_END();
2469
2470 HANDLE_INSTRUCTION_START(UNUSED_FA)
Ian Rogerse94652f2014-12-02 11:13:19 -08002471 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002472 HANDLE_INSTRUCTION_END();
2473
2474 HANDLE_INSTRUCTION_START(UNUSED_FB)
Ian Rogerse94652f2014-12-02 11:13:19 -08002475 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002476 HANDLE_INSTRUCTION_END();
2477
2478 HANDLE_INSTRUCTION_START(UNUSED_FC)
Ian Rogerse94652f2014-12-02 11:13:19 -08002479 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002480 HANDLE_INSTRUCTION_END();
2481
2482 HANDLE_INSTRUCTION_START(UNUSED_FD)
Ian Rogerse94652f2014-12-02 11:13:19 -08002483 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002484 HANDLE_INSTRUCTION_END();
2485
2486 HANDLE_INSTRUCTION_START(UNUSED_FE)
Ian Rogerse94652f2014-12-02 11:13:19 -08002487 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002488 HANDLE_INSTRUCTION_END();
2489
2490 HANDLE_INSTRUCTION_START(UNUSED_FF)
Ian Rogerse94652f2014-12-02 11:13:19 -08002491 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002492 HANDLE_INSTRUCTION_END();
2493
2494 exception_pending_label: {
2495 CHECK(self->IsExceptionPending());
Sebastien Hertz1eda2262013-09-09 16:53:14 +02002496 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -07002497 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +02002498 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +02002499 }
Sebastien Hertzee1997a2013-09-19 14:47:09 +02002500 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002501 uint32_t found_dex_pc = FindNextInstructionFollowingException(self, shadow_frame, dex_pc,
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002502 instrumentation);
2503 if (found_dex_pc == DexFile::kDexNoIndex) {
2504 return JValue(); /* Handled in caller. */
2505 } else {
2506 int32_t displacement = static_cast<int32_t>(found_dex_pc) - static_cast<int32_t>(dex_pc);
2507 ADVANCE(displacement);
2508 }
2509 }
2510
Sebastien Hertz8379b222014-02-24 17:38:15 +01002511// Create alternative instruction handlers dedicated to instrumentation.
2512// Return instructions must not call Instrumentation::DexPcMovedEvent since they already call
2513// Instrumentation::MethodExited. This is to avoid posting debugger events twice for this location.
Sebastien Hertze713d932014-05-15 10:48:53 +02002514// Note: we do not use the kReturn instruction flag here (to test the instruction is a return). The
2515// compiler seems to not evaluate "(Instruction::FlagsOf(Instruction::code) & kReturn) != 0" to
2516// a constant condition that would remove the "if" statement so the test is free.
Sebastien Hertz9d6bf692015-04-10 12:12:33 +02002517#define INSTRUMENTATION_INSTRUCTION_HANDLER(o, code, n, f, r, i, a, v) \
2518 alt_op_##code: { \
2519 Runtime* const runtime = Runtime::Current(); \
2520 const instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation(); \
2521 if (UNLIKELY(instrumentation->HasDexPcListeners())) { \
2522 Object* this_object = shadow_frame.GetThisObject(code_item->ins_size_); \
2523 instrumentation->DexPcMovedEvent(self, this_object, shadow_frame.GetMethod(), dex_pc); \
2524 } \
2525 UPDATE_HANDLER_TABLE(); \
2526 goto *handlersTable[instrumentation::kMainHandlerTable][Instruction::code]; \
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002527 }
2528#include "dex_instruction_list.h"
2529 DEX_INSTRUCTION_LIST(INSTRUMENTATION_INSTRUCTION_HANDLER)
2530#undef DEX_INSTRUCTION_LIST
2531#undef INSTRUMENTATION_INSTRUCTION_HANDLER
2532} // NOLINT(readability/fn_size)
2533
2534// Explicit definitions of ExecuteGotoImpl.
Sebastien Hertzc6714852013-09-30 16:42:32 +02002535template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) HOT_ATTR
Ian Rogerse94652f2014-12-02 11:13:19 -08002536JValue ExecuteGotoImpl<true, false>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002537 ShadowFrame& shadow_frame, JValue result_register);
Sebastien Hertzc6714852013-09-30 16:42:32 +02002538template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) HOT_ATTR
Ian Rogerse94652f2014-12-02 11:13:19 -08002539JValue ExecuteGotoImpl<false, false>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002540 ShadowFrame& shadow_frame, JValue result_register);
2541template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
Ian Rogerse94652f2014-12-02 11:13:19 -08002542JValue ExecuteGotoImpl<true, true>(Thread* self, const DexFile::CodeItem* code_item,
2543 ShadowFrame& shadow_frame, JValue result_register);
2544template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
2545JValue ExecuteGotoImpl<false, true>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002546 ShadowFrame& shadow_frame, JValue result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002547
2548} // namespace interpreter
2549} // namespace art
Colin Crosse84e4f72015-03-18 14:01:19 -07002550
2551#endif