blob: ca006214c8d7c0e980dbd398cdb4545c6eb6f8bb [file] [log] [blame]
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Colin Crosse84e4f72015-03-18 14:01:19 -070017#if !defined(__clang__)
18// Clang 3.4 fails to build the goto interpreter implementation.
19
Igor Murashkin6918bf12015-09-27 19:19:06 -070020
21#include "base/stl_util.h" // MakeUnique
Alex Lighteb7c1442015-08-31 13:17:42 -070022#include "experimental_flags.h"
Sebastien Hertz8ece0502013-08-07 11:26:41 +020023#include "interpreter_common.h"
Ian Rogersf72a11d2014-10-30 15:41:08 -070024#include "safe_math.h"
Sebastien Hertz8ece0502013-08-07 11:26:41 +020025
Igor Murashkin6918bf12015-09-27 19:19:06 -070026#include <memory> // std::unique_ptr
27
Sebastien Hertz8ece0502013-08-07 11:26:41 +020028namespace art {
29namespace interpreter {
30
31// In the following macros, we expect the following local variables exist:
32// - "self": the current Thread*.
33// - "inst" : the current Instruction*.
Sebastien Hertz3b588e02013-09-11 14:33:18 +020034// - "inst_data" : the current instruction's first 16 bits.
Sebastien Hertz8ece0502013-08-07 11:26:41 +020035// - "dex_pc": the current pc.
36// - "shadow_frame": the current shadow frame.
Sebastien Hertz8ece0502013-08-07 11:26:41 +020037// - "currentHandlersTable": the current table of pointer to each instruction handler.
38
39// Advance to the next instruction and updates interpreter state.
Sebastien Hertz8ece0502013-08-07 11:26:41 +020040#define ADVANCE(_offset) \
41 do { \
42 int32_t disp = static_cast<int32_t>(_offset); \
43 inst = inst->RelativeAt(disp); \
44 dex_pc = static_cast<uint32_t>(static_cast<int32_t>(dex_pc) + disp); \
45 shadow_frame.SetDexPC(dex_pc); \
Ian Rogerse94652f2014-12-02 11:13:19 -080046 TraceExecution(shadow_frame, inst, dex_pc); \
Sebastien Hertz3b588e02013-09-11 14:33:18 +020047 inst_data = inst->Fetch16(0); \
48 goto *currentHandlersTable[inst->Opcode(inst_data)]; \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020049 } while (false)
50
51#define HANDLE_PENDING_EXCEPTION() goto exception_pending_label
52
53#define POSSIBLY_HANDLE_PENDING_EXCEPTION(_is_exception_pending, _offset) \
54 do { \
55 if (UNLIKELY(_is_exception_pending)) { \
56 HANDLE_PENDING_EXCEPTION(); \
57 } else { \
58 ADVANCE(_offset); \
59 } \
60 } while (false)
61
Sebastien Hertzee1997a2013-09-19 14:47:09 +020062#define UPDATE_HANDLER_TABLE() \
Mathieu Chartier2cebb242015-04-21 16:50:40 -070063 currentHandlersTable = handlersTable[ \
64 Runtime::Current()->GetInstrumentation()->GetInterpreterHandlerTable()]
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +020065
Nicolas Geoffray81f0f952016-01-20 16:25:19 +000066#define BRANCH_INSTRUMENTATION(offset) \
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080067 do { \
68 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation(); \
Nicolas Geoffray81f0f952016-01-20 16:25:19 +000069 instrumentation->Branch(self, shadow_frame.GetMethod(), dex_pc, offset); \
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080070 } while (false)
71
Sebastien Hertz8ece0502013-08-07 11:26:41 +020072#define UNREACHABLE_CODE_CHECK() \
73 do { \
74 if (kIsDebugBuild) { \
75 LOG(FATAL) << "We should not be here !"; \
Ian Rogerse94652f2014-12-02 11:13:19 -080076 UNREACHABLE(); \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020077 } \
78 } while (false)
79
80#define HANDLE_INSTRUCTION_START(opcode) op_##opcode: // NOLINT(whitespace/labels)
81#define HANDLE_INSTRUCTION_END() UNREACHABLE_CODE_CHECK()
82
Igor Murashkin158f35c2015-06-10 15:55:30 -070083// Use with instructions labeled with kExperimental flag:
84#define HANDLE_EXPERIMENTAL_INSTRUCTION_START(opcode) \
85 HANDLE_INSTRUCTION_START(opcode); \
86 DCHECK(inst->IsExperimental()); \
Alex Lighteb7c1442015-08-31 13:17:42 -070087 if (Runtime::Current()->AreExperimentalFlagsEnabled(ExperimentalFlags::kLambdas)) {
Igor Murashkin158f35c2015-06-10 15:55:30 -070088#define HANDLE_EXPERIMENTAL_INSTRUCTION_END() \
89 } else { \
90 UnexpectedOpcode(inst, shadow_frame); \
91 } HANDLE_INSTRUCTION_END();
92
Andreas Gampe03ec9302015-08-27 17:41:47 -070093#define HANDLE_MONITOR_CHECKS() \
94 if (!shadow_frame.GetLockCountData(). \
95 CheckAllMonitorsReleasedOrThrow<do_assignability_check>(self)) { \
96 HANDLE_PENDING_EXCEPTION(); \
97 }
Igor Murashkin158f35c2015-06-10 15:55:30 -070098
Sebastien Hertzee1997a2013-09-19 14:47:09 +020099/**
100 * Interpreter based on computed goto tables.
101 *
102 * Each instruction is associated to a handler. This handler is responsible for executing the
103 * instruction and jump to the next instruction's handler.
104 * In order to limit the cost of instrumentation, we have two handler tables:
105 * - the "main" handler table: it contains handlers for normal execution of each instruction without
106 * handling of instrumentation.
107 * - the "alternative" handler table: it contains alternative handlers which first handle
108 * instrumentation before jumping to the corresponding "normal" instruction's handler.
109 *
110 * When instrumentation is active, the interpreter uses the "alternative" handler table. Otherwise
111 * it uses the "main" handler table.
112 *
113 * The current handler table is the handler table being used by the interpreter. It is updated:
114 * - on backward branch (goto, if and switch instructions)
115 * - after invoke
116 * - when an exception is thrown.
117 * This allows to support an attaching debugger to an already running application for instance.
118 *
119 * For a fast handler table update, handler tables are stored in an array of handler tables. Each
120 * handler table is represented by the InterpreterHandlerTable enum which allows to associate it
121 * to an index in this array of handler tables ((see Instrumentation::GetInterpreterHandlerTable).
122 *
123 * Here's the current layout of this array of handler tables:
124 *
125 * ---------------------+---------------+
126 * | NOP | (handler for NOP instruction)
127 * +---------------+
128 * "main" | MOVE | (handler for MOVE instruction)
129 * handler table +---------------+
130 * | ... |
131 * +---------------+
132 * | UNUSED_FF | (handler for UNUSED_FF instruction)
133 * ---------------------+---------------+
134 * | NOP | (alternative handler for NOP instruction)
135 * +---------------+
136 * "alternative" | MOVE | (alternative handler for MOVE instruction)
137 * handler table +---------------+
138 * | ... |
139 * +---------------+
140 * | UNUSED_FF | (alternative handler for UNUSED_FF instruction)
141 * ---------------------+---------------+
142 *
143 */
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100144template<bool do_access_check, bool transaction_active>
Ian Rogerse94652f2014-12-02 11:13:19 -0800145JValue ExecuteGotoImpl(Thread* self, const DexFile::CodeItem* code_item, ShadowFrame& shadow_frame,
146 JValue result_register) {
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200147 // Define handler tables:
148 // - The main handler table contains execution handlers for each instruction.
149 // - The alternative handler table contains prelude handlers which check for thread suspend and
150 // manage instrumentation before jumping to the execution handler.
151 static const void* const handlersTable[instrumentation::kNumHandlerTables][kNumPackedOpcodes] = {
152 {
153 // Main handler table.
154#define INSTRUCTION_HANDLER(o, code, n, f, r, i, a, v) &&op_##code,
155#include "dex_instruction_list.h"
156 DEX_INSTRUCTION_LIST(INSTRUCTION_HANDLER)
157#undef DEX_INSTRUCTION_LIST
158#undef INSTRUCTION_HANDLER
159 }, {
160 // Alternative handler table.
161#define INSTRUCTION_HANDLER(o, code, n, f, r, i, a, v) &&alt_op_##code,
162#include "dex_instruction_list.h"
163 DEX_INSTRUCTION_LIST(INSTRUCTION_HANDLER)
164#undef DEX_INSTRUCTION_LIST
165#undef INSTRUCTION_HANDLER
166 }
167 };
168
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800169 constexpr bool do_assignability_check = do_access_check;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200170 if (UNLIKELY(!shadow_frame.HasReferenceArray())) {
171 LOG(FATAL) << "Invalid shadow frame for interpreter use";
172 return JValue();
173 }
174 self->VerifyStack();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200175
176 uint32_t dex_pc = shadow_frame.GetDexPC();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200177 const Instruction* inst = Instruction::At(code_item->insns_ + dex_pc);
178 uint16_t inst_data;
179 const void* const* currentHandlersTable;
180 UPDATE_HANDLER_TABLE();
Sebastien Hertz270a0e12015-01-16 19:49:09 +0100181 if (LIKELY(dex_pc == 0)) { // We are entering the method as opposed to deoptimizing.
182 if (kIsDebugBuild) {
183 self->AssertNoPendingException();
184 }
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200185 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200186 if (UNLIKELY(instrumentation->HasMethodEntryListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200187 instrumentation->MethodEnterEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200188 shadow_frame.GetMethod(), 0);
189 }
190 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200191
Igor Murashkin6918bf12015-09-27 19:19:06 -0700192 std::unique_ptr<lambda::ClosureBuilder> lambda_closure_builder;
193 size_t lambda_captured_variable_index = 0;
194
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 Hertzee1997a2013-09-19 14:47:09 +0200285 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200286 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200287 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200288 shadow_frame.GetMethod(), dex_pc,
289 result);
290 }
291 return result;
292 }
293 HANDLE_INSTRUCTION_END();
294
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700295 HANDLE_INSTRUCTION_START(RETURN_VOID) {
Hans Boehm30359612014-05-21 17:46:23 -0700296 QuasiAtomic::ThreadFenceForConstructor();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200297 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700298 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700299 HANDLE_MONITOR_CHECKS();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200300 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200301 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200302 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200303 shadow_frame.GetMethod(), dex_pc,
304 result);
305 }
306 return result;
307 }
308 HANDLE_INSTRUCTION_END();
309
310 HANDLE_INSTRUCTION_START(RETURN) {
311 JValue result;
312 result.SetJ(0);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200313 result.SetI(shadow_frame.GetVReg(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700314 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700315 HANDLE_MONITOR_CHECKS();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200316 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200317 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200318 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200319 shadow_frame.GetMethod(), dex_pc,
320 result);
321 }
322 return result;
323 }
324 HANDLE_INSTRUCTION_END();
325
326 HANDLE_INSTRUCTION_START(RETURN_WIDE) {
327 JValue result;
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200328 result.SetJ(shadow_frame.GetVRegLong(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700329 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700330 HANDLE_MONITOR_CHECKS();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200331 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200332 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200333 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200334 shadow_frame.GetMethod(), dex_pc,
335 result);
336 }
337 return result;
338 }
339 HANDLE_INSTRUCTION_END();
340
341 HANDLE_INSTRUCTION_START(RETURN_OBJECT) {
342 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700343 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700344 HANDLE_MONITOR_CHECKS();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700345 const uint8_t vreg_index = inst->VRegA_11x(inst_data);
346 Object* obj_result = shadow_frame.GetVRegReference(vreg_index);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700347 if (do_assignability_check && obj_result != nullptr) {
Vladimir Marko05792b92015-08-03 11:56:49 +0100348 size_t pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
349 Class* return_type = shadow_frame.GetMethod()->GetReturnType(true /* resolve */,
350 pointer_size);
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700351 obj_result = shadow_frame.GetVRegReference(vreg_index);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700352 if (return_type == nullptr) {
Jeff Haoa3faaf42013-09-03 19:07:00 -0700353 // Return the pending exception.
354 HANDLE_PENDING_EXCEPTION();
355 }
356 if (!obj_result->VerifierInstanceOf(return_type)) {
357 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700358 std::string temp1, temp2;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000359 self->ThrowNewExceptionF("Ljava/lang/VirtualMachineError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700360 "Returning '%s' that is not instance of return type '%s'",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700361 obj_result->GetClass()->GetDescriptor(&temp1),
362 return_type->GetDescriptor(&temp2));
Jeff Haoa3faaf42013-09-03 19:07:00 -0700363 HANDLE_PENDING_EXCEPTION();
364 }
365 }
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700366 result.SetL(obj_result);
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200367 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200368 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200369 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200370 shadow_frame.GetMethod(), dex_pc,
371 result);
372 }
373 return result;
374 }
375 HANDLE_INSTRUCTION_END();
376
377 HANDLE_INSTRUCTION_START(CONST_4) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200378 uint32_t dst = inst->VRegA_11n(inst_data);
379 int32_t val = inst->VRegB_11n(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200380 shadow_frame.SetVReg(dst, val);
381 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700382 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200383 }
384 ADVANCE(1);
385 }
386 HANDLE_INSTRUCTION_END();
387
388 HANDLE_INSTRUCTION_START(CONST_16) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200389 uint32_t dst = inst->VRegA_21s(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200390 int32_t val = inst->VRegB_21s();
391 shadow_frame.SetVReg(dst, val);
392 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700393 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200394 }
395 ADVANCE(2);
396 }
397 HANDLE_INSTRUCTION_END();
398
399 HANDLE_INSTRUCTION_START(CONST) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200400 uint32_t dst = inst->VRegA_31i(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200401 int32_t val = inst->VRegB_31i();
402 shadow_frame.SetVReg(dst, val);
403 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700404 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200405 }
406 ADVANCE(3);
407 }
408 HANDLE_INSTRUCTION_END();
409
410 HANDLE_INSTRUCTION_START(CONST_HIGH16) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200411 uint32_t dst = inst->VRegA_21h(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200412 int32_t val = static_cast<int32_t>(inst->VRegB_21h() << 16);
413 shadow_frame.SetVReg(dst, val);
414 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700415 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200416 }
417 ADVANCE(2);
418 }
419 HANDLE_INSTRUCTION_END();
420
421 HANDLE_INSTRUCTION_START(CONST_WIDE_16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200422 shadow_frame.SetVRegLong(inst->VRegA_21s(inst_data), inst->VRegB_21s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200423 ADVANCE(2);
424 HANDLE_INSTRUCTION_END();
425
426 HANDLE_INSTRUCTION_START(CONST_WIDE_32)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200427 shadow_frame.SetVRegLong(inst->VRegA_31i(inst_data), inst->VRegB_31i());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200428 ADVANCE(3);
429 HANDLE_INSTRUCTION_END();
430
431 HANDLE_INSTRUCTION_START(CONST_WIDE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200432 shadow_frame.SetVRegLong(inst->VRegA_51l(inst_data), inst->VRegB_51l());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200433 ADVANCE(5);
434 HANDLE_INSTRUCTION_END();
435
436 HANDLE_INSTRUCTION_START(CONST_WIDE_HIGH16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200437 shadow_frame.SetVRegLong(inst->VRegA_21h(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200438 static_cast<uint64_t>(inst->VRegB_21h()) << 48);
439 ADVANCE(2);
440 HANDLE_INSTRUCTION_END();
441
442 HANDLE_INSTRUCTION_START(CONST_STRING) {
Ian Rogers6786a582014-10-28 12:49:06 -0700443 String* s = ResolveString(self, shadow_frame, inst->VRegB_21c());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700444 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200445 HANDLE_PENDING_EXCEPTION();
446 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200447 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200448 ADVANCE(2);
449 }
450 }
451 HANDLE_INSTRUCTION_END();
452
453 HANDLE_INSTRUCTION_START(CONST_STRING_JUMBO) {
Ian Rogers6786a582014-10-28 12:49:06 -0700454 String* s = ResolveString(self, shadow_frame, inst->VRegB_31c());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700455 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200456 HANDLE_PENDING_EXCEPTION();
457 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200458 shadow_frame.SetVRegReference(inst->VRegA_31c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200459 ADVANCE(3);
460 }
461 }
462 HANDLE_INSTRUCTION_END();
463
464 HANDLE_INSTRUCTION_START(CONST_CLASS) {
465 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
466 self, false, do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700467 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200468 HANDLE_PENDING_EXCEPTION();
469 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200470 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), c);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200471 ADVANCE(2);
472 }
473 }
474 HANDLE_INSTRUCTION_END();
475
476 HANDLE_INSTRUCTION_START(MONITOR_ENTER) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200477 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700478 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000479 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200480 HANDLE_PENDING_EXCEPTION();
481 } else {
Andreas Gampe03ec9302015-08-27 17:41:47 -0700482 DoMonitorEnter<do_access_check>(self, &shadow_frame, obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200483 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), 1);
484 }
485 }
486 HANDLE_INSTRUCTION_END();
487
488 HANDLE_INSTRUCTION_START(MONITOR_EXIT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200489 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700490 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000491 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200492 HANDLE_PENDING_EXCEPTION();
493 } else {
Andreas Gampe03ec9302015-08-27 17:41:47 -0700494 DoMonitorExit<do_access_check>(self, &shadow_frame, obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200495 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), 1);
496 }
497 }
498 HANDLE_INSTRUCTION_END();
499
500 HANDLE_INSTRUCTION_START(CHECK_CAST) {
501 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
502 self, false, do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700503 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200504 HANDLE_PENDING_EXCEPTION();
505 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200506 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_21c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700507 if (UNLIKELY(obj != nullptr && !obj->InstanceOf(c))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200508 ThrowClassCastException(c, obj->GetClass());
509 HANDLE_PENDING_EXCEPTION();
510 } else {
511 ADVANCE(2);
512 }
513 }
514 }
515 HANDLE_INSTRUCTION_END();
516
517 HANDLE_INSTRUCTION_START(INSTANCE_OF) {
518 Class* c = ResolveVerifyAndClinit(inst->VRegC_22c(), shadow_frame.GetMethod(),
519 self, false, do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700520 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200521 HANDLE_PENDING_EXCEPTION();
522 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200523 Object* obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700524 shadow_frame.SetVReg(inst->VRegA_22c(inst_data), (obj != nullptr && obj->InstanceOf(c)) ? 1 : 0);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200525 ADVANCE(2);
526 }
527 }
528 HANDLE_INSTRUCTION_END();
529
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700530 HANDLE_INSTRUCTION_START(ARRAY_LENGTH) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200531 Object* array = shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700532 if (UNLIKELY(array == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000533 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200534 HANDLE_PENDING_EXCEPTION();
535 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200536 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), array->AsArray()->GetLength());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200537 ADVANCE(1);
538 }
539 }
540 HANDLE_INSTRUCTION_END();
541
542 HANDLE_INSTRUCTION_START(NEW_INSTANCE) {
Jeff Hao848f70a2014-01-15 13:49:50 -0800543 Object* obj = nullptr;
544 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
545 self, false, do_access_check);
546 if (LIKELY(c != nullptr)) {
547 if (UNLIKELY(c->IsStringClass())) {
548 gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
549 mirror::SetStringCountVisitor visitor(0);
550 obj = String::Alloc<true>(self, 0, allocator_type, visitor);
551 } else {
552 obj = AllocObjectFromCode<do_access_check, true>(
553 inst->VRegB_21c(), shadow_frame.GetMethod(), self,
554 Runtime::Current()->GetHeap()->GetCurrentAllocator());
555 }
556 }
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700557 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200558 HANDLE_PENDING_EXCEPTION();
559 } else {
Sebastien Hertz4e99b3d2014-06-24 14:35:40 +0200560 obj->GetClass()->AssertInitializedOrInitializingInThread(self);
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700561 // Don't allow finalizable objects to be allocated during a transaction since these can't be
562 // finalized without a started runtime.
563 if (transaction_active && obj->GetClass()->IsFinalizable()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +0200564 AbortTransactionF(self, "Allocating finalizable object in transaction: %s",
565 PrettyTypeOf(obj).c_str());
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700566 HANDLE_PENDING_EXCEPTION();
567 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200568 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200569 ADVANCE(2);
570 }
571 }
572 HANDLE_INSTRUCTION_END();
573
574 HANDLE_INSTRUCTION_START(NEW_ARRAY) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200575 int32_t length = shadow_frame.GetVReg(inst->VRegB_22c(inst_data));
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800576 Object* obj = AllocArrayFromCode<do_access_check, true>(
Andreas Gampe1cc7dba2014-12-17 18:43:01 -0800577 inst->VRegC_22c(), length, shadow_frame.GetMethod(), self,
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800578 Runtime::Current()->GetHeap()->GetCurrentAllocator());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700579 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200580 HANDLE_PENDING_EXCEPTION();
581 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200582 shadow_frame.SetVRegReference(inst->VRegA_22c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200583 ADVANCE(2);
584 }
585 }
586 HANDLE_INSTRUCTION_END();
587
588 HANDLE_INSTRUCTION_START(FILLED_NEW_ARRAY) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100589 bool success =
590 DoFilledNewArray<false, do_access_check, transaction_active>(inst, shadow_frame,
591 self, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200592 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
593 }
594 HANDLE_INSTRUCTION_END();
595
596 HANDLE_INSTRUCTION_START(FILLED_NEW_ARRAY_RANGE) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100597 bool success =
598 DoFilledNewArray<true, do_access_check, transaction_active>(inst, shadow_frame,
599 self, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200600 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
601 }
602 HANDLE_INSTRUCTION_END();
603
604 HANDLE_INSTRUCTION_START(FILL_ARRAY_DATA) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200605 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_31t(inst_data));
Ian Rogers832336b2014-10-08 15:35:22 -0700606 const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t();
607 const Instruction::ArrayDataPayload* payload =
608 reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr);
609 bool success = FillArrayData(obj, payload);
610 if (transaction_active && success) {
611 RecordArrayElementsInTransaction(obj->AsArray(), payload->element_count);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200612 }
Ian Rogers832336b2014-10-08 15:35:22 -0700613 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200614 }
615 HANDLE_INSTRUCTION_END();
616
617 HANDLE_INSTRUCTION_START(THROW) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200618 Object* exception = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700619 if (UNLIKELY(exception == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000620 ThrowNullPointerException("throw with null exception");
Jeff Haoa3faaf42013-09-03 19:07:00 -0700621 } else if (do_assignability_check && !exception->GetClass()->IsThrowableClass()) {
622 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700623 std::string temp;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000624 self->ThrowNewExceptionF("Ljava/lang/VirtualMachineError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700625 "Throwing '%s' that is not instance of Throwable",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700626 exception->GetClass()->GetDescriptor(&temp));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200627 } else {
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000628 self->SetException(exception->AsThrowable());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200629 }
630 HANDLE_PENDING_EXCEPTION();
631 }
632 HANDLE_INSTRUCTION_END();
633
634 HANDLE_INSTRUCTION_START(GOTO) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200635 int8_t offset = inst->VRegA_10t(inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000636 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200637 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200638 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700639 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200640 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200641 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200642 }
643 ADVANCE(offset);
644 }
645 HANDLE_INSTRUCTION_END();
646
647 HANDLE_INSTRUCTION_START(GOTO_16) {
648 int16_t offset = inst->VRegA_20t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000649 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200650 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200651 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700652 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200653 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200654 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200655 }
656 ADVANCE(offset);
657 }
658 HANDLE_INSTRUCTION_END();
659
660 HANDLE_INSTRUCTION_START(GOTO_32) {
661 int32_t offset = inst->VRegA_30t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000662 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200663 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200664 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700665 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200666 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200667 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200668 }
669 ADVANCE(offset);
670 }
671 HANDLE_INSTRUCTION_END();
672
673 HANDLE_INSTRUCTION_START(PACKED_SWITCH) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200674 int32_t offset = DoPackedSwitch(inst, shadow_frame, inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000675 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200676 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200677 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700678 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200679 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200680 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200681 }
682 ADVANCE(offset);
683 }
684 HANDLE_INSTRUCTION_END();
685
686 HANDLE_INSTRUCTION_START(SPARSE_SWITCH) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200687 int32_t offset = DoSparseSwitch(inst, shadow_frame, inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000688 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200689 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200690 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700691 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200692 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200693 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200694 }
695 ADVANCE(offset);
696 }
697 HANDLE_INSTRUCTION_END();
698
Ian Rogers647b1a82014-10-10 11:02:11 -0700699#if defined(__clang__)
700#pragma clang diagnostic push
701#pragma clang diagnostic ignored "-Wfloat-equal"
702#endif
703
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200704 HANDLE_INSTRUCTION_START(CMPL_FLOAT) {
705 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
706 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
707 int32_t result;
708 if (val1 > val2) {
709 result = 1;
710 } else if (val1 == val2) {
711 result = 0;
712 } else {
713 result = -1;
714 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200715 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200716 ADVANCE(2);
717 }
718 HANDLE_INSTRUCTION_END();
719
720 HANDLE_INSTRUCTION_START(CMPG_FLOAT) {
721 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
722 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
723 int32_t result;
724 if (val1 < val2) {
725 result = -1;
726 } else if (val1 == val2) {
727 result = 0;
728 } else {
729 result = 1;
730 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200731 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200732 ADVANCE(2);
733 }
734 HANDLE_INSTRUCTION_END();
735
736 HANDLE_INSTRUCTION_START(CMPL_DOUBLE) {
737 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
738 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
739 int32_t result;
740 if (val1 > val2) {
741 result = 1;
742 } else if (val1 == val2) {
743 result = 0;
744 } else {
745 result = -1;
746 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200747 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200748 ADVANCE(2);
749 }
750 HANDLE_INSTRUCTION_END();
751
752 HANDLE_INSTRUCTION_START(CMPG_DOUBLE) {
753 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
754 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
755 int32_t result;
756 if (val1 < val2) {
757 result = -1;
758 } else if (val1 == val2) {
759 result = 0;
760 } else {
761 result = 1;
762 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200763 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200764 ADVANCE(2);
765 }
766 HANDLE_INSTRUCTION_END();
767
Ian Rogers647b1a82014-10-10 11:02:11 -0700768#if defined(__clang__)
769#pragma clang diagnostic pop
770#endif
771
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200772 HANDLE_INSTRUCTION_START(CMP_LONG) {
773 int64_t val1 = shadow_frame.GetVRegLong(inst->VRegB_23x());
774 int64_t val2 = shadow_frame.GetVRegLong(inst->VRegC_23x());
775 int32_t result;
776 if (val1 > val2) {
777 result = 1;
778 } else if (val1 == val2) {
779 result = 0;
780 } else {
781 result = -1;
782 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200783 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200784 ADVANCE(2);
785 }
786 HANDLE_INSTRUCTION_END();
787
788 HANDLE_INSTRUCTION_START(IF_EQ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200789 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) == shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200790 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000791 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200792 if (IsBackwardBranch(offset)) {
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 {
800 ADVANCE(2);
801 }
802 }
803 HANDLE_INSTRUCTION_END();
804
805 HANDLE_INSTRUCTION_START(IF_NE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700806 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) !=
807 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200808 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000809 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200810 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200811 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700812 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200813 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200814 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200815 }
816 ADVANCE(offset);
817 } else {
818 ADVANCE(2);
819 }
820 }
821 HANDLE_INSTRUCTION_END();
822
823 HANDLE_INSTRUCTION_START(IF_LT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700824 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <
825 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200826 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000827 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200828 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200829 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700830 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200831 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200832 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200833 }
834 ADVANCE(offset);
835 } else {
836 ADVANCE(2);
837 }
838 }
839 HANDLE_INSTRUCTION_END();
840
841 HANDLE_INSTRUCTION_START(IF_GE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700842 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >=
843 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200844 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000845 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200846 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200847 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700848 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200849 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200850 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200851 }
852 ADVANCE(offset);
853 } else {
854 ADVANCE(2);
855 }
856 }
857 HANDLE_INSTRUCTION_END();
858
859 HANDLE_INSTRUCTION_START(IF_GT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700860 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >
861 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200862 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000863 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200864 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200865 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700866 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200867 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200868 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200869 }
870 ADVANCE(offset);
871 } else {
872 ADVANCE(2);
873 }
874 }
875 HANDLE_INSTRUCTION_END();
876
877 HANDLE_INSTRUCTION_START(IF_LE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700878 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <=
879 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200880 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000881 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200882 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200883 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700884 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200885 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200886 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200887 }
888 ADVANCE(offset);
889 } else {
890 ADVANCE(2);
891 }
892 }
893 HANDLE_INSTRUCTION_END();
894
895 HANDLE_INSTRUCTION_START(IF_EQZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200896 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) == 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200897 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000898 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200899 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200900 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700901 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200902 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200903 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200904 }
905 ADVANCE(offset);
906 } else {
907 ADVANCE(2);
908 }
909 }
910 HANDLE_INSTRUCTION_END();
911
912 HANDLE_INSTRUCTION_START(IF_NEZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200913 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) != 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200914 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000915 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200916 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200917 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700918 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200919 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200920 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200921 }
922 ADVANCE(offset);
923 } else {
924 ADVANCE(2);
925 }
926 }
927 HANDLE_INSTRUCTION_END();
928
929 HANDLE_INSTRUCTION_START(IF_LTZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200930 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) < 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200931 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000932 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200933 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200934 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700935 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200936 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200937 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200938 }
939 ADVANCE(offset);
940 } else {
941 ADVANCE(2);
942 }
943 }
944 HANDLE_INSTRUCTION_END();
945
946 HANDLE_INSTRUCTION_START(IF_GEZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200947 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) >= 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200948 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000949 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200950 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200951 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700952 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200953 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200954 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200955 }
956 ADVANCE(offset);
957 } else {
958 ADVANCE(2);
959 }
960 }
961 HANDLE_INSTRUCTION_END();
962
963 HANDLE_INSTRUCTION_START(IF_GTZ) {
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)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200968 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700969 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200970 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200971 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200972 }
973 ADVANCE(offset);
974 } else {
975 ADVANCE(2);
976 }
977 }
978 HANDLE_INSTRUCTION_END();
979
980 HANDLE_INSTRUCTION_START(IF_LEZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200981 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) <= 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200982 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000983 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200984 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200985 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700986 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200987 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200988 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200989 }
990 ADVANCE(offset);
991 } else {
992 ADVANCE(2);
993 }
994 }
995 HANDLE_INSTRUCTION_END();
996
997 HANDLE_INSTRUCTION_START(AGET_BOOLEAN) {
998 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700999 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001000 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001001 HANDLE_PENDING_EXCEPTION();
1002 } else {
1003 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1004 BooleanArray* array = a->AsBooleanArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001005 if (LIKELY(array->CheckIsValidIndex(index))) {
1006 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001007 ADVANCE(2);
1008 } else {
1009 HANDLE_PENDING_EXCEPTION();
1010 }
1011 }
1012 }
1013 HANDLE_INSTRUCTION_END();
1014
1015 HANDLE_INSTRUCTION_START(AGET_BYTE) {
1016 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001017 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001018 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001019 HANDLE_PENDING_EXCEPTION();
1020 } else {
1021 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1022 ByteArray* array = a->AsByteArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001023 if (LIKELY(array->CheckIsValidIndex(index))) {
1024 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001025 ADVANCE(2);
1026 } else {
1027 HANDLE_PENDING_EXCEPTION();
1028 }
1029 }
1030 }
1031 HANDLE_INSTRUCTION_END();
1032
1033 HANDLE_INSTRUCTION_START(AGET_CHAR) {
1034 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001035 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001036 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001037 HANDLE_PENDING_EXCEPTION();
1038 } else {
1039 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1040 CharArray* array = a->AsCharArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001041 if (LIKELY(array->CheckIsValidIndex(index))) {
1042 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001043 ADVANCE(2);
1044 } else {
1045 HANDLE_PENDING_EXCEPTION();
1046 }
1047 }
1048 }
1049 HANDLE_INSTRUCTION_END();
1050
1051 HANDLE_INSTRUCTION_START(AGET_SHORT) {
1052 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001053 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001054 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001055 HANDLE_PENDING_EXCEPTION();
1056 } else {
1057 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1058 ShortArray* array = a->AsShortArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001059 if (LIKELY(array->CheckIsValidIndex(index))) {
1060 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001061 ADVANCE(2);
1062 } else {
1063 HANDLE_PENDING_EXCEPTION();
1064 }
1065 }
1066 }
1067 HANDLE_INSTRUCTION_END();
1068
1069 HANDLE_INSTRUCTION_START(AGET) {
1070 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001071 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001072 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001073 HANDLE_PENDING_EXCEPTION();
1074 } else {
1075 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001076 DCHECK(a->IsIntArray() || a->IsFloatArray()) << PrettyTypeOf(a);
1077 auto* array = down_cast<IntArray*>(a);
Sebastien Hertzabff6432014-01-27 18:01:39 +01001078 if (LIKELY(array->CheckIsValidIndex(index))) {
1079 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001080 ADVANCE(2);
1081 } else {
1082 HANDLE_PENDING_EXCEPTION();
1083 }
1084 }
1085 }
1086 HANDLE_INSTRUCTION_END();
1087
1088 HANDLE_INSTRUCTION_START(AGET_WIDE) {
1089 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001090 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001091 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001092 HANDLE_PENDING_EXCEPTION();
1093 } else {
1094 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001095 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << PrettyTypeOf(a);
1096 auto* array = down_cast<LongArray*>(a);
Sebastien Hertzabff6432014-01-27 18:01:39 +01001097 if (LIKELY(array->CheckIsValidIndex(index))) {
1098 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001099 ADVANCE(2);
1100 } else {
1101 HANDLE_PENDING_EXCEPTION();
1102 }
1103 }
1104 }
1105 HANDLE_INSTRUCTION_END();
1106
1107 HANDLE_INSTRUCTION_START(AGET_OBJECT) {
1108 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001109 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001110 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001111 HANDLE_PENDING_EXCEPTION();
1112 } else {
1113 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1114 ObjectArray<Object>* array = a->AsObjectArray<Object>();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001115 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001116 shadow_frame.SetVRegReference(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001117 ADVANCE(2);
1118 } else {
1119 HANDLE_PENDING_EXCEPTION();
1120 }
1121 }
1122 }
1123 HANDLE_INSTRUCTION_END();
1124
1125 HANDLE_INSTRUCTION_START(APUT_BOOLEAN) {
1126 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001127 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001128 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001129 HANDLE_PENDING_EXCEPTION();
1130 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001131 uint8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001132 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1133 BooleanArray* array = a->AsBooleanArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001134 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001135 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001136 ADVANCE(2);
1137 } else {
1138 HANDLE_PENDING_EXCEPTION();
1139 }
1140 }
1141 }
1142 HANDLE_INSTRUCTION_END();
1143
1144 HANDLE_INSTRUCTION_START(APUT_BYTE) {
1145 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001146 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001147 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001148 HANDLE_PENDING_EXCEPTION();
1149 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001150 int8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001151 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1152 ByteArray* array = a->AsByteArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001153 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001154 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001155 ADVANCE(2);
1156 } else {
1157 HANDLE_PENDING_EXCEPTION();
1158 }
1159 }
1160 }
1161 HANDLE_INSTRUCTION_END();
1162
1163 HANDLE_INSTRUCTION_START(APUT_CHAR) {
1164 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001165 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001166 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001167 HANDLE_PENDING_EXCEPTION();
1168 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001169 uint16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001170 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1171 CharArray* array = a->AsCharArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001172 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001173 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001174 ADVANCE(2);
1175 } else {
1176 HANDLE_PENDING_EXCEPTION();
1177 }
1178 }
1179 }
1180 HANDLE_INSTRUCTION_END();
1181
1182 HANDLE_INSTRUCTION_START(APUT_SHORT) {
1183 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001184 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001185 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001186 HANDLE_PENDING_EXCEPTION();
1187 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001188 int16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001189 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1190 ShortArray* array = a->AsShortArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001191 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001192 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001193 ADVANCE(2);
1194 } else {
1195 HANDLE_PENDING_EXCEPTION();
1196 }
1197 }
1198 }
1199 HANDLE_INSTRUCTION_END();
1200
1201 HANDLE_INSTRUCTION_START(APUT) {
1202 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001203 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001204 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001205 HANDLE_PENDING_EXCEPTION();
1206 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001207 int32_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001208 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001209 DCHECK(a->IsIntArray() || a->IsFloatArray()) << PrettyTypeOf(a);
1210 auto* array = down_cast<IntArray*>(a);
Sebastien Hertzabff6432014-01-27 18:01:39 +01001211 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001212 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001213 ADVANCE(2);
1214 } else {
1215 HANDLE_PENDING_EXCEPTION();
1216 }
1217 }
1218 }
1219 HANDLE_INSTRUCTION_END();
1220
1221 HANDLE_INSTRUCTION_START(APUT_WIDE) {
1222 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001223 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001224 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001225 HANDLE_PENDING_EXCEPTION();
1226 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001227 int64_t val = shadow_frame.GetVRegLong(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001228 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001229 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << PrettyTypeOf(a);
1230 auto* array = down_cast<LongArray*>(a);
Sebastien Hertzabff6432014-01-27 18:01:39 +01001231 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001232 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001233 ADVANCE(2);
1234 } else {
1235 HANDLE_PENDING_EXCEPTION();
1236 }
1237 }
1238 }
1239 HANDLE_INSTRUCTION_END();
1240
1241 HANDLE_INSTRUCTION_START(APUT_OBJECT) {
1242 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001243 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001244 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001245 HANDLE_PENDING_EXCEPTION();
1246 } else {
1247 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001248 Object* val = shadow_frame.GetVRegReference(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001249 ObjectArray<Object>* array = a->AsObjectArray<Object>();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001250 if (LIKELY(array->CheckIsValidIndex(index) && array->CheckAssignable(val))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001251 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001252 ADVANCE(2);
1253 } else {
1254 HANDLE_PENDING_EXCEPTION();
1255 }
1256 }
1257 }
1258 HANDLE_INSTRUCTION_END();
1259
1260 HANDLE_INSTRUCTION_START(IGET_BOOLEAN) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001261 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimBoolean, do_access_check>(
1262 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001263 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1264 }
1265 HANDLE_INSTRUCTION_END();
1266
1267 HANDLE_INSTRUCTION_START(IGET_BYTE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001268 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimByte, do_access_check>(
1269 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001270 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1271 }
1272 HANDLE_INSTRUCTION_END();
1273
1274 HANDLE_INSTRUCTION_START(IGET_CHAR) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001275 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimChar, do_access_check>(
1276 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001277 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1278 }
1279 HANDLE_INSTRUCTION_END();
1280
1281 HANDLE_INSTRUCTION_START(IGET_SHORT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001282 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimShort, do_access_check>(
1283 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001284 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1285 }
1286 HANDLE_INSTRUCTION_END();
1287
1288 HANDLE_INSTRUCTION_START(IGET) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001289 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimInt, do_access_check>(
1290 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001291 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1292 }
1293 HANDLE_INSTRUCTION_END();
1294
1295 HANDLE_INSTRUCTION_START(IGET_WIDE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001296 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimLong, do_access_check>(
1297 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001298 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1299 }
1300 HANDLE_INSTRUCTION_END();
1301
1302 HANDLE_INSTRUCTION_START(IGET_OBJECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001303 bool success = DoFieldGet<InstanceObjectRead, Primitive::kPrimNot, do_access_check>(
1304 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001305 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1306 }
1307 HANDLE_INSTRUCTION_END();
1308
1309 HANDLE_INSTRUCTION_START(IGET_QUICK) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001310 bool success = DoIGetQuick<Primitive::kPrimInt>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001311 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1312 }
1313 HANDLE_INSTRUCTION_END();
1314
Mathieu Chartierffc605c2014-12-10 10:35:44 -08001315 HANDLE_INSTRUCTION_START(IGET_BOOLEAN_QUICK) {
1316 bool success = DoIGetQuick<Primitive::kPrimBoolean>(shadow_frame, inst, inst_data);
1317 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1318 }
1319 HANDLE_INSTRUCTION_END();
1320
1321 HANDLE_INSTRUCTION_START(IGET_BYTE_QUICK) {
1322 bool success = DoIGetQuick<Primitive::kPrimByte>(shadow_frame, inst, inst_data);
1323 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1324 }
1325 HANDLE_INSTRUCTION_END();
1326
1327 HANDLE_INSTRUCTION_START(IGET_CHAR_QUICK) {
1328 bool success = DoIGetQuick<Primitive::kPrimChar>(shadow_frame, inst, inst_data);
1329 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1330 }
1331 HANDLE_INSTRUCTION_END();
1332
1333 HANDLE_INSTRUCTION_START(IGET_SHORT_QUICK) {
1334 bool success = DoIGetQuick<Primitive::kPrimShort>(shadow_frame, inst, inst_data);
1335 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1336 }
1337 HANDLE_INSTRUCTION_END();
1338
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001339 HANDLE_INSTRUCTION_START(IGET_WIDE_QUICK) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001340 bool success = DoIGetQuick<Primitive::kPrimLong>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001341 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1342 }
1343 HANDLE_INSTRUCTION_END();
1344
1345 HANDLE_INSTRUCTION_START(IGET_OBJECT_QUICK) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001346 bool success = DoIGetQuick<Primitive::kPrimNot>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001347 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1348 }
1349 HANDLE_INSTRUCTION_END();
1350
1351 HANDLE_INSTRUCTION_START(SGET_BOOLEAN) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001352 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimBoolean, do_access_check>(
1353 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001354 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1355 }
1356 HANDLE_INSTRUCTION_END();
1357
1358 HANDLE_INSTRUCTION_START(SGET_BYTE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001359 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimByte, do_access_check>(
1360 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001361 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1362 }
1363 HANDLE_INSTRUCTION_END();
1364
1365 HANDLE_INSTRUCTION_START(SGET_CHAR) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001366 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimChar, do_access_check>(
1367 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001368 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1369 }
1370 HANDLE_INSTRUCTION_END();
1371
1372 HANDLE_INSTRUCTION_START(SGET_SHORT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001373 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimShort, do_access_check>(
1374 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001375 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1376 }
1377 HANDLE_INSTRUCTION_END();
1378
1379 HANDLE_INSTRUCTION_START(SGET) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001380 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimInt, do_access_check>(
1381 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001382 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1383 }
1384 HANDLE_INSTRUCTION_END();
1385
1386 HANDLE_INSTRUCTION_START(SGET_WIDE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001387 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimLong, do_access_check>(
1388 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001389 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1390 }
1391 HANDLE_INSTRUCTION_END();
1392
1393 HANDLE_INSTRUCTION_START(SGET_OBJECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001394 bool success = DoFieldGet<StaticObjectRead, Primitive::kPrimNot, do_access_check>(
1395 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001396 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1397 }
1398 HANDLE_INSTRUCTION_END();
1399
1400 HANDLE_INSTRUCTION_START(IPUT_BOOLEAN) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001401 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1402 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001403 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1404 }
1405 HANDLE_INSTRUCTION_END();
1406
1407 HANDLE_INSTRUCTION_START(IPUT_BYTE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001408 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimByte, do_access_check,
1409 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001410 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1411 }
1412 HANDLE_INSTRUCTION_END();
1413
1414 HANDLE_INSTRUCTION_START(IPUT_CHAR) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001415 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimChar, do_access_check,
1416 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001417 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1418 }
1419 HANDLE_INSTRUCTION_END();
1420
1421 HANDLE_INSTRUCTION_START(IPUT_SHORT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001422 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimShort, do_access_check,
1423 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001424 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1425 }
1426 HANDLE_INSTRUCTION_END();
1427
1428 HANDLE_INSTRUCTION_START(IPUT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001429 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimInt, do_access_check,
1430 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001431 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1432 }
1433 HANDLE_INSTRUCTION_END();
1434
1435 HANDLE_INSTRUCTION_START(IPUT_WIDE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001436 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimLong, do_access_check,
1437 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001438 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1439 }
1440 HANDLE_INSTRUCTION_END();
1441
1442 HANDLE_INSTRUCTION_START(IPUT_OBJECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001443 bool success = DoFieldPut<InstanceObjectWrite, Primitive::kPrimNot, do_access_check,
1444 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001445 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1446 }
1447 HANDLE_INSTRUCTION_END();
1448
1449 HANDLE_INSTRUCTION_START(IPUT_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001450 bool success = DoIPutQuick<Primitive::kPrimInt, transaction_active>(
1451 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001452 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1453 }
1454 HANDLE_INSTRUCTION_END();
1455
Fred Shih37f05ef2014-07-16 18:38:08 -07001456 HANDLE_INSTRUCTION_START(IPUT_BOOLEAN_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001457 bool success = DoIPutQuick<Primitive::kPrimBoolean, transaction_active>(
1458 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001459 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1460 }
1461 HANDLE_INSTRUCTION_END();
1462
1463 HANDLE_INSTRUCTION_START(IPUT_BYTE_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001464 bool success = DoIPutQuick<Primitive::kPrimByte, transaction_active>(
1465 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001466 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1467 }
1468 HANDLE_INSTRUCTION_END();
1469
1470 HANDLE_INSTRUCTION_START(IPUT_CHAR_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001471 bool success = DoIPutQuick<Primitive::kPrimChar, transaction_active>(
1472 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001473 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1474 }
1475 HANDLE_INSTRUCTION_END();
1476
1477 HANDLE_INSTRUCTION_START(IPUT_SHORT_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001478 bool success = DoIPutQuick<Primitive::kPrimShort, transaction_active>(
1479 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001480 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1481 }
1482 HANDLE_INSTRUCTION_END();
1483
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001484 HANDLE_INSTRUCTION_START(IPUT_WIDE_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001485 bool success = DoIPutQuick<Primitive::kPrimLong, transaction_active>(
1486 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001487 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1488 }
1489 HANDLE_INSTRUCTION_END();
1490
1491 HANDLE_INSTRUCTION_START(IPUT_OBJECT_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001492 bool success = DoIPutQuick<Primitive::kPrimNot, transaction_active>(
1493 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001494 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1495 }
1496 HANDLE_INSTRUCTION_END();
1497
1498 HANDLE_INSTRUCTION_START(SPUT_BOOLEAN) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001499 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1500 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001501 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1502 }
1503 HANDLE_INSTRUCTION_END();
1504
1505 HANDLE_INSTRUCTION_START(SPUT_BYTE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001506 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimByte, do_access_check,
1507 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001508 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1509 }
1510 HANDLE_INSTRUCTION_END();
1511
1512 HANDLE_INSTRUCTION_START(SPUT_CHAR) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001513 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimChar, do_access_check,
1514 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001515 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1516 }
1517 HANDLE_INSTRUCTION_END();
1518
1519 HANDLE_INSTRUCTION_START(SPUT_SHORT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001520 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimShort, do_access_check,
1521 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001522 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1523 }
1524 HANDLE_INSTRUCTION_END();
1525
1526 HANDLE_INSTRUCTION_START(SPUT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001527 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimInt, do_access_check,
1528 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001529 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1530 }
1531 HANDLE_INSTRUCTION_END();
1532
1533 HANDLE_INSTRUCTION_START(SPUT_WIDE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001534 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimLong, do_access_check,
1535 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001536 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1537 }
1538 HANDLE_INSTRUCTION_END();
1539
1540 HANDLE_INSTRUCTION_START(SPUT_OBJECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001541 bool success = DoFieldPut<StaticObjectWrite, Primitive::kPrimNot, do_access_check,
1542 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001543 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1544 }
1545 HANDLE_INSTRUCTION_END();
1546
1547 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001548 bool success = DoInvoke<kVirtual, false, do_access_check>(
1549 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001550 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001551 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1552 }
1553 HANDLE_INSTRUCTION_END();
1554
1555 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001556 bool success = DoInvoke<kVirtual, true, do_access_check>(
1557 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001558 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001559 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1560 }
1561 HANDLE_INSTRUCTION_END();
1562
1563 HANDLE_INSTRUCTION_START(INVOKE_SUPER) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001564 bool success = DoInvoke<kSuper, false, do_access_check>(
1565 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001566 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001567 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1568 }
1569 HANDLE_INSTRUCTION_END();
1570
1571 HANDLE_INSTRUCTION_START(INVOKE_SUPER_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001572 bool success = DoInvoke<kSuper, true, do_access_check>(
1573 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001574 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001575 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1576 }
1577 HANDLE_INSTRUCTION_END();
1578
1579 HANDLE_INSTRUCTION_START(INVOKE_DIRECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001580 bool success = DoInvoke<kDirect, false, do_access_check>(
1581 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001582 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001583 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1584 }
1585 HANDLE_INSTRUCTION_END();
1586
1587 HANDLE_INSTRUCTION_START(INVOKE_DIRECT_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001588 bool success = DoInvoke<kDirect, true, do_access_check>(
1589 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001590 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001591 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1592 }
1593 HANDLE_INSTRUCTION_END();
1594
1595 HANDLE_INSTRUCTION_START(INVOKE_INTERFACE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001596 bool success = DoInvoke<kInterface, false, do_access_check>(
1597 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001598 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001599 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1600 }
1601 HANDLE_INSTRUCTION_END();
1602
1603 HANDLE_INSTRUCTION_START(INVOKE_INTERFACE_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001604 bool success = DoInvoke<kInterface, true, do_access_check>(
1605 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001606 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001607 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1608 }
1609 HANDLE_INSTRUCTION_END();
1610
1611 HANDLE_INSTRUCTION_START(INVOKE_STATIC) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001612 bool success = DoInvoke<kStatic, false, do_access_check>(
1613 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001614 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001615 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1616 }
1617 HANDLE_INSTRUCTION_END();
1618
1619 HANDLE_INSTRUCTION_START(INVOKE_STATIC_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001620 bool success = DoInvoke<kStatic, true, do_access_check>(
1621 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001622 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001623 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1624 }
1625 HANDLE_INSTRUCTION_END();
1626
1627 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001628 bool success = DoInvokeVirtualQuick<false>(
1629 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001630 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001631 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1632 }
1633 HANDLE_INSTRUCTION_END();
1634
1635 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_RANGE_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001636 bool success = DoInvokeVirtualQuick<true>(
1637 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001638 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001639 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1640 }
1641 HANDLE_INSTRUCTION_END();
1642
Igor Murashkin158f35c2015-06-10 15:55:30 -07001643 HANDLE_EXPERIMENTAL_INSTRUCTION_START(INVOKE_LAMBDA) {
1644 bool success = DoInvokeLambda<do_access_check>(self, shadow_frame, inst, inst_data,
1645 &result_register);
1646 UPDATE_HANDLER_TABLE();
1647 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1648 }
1649 HANDLE_EXPERIMENTAL_INSTRUCTION_END();
1650
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001651 HANDLE_INSTRUCTION_START(NEG_INT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001652 shadow_frame.SetVReg(
1653 inst->VRegA_12x(inst_data), -shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001654 ADVANCE(1);
1655 HANDLE_INSTRUCTION_END();
1656
1657 HANDLE_INSTRUCTION_START(NOT_INT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001658 shadow_frame.SetVReg(
1659 inst->VRegA_12x(inst_data), ~shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001660 ADVANCE(1);
1661 HANDLE_INSTRUCTION_END();
1662
1663 HANDLE_INSTRUCTION_START(NEG_LONG)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001664 shadow_frame.SetVRegLong(
1665 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001666 ADVANCE(1);
1667 HANDLE_INSTRUCTION_END();
1668
1669 HANDLE_INSTRUCTION_START(NOT_LONG)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001670 shadow_frame.SetVRegLong(
1671 inst->VRegA_12x(inst_data), ~shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001672 ADVANCE(1);
1673 HANDLE_INSTRUCTION_END();
1674
1675 HANDLE_INSTRUCTION_START(NEG_FLOAT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001676 shadow_frame.SetVRegFloat(
1677 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001678 ADVANCE(1);
1679 HANDLE_INSTRUCTION_END();
1680
1681 HANDLE_INSTRUCTION_START(NEG_DOUBLE)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001682 shadow_frame.SetVRegDouble(
1683 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001684 ADVANCE(1);
1685 HANDLE_INSTRUCTION_END();
1686
1687 HANDLE_INSTRUCTION_START(INT_TO_LONG)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001688 shadow_frame.SetVRegLong(
1689 inst->VRegA_12x(inst_data), shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001690 ADVANCE(1);
1691 HANDLE_INSTRUCTION_END();
1692
1693 HANDLE_INSTRUCTION_START(INT_TO_FLOAT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001694 shadow_frame.SetVRegFloat(
1695 inst->VRegA_12x(inst_data), shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001696 ADVANCE(1);
1697 HANDLE_INSTRUCTION_END();
1698
1699 HANDLE_INSTRUCTION_START(INT_TO_DOUBLE)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001700 shadow_frame.SetVRegDouble(
1701 inst->VRegA_12x(inst_data), shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001702 ADVANCE(1);
1703 HANDLE_INSTRUCTION_END();
1704
1705 HANDLE_INSTRUCTION_START(LONG_TO_INT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001706 shadow_frame.SetVReg(
1707 inst->VRegA_12x(inst_data), shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001708 ADVANCE(1);
1709 HANDLE_INSTRUCTION_END();
1710
1711 HANDLE_INSTRUCTION_START(LONG_TO_FLOAT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001712 shadow_frame.SetVRegFloat(
1713 inst->VRegA_12x(inst_data), shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001714 ADVANCE(1);
1715 HANDLE_INSTRUCTION_END();
1716
1717 HANDLE_INSTRUCTION_START(LONG_TO_DOUBLE)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001718 shadow_frame.SetVRegDouble(
1719 inst->VRegA_12x(inst_data), shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001720 ADVANCE(1);
1721 HANDLE_INSTRUCTION_END();
1722
1723 HANDLE_INSTRUCTION_START(FLOAT_TO_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001724 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001725 int32_t result = art_float_to_integral<int32_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001726 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001727 ADVANCE(1);
1728 }
1729 HANDLE_INSTRUCTION_END();
1730
1731 HANDLE_INSTRUCTION_START(FLOAT_TO_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001732 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001733 int64_t result = art_float_to_integral<int64_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001734 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001735 ADVANCE(1);
1736 }
1737 HANDLE_INSTRUCTION_END();
1738
1739 HANDLE_INSTRUCTION_START(FLOAT_TO_DOUBLE)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001740 shadow_frame.SetVRegDouble(
1741 inst->VRegA_12x(inst_data), shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001742 ADVANCE(1);
1743 HANDLE_INSTRUCTION_END();
1744
1745 HANDLE_INSTRUCTION_START(DOUBLE_TO_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001746 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001747 int32_t result = art_float_to_integral<int32_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001748 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001749 ADVANCE(1);
1750 }
1751 HANDLE_INSTRUCTION_END();
1752
1753 HANDLE_INSTRUCTION_START(DOUBLE_TO_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001754 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001755 int64_t result = art_float_to_integral<int64_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001756 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001757 ADVANCE(1);
1758 }
1759 HANDLE_INSTRUCTION_END();
1760
1761 HANDLE_INSTRUCTION_START(DOUBLE_TO_FLOAT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001762 shadow_frame.SetVRegFloat(
1763 inst->VRegA_12x(inst_data), shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001764 ADVANCE(1);
1765 HANDLE_INSTRUCTION_END();
1766
1767 HANDLE_INSTRUCTION_START(INT_TO_BYTE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001768 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1769 static_cast<int8_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001770 ADVANCE(1);
1771 HANDLE_INSTRUCTION_END();
1772
1773 HANDLE_INSTRUCTION_START(INT_TO_CHAR)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001774 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1775 static_cast<uint16_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001776 ADVANCE(1);
1777 HANDLE_INSTRUCTION_END();
1778
1779 HANDLE_INSTRUCTION_START(INT_TO_SHORT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001780 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1781 static_cast<int16_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001782 ADVANCE(1);
1783 HANDLE_INSTRUCTION_END();
1784
1785 HANDLE_INSTRUCTION_START(ADD_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001786 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001787 SafeAdd(shadow_frame.GetVReg(inst->VRegB_23x()),
1788 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001789 ADVANCE(2);
1790 HANDLE_INSTRUCTION_END();
1791
1792 HANDLE_INSTRUCTION_START(SUB_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001793 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001794 SafeSub(shadow_frame.GetVReg(inst->VRegB_23x()),
1795 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001796 ADVANCE(2);
1797 HANDLE_INSTRUCTION_END();
1798
1799 HANDLE_INSTRUCTION_START(MUL_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001800 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001801 SafeMul(shadow_frame.GetVReg(inst->VRegB_23x()),
1802 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001803 ADVANCE(2);
1804 HANDLE_INSTRUCTION_END();
1805
1806 HANDLE_INSTRUCTION_START(DIV_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001807 bool success = DoIntDivide(shadow_frame, inst->VRegA_23x(inst_data),
1808 shadow_frame.GetVReg(inst->VRegB_23x()),
1809 shadow_frame.GetVReg(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001810 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1811 }
1812 HANDLE_INSTRUCTION_END();
1813
1814 HANDLE_INSTRUCTION_START(REM_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001815 bool success = DoIntRemainder(shadow_frame, inst->VRegA_23x(inst_data),
1816 shadow_frame.GetVReg(inst->VRegB_23x()),
1817 shadow_frame.GetVReg(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001818 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1819 }
1820 HANDLE_INSTRUCTION_END();
1821
1822 HANDLE_INSTRUCTION_START(SHL_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001823 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001824 shadow_frame.GetVReg(inst->VRegB_23x()) <<
1825 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1826 ADVANCE(2);
1827 HANDLE_INSTRUCTION_END();
1828
1829 HANDLE_INSTRUCTION_START(SHR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001830 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001831 shadow_frame.GetVReg(inst->VRegB_23x()) >>
1832 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1833 ADVANCE(2);
1834 HANDLE_INSTRUCTION_END();
1835
1836 HANDLE_INSTRUCTION_START(USHR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001837 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001838 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_23x())) >>
1839 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1840 ADVANCE(2);
1841 HANDLE_INSTRUCTION_END();
1842
1843 HANDLE_INSTRUCTION_START(AND_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001844 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001845 shadow_frame.GetVReg(inst->VRegB_23x()) &
1846 shadow_frame.GetVReg(inst->VRegC_23x()));
1847 ADVANCE(2);
1848 HANDLE_INSTRUCTION_END();
1849
1850 HANDLE_INSTRUCTION_START(OR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001851 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001852 shadow_frame.GetVReg(inst->VRegB_23x()) |
1853 shadow_frame.GetVReg(inst->VRegC_23x()));
1854 ADVANCE(2);
1855 HANDLE_INSTRUCTION_END();
1856
1857 HANDLE_INSTRUCTION_START(XOR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001858 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001859 shadow_frame.GetVReg(inst->VRegB_23x()) ^
1860 shadow_frame.GetVReg(inst->VRegC_23x()));
1861 ADVANCE(2);
1862 HANDLE_INSTRUCTION_END();
1863
1864 HANDLE_INSTRUCTION_START(ADD_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001865 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001866 SafeAdd(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1867 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001868 ADVANCE(2);
1869 HANDLE_INSTRUCTION_END();
1870
1871 HANDLE_INSTRUCTION_START(SUB_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001872 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001873 SafeSub(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1874 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001875 ADVANCE(2);
1876 HANDLE_INSTRUCTION_END();
1877
1878 HANDLE_INSTRUCTION_START(MUL_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001879 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001880 SafeMul(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1881 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001882 ADVANCE(2);
1883 HANDLE_INSTRUCTION_END();
1884
1885 HANDLE_INSTRUCTION_START(DIV_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001886 bool success = DoLongDivide(shadow_frame, inst->VRegA_23x(inst_data),
1887 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1888 shadow_frame.GetVRegLong(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001889 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1890 }
1891 HANDLE_INSTRUCTION_END();
1892
1893 HANDLE_INSTRUCTION_START(REM_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001894 bool success = DoLongRemainder(shadow_frame, inst->VRegA_23x(inst_data),
1895 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1896 shadow_frame.GetVRegLong(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001897 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1898 }
1899 HANDLE_INSTRUCTION_END();
1900
1901 HANDLE_INSTRUCTION_START(AND_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001902 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001903 shadow_frame.GetVRegLong(inst->VRegB_23x()) &
1904 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1905 ADVANCE(2);
1906 HANDLE_INSTRUCTION_END();
1907
1908 HANDLE_INSTRUCTION_START(OR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001909 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001910 shadow_frame.GetVRegLong(inst->VRegB_23x()) |
1911 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1912 ADVANCE(2);
1913 HANDLE_INSTRUCTION_END();
1914
1915 HANDLE_INSTRUCTION_START(XOR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001916 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001917 shadow_frame.GetVRegLong(inst->VRegB_23x()) ^
1918 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1919 ADVANCE(2);
1920 HANDLE_INSTRUCTION_END();
1921
1922 HANDLE_INSTRUCTION_START(SHL_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001923 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001924 shadow_frame.GetVRegLong(inst->VRegB_23x()) <<
1925 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1926 ADVANCE(2);
1927 HANDLE_INSTRUCTION_END();
1928
1929 HANDLE_INSTRUCTION_START(SHR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001930 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001931 shadow_frame.GetVRegLong(inst->VRegB_23x()) >>
1932 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1933 ADVANCE(2);
1934 HANDLE_INSTRUCTION_END();
1935
1936 HANDLE_INSTRUCTION_START(USHR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001937 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001938 static_cast<uint64_t>(shadow_frame.GetVRegLong(inst->VRegB_23x())) >>
1939 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1940 ADVANCE(2);
1941 HANDLE_INSTRUCTION_END();
1942
1943 HANDLE_INSTRUCTION_START(ADD_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001944 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001945 shadow_frame.GetVRegFloat(inst->VRegB_23x()) +
1946 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1947 ADVANCE(2);
1948 HANDLE_INSTRUCTION_END();
1949
1950 HANDLE_INSTRUCTION_START(SUB_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001951 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001952 shadow_frame.GetVRegFloat(inst->VRegB_23x()) -
1953 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1954 ADVANCE(2);
1955 HANDLE_INSTRUCTION_END();
1956
1957 HANDLE_INSTRUCTION_START(MUL_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001958 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001959 shadow_frame.GetVRegFloat(inst->VRegB_23x()) *
1960 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1961 ADVANCE(2);
1962 HANDLE_INSTRUCTION_END();
1963
1964 HANDLE_INSTRUCTION_START(DIV_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001965 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001966 shadow_frame.GetVRegFloat(inst->VRegB_23x()) /
1967 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1968 ADVANCE(2);
1969 HANDLE_INSTRUCTION_END();
1970
1971 HANDLE_INSTRUCTION_START(REM_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001972 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001973 fmodf(shadow_frame.GetVRegFloat(inst->VRegB_23x()),
1974 shadow_frame.GetVRegFloat(inst->VRegC_23x())));
1975 ADVANCE(2);
1976 HANDLE_INSTRUCTION_END();
1977
1978 HANDLE_INSTRUCTION_START(ADD_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001979 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001980 shadow_frame.GetVRegDouble(inst->VRegB_23x()) +
1981 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1982 ADVANCE(2);
1983 HANDLE_INSTRUCTION_END();
1984
1985 HANDLE_INSTRUCTION_START(SUB_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001986 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001987 shadow_frame.GetVRegDouble(inst->VRegB_23x()) -
1988 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1989 ADVANCE(2);
1990 HANDLE_INSTRUCTION_END();
1991
1992 HANDLE_INSTRUCTION_START(MUL_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001993 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001994 shadow_frame.GetVRegDouble(inst->VRegB_23x()) *
1995 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1996 ADVANCE(2);
1997 HANDLE_INSTRUCTION_END();
1998
1999 HANDLE_INSTRUCTION_START(DIV_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002000 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002001 shadow_frame.GetVRegDouble(inst->VRegB_23x()) /
2002 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
2003 ADVANCE(2);
2004 HANDLE_INSTRUCTION_END();
2005
2006 HANDLE_INSTRUCTION_START(REM_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002007 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002008 fmod(shadow_frame.GetVRegDouble(inst->VRegB_23x()),
2009 shadow_frame.GetVRegDouble(inst->VRegC_23x())));
2010 ADVANCE(2);
2011 HANDLE_INSTRUCTION_END();
2012
2013 HANDLE_INSTRUCTION_START(ADD_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002014 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002015 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002016 SafeAdd(shadow_frame.GetVReg(vregA),
2017 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002018 ADVANCE(1);
2019 }
2020 HANDLE_INSTRUCTION_END();
2021
2022 HANDLE_INSTRUCTION_START(SUB_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002023 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002024 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002025 SafeSub(shadow_frame.GetVReg(vregA),
2026 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002027 ADVANCE(1);
2028 }
2029 HANDLE_INSTRUCTION_END();
2030
2031 HANDLE_INSTRUCTION_START(MUL_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002032 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002033 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002034 SafeMul(shadow_frame.GetVReg(vregA),
2035 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002036 ADVANCE(1);
2037 }
2038 HANDLE_INSTRUCTION_END();
2039
2040 HANDLE_INSTRUCTION_START(DIV_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002041 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002042 bool success = DoIntDivide(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002043 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002044 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2045 }
2046 HANDLE_INSTRUCTION_END();
2047
2048 HANDLE_INSTRUCTION_START(REM_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002049 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002050 bool success = DoIntRemainder(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002051 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002052 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2053 }
2054 HANDLE_INSTRUCTION_END();
2055
2056 HANDLE_INSTRUCTION_START(SHL_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002057 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002058 shadow_frame.SetVReg(vregA,
2059 shadow_frame.GetVReg(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002060 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002061 ADVANCE(1);
2062 }
2063 HANDLE_INSTRUCTION_END();
2064
2065 HANDLE_INSTRUCTION_START(SHR_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002066 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002067 shadow_frame.SetVReg(vregA,
2068 shadow_frame.GetVReg(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002069 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002070 ADVANCE(1);
2071 }
2072 HANDLE_INSTRUCTION_END();
2073
2074 HANDLE_INSTRUCTION_START(USHR_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002075 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002076 shadow_frame.SetVReg(vregA,
2077 static_cast<uint32_t>(shadow_frame.GetVReg(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002078 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002079 ADVANCE(1);
2080 }
2081 HANDLE_INSTRUCTION_END();
2082
2083 HANDLE_INSTRUCTION_START(AND_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002084 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002085 shadow_frame.SetVReg(vregA,
2086 shadow_frame.GetVReg(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002087 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002088 ADVANCE(1);
2089 }
2090 HANDLE_INSTRUCTION_END();
2091
2092 HANDLE_INSTRUCTION_START(OR_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002093 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002094 shadow_frame.SetVReg(vregA,
2095 shadow_frame.GetVReg(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002096 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002097 ADVANCE(1);
2098 }
2099 HANDLE_INSTRUCTION_END();
2100
2101 HANDLE_INSTRUCTION_START(XOR_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002102 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002103 shadow_frame.SetVReg(vregA,
2104 shadow_frame.GetVReg(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002105 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002106 ADVANCE(1);
2107 }
2108 HANDLE_INSTRUCTION_END();
2109
2110 HANDLE_INSTRUCTION_START(ADD_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002111 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002112 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002113 SafeAdd(shadow_frame.GetVRegLong(vregA),
2114 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002115 ADVANCE(1);
2116 }
2117 HANDLE_INSTRUCTION_END();
2118
2119 HANDLE_INSTRUCTION_START(SUB_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002120 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002121 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002122 SafeSub(shadow_frame.GetVRegLong(vregA),
2123 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002124 ADVANCE(1);
2125 }
2126 HANDLE_INSTRUCTION_END();
2127
2128 HANDLE_INSTRUCTION_START(MUL_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002129 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002130 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002131 SafeMul(shadow_frame.GetVRegLong(vregA),
2132 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002133 ADVANCE(1);
2134 }
2135 HANDLE_INSTRUCTION_END();
2136
2137 HANDLE_INSTRUCTION_START(DIV_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002138 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002139 bool success = DoLongDivide(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002140 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002141 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2142 }
2143 HANDLE_INSTRUCTION_END();
2144
2145 HANDLE_INSTRUCTION_START(REM_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002146 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002147 bool success = DoLongRemainder(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002148 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002149 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2150 }
2151 HANDLE_INSTRUCTION_END();
2152
2153 HANDLE_INSTRUCTION_START(AND_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002154 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002155 shadow_frame.SetVRegLong(vregA,
2156 shadow_frame.GetVRegLong(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002157 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002158 ADVANCE(1);
2159 }
2160 HANDLE_INSTRUCTION_END();
2161
2162 HANDLE_INSTRUCTION_START(OR_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002163 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002164 shadow_frame.SetVRegLong(vregA,
2165 shadow_frame.GetVRegLong(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002166 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002167 ADVANCE(1);
2168 }
2169 HANDLE_INSTRUCTION_END();
2170
2171 HANDLE_INSTRUCTION_START(XOR_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002172 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002173 shadow_frame.SetVRegLong(vregA,
2174 shadow_frame.GetVRegLong(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002175 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002176 ADVANCE(1);
2177 }
2178 HANDLE_INSTRUCTION_END();
2179
2180 HANDLE_INSTRUCTION_START(SHL_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002181 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002182 shadow_frame.SetVRegLong(vregA,
2183 shadow_frame.GetVRegLong(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002184 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002185 ADVANCE(1);
2186 }
2187 HANDLE_INSTRUCTION_END();
2188
2189 HANDLE_INSTRUCTION_START(SHR_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002190 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002191 shadow_frame.SetVRegLong(vregA,
2192 shadow_frame.GetVRegLong(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002193 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002194 ADVANCE(1);
2195 }
2196 HANDLE_INSTRUCTION_END();
2197
2198 HANDLE_INSTRUCTION_START(USHR_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002199 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002200 shadow_frame.SetVRegLong(vregA,
2201 static_cast<uint64_t>(shadow_frame.GetVRegLong(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002202 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002203 ADVANCE(1);
2204 }
2205 HANDLE_INSTRUCTION_END();
2206
2207 HANDLE_INSTRUCTION_START(ADD_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002208 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002209 shadow_frame.SetVRegFloat(vregA,
2210 shadow_frame.GetVRegFloat(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002211 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002212 ADVANCE(1);
2213 }
2214 HANDLE_INSTRUCTION_END();
2215
2216 HANDLE_INSTRUCTION_START(SUB_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002217 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002218 shadow_frame.SetVRegFloat(vregA,
2219 shadow_frame.GetVRegFloat(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002220 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002221 ADVANCE(1);
2222 }
2223 HANDLE_INSTRUCTION_END();
2224
2225 HANDLE_INSTRUCTION_START(MUL_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002226 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002227 shadow_frame.SetVRegFloat(vregA,
2228 shadow_frame.GetVRegFloat(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002229 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002230 ADVANCE(1);
2231 }
2232 HANDLE_INSTRUCTION_END();
2233
2234 HANDLE_INSTRUCTION_START(DIV_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002235 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002236 shadow_frame.SetVRegFloat(vregA,
2237 shadow_frame.GetVRegFloat(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002238 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002239 ADVANCE(1);
2240 }
2241 HANDLE_INSTRUCTION_END();
2242
2243 HANDLE_INSTRUCTION_START(REM_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002244 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002245 shadow_frame.SetVRegFloat(vregA,
2246 fmodf(shadow_frame.GetVRegFloat(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002247 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002248 ADVANCE(1);
2249 }
2250 HANDLE_INSTRUCTION_END();
2251
2252 HANDLE_INSTRUCTION_START(ADD_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002253 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002254 shadow_frame.SetVRegDouble(vregA,
2255 shadow_frame.GetVRegDouble(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002256 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002257 ADVANCE(1);
2258 }
2259 HANDLE_INSTRUCTION_END();
2260
2261 HANDLE_INSTRUCTION_START(SUB_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002262 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002263 shadow_frame.SetVRegDouble(vregA,
2264 shadow_frame.GetVRegDouble(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002265 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002266 ADVANCE(1);
2267 }
2268 HANDLE_INSTRUCTION_END();
2269
2270 HANDLE_INSTRUCTION_START(MUL_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002271 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002272 shadow_frame.SetVRegDouble(vregA,
2273 shadow_frame.GetVRegDouble(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002274 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002275 ADVANCE(1);
2276 }
2277 HANDLE_INSTRUCTION_END();
2278
2279 HANDLE_INSTRUCTION_START(DIV_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002280 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002281 shadow_frame.SetVRegDouble(vregA,
2282 shadow_frame.GetVRegDouble(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002283 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002284 ADVANCE(1);
2285 }
2286 HANDLE_INSTRUCTION_END();
2287
2288 HANDLE_INSTRUCTION_START(REM_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002289 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002290 shadow_frame.SetVRegDouble(vregA,
2291 fmod(shadow_frame.GetVRegDouble(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002292 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002293 ADVANCE(1);
2294 }
2295 HANDLE_INSTRUCTION_END();
2296
2297 HANDLE_INSTRUCTION_START(ADD_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002298 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002299 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2300 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002301 ADVANCE(2);
2302 HANDLE_INSTRUCTION_END();
2303
2304 HANDLE_INSTRUCTION_START(RSUB_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002305 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002306 SafeSub(inst->VRegC_22s(),
2307 shadow_frame.GetVReg(inst->VRegB_22s(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002308 ADVANCE(2);
2309 HANDLE_INSTRUCTION_END();
2310
2311 HANDLE_INSTRUCTION_START(MUL_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002312 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002313 SafeMul(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2314 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002315 ADVANCE(2);
2316 HANDLE_INSTRUCTION_END();
2317
2318 HANDLE_INSTRUCTION_START(DIV_INT_LIT16) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002319 bool success = DoIntDivide(
2320 shadow_frame, inst->VRegA_22s(inst_data), shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2321 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002322 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2323 }
2324 HANDLE_INSTRUCTION_END();
2325
2326 HANDLE_INSTRUCTION_START(REM_INT_LIT16) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002327 bool success = DoIntRemainder(
2328 shadow_frame, inst->VRegA_22s(inst_data), shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2329 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002330 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2331 }
2332 HANDLE_INSTRUCTION_END();
2333
2334 HANDLE_INSTRUCTION_START(AND_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002335 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2336 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) &
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002337 inst->VRegC_22s());
2338 ADVANCE(2);
2339 HANDLE_INSTRUCTION_END();
2340
2341 HANDLE_INSTRUCTION_START(OR_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002342 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2343 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) |
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002344 inst->VRegC_22s());
2345 ADVANCE(2);
2346 HANDLE_INSTRUCTION_END();
2347
2348 HANDLE_INSTRUCTION_START(XOR_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002349 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2350 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) ^
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002351 inst->VRegC_22s());
2352 ADVANCE(2);
2353 HANDLE_INSTRUCTION_END();
2354
2355 HANDLE_INSTRUCTION_START(ADD_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002356 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002357 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22b()),
2358 inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002359 ADVANCE(2);
2360 HANDLE_INSTRUCTION_END();
2361
2362 HANDLE_INSTRUCTION_START(RSUB_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002363 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002364 SafeSub(inst->VRegC_22b(),
2365 shadow_frame.GetVReg(inst->VRegB_22b())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002366 ADVANCE(2);
2367 HANDLE_INSTRUCTION_END();
2368
2369 HANDLE_INSTRUCTION_START(MUL_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002370 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002371 SafeMul(shadow_frame.GetVReg(inst->VRegB_22b()),
2372 inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002373 ADVANCE(2);
2374 HANDLE_INSTRUCTION_END();
2375
2376 HANDLE_INSTRUCTION_START(DIV_INT_LIT8) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002377 bool success = DoIntDivide(shadow_frame, inst->VRegA_22b(inst_data),
2378 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002379 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2380 }
2381 HANDLE_INSTRUCTION_END();
2382
2383 HANDLE_INSTRUCTION_START(REM_INT_LIT8) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002384 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22b(inst_data),
2385 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002386 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2387 }
2388 HANDLE_INSTRUCTION_END();
2389
2390 HANDLE_INSTRUCTION_START(AND_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002391 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002392 shadow_frame.GetVReg(inst->VRegB_22b()) &
2393 inst->VRegC_22b());
2394 ADVANCE(2);
2395 HANDLE_INSTRUCTION_END();
2396
2397 HANDLE_INSTRUCTION_START(OR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002398 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002399 shadow_frame.GetVReg(inst->VRegB_22b()) |
2400 inst->VRegC_22b());
2401 ADVANCE(2);
2402 HANDLE_INSTRUCTION_END();
2403
2404 HANDLE_INSTRUCTION_START(XOR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002405 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002406 shadow_frame.GetVReg(inst->VRegB_22b()) ^
2407 inst->VRegC_22b());
2408 ADVANCE(2);
2409 HANDLE_INSTRUCTION_END();
2410
2411 HANDLE_INSTRUCTION_START(SHL_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002412 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002413 shadow_frame.GetVReg(inst->VRegB_22b()) <<
2414 (inst->VRegC_22b() & 0x1f));
2415 ADVANCE(2);
2416 HANDLE_INSTRUCTION_END();
2417
2418 HANDLE_INSTRUCTION_START(SHR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002419 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002420 shadow_frame.GetVReg(inst->VRegB_22b()) >>
2421 (inst->VRegC_22b() & 0x1f));
2422 ADVANCE(2);
2423 HANDLE_INSTRUCTION_END();
2424
2425 HANDLE_INSTRUCTION_START(USHR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002426 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002427 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_22b())) >>
2428 (inst->VRegC_22b() & 0x1f));
2429 ADVANCE(2);
2430 HANDLE_INSTRUCTION_END();
2431
Igor Murashkin158f35c2015-06-10 15:55:30 -07002432 HANDLE_EXPERIMENTAL_INSTRUCTION_START(CREATE_LAMBDA) {
Igor Murashkin6918bf12015-09-27 19:19:06 -07002433 if (lambda_closure_builder == nullptr) {
2434 // DoCreateLambda always needs a ClosureBuilder, even if it has 0 captured variables.
2435 lambda_closure_builder = MakeUnique<lambda::ClosureBuilder>();
2436 }
2437
2438 // TODO: these allocations should not leak, and the lambda method should not be local.
2439 lambda::Closure* lambda_closure =
2440 reinterpret_cast<lambda::Closure*>(alloca(lambda_closure_builder->GetSize()));
2441 bool success = DoCreateLambda<do_access_check>(self,
2442 inst,
2443 /*inout*/shadow_frame,
2444 /*inout*/lambda_closure_builder.get(),
2445 /*inout*/lambda_closure);
2446 lambda_closure_builder.reset(nullptr); // reset state of variables captured
Igor Murashkin158f35c2015-06-10 15:55:30 -07002447 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2448 }
2449 HANDLE_EXPERIMENTAL_INSTRUCTION_END();
2450
Igor Murashkin2ee54e22015-06-18 10:05:11 -07002451 HANDLE_EXPERIMENTAL_INSTRUCTION_START(BOX_LAMBDA) {
2452 bool success = DoBoxLambda<do_access_check>(self, shadow_frame, inst, inst_data);
2453 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2454 }
2455 HANDLE_EXPERIMENTAL_INSTRUCTION_END();
2456
2457 HANDLE_EXPERIMENTAL_INSTRUCTION_START(UNBOX_LAMBDA) {
2458 bool success = DoUnboxLambda<do_access_check>(self, shadow_frame, inst, inst_data);
2459 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2460 }
2461 HANDLE_EXPERIMENTAL_INSTRUCTION_END();
2462
Igor Murashkin6918bf12015-09-27 19:19:06 -07002463 HANDLE_EXPERIMENTAL_INSTRUCTION_START(CAPTURE_VARIABLE) {
2464 if (lambda_closure_builder == nullptr) {
2465 lambda_closure_builder = MakeUnique<lambda::ClosureBuilder>();
2466 }
2467
2468 bool success = DoCaptureVariable<do_access_check>(self,
2469 inst,
2470 /*inout*/shadow_frame,
2471 /*inout*/lambda_closure_builder.get());
2472
2473 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2474 }
2475 HANDLE_EXPERIMENTAL_INSTRUCTION_END();
2476
2477 HANDLE_EXPERIMENTAL_INSTRUCTION_START(LIBERATE_VARIABLE) {
2478 bool success = DoLiberateVariable<do_access_check>(self,
2479 inst,
2480 lambda_captured_variable_index,
2481 /*inout*/shadow_frame);
2482 // Temporarily only allow sequences of 'liberate-variable, liberate-variable, ...'
2483 lambda_captured_variable_index++;
2484 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2485 }
2486 HANDLE_EXPERIMENTAL_INSTRUCTION_END();
2487
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002488 HANDLE_INSTRUCTION_START(UNUSED_3E)
Ian Rogerse94652f2014-12-02 11:13:19 -08002489 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002490 HANDLE_INSTRUCTION_END();
2491
2492 HANDLE_INSTRUCTION_START(UNUSED_3F)
Ian Rogerse94652f2014-12-02 11:13:19 -08002493 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002494 HANDLE_INSTRUCTION_END();
2495
2496 HANDLE_INSTRUCTION_START(UNUSED_40)
Ian Rogerse94652f2014-12-02 11:13:19 -08002497 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002498 HANDLE_INSTRUCTION_END();
2499
2500 HANDLE_INSTRUCTION_START(UNUSED_41)
Ian Rogerse94652f2014-12-02 11:13:19 -08002501 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002502 HANDLE_INSTRUCTION_END();
2503
2504 HANDLE_INSTRUCTION_START(UNUSED_42)
Ian Rogerse94652f2014-12-02 11:13:19 -08002505 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002506 HANDLE_INSTRUCTION_END();
2507
2508 HANDLE_INSTRUCTION_START(UNUSED_43)
Ian Rogerse94652f2014-12-02 11:13:19 -08002509 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002510 HANDLE_INSTRUCTION_END();
2511
2512 HANDLE_INSTRUCTION_START(UNUSED_79)
Ian Rogerse94652f2014-12-02 11:13:19 -08002513 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002514 HANDLE_INSTRUCTION_END();
2515
2516 HANDLE_INSTRUCTION_START(UNUSED_7A)
Ian Rogerse94652f2014-12-02 11:13:19 -08002517 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002518 HANDLE_INSTRUCTION_END();
2519
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002520 HANDLE_INSTRUCTION_START(UNUSED_F4)
Ian Rogerse94652f2014-12-02 11:13:19 -08002521 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002522 HANDLE_INSTRUCTION_END();
2523
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002524 HANDLE_INSTRUCTION_START(UNUSED_FA)
Ian Rogerse94652f2014-12-02 11:13:19 -08002525 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002526 HANDLE_INSTRUCTION_END();
2527
2528 HANDLE_INSTRUCTION_START(UNUSED_FB)
Ian Rogerse94652f2014-12-02 11:13:19 -08002529 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002530 HANDLE_INSTRUCTION_END();
2531
2532 HANDLE_INSTRUCTION_START(UNUSED_FC)
Ian Rogerse94652f2014-12-02 11:13:19 -08002533 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002534 HANDLE_INSTRUCTION_END();
2535
2536 HANDLE_INSTRUCTION_START(UNUSED_FD)
Ian Rogerse94652f2014-12-02 11:13:19 -08002537 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002538 HANDLE_INSTRUCTION_END();
2539
2540 HANDLE_INSTRUCTION_START(UNUSED_FE)
Ian Rogerse94652f2014-12-02 11:13:19 -08002541 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002542 HANDLE_INSTRUCTION_END();
2543
2544 HANDLE_INSTRUCTION_START(UNUSED_FF)
Ian Rogerse94652f2014-12-02 11:13:19 -08002545 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002546 HANDLE_INSTRUCTION_END();
2547
2548 exception_pending_label: {
2549 CHECK(self->IsExceptionPending());
Sebastien Hertz1eda2262013-09-09 16:53:14 +02002550 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -07002551 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +02002552 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +02002553 }
Sebastien Hertzee1997a2013-09-19 14:47:09 +02002554 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002555 uint32_t found_dex_pc = FindNextInstructionFollowingException(self, shadow_frame, dex_pc,
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002556 instrumentation);
2557 if (found_dex_pc == DexFile::kDexNoIndex) {
Andreas Gampe03ec9302015-08-27 17:41:47 -07002558 // Structured locking is to be enforced for abnormal termination, too.
2559 shadow_frame.GetLockCountData().CheckAllMonitorsReleasedOrThrow<do_assignability_check>(self);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002560 return JValue(); /* Handled in caller. */
2561 } else {
2562 int32_t displacement = static_cast<int32_t>(found_dex_pc) - static_cast<int32_t>(dex_pc);
2563 ADVANCE(displacement);
2564 }
2565 }
2566
Sebastien Hertz8379b222014-02-24 17:38:15 +01002567// Create alternative instruction handlers dedicated to instrumentation.
2568// Return instructions must not call Instrumentation::DexPcMovedEvent since they already call
2569// Instrumentation::MethodExited. This is to avoid posting debugger events twice for this location.
Sebastien Hertze713d932014-05-15 10:48:53 +02002570// Note: we do not use the kReturn instruction flag here (to test the instruction is a return). The
2571// compiler seems to not evaluate "(Instruction::FlagsOf(Instruction::code) & kReturn) != 0" to
2572// a constant condition that would remove the "if" statement so the test is free.
Sebastien Hertz9d6bf692015-04-10 12:12:33 +02002573#define INSTRUMENTATION_INSTRUCTION_HANDLER(o, code, n, f, r, i, a, v) \
2574 alt_op_##code: { \
2575 Runtime* const runtime = Runtime::Current(); \
2576 const instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation(); \
2577 if (UNLIKELY(instrumentation->HasDexPcListeners())) { \
2578 Object* this_object = shadow_frame.GetThisObject(code_item->ins_size_); \
2579 instrumentation->DexPcMovedEvent(self, this_object, shadow_frame.GetMethod(), dex_pc); \
2580 } \
2581 UPDATE_HANDLER_TABLE(); \
2582 goto *handlersTable[instrumentation::kMainHandlerTable][Instruction::code]; \
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002583 }
2584#include "dex_instruction_list.h"
2585 DEX_INSTRUCTION_LIST(INSTRUMENTATION_INSTRUCTION_HANDLER)
2586#undef DEX_INSTRUCTION_LIST
2587#undef INSTRUMENTATION_INSTRUCTION_HANDLER
2588} // NOLINT(readability/fn_size)
2589
2590// Explicit definitions of ExecuteGotoImpl.
Mathieu Chartier90443472015-07-16 20:32:27 -07002591template SHARED_REQUIRES(Locks::mutator_lock_) HOT_ATTR
Ian Rogerse94652f2014-12-02 11:13:19 -08002592JValue ExecuteGotoImpl<true, false>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002593 ShadowFrame& shadow_frame, JValue result_register);
Mathieu Chartier90443472015-07-16 20:32:27 -07002594template SHARED_REQUIRES(Locks::mutator_lock_) HOT_ATTR
Ian Rogerse94652f2014-12-02 11:13:19 -08002595JValue ExecuteGotoImpl<false, false>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002596 ShadowFrame& shadow_frame, JValue result_register);
Mathieu Chartier90443472015-07-16 20:32:27 -07002597template SHARED_REQUIRES(Locks::mutator_lock_)
Ian Rogerse94652f2014-12-02 11:13:19 -08002598JValue ExecuteGotoImpl<true, true>(Thread* self, const DexFile::CodeItem* code_item,
2599 ShadowFrame& shadow_frame, JValue result_register);
Mathieu Chartier90443472015-07-16 20:32:27 -07002600template SHARED_REQUIRES(Locks::mutator_lock_)
Ian Rogerse94652f2014-12-02 11:13:19 -08002601JValue ExecuteGotoImpl<false, true>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002602 ShadowFrame& shadow_frame, JValue result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002603
2604} // namespace interpreter
2605} // namespace art
Colin Crosse84e4f72015-03-18 14:01:19 -07002606
2607#endif