blob: 37dd63b4d87f51464f4490fc5089cd12c21691e5 [file] [log] [blame]
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Andreas Gampe5e26eb12016-08-22 17:54:17 -070017#include "interpreter_goto_table_impl.h"
18
19// Common includes
20#include "base/logging.h"
21#include "base/macros.h"
22#include "base/mutex.h"
23#include "stack.h"
24#include "thread.h"
25
26// Clang compiles the GOTO interpreter very slowly. So we skip it. These are the implementation
27// details only necessary when compiling it.
Colin Crosse84e4f72015-03-18 14:01:19 -070028#if !defined(__clang__)
Alex Lighteb7c1442015-08-31 13:17:42 -070029#include "experimental_flags.h"
Sebastien Hertz8ece0502013-08-07 11:26:41 +020030#include "interpreter_common.h"
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +000031#include "jit/jit.h"
Ian Rogersf72a11d2014-10-30 15:41:08 -070032#include "safe_math.h"
Andreas Gampe5e26eb12016-08-22 17:54:17 -070033#endif
Sebastien Hertz8ece0502013-08-07 11:26:41 +020034
35namespace art {
36namespace interpreter {
37
Andreas Gampe5e26eb12016-08-22 17:54:17 -070038#if !defined(__clang__)
39
Sebastien Hertz8ece0502013-08-07 11:26:41 +020040// In the following macros, we expect the following local variables exist:
41// - "self": the current Thread*.
42// - "inst" : the current Instruction*.
Sebastien Hertz3b588e02013-09-11 14:33:18 +020043// - "inst_data" : the current instruction's first 16 bits.
Sebastien Hertz8ece0502013-08-07 11:26:41 +020044// - "dex_pc": the current pc.
45// - "shadow_frame": the current shadow frame.
Sebastien Hertz8ece0502013-08-07 11:26:41 +020046// - "currentHandlersTable": the current table of pointer to each instruction handler.
47
48// Advance to the next instruction and updates interpreter state.
Sebastien Hertz8ece0502013-08-07 11:26:41 +020049#define ADVANCE(_offset) \
50 do { \
51 int32_t disp = static_cast<int32_t>(_offset); \
52 inst = inst->RelativeAt(disp); \
53 dex_pc = static_cast<uint32_t>(static_cast<int32_t>(dex_pc) + disp); \
54 shadow_frame.SetDexPC(dex_pc); \
Ian Rogerse94652f2014-12-02 11:13:19 -080055 TraceExecution(shadow_frame, inst, dex_pc); \
Sebastien Hertz3b588e02013-09-11 14:33:18 +020056 inst_data = inst->Fetch16(0); \
57 goto *currentHandlersTable[inst->Opcode(inst_data)]; \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020058 } while (false)
59
60#define HANDLE_PENDING_EXCEPTION() goto exception_pending_label
61
62#define POSSIBLY_HANDLE_PENDING_EXCEPTION(_is_exception_pending, _offset) \
63 do { \
64 if (UNLIKELY(_is_exception_pending)) { \
65 HANDLE_PENDING_EXCEPTION(); \
66 } else { \
67 ADVANCE(_offset); \
68 } \
69 } while (false)
70
Sebastien Hertzee1997a2013-09-19 14:47:09 +020071#define UPDATE_HANDLER_TABLE() \
Mathieu Chartier2cebb242015-04-21 16:50:40 -070072 currentHandlersTable = handlersTable[ \
73 Runtime::Current()->GetInstrumentation()->GetInterpreterHandlerTable()]
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +020074
Bill Buzbee1d011d92016-04-04 16:59:29 +000075#define BRANCH_INSTRUMENTATION(offset) \
76 do { \
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +010077 if (UNLIKELY(instrumentation->HasBranchListeners())) { \
78 instrumentation->Branch(self, method, dex_pc, offset); \
79 } \
Bill Buzbee1d011d92016-04-04 16:59:29 +000080 JValue result; \
81 if (jit::Jit::MaybeDoOnStackReplacement(self, method, dex_pc, offset, &result)) { \
82 return result; \
83 } \
84 } while (false)
85
86#define HOTNESS_UPDATE() \
87 do { \
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +010088 if (jit != nullptr) { \
Nicolas Geoffray71cd50f2016-04-14 15:00:33 +010089 jit->AddSamples(self, method, 1, /*with_backedges*/ true); \
Bill Buzbee1d011d92016-04-04 16:59:29 +000090 } \
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080091 } while (false)
92
Sebastien Hertz8ece0502013-08-07 11:26:41 +020093#define UNREACHABLE_CODE_CHECK() \
94 do { \
95 if (kIsDebugBuild) { \
96 LOG(FATAL) << "We should not be here !"; \
Ian Rogerse94652f2014-12-02 11:13:19 -080097 UNREACHABLE(); \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020098 } \
99 } while (false)
100
101#define HANDLE_INSTRUCTION_START(opcode) op_##opcode: // NOLINT(whitespace/labels)
102#define HANDLE_INSTRUCTION_END() UNREACHABLE_CODE_CHECK()
103
Andreas Gampe03ec9302015-08-27 17:41:47 -0700104#define HANDLE_MONITOR_CHECKS() \
Andreas Gampe56fdd0e2016-04-28 14:56:54 -0700105 if (!DoMonitorCheckOnExit<do_assignability_check>(self, &shadow_frame)) { \
Andreas Gampe03ec9302015-08-27 17:41:47 -0700106 HANDLE_PENDING_EXCEPTION(); \
107 }
Igor Murashkin158f35c2015-06-10 15:55:30 -0700108
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200109/**
110 * Interpreter based on computed goto tables.
111 *
112 * Each instruction is associated to a handler. This handler is responsible for executing the
113 * instruction and jump to the next instruction's handler.
114 * In order to limit the cost of instrumentation, we have two handler tables:
115 * - the "main" handler table: it contains handlers for normal execution of each instruction without
116 * handling of instrumentation.
117 * - the "alternative" handler table: it contains alternative handlers which first handle
118 * instrumentation before jumping to the corresponding "normal" instruction's handler.
119 *
120 * When instrumentation is active, the interpreter uses the "alternative" handler table. Otherwise
121 * it uses the "main" handler table.
122 *
123 * The current handler table is the handler table being used by the interpreter. It is updated:
124 * - on backward branch (goto, if and switch instructions)
125 * - after invoke
126 * - when an exception is thrown.
127 * This allows to support an attaching debugger to an already running application for instance.
128 *
129 * For a fast handler table update, handler tables are stored in an array of handler tables. Each
130 * handler table is represented by the InterpreterHandlerTable enum which allows to associate it
131 * to an index in this array of handler tables ((see Instrumentation::GetInterpreterHandlerTable).
132 *
133 * Here's the current layout of this array of handler tables:
134 *
135 * ---------------------+---------------+
136 * | NOP | (handler for NOP instruction)
137 * +---------------+
138 * "main" | MOVE | (handler for MOVE instruction)
139 * handler table +---------------+
140 * | ... |
141 * +---------------+
142 * | UNUSED_FF | (handler for UNUSED_FF instruction)
143 * ---------------------+---------------+
144 * | NOP | (alternative handler for NOP instruction)
145 * +---------------+
146 * "alternative" | MOVE | (alternative handler for MOVE instruction)
147 * handler table +---------------+
148 * | ... |
149 * +---------------+
150 * | UNUSED_FF | (alternative handler for UNUSED_FF instruction)
151 * ---------------------+---------------+
152 *
153 */
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100154template<bool do_access_check, bool transaction_active>
Ian Rogerse94652f2014-12-02 11:13:19 -0800155JValue ExecuteGotoImpl(Thread* self, const DexFile::CodeItem* code_item, ShadowFrame& shadow_frame,
156 JValue result_register) {
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200157 // Define handler tables:
158 // - The main handler table contains execution handlers for each instruction.
159 // - The alternative handler table contains prelude handlers which check for thread suspend and
160 // manage instrumentation before jumping to the execution handler.
161 static const void* const handlersTable[instrumentation::kNumHandlerTables][kNumPackedOpcodes] = {
162 {
163 // Main handler table.
Narayan Kamathbd48b342016-08-01 17:32:37 +0100164#define INSTRUCTION_HANDLER(o, code, n, f, i, a, v) &&op_##code,
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200165#include "dex_instruction_list.h"
166 DEX_INSTRUCTION_LIST(INSTRUCTION_HANDLER)
167#undef DEX_INSTRUCTION_LIST
168#undef INSTRUCTION_HANDLER
169 }, {
170 // Alternative handler table.
Narayan Kamathbd48b342016-08-01 17:32:37 +0100171#define INSTRUCTION_HANDLER(o, code, n, f, i, a, v) &&alt_op_##code,
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200172#include "dex_instruction_list.h"
173 DEX_INSTRUCTION_LIST(INSTRUCTION_HANDLER)
174#undef DEX_INSTRUCTION_LIST
175#undef INSTRUCTION_HANDLER
176 }
177 };
178
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800179 constexpr bool do_assignability_check = do_access_check;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200180 if (UNLIKELY(!shadow_frame.HasReferenceArray())) {
181 LOG(FATAL) << "Invalid shadow frame for interpreter use";
182 return JValue();
183 }
184 self->VerifyStack();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200185
186 uint32_t dex_pc = shadow_frame.GetDexPC();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200187 const Instruction* inst = Instruction::At(code_item->insns_ + dex_pc);
188 uint16_t inst_data;
189 const void* const* currentHandlersTable;
190 UPDATE_HANDLER_TABLE();
Bill Buzbee1d011d92016-04-04 16:59:29 +0000191 const auto* const instrumentation = Runtime::Current()->GetInstrumentation();
192 ArtMethod* method = shadow_frame.GetMethod();
193 jit::Jit* jit = Runtime::Current()->GetJit();
Igor Murashkin6918bf12015-09-27 19:19:06 -0700194
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200195 // Jump to first instruction.
196 ADVANCE(0);
197 UNREACHABLE_CODE_CHECK();
198
199 HANDLE_INSTRUCTION_START(NOP)
200 ADVANCE(1);
201 HANDLE_INSTRUCTION_END();
202
203 HANDLE_INSTRUCTION_START(MOVE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200204 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
205 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200206 ADVANCE(1);
207 HANDLE_INSTRUCTION_END();
208
209 HANDLE_INSTRUCTION_START(MOVE_FROM16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200210 shadow_frame.SetVReg(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200211 shadow_frame.GetVReg(inst->VRegB_22x()));
212 ADVANCE(2);
213 HANDLE_INSTRUCTION_END();
214
215 HANDLE_INSTRUCTION_START(MOVE_16)
216 shadow_frame.SetVReg(inst->VRegA_32x(),
217 shadow_frame.GetVReg(inst->VRegB_32x()));
218 ADVANCE(3);
219 HANDLE_INSTRUCTION_END();
220
221 HANDLE_INSTRUCTION_START(MOVE_WIDE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200222 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
223 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200224 ADVANCE(1);
225 HANDLE_INSTRUCTION_END();
226
227 HANDLE_INSTRUCTION_START(MOVE_WIDE_FROM16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200228 shadow_frame.SetVRegLong(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200229 shadow_frame.GetVRegLong(inst->VRegB_22x()));
230 ADVANCE(2);
231 HANDLE_INSTRUCTION_END();
232
233 HANDLE_INSTRUCTION_START(MOVE_WIDE_16)
234 shadow_frame.SetVRegLong(inst->VRegA_32x(),
235 shadow_frame.GetVRegLong(inst->VRegB_32x()));
236 ADVANCE(3);
237 HANDLE_INSTRUCTION_END();
238
239 HANDLE_INSTRUCTION_START(MOVE_OBJECT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200240 shadow_frame.SetVRegReference(inst->VRegA_12x(inst_data),
241 shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200242 ADVANCE(1);
243 HANDLE_INSTRUCTION_END();
244
245 HANDLE_INSTRUCTION_START(MOVE_OBJECT_FROM16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200246 shadow_frame.SetVRegReference(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200247 shadow_frame.GetVRegReference(inst->VRegB_22x()));
248 ADVANCE(2);
249 HANDLE_INSTRUCTION_END();
250
251 HANDLE_INSTRUCTION_START(MOVE_OBJECT_16)
252 shadow_frame.SetVRegReference(inst->VRegA_32x(),
253 shadow_frame.GetVRegReference(inst->VRegB_32x()));
254 ADVANCE(3);
255 HANDLE_INSTRUCTION_END();
256
257 HANDLE_INSTRUCTION_START(MOVE_RESULT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200258 shadow_frame.SetVReg(inst->VRegA_11x(inst_data), result_register.GetI());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200259 ADVANCE(1);
260 HANDLE_INSTRUCTION_END();
261
262 HANDLE_INSTRUCTION_START(MOVE_RESULT_WIDE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200263 shadow_frame.SetVRegLong(inst->VRegA_11x(inst_data), result_register.GetJ());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200264 ADVANCE(1);
265 HANDLE_INSTRUCTION_END();
266
267 HANDLE_INSTRUCTION_START(MOVE_RESULT_OBJECT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200268 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), result_register.GetL());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200269 ADVANCE(1);
270 HANDLE_INSTRUCTION_END();
271
272 HANDLE_INSTRUCTION_START(MOVE_EXCEPTION) {
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000273 Throwable* exception = self->GetException();
Sebastien Hertz270a0e12015-01-16 19:49:09 +0100274 DCHECK(exception != nullptr) << "No pending exception on MOVE_EXCEPTION instruction";
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200275 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), exception);
Sebastien Hertz5c004902014-05-21 10:07:42 +0200276 self->ClearException();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200277 ADVANCE(1);
278 }
279 HANDLE_INSTRUCTION_END();
280
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700281 HANDLE_INSTRUCTION_START(RETURN_VOID_NO_BARRIER) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200282 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700283 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700284 HANDLE_MONITOR_CHECKS();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200285 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200286 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200287 shadow_frame.GetMethod(), dex_pc,
288 result);
289 }
290 return result;
291 }
292 HANDLE_INSTRUCTION_END();
293
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700294 HANDLE_INSTRUCTION_START(RETURN_VOID) {
Hans Boehm30359612014-05-21 17:46:23 -0700295 QuasiAtomic::ThreadFenceForConstructor();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200296 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700297 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700298 HANDLE_MONITOR_CHECKS();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200299 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200300 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200301 shadow_frame.GetMethod(), dex_pc,
302 result);
303 }
304 return result;
305 }
306 HANDLE_INSTRUCTION_END();
307
308 HANDLE_INSTRUCTION_START(RETURN) {
309 JValue result;
310 result.SetJ(0);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200311 result.SetI(shadow_frame.GetVReg(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700312 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700313 HANDLE_MONITOR_CHECKS();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200314 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200315 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200316 shadow_frame.GetMethod(), dex_pc,
317 result);
318 }
319 return result;
320 }
321 HANDLE_INSTRUCTION_END();
322
323 HANDLE_INSTRUCTION_START(RETURN_WIDE) {
324 JValue result;
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200325 result.SetJ(shadow_frame.GetVRegLong(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700326 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700327 HANDLE_MONITOR_CHECKS();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200328 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200329 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200330 shadow_frame.GetMethod(), dex_pc,
331 result);
332 }
333 return result;
334 }
335 HANDLE_INSTRUCTION_END();
336
337 HANDLE_INSTRUCTION_START(RETURN_OBJECT) {
338 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700339 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700340 HANDLE_MONITOR_CHECKS();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700341 const uint8_t vreg_index = inst->VRegA_11x(inst_data);
342 Object* obj_result = shadow_frame.GetVRegReference(vreg_index);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700343 if (do_assignability_check && obj_result != nullptr) {
Vladimir Marko05792b92015-08-03 11:56:49 +0100344 size_t pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
345 Class* return_type = shadow_frame.GetMethod()->GetReturnType(true /* resolve */,
346 pointer_size);
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700347 obj_result = shadow_frame.GetVRegReference(vreg_index);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700348 if (return_type == nullptr) {
Jeff Haoa3faaf42013-09-03 19:07:00 -0700349 // Return the pending exception.
350 HANDLE_PENDING_EXCEPTION();
351 }
352 if (!obj_result->VerifierInstanceOf(return_type)) {
353 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700354 std::string temp1, temp2;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000355 self->ThrowNewExceptionF("Ljava/lang/VirtualMachineError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700356 "Returning '%s' that is not instance of return type '%s'",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700357 obj_result->GetClass()->GetDescriptor(&temp1),
358 return_type->GetDescriptor(&temp2));
Jeff Haoa3faaf42013-09-03 19:07:00 -0700359 HANDLE_PENDING_EXCEPTION();
360 }
361 }
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700362 result.SetL(obj_result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200363 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200364 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200365 shadow_frame.GetMethod(), dex_pc,
366 result);
367 }
368 return result;
369 }
370 HANDLE_INSTRUCTION_END();
371
372 HANDLE_INSTRUCTION_START(CONST_4) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200373 uint32_t dst = inst->VRegA_11n(inst_data);
374 int32_t val = inst->VRegB_11n(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200375 shadow_frame.SetVReg(dst, val);
376 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700377 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200378 }
379 ADVANCE(1);
380 }
381 HANDLE_INSTRUCTION_END();
382
383 HANDLE_INSTRUCTION_START(CONST_16) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200384 uint32_t dst = inst->VRegA_21s(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200385 int32_t val = inst->VRegB_21s();
386 shadow_frame.SetVReg(dst, val);
387 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700388 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200389 }
390 ADVANCE(2);
391 }
392 HANDLE_INSTRUCTION_END();
393
394 HANDLE_INSTRUCTION_START(CONST) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200395 uint32_t dst = inst->VRegA_31i(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200396 int32_t val = inst->VRegB_31i();
397 shadow_frame.SetVReg(dst, val);
398 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700399 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200400 }
401 ADVANCE(3);
402 }
403 HANDLE_INSTRUCTION_END();
404
405 HANDLE_INSTRUCTION_START(CONST_HIGH16) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200406 uint32_t dst = inst->VRegA_21h(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200407 int32_t val = static_cast<int32_t>(inst->VRegB_21h() << 16);
408 shadow_frame.SetVReg(dst, val);
409 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700410 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200411 }
412 ADVANCE(2);
413 }
414 HANDLE_INSTRUCTION_END();
415
416 HANDLE_INSTRUCTION_START(CONST_WIDE_16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200417 shadow_frame.SetVRegLong(inst->VRegA_21s(inst_data), inst->VRegB_21s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200418 ADVANCE(2);
419 HANDLE_INSTRUCTION_END();
420
421 HANDLE_INSTRUCTION_START(CONST_WIDE_32)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200422 shadow_frame.SetVRegLong(inst->VRegA_31i(inst_data), inst->VRegB_31i());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200423 ADVANCE(3);
424 HANDLE_INSTRUCTION_END();
425
426 HANDLE_INSTRUCTION_START(CONST_WIDE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200427 shadow_frame.SetVRegLong(inst->VRegA_51l(inst_data), inst->VRegB_51l());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200428 ADVANCE(5);
429 HANDLE_INSTRUCTION_END();
430
431 HANDLE_INSTRUCTION_START(CONST_WIDE_HIGH16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200432 shadow_frame.SetVRegLong(inst->VRegA_21h(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200433 static_cast<uint64_t>(inst->VRegB_21h()) << 48);
434 ADVANCE(2);
435 HANDLE_INSTRUCTION_END();
436
437 HANDLE_INSTRUCTION_START(CONST_STRING) {
Ian Rogers6786a582014-10-28 12:49:06 -0700438 String* s = ResolveString(self, shadow_frame, inst->VRegB_21c());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700439 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200440 HANDLE_PENDING_EXCEPTION();
441 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200442 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200443 ADVANCE(2);
444 }
445 }
446 HANDLE_INSTRUCTION_END();
447
448 HANDLE_INSTRUCTION_START(CONST_STRING_JUMBO) {
Ian Rogers6786a582014-10-28 12:49:06 -0700449 String* s = ResolveString(self, shadow_frame, inst->VRegB_31c());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700450 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200451 HANDLE_PENDING_EXCEPTION();
452 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200453 shadow_frame.SetVRegReference(inst->VRegA_31c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200454 ADVANCE(3);
455 }
456 }
457 HANDLE_INSTRUCTION_END();
458
459 HANDLE_INSTRUCTION_START(CONST_CLASS) {
460 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
461 self, false, do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700462 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200463 HANDLE_PENDING_EXCEPTION();
464 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200465 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), c);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200466 ADVANCE(2);
467 }
468 }
469 HANDLE_INSTRUCTION_END();
470
471 HANDLE_INSTRUCTION_START(MONITOR_ENTER) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200472 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700473 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000474 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200475 HANDLE_PENDING_EXCEPTION();
476 } else {
Andreas Gampe03ec9302015-08-27 17:41:47 -0700477 DoMonitorEnter<do_access_check>(self, &shadow_frame, obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200478 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), 1);
479 }
480 }
481 HANDLE_INSTRUCTION_END();
482
483 HANDLE_INSTRUCTION_START(MONITOR_EXIT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200484 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700485 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000486 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200487 HANDLE_PENDING_EXCEPTION();
488 } else {
Andreas Gampe03ec9302015-08-27 17:41:47 -0700489 DoMonitorExit<do_access_check>(self, &shadow_frame, obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200490 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), 1);
491 }
492 }
493 HANDLE_INSTRUCTION_END();
494
495 HANDLE_INSTRUCTION_START(CHECK_CAST) {
496 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
497 self, false, do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700498 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200499 HANDLE_PENDING_EXCEPTION();
500 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200501 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_21c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700502 if (UNLIKELY(obj != nullptr && !obj->InstanceOf(c))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200503 ThrowClassCastException(c, obj->GetClass());
504 HANDLE_PENDING_EXCEPTION();
505 } else {
506 ADVANCE(2);
507 }
508 }
509 }
510 HANDLE_INSTRUCTION_END();
511
512 HANDLE_INSTRUCTION_START(INSTANCE_OF) {
513 Class* c = ResolveVerifyAndClinit(inst->VRegC_22c(), shadow_frame.GetMethod(),
514 self, false, do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700515 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200516 HANDLE_PENDING_EXCEPTION();
517 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200518 Object* obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700519 shadow_frame.SetVReg(inst->VRegA_22c(inst_data), (obj != nullptr && obj->InstanceOf(c)) ? 1 : 0);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200520 ADVANCE(2);
521 }
522 }
523 HANDLE_INSTRUCTION_END();
524
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700525 HANDLE_INSTRUCTION_START(ARRAY_LENGTH) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200526 Object* array = shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700527 if (UNLIKELY(array == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000528 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200529 HANDLE_PENDING_EXCEPTION();
530 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200531 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), array->AsArray()->GetLength());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200532 ADVANCE(1);
533 }
534 }
535 HANDLE_INSTRUCTION_END();
536
537 HANDLE_INSTRUCTION_START(NEW_INSTANCE) {
Jeff Hao848f70a2014-01-15 13:49:50 -0800538 Object* obj = nullptr;
539 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
540 self, false, do_access_check);
541 if (LIKELY(c != nullptr)) {
542 if (UNLIKELY(c->IsStringClass())) {
543 gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
jessicahandojo3aaa37b2016-07-29 14:46:37 -0700544 obj = mirror::String::AllocEmptyString<true>(self, allocator_type);
Jeff Hao848f70a2014-01-15 13:49:50 -0800545 } else {
546 obj = AllocObjectFromCode<do_access_check, true>(
547 inst->VRegB_21c(), shadow_frame.GetMethod(), self,
548 Runtime::Current()->GetHeap()->GetCurrentAllocator());
549 }
550 }
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700551 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200552 HANDLE_PENDING_EXCEPTION();
553 } else {
Sebastien Hertz4e99b3d2014-06-24 14:35:40 +0200554 obj->GetClass()->AssertInitializedOrInitializingInThread(self);
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700555 // Don't allow finalizable objects to be allocated during a transaction since these can't be
556 // finalized without a started runtime.
557 if (transaction_active && obj->GetClass()->IsFinalizable()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +0200558 AbortTransactionF(self, "Allocating finalizable object in transaction: %s",
559 PrettyTypeOf(obj).c_str());
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700560 HANDLE_PENDING_EXCEPTION();
561 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200562 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200563 ADVANCE(2);
564 }
565 }
566 HANDLE_INSTRUCTION_END();
567
568 HANDLE_INSTRUCTION_START(NEW_ARRAY) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200569 int32_t length = shadow_frame.GetVReg(inst->VRegB_22c(inst_data));
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800570 Object* obj = AllocArrayFromCode<do_access_check, true>(
Andreas Gampe1cc7dba2014-12-17 18:43:01 -0800571 inst->VRegC_22c(), length, shadow_frame.GetMethod(), self,
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800572 Runtime::Current()->GetHeap()->GetCurrentAllocator());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700573 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200574 HANDLE_PENDING_EXCEPTION();
575 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200576 shadow_frame.SetVRegReference(inst->VRegA_22c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200577 ADVANCE(2);
578 }
579 }
580 HANDLE_INSTRUCTION_END();
581
582 HANDLE_INSTRUCTION_START(FILLED_NEW_ARRAY) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100583 bool success =
584 DoFilledNewArray<false, do_access_check, transaction_active>(inst, shadow_frame,
585 self, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200586 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
587 }
588 HANDLE_INSTRUCTION_END();
589
590 HANDLE_INSTRUCTION_START(FILLED_NEW_ARRAY_RANGE) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100591 bool success =
592 DoFilledNewArray<true, do_access_check, transaction_active>(inst, shadow_frame,
593 self, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200594 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
595 }
596 HANDLE_INSTRUCTION_END();
597
598 HANDLE_INSTRUCTION_START(FILL_ARRAY_DATA) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200599 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_31t(inst_data));
Ian Rogers832336b2014-10-08 15:35:22 -0700600 const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t();
601 const Instruction::ArrayDataPayload* payload =
602 reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr);
603 bool success = FillArrayData(obj, payload);
604 if (transaction_active && success) {
605 RecordArrayElementsInTransaction(obj->AsArray(), payload->element_count);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200606 }
Ian Rogers832336b2014-10-08 15:35:22 -0700607 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200608 }
609 HANDLE_INSTRUCTION_END();
610
611 HANDLE_INSTRUCTION_START(THROW) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200612 Object* exception = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700613 if (UNLIKELY(exception == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000614 ThrowNullPointerException("throw with null exception");
Jeff Haoa3faaf42013-09-03 19:07:00 -0700615 } else if (do_assignability_check && !exception->GetClass()->IsThrowableClass()) {
616 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700617 std::string temp;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000618 self->ThrowNewExceptionF("Ljava/lang/VirtualMachineError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700619 "Throwing '%s' that is not instance of Throwable",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700620 exception->GetClass()->GetDescriptor(&temp));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200621 } else {
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000622 self->SetException(exception->AsThrowable());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200623 }
624 HANDLE_PENDING_EXCEPTION();
625 }
626 HANDLE_INSTRUCTION_END();
627
628 HANDLE_INSTRUCTION_START(GOTO) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200629 int8_t offset = inst->VRegA_10t(inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000630 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200631 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000632 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200633 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700634 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200635 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200636 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200637 }
638 ADVANCE(offset);
639 }
640 HANDLE_INSTRUCTION_END();
641
642 HANDLE_INSTRUCTION_START(GOTO_16) {
643 int16_t offset = inst->VRegA_20t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000644 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200645 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000646 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200647 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700648 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200649 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200650 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200651 }
652 ADVANCE(offset);
653 }
654 HANDLE_INSTRUCTION_END();
655
656 HANDLE_INSTRUCTION_START(GOTO_32) {
657 int32_t offset = inst->VRegA_30t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000658 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200659 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000660 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200661 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700662 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200663 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200664 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200665 }
666 ADVANCE(offset);
667 }
668 HANDLE_INSTRUCTION_END();
669
670 HANDLE_INSTRUCTION_START(PACKED_SWITCH) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200671 int32_t offset = DoPackedSwitch(inst, shadow_frame, inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000672 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200673 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000674 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200675 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700676 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200677 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200678 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200679 }
680 ADVANCE(offset);
681 }
682 HANDLE_INSTRUCTION_END();
683
684 HANDLE_INSTRUCTION_START(SPARSE_SWITCH) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200685 int32_t offset = DoSparseSwitch(inst, shadow_frame, inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000686 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200687 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000688 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200689 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700690 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200691 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200692 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200693 }
694 ADVANCE(offset);
695 }
696 HANDLE_INSTRUCTION_END();
697
Ian Rogers647b1a82014-10-10 11:02:11 -0700698#if defined(__clang__)
699#pragma clang diagnostic push
700#pragma clang diagnostic ignored "-Wfloat-equal"
701#endif
702
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200703 HANDLE_INSTRUCTION_START(CMPL_FLOAT) {
704 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
705 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
706 int32_t result;
707 if (val1 > val2) {
708 result = 1;
709 } else if (val1 == val2) {
710 result = 0;
711 } else {
712 result = -1;
713 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200714 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200715 ADVANCE(2);
716 }
717 HANDLE_INSTRUCTION_END();
718
719 HANDLE_INSTRUCTION_START(CMPG_FLOAT) {
720 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
721 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
722 int32_t result;
723 if (val1 < val2) {
724 result = -1;
725 } else if (val1 == val2) {
726 result = 0;
727 } else {
728 result = 1;
729 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200730 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200731 ADVANCE(2);
732 }
733 HANDLE_INSTRUCTION_END();
734
735 HANDLE_INSTRUCTION_START(CMPL_DOUBLE) {
736 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
737 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
738 int32_t result;
739 if (val1 > val2) {
740 result = 1;
741 } else if (val1 == val2) {
742 result = 0;
743 } else {
744 result = -1;
745 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200746 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200747 ADVANCE(2);
748 }
749 HANDLE_INSTRUCTION_END();
750
751 HANDLE_INSTRUCTION_START(CMPG_DOUBLE) {
752 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
753 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
754 int32_t result;
755 if (val1 < val2) {
756 result = -1;
757 } else if (val1 == val2) {
758 result = 0;
759 } else {
760 result = 1;
761 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200762 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200763 ADVANCE(2);
764 }
765 HANDLE_INSTRUCTION_END();
766
Ian Rogers647b1a82014-10-10 11:02:11 -0700767#if defined(__clang__)
768#pragma clang diagnostic pop
769#endif
770
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200771 HANDLE_INSTRUCTION_START(CMP_LONG) {
772 int64_t val1 = shadow_frame.GetVRegLong(inst->VRegB_23x());
773 int64_t val2 = shadow_frame.GetVRegLong(inst->VRegC_23x());
774 int32_t result;
775 if (val1 > val2) {
776 result = 1;
777 } else if (val1 == val2) {
778 result = 0;
779 } else {
780 result = -1;
781 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200782 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200783 ADVANCE(2);
784 }
785 HANDLE_INSTRUCTION_END();
786
787 HANDLE_INSTRUCTION_START(IF_EQ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200788 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) == shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200789 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000790 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200791 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000792 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200793 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700794 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200795 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200796 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200797 }
798 ADVANCE(offset);
799 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800800 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200801 ADVANCE(2);
802 }
803 }
804 HANDLE_INSTRUCTION_END();
805
806 HANDLE_INSTRUCTION_START(IF_NE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700807 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) !=
808 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200809 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000810 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200811 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000812 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200813 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700814 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200815 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200816 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200817 }
818 ADVANCE(offset);
819 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800820 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200821 ADVANCE(2);
822 }
823 }
824 HANDLE_INSTRUCTION_END();
825
826 HANDLE_INSTRUCTION_START(IF_LT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700827 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <
828 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200829 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000830 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200831 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000832 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200833 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700834 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200835 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200836 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200837 }
838 ADVANCE(offset);
839 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800840 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200841 ADVANCE(2);
842 }
843 }
844 HANDLE_INSTRUCTION_END();
845
846 HANDLE_INSTRUCTION_START(IF_GE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700847 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >=
848 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200849 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000850 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200851 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000852 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200853 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700854 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200855 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200856 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200857 }
858 ADVANCE(offset);
859 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800860 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200861 ADVANCE(2);
862 }
863 }
864 HANDLE_INSTRUCTION_END();
865
866 HANDLE_INSTRUCTION_START(IF_GT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700867 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >
868 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200869 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000870 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200871 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000872 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200873 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700874 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200875 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200876 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200877 }
878 ADVANCE(offset);
879 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800880 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200881 ADVANCE(2);
882 }
883 }
884 HANDLE_INSTRUCTION_END();
885
886 HANDLE_INSTRUCTION_START(IF_LE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700887 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <=
888 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200889 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000890 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200891 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000892 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200893 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700894 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200895 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200896 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200897 }
898 ADVANCE(offset);
899 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800900 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200901 ADVANCE(2);
902 }
903 }
904 HANDLE_INSTRUCTION_END();
905
906 HANDLE_INSTRUCTION_START(IF_EQZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200907 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) == 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200908 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000909 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200910 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000911 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200912 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700913 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200914 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200915 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200916 }
917 ADVANCE(offset);
918 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800919 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200920 ADVANCE(2);
921 }
922 }
923 HANDLE_INSTRUCTION_END();
924
925 HANDLE_INSTRUCTION_START(IF_NEZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200926 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) != 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200927 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000928 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200929 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000930 HOTNESS_UPDATE();
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 {
buzbeef1dcacc2016-02-24 14:24:24 -0800938 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200939 ADVANCE(2);
940 }
941 }
942 HANDLE_INSTRUCTION_END();
943
944 HANDLE_INSTRUCTION_START(IF_LTZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200945 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) < 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200946 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000947 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200948 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000949 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200950 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700951 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200952 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200953 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200954 }
955 ADVANCE(offset);
956 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800957 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200958 ADVANCE(2);
959 }
960 }
961 HANDLE_INSTRUCTION_END();
962
963 HANDLE_INSTRUCTION_START(IF_GEZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200964 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) >= 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200965 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000966 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200967 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000968 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200969 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700970 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200971 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200972 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200973 }
974 ADVANCE(offset);
975 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800976 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200977 ADVANCE(2);
978 }
979 }
980 HANDLE_INSTRUCTION_END();
981
982 HANDLE_INSTRUCTION_START(IF_GTZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200983 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) > 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200984 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000985 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200986 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000987 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200988 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700989 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200990 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200991 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200992 }
993 ADVANCE(offset);
994 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800995 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200996 ADVANCE(2);
997 }
998 }
999 HANDLE_INSTRUCTION_END();
1000
1001 HANDLE_INSTRUCTION_START(IF_LEZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001002 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) <= 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001003 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +00001004 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001005 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +00001006 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001007 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -07001008 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +02001009 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001010 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001011 }
1012 ADVANCE(offset);
1013 } else {
buzbeef1dcacc2016-02-24 14:24:24 -08001014 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001015 ADVANCE(2);
1016 }
1017 }
1018 HANDLE_INSTRUCTION_END();
1019
1020 HANDLE_INSTRUCTION_START(AGET_BOOLEAN) {
1021 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001022 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001023 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001024 HANDLE_PENDING_EXCEPTION();
1025 } else {
1026 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1027 BooleanArray* array = a->AsBooleanArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001028 if (LIKELY(array->CheckIsValidIndex(index))) {
1029 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001030 ADVANCE(2);
1031 } else {
1032 HANDLE_PENDING_EXCEPTION();
1033 }
1034 }
1035 }
1036 HANDLE_INSTRUCTION_END();
1037
1038 HANDLE_INSTRUCTION_START(AGET_BYTE) {
1039 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001040 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001041 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001042 HANDLE_PENDING_EXCEPTION();
1043 } else {
1044 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1045 ByteArray* array = a->AsByteArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001046 if (LIKELY(array->CheckIsValidIndex(index))) {
1047 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001048 ADVANCE(2);
1049 } else {
1050 HANDLE_PENDING_EXCEPTION();
1051 }
1052 }
1053 }
1054 HANDLE_INSTRUCTION_END();
1055
1056 HANDLE_INSTRUCTION_START(AGET_CHAR) {
1057 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001058 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001059 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001060 HANDLE_PENDING_EXCEPTION();
1061 } else {
1062 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1063 CharArray* array = a->AsCharArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001064 if (LIKELY(array->CheckIsValidIndex(index))) {
1065 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001066 ADVANCE(2);
1067 } else {
1068 HANDLE_PENDING_EXCEPTION();
1069 }
1070 }
1071 }
1072 HANDLE_INSTRUCTION_END();
1073
1074 HANDLE_INSTRUCTION_START(AGET_SHORT) {
1075 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001076 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001077 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001078 HANDLE_PENDING_EXCEPTION();
1079 } else {
1080 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1081 ShortArray* array = a->AsShortArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001082 if (LIKELY(array->CheckIsValidIndex(index))) {
1083 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001084 ADVANCE(2);
1085 } else {
1086 HANDLE_PENDING_EXCEPTION();
1087 }
1088 }
1089 }
1090 HANDLE_INSTRUCTION_END();
1091
1092 HANDLE_INSTRUCTION_START(AGET) {
1093 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001094 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001095 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001096 HANDLE_PENDING_EXCEPTION();
1097 } else {
1098 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001099 DCHECK(a->IsIntArray() || a->IsFloatArray()) << PrettyTypeOf(a);
1100 auto* array = down_cast<IntArray*>(a);
Sebastien Hertzabff6432014-01-27 18:01:39 +01001101 if (LIKELY(array->CheckIsValidIndex(index))) {
1102 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001103 ADVANCE(2);
1104 } else {
1105 HANDLE_PENDING_EXCEPTION();
1106 }
1107 }
1108 }
1109 HANDLE_INSTRUCTION_END();
1110
1111 HANDLE_INSTRUCTION_START(AGET_WIDE) {
1112 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001113 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001114 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001115 HANDLE_PENDING_EXCEPTION();
1116 } else {
1117 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001118 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << PrettyTypeOf(a);
1119 auto* array = down_cast<LongArray*>(a);
Sebastien Hertzabff6432014-01-27 18:01:39 +01001120 if (LIKELY(array->CheckIsValidIndex(index))) {
1121 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001122 ADVANCE(2);
1123 } else {
1124 HANDLE_PENDING_EXCEPTION();
1125 }
1126 }
1127 }
1128 HANDLE_INSTRUCTION_END();
1129
1130 HANDLE_INSTRUCTION_START(AGET_OBJECT) {
1131 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001132 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001133 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001134 HANDLE_PENDING_EXCEPTION();
1135 } else {
1136 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1137 ObjectArray<Object>* array = a->AsObjectArray<Object>();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001138 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001139 shadow_frame.SetVRegReference(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001140 ADVANCE(2);
1141 } else {
1142 HANDLE_PENDING_EXCEPTION();
1143 }
1144 }
1145 }
1146 HANDLE_INSTRUCTION_END();
1147
1148 HANDLE_INSTRUCTION_START(APUT_BOOLEAN) {
1149 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001150 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001151 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001152 HANDLE_PENDING_EXCEPTION();
1153 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001154 uint8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001155 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1156 BooleanArray* array = a->AsBooleanArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001157 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001158 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001159 ADVANCE(2);
1160 } else {
1161 HANDLE_PENDING_EXCEPTION();
1162 }
1163 }
1164 }
1165 HANDLE_INSTRUCTION_END();
1166
1167 HANDLE_INSTRUCTION_START(APUT_BYTE) {
1168 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001169 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001170 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001171 HANDLE_PENDING_EXCEPTION();
1172 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001173 int8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001174 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1175 ByteArray* array = a->AsByteArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001176 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001177 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001178 ADVANCE(2);
1179 } else {
1180 HANDLE_PENDING_EXCEPTION();
1181 }
1182 }
1183 }
1184 HANDLE_INSTRUCTION_END();
1185
1186 HANDLE_INSTRUCTION_START(APUT_CHAR) {
1187 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001188 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001189 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001190 HANDLE_PENDING_EXCEPTION();
1191 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001192 uint16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001193 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1194 CharArray* array = a->AsCharArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001195 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001196 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001197 ADVANCE(2);
1198 } else {
1199 HANDLE_PENDING_EXCEPTION();
1200 }
1201 }
1202 }
1203 HANDLE_INSTRUCTION_END();
1204
1205 HANDLE_INSTRUCTION_START(APUT_SHORT) {
1206 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001207 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001208 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001209 HANDLE_PENDING_EXCEPTION();
1210 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001211 int16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001212 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1213 ShortArray* array = a->AsShortArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001214 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001215 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001216 ADVANCE(2);
1217 } else {
1218 HANDLE_PENDING_EXCEPTION();
1219 }
1220 }
1221 }
1222 HANDLE_INSTRUCTION_END();
1223
1224 HANDLE_INSTRUCTION_START(APUT) {
1225 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001226 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001227 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001228 HANDLE_PENDING_EXCEPTION();
1229 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001230 int32_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001231 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001232 DCHECK(a->IsIntArray() || a->IsFloatArray()) << PrettyTypeOf(a);
1233 auto* array = down_cast<IntArray*>(a);
Sebastien Hertzabff6432014-01-27 18:01:39 +01001234 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001235 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001236 ADVANCE(2);
1237 } else {
1238 HANDLE_PENDING_EXCEPTION();
1239 }
1240 }
1241 }
1242 HANDLE_INSTRUCTION_END();
1243
1244 HANDLE_INSTRUCTION_START(APUT_WIDE) {
1245 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001246 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001247 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001248 HANDLE_PENDING_EXCEPTION();
1249 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001250 int64_t val = shadow_frame.GetVRegLong(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001251 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001252 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << PrettyTypeOf(a);
1253 auto* array = down_cast<LongArray*>(a);
Sebastien Hertzabff6432014-01-27 18:01:39 +01001254 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001255 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001256 ADVANCE(2);
1257 } else {
1258 HANDLE_PENDING_EXCEPTION();
1259 }
1260 }
1261 }
1262 HANDLE_INSTRUCTION_END();
1263
1264 HANDLE_INSTRUCTION_START(APUT_OBJECT) {
1265 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001266 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001267 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001268 HANDLE_PENDING_EXCEPTION();
1269 } else {
1270 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001271 Object* val = shadow_frame.GetVRegReference(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001272 ObjectArray<Object>* array = a->AsObjectArray<Object>();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001273 if (LIKELY(array->CheckIsValidIndex(index) && array->CheckAssignable(val))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001274 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001275 ADVANCE(2);
1276 } else {
1277 HANDLE_PENDING_EXCEPTION();
1278 }
1279 }
1280 }
1281 HANDLE_INSTRUCTION_END();
1282
1283 HANDLE_INSTRUCTION_START(IGET_BOOLEAN) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001284 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimBoolean, do_access_check>(
1285 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001286 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1287 }
1288 HANDLE_INSTRUCTION_END();
1289
1290 HANDLE_INSTRUCTION_START(IGET_BYTE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001291 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimByte, do_access_check>(
1292 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001293 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1294 }
1295 HANDLE_INSTRUCTION_END();
1296
1297 HANDLE_INSTRUCTION_START(IGET_CHAR) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001298 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimChar, do_access_check>(
1299 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001300 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1301 }
1302 HANDLE_INSTRUCTION_END();
1303
1304 HANDLE_INSTRUCTION_START(IGET_SHORT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001305 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimShort, do_access_check>(
1306 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001307 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1308 }
1309 HANDLE_INSTRUCTION_END();
1310
1311 HANDLE_INSTRUCTION_START(IGET) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001312 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimInt, do_access_check>(
1313 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001314 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1315 }
1316 HANDLE_INSTRUCTION_END();
1317
1318 HANDLE_INSTRUCTION_START(IGET_WIDE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001319 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimLong, do_access_check>(
1320 self, 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) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001326 bool success = DoFieldGet<InstanceObjectRead, Primitive::kPrimNot, do_access_check>(
1327 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001328 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1329 }
1330 HANDLE_INSTRUCTION_END();
1331
1332 HANDLE_INSTRUCTION_START(IGET_QUICK) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001333 bool success = DoIGetQuick<Primitive::kPrimInt>(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
Mathieu Chartierffc605c2014-12-10 10:35:44 -08001338 HANDLE_INSTRUCTION_START(IGET_BOOLEAN_QUICK) {
1339 bool success = DoIGetQuick<Primitive::kPrimBoolean>(shadow_frame, inst, inst_data);
1340 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1341 }
1342 HANDLE_INSTRUCTION_END();
1343
1344 HANDLE_INSTRUCTION_START(IGET_BYTE_QUICK) {
1345 bool success = DoIGetQuick<Primitive::kPrimByte>(shadow_frame, inst, inst_data);
1346 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1347 }
1348 HANDLE_INSTRUCTION_END();
1349
1350 HANDLE_INSTRUCTION_START(IGET_CHAR_QUICK) {
1351 bool success = DoIGetQuick<Primitive::kPrimChar>(shadow_frame, inst, inst_data);
1352 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1353 }
1354 HANDLE_INSTRUCTION_END();
1355
1356 HANDLE_INSTRUCTION_START(IGET_SHORT_QUICK) {
1357 bool success = DoIGetQuick<Primitive::kPrimShort>(shadow_frame, inst, inst_data);
1358 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1359 }
1360 HANDLE_INSTRUCTION_END();
1361
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001362 HANDLE_INSTRUCTION_START(IGET_WIDE_QUICK) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001363 bool success = DoIGetQuick<Primitive::kPrimLong>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001364 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1365 }
1366 HANDLE_INSTRUCTION_END();
1367
1368 HANDLE_INSTRUCTION_START(IGET_OBJECT_QUICK) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001369 bool success = DoIGetQuick<Primitive::kPrimNot>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001370 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1371 }
1372 HANDLE_INSTRUCTION_END();
1373
1374 HANDLE_INSTRUCTION_START(SGET_BOOLEAN) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001375 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimBoolean, do_access_check>(
1376 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001377 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1378 }
1379 HANDLE_INSTRUCTION_END();
1380
1381 HANDLE_INSTRUCTION_START(SGET_BYTE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001382 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimByte, do_access_check>(
1383 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001384 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1385 }
1386 HANDLE_INSTRUCTION_END();
1387
1388 HANDLE_INSTRUCTION_START(SGET_CHAR) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001389 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimChar, do_access_check>(
1390 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001391 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1392 }
1393 HANDLE_INSTRUCTION_END();
1394
1395 HANDLE_INSTRUCTION_START(SGET_SHORT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001396 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimShort, do_access_check>(
1397 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001398 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1399 }
1400 HANDLE_INSTRUCTION_END();
1401
1402 HANDLE_INSTRUCTION_START(SGET) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001403 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimInt, do_access_check>(
1404 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001405 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1406 }
1407 HANDLE_INSTRUCTION_END();
1408
1409 HANDLE_INSTRUCTION_START(SGET_WIDE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001410 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimLong, do_access_check>(
1411 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001412 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1413 }
1414 HANDLE_INSTRUCTION_END();
1415
1416 HANDLE_INSTRUCTION_START(SGET_OBJECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001417 bool success = DoFieldGet<StaticObjectRead, Primitive::kPrimNot, do_access_check>(
1418 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001419 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1420 }
1421 HANDLE_INSTRUCTION_END();
1422
1423 HANDLE_INSTRUCTION_START(IPUT_BOOLEAN) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001424 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1425 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001426 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1427 }
1428 HANDLE_INSTRUCTION_END();
1429
1430 HANDLE_INSTRUCTION_START(IPUT_BYTE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001431 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimByte, do_access_check,
1432 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001433 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1434 }
1435 HANDLE_INSTRUCTION_END();
1436
1437 HANDLE_INSTRUCTION_START(IPUT_CHAR) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001438 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimChar, do_access_check,
1439 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001440 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1441 }
1442 HANDLE_INSTRUCTION_END();
1443
1444 HANDLE_INSTRUCTION_START(IPUT_SHORT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001445 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimShort, do_access_check,
1446 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001447 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1448 }
1449 HANDLE_INSTRUCTION_END();
1450
1451 HANDLE_INSTRUCTION_START(IPUT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001452 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimInt, do_access_check,
1453 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001454 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1455 }
1456 HANDLE_INSTRUCTION_END();
1457
1458 HANDLE_INSTRUCTION_START(IPUT_WIDE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001459 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimLong, do_access_check,
1460 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001461 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1462 }
1463 HANDLE_INSTRUCTION_END();
1464
1465 HANDLE_INSTRUCTION_START(IPUT_OBJECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001466 bool success = DoFieldPut<InstanceObjectWrite, Primitive::kPrimNot, do_access_check,
1467 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001468 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1469 }
1470 HANDLE_INSTRUCTION_END();
1471
1472 HANDLE_INSTRUCTION_START(IPUT_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001473 bool success = DoIPutQuick<Primitive::kPrimInt, transaction_active>(
1474 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001475 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1476 }
1477 HANDLE_INSTRUCTION_END();
1478
Fred Shih37f05ef2014-07-16 18:38:08 -07001479 HANDLE_INSTRUCTION_START(IPUT_BOOLEAN_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001480 bool success = DoIPutQuick<Primitive::kPrimBoolean, transaction_active>(
1481 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001482 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1483 }
1484 HANDLE_INSTRUCTION_END();
1485
1486 HANDLE_INSTRUCTION_START(IPUT_BYTE_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001487 bool success = DoIPutQuick<Primitive::kPrimByte, transaction_active>(
1488 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001489 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1490 }
1491 HANDLE_INSTRUCTION_END();
1492
1493 HANDLE_INSTRUCTION_START(IPUT_CHAR_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001494 bool success = DoIPutQuick<Primitive::kPrimChar, transaction_active>(
1495 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001496 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1497 }
1498 HANDLE_INSTRUCTION_END();
1499
1500 HANDLE_INSTRUCTION_START(IPUT_SHORT_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001501 bool success = DoIPutQuick<Primitive::kPrimShort, transaction_active>(
1502 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001503 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1504 }
1505 HANDLE_INSTRUCTION_END();
1506
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001507 HANDLE_INSTRUCTION_START(IPUT_WIDE_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001508 bool success = DoIPutQuick<Primitive::kPrimLong, transaction_active>(
1509 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001510 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1511 }
1512 HANDLE_INSTRUCTION_END();
1513
1514 HANDLE_INSTRUCTION_START(IPUT_OBJECT_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001515 bool success = DoIPutQuick<Primitive::kPrimNot, transaction_active>(
1516 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001517 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1518 }
1519 HANDLE_INSTRUCTION_END();
1520
1521 HANDLE_INSTRUCTION_START(SPUT_BOOLEAN) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001522 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1523 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001524 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1525 }
1526 HANDLE_INSTRUCTION_END();
1527
1528 HANDLE_INSTRUCTION_START(SPUT_BYTE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001529 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimByte, do_access_check,
1530 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001531 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1532 }
1533 HANDLE_INSTRUCTION_END();
1534
1535 HANDLE_INSTRUCTION_START(SPUT_CHAR) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001536 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimChar, do_access_check,
1537 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001538 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1539 }
1540 HANDLE_INSTRUCTION_END();
1541
1542 HANDLE_INSTRUCTION_START(SPUT_SHORT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001543 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimShort, do_access_check,
1544 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001545 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1546 }
1547 HANDLE_INSTRUCTION_END();
1548
1549 HANDLE_INSTRUCTION_START(SPUT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001550 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimInt, do_access_check,
1551 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001552 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1553 }
1554 HANDLE_INSTRUCTION_END();
1555
1556 HANDLE_INSTRUCTION_START(SPUT_WIDE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001557 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimLong, do_access_check,
1558 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001559 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1560 }
1561 HANDLE_INSTRUCTION_END();
1562
1563 HANDLE_INSTRUCTION_START(SPUT_OBJECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001564 bool success = DoFieldPut<StaticObjectWrite, Primitive::kPrimNot, do_access_check,
1565 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001566 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1567 }
1568 HANDLE_INSTRUCTION_END();
1569
1570 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001571 bool success = DoInvoke<kVirtual, false, do_access_check>(
1572 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001573 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001574 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1575 }
1576 HANDLE_INSTRUCTION_END();
1577
1578 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001579 bool success = DoInvoke<kVirtual, true, do_access_check>(
1580 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001581 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001582 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1583 }
1584 HANDLE_INSTRUCTION_END();
1585
1586 HANDLE_INSTRUCTION_START(INVOKE_SUPER) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001587 bool success = DoInvoke<kSuper, false, do_access_check>(
1588 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001589 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001590 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1591 }
1592 HANDLE_INSTRUCTION_END();
1593
1594 HANDLE_INSTRUCTION_START(INVOKE_SUPER_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001595 bool success = DoInvoke<kSuper, true, do_access_check>(
1596 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001597 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001598 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1599 }
1600 HANDLE_INSTRUCTION_END();
1601
1602 HANDLE_INSTRUCTION_START(INVOKE_DIRECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001603 bool success = DoInvoke<kDirect, false, do_access_check>(
1604 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001605 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001606 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1607 }
1608 HANDLE_INSTRUCTION_END();
1609
1610 HANDLE_INSTRUCTION_START(INVOKE_DIRECT_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001611 bool success = DoInvoke<kDirect, true, do_access_check>(
1612 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001613 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001614 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1615 }
1616 HANDLE_INSTRUCTION_END();
1617
1618 HANDLE_INSTRUCTION_START(INVOKE_INTERFACE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001619 bool success = DoInvoke<kInterface, false, do_access_check>(
1620 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001621 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001622 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1623 }
1624 HANDLE_INSTRUCTION_END();
1625
1626 HANDLE_INSTRUCTION_START(INVOKE_INTERFACE_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001627 bool success = DoInvoke<kInterface, true, do_access_check>(
1628 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001629 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001630 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1631 }
1632 HANDLE_INSTRUCTION_END();
1633
1634 HANDLE_INSTRUCTION_START(INVOKE_STATIC) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001635 bool success = DoInvoke<kStatic, false, do_access_check>(
1636 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001637 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001638 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1639 }
1640 HANDLE_INSTRUCTION_END();
1641
1642 HANDLE_INSTRUCTION_START(INVOKE_STATIC_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001643 bool success = DoInvoke<kStatic, true, do_access_check>(
1644 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001645 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001646 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1647 }
1648 HANDLE_INSTRUCTION_END();
1649
1650 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001651 bool success = DoInvokeVirtualQuick<false>(
1652 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001653 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001654 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1655 }
1656 HANDLE_INSTRUCTION_END();
1657
1658 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_RANGE_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001659 bool success = DoInvokeVirtualQuick<true>(
1660 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001661 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001662 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1663 }
1664 HANDLE_INSTRUCTION_END();
1665
1666 HANDLE_INSTRUCTION_START(NEG_INT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001667 shadow_frame.SetVReg(
1668 inst->VRegA_12x(inst_data), -shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001669 ADVANCE(1);
1670 HANDLE_INSTRUCTION_END();
1671
1672 HANDLE_INSTRUCTION_START(NOT_INT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001673 shadow_frame.SetVReg(
1674 inst->VRegA_12x(inst_data), ~shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001675 ADVANCE(1);
1676 HANDLE_INSTRUCTION_END();
1677
1678 HANDLE_INSTRUCTION_START(NEG_LONG)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001679 shadow_frame.SetVRegLong(
1680 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001681 ADVANCE(1);
1682 HANDLE_INSTRUCTION_END();
1683
1684 HANDLE_INSTRUCTION_START(NOT_LONG)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001685 shadow_frame.SetVRegLong(
1686 inst->VRegA_12x(inst_data), ~shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001687 ADVANCE(1);
1688 HANDLE_INSTRUCTION_END();
1689
1690 HANDLE_INSTRUCTION_START(NEG_FLOAT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001691 shadow_frame.SetVRegFloat(
1692 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001693 ADVANCE(1);
1694 HANDLE_INSTRUCTION_END();
1695
1696 HANDLE_INSTRUCTION_START(NEG_DOUBLE)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001697 shadow_frame.SetVRegDouble(
1698 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001699 ADVANCE(1);
1700 HANDLE_INSTRUCTION_END();
1701
1702 HANDLE_INSTRUCTION_START(INT_TO_LONG)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001703 shadow_frame.SetVRegLong(
1704 inst->VRegA_12x(inst_data), shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001705 ADVANCE(1);
1706 HANDLE_INSTRUCTION_END();
1707
1708 HANDLE_INSTRUCTION_START(INT_TO_FLOAT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001709 shadow_frame.SetVRegFloat(
1710 inst->VRegA_12x(inst_data), shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001711 ADVANCE(1);
1712 HANDLE_INSTRUCTION_END();
1713
1714 HANDLE_INSTRUCTION_START(INT_TO_DOUBLE)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001715 shadow_frame.SetVRegDouble(
1716 inst->VRegA_12x(inst_data), shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001717 ADVANCE(1);
1718 HANDLE_INSTRUCTION_END();
1719
1720 HANDLE_INSTRUCTION_START(LONG_TO_INT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001721 shadow_frame.SetVReg(
1722 inst->VRegA_12x(inst_data), shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001723 ADVANCE(1);
1724 HANDLE_INSTRUCTION_END();
1725
1726 HANDLE_INSTRUCTION_START(LONG_TO_FLOAT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001727 shadow_frame.SetVRegFloat(
1728 inst->VRegA_12x(inst_data), shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001729 ADVANCE(1);
1730 HANDLE_INSTRUCTION_END();
1731
1732 HANDLE_INSTRUCTION_START(LONG_TO_DOUBLE)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001733 shadow_frame.SetVRegDouble(
1734 inst->VRegA_12x(inst_data), shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001735 ADVANCE(1);
1736 HANDLE_INSTRUCTION_END();
1737
1738 HANDLE_INSTRUCTION_START(FLOAT_TO_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001739 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001740 int32_t result = art_float_to_integral<int32_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001741 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001742 ADVANCE(1);
1743 }
1744 HANDLE_INSTRUCTION_END();
1745
1746 HANDLE_INSTRUCTION_START(FLOAT_TO_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001747 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001748 int64_t result = art_float_to_integral<int64_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001749 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001750 ADVANCE(1);
1751 }
1752 HANDLE_INSTRUCTION_END();
1753
1754 HANDLE_INSTRUCTION_START(FLOAT_TO_DOUBLE)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001755 shadow_frame.SetVRegDouble(
1756 inst->VRegA_12x(inst_data), shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001757 ADVANCE(1);
1758 HANDLE_INSTRUCTION_END();
1759
1760 HANDLE_INSTRUCTION_START(DOUBLE_TO_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001761 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001762 int32_t result = art_float_to_integral<int32_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001763 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001764 ADVANCE(1);
1765 }
1766 HANDLE_INSTRUCTION_END();
1767
1768 HANDLE_INSTRUCTION_START(DOUBLE_TO_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001769 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001770 int64_t result = art_float_to_integral<int64_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001771 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001772 ADVANCE(1);
1773 }
1774 HANDLE_INSTRUCTION_END();
1775
1776 HANDLE_INSTRUCTION_START(DOUBLE_TO_FLOAT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001777 shadow_frame.SetVRegFloat(
1778 inst->VRegA_12x(inst_data), shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001779 ADVANCE(1);
1780 HANDLE_INSTRUCTION_END();
1781
1782 HANDLE_INSTRUCTION_START(INT_TO_BYTE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001783 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1784 static_cast<int8_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001785 ADVANCE(1);
1786 HANDLE_INSTRUCTION_END();
1787
1788 HANDLE_INSTRUCTION_START(INT_TO_CHAR)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001789 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1790 static_cast<uint16_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001791 ADVANCE(1);
1792 HANDLE_INSTRUCTION_END();
1793
1794 HANDLE_INSTRUCTION_START(INT_TO_SHORT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001795 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1796 static_cast<int16_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001797 ADVANCE(1);
1798 HANDLE_INSTRUCTION_END();
1799
1800 HANDLE_INSTRUCTION_START(ADD_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001801 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001802 SafeAdd(shadow_frame.GetVReg(inst->VRegB_23x()),
1803 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001804 ADVANCE(2);
1805 HANDLE_INSTRUCTION_END();
1806
1807 HANDLE_INSTRUCTION_START(SUB_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001808 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001809 SafeSub(shadow_frame.GetVReg(inst->VRegB_23x()),
1810 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001811 ADVANCE(2);
1812 HANDLE_INSTRUCTION_END();
1813
1814 HANDLE_INSTRUCTION_START(MUL_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001815 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001816 SafeMul(shadow_frame.GetVReg(inst->VRegB_23x()),
1817 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001818 ADVANCE(2);
1819 HANDLE_INSTRUCTION_END();
1820
1821 HANDLE_INSTRUCTION_START(DIV_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001822 bool success = DoIntDivide(shadow_frame, inst->VRegA_23x(inst_data),
1823 shadow_frame.GetVReg(inst->VRegB_23x()),
1824 shadow_frame.GetVReg(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001825 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1826 }
1827 HANDLE_INSTRUCTION_END();
1828
1829 HANDLE_INSTRUCTION_START(REM_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001830 bool success = DoIntRemainder(shadow_frame, inst->VRegA_23x(inst_data),
1831 shadow_frame.GetVReg(inst->VRegB_23x()),
1832 shadow_frame.GetVReg(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001833 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1834 }
1835 HANDLE_INSTRUCTION_END();
1836
1837 HANDLE_INSTRUCTION_START(SHL_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()) & 0x1f));
1841 ADVANCE(2);
1842 HANDLE_INSTRUCTION_END();
1843
1844 HANDLE_INSTRUCTION_START(SHR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001845 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001846 shadow_frame.GetVReg(inst->VRegB_23x()) >>
1847 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1848 ADVANCE(2);
1849 HANDLE_INSTRUCTION_END();
1850
1851 HANDLE_INSTRUCTION_START(USHR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001852 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001853 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_23x())) >>
1854 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1855 ADVANCE(2);
1856 HANDLE_INSTRUCTION_END();
1857
1858 HANDLE_INSTRUCTION_START(AND_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001859 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001860 shadow_frame.GetVReg(inst->VRegB_23x()) &
1861 shadow_frame.GetVReg(inst->VRegC_23x()));
1862 ADVANCE(2);
1863 HANDLE_INSTRUCTION_END();
1864
1865 HANDLE_INSTRUCTION_START(OR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001866 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001867 shadow_frame.GetVReg(inst->VRegB_23x()) |
1868 shadow_frame.GetVReg(inst->VRegC_23x()));
1869 ADVANCE(2);
1870 HANDLE_INSTRUCTION_END();
1871
1872 HANDLE_INSTRUCTION_START(XOR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001873 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001874 shadow_frame.GetVReg(inst->VRegB_23x()) ^
1875 shadow_frame.GetVReg(inst->VRegC_23x()));
1876 ADVANCE(2);
1877 HANDLE_INSTRUCTION_END();
1878
1879 HANDLE_INSTRUCTION_START(ADD_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001880 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001881 SafeAdd(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1882 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001883 ADVANCE(2);
1884 HANDLE_INSTRUCTION_END();
1885
1886 HANDLE_INSTRUCTION_START(SUB_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001887 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001888 SafeSub(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1889 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001890 ADVANCE(2);
1891 HANDLE_INSTRUCTION_END();
1892
1893 HANDLE_INSTRUCTION_START(MUL_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001894 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001895 SafeMul(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1896 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001897 ADVANCE(2);
1898 HANDLE_INSTRUCTION_END();
1899
1900 HANDLE_INSTRUCTION_START(DIV_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001901 bool success = DoLongDivide(shadow_frame, inst->VRegA_23x(inst_data),
1902 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1903 shadow_frame.GetVRegLong(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001904 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1905 }
1906 HANDLE_INSTRUCTION_END();
1907
1908 HANDLE_INSTRUCTION_START(REM_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001909 bool success = DoLongRemainder(shadow_frame, inst->VRegA_23x(inst_data),
1910 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1911 shadow_frame.GetVRegLong(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001912 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1913 }
1914 HANDLE_INSTRUCTION_END();
1915
1916 HANDLE_INSTRUCTION_START(AND_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 shadow_frame.GetVRegLong(inst->VRegB_23x()) &
1919 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1920 ADVANCE(2);
1921 HANDLE_INSTRUCTION_END();
1922
1923 HANDLE_INSTRUCTION_START(OR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001924 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001925 shadow_frame.GetVRegLong(inst->VRegB_23x()) |
1926 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1927 ADVANCE(2);
1928 HANDLE_INSTRUCTION_END();
1929
1930 HANDLE_INSTRUCTION_START(XOR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001931 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001932 shadow_frame.GetVRegLong(inst->VRegB_23x()) ^
1933 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1934 ADVANCE(2);
1935 HANDLE_INSTRUCTION_END();
1936
1937 HANDLE_INSTRUCTION_START(SHL_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001938 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001939 shadow_frame.GetVRegLong(inst->VRegB_23x()) <<
1940 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1941 ADVANCE(2);
1942 HANDLE_INSTRUCTION_END();
1943
1944 HANDLE_INSTRUCTION_START(SHR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001945 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001946 shadow_frame.GetVRegLong(inst->VRegB_23x()) >>
1947 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1948 ADVANCE(2);
1949 HANDLE_INSTRUCTION_END();
1950
1951 HANDLE_INSTRUCTION_START(USHR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001952 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001953 static_cast<uint64_t>(shadow_frame.GetVRegLong(inst->VRegB_23x())) >>
1954 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1955 ADVANCE(2);
1956 HANDLE_INSTRUCTION_END();
1957
1958 HANDLE_INSTRUCTION_START(ADD_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001959 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001960 shadow_frame.GetVRegFloat(inst->VRegB_23x()) +
1961 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1962 ADVANCE(2);
1963 HANDLE_INSTRUCTION_END();
1964
1965 HANDLE_INSTRUCTION_START(SUB_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001966 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001967 shadow_frame.GetVRegFloat(inst->VRegB_23x()) -
1968 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1969 ADVANCE(2);
1970 HANDLE_INSTRUCTION_END();
1971
1972 HANDLE_INSTRUCTION_START(MUL_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001973 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001974 shadow_frame.GetVRegFloat(inst->VRegB_23x()) *
1975 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1976 ADVANCE(2);
1977 HANDLE_INSTRUCTION_END();
1978
1979 HANDLE_INSTRUCTION_START(DIV_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001980 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001981 shadow_frame.GetVRegFloat(inst->VRegB_23x()) /
1982 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1983 ADVANCE(2);
1984 HANDLE_INSTRUCTION_END();
1985
1986 HANDLE_INSTRUCTION_START(REM_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001987 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001988 fmodf(shadow_frame.GetVRegFloat(inst->VRegB_23x()),
1989 shadow_frame.GetVRegFloat(inst->VRegC_23x())));
1990 ADVANCE(2);
1991 HANDLE_INSTRUCTION_END();
1992
1993 HANDLE_INSTRUCTION_START(ADD_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001994 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001995 shadow_frame.GetVRegDouble(inst->VRegB_23x()) +
1996 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1997 ADVANCE(2);
1998 HANDLE_INSTRUCTION_END();
1999
2000 HANDLE_INSTRUCTION_START(SUB_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002001 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002002 shadow_frame.GetVRegDouble(inst->VRegB_23x()) -
2003 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
2004 ADVANCE(2);
2005 HANDLE_INSTRUCTION_END();
2006
2007 HANDLE_INSTRUCTION_START(MUL_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002008 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002009 shadow_frame.GetVRegDouble(inst->VRegB_23x()) *
2010 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
2011 ADVANCE(2);
2012 HANDLE_INSTRUCTION_END();
2013
2014 HANDLE_INSTRUCTION_START(DIV_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002015 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002016 shadow_frame.GetVRegDouble(inst->VRegB_23x()) /
2017 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
2018 ADVANCE(2);
2019 HANDLE_INSTRUCTION_END();
2020
2021 HANDLE_INSTRUCTION_START(REM_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002022 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002023 fmod(shadow_frame.GetVRegDouble(inst->VRegB_23x()),
2024 shadow_frame.GetVRegDouble(inst->VRegC_23x())));
2025 ADVANCE(2);
2026 HANDLE_INSTRUCTION_END();
2027
2028 HANDLE_INSTRUCTION_START(ADD_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 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002031 SafeAdd(shadow_frame.GetVReg(vregA),
2032 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002033 ADVANCE(1);
2034 }
2035 HANDLE_INSTRUCTION_END();
2036
2037 HANDLE_INSTRUCTION_START(SUB_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002038 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002039 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002040 SafeSub(shadow_frame.GetVReg(vregA),
2041 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002042 ADVANCE(1);
2043 }
2044 HANDLE_INSTRUCTION_END();
2045
2046 HANDLE_INSTRUCTION_START(MUL_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002047 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002048 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002049 SafeMul(shadow_frame.GetVReg(vregA),
2050 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002051 ADVANCE(1);
2052 }
2053 HANDLE_INSTRUCTION_END();
2054
2055 HANDLE_INSTRUCTION_START(DIV_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002056 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002057 bool success = DoIntDivide(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002058 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002059 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2060 }
2061 HANDLE_INSTRUCTION_END();
2062
2063 HANDLE_INSTRUCTION_START(REM_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 bool success = DoIntRemainder(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002066 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002067 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2068 }
2069 HANDLE_INSTRUCTION_END();
2070
2071 HANDLE_INSTRUCTION_START(SHL_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002072 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002073 shadow_frame.SetVReg(vregA,
2074 shadow_frame.GetVReg(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002075 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002076 ADVANCE(1);
2077 }
2078 HANDLE_INSTRUCTION_END();
2079
2080 HANDLE_INSTRUCTION_START(SHR_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002081 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002082 shadow_frame.SetVReg(vregA,
2083 shadow_frame.GetVReg(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002084 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002085 ADVANCE(1);
2086 }
2087 HANDLE_INSTRUCTION_END();
2088
2089 HANDLE_INSTRUCTION_START(USHR_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002090 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002091 shadow_frame.SetVReg(vregA,
2092 static_cast<uint32_t>(shadow_frame.GetVReg(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002093 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002094 ADVANCE(1);
2095 }
2096 HANDLE_INSTRUCTION_END();
2097
2098 HANDLE_INSTRUCTION_START(AND_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002099 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002100 shadow_frame.SetVReg(vregA,
2101 shadow_frame.GetVReg(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002102 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002103 ADVANCE(1);
2104 }
2105 HANDLE_INSTRUCTION_END();
2106
2107 HANDLE_INSTRUCTION_START(OR_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002108 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002109 shadow_frame.SetVReg(vregA,
2110 shadow_frame.GetVReg(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002111 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002112 ADVANCE(1);
2113 }
2114 HANDLE_INSTRUCTION_END();
2115
2116 HANDLE_INSTRUCTION_START(XOR_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002117 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002118 shadow_frame.SetVReg(vregA,
2119 shadow_frame.GetVReg(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002120 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002121 ADVANCE(1);
2122 }
2123 HANDLE_INSTRUCTION_END();
2124
2125 HANDLE_INSTRUCTION_START(ADD_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 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002128 SafeAdd(shadow_frame.GetVRegLong(vregA),
2129 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002130 ADVANCE(1);
2131 }
2132 HANDLE_INSTRUCTION_END();
2133
2134 HANDLE_INSTRUCTION_START(SUB_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002135 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002136 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002137 SafeSub(shadow_frame.GetVRegLong(vregA),
2138 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002139 ADVANCE(1);
2140 }
2141 HANDLE_INSTRUCTION_END();
2142
2143 HANDLE_INSTRUCTION_START(MUL_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002144 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002145 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002146 SafeMul(shadow_frame.GetVRegLong(vregA),
2147 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002148 ADVANCE(1);
2149 }
2150 HANDLE_INSTRUCTION_END();
2151
2152 HANDLE_INSTRUCTION_START(DIV_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002153 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002154 bool success = DoLongDivide(shadow_frame, vregA, 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 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2157 }
2158 HANDLE_INSTRUCTION_END();
2159
2160 HANDLE_INSTRUCTION_START(REM_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 bool success = DoLongRemainder(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002163 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002164 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2165 }
2166 HANDLE_INSTRUCTION_END();
2167
2168 HANDLE_INSTRUCTION_START(AND_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002169 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002170 shadow_frame.SetVRegLong(vregA,
2171 shadow_frame.GetVRegLong(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002172 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002173 ADVANCE(1);
2174 }
2175 HANDLE_INSTRUCTION_END();
2176
2177 HANDLE_INSTRUCTION_START(OR_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002178 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002179 shadow_frame.SetVRegLong(vregA,
2180 shadow_frame.GetVRegLong(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002181 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002182 ADVANCE(1);
2183 }
2184 HANDLE_INSTRUCTION_END();
2185
2186 HANDLE_INSTRUCTION_START(XOR_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002187 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002188 shadow_frame.SetVRegLong(vregA,
2189 shadow_frame.GetVRegLong(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002190 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002191 ADVANCE(1);
2192 }
2193 HANDLE_INSTRUCTION_END();
2194
2195 HANDLE_INSTRUCTION_START(SHL_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002196 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002197 shadow_frame.SetVRegLong(vregA,
2198 shadow_frame.GetVRegLong(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002199 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002200 ADVANCE(1);
2201 }
2202 HANDLE_INSTRUCTION_END();
2203
2204 HANDLE_INSTRUCTION_START(SHR_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002205 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002206 shadow_frame.SetVRegLong(vregA,
2207 shadow_frame.GetVRegLong(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002208 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002209 ADVANCE(1);
2210 }
2211 HANDLE_INSTRUCTION_END();
2212
2213 HANDLE_INSTRUCTION_START(USHR_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002214 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002215 shadow_frame.SetVRegLong(vregA,
2216 static_cast<uint64_t>(shadow_frame.GetVRegLong(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002217 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002218 ADVANCE(1);
2219 }
2220 HANDLE_INSTRUCTION_END();
2221
2222 HANDLE_INSTRUCTION_START(ADD_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002223 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002224 shadow_frame.SetVRegFloat(vregA,
2225 shadow_frame.GetVRegFloat(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002226 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002227 ADVANCE(1);
2228 }
2229 HANDLE_INSTRUCTION_END();
2230
2231 HANDLE_INSTRUCTION_START(SUB_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002232 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002233 shadow_frame.SetVRegFloat(vregA,
2234 shadow_frame.GetVRegFloat(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002235 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002236 ADVANCE(1);
2237 }
2238 HANDLE_INSTRUCTION_END();
2239
2240 HANDLE_INSTRUCTION_START(MUL_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002241 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002242 shadow_frame.SetVRegFloat(vregA,
2243 shadow_frame.GetVRegFloat(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002244 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002245 ADVANCE(1);
2246 }
2247 HANDLE_INSTRUCTION_END();
2248
2249 HANDLE_INSTRUCTION_START(DIV_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002250 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002251 shadow_frame.SetVRegFloat(vregA,
2252 shadow_frame.GetVRegFloat(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002253 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002254 ADVANCE(1);
2255 }
2256 HANDLE_INSTRUCTION_END();
2257
2258 HANDLE_INSTRUCTION_START(REM_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002259 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002260 shadow_frame.SetVRegFloat(vregA,
2261 fmodf(shadow_frame.GetVRegFloat(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002262 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002263 ADVANCE(1);
2264 }
2265 HANDLE_INSTRUCTION_END();
2266
2267 HANDLE_INSTRUCTION_START(ADD_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002268 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002269 shadow_frame.SetVRegDouble(vregA,
2270 shadow_frame.GetVRegDouble(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002271 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002272 ADVANCE(1);
2273 }
2274 HANDLE_INSTRUCTION_END();
2275
2276 HANDLE_INSTRUCTION_START(SUB_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002277 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002278 shadow_frame.SetVRegDouble(vregA,
2279 shadow_frame.GetVRegDouble(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002280 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002281 ADVANCE(1);
2282 }
2283 HANDLE_INSTRUCTION_END();
2284
2285 HANDLE_INSTRUCTION_START(MUL_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002286 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002287 shadow_frame.SetVRegDouble(vregA,
2288 shadow_frame.GetVRegDouble(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002289 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002290 ADVANCE(1);
2291 }
2292 HANDLE_INSTRUCTION_END();
2293
2294 HANDLE_INSTRUCTION_START(DIV_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002295 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002296 shadow_frame.SetVRegDouble(vregA,
2297 shadow_frame.GetVRegDouble(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002298 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002299 ADVANCE(1);
2300 }
2301 HANDLE_INSTRUCTION_END();
2302
2303 HANDLE_INSTRUCTION_START(REM_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002304 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002305 shadow_frame.SetVRegDouble(vregA,
2306 fmod(shadow_frame.GetVRegDouble(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002307 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002308 ADVANCE(1);
2309 }
2310 HANDLE_INSTRUCTION_END();
2311
2312 HANDLE_INSTRUCTION_START(ADD_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002313 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002314 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2315 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002316 ADVANCE(2);
2317 HANDLE_INSTRUCTION_END();
2318
2319 HANDLE_INSTRUCTION_START(RSUB_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002320 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002321 SafeSub(inst->VRegC_22s(),
2322 shadow_frame.GetVReg(inst->VRegB_22s(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002323 ADVANCE(2);
2324 HANDLE_INSTRUCTION_END();
2325
2326 HANDLE_INSTRUCTION_START(MUL_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002327 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002328 SafeMul(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2329 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002330 ADVANCE(2);
2331 HANDLE_INSTRUCTION_END();
2332
2333 HANDLE_INSTRUCTION_START(DIV_INT_LIT16) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002334 bool success = DoIntDivide(
2335 shadow_frame, inst->VRegA_22s(inst_data), shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2336 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002337 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2338 }
2339 HANDLE_INSTRUCTION_END();
2340
2341 HANDLE_INSTRUCTION_START(REM_INT_LIT16) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002342 bool success = DoIntRemainder(
2343 shadow_frame, inst->VRegA_22s(inst_data), shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2344 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002345 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2346 }
2347 HANDLE_INSTRUCTION_END();
2348
2349 HANDLE_INSTRUCTION_START(AND_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002350 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2351 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) &
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002352 inst->VRegC_22s());
2353 ADVANCE(2);
2354 HANDLE_INSTRUCTION_END();
2355
2356 HANDLE_INSTRUCTION_START(OR_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002357 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2358 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) |
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002359 inst->VRegC_22s());
2360 ADVANCE(2);
2361 HANDLE_INSTRUCTION_END();
2362
2363 HANDLE_INSTRUCTION_START(XOR_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002364 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2365 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) ^
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002366 inst->VRegC_22s());
2367 ADVANCE(2);
2368 HANDLE_INSTRUCTION_END();
2369
2370 HANDLE_INSTRUCTION_START(ADD_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002371 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002372 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22b()),
2373 inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002374 ADVANCE(2);
2375 HANDLE_INSTRUCTION_END();
2376
2377 HANDLE_INSTRUCTION_START(RSUB_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002378 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002379 SafeSub(inst->VRegC_22b(),
2380 shadow_frame.GetVReg(inst->VRegB_22b())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002381 ADVANCE(2);
2382 HANDLE_INSTRUCTION_END();
2383
2384 HANDLE_INSTRUCTION_START(MUL_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002385 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002386 SafeMul(shadow_frame.GetVReg(inst->VRegB_22b()),
2387 inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002388 ADVANCE(2);
2389 HANDLE_INSTRUCTION_END();
2390
2391 HANDLE_INSTRUCTION_START(DIV_INT_LIT8) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002392 bool success = DoIntDivide(shadow_frame, inst->VRegA_22b(inst_data),
2393 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002394 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2395 }
2396 HANDLE_INSTRUCTION_END();
2397
2398 HANDLE_INSTRUCTION_START(REM_INT_LIT8) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002399 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22b(inst_data),
2400 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002401 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2402 }
2403 HANDLE_INSTRUCTION_END();
2404
2405 HANDLE_INSTRUCTION_START(AND_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 shadow_frame.GetVReg(inst->VRegB_22b()) &
2408 inst->VRegC_22b());
2409 ADVANCE(2);
2410 HANDLE_INSTRUCTION_END();
2411
2412 HANDLE_INSTRUCTION_START(OR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002413 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002414 shadow_frame.GetVReg(inst->VRegB_22b()) |
2415 inst->VRegC_22b());
2416 ADVANCE(2);
2417 HANDLE_INSTRUCTION_END();
2418
2419 HANDLE_INSTRUCTION_START(XOR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002420 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002421 shadow_frame.GetVReg(inst->VRegB_22b()) ^
2422 inst->VRegC_22b());
2423 ADVANCE(2);
2424 HANDLE_INSTRUCTION_END();
2425
2426 HANDLE_INSTRUCTION_START(SHL_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002427 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002428 shadow_frame.GetVReg(inst->VRegB_22b()) <<
2429 (inst->VRegC_22b() & 0x1f));
2430 ADVANCE(2);
2431 HANDLE_INSTRUCTION_END();
2432
2433 HANDLE_INSTRUCTION_START(SHR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002434 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002435 shadow_frame.GetVReg(inst->VRegB_22b()) >>
2436 (inst->VRegC_22b() & 0x1f));
2437 ADVANCE(2);
2438 HANDLE_INSTRUCTION_END();
2439
2440 HANDLE_INSTRUCTION_START(USHR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002441 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002442 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_22b())) >>
2443 (inst->VRegC_22b() & 0x1f));
2444 ADVANCE(2);
2445 HANDLE_INSTRUCTION_END();
2446
2447 HANDLE_INSTRUCTION_START(UNUSED_3E)
Ian Rogerse94652f2014-12-02 11:13:19 -08002448 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002449 HANDLE_INSTRUCTION_END();
2450
2451 HANDLE_INSTRUCTION_START(UNUSED_3F)
Ian Rogerse94652f2014-12-02 11:13:19 -08002452 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002453 HANDLE_INSTRUCTION_END();
2454
2455 HANDLE_INSTRUCTION_START(UNUSED_40)
Ian Rogerse94652f2014-12-02 11:13:19 -08002456 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002457 HANDLE_INSTRUCTION_END();
2458
2459 HANDLE_INSTRUCTION_START(UNUSED_41)
Ian Rogerse94652f2014-12-02 11:13:19 -08002460 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002461 HANDLE_INSTRUCTION_END();
2462
2463 HANDLE_INSTRUCTION_START(UNUSED_42)
Ian Rogerse94652f2014-12-02 11:13:19 -08002464 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002465 HANDLE_INSTRUCTION_END();
2466
2467 HANDLE_INSTRUCTION_START(UNUSED_43)
Ian Rogerse94652f2014-12-02 11:13:19 -08002468 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002469 HANDLE_INSTRUCTION_END();
2470
2471 HANDLE_INSTRUCTION_START(UNUSED_79)
Ian Rogerse94652f2014-12-02 11:13:19 -08002472 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002473 HANDLE_INSTRUCTION_END();
2474
2475 HANDLE_INSTRUCTION_START(UNUSED_7A)
Ian Rogerse94652f2014-12-02 11:13:19 -08002476 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002477 HANDLE_INSTRUCTION_END();
2478
Narayan Kamath14832ef2016-08-05 11:44:32 +01002479 HANDLE_INSTRUCTION_START(UNUSED_F3)
2480 UnexpectedOpcode(inst, shadow_frame);
2481 HANDLE_INSTRUCTION_END();
2482
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002483 HANDLE_INSTRUCTION_START(UNUSED_F4)
Ian Rogerse94652f2014-12-02 11:13:19 -08002484 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002485 HANDLE_INSTRUCTION_END();
2486
Narayan Kamath14832ef2016-08-05 11:44:32 +01002487 HANDLE_INSTRUCTION_START(UNUSED_F5)
2488 UnexpectedOpcode(inst, shadow_frame);
2489 HANDLE_INSTRUCTION_END();
2490
2491 HANDLE_INSTRUCTION_START(UNUSED_F6)
2492 UnexpectedOpcode(inst, shadow_frame);
2493 HANDLE_INSTRUCTION_END();
2494
2495 HANDLE_INSTRUCTION_START(UNUSED_F7)
2496 UnexpectedOpcode(inst, shadow_frame);
2497 HANDLE_INSTRUCTION_END();
2498
2499 HANDLE_INSTRUCTION_START(UNUSED_F8)
2500 UnexpectedOpcode(inst, shadow_frame);
2501 HANDLE_INSTRUCTION_END();
2502
2503 HANDLE_INSTRUCTION_START(UNUSED_F9)
2504 UnexpectedOpcode(inst, shadow_frame);
2505 HANDLE_INSTRUCTION_END();
2506
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002507 HANDLE_INSTRUCTION_START(UNUSED_FA)
Ian Rogerse94652f2014-12-02 11:13:19 -08002508 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002509 HANDLE_INSTRUCTION_END();
2510
2511 HANDLE_INSTRUCTION_START(UNUSED_FB)
Ian Rogerse94652f2014-12-02 11:13:19 -08002512 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002513 HANDLE_INSTRUCTION_END();
2514
2515 HANDLE_INSTRUCTION_START(UNUSED_FC)
Ian Rogerse94652f2014-12-02 11:13:19 -08002516 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002517 HANDLE_INSTRUCTION_END();
2518
2519 HANDLE_INSTRUCTION_START(UNUSED_FD)
Ian Rogerse94652f2014-12-02 11:13:19 -08002520 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002521 HANDLE_INSTRUCTION_END();
2522
2523 HANDLE_INSTRUCTION_START(UNUSED_FE)
Ian Rogerse94652f2014-12-02 11:13:19 -08002524 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002525 HANDLE_INSTRUCTION_END();
2526
2527 HANDLE_INSTRUCTION_START(UNUSED_FF)
Ian Rogerse94652f2014-12-02 11:13:19 -08002528 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002529 HANDLE_INSTRUCTION_END();
2530
2531 exception_pending_label: {
2532 CHECK(self->IsExceptionPending());
Sebastien Hertz1eda2262013-09-09 16:53:14 +02002533 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -07002534 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +02002535 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +02002536 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002537 uint32_t found_dex_pc = FindNextInstructionFollowingException(self, shadow_frame, dex_pc,
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002538 instrumentation);
2539 if (found_dex_pc == DexFile::kDexNoIndex) {
Andreas Gampe03ec9302015-08-27 17:41:47 -07002540 // Structured locking is to be enforced for abnormal termination, too.
Andreas Gampe56fdd0e2016-04-28 14:56:54 -07002541 DoMonitorCheckOnExit<do_assignability_check>(self, &shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002542 return JValue(); /* Handled in caller. */
2543 } else {
2544 int32_t displacement = static_cast<int32_t>(found_dex_pc) - static_cast<int32_t>(dex_pc);
2545 ADVANCE(displacement);
2546 }
2547 }
2548
Sebastien Hertz8379b222014-02-24 17:38:15 +01002549// Create alternative instruction handlers dedicated to instrumentation.
2550// Return instructions must not call Instrumentation::DexPcMovedEvent since they already call
2551// Instrumentation::MethodExited. This is to avoid posting debugger events twice for this location.
Sebastien Hertze713d932014-05-15 10:48:53 +02002552// Note: we do not use the kReturn instruction flag here (to test the instruction is a return). The
2553// compiler seems to not evaluate "(Instruction::FlagsOf(Instruction::code) & kReturn) != 0" to
2554// a constant condition that would remove the "if" statement so the test is free.
Narayan Kamathbd48b342016-08-01 17:32:37 +01002555#define INSTRUMENTATION_INSTRUCTION_HANDLER(o, code, n, f, i, a, v) \
Sebastien Hertz9d6bf692015-04-10 12:12:33 +02002556 alt_op_##code: { \
Sebastien Hertz9d6bf692015-04-10 12:12:33 +02002557 if (UNLIKELY(instrumentation->HasDexPcListeners())) { \
2558 Object* this_object = shadow_frame.GetThisObject(code_item->ins_size_); \
2559 instrumentation->DexPcMovedEvent(self, this_object, shadow_frame.GetMethod(), dex_pc); \
2560 } \
2561 UPDATE_HANDLER_TABLE(); \
2562 goto *handlersTable[instrumentation::kMainHandlerTable][Instruction::code]; \
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002563 }
2564#include "dex_instruction_list.h"
2565 DEX_INSTRUCTION_LIST(INSTRUMENTATION_INSTRUCTION_HANDLER)
2566#undef DEX_INSTRUCTION_LIST
2567#undef INSTRUMENTATION_INSTRUCTION_HANDLER
2568} // NOLINT(readability/fn_size)
2569
2570// Explicit definitions of ExecuteGotoImpl.
Andreas Gampe5e26eb12016-08-22 17:54:17 -07002571template HOT_ATTR
Ian Rogerse94652f2014-12-02 11:13:19 -08002572JValue ExecuteGotoImpl<true, false>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002573 ShadowFrame& shadow_frame, JValue result_register);
Andreas Gampe5e26eb12016-08-22 17:54:17 -07002574template HOT_ATTR
Ian Rogerse94652f2014-12-02 11:13:19 -08002575JValue ExecuteGotoImpl<false, false>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002576 ShadowFrame& shadow_frame, JValue result_register);
Andreas Gampe5e26eb12016-08-22 17:54:17 -07002577template
Ian Rogerse94652f2014-12-02 11:13:19 -08002578JValue ExecuteGotoImpl<true, true>(Thread* self, const DexFile::CodeItem* code_item,
2579 ShadowFrame& shadow_frame, JValue result_register);
Andreas Gampe5e26eb12016-08-22 17:54:17 -07002580template
Ian Rogerse94652f2014-12-02 11:13:19 -08002581JValue ExecuteGotoImpl<false, true>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002582 ShadowFrame& shadow_frame, JValue result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002583
Andreas Gampe5e26eb12016-08-22 17:54:17 -07002584#else
2585
2586template<bool do_access_check, bool transaction_active>
2587JValue ExecuteGotoImpl(Thread*, const DexFile::CodeItem*, ShadowFrame&, JValue) {
2588 LOG(FATAL) << "UNREACHABLE";
2589 UNREACHABLE();
2590}
2591// Explicit definitions of ExecuteGotoImpl.
2592template<>
2593JValue ExecuteGotoImpl<true, false>(Thread* self, const DexFile::CodeItem* code_item,
2594 ShadowFrame& shadow_frame, JValue result_register);
2595template<>
2596JValue ExecuteGotoImpl<false, false>(Thread* self, const DexFile::CodeItem* code_item,
2597 ShadowFrame& shadow_frame, JValue result_register);
2598template<>
2599JValue ExecuteGotoImpl<true, true>(Thread* self, const DexFile::CodeItem* code_item,
2600 ShadowFrame& shadow_frame, JValue result_register);
2601template<>
2602JValue ExecuteGotoImpl<false, true>(Thread* self, const DexFile::CodeItem* code_item,
2603 ShadowFrame& shadow_frame, JValue result_register);
2604#endif
2605
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002606} // namespace interpreter
2607} // namespace art