blob: d50cfe64ae7c4716229123a979badc9d2033df70 [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"
Siva Chandra05d24152016-01-05 17:43:17 -080024#include "jit/jit.h"
Ian Rogersf72a11d2014-10-30 15:41:08 -070025#include "safe_math.h"
Sebastien Hertz8ece0502013-08-07 11:26:41 +020026
Igor Murashkin6918bf12015-09-27 19:19:06 -070027#include <memory> // std::unique_ptr
28
Sebastien Hertz8ece0502013-08-07 11:26:41 +020029namespace art {
30namespace interpreter {
31
32// In the following macros, we expect the following local variables exist:
33// - "self": the current Thread*.
34// - "inst" : the current Instruction*.
Sebastien Hertz3b588e02013-09-11 14:33:18 +020035// - "inst_data" : the current instruction's first 16 bits.
Sebastien Hertz8ece0502013-08-07 11:26:41 +020036// - "dex_pc": the current pc.
37// - "shadow_frame": the current shadow frame.
Sebastien Hertz8ece0502013-08-07 11:26:41 +020038// - "currentHandlersTable": the current table of pointer to each instruction handler.
39
40// Advance to the next instruction and updates interpreter state.
Sebastien Hertz8ece0502013-08-07 11:26:41 +020041#define ADVANCE(_offset) \
42 do { \
43 int32_t disp = static_cast<int32_t>(_offset); \
44 inst = inst->RelativeAt(disp); \
45 dex_pc = static_cast<uint32_t>(static_cast<int32_t>(dex_pc) + disp); \
46 shadow_frame.SetDexPC(dex_pc); \
Ian Rogerse94652f2014-12-02 11:13:19 -080047 TraceExecution(shadow_frame, inst, dex_pc); \
Sebastien Hertz3b588e02013-09-11 14:33:18 +020048 inst_data = inst->Fetch16(0); \
49 goto *currentHandlersTable[inst->Opcode(inst_data)]; \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020050 } while (false)
51
52#define HANDLE_PENDING_EXCEPTION() goto exception_pending_label
53
54#define POSSIBLY_HANDLE_PENDING_EXCEPTION(_is_exception_pending, _offset) \
55 do { \
56 if (UNLIKELY(_is_exception_pending)) { \
57 HANDLE_PENDING_EXCEPTION(); \
58 } else { \
59 ADVANCE(_offset); \
60 } \
61 } while (false)
62
Sebastien Hertzee1997a2013-09-19 14:47:09 +020063#define UPDATE_HANDLER_TABLE() \
Mathieu Chartier2cebb242015-04-21 16:50:40 -070064 currentHandlersTable = handlersTable[ \
65 Runtime::Current()->GetInstrumentation()->GetInterpreterHandlerTable()]
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +020066
Nicolas Geoffray81f0f952016-01-20 16:25:19 +000067#define BRANCH_INSTRUMENTATION(offset) \
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080068 do { \
69 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation(); \
Nicolas Geoffray81f0f952016-01-20 16:25:19 +000070 instrumentation->Branch(self, shadow_frame.GetMethod(), dex_pc, offset); \
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080071 } while (false)
72
Sebastien Hertz8ece0502013-08-07 11:26:41 +020073#define UNREACHABLE_CODE_CHECK() \
74 do { \
75 if (kIsDebugBuild) { \
76 LOG(FATAL) << "We should not be here !"; \
Ian Rogerse94652f2014-12-02 11:13:19 -080077 UNREACHABLE(); \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020078 } \
79 } while (false)
80
81#define HANDLE_INSTRUCTION_START(opcode) op_##opcode: // NOLINT(whitespace/labels)
82#define HANDLE_INSTRUCTION_END() UNREACHABLE_CODE_CHECK()
83
Igor Murashkin158f35c2015-06-10 15:55:30 -070084// Use with instructions labeled with kExperimental flag:
85#define HANDLE_EXPERIMENTAL_INSTRUCTION_START(opcode) \
86 HANDLE_INSTRUCTION_START(opcode); \
87 DCHECK(inst->IsExperimental()); \
Alex Lighteb7c1442015-08-31 13:17:42 -070088 if (Runtime::Current()->AreExperimentalFlagsEnabled(ExperimentalFlags::kLambdas)) {
Igor Murashkin158f35c2015-06-10 15:55:30 -070089#define HANDLE_EXPERIMENTAL_INSTRUCTION_END() \
90 } else { \
91 UnexpectedOpcode(inst, shadow_frame); \
92 } HANDLE_INSTRUCTION_END();
93
Andreas Gampe03ec9302015-08-27 17:41:47 -070094#define HANDLE_MONITOR_CHECKS() \
95 if (!shadow_frame.GetLockCountData(). \
96 CheckAllMonitorsReleasedOrThrow<do_assignability_check>(self)) { \
97 HANDLE_PENDING_EXCEPTION(); \
98 }
Igor Murashkin158f35c2015-06-10 15:55:30 -070099
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200100/**
101 * Interpreter based on computed goto tables.
102 *
103 * Each instruction is associated to a handler. This handler is responsible for executing the
104 * instruction and jump to the next instruction's handler.
105 * In order to limit the cost of instrumentation, we have two handler tables:
106 * - the "main" handler table: it contains handlers for normal execution of each instruction without
107 * handling of instrumentation.
108 * - the "alternative" handler table: it contains alternative handlers which first handle
109 * instrumentation before jumping to the corresponding "normal" instruction's handler.
110 *
111 * When instrumentation is active, the interpreter uses the "alternative" handler table. Otherwise
112 * it uses the "main" handler table.
113 *
114 * The current handler table is the handler table being used by the interpreter. It is updated:
115 * - on backward branch (goto, if and switch instructions)
116 * - after invoke
117 * - when an exception is thrown.
118 * This allows to support an attaching debugger to an already running application for instance.
119 *
120 * For a fast handler table update, handler tables are stored in an array of handler tables. Each
121 * handler table is represented by the InterpreterHandlerTable enum which allows to associate it
122 * to an index in this array of handler tables ((see Instrumentation::GetInterpreterHandlerTable).
123 *
124 * Here's the current layout of this array of handler tables:
125 *
126 * ---------------------+---------------+
127 * | NOP | (handler for NOP instruction)
128 * +---------------+
129 * "main" | MOVE | (handler for MOVE instruction)
130 * handler table +---------------+
131 * | ... |
132 * +---------------+
133 * | UNUSED_FF | (handler for UNUSED_FF instruction)
134 * ---------------------+---------------+
135 * | NOP | (alternative handler for NOP instruction)
136 * +---------------+
137 * "alternative" | MOVE | (alternative handler for MOVE instruction)
138 * handler table +---------------+
139 * | ... |
140 * +---------------+
141 * | UNUSED_FF | (alternative handler for UNUSED_FF instruction)
142 * ---------------------+---------------+
143 *
144 */
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100145template<bool do_access_check, bool transaction_active>
Ian Rogerse94652f2014-12-02 11:13:19 -0800146JValue ExecuteGotoImpl(Thread* self, const DexFile::CodeItem* code_item, ShadowFrame& shadow_frame,
147 JValue result_register) {
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200148 // Define handler tables:
149 // - The main handler table contains execution handlers for each instruction.
150 // - The alternative handler table contains prelude handlers which check for thread suspend and
151 // manage instrumentation before jumping to the execution handler.
152 static const void* const handlersTable[instrumentation::kNumHandlerTables][kNumPackedOpcodes] = {
153 {
154 // Main handler table.
155#define INSTRUCTION_HANDLER(o, code, n, f, r, i, a, v) &&op_##code,
156#include "dex_instruction_list.h"
157 DEX_INSTRUCTION_LIST(INSTRUCTION_HANDLER)
158#undef DEX_INSTRUCTION_LIST
159#undef INSTRUCTION_HANDLER
160 }, {
161 // Alternative handler table.
162#define INSTRUCTION_HANDLER(o, code, n, f, r, i, a, v) &&alt_op_##code,
163#include "dex_instruction_list.h"
164 DEX_INSTRUCTION_LIST(INSTRUCTION_HANDLER)
165#undef DEX_INSTRUCTION_LIST
166#undef INSTRUCTION_HANDLER
167 }
168 };
169
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800170 constexpr bool do_assignability_check = do_access_check;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200171 if (UNLIKELY(!shadow_frame.HasReferenceArray())) {
172 LOG(FATAL) << "Invalid shadow frame for interpreter use";
173 return JValue();
174 }
175 self->VerifyStack();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200176
177 uint32_t dex_pc = shadow_frame.GetDexPC();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200178 const Instruction* inst = Instruction::At(code_item->insns_ + dex_pc);
179 uint16_t inst_data;
180 const void* const* currentHandlersTable;
181 UPDATE_HANDLER_TABLE();
Sebastien Hertz270a0e12015-01-16 19:49:09 +0100182 if (LIKELY(dex_pc == 0)) { // We are entering the method as opposed to deoptimizing.
183 if (kIsDebugBuild) {
184 self->AssertNoPendingException();
185 }
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200186 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Siva Chandra05d24152016-01-05 17:43:17 -0800187 ArtMethod *method = shadow_frame.GetMethod();
188
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200189 if (UNLIKELY(instrumentation->HasMethodEntryListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200190 instrumentation->MethodEnterEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Siva Chandra05d24152016-01-05 17:43:17 -0800191 method, 0);
192 }
193
194 if (UNLIKELY(Runtime::Current()->GetJit() != nullptr &&
195 Runtime::Current()->GetJit()->JitAtFirstUse() &&
196 method->HasAnyCompiledCode())) {
197 JValue result;
198
199 // Pop the shadow frame before calling into compiled code.
200 self->PopShadowFrame();
201 ArtInterpreterToCompiledCodeBridge(self, code_item, &shadow_frame, &result);
202 // Push the shadow frame back as the caller will expect it.
203 self->PushShadowFrame(&shadow_frame);
204
205 return result;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200206 }
207 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200208
Igor Murashkin6918bf12015-09-27 19:19:06 -0700209 std::unique_ptr<lambda::ClosureBuilder> lambda_closure_builder;
210 size_t lambda_captured_variable_index = 0;
211
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200212 // Jump to first instruction.
213 ADVANCE(0);
214 UNREACHABLE_CODE_CHECK();
215
216 HANDLE_INSTRUCTION_START(NOP)
217 ADVANCE(1);
218 HANDLE_INSTRUCTION_END();
219
220 HANDLE_INSTRUCTION_START(MOVE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200221 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
222 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200223 ADVANCE(1);
224 HANDLE_INSTRUCTION_END();
225
226 HANDLE_INSTRUCTION_START(MOVE_FROM16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200227 shadow_frame.SetVReg(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200228 shadow_frame.GetVReg(inst->VRegB_22x()));
229 ADVANCE(2);
230 HANDLE_INSTRUCTION_END();
231
232 HANDLE_INSTRUCTION_START(MOVE_16)
233 shadow_frame.SetVReg(inst->VRegA_32x(),
234 shadow_frame.GetVReg(inst->VRegB_32x()));
235 ADVANCE(3);
236 HANDLE_INSTRUCTION_END();
237
238 HANDLE_INSTRUCTION_START(MOVE_WIDE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200239 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
240 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200241 ADVANCE(1);
242 HANDLE_INSTRUCTION_END();
243
244 HANDLE_INSTRUCTION_START(MOVE_WIDE_FROM16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200245 shadow_frame.SetVRegLong(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200246 shadow_frame.GetVRegLong(inst->VRegB_22x()));
247 ADVANCE(2);
248 HANDLE_INSTRUCTION_END();
249
250 HANDLE_INSTRUCTION_START(MOVE_WIDE_16)
251 shadow_frame.SetVRegLong(inst->VRegA_32x(),
252 shadow_frame.GetVRegLong(inst->VRegB_32x()));
253 ADVANCE(3);
254 HANDLE_INSTRUCTION_END();
255
256 HANDLE_INSTRUCTION_START(MOVE_OBJECT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200257 shadow_frame.SetVRegReference(inst->VRegA_12x(inst_data),
258 shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200259 ADVANCE(1);
260 HANDLE_INSTRUCTION_END();
261
262 HANDLE_INSTRUCTION_START(MOVE_OBJECT_FROM16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200263 shadow_frame.SetVRegReference(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200264 shadow_frame.GetVRegReference(inst->VRegB_22x()));
265 ADVANCE(2);
266 HANDLE_INSTRUCTION_END();
267
268 HANDLE_INSTRUCTION_START(MOVE_OBJECT_16)
269 shadow_frame.SetVRegReference(inst->VRegA_32x(),
270 shadow_frame.GetVRegReference(inst->VRegB_32x()));
271 ADVANCE(3);
272 HANDLE_INSTRUCTION_END();
273
274 HANDLE_INSTRUCTION_START(MOVE_RESULT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200275 shadow_frame.SetVReg(inst->VRegA_11x(inst_data), result_register.GetI());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200276 ADVANCE(1);
277 HANDLE_INSTRUCTION_END();
278
279 HANDLE_INSTRUCTION_START(MOVE_RESULT_WIDE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200280 shadow_frame.SetVRegLong(inst->VRegA_11x(inst_data), result_register.GetJ());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200281 ADVANCE(1);
282 HANDLE_INSTRUCTION_END();
283
284 HANDLE_INSTRUCTION_START(MOVE_RESULT_OBJECT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200285 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), result_register.GetL());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200286 ADVANCE(1);
287 HANDLE_INSTRUCTION_END();
288
289 HANDLE_INSTRUCTION_START(MOVE_EXCEPTION) {
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000290 Throwable* exception = self->GetException();
Sebastien Hertz270a0e12015-01-16 19:49:09 +0100291 DCHECK(exception != nullptr) << "No pending exception on MOVE_EXCEPTION instruction";
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200292 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), exception);
Sebastien Hertz5c004902014-05-21 10:07:42 +0200293 self->ClearException();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200294 ADVANCE(1);
295 }
296 HANDLE_INSTRUCTION_END();
297
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700298 HANDLE_INSTRUCTION_START(RETURN_VOID_NO_BARRIER) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200299 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700300 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700301 HANDLE_MONITOR_CHECKS();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200302 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200303 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200304 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200305 shadow_frame.GetMethod(), dex_pc,
306 result);
307 }
308 return result;
309 }
310 HANDLE_INSTRUCTION_END();
311
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700312 HANDLE_INSTRUCTION_START(RETURN_VOID) {
Hans Boehm30359612014-05-21 17:46:23 -0700313 QuasiAtomic::ThreadFenceForConstructor();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200314 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700315 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700316 HANDLE_MONITOR_CHECKS();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200317 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200318 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200319 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200320 shadow_frame.GetMethod(), dex_pc,
321 result);
322 }
323 return result;
324 }
325 HANDLE_INSTRUCTION_END();
326
327 HANDLE_INSTRUCTION_START(RETURN) {
328 JValue result;
329 result.SetJ(0);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200330 result.SetI(shadow_frame.GetVReg(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700331 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700332 HANDLE_MONITOR_CHECKS();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200333 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200334 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200335 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200336 shadow_frame.GetMethod(), dex_pc,
337 result);
338 }
339 return result;
340 }
341 HANDLE_INSTRUCTION_END();
342
343 HANDLE_INSTRUCTION_START(RETURN_WIDE) {
344 JValue result;
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200345 result.SetJ(shadow_frame.GetVRegLong(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700346 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700347 HANDLE_MONITOR_CHECKS();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200348 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200349 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200350 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200351 shadow_frame.GetMethod(), dex_pc,
352 result);
353 }
354 return result;
355 }
356 HANDLE_INSTRUCTION_END();
357
358 HANDLE_INSTRUCTION_START(RETURN_OBJECT) {
359 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700360 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700361 HANDLE_MONITOR_CHECKS();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700362 const uint8_t vreg_index = inst->VRegA_11x(inst_data);
363 Object* obj_result = shadow_frame.GetVRegReference(vreg_index);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700364 if (do_assignability_check && obj_result != nullptr) {
Vladimir Marko05792b92015-08-03 11:56:49 +0100365 size_t pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
366 Class* return_type = shadow_frame.GetMethod()->GetReturnType(true /* resolve */,
367 pointer_size);
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700368 obj_result = shadow_frame.GetVRegReference(vreg_index);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700369 if (return_type == nullptr) {
Jeff Haoa3faaf42013-09-03 19:07:00 -0700370 // Return the pending exception.
371 HANDLE_PENDING_EXCEPTION();
372 }
373 if (!obj_result->VerifierInstanceOf(return_type)) {
374 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700375 std::string temp1, temp2;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000376 self->ThrowNewExceptionF("Ljava/lang/VirtualMachineError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700377 "Returning '%s' that is not instance of return type '%s'",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700378 obj_result->GetClass()->GetDescriptor(&temp1),
379 return_type->GetDescriptor(&temp2));
Jeff Haoa3faaf42013-09-03 19:07:00 -0700380 HANDLE_PENDING_EXCEPTION();
381 }
382 }
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700383 result.SetL(obj_result);
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200384 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200385 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200386 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200387 shadow_frame.GetMethod(), dex_pc,
388 result);
389 }
390 return result;
391 }
392 HANDLE_INSTRUCTION_END();
393
394 HANDLE_INSTRUCTION_START(CONST_4) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200395 uint32_t dst = inst->VRegA_11n(inst_data);
396 int32_t val = inst->VRegB_11n(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200397 shadow_frame.SetVReg(dst, val);
398 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700399 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200400 }
401 ADVANCE(1);
402 }
403 HANDLE_INSTRUCTION_END();
404
405 HANDLE_INSTRUCTION_START(CONST_16) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200406 uint32_t dst = inst->VRegA_21s(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200407 int32_t val = inst->VRegB_21s();
408 shadow_frame.SetVReg(dst, val);
409 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700410 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200411 }
412 ADVANCE(2);
413 }
414 HANDLE_INSTRUCTION_END();
415
416 HANDLE_INSTRUCTION_START(CONST) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200417 uint32_t dst = inst->VRegA_31i(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200418 int32_t val = inst->VRegB_31i();
419 shadow_frame.SetVReg(dst, val);
420 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700421 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200422 }
423 ADVANCE(3);
424 }
425 HANDLE_INSTRUCTION_END();
426
427 HANDLE_INSTRUCTION_START(CONST_HIGH16) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200428 uint32_t dst = inst->VRegA_21h(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200429 int32_t val = static_cast<int32_t>(inst->VRegB_21h() << 16);
430 shadow_frame.SetVReg(dst, val);
431 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700432 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200433 }
434 ADVANCE(2);
435 }
436 HANDLE_INSTRUCTION_END();
437
438 HANDLE_INSTRUCTION_START(CONST_WIDE_16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200439 shadow_frame.SetVRegLong(inst->VRegA_21s(inst_data), inst->VRegB_21s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200440 ADVANCE(2);
441 HANDLE_INSTRUCTION_END();
442
443 HANDLE_INSTRUCTION_START(CONST_WIDE_32)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200444 shadow_frame.SetVRegLong(inst->VRegA_31i(inst_data), inst->VRegB_31i());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200445 ADVANCE(3);
446 HANDLE_INSTRUCTION_END();
447
448 HANDLE_INSTRUCTION_START(CONST_WIDE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200449 shadow_frame.SetVRegLong(inst->VRegA_51l(inst_data), inst->VRegB_51l());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200450 ADVANCE(5);
451 HANDLE_INSTRUCTION_END();
452
453 HANDLE_INSTRUCTION_START(CONST_WIDE_HIGH16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200454 shadow_frame.SetVRegLong(inst->VRegA_21h(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200455 static_cast<uint64_t>(inst->VRegB_21h()) << 48);
456 ADVANCE(2);
457 HANDLE_INSTRUCTION_END();
458
459 HANDLE_INSTRUCTION_START(CONST_STRING) {
Ian Rogers6786a582014-10-28 12:49:06 -0700460 String* s = ResolveString(self, shadow_frame, inst->VRegB_21c());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700461 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200462 HANDLE_PENDING_EXCEPTION();
463 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200464 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200465 ADVANCE(2);
466 }
467 }
468 HANDLE_INSTRUCTION_END();
469
470 HANDLE_INSTRUCTION_START(CONST_STRING_JUMBO) {
Ian Rogers6786a582014-10-28 12:49:06 -0700471 String* s = ResolveString(self, shadow_frame, inst->VRegB_31c());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700472 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200473 HANDLE_PENDING_EXCEPTION();
474 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200475 shadow_frame.SetVRegReference(inst->VRegA_31c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200476 ADVANCE(3);
477 }
478 }
479 HANDLE_INSTRUCTION_END();
480
481 HANDLE_INSTRUCTION_START(CONST_CLASS) {
482 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
483 self, false, do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700484 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200485 HANDLE_PENDING_EXCEPTION();
486 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200487 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), c);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200488 ADVANCE(2);
489 }
490 }
491 HANDLE_INSTRUCTION_END();
492
493 HANDLE_INSTRUCTION_START(MONITOR_ENTER) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200494 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700495 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000496 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200497 HANDLE_PENDING_EXCEPTION();
498 } else {
Andreas Gampe03ec9302015-08-27 17:41:47 -0700499 DoMonitorEnter<do_access_check>(self, &shadow_frame, obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200500 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), 1);
501 }
502 }
503 HANDLE_INSTRUCTION_END();
504
505 HANDLE_INSTRUCTION_START(MONITOR_EXIT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200506 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700507 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000508 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200509 HANDLE_PENDING_EXCEPTION();
510 } else {
Andreas Gampe03ec9302015-08-27 17:41:47 -0700511 DoMonitorExit<do_access_check>(self, &shadow_frame, obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200512 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), 1);
513 }
514 }
515 HANDLE_INSTRUCTION_END();
516
517 HANDLE_INSTRUCTION_START(CHECK_CAST) {
518 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), 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->VRegA_21c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700524 if (UNLIKELY(obj != nullptr && !obj->InstanceOf(c))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200525 ThrowClassCastException(c, obj->GetClass());
526 HANDLE_PENDING_EXCEPTION();
527 } else {
528 ADVANCE(2);
529 }
530 }
531 }
532 HANDLE_INSTRUCTION_END();
533
534 HANDLE_INSTRUCTION_START(INSTANCE_OF) {
535 Class* c = ResolveVerifyAndClinit(inst->VRegC_22c(), shadow_frame.GetMethod(),
536 self, false, do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700537 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200538 HANDLE_PENDING_EXCEPTION();
539 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200540 Object* obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700541 shadow_frame.SetVReg(inst->VRegA_22c(inst_data), (obj != nullptr && obj->InstanceOf(c)) ? 1 : 0);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200542 ADVANCE(2);
543 }
544 }
545 HANDLE_INSTRUCTION_END();
546
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700547 HANDLE_INSTRUCTION_START(ARRAY_LENGTH) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200548 Object* array = shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700549 if (UNLIKELY(array == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000550 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200551 HANDLE_PENDING_EXCEPTION();
552 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200553 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), array->AsArray()->GetLength());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200554 ADVANCE(1);
555 }
556 }
557 HANDLE_INSTRUCTION_END();
558
559 HANDLE_INSTRUCTION_START(NEW_INSTANCE) {
Jeff Hao848f70a2014-01-15 13:49:50 -0800560 Object* obj = nullptr;
561 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
562 self, false, do_access_check);
563 if (LIKELY(c != nullptr)) {
564 if (UNLIKELY(c->IsStringClass())) {
565 gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
566 mirror::SetStringCountVisitor visitor(0);
567 obj = String::Alloc<true>(self, 0, allocator_type, visitor);
568 } else {
569 obj = AllocObjectFromCode<do_access_check, true>(
570 inst->VRegB_21c(), shadow_frame.GetMethod(), self,
571 Runtime::Current()->GetHeap()->GetCurrentAllocator());
572 }
573 }
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700574 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200575 HANDLE_PENDING_EXCEPTION();
576 } else {
Sebastien Hertz4e99b3d2014-06-24 14:35:40 +0200577 obj->GetClass()->AssertInitializedOrInitializingInThread(self);
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700578 // Don't allow finalizable objects to be allocated during a transaction since these can't be
579 // finalized without a started runtime.
580 if (transaction_active && obj->GetClass()->IsFinalizable()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +0200581 AbortTransactionF(self, "Allocating finalizable object in transaction: %s",
582 PrettyTypeOf(obj).c_str());
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700583 HANDLE_PENDING_EXCEPTION();
584 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200585 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200586 ADVANCE(2);
587 }
588 }
589 HANDLE_INSTRUCTION_END();
590
591 HANDLE_INSTRUCTION_START(NEW_ARRAY) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200592 int32_t length = shadow_frame.GetVReg(inst->VRegB_22c(inst_data));
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800593 Object* obj = AllocArrayFromCode<do_access_check, true>(
Andreas Gampe1cc7dba2014-12-17 18:43:01 -0800594 inst->VRegC_22c(), length, shadow_frame.GetMethod(), self,
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800595 Runtime::Current()->GetHeap()->GetCurrentAllocator());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700596 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200597 HANDLE_PENDING_EXCEPTION();
598 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200599 shadow_frame.SetVRegReference(inst->VRegA_22c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200600 ADVANCE(2);
601 }
602 }
603 HANDLE_INSTRUCTION_END();
604
605 HANDLE_INSTRUCTION_START(FILLED_NEW_ARRAY) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100606 bool success =
607 DoFilledNewArray<false, do_access_check, transaction_active>(inst, shadow_frame,
608 self, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200609 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
610 }
611 HANDLE_INSTRUCTION_END();
612
613 HANDLE_INSTRUCTION_START(FILLED_NEW_ARRAY_RANGE) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100614 bool success =
615 DoFilledNewArray<true, do_access_check, transaction_active>(inst, shadow_frame,
616 self, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200617 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
618 }
619 HANDLE_INSTRUCTION_END();
620
621 HANDLE_INSTRUCTION_START(FILL_ARRAY_DATA) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200622 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_31t(inst_data));
Ian Rogers832336b2014-10-08 15:35:22 -0700623 const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t();
624 const Instruction::ArrayDataPayload* payload =
625 reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr);
626 bool success = FillArrayData(obj, payload);
627 if (transaction_active && success) {
628 RecordArrayElementsInTransaction(obj->AsArray(), payload->element_count);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200629 }
Ian Rogers832336b2014-10-08 15:35:22 -0700630 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200631 }
632 HANDLE_INSTRUCTION_END();
633
634 HANDLE_INSTRUCTION_START(THROW) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200635 Object* exception = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700636 if (UNLIKELY(exception == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000637 ThrowNullPointerException("throw with null exception");
Jeff Haoa3faaf42013-09-03 19:07:00 -0700638 } else if (do_assignability_check && !exception->GetClass()->IsThrowableClass()) {
639 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700640 std::string temp;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000641 self->ThrowNewExceptionF("Ljava/lang/VirtualMachineError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700642 "Throwing '%s' that is not instance of Throwable",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700643 exception->GetClass()->GetDescriptor(&temp));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200644 } else {
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000645 self->SetException(exception->AsThrowable());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200646 }
647 HANDLE_PENDING_EXCEPTION();
648 }
649 HANDLE_INSTRUCTION_END();
650
651 HANDLE_INSTRUCTION_START(GOTO) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200652 int8_t offset = inst->VRegA_10t(inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000653 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200654 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200655 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700656 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200657 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200658 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200659 }
660 ADVANCE(offset);
661 }
662 HANDLE_INSTRUCTION_END();
663
664 HANDLE_INSTRUCTION_START(GOTO_16) {
665 int16_t offset = inst->VRegA_20t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000666 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200667 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200668 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700669 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200670 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200671 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200672 }
673 ADVANCE(offset);
674 }
675 HANDLE_INSTRUCTION_END();
676
677 HANDLE_INSTRUCTION_START(GOTO_32) {
678 int32_t offset = inst->VRegA_30t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000679 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200680 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200681 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700682 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200683 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200684 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200685 }
686 ADVANCE(offset);
687 }
688 HANDLE_INSTRUCTION_END();
689
690 HANDLE_INSTRUCTION_START(PACKED_SWITCH) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200691 int32_t offset = DoPackedSwitch(inst, shadow_frame, inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000692 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200693 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200694 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700695 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200696 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200697 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200698 }
699 ADVANCE(offset);
700 }
701 HANDLE_INSTRUCTION_END();
702
703 HANDLE_INSTRUCTION_START(SPARSE_SWITCH) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200704 int32_t offset = DoSparseSwitch(inst, shadow_frame, inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000705 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200706 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200707 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700708 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200709 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200710 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200711 }
712 ADVANCE(offset);
713 }
714 HANDLE_INSTRUCTION_END();
715
Ian Rogers647b1a82014-10-10 11:02:11 -0700716#if defined(__clang__)
717#pragma clang diagnostic push
718#pragma clang diagnostic ignored "-Wfloat-equal"
719#endif
720
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200721 HANDLE_INSTRUCTION_START(CMPL_FLOAT) {
722 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
723 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
724 int32_t result;
725 if (val1 > val2) {
726 result = 1;
727 } else if (val1 == val2) {
728 result = 0;
729 } else {
730 result = -1;
731 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200732 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200733 ADVANCE(2);
734 }
735 HANDLE_INSTRUCTION_END();
736
737 HANDLE_INSTRUCTION_START(CMPG_FLOAT) {
738 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
739 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
740 int32_t result;
741 if (val1 < val2) {
742 result = -1;
743 } else if (val1 == val2) {
744 result = 0;
745 } else {
746 result = 1;
747 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200748 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200749 ADVANCE(2);
750 }
751 HANDLE_INSTRUCTION_END();
752
753 HANDLE_INSTRUCTION_START(CMPL_DOUBLE) {
754 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
755 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
756 int32_t result;
757 if (val1 > val2) {
758 result = 1;
759 } else if (val1 == val2) {
760 result = 0;
761 } else {
762 result = -1;
763 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200764 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200765 ADVANCE(2);
766 }
767 HANDLE_INSTRUCTION_END();
768
769 HANDLE_INSTRUCTION_START(CMPG_DOUBLE) {
770 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
771 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
772 int32_t result;
773 if (val1 < val2) {
774 result = -1;
775 } else if (val1 == val2) {
776 result = 0;
777 } else {
778 result = 1;
779 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200780 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200781 ADVANCE(2);
782 }
783 HANDLE_INSTRUCTION_END();
784
Ian Rogers647b1a82014-10-10 11:02:11 -0700785#if defined(__clang__)
786#pragma clang diagnostic pop
787#endif
788
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200789 HANDLE_INSTRUCTION_START(CMP_LONG) {
790 int64_t val1 = shadow_frame.GetVRegLong(inst->VRegB_23x());
791 int64_t val2 = shadow_frame.GetVRegLong(inst->VRegC_23x());
792 int32_t result;
793 if (val1 > val2) {
794 result = 1;
795 } else if (val1 == val2) {
796 result = 0;
797 } else {
798 result = -1;
799 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200800 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200801 ADVANCE(2);
802 }
803 HANDLE_INSTRUCTION_END();
804
805 HANDLE_INSTRUCTION_START(IF_EQ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200806 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) == shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200807 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000808 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200809 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200810 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700811 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200812 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200813 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200814 }
815 ADVANCE(offset);
816 } else {
817 ADVANCE(2);
818 }
819 }
820 HANDLE_INSTRUCTION_END();
821
822 HANDLE_INSTRUCTION_START(IF_NE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700823 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) !=
824 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200825 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000826 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200827 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200828 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700829 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200830 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200831 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200832 }
833 ADVANCE(offset);
834 } else {
835 ADVANCE(2);
836 }
837 }
838 HANDLE_INSTRUCTION_END();
839
840 HANDLE_INSTRUCTION_START(IF_LT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700841 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <
842 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200843 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000844 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200845 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200846 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700847 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200848 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200849 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200850 }
851 ADVANCE(offset);
852 } else {
853 ADVANCE(2);
854 }
855 }
856 HANDLE_INSTRUCTION_END();
857
858 HANDLE_INSTRUCTION_START(IF_GE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700859 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >=
860 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200861 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000862 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200863 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200864 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700865 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200866 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200867 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200868 }
869 ADVANCE(offset);
870 } else {
871 ADVANCE(2);
872 }
873 }
874 HANDLE_INSTRUCTION_END();
875
876 HANDLE_INSTRUCTION_START(IF_GT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700877 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >
878 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200879 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000880 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200881 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200882 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700883 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200884 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200885 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200886 }
887 ADVANCE(offset);
888 } else {
889 ADVANCE(2);
890 }
891 }
892 HANDLE_INSTRUCTION_END();
893
894 HANDLE_INSTRUCTION_START(IF_LE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700895 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <=
896 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200897 int16_t offset = inst->VRegC_22t();
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_EQZ) {
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_NEZ) {
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_LTZ) {
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_GEZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200964 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) >= 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200965 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000966 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200967 if (IsBackwardBranch(offset)) {
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_GTZ) {
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(IF_LEZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200998 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) <= 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200999 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +00001000 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001001 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001002 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -07001003 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +02001004 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001005 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001006 }
1007 ADVANCE(offset);
1008 } else {
1009 ADVANCE(2);
1010 }
1011 }
1012 HANDLE_INSTRUCTION_END();
1013
1014 HANDLE_INSTRUCTION_START(AGET_BOOLEAN) {
1015 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001016 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001017 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001018 HANDLE_PENDING_EXCEPTION();
1019 } else {
1020 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1021 BooleanArray* array = a->AsBooleanArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001022 if (LIKELY(array->CheckIsValidIndex(index))) {
1023 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001024 ADVANCE(2);
1025 } else {
1026 HANDLE_PENDING_EXCEPTION();
1027 }
1028 }
1029 }
1030 HANDLE_INSTRUCTION_END();
1031
1032 HANDLE_INSTRUCTION_START(AGET_BYTE) {
1033 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001034 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001035 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001036 HANDLE_PENDING_EXCEPTION();
1037 } else {
1038 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1039 ByteArray* array = a->AsByteArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001040 if (LIKELY(array->CheckIsValidIndex(index))) {
1041 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001042 ADVANCE(2);
1043 } else {
1044 HANDLE_PENDING_EXCEPTION();
1045 }
1046 }
1047 }
1048 HANDLE_INSTRUCTION_END();
1049
1050 HANDLE_INSTRUCTION_START(AGET_CHAR) {
1051 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001052 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001053 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001054 HANDLE_PENDING_EXCEPTION();
1055 } else {
1056 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1057 CharArray* array = a->AsCharArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001058 if (LIKELY(array->CheckIsValidIndex(index))) {
1059 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001060 ADVANCE(2);
1061 } else {
1062 HANDLE_PENDING_EXCEPTION();
1063 }
1064 }
1065 }
1066 HANDLE_INSTRUCTION_END();
1067
1068 HANDLE_INSTRUCTION_START(AGET_SHORT) {
1069 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001070 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001071 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001072 HANDLE_PENDING_EXCEPTION();
1073 } else {
1074 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1075 ShortArray* array = a->AsShortArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001076 if (LIKELY(array->CheckIsValidIndex(index))) {
1077 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001078 ADVANCE(2);
1079 } else {
1080 HANDLE_PENDING_EXCEPTION();
1081 }
1082 }
1083 }
1084 HANDLE_INSTRUCTION_END();
1085
1086 HANDLE_INSTRUCTION_START(AGET) {
1087 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001088 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001089 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001090 HANDLE_PENDING_EXCEPTION();
1091 } else {
1092 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001093 DCHECK(a->IsIntArray() || a->IsFloatArray()) << PrettyTypeOf(a);
1094 auto* array = down_cast<IntArray*>(a);
Sebastien Hertzabff6432014-01-27 18:01:39 +01001095 if (LIKELY(array->CheckIsValidIndex(index))) {
1096 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001097 ADVANCE(2);
1098 } else {
1099 HANDLE_PENDING_EXCEPTION();
1100 }
1101 }
1102 }
1103 HANDLE_INSTRUCTION_END();
1104
1105 HANDLE_INSTRUCTION_START(AGET_WIDE) {
1106 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001107 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001108 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001109 HANDLE_PENDING_EXCEPTION();
1110 } else {
1111 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001112 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << PrettyTypeOf(a);
1113 auto* array = down_cast<LongArray*>(a);
Sebastien Hertzabff6432014-01-27 18:01:39 +01001114 if (LIKELY(array->CheckIsValidIndex(index))) {
1115 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001116 ADVANCE(2);
1117 } else {
1118 HANDLE_PENDING_EXCEPTION();
1119 }
1120 }
1121 }
1122 HANDLE_INSTRUCTION_END();
1123
1124 HANDLE_INSTRUCTION_START(AGET_OBJECT) {
1125 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001126 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001127 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001128 HANDLE_PENDING_EXCEPTION();
1129 } else {
1130 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1131 ObjectArray<Object>* array = a->AsObjectArray<Object>();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001132 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001133 shadow_frame.SetVRegReference(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001134 ADVANCE(2);
1135 } else {
1136 HANDLE_PENDING_EXCEPTION();
1137 }
1138 }
1139 }
1140 HANDLE_INSTRUCTION_END();
1141
1142 HANDLE_INSTRUCTION_START(APUT_BOOLEAN) {
1143 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001144 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001145 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001146 HANDLE_PENDING_EXCEPTION();
1147 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001148 uint8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001149 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1150 BooleanArray* array = a->AsBooleanArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001151 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001152 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001153 ADVANCE(2);
1154 } else {
1155 HANDLE_PENDING_EXCEPTION();
1156 }
1157 }
1158 }
1159 HANDLE_INSTRUCTION_END();
1160
1161 HANDLE_INSTRUCTION_START(APUT_BYTE) {
1162 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001163 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001164 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001165 HANDLE_PENDING_EXCEPTION();
1166 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001167 int8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001168 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1169 ByteArray* array = a->AsByteArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001170 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001171 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001172 ADVANCE(2);
1173 } else {
1174 HANDLE_PENDING_EXCEPTION();
1175 }
1176 }
1177 }
1178 HANDLE_INSTRUCTION_END();
1179
1180 HANDLE_INSTRUCTION_START(APUT_CHAR) {
1181 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001182 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001183 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001184 HANDLE_PENDING_EXCEPTION();
1185 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001186 uint16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001187 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1188 CharArray* array = a->AsCharArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001189 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001190 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001191 ADVANCE(2);
1192 } else {
1193 HANDLE_PENDING_EXCEPTION();
1194 }
1195 }
1196 }
1197 HANDLE_INSTRUCTION_END();
1198
1199 HANDLE_INSTRUCTION_START(APUT_SHORT) {
1200 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001201 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001202 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001203 HANDLE_PENDING_EXCEPTION();
1204 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001205 int16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001206 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1207 ShortArray* array = a->AsShortArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001208 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001209 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001210 ADVANCE(2);
1211 } else {
1212 HANDLE_PENDING_EXCEPTION();
1213 }
1214 }
1215 }
1216 HANDLE_INSTRUCTION_END();
1217
1218 HANDLE_INSTRUCTION_START(APUT) {
1219 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001220 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001221 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001222 HANDLE_PENDING_EXCEPTION();
1223 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001224 int32_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001225 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001226 DCHECK(a->IsIntArray() || a->IsFloatArray()) << PrettyTypeOf(a);
1227 auto* array = down_cast<IntArray*>(a);
Sebastien Hertzabff6432014-01-27 18:01:39 +01001228 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001229 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001230 ADVANCE(2);
1231 } else {
1232 HANDLE_PENDING_EXCEPTION();
1233 }
1234 }
1235 }
1236 HANDLE_INSTRUCTION_END();
1237
1238 HANDLE_INSTRUCTION_START(APUT_WIDE) {
1239 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001240 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001241 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001242 HANDLE_PENDING_EXCEPTION();
1243 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001244 int64_t val = shadow_frame.GetVRegLong(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001245 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001246 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << PrettyTypeOf(a);
1247 auto* array = down_cast<LongArray*>(a);
Sebastien Hertzabff6432014-01-27 18:01:39 +01001248 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001249 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001250 ADVANCE(2);
1251 } else {
1252 HANDLE_PENDING_EXCEPTION();
1253 }
1254 }
1255 }
1256 HANDLE_INSTRUCTION_END();
1257
1258 HANDLE_INSTRUCTION_START(APUT_OBJECT) {
1259 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001260 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001261 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001262 HANDLE_PENDING_EXCEPTION();
1263 } else {
1264 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001265 Object* val = shadow_frame.GetVRegReference(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001266 ObjectArray<Object>* array = a->AsObjectArray<Object>();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001267 if (LIKELY(array->CheckIsValidIndex(index) && array->CheckAssignable(val))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001268 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001269 ADVANCE(2);
1270 } else {
1271 HANDLE_PENDING_EXCEPTION();
1272 }
1273 }
1274 }
1275 HANDLE_INSTRUCTION_END();
1276
1277 HANDLE_INSTRUCTION_START(IGET_BOOLEAN) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001278 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimBoolean, do_access_check>(
1279 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001280 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1281 }
1282 HANDLE_INSTRUCTION_END();
1283
1284 HANDLE_INSTRUCTION_START(IGET_BYTE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001285 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimByte, do_access_check>(
1286 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001287 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1288 }
1289 HANDLE_INSTRUCTION_END();
1290
1291 HANDLE_INSTRUCTION_START(IGET_CHAR) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001292 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimChar, do_access_check>(
1293 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001294 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1295 }
1296 HANDLE_INSTRUCTION_END();
1297
1298 HANDLE_INSTRUCTION_START(IGET_SHORT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001299 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimShort, do_access_check>(
1300 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001301 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1302 }
1303 HANDLE_INSTRUCTION_END();
1304
1305 HANDLE_INSTRUCTION_START(IGET) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001306 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimInt, do_access_check>(
1307 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001308 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1309 }
1310 HANDLE_INSTRUCTION_END();
1311
1312 HANDLE_INSTRUCTION_START(IGET_WIDE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001313 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimLong, do_access_check>(
1314 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001315 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1316 }
1317 HANDLE_INSTRUCTION_END();
1318
1319 HANDLE_INSTRUCTION_START(IGET_OBJECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001320 bool success = DoFieldGet<InstanceObjectRead, Primitive::kPrimNot, do_access_check>(
1321 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001322 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1323 }
1324 HANDLE_INSTRUCTION_END();
1325
1326 HANDLE_INSTRUCTION_START(IGET_QUICK) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001327 bool success = DoIGetQuick<Primitive::kPrimInt>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001328 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1329 }
1330 HANDLE_INSTRUCTION_END();
1331
Mathieu Chartierffc605c2014-12-10 10:35:44 -08001332 HANDLE_INSTRUCTION_START(IGET_BOOLEAN_QUICK) {
1333 bool success = DoIGetQuick<Primitive::kPrimBoolean>(shadow_frame, inst, inst_data);
1334 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1335 }
1336 HANDLE_INSTRUCTION_END();
1337
1338 HANDLE_INSTRUCTION_START(IGET_BYTE_QUICK) {
1339 bool success = DoIGetQuick<Primitive::kPrimByte>(shadow_frame, inst, inst_data);
1340 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1341 }
1342 HANDLE_INSTRUCTION_END();
1343
1344 HANDLE_INSTRUCTION_START(IGET_CHAR_QUICK) {
1345 bool success = DoIGetQuick<Primitive::kPrimChar>(shadow_frame, inst, inst_data);
1346 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1347 }
1348 HANDLE_INSTRUCTION_END();
1349
1350 HANDLE_INSTRUCTION_START(IGET_SHORT_QUICK) {
1351 bool success = DoIGetQuick<Primitive::kPrimShort>(shadow_frame, inst, inst_data);
1352 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1353 }
1354 HANDLE_INSTRUCTION_END();
1355
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001356 HANDLE_INSTRUCTION_START(IGET_WIDE_QUICK) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001357 bool success = DoIGetQuick<Primitive::kPrimLong>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001358 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1359 }
1360 HANDLE_INSTRUCTION_END();
1361
1362 HANDLE_INSTRUCTION_START(IGET_OBJECT_QUICK) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001363 bool success = DoIGetQuick<Primitive::kPrimNot>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001364 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1365 }
1366 HANDLE_INSTRUCTION_END();
1367
1368 HANDLE_INSTRUCTION_START(SGET_BOOLEAN) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001369 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimBoolean, do_access_check>(
1370 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001371 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1372 }
1373 HANDLE_INSTRUCTION_END();
1374
1375 HANDLE_INSTRUCTION_START(SGET_BYTE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001376 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimByte, do_access_check>(
1377 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001378 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1379 }
1380 HANDLE_INSTRUCTION_END();
1381
1382 HANDLE_INSTRUCTION_START(SGET_CHAR) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001383 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimChar, do_access_check>(
1384 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001385 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1386 }
1387 HANDLE_INSTRUCTION_END();
1388
1389 HANDLE_INSTRUCTION_START(SGET_SHORT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001390 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimShort, do_access_check>(
1391 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001392 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1393 }
1394 HANDLE_INSTRUCTION_END();
1395
1396 HANDLE_INSTRUCTION_START(SGET) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001397 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimInt, do_access_check>(
1398 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001399 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1400 }
1401 HANDLE_INSTRUCTION_END();
1402
1403 HANDLE_INSTRUCTION_START(SGET_WIDE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001404 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimLong, do_access_check>(
1405 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001406 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1407 }
1408 HANDLE_INSTRUCTION_END();
1409
1410 HANDLE_INSTRUCTION_START(SGET_OBJECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001411 bool success = DoFieldGet<StaticObjectRead, Primitive::kPrimNot, do_access_check>(
1412 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001413 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1414 }
1415 HANDLE_INSTRUCTION_END();
1416
1417 HANDLE_INSTRUCTION_START(IPUT_BOOLEAN) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001418 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1419 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001420 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1421 }
1422 HANDLE_INSTRUCTION_END();
1423
1424 HANDLE_INSTRUCTION_START(IPUT_BYTE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001425 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimByte, do_access_check,
1426 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001427 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1428 }
1429 HANDLE_INSTRUCTION_END();
1430
1431 HANDLE_INSTRUCTION_START(IPUT_CHAR) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001432 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimChar, do_access_check,
1433 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001434 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1435 }
1436 HANDLE_INSTRUCTION_END();
1437
1438 HANDLE_INSTRUCTION_START(IPUT_SHORT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001439 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimShort, do_access_check,
1440 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001441 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1442 }
1443 HANDLE_INSTRUCTION_END();
1444
1445 HANDLE_INSTRUCTION_START(IPUT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001446 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimInt, do_access_check,
1447 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001448 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1449 }
1450 HANDLE_INSTRUCTION_END();
1451
1452 HANDLE_INSTRUCTION_START(IPUT_WIDE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001453 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimLong, do_access_check,
1454 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001455 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1456 }
1457 HANDLE_INSTRUCTION_END();
1458
1459 HANDLE_INSTRUCTION_START(IPUT_OBJECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001460 bool success = DoFieldPut<InstanceObjectWrite, Primitive::kPrimNot, do_access_check,
1461 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001462 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1463 }
1464 HANDLE_INSTRUCTION_END();
1465
1466 HANDLE_INSTRUCTION_START(IPUT_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001467 bool success = DoIPutQuick<Primitive::kPrimInt, transaction_active>(
1468 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001469 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1470 }
1471 HANDLE_INSTRUCTION_END();
1472
Fred Shih37f05ef2014-07-16 18:38:08 -07001473 HANDLE_INSTRUCTION_START(IPUT_BOOLEAN_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001474 bool success = DoIPutQuick<Primitive::kPrimBoolean, transaction_active>(
1475 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001476 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1477 }
1478 HANDLE_INSTRUCTION_END();
1479
1480 HANDLE_INSTRUCTION_START(IPUT_BYTE_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001481 bool success = DoIPutQuick<Primitive::kPrimByte, transaction_active>(
1482 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001483 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1484 }
1485 HANDLE_INSTRUCTION_END();
1486
1487 HANDLE_INSTRUCTION_START(IPUT_CHAR_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001488 bool success = DoIPutQuick<Primitive::kPrimChar, transaction_active>(
1489 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001490 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1491 }
1492 HANDLE_INSTRUCTION_END();
1493
1494 HANDLE_INSTRUCTION_START(IPUT_SHORT_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001495 bool success = DoIPutQuick<Primitive::kPrimShort, transaction_active>(
1496 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001497 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1498 }
1499 HANDLE_INSTRUCTION_END();
1500
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001501 HANDLE_INSTRUCTION_START(IPUT_WIDE_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001502 bool success = DoIPutQuick<Primitive::kPrimLong, transaction_active>(
1503 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001504 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1505 }
1506 HANDLE_INSTRUCTION_END();
1507
1508 HANDLE_INSTRUCTION_START(IPUT_OBJECT_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001509 bool success = DoIPutQuick<Primitive::kPrimNot, transaction_active>(
1510 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001511 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1512 }
1513 HANDLE_INSTRUCTION_END();
1514
1515 HANDLE_INSTRUCTION_START(SPUT_BOOLEAN) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001516 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1517 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001518 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1519 }
1520 HANDLE_INSTRUCTION_END();
1521
1522 HANDLE_INSTRUCTION_START(SPUT_BYTE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001523 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimByte, do_access_check,
1524 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001525 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1526 }
1527 HANDLE_INSTRUCTION_END();
1528
1529 HANDLE_INSTRUCTION_START(SPUT_CHAR) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001530 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimChar, do_access_check,
1531 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001532 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1533 }
1534 HANDLE_INSTRUCTION_END();
1535
1536 HANDLE_INSTRUCTION_START(SPUT_SHORT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001537 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimShort, do_access_check,
1538 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001539 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1540 }
1541 HANDLE_INSTRUCTION_END();
1542
1543 HANDLE_INSTRUCTION_START(SPUT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001544 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimInt, do_access_check,
1545 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001546 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1547 }
1548 HANDLE_INSTRUCTION_END();
1549
1550 HANDLE_INSTRUCTION_START(SPUT_WIDE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001551 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimLong, do_access_check,
1552 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001553 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1554 }
1555 HANDLE_INSTRUCTION_END();
1556
1557 HANDLE_INSTRUCTION_START(SPUT_OBJECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001558 bool success = DoFieldPut<StaticObjectWrite, Primitive::kPrimNot, do_access_check,
1559 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001560 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1561 }
1562 HANDLE_INSTRUCTION_END();
1563
1564 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001565 bool success = DoInvoke<kVirtual, false, do_access_check>(
1566 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001567 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001568 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1569 }
1570 HANDLE_INSTRUCTION_END();
1571
1572 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001573 bool success = DoInvoke<kVirtual, true, do_access_check>(
1574 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001575 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001576 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1577 }
1578 HANDLE_INSTRUCTION_END();
1579
1580 HANDLE_INSTRUCTION_START(INVOKE_SUPER) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001581 bool success = DoInvoke<kSuper, false, do_access_check>(
1582 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001583 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001584 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1585 }
1586 HANDLE_INSTRUCTION_END();
1587
1588 HANDLE_INSTRUCTION_START(INVOKE_SUPER_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001589 bool success = DoInvoke<kSuper, true, do_access_check>(
1590 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001591 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001592 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1593 }
1594 HANDLE_INSTRUCTION_END();
1595
1596 HANDLE_INSTRUCTION_START(INVOKE_DIRECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001597 bool success = DoInvoke<kDirect, false, do_access_check>(
1598 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001599 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001600 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1601 }
1602 HANDLE_INSTRUCTION_END();
1603
1604 HANDLE_INSTRUCTION_START(INVOKE_DIRECT_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001605 bool success = DoInvoke<kDirect, true, do_access_check>(
1606 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001607 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001608 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1609 }
1610 HANDLE_INSTRUCTION_END();
1611
1612 HANDLE_INSTRUCTION_START(INVOKE_INTERFACE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001613 bool success = DoInvoke<kInterface, false, do_access_check>(
1614 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001615 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001616 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1617 }
1618 HANDLE_INSTRUCTION_END();
1619
1620 HANDLE_INSTRUCTION_START(INVOKE_INTERFACE_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001621 bool success = DoInvoke<kInterface, true, do_access_check>(
1622 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001623 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001624 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1625 }
1626 HANDLE_INSTRUCTION_END();
1627
1628 HANDLE_INSTRUCTION_START(INVOKE_STATIC) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001629 bool success = DoInvoke<kStatic, false, do_access_check>(
1630 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001631 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001632 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1633 }
1634 HANDLE_INSTRUCTION_END();
1635
1636 HANDLE_INSTRUCTION_START(INVOKE_STATIC_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001637 bool success = DoInvoke<kStatic, true, do_access_check>(
1638 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001639 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001640 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1641 }
1642 HANDLE_INSTRUCTION_END();
1643
1644 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001645 bool success = DoInvokeVirtualQuick<false>(
1646 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001647 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001648 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1649 }
1650 HANDLE_INSTRUCTION_END();
1651
1652 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_RANGE_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001653 bool success = DoInvokeVirtualQuick<true>(
1654 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001655 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001656 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1657 }
1658 HANDLE_INSTRUCTION_END();
1659
Igor Murashkin158f35c2015-06-10 15:55:30 -07001660 HANDLE_EXPERIMENTAL_INSTRUCTION_START(INVOKE_LAMBDA) {
1661 bool success = DoInvokeLambda<do_access_check>(self, shadow_frame, inst, inst_data,
1662 &result_register);
1663 UPDATE_HANDLER_TABLE();
1664 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1665 }
1666 HANDLE_EXPERIMENTAL_INSTRUCTION_END();
1667
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001668 HANDLE_INSTRUCTION_START(NEG_INT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001669 shadow_frame.SetVReg(
1670 inst->VRegA_12x(inst_data), -shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001671 ADVANCE(1);
1672 HANDLE_INSTRUCTION_END();
1673
1674 HANDLE_INSTRUCTION_START(NOT_INT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001675 shadow_frame.SetVReg(
1676 inst->VRegA_12x(inst_data), ~shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001677 ADVANCE(1);
1678 HANDLE_INSTRUCTION_END();
1679
1680 HANDLE_INSTRUCTION_START(NEG_LONG)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001681 shadow_frame.SetVRegLong(
1682 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001683 ADVANCE(1);
1684 HANDLE_INSTRUCTION_END();
1685
1686 HANDLE_INSTRUCTION_START(NOT_LONG)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001687 shadow_frame.SetVRegLong(
1688 inst->VRegA_12x(inst_data), ~shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001689 ADVANCE(1);
1690 HANDLE_INSTRUCTION_END();
1691
1692 HANDLE_INSTRUCTION_START(NEG_FLOAT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001693 shadow_frame.SetVRegFloat(
1694 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001695 ADVANCE(1);
1696 HANDLE_INSTRUCTION_END();
1697
1698 HANDLE_INSTRUCTION_START(NEG_DOUBLE)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001699 shadow_frame.SetVRegDouble(
1700 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001701 ADVANCE(1);
1702 HANDLE_INSTRUCTION_END();
1703
1704 HANDLE_INSTRUCTION_START(INT_TO_LONG)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001705 shadow_frame.SetVRegLong(
1706 inst->VRegA_12x(inst_data), shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001707 ADVANCE(1);
1708 HANDLE_INSTRUCTION_END();
1709
1710 HANDLE_INSTRUCTION_START(INT_TO_FLOAT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001711 shadow_frame.SetVRegFloat(
1712 inst->VRegA_12x(inst_data), shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001713 ADVANCE(1);
1714 HANDLE_INSTRUCTION_END();
1715
1716 HANDLE_INSTRUCTION_START(INT_TO_DOUBLE)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001717 shadow_frame.SetVRegDouble(
1718 inst->VRegA_12x(inst_data), shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001719 ADVANCE(1);
1720 HANDLE_INSTRUCTION_END();
1721
1722 HANDLE_INSTRUCTION_START(LONG_TO_INT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001723 shadow_frame.SetVReg(
1724 inst->VRegA_12x(inst_data), shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001725 ADVANCE(1);
1726 HANDLE_INSTRUCTION_END();
1727
1728 HANDLE_INSTRUCTION_START(LONG_TO_FLOAT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001729 shadow_frame.SetVRegFloat(
1730 inst->VRegA_12x(inst_data), shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001731 ADVANCE(1);
1732 HANDLE_INSTRUCTION_END();
1733
1734 HANDLE_INSTRUCTION_START(LONG_TO_DOUBLE)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001735 shadow_frame.SetVRegDouble(
1736 inst->VRegA_12x(inst_data), shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001737 ADVANCE(1);
1738 HANDLE_INSTRUCTION_END();
1739
1740 HANDLE_INSTRUCTION_START(FLOAT_TO_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001741 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001742 int32_t result = art_float_to_integral<int32_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001743 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001744 ADVANCE(1);
1745 }
1746 HANDLE_INSTRUCTION_END();
1747
1748 HANDLE_INSTRUCTION_START(FLOAT_TO_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001749 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001750 int64_t result = art_float_to_integral<int64_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001751 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001752 ADVANCE(1);
1753 }
1754 HANDLE_INSTRUCTION_END();
1755
1756 HANDLE_INSTRUCTION_START(FLOAT_TO_DOUBLE)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001757 shadow_frame.SetVRegDouble(
1758 inst->VRegA_12x(inst_data), shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001759 ADVANCE(1);
1760 HANDLE_INSTRUCTION_END();
1761
1762 HANDLE_INSTRUCTION_START(DOUBLE_TO_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001763 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001764 int32_t result = art_float_to_integral<int32_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001765 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001766 ADVANCE(1);
1767 }
1768 HANDLE_INSTRUCTION_END();
1769
1770 HANDLE_INSTRUCTION_START(DOUBLE_TO_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001771 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001772 int64_t result = art_float_to_integral<int64_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001773 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001774 ADVANCE(1);
1775 }
1776 HANDLE_INSTRUCTION_END();
1777
1778 HANDLE_INSTRUCTION_START(DOUBLE_TO_FLOAT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001779 shadow_frame.SetVRegFloat(
1780 inst->VRegA_12x(inst_data), shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001781 ADVANCE(1);
1782 HANDLE_INSTRUCTION_END();
1783
1784 HANDLE_INSTRUCTION_START(INT_TO_BYTE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001785 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1786 static_cast<int8_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001787 ADVANCE(1);
1788 HANDLE_INSTRUCTION_END();
1789
1790 HANDLE_INSTRUCTION_START(INT_TO_CHAR)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001791 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1792 static_cast<uint16_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001793 ADVANCE(1);
1794 HANDLE_INSTRUCTION_END();
1795
1796 HANDLE_INSTRUCTION_START(INT_TO_SHORT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001797 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1798 static_cast<int16_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001799 ADVANCE(1);
1800 HANDLE_INSTRUCTION_END();
1801
1802 HANDLE_INSTRUCTION_START(ADD_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001803 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001804 SafeAdd(shadow_frame.GetVReg(inst->VRegB_23x()),
1805 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001806 ADVANCE(2);
1807 HANDLE_INSTRUCTION_END();
1808
1809 HANDLE_INSTRUCTION_START(SUB_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001810 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001811 SafeSub(shadow_frame.GetVReg(inst->VRegB_23x()),
1812 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001813 ADVANCE(2);
1814 HANDLE_INSTRUCTION_END();
1815
1816 HANDLE_INSTRUCTION_START(MUL_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001817 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001818 SafeMul(shadow_frame.GetVReg(inst->VRegB_23x()),
1819 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001820 ADVANCE(2);
1821 HANDLE_INSTRUCTION_END();
1822
1823 HANDLE_INSTRUCTION_START(DIV_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001824 bool success = DoIntDivide(shadow_frame, inst->VRegA_23x(inst_data),
1825 shadow_frame.GetVReg(inst->VRegB_23x()),
1826 shadow_frame.GetVReg(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001827 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1828 }
1829 HANDLE_INSTRUCTION_END();
1830
1831 HANDLE_INSTRUCTION_START(REM_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001832 bool success = DoIntRemainder(shadow_frame, inst->VRegA_23x(inst_data),
1833 shadow_frame.GetVReg(inst->VRegB_23x()),
1834 shadow_frame.GetVReg(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001835 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1836 }
1837 HANDLE_INSTRUCTION_END();
1838
1839 HANDLE_INSTRUCTION_START(SHL_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001840 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001841 shadow_frame.GetVReg(inst->VRegB_23x()) <<
1842 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1843 ADVANCE(2);
1844 HANDLE_INSTRUCTION_END();
1845
1846 HANDLE_INSTRUCTION_START(SHR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001847 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001848 shadow_frame.GetVReg(inst->VRegB_23x()) >>
1849 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1850 ADVANCE(2);
1851 HANDLE_INSTRUCTION_END();
1852
1853 HANDLE_INSTRUCTION_START(USHR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001854 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001855 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_23x())) >>
1856 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1857 ADVANCE(2);
1858 HANDLE_INSTRUCTION_END();
1859
1860 HANDLE_INSTRUCTION_START(AND_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001861 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001862 shadow_frame.GetVReg(inst->VRegB_23x()) &
1863 shadow_frame.GetVReg(inst->VRegC_23x()));
1864 ADVANCE(2);
1865 HANDLE_INSTRUCTION_END();
1866
1867 HANDLE_INSTRUCTION_START(OR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001868 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001869 shadow_frame.GetVReg(inst->VRegB_23x()) |
1870 shadow_frame.GetVReg(inst->VRegC_23x()));
1871 ADVANCE(2);
1872 HANDLE_INSTRUCTION_END();
1873
1874 HANDLE_INSTRUCTION_START(XOR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001875 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001876 shadow_frame.GetVReg(inst->VRegB_23x()) ^
1877 shadow_frame.GetVReg(inst->VRegC_23x()));
1878 ADVANCE(2);
1879 HANDLE_INSTRUCTION_END();
1880
1881 HANDLE_INSTRUCTION_START(ADD_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001882 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001883 SafeAdd(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1884 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001885 ADVANCE(2);
1886 HANDLE_INSTRUCTION_END();
1887
1888 HANDLE_INSTRUCTION_START(SUB_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001889 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001890 SafeSub(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1891 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001892 ADVANCE(2);
1893 HANDLE_INSTRUCTION_END();
1894
1895 HANDLE_INSTRUCTION_START(MUL_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001896 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001897 SafeMul(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1898 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001899 ADVANCE(2);
1900 HANDLE_INSTRUCTION_END();
1901
1902 HANDLE_INSTRUCTION_START(DIV_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001903 bool success = DoLongDivide(shadow_frame, inst->VRegA_23x(inst_data),
1904 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1905 shadow_frame.GetVRegLong(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001906 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1907 }
1908 HANDLE_INSTRUCTION_END();
1909
1910 HANDLE_INSTRUCTION_START(REM_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001911 bool success = DoLongRemainder(shadow_frame, inst->VRegA_23x(inst_data),
1912 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1913 shadow_frame.GetVRegLong(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001914 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1915 }
1916 HANDLE_INSTRUCTION_END();
1917
1918 HANDLE_INSTRUCTION_START(AND_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001919 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001920 shadow_frame.GetVRegLong(inst->VRegB_23x()) &
1921 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1922 ADVANCE(2);
1923 HANDLE_INSTRUCTION_END();
1924
1925 HANDLE_INSTRUCTION_START(OR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001926 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001927 shadow_frame.GetVRegLong(inst->VRegB_23x()) |
1928 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1929 ADVANCE(2);
1930 HANDLE_INSTRUCTION_END();
1931
1932 HANDLE_INSTRUCTION_START(XOR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001933 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001934 shadow_frame.GetVRegLong(inst->VRegB_23x()) ^
1935 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1936 ADVANCE(2);
1937 HANDLE_INSTRUCTION_END();
1938
1939 HANDLE_INSTRUCTION_START(SHL_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001940 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001941 shadow_frame.GetVRegLong(inst->VRegB_23x()) <<
1942 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1943 ADVANCE(2);
1944 HANDLE_INSTRUCTION_END();
1945
1946 HANDLE_INSTRUCTION_START(SHR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001947 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001948 shadow_frame.GetVRegLong(inst->VRegB_23x()) >>
1949 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1950 ADVANCE(2);
1951 HANDLE_INSTRUCTION_END();
1952
1953 HANDLE_INSTRUCTION_START(USHR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001954 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001955 static_cast<uint64_t>(shadow_frame.GetVRegLong(inst->VRegB_23x())) >>
1956 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1957 ADVANCE(2);
1958 HANDLE_INSTRUCTION_END();
1959
1960 HANDLE_INSTRUCTION_START(ADD_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001961 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001962 shadow_frame.GetVRegFloat(inst->VRegB_23x()) +
1963 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1964 ADVANCE(2);
1965 HANDLE_INSTRUCTION_END();
1966
1967 HANDLE_INSTRUCTION_START(SUB_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001968 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001969 shadow_frame.GetVRegFloat(inst->VRegB_23x()) -
1970 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1971 ADVANCE(2);
1972 HANDLE_INSTRUCTION_END();
1973
1974 HANDLE_INSTRUCTION_START(MUL_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001975 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001976 shadow_frame.GetVRegFloat(inst->VRegB_23x()) *
1977 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1978 ADVANCE(2);
1979 HANDLE_INSTRUCTION_END();
1980
1981 HANDLE_INSTRUCTION_START(DIV_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001982 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001983 shadow_frame.GetVRegFloat(inst->VRegB_23x()) /
1984 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1985 ADVANCE(2);
1986 HANDLE_INSTRUCTION_END();
1987
1988 HANDLE_INSTRUCTION_START(REM_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001989 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001990 fmodf(shadow_frame.GetVRegFloat(inst->VRegB_23x()),
1991 shadow_frame.GetVRegFloat(inst->VRegC_23x())));
1992 ADVANCE(2);
1993 HANDLE_INSTRUCTION_END();
1994
1995 HANDLE_INSTRUCTION_START(ADD_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001996 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001997 shadow_frame.GetVRegDouble(inst->VRegB_23x()) +
1998 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1999 ADVANCE(2);
2000 HANDLE_INSTRUCTION_END();
2001
2002 HANDLE_INSTRUCTION_START(SUB_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002003 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002004 shadow_frame.GetVRegDouble(inst->VRegB_23x()) -
2005 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
2006 ADVANCE(2);
2007 HANDLE_INSTRUCTION_END();
2008
2009 HANDLE_INSTRUCTION_START(MUL_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002010 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002011 shadow_frame.GetVRegDouble(inst->VRegB_23x()) *
2012 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
2013 ADVANCE(2);
2014 HANDLE_INSTRUCTION_END();
2015
2016 HANDLE_INSTRUCTION_START(DIV_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002017 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002018 shadow_frame.GetVRegDouble(inst->VRegB_23x()) /
2019 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
2020 ADVANCE(2);
2021 HANDLE_INSTRUCTION_END();
2022
2023 HANDLE_INSTRUCTION_START(REM_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002024 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002025 fmod(shadow_frame.GetVRegDouble(inst->VRegB_23x()),
2026 shadow_frame.GetVRegDouble(inst->VRegC_23x())));
2027 ADVANCE(2);
2028 HANDLE_INSTRUCTION_END();
2029
2030 HANDLE_INSTRUCTION_START(ADD_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002031 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002032 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002033 SafeAdd(shadow_frame.GetVReg(vregA),
2034 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002035 ADVANCE(1);
2036 }
2037 HANDLE_INSTRUCTION_END();
2038
2039 HANDLE_INSTRUCTION_START(SUB_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002040 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002041 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002042 SafeSub(shadow_frame.GetVReg(vregA),
2043 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002044 ADVANCE(1);
2045 }
2046 HANDLE_INSTRUCTION_END();
2047
2048 HANDLE_INSTRUCTION_START(MUL_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 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002051 SafeMul(shadow_frame.GetVReg(vregA),
2052 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002053 ADVANCE(1);
2054 }
2055 HANDLE_INSTRUCTION_END();
2056
2057 HANDLE_INSTRUCTION_START(DIV_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002058 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002059 bool success = DoIntDivide(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002060 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002061 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2062 }
2063 HANDLE_INSTRUCTION_END();
2064
2065 HANDLE_INSTRUCTION_START(REM_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 bool success = DoIntRemainder(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002068 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002069 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2070 }
2071 HANDLE_INSTRUCTION_END();
2072
2073 HANDLE_INSTRUCTION_START(SHL_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002074 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002075 shadow_frame.SetVReg(vregA,
2076 shadow_frame.GetVReg(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002077 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002078 ADVANCE(1);
2079 }
2080 HANDLE_INSTRUCTION_END();
2081
2082 HANDLE_INSTRUCTION_START(SHR_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002083 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002084 shadow_frame.SetVReg(vregA,
2085 shadow_frame.GetVReg(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002086 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002087 ADVANCE(1);
2088 }
2089 HANDLE_INSTRUCTION_END();
2090
2091 HANDLE_INSTRUCTION_START(USHR_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002092 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002093 shadow_frame.SetVReg(vregA,
2094 static_cast<uint32_t>(shadow_frame.GetVReg(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002095 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002096 ADVANCE(1);
2097 }
2098 HANDLE_INSTRUCTION_END();
2099
2100 HANDLE_INSTRUCTION_START(AND_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002101 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002102 shadow_frame.SetVReg(vregA,
2103 shadow_frame.GetVReg(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002104 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002105 ADVANCE(1);
2106 }
2107 HANDLE_INSTRUCTION_END();
2108
2109 HANDLE_INSTRUCTION_START(OR_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002110 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002111 shadow_frame.SetVReg(vregA,
2112 shadow_frame.GetVReg(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002113 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002114 ADVANCE(1);
2115 }
2116 HANDLE_INSTRUCTION_END();
2117
2118 HANDLE_INSTRUCTION_START(XOR_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002119 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002120 shadow_frame.SetVReg(vregA,
2121 shadow_frame.GetVReg(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002122 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002123 ADVANCE(1);
2124 }
2125 HANDLE_INSTRUCTION_END();
2126
2127 HANDLE_INSTRUCTION_START(ADD_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002128 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002129 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002130 SafeAdd(shadow_frame.GetVRegLong(vregA),
2131 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002132 ADVANCE(1);
2133 }
2134 HANDLE_INSTRUCTION_END();
2135
2136 HANDLE_INSTRUCTION_START(SUB_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002137 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002138 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002139 SafeSub(shadow_frame.GetVRegLong(vregA),
2140 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002141 ADVANCE(1);
2142 }
2143 HANDLE_INSTRUCTION_END();
2144
2145 HANDLE_INSTRUCTION_START(MUL_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 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002148 SafeMul(shadow_frame.GetVRegLong(vregA),
2149 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002150 ADVANCE(1);
2151 }
2152 HANDLE_INSTRUCTION_END();
2153
2154 HANDLE_INSTRUCTION_START(DIV_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002155 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002156 bool success = DoLongDivide(shadow_frame, vregA, 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 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2159 }
2160 HANDLE_INSTRUCTION_END();
2161
2162 HANDLE_INSTRUCTION_START(REM_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 bool success = DoLongRemainder(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002165 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002166 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2167 }
2168 HANDLE_INSTRUCTION_END();
2169
2170 HANDLE_INSTRUCTION_START(AND_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002171 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002172 shadow_frame.SetVRegLong(vregA,
2173 shadow_frame.GetVRegLong(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002174 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002175 ADVANCE(1);
2176 }
2177 HANDLE_INSTRUCTION_END();
2178
2179 HANDLE_INSTRUCTION_START(OR_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002180 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002181 shadow_frame.SetVRegLong(vregA,
2182 shadow_frame.GetVRegLong(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002183 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002184 ADVANCE(1);
2185 }
2186 HANDLE_INSTRUCTION_END();
2187
2188 HANDLE_INSTRUCTION_START(XOR_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002189 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002190 shadow_frame.SetVRegLong(vregA,
2191 shadow_frame.GetVRegLong(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002192 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002193 ADVANCE(1);
2194 }
2195 HANDLE_INSTRUCTION_END();
2196
2197 HANDLE_INSTRUCTION_START(SHL_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002198 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002199 shadow_frame.SetVRegLong(vregA,
2200 shadow_frame.GetVRegLong(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002201 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002202 ADVANCE(1);
2203 }
2204 HANDLE_INSTRUCTION_END();
2205
2206 HANDLE_INSTRUCTION_START(SHR_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002207 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002208 shadow_frame.SetVRegLong(vregA,
2209 shadow_frame.GetVRegLong(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002210 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002211 ADVANCE(1);
2212 }
2213 HANDLE_INSTRUCTION_END();
2214
2215 HANDLE_INSTRUCTION_START(USHR_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002216 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002217 shadow_frame.SetVRegLong(vregA,
2218 static_cast<uint64_t>(shadow_frame.GetVRegLong(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002219 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002220 ADVANCE(1);
2221 }
2222 HANDLE_INSTRUCTION_END();
2223
2224 HANDLE_INSTRUCTION_START(ADD_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002225 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002226 shadow_frame.SetVRegFloat(vregA,
2227 shadow_frame.GetVRegFloat(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002228 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002229 ADVANCE(1);
2230 }
2231 HANDLE_INSTRUCTION_END();
2232
2233 HANDLE_INSTRUCTION_START(SUB_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002234 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002235 shadow_frame.SetVRegFloat(vregA,
2236 shadow_frame.GetVRegFloat(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002237 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002238 ADVANCE(1);
2239 }
2240 HANDLE_INSTRUCTION_END();
2241
2242 HANDLE_INSTRUCTION_START(MUL_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002243 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002244 shadow_frame.SetVRegFloat(vregA,
2245 shadow_frame.GetVRegFloat(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002246 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002247 ADVANCE(1);
2248 }
2249 HANDLE_INSTRUCTION_END();
2250
2251 HANDLE_INSTRUCTION_START(DIV_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002252 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002253 shadow_frame.SetVRegFloat(vregA,
2254 shadow_frame.GetVRegFloat(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002255 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002256 ADVANCE(1);
2257 }
2258 HANDLE_INSTRUCTION_END();
2259
2260 HANDLE_INSTRUCTION_START(REM_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002261 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002262 shadow_frame.SetVRegFloat(vregA,
2263 fmodf(shadow_frame.GetVRegFloat(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002264 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002265 ADVANCE(1);
2266 }
2267 HANDLE_INSTRUCTION_END();
2268
2269 HANDLE_INSTRUCTION_START(ADD_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002270 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002271 shadow_frame.SetVRegDouble(vregA,
2272 shadow_frame.GetVRegDouble(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002273 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002274 ADVANCE(1);
2275 }
2276 HANDLE_INSTRUCTION_END();
2277
2278 HANDLE_INSTRUCTION_START(SUB_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002279 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002280 shadow_frame.SetVRegDouble(vregA,
2281 shadow_frame.GetVRegDouble(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002282 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002283 ADVANCE(1);
2284 }
2285 HANDLE_INSTRUCTION_END();
2286
2287 HANDLE_INSTRUCTION_START(MUL_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002288 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002289 shadow_frame.SetVRegDouble(vregA,
2290 shadow_frame.GetVRegDouble(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002291 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002292 ADVANCE(1);
2293 }
2294 HANDLE_INSTRUCTION_END();
2295
2296 HANDLE_INSTRUCTION_START(DIV_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002297 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002298 shadow_frame.SetVRegDouble(vregA,
2299 shadow_frame.GetVRegDouble(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002300 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002301 ADVANCE(1);
2302 }
2303 HANDLE_INSTRUCTION_END();
2304
2305 HANDLE_INSTRUCTION_START(REM_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002306 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002307 shadow_frame.SetVRegDouble(vregA,
2308 fmod(shadow_frame.GetVRegDouble(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002309 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002310 ADVANCE(1);
2311 }
2312 HANDLE_INSTRUCTION_END();
2313
2314 HANDLE_INSTRUCTION_START(ADD_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002315 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002316 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2317 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002318 ADVANCE(2);
2319 HANDLE_INSTRUCTION_END();
2320
2321 HANDLE_INSTRUCTION_START(RSUB_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002322 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002323 SafeSub(inst->VRegC_22s(),
2324 shadow_frame.GetVReg(inst->VRegB_22s(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002325 ADVANCE(2);
2326 HANDLE_INSTRUCTION_END();
2327
2328 HANDLE_INSTRUCTION_START(MUL_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002329 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002330 SafeMul(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2331 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002332 ADVANCE(2);
2333 HANDLE_INSTRUCTION_END();
2334
2335 HANDLE_INSTRUCTION_START(DIV_INT_LIT16) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002336 bool success = DoIntDivide(
2337 shadow_frame, inst->VRegA_22s(inst_data), shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2338 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002339 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2340 }
2341 HANDLE_INSTRUCTION_END();
2342
2343 HANDLE_INSTRUCTION_START(REM_INT_LIT16) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002344 bool success = DoIntRemainder(
2345 shadow_frame, inst->VRegA_22s(inst_data), shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2346 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002347 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2348 }
2349 HANDLE_INSTRUCTION_END();
2350
2351 HANDLE_INSTRUCTION_START(AND_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002352 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2353 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) &
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002354 inst->VRegC_22s());
2355 ADVANCE(2);
2356 HANDLE_INSTRUCTION_END();
2357
2358 HANDLE_INSTRUCTION_START(OR_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002359 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2360 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) |
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002361 inst->VRegC_22s());
2362 ADVANCE(2);
2363 HANDLE_INSTRUCTION_END();
2364
2365 HANDLE_INSTRUCTION_START(XOR_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002366 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2367 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) ^
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002368 inst->VRegC_22s());
2369 ADVANCE(2);
2370 HANDLE_INSTRUCTION_END();
2371
2372 HANDLE_INSTRUCTION_START(ADD_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002373 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002374 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22b()),
2375 inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002376 ADVANCE(2);
2377 HANDLE_INSTRUCTION_END();
2378
2379 HANDLE_INSTRUCTION_START(RSUB_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002380 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002381 SafeSub(inst->VRegC_22b(),
2382 shadow_frame.GetVReg(inst->VRegB_22b())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002383 ADVANCE(2);
2384 HANDLE_INSTRUCTION_END();
2385
2386 HANDLE_INSTRUCTION_START(MUL_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002387 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002388 SafeMul(shadow_frame.GetVReg(inst->VRegB_22b()),
2389 inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002390 ADVANCE(2);
2391 HANDLE_INSTRUCTION_END();
2392
2393 HANDLE_INSTRUCTION_START(DIV_INT_LIT8) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002394 bool success = DoIntDivide(shadow_frame, inst->VRegA_22b(inst_data),
2395 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002396 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2397 }
2398 HANDLE_INSTRUCTION_END();
2399
2400 HANDLE_INSTRUCTION_START(REM_INT_LIT8) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002401 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22b(inst_data),
2402 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002403 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2404 }
2405 HANDLE_INSTRUCTION_END();
2406
2407 HANDLE_INSTRUCTION_START(AND_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002408 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002409 shadow_frame.GetVReg(inst->VRegB_22b()) &
2410 inst->VRegC_22b());
2411 ADVANCE(2);
2412 HANDLE_INSTRUCTION_END();
2413
2414 HANDLE_INSTRUCTION_START(OR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002415 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002416 shadow_frame.GetVReg(inst->VRegB_22b()) |
2417 inst->VRegC_22b());
2418 ADVANCE(2);
2419 HANDLE_INSTRUCTION_END();
2420
2421 HANDLE_INSTRUCTION_START(XOR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002422 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002423 shadow_frame.GetVReg(inst->VRegB_22b()) ^
2424 inst->VRegC_22b());
2425 ADVANCE(2);
2426 HANDLE_INSTRUCTION_END();
2427
2428 HANDLE_INSTRUCTION_START(SHL_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002429 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002430 shadow_frame.GetVReg(inst->VRegB_22b()) <<
2431 (inst->VRegC_22b() & 0x1f));
2432 ADVANCE(2);
2433 HANDLE_INSTRUCTION_END();
2434
2435 HANDLE_INSTRUCTION_START(SHR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002436 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002437 shadow_frame.GetVReg(inst->VRegB_22b()) >>
2438 (inst->VRegC_22b() & 0x1f));
2439 ADVANCE(2);
2440 HANDLE_INSTRUCTION_END();
2441
2442 HANDLE_INSTRUCTION_START(USHR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002443 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002444 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_22b())) >>
2445 (inst->VRegC_22b() & 0x1f));
2446 ADVANCE(2);
2447 HANDLE_INSTRUCTION_END();
2448
Igor Murashkin158f35c2015-06-10 15:55:30 -07002449 HANDLE_EXPERIMENTAL_INSTRUCTION_START(CREATE_LAMBDA) {
Igor Murashkin6918bf12015-09-27 19:19:06 -07002450 if (lambda_closure_builder == nullptr) {
2451 // DoCreateLambda always needs a ClosureBuilder, even if it has 0 captured variables.
2452 lambda_closure_builder = MakeUnique<lambda::ClosureBuilder>();
2453 }
2454
2455 // TODO: these allocations should not leak, and the lambda method should not be local.
2456 lambda::Closure* lambda_closure =
2457 reinterpret_cast<lambda::Closure*>(alloca(lambda_closure_builder->GetSize()));
2458 bool success = DoCreateLambda<do_access_check>(self,
2459 inst,
2460 /*inout*/shadow_frame,
2461 /*inout*/lambda_closure_builder.get(),
2462 /*inout*/lambda_closure);
2463 lambda_closure_builder.reset(nullptr); // reset state of variables captured
Igor Murashkin158f35c2015-06-10 15:55:30 -07002464 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2465 }
2466 HANDLE_EXPERIMENTAL_INSTRUCTION_END();
2467
Igor Murashkin2ee54e22015-06-18 10:05:11 -07002468 HANDLE_EXPERIMENTAL_INSTRUCTION_START(BOX_LAMBDA) {
2469 bool success = DoBoxLambda<do_access_check>(self, shadow_frame, inst, inst_data);
2470 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2471 }
2472 HANDLE_EXPERIMENTAL_INSTRUCTION_END();
2473
2474 HANDLE_EXPERIMENTAL_INSTRUCTION_START(UNBOX_LAMBDA) {
2475 bool success = DoUnboxLambda<do_access_check>(self, shadow_frame, inst, inst_data);
2476 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2477 }
2478 HANDLE_EXPERIMENTAL_INSTRUCTION_END();
2479
Igor Murashkin6918bf12015-09-27 19:19:06 -07002480 HANDLE_EXPERIMENTAL_INSTRUCTION_START(CAPTURE_VARIABLE) {
2481 if (lambda_closure_builder == nullptr) {
2482 lambda_closure_builder = MakeUnique<lambda::ClosureBuilder>();
2483 }
2484
2485 bool success = DoCaptureVariable<do_access_check>(self,
2486 inst,
2487 /*inout*/shadow_frame,
2488 /*inout*/lambda_closure_builder.get());
2489
2490 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2491 }
2492 HANDLE_EXPERIMENTAL_INSTRUCTION_END();
2493
2494 HANDLE_EXPERIMENTAL_INSTRUCTION_START(LIBERATE_VARIABLE) {
2495 bool success = DoLiberateVariable<do_access_check>(self,
2496 inst,
2497 lambda_captured_variable_index,
2498 /*inout*/shadow_frame);
2499 // Temporarily only allow sequences of 'liberate-variable, liberate-variable, ...'
2500 lambda_captured_variable_index++;
2501 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2502 }
2503 HANDLE_EXPERIMENTAL_INSTRUCTION_END();
2504
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002505 HANDLE_INSTRUCTION_START(UNUSED_3E)
Ian Rogerse94652f2014-12-02 11:13:19 -08002506 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002507 HANDLE_INSTRUCTION_END();
2508
2509 HANDLE_INSTRUCTION_START(UNUSED_3F)
Ian Rogerse94652f2014-12-02 11:13:19 -08002510 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002511 HANDLE_INSTRUCTION_END();
2512
2513 HANDLE_INSTRUCTION_START(UNUSED_40)
Ian Rogerse94652f2014-12-02 11:13:19 -08002514 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002515 HANDLE_INSTRUCTION_END();
2516
2517 HANDLE_INSTRUCTION_START(UNUSED_41)
Ian Rogerse94652f2014-12-02 11:13:19 -08002518 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002519 HANDLE_INSTRUCTION_END();
2520
2521 HANDLE_INSTRUCTION_START(UNUSED_42)
Ian Rogerse94652f2014-12-02 11:13:19 -08002522 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002523 HANDLE_INSTRUCTION_END();
2524
2525 HANDLE_INSTRUCTION_START(UNUSED_43)
Ian Rogerse94652f2014-12-02 11:13:19 -08002526 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002527 HANDLE_INSTRUCTION_END();
2528
2529 HANDLE_INSTRUCTION_START(UNUSED_79)
Ian Rogerse94652f2014-12-02 11:13:19 -08002530 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002531 HANDLE_INSTRUCTION_END();
2532
2533 HANDLE_INSTRUCTION_START(UNUSED_7A)
Ian Rogerse94652f2014-12-02 11:13:19 -08002534 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002535 HANDLE_INSTRUCTION_END();
2536
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002537 HANDLE_INSTRUCTION_START(UNUSED_F4)
Ian Rogerse94652f2014-12-02 11:13:19 -08002538 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002539 HANDLE_INSTRUCTION_END();
2540
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002541 HANDLE_INSTRUCTION_START(UNUSED_FA)
Ian Rogerse94652f2014-12-02 11:13:19 -08002542 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002543 HANDLE_INSTRUCTION_END();
2544
2545 HANDLE_INSTRUCTION_START(UNUSED_FB)
Ian Rogerse94652f2014-12-02 11:13:19 -08002546 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002547 HANDLE_INSTRUCTION_END();
2548
2549 HANDLE_INSTRUCTION_START(UNUSED_FC)
Ian Rogerse94652f2014-12-02 11:13:19 -08002550 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002551 HANDLE_INSTRUCTION_END();
2552
2553 HANDLE_INSTRUCTION_START(UNUSED_FD)
Ian Rogerse94652f2014-12-02 11:13:19 -08002554 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002555 HANDLE_INSTRUCTION_END();
2556
2557 HANDLE_INSTRUCTION_START(UNUSED_FE)
Ian Rogerse94652f2014-12-02 11:13:19 -08002558 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002559 HANDLE_INSTRUCTION_END();
2560
2561 HANDLE_INSTRUCTION_START(UNUSED_FF)
Ian Rogerse94652f2014-12-02 11:13:19 -08002562 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002563 HANDLE_INSTRUCTION_END();
2564
2565 exception_pending_label: {
2566 CHECK(self->IsExceptionPending());
Sebastien Hertz1eda2262013-09-09 16:53:14 +02002567 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -07002568 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +02002569 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +02002570 }
Sebastien Hertzee1997a2013-09-19 14:47:09 +02002571 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002572 uint32_t found_dex_pc = FindNextInstructionFollowingException(self, shadow_frame, dex_pc,
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002573 instrumentation);
2574 if (found_dex_pc == DexFile::kDexNoIndex) {
Andreas Gampe03ec9302015-08-27 17:41:47 -07002575 // Structured locking is to be enforced for abnormal termination, too.
2576 shadow_frame.GetLockCountData().CheckAllMonitorsReleasedOrThrow<do_assignability_check>(self);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002577 return JValue(); /* Handled in caller. */
2578 } else {
2579 int32_t displacement = static_cast<int32_t>(found_dex_pc) - static_cast<int32_t>(dex_pc);
2580 ADVANCE(displacement);
2581 }
2582 }
2583
Sebastien Hertz8379b222014-02-24 17:38:15 +01002584// Create alternative instruction handlers dedicated to instrumentation.
2585// Return instructions must not call Instrumentation::DexPcMovedEvent since they already call
2586// Instrumentation::MethodExited. This is to avoid posting debugger events twice for this location.
Sebastien Hertze713d932014-05-15 10:48:53 +02002587// Note: we do not use the kReturn instruction flag here (to test the instruction is a return). The
2588// compiler seems to not evaluate "(Instruction::FlagsOf(Instruction::code) & kReturn) != 0" to
2589// a constant condition that would remove the "if" statement so the test is free.
Sebastien Hertz9d6bf692015-04-10 12:12:33 +02002590#define INSTRUMENTATION_INSTRUCTION_HANDLER(o, code, n, f, r, i, a, v) \
2591 alt_op_##code: { \
2592 Runtime* const runtime = Runtime::Current(); \
2593 const instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation(); \
2594 if (UNLIKELY(instrumentation->HasDexPcListeners())) { \
2595 Object* this_object = shadow_frame.GetThisObject(code_item->ins_size_); \
2596 instrumentation->DexPcMovedEvent(self, this_object, shadow_frame.GetMethod(), dex_pc); \
2597 } \
2598 UPDATE_HANDLER_TABLE(); \
2599 goto *handlersTable[instrumentation::kMainHandlerTable][Instruction::code]; \
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002600 }
2601#include "dex_instruction_list.h"
2602 DEX_INSTRUCTION_LIST(INSTRUMENTATION_INSTRUCTION_HANDLER)
2603#undef DEX_INSTRUCTION_LIST
2604#undef INSTRUMENTATION_INSTRUCTION_HANDLER
2605} // NOLINT(readability/fn_size)
2606
2607// Explicit definitions of ExecuteGotoImpl.
Mathieu Chartier90443472015-07-16 20:32:27 -07002608template SHARED_REQUIRES(Locks::mutator_lock_) HOT_ATTR
Ian Rogerse94652f2014-12-02 11:13:19 -08002609JValue ExecuteGotoImpl<true, false>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002610 ShadowFrame& shadow_frame, JValue result_register);
Mathieu Chartier90443472015-07-16 20:32:27 -07002611template SHARED_REQUIRES(Locks::mutator_lock_) HOT_ATTR
Ian Rogerse94652f2014-12-02 11:13:19 -08002612JValue ExecuteGotoImpl<false, false>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002613 ShadowFrame& shadow_frame, JValue result_register);
Mathieu Chartier90443472015-07-16 20:32:27 -07002614template SHARED_REQUIRES(Locks::mutator_lock_)
Ian Rogerse94652f2014-12-02 11:13:19 -08002615JValue ExecuteGotoImpl<true, true>(Thread* self, const DexFile::CodeItem* code_item,
2616 ShadowFrame& shadow_frame, JValue result_register);
Mathieu Chartier90443472015-07-16 20:32:27 -07002617template SHARED_REQUIRES(Locks::mutator_lock_)
Ian Rogerse94652f2014-12-02 11:13:19 -08002618JValue ExecuteGotoImpl<false, true>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002619 ShadowFrame& shadow_frame, JValue result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002620
2621} // namespace interpreter
2622} // namespace art
Colin Crosse84e4f72015-03-18 14:01:19 -07002623
2624#endif