blob: 72e2ba0e7b4893bff4c125dbe2966f449855a045 [file] [log] [blame]
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Colin Crosse84e4f72015-03-18 14:01:19 -070017#if !defined(__clang__)
18// Clang 3.4 fails to build the goto interpreter implementation.
19
Sebastien Hertz8ece0502013-08-07 11:26:41 +020020#include "interpreter_common.h"
Ian Rogersf72a11d2014-10-30 15:41:08 -070021#include "safe_math.h"
Sebastien Hertz8ece0502013-08-07 11:26:41 +020022
23namespace art {
24namespace interpreter {
25
26// In the following macros, we expect the following local variables exist:
27// - "self": the current Thread*.
28// - "inst" : the current Instruction*.
Sebastien Hertz3b588e02013-09-11 14:33:18 +020029// - "inst_data" : the current instruction's first 16 bits.
Sebastien Hertz8ece0502013-08-07 11:26:41 +020030// - "dex_pc": the current pc.
31// - "shadow_frame": the current shadow frame.
Sebastien Hertz8ece0502013-08-07 11:26:41 +020032// - "currentHandlersTable": the current table of pointer to each instruction handler.
33
34// Advance to the next instruction and updates interpreter state.
Sebastien Hertz8ece0502013-08-07 11:26:41 +020035#define ADVANCE(_offset) \
36 do { \
37 int32_t disp = static_cast<int32_t>(_offset); \
38 inst = inst->RelativeAt(disp); \
39 dex_pc = static_cast<uint32_t>(static_cast<int32_t>(dex_pc) + disp); \
40 shadow_frame.SetDexPC(dex_pc); \
Ian Rogerse94652f2014-12-02 11:13:19 -080041 TraceExecution(shadow_frame, inst, dex_pc); \
Sebastien Hertz3b588e02013-09-11 14:33:18 +020042 inst_data = inst->Fetch16(0); \
43 goto *currentHandlersTable[inst->Opcode(inst_data)]; \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020044 } while (false)
45
46#define HANDLE_PENDING_EXCEPTION() goto exception_pending_label
47
48#define POSSIBLY_HANDLE_PENDING_EXCEPTION(_is_exception_pending, _offset) \
49 do { \
50 if (UNLIKELY(_is_exception_pending)) { \
51 HANDLE_PENDING_EXCEPTION(); \
52 } else { \
53 ADVANCE(_offset); \
54 } \
55 } while (false)
56
Sebastien Hertzee1997a2013-09-19 14:47:09 +020057#define UPDATE_HANDLER_TABLE() \
Mathieu Chartier2cebb242015-04-21 16:50:40 -070058 currentHandlersTable = handlersTable[ \
59 Runtime::Current()->GetInstrumentation()->GetInterpreterHandlerTable()]
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +020060
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080061#define BACKWARD_BRANCH_INSTRUMENTATION(offset) \
62 do { \
63 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation(); \
64 instrumentation->BackwardBranch(self, shadow_frame.GetMethod(), offset); \
65 } while (false)
66
Sebastien Hertz8ece0502013-08-07 11:26:41 +020067#define UNREACHABLE_CODE_CHECK() \
68 do { \
69 if (kIsDebugBuild) { \
70 LOG(FATAL) << "We should not be here !"; \
Ian Rogerse94652f2014-12-02 11:13:19 -080071 UNREACHABLE(); \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020072 } \
73 } while (false)
74
75#define HANDLE_INSTRUCTION_START(opcode) op_##opcode: // NOLINT(whitespace/labels)
76#define HANDLE_INSTRUCTION_END() UNREACHABLE_CODE_CHECK()
77
Igor Murashkin158f35c2015-06-10 15:55:30 -070078// Use with instructions labeled with kExperimental flag:
79#define HANDLE_EXPERIMENTAL_INSTRUCTION_START(opcode) \
80 HANDLE_INSTRUCTION_START(opcode); \
81 DCHECK(inst->IsExperimental()); \
82 if (Runtime::Current()->AreExperimentalLambdasEnabled()) {
83#define HANDLE_EXPERIMENTAL_INSTRUCTION_END() \
84 } else { \
85 UnexpectedOpcode(inst, shadow_frame); \
86 } HANDLE_INSTRUCTION_END();
87
88
Sebastien Hertzee1997a2013-09-19 14:47:09 +020089/**
90 * Interpreter based on computed goto tables.
91 *
92 * Each instruction is associated to a handler. This handler is responsible for executing the
93 * instruction and jump to the next instruction's handler.
94 * In order to limit the cost of instrumentation, we have two handler tables:
95 * - the "main" handler table: it contains handlers for normal execution of each instruction without
96 * handling of instrumentation.
97 * - the "alternative" handler table: it contains alternative handlers which first handle
98 * instrumentation before jumping to the corresponding "normal" instruction's handler.
99 *
100 * When instrumentation is active, the interpreter uses the "alternative" handler table. Otherwise
101 * it uses the "main" handler table.
102 *
103 * The current handler table is the handler table being used by the interpreter. It is updated:
104 * - on backward branch (goto, if and switch instructions)
105 * - after invoke
106 * - when an exception is thrown.
107 * This allows to support an attaching debugger to an already running application for instance.
108 *
109 * For a fast handler table update, handler tables are stored in an array of handler tables. Each
110 * handler table is represented by the InterpreterHandlerTable enum which allows to associate it
111 * to an index in this array of handler tables ((see Instrumentation::GetInterpreterHandlerTable).
112 *
113 * Here's the current layout of this array of handler tables:
114 *
115 * ---------------------+---------------+
116 * | NOP | (handler for NOP instruction)
117 * +---------------+
118 * "main" | MOVE | (handler for MOVE instruction)
119 * handler table +---------------+
120 * | ... |
121 * +---------------+
122 * | UNUSED_FF | (handler for UNUSED_FF instruction)
123 * ---------------------+---------------+
124 * | NOP | (alternative handler for NOP instruction)
125 * +---------------+
126 * "alternative" | MOVE | (alternative handler for MOVE instruction)
127 * handler table +---------------+
128 * | ... |
129 * +---------------+
130 * | UNUSED_FF | (alternative handler for UNUSED_FF instruction)
131 * ---------------------+---------------+
132 *
133 */
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100134template<bool do_access_check, bool transaction_active>
Ian Rogerse94652f2014-12-02 11:13:19 -0800135JValue ExecuteGotoImpl(Thread* self, const DexFile::CodeItem* code_item, ShadowFrame& shadow_frame,
136 JValue result_register) {
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200137 // Define handler tables:
138 // - The main handler table contains execution handlers for each instruction.
139 // - The alternative handler table contains prelude handlers which check for thread suspend and
140 // manage instrumentation before jumping to the execution handler.
141 static const void* const handlersTable[instrumentation::kNumHandlerTables][kNumPackedOpcodes] = {
142 {
143 // Main handler table.
144#define INSTRUCTION_HANDLER(o, code, n, f, r, i, a, v) &&op_##code,
145#include "dex_instruction_list.h"
146 DEX_INSTRUCTION_LIST(INSTRUCTION_HANDLER)
147#undef DEX_INSTRUCTION_LIST
148#undef INSTRUCTION_HANDLER
149 }, {
150 // Alternative handler table.
151#define INSTRUCTION_HANDLER(o, code, n, f, r, i, a, v) &&alt_op_##code,
152#include "dex_instruction_list.h"
153 DEX_INSTRUCTION_LIST(INSTRUCTION_HANDLER)
154#undef DEX_INSTRUCTION_LIST
155#undef INSTRUCTION_HANDLER
156 }
157 };
158
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800159 constexpr bool do_assignability_check = do_access_check;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200160 if (UNLIKELY(!shadow_frame.HasReferenceArray())) {
161 LOG(FATAL) << "Invalid shadow frame for interpreter use";
162 return JValue();
163 }
164 self->VerifyStack();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200165
166 uint32_t dex_pc = shadow_frame.GetDexPC();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200167 const Instruction* inst = Instruction::At(code_item->insns_ + dex_pc);
168 uint16_t inst_data;
169 const void* const* currentHandlersTable;
170 UPDATE_HANDLER_TABLE();
Sebastien Hertz270a0e12015-01-16 19:49:09 +0100171 if (LIKELY(dex_pc == 0)) { // We are entering the method as opposed to deoptimizing.
172 if (kIsDebugBuild) {
173 self->AssertNoPendingException();
174 }
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200175 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200176 if (UNLIKELY(instrumentation->HasMethodEntryListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200177 instrumentation->MethodEnterEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200178 shadow_frame.GetMethod(), 0);
179 }
180 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200181
182 // Jump to first instruction.
183 ADVANCE(0);
184 UNREACHABLE_CODE_CHECK();
185
186 HANDLE_INSTRUCTION_START(NOP)
187 ADVANCE(1);
188 HANDLE_INSTRUCTION_END();
189
190 HANDLE_INSTRUCTION_START(MOVE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200191 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
192 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200193 ADVANCE(1);
194 HANDLE_INSTRUCTION_END();
195
196 HANDLE_INSTRUCTION_START(MOVE_FROM16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200197 shadow_frame.SetVReg(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200198 shadow_frame.GetVReg(inst->VRegB_22x()));
199 ADVANCE(2);
200 HANDLE_INSTRUCTION_END();
201
202 HANDLE_INSTRUCTION_START(MOVE_16)
203 shadow_frame.SetVReg(inst->VRegA_32x(),
204 shadow_frame.GetVReg(inst->VRegB_32x()));
205 ADVANCE(3);
206 HANDLE_INSTRUCTION_END();
207
208 HANDLE_INSTRUCTION_START(MOVE_WIDE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200209 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
210 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200211 ADVANCE(1);
212 HANDLE_INSTRUCTION_END();
213
214 HANDLE_INSTRUCTION_START(MOVE_WIDE_FROM16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200215 shadow_frame.SetVRegLong(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200216 shadow_frame.GetVRegLong(inst->VRegB_22x()));
217 ADVANCE(2);
218 HANDLE_INSTRUCTION_END();
219
220 HANDLE_INSTRUCTION_START(MOVE_WIDE_16)
221 shadow_frame.SetVRegLong(inst->VRegA_32x(),
222 shadow_frame.GetVRegLong(inst->VRegB_32x()));
223 ADVANCE(3);
224 HANDLE_INSTRUCTION_END();
225
226 HANDLE_INSTRUCTION_START(MOVE_OBJECT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200227 shadow_frame.SetVRegReference(inst->VRegA_12x(inst_data),
228 shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200229 ADVANCE(1);
230 HANDLE_INSTRUCTION_END();
231
232 HANDLE_INSTRUCTION_START(MOVE_OBJECT_FROM16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200233 shadow_frame.SetVRegReference(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200234 shadow_frame.GetVRegReference(inst->VRegB_22x()));
235 ADVANCE(2);
236 HANDLE_INSTRUCTION_END();
237
238 HANDLE_INSTRUCTION_START(MOVE_OBJECT_16)
239 shadow_frame.SetVRegReference(inst->VRegA_32x(),
240 shadow_frame.GetVRegReference(inst->VRegB_32x()));
241 ADVANCE(3);
242 HANDLE_INSTRUCTION_END();
243
244 HANDLE_INSTRUCTION_START(MOVE_RESULT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200245 shadow_frame.SetVReg(inst->VRegA_11x(inst_data), result_register.GetI());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200246 ADVANCE(1);
247 HANDLE_INSTRUCTION_END();
248
249 HANDLE_INSTRUCTION_START(MOVE_RESULT_WIDE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200250 shadow_frame.SetVRegLong(inst->VRegA_11x(inst_data), result_register.GetJ());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200251 ADVANCE(1);
252 HANDLE_INSTRUCTION_END();
253
254 HANDLE_INSTRUCTION_START(MOVE_RESULT_OBJECT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200255 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), result_register.GetL());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200256 ADVANCE(1);
257 HANDLE_INSTRUCTION_END();
258
259 HANDLE_INSTRUCTION_START(MOVE_EXCEPTION) {
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000260 Throwable* exception = self->GetException();
Sebastien Hertz270a0e12015-01-16 19:49:09 +0100261 DCHECK(exception != nullptr) << "No pending exception on MOVE_EXCEPTION instruction";
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200262 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), exception);
Sebastien Hertz5c004902014-05-21 10:07:42 +0200263 self->ClearException();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200264 ADVANCE(1);
265 }
266 HANDLE_INSTRUCTION_END();
267
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700268 HANDLE_INSTRUCTION_START(RETURN_VOID_NO_BARRIER) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200269 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700270 self->AllowThreadSuspension();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200271 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200272 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200273 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200274 shadow_frame.GetMethod(), dex_pc,
275 result);
276 }
277 return result;
278 }
279 HANDLE_INSTRUCTION_END();
280
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700281 HANDLE_INSTRUCTION_START(RETURN_VOID) {
Hans Boehm30359612014-05-21 17:46:23 -0700282 QuasiAtomic::ThreadFenceForConstructor();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200283 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700284 self->AllowThreadSuspension();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200285 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200286 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200287 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200288 shadow_frame.GetMethod(), dex_pc,
289 result);
290 }
291 return result;
292 }
293 HANDLE_INSTRUCTION_END();
294
295 HANDLE_INSTRUCTION_START(RETURN) {
296 JValue result;
297 result.SetJ(0);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200298 result.SetI(shadow_frame.GetVReg(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700299 self->AllowThreadSuspension();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200300 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200301 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200302 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200303 shadow_frame.GetMethod(), dex_pc,
304 result);
305 }
306 return result;
307 }
308 HANDLE_INSTRUCTION_END();
309
310 HANDLE_INSTRUCTION_START(RETURN_WIDE) {
311 JValue result;
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200312 result.SetJ(shadow_frame.GetVRegLong(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700313 self->AllowThreadSuspension();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200314 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200315 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200316 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200317 shadow_frame.GetMethod(), dex_pc,
318 result);
319 }
320 return result;
321 }
322 HANDLE_INSTRUCTION_END();
323
324 HANDLE_INSTRUCTION_START(RETURN_OBJECT) {
325 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700326 self->AllowThreadSuspension();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700327 const uint8_t vreg_index = inst->VRegA_11x(inst_data);
328 Object* obj_result = shadow_frame.GetVRegReference(vreg_index);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700329 if (do_assignability_check && obj_result != nullptr) {
Vladimir Marko05792b92015-08-03 11:56:49 +0100330 size_t pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
331 Class* return_type = shadow_frame.GetMethod()->GetReturnType(true /* resolve */,
332 pointer_size);
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700333 obj_result = shadow_frame.GetVRegReference(vreg_index);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700334 if (return_type == nullptr) {
Jeff Haoa3faaf42013-09-03 19:07:00 -0700335 // Return the pending exception.
336 HANDLE_PENDING_EXCEPTION();
337 }
338 if (!obj_result->VerifierInstanceOf(return_type)) {
339 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700340 std::string temp1, temp2;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000341 self->ThrowNewExceptionF("Ljava/lang/VirtualMachineError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700342 "Returning '%s' that is not instance of return type '%s'",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700343 obj_result->GetClass()->GetDescriptor(&temp1),
344 return_type->GetDescriptor(&temp2));
Jeff Haoa3faaf42013-09-03 19:07:00 -0700345 HANDLE_PENDING_EXCEPTION();
346 }
347 }
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700348 result.SetL(obj_result);
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200349 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200350 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200351 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200352 shadow_frame.GetMethod(), dex_pc,
353 result);
354 }
355 return result;
356 }
357 HANDLE_INSTRUCTION_END();
358
359 HANDLE_INSTRUCTION_START(CONST_4) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200360 uint32_t dst = inst->VRegA_11n(inst_data);
361 int32_t val = inst->VRegB_11n(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200362 shadow_frame.SetVReg(dst, val);
363 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700364 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200365 }
366 ADVANCE(1);
367 }
368 HANDLE_INSTRUCTION_END();
369
370 HANDLE_INSTRUCTION_START(CONST_16) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200371 uint32_t dst = inst->VRegA_21s(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200372 int32_t val = inst->VRegB_21s();
373 shadow_frame.SetVReg(dst, val);
374 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700375 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200376 }
377 ADVANCE(2);
378 }
379 HANDLE_INSTRUCTION_END();
380
381 HANDLE_INSTRUCTION_START(CONST) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200382 uint32_t dst = inst->VRegA_31i(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200383 int32_t val = inst->VRegB_31i();
384 shadow_frame.SetVReg(dst, val);
385 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700386 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200387 }
388 ADVANCE(3);
389 }
390 HANDLE_INSTRUCTION_END();
391
392 HANDLE_INSTRUCTION_START(CONST_HIGH16) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200393 uint32_t dst = inst->VRegA_21h(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200394 int32_t val = static_cast<int32_t>(inst->VRegB_21h() << 16);
395 shadow_frame.SetVReg(dst, val);
396 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700397 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200398 }
399 ADVANCE(2);
400 }
401 HANDLE_INSTRUCTION_END();
402
403 HANDLE_INSTRUCTION_START(CONST_WIDE_16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200404 shadow_frame.SetVRegLong(inst->VRegA_21s(inst_data), inst->VRegB_21s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200405 ADVANCE(2);
406 HANDLE_INSTRUCTION_END();
407
408 HANDLE_INSTRUCTION_START(CONST_WIDE_32)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200409 shadow_frame.SetVRegLong(inst->VRegA_31i(inst_data), inst->VRegB_31i());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200410 ADVANCE(3);
411 HANDLE_INSTRUCTION_END();
412
413 HANDLE_INSTRUCTION_START(CONST_WIDE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200414 shadow_frame.SetVRegLong(inst->VRegA_51l(inst_data), inst->VRegB_51l());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200415 ADVANCE(5);
416 HANDLE_INSTRUCTION_END();
417
418 HANDLE_INSTRUCTION_START(CONST_WIDE_HIGH16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200419 shadow_frame.SetVRegLong(inst->VRegA_21h(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200420 static_cast<uint64_t>(inst->VRegB_21h()) << 48);
421 ADVANCE(2);
422 HANDLE_INSTRUCTION_END();
423
424 HANDLE_INSTRUCTION_START(CONST_STRING) {
Ian Rogers6786a582014-10-28 12:49:06 -0700425 String* s = ResolveString(self, shadow_frame, inst->VRegB_21c());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700426 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200427 HANDLE_PENDING_EXCEPTION();
428 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200429 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200430 ADVANCE(2);
431 }
432 }
433 HANDLE_INSTRUCTION_END();
434
435 HANDLE_INSTRUCTION_START(CONST_STRING_JUMBO) {
Ian Rogers6786a582014-10-28 12:49:06 -0700436 String* s = ResolveString(self, shadow_frame, inst->VRegB_31c());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700437 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200438 HANDLE_PENDING_EXCEPTION();
439 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200440 shadow_frame.SetVRegReference(inst->VRegA_31c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200441 ADVANCE(3);
442 }
443 }
444 HANDLE_INSTRUCTION_END();
445
446 HANDLE_INSTRUCTION_START(CONST_CLASS) {
447 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
448 self, false, do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700449 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200450 HANDLE_PENDING_EXCEPTION();
451 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200452 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), c);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200453 ADVANCE(2);
454 }
455 }
456 HANDLE_INSTRUCTION_END();
457
458 HANDLE_INSTRUCTION_START(MONITOR_ENTER) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200459 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700460 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000461 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200462 HANDLE_PENDING_EXCEPTION();
463 } else {
464 DoMonitorEnter(self, obj);
465 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), 1);
466 }
467 }
468 HANDLE_INSTRUCTION_END();
469
470 HANDLE_INSTRUCTION_START(MONITOR_EXIT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200471 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700472 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000473 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200474 HANDLE_PENDING_EXCEPTION();
475 } else {
476 DoMonitorExit(self, obj);
477 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), 1);
478 }
479 }
480 HANDLE_INSTRUCTION_END();
481
482 HANDLE_INSTRUCTION_START(CHECK_CAST) {
483 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
484 self, false, do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700485 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200486 HANDLE_PENDING_EXCEPTION();
487 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200488 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_21c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700489 if (UNLIKELY(obj != nullptr && !obj->InstanceOf(c))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200490 ThrowClassCastException(c, obj->GetClass());
491 HANDLE_PENDING_EXCEPTION();
492 } else {
493 ADVANCE(2);
494 }
495 }
496 }
497 HANDLE_INSTRUCTION_END();
498
499 HANDLE_INSTRUCTION_START(INSTANCE_OF) {
500 Class* c = ResolveVerifyAndClinit(inst->VRegC_22c(), shadow_frame.GetMethod(),
501 self, false, do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700502 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200503 HANDLE_PENDING_EXCEPTION();
504 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200505 Object* obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700506 shadow_frame.SetVReg(inst->VRegA_22c(inst_data), (obj != nullptr && obj->InstanceOf(c)) ? 1 : 0);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200507 ADVANCE(2);
508 }
509 }
510 HANDLE_INSTRUCTION_END();
511
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700512 HANDLE_INSTRUCTION_START(ARRAY_LENGTH) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200513 Object* array = shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700514 if (UNLIKELY(array == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000515 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200516 HANDLE_PENDING_EXCEPTION();
517 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200518 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), array->AsArray()->GetLength());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200519 ADVANCE(1);
520 }
521 }
522 HANDLE_INSTRUCTION_END();
523
524 HANDLE_INSTRUCTION_START(NEW_INSTANCE) {
Jeff Hao848f70a2014-01-15 13:49:50 -0800525 Object* obj = nullptr;
526 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
527 self, false, do_access_check);
528 if (LIKELY(c != nullptr)) {
529 if (UNLIKELY(c->IsStringClass())) {
530 gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
531 mirror::SetStringCountVisitor visitor(0);
532 obj = String::Alloc<true>(self, 0, allocator_type, visitor);
533 } else {
534 obj = AllocObjectFromCode<do_access_check, true>(
535 inst->VRegB_21c(), shadow_frame.GetMethod(), self,
536 Runtime::Current()->GetHeap()->GetCurrentAllocator());
537 }
538 }
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700539 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200540 HANDLE_PENDING_EXCEPTION();
541 } else {
Sebastien Hertz4e99b3d2014-06-24 14:35:40 +0200542 obj->GetClass()->AssertInitializedOrInitializingInThread(self);
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700543 // Don't allow finalizable objects to be allocated during a transaction since these can't be
544 // finalized without a started runtime.
545 if (transaction_active && obj->GetClass()->IsFinalizable()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +0200546 AbortTransactionF(self, "Allocating finalizable object in transaction: %s",
547 PrettyTypeOf(obj).c_str());
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700548 HANDLE_PENDING_EXCEPTION();
549 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200550 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200551 ADVANCE(2);
552 }
553 }
554 HANDLE_INSTRUCTION_END();
555
556 HANDLE_INSTRUCTION_START(NEW_ARRAY) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200557 int32_t length = shadow_frame.GetVReg(inst->VRegB_22c(inst_data));
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800558 Object* obj = AllocArrayFromCode<do_access_check, true>(
Andreas Gampe1cc7dba2014-12-17 18:43:01 -0800559 inst->VRegC_22c(), length, shadow_frame.GetMethod(), self,
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800560 Runtime::Current()->GetHeap()->GetCurrentAllocator());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700561 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200562 HANDLE_PENDING_EXCEPTION();
563 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200564 shadow_frame.SetVRegReference(inst->VRegA_22c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200565 ADVANCE(2);
566 }
567 }
568 HANDLE_INSTRUCTION_END();
569
570 HANDLE_INSTRUCTION_START(FILLED_NEW_ARRAY) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100571 bool success =
572 DoFilledNewArray<false, do_access_check, transaction_active>(inst, shadow_frame,
573 self, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200574 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
575 }
576 HANDLE_INSTRUCTION_END();
577
578 HANDLE_INSTRUCTION_START(FILLED_NEW_ARRAY_RANGE) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100579 bool success =
580 DoFilledNewArray<true, do_access_check, transaction_active>(inst, shadow_frame,
581 self, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200582 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
583 }
584 HANDLE_INSTRUCTION_END();
585
586 HANDLE_INSTRUCTION_START(FILL_ARRAY_DATA) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200587 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_31t(inst_data));
Ian Rogers832336b2014-10-08 15:35:22 -0700588 const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t();
589 const Instruction::ArrayDataPayload* payload =
590 reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr);
591 bool success = FillArrayData(obj, payload);
592 if (transaction_active && success) {
593 RecordArrayElementsInTransaction(obj->AsArray(), payload->element_count);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200594 }
Ian Rogers832336b2014-10-08 15:35:22 -0700595 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200596 }
597 HANDLE_INSTRUCTION_END();
598
599 HANDLE_INSTRUCTION_START(THROW) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200600 Object* exception = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700601 if (UNLIKELY(exception == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000602 ThrowNullPointerException("throw with null exception");
Jeff Haoa3faaf42013-09-03 19:07:00 -0700603 } else if (do_assignability_check && !exception->GetClass()->IsThrowableClass()) {
604 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700605 std::string temp;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000606 self->ThrowNewExceptionF("Ljava/lang/VirtualMachineError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700607 "Throwing '%s' that is not instance of Throwable",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700608 exception->GetClass()->GetDescriptor(&temp));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200609 } else {
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000610 self->SetException(exception->AsThrowable());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200611 }
612 HANDLE_PENDING_EXCEPTION();
613 }
614 HANDLE_INSTRUCTION_END();
615
616 HANDLE_INSTRUCTION_START(GOTO) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200617 int8_t offset = inst->VRegA_10t(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200618 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800619 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200620 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700621 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200622 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200623 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200624 }
625 ADVANCE(offset);
626 }
627 HANDLE_INSTRUCTION_END();
628
629 HANDLE_INSTRUCTION_START(GOTO_16) {
630 int16_t offset = inst->VRegA_20t();
631 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800632 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200633 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700634 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200635 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200636 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200637 }
638 ADVANCE(offset);
639 }
640 HANDLE_INSTRUCTION_END();
641
642 HANDLE_INSTRUCTION_START(GOTO_32) {
643 int32_t offset = inst->VRegA_30t();
644 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800645 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200646 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700647 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200648 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200649 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200650 }
651 ADVANCE(offset);
652 }
653 HANDLE_INSTRUCTION_END();
654
655 HANDLE_INSTRUCTION_START(PACKED_SWITCH) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200656 int32_t offset = DoPackedSwitch(inst, shadow_frame, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200657 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800658 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200659 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700660 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200661 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200662 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200663 }
664 ADVANCE(offset);
665 }
666 HANDLE_INSTRUCTION_END();
667
668 HANDLE_INSTRUCTION_START(SPARSE_SWITCH) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200669 int32_t offset = DoSparseSwitch(inst, shadow_frame, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200670 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800671 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200672 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700673 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200674 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200675 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200676 }
677 ADVANCE(offset);
678 }
679 HANDLE_INSTRUCTION_END();
680
Ian Rogers647b1a82014-10-10 11:02:11 -0700681#if defined(__clang__)
682#pragma clang diagnostic push
683#pragma clang diagnostic ignored "-Wfloat-equal"
684#endif
685
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200686 HANDLE_INSTRUCTION_START(CMPL_FLOAT) {
687 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
688 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
689 int32_t result;
690 if (val1 > val2) {
691 result = 1;
692 } else if (val1 == val2) {
693 result = 0;
694 } else {
695 result = -1;
696 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200697 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200698 ADVANCE(2);
699 }
700 HANDLE_INSTRUCTION_END();
701
702 HANDLE_INSTRUCTION_START(CMPG_FLOAT) {
703 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
704 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
705 int32_t result;
706 if (val1 < val2) {
707 result = -1;
708 } else if (val1 == val2) {
709 result = 0;
710 } else {
711 result = 1;
712 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200713 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200714 ADVANCE(2);
715 }
716 HANDLE_INSTRUCTION_END();
717
718 HANDLE_INSTRUCTION_START(CMPL_DOUBLE) {
719 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
720 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
721 int32_t result;
722 if (val1 > val2) {
723 result = 1;
724 } else if (val1 == val2) {
725 result = 0;
726 } else {
727 result = -1;
728 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200729 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200730 ADVANCE(2);
731 }
732 HANDLE_INSTRUCTION_END();
733
734 HANDLE_INSTRUCTION_START(CMPG_DOUBLE) {
735 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
736 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
737 int32_t result;
738 if (val1 < val2) {
739 result = -1;
740 } else if (val1 == val2) {
741 result = 0;
742 } else {
743 result = 1;
744 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200745 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200746 ADVANCE(2);
747 }
748 HANDLE_INSTRUCTION_END();
749
Ian Rogers647b1a82014-10-10 11:02:11 -0700750#if defined(__clang__)
751#pragma clang diagnostic pop
752#endif
753
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200754 HANDLE_INSTRUCTION_START(CMP_LONG) {
755 int64_t val1 = shadow_frame.GetVRegLong(inst->VRegB_23x());
756 int64_t val2 = shadow_frame.GetVRegLong(inst->VRegC_23x());
757 int32_t result;
758 if (val1 > val2) {
759 result = 1;
760 } else if (val1 == val2) {
761 result = 0;
762 } else {
763 result = -1;
764 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200765 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200766 ADVANCE(2);
767 }
768 HANDLE_INSTRUCTION_END();
769
770 HANDLE_INSTRUCTION_START(IF_EQ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200771 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) == shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200772 int16_t offset = inst->VRegC_22t();
773 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800774 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200775 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700776 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200777 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200778 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200779 }
780 ADVANCE(offset);
781 } else {
782 ADVANCE(2);
783 }
784 }
785 HANDLE_INSTRUCTION_END();
786
787 HANDLE_INSTRUCTION_START(IF_NE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700788 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) !=
789 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200790 int16_t offset = inst->VRegC_22t();
791 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800792 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200793 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700794 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200795 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200796 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200797 }
798 ADVANCE(offset);
799 } else {
800 ADVANCE(2);
801 }
802 }
803 HANDLE_INSTRUCTION_END();
804
805 HANDLE_INSTRUCTION_START(IF_LT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700806 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <
807 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200808 int16_t offset = inst->VRegC_22t();
809 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800810 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200811 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700812 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200813 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200814 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200815 }
816 ADVANCE(offset);
817 } else {
818 ADVANCE(2);
819 }
820 }
821 HANDLE_INSTRUCTION_END();
822
823 HANDLE_INSTRUCTION_START(IF_GE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700824 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >=
825 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200826 int16_t offset = inst->VRegC_22t();
827 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800828 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200829 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700830 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200831 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200832 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200833 }
834 ADVANCE(offset);
835 } else {
836 ADVANCE(2);
837 }
838 }
839 HANDLE_INSTRUCTION_END();
840
841 HANDLE_INSTRUCTION_START(IF_GT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700842 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >
843 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200844 int16_t offset = inst->VRegC_22t();
845 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800846 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200847 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700848 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200849 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200850 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200851 }
852 ADVANCE(offset);
853 } else {
854 ADVANCE(2);
855 }
856 }
857 HANDLE_INSTRUCTION_END();
858
859 HANDLE_INSTRUCTION_START(IF_LE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700860 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <=
861 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200862 int16_t offset = inst->VRegC_22t();
863 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800864 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200865 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700866 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200867 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200868 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200869 }
870 ADVANCE(offset);
871 } else {
872 ADVANCE(2);
873 }
874 }
875 HANDLE_INSTRUCTION_END();
876
877 HANDLE_INSTRUCTION_START(IF_EQZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200878 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) == 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200879 int16_t offset = inst->VRegB_21t();
880 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800881 BACKWARD_BRANCH_INSTRUMENTATION(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_NEZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200895 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) != 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200896 int16_t offset = inst->VRegB_21t();
897 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800898 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200899 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700900 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200901 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200902 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200903 }
904 ADVANCE(offset);
905 } else {
906 ADVANCE(2);
907 }
908 }
909 HANDLE_INSTRUCTION_END();
910
911 HANDLE_INSTRUCTION_START(IF_LTZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200912 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) < 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200913 int16_t offset = inst->VRegB_21t();
914 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800915 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200916 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700917 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200918 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200919 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200920 }
921 ADVANCE(offset);
922 } else {
923 ADVANCE(2);
924 }
925 }
926 HANDLE_INSTRUCTION_END();
927
928 HANDLE_INSTRUCTION_START(IF_GEZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200929 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) >= 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200930 int16_t offset = inst->VRegB_21t();
931 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800932 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200933 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700934 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200935 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200936 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200937 }
938 ADVANCE(offset);
939 } else {
940 ADVANCE(2);
941 }
942 }
943 HANDLE_INSTRUCTION_END();
944
945 HANDLE_INSTRUCTION_START(IF_GTZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200946 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) > 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200947 int16_t offset = inst->VRegB_21t();
948 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800949 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200950 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700951 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200952 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200953 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200954 }
955 ADVANCE(offset);
956 } else {
957 ADVANCE(2);
958 }
959 }
960 HANDLE_INSTRUCTION_END();
961
962 HANDLE_INSTRUCTION_START(IF_LEZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200963 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) <= 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200964 int16_t offset = inst->VRegB_21t();
965 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800966 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200967 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700968 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200969 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200970 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200971 }
972 ADVANCE(offset);
973 } else {
974 ADVANCE(2);
975 }
976 }
977 HANDLE_INSTRUCTION_END();
978
979 HANDLE_INSTRUCTION_START(AGET_BOOLEAN) {
980 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700981 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000982 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200983 HANDLE_PENDING_EXCEPTION();
984 } else {
985 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
986 BooleanArray* array = a->AsBooleanArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +0100987 if (LIKELY(array->CheckIsValidIndex(index))) {
988 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200989 ADVANCE(2);
990 } else {
991 HANDLE_PENDING_EXCEPTION();
992 }
993 }
994 }
995 HANDLE_INSTRUCTION_END();
996
997 HANDLE_INSTRUCTION_START(AGET_BYTE) {
998 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700999 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001000 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001001 HANDLE_PENDING_EXCEPTION();
1002 } else {
1003 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1004 ByteArray* array = a->AsByteArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001005 if (LIKELY(array->CheckIsValidIndex(index))) {
1006 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001007 ADVANCE(2);
1008 } else {
1009 HANDLE_PENDING_EXCEPTION();
1010 }
1011 }
1012 }
1013 HANDLE_INSTRUCTION_END();
1014
1015 HANDLE_INSTRUCTION_START(AGET_CHAR) {
1016 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001017 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001018 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001019 HANDLE_PENDING_EXCEPTION();
1020 } else {
1021 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1022 CharArray* array = a->AsCharArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001023 if (LIKELY(array->CheckIsValidIndex(index))) {
1024 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001025 ADVANCE(2);
1026 } else {
1027 HANDLE_PENDING_EXCEPTION();
1028 }
1029 }
1030 }
1031 HANDLE_INSTRUCTION_END();
1032
1033 HANDLE_INSTRUCTION_START(AGET_SHORT) {
1034 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001035 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001036 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001037 HANDLE_PENDING_EXCEPTION();
1038 } else {
1039 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1040 ShortArray* array = a->AsShortArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001041 if (LIKELY(array->CheckIsValidIndex(index))) {
1042 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001043 ADVANCE(2);
1044 } else {
1045 HANDLE_PENDING_EXCEPTION();
1046 }
1047 }
1048 }
1049 HANDLE_INSTRUCTION_END();
1050
1051 HANDLE_INSTRUCTION_START(AGET) {
1052 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001053 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001054 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001055 HANDLE_PENDING_EXCEPTION();
1056 } else {
1057 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001058 DCHECK(a->IsIntArray() || a->IsFloatArray()) << PrettyTypeOf(a);
1059 auto* array = down_cast<IntArray*>(a);
Sebastien Hertzabff6432014-01-27 18:01:39 +01001060 if (LIKELY(array->CheckIsValidIndex(index))) {
1061 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001062 ADVANCE(2);
1063 } else {
1064 HANDLE_PENDING_EXCEPTION();
1065 }
1066 }
1067 }
1068 HANDLE_INSTRUCTION_END();
1069
1070 HANDLE_INSTRUCTION_START(AGET_WIDE) {
1071 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001072 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001073 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001074 HANDLE_PENDING_EXCEPTION();
1075 } else {
1076 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001077 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << PrettyTypeOf(a);
1078 auto* array = down_cast<LongArray*>(a);
Sebastien Hertzabff6432014-01-27 18:01:39 +01001079 if (LIKELY(array->CheckIsValidIndex(index))) {
1080 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001081 ADVANCE(2);
1082 } else {
1083 HANDLE_PENDING_EXCEPTION();
1084 }
1085 }
1086 }
1087 HANDLE_INSTRUCTION_END();
1088
1089 HANDLE_INSTRUCTION_START(AGET_OBJECT) {
1090 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001091 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001092 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001093 HANDLE_PENDING_EXCEPTION();
1094 } else {
1095 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1096 ObjectArray<Object>* array = a->AsObjectArray<Object>();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001097 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001098 shadow_frame.SetVRegReference(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001099 ADVANCE(2);
1100 } else {
1101 HANDLE_PENDING_EXCEPTION();
1102 }
1103 }
1104 }
1105 HANDLE_INSTRUCTION_END();
1106
1107 HANDLE_INSTRUCTION_START(APUT_BOOLEAN) {
1108 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001109 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001110 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001111 HANDLE_PENDING_EXCEPTION();
1112 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001113 uint8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001114 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1115 BooleanArray* array = a->AsBooleanArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001116 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001117 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001118 ADVANCE(2);
1119 } else {
1120 HANDLE_PENDING_EXCEPTION();
1121 }
1122 }
1123 }
1124 HANDLE_INSTRUCTION_END();
1125
1126 HANDLE_INSTRUCTION_START(APUT_BYTE) {
1127 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001128 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001129 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001130 HANDLE_PENDING_EXCEPTION();
1131 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001132 int8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001133 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1134 ByteArray* array = a->AsByteArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001135 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001136 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001137 ADVANCE(2);
1138 } else {
1139 HANDLE_PENDING_EXCEPTION();
1140 }
1141 }
1142 }
1143 HANDLE_INSTRUCTION_END();
1144
1145 HANDLE_INSTRUCTION_START(APUT_CHAR) {
1146 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001147 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001148 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001149 HANDLE_PENDING_EXCEPTION();
1150 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001151 uint16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001152 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1153 CharArray* array = a->AsCharArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001154 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001155 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001156 ADVANCE(2);
1157 } else {
1158 HANDLE_PENDING_EXCEPTION();
1159 }
1160 }
1161 }
1162 HANDLE_INSTRUCTION_END();
1163
1164 HANDLE_INSTRUCTION_START(APUT_SHORT) {
1165 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001166 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001167 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001168 HANDLE_PENDING_EXCEPTION();
1169 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001170 int16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001171 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1172 ShortArray* array = a->AsShortArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001173 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001174 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001175 ADVANCE(2);
1176 } else {
1177 HANDLE_PENDING_EXCEPTION();
1178 }
1179 }
1180 }
1181 HANDLE_INSTRUCTION_END();
1182
1183 HANDLE_INSTRUCTION_START(APUT) {
1184 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001185 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001186 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001187 HANDLE_PENDING_EXCEPTION();
1188 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001189 int32_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001190 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001191 DCHECK(a->IsIntArray() || a->IsFloatArray()) << PrettyTypeOf(a);
1192 auto* array = down_cast<IntArray*>(a);
Sebastien Hertzabff6432014-01-27 18:01:39 +01001193 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001194 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001195 ADVANCE(2);
1196 } else {
1197 HANDLE_PENDING_EXCEPTION();
1198 }
1199 }
1200 }
1201 HANDLE_INSTRUCTION_END();
1202
1203 HANDLE_INSTRUCTION_START(APUT_WIDE) {
1204 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001205 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001206 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001207 HANDLE_PENDING_EXCEPTION();
1208 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001209 int64_t val = shadow_frame.GetVRegLong(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001210 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001211 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << PrettyTypeOf(a);
1212 auto* array = down_cast<LongArray*>(a);
Sebastien Hertzabff6432014-01-27 18:01:39 +01001213 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001214 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001215 ADVANCE(2);
1216 } else {
1217 HANDLE_PENDING_EXCEPTION();
1218 }
1219 }
1220 }
1221 HANDLE_INSTRUCTION_END();
1222
1223 HANDLE_INSTRUCTION_START(APUT_OBJECT) {
1224 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001225 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001226 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001227 HANDLE_PENDING_EXCEPTION();
1228 } else {
1229 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001230 Object* val = shadow_frame.GetVRegReference(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001231 ObjectArray<Object>* array = a->AsObjectArray<Object>();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001232 if (LIKELY(array->CheckIsValidIndex(index) && array->CheckAssignable(val))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001233 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001234 ADVANCE(2);
1235 } else {
1236 HANDLE_PENDING_EXCEPTION();
1237 }
1238 }
1239 }
1240 HANDLE_INSTRUCTION_END();
1241
1242 HANDLE_INSTRUCTION_START(IGET_BOOLEAN) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001243 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimBoolean, do_access_check>(
1244 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001245 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1246 }
1247 HANDLE_INSTRUCTION_END();
1248
1249 HANDLE_INSTRUCTION_START(IGET_BYTE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001250 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimByte, do_access_check>(
1251 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001252 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1253 }
1254 HANDLE_INSTRUCTION_END();
1255
1256 HANDLE_INSTRUCTION_START(IGET_CHAR) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001257 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimChar, do_access_check>(
1258 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001259 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1260 }
1261 HANDLE_INSTRUCTION_END();
1262
1263 HANDLE_INSTRUCTION_START(IGET_SHORT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001264 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimShort, do_access_check>(
1265 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001266 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1267 }
1268 HANDLE_INSTRUCTION_END();
1269
1270 HANDLE_INSTRUCTION_START(IGET) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001271 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimInt, do_access_check>(
1272 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001273 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1274 }
1275 HANDLE_INSTRUCTION_END();
1276
1277 HANDLE_INSTRUCTION_START(IGET_WIDE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001278 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimLong, 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_OBJECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001285 bool success = DoFieldGet<InstanceObjectRead, Primitive::kPrimNot, 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_QUICK) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001292 bool success = DoIGetQuick<Primitive::kPrimInt>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001293 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1294 }
1295 HANDLE_INSTRUCTION_END();
1296
Mathieu Chartierffc605c2014-12-10 10:35:44 -08001297 HANDLE_INSTRUCTION_START(IGET_BOOLEAN_QUICK) {
1298 bool success = DoIGetQuick<Primitive::kPrimBoolean>(shadow_frame, inst, inst_data);
1299 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1300 }
1301 HANDLE_INSTRUCTION_END();
1302
1303 HANDLE_INSTRUCTION_START(IGET_BYTE_QUICK) {
1304 bool success = DoIGetQuick<Primitive::kPrimByte>(shadow_frame, inst, inst_data);
1305 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1306 }
1307 HANDLE_INSTRUCTION_END();
1308
1309 HANDLE_INSTRUCTION_START(IGET_CHAR_QUICK) {
1310 bool success = DoIGetQuick<Primitive::kPrimChar>(shadow_frame, inst, inst_data);
1311 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1312 }
1313 HANDLE_INSTRUCTION_END();
1314
1315 HANDLE_INSTRUCTION_START(IGET_SHORT_QUICK) {
1316 bool success = DoIGetQuick<Primitive::kPrimShort>(shadow_frame, inst, inst_data);
1317 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1318 }
1319 HANDLE_INSTRUCTION_END();
1320
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001321 HANDLE_INSTRUCTION_START(IGET_WIDE_QUICK) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001322 bool success = DoIGetQuick<Primitive::kPrimLong>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001323 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1324 }
1325 HANDLE_INSTRUCTION_END();
1326
1327 HANDLE_INSTRUCTION_START(IGET_OBJECT_QUICK) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001328 bool success = DoIGetQuick<Primitive::kPrimNot>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001329 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1330 }
1331 HANDLE_INSTRUCTION_END();
1332
1333 HANDLE_INSTRUCTION_START(SGET_BOOLEAN) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001334 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimBoolean, do_access_check>(
1335 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001336 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1337 }
1338 HANDLE_INSTRUCTION_END();
1339
1340 HANDLE_INSTRUCTION_START(SGET_BYTE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001341 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimByte, do_access_check>(
1342 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001343 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1344 }
1345 HANDLE_INSTRUCTION_END();
1346
1347 HANDLE_INSTRUCTION_START(SGET_CHAR) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001348 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimChar, do_access_check>(
1349 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001350 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1351 }
1352 HANDLE_INSTRUCTION_END();
1353
1354 HANDLE_INSTRUCTION_START(SGET_SHORT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001355 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimShort, do_access_check>(
1356 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001357 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1358 }
1359 HANDLE_INSTRUCTION_END();
1360
1361 HANDLE_INSTRUCTION_START(SGET) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001362 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimInt, do_access_check>(
1363 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001364 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1365 }
1366 HANDLE_INSTRUCTION_END();
1367
1368 HANDLE_INSTRUCTION_START(SGET_WIDE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001369 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimLong, 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_OBJECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001376 bool success = DoFieldGet<StaticObjectRead, Primitive::kPrimNot, 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(IPUT_BOOLEAN) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001383 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1384 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001385 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1386 }
1387 HANDLE_INSTRUCTION_END();
1388
1389 HANDLE_INSTRUCTION_START(IPUT_BYTE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001390 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimByte, do_access_check,
1391 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001392 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1393 }
1394 HANDLE_INSTRUCTION_END();
1395
1396 HANDLE_INSTRUCTION_START(IPUT_CHAR) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001397 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimChar, do_access_check,
1398 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001399 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1400 }
1401 HANDLE_INSTRUCTION_END();
1402
1403 HANDLE_INSTRUCTION_START(IPUT_SHORT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001404 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimShort, do_access_check,
1405 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001406 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1407 }
1408 HANDLE_INSTRUCTION_END();
1409
1410 HANDLE_INSTRUCTION_START(IPUT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001411 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimInt, do_access_check,
1412 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001413 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1414 }
1415 HANDLE_INSTRUCTION_END();
1416
1417 HANDLE_INSTRUCTION_START(IPUT_WIDE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001418 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimLong, 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_OBJECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001425 bool success = DoFieldPut<InstanceObjectWrite, Primitive::kPrimNot, 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_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001432 bool success = DoIPutQuick<Primitive::kPrimInt, transaction_active>(
1433 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
Fred Shih37f05ef2014-07-16 18:38:08 -07001438 HANDLE_INSTRUCTION_START(IPUT_BOOLEAN_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001439 bool success = DoIPutQuick<Primitive::kPrimBoolean, transaction_active>(
1440 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001441 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1442 }
1443 HANDLE_INSTRUCTION_END();
1444
1445 HANDLE_INSTRUCTION_START(IPUT_BYTE_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001446 bool success = DoIPutQuick<Primitive::kPrimByte, transaction_active>(
1447 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001448 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1449 }
1450 HANDLE_INSTRUCTION_END();
1451
1452 HANDLE_INSTRUCTION_START(IPUT_CHAR_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001453 bool success = DoIPutQuick<Primitive::kPrimChar, transaction_active>(
1454 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001455 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1456 }
1457 HANDLE_INSTRUCTION_END();
1458
1459 HANDLE_INSTRUCTION_START(IPUT_SHORT_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001460 bool success = DoIPutQuick<Primitive::kPrimShort, transaction_active>(
1461 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001462 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1463 }
1464 HANDLE_INSTRUCTION_END();
1465
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001466 HANDLE_INSTRUCTION_START(IPUT_WIDE_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001467 bool success = DoIPutQuick<Primitive::kPrimLong, 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
1473 HANDLE_INSTRUCTION_START(IPUT_OBJECT_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001474 bool success = DoIPutQuick<Primitive::kPrimNot, transaction_active>(
1475 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001476 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1477 }
1478 HANDLE_INSTRUCTION_END();
1479
1480 HANDLE_INSTRUCTION_START(SPUT_BOOLEAN) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001481 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1482 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001483 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1484 }
1485 HANDLE_INSTRUCTION_END();
1486
1487 HANDLE_INSTRUCTION_START(SPUT_BYTE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001488 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimByte, do_access_check,
1489 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001490 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1491 }
1492 HANDLE_INSTRUCTION_END();
1493
1494 HANDLE_INSTRUCTION_START(SPUT_CHAR) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001495 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimChar, do_access_check,
1496 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001497 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1498 }
1499 HANDLE_INSTRUCTION_END();
1500
1501 HANDLE_INSTRUCTION_START(SPUT_SHORT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001502 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimShort, do_access_check,
1503 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001504 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1505 }
1506 HANDLE_INSTRUCTION_END();
1507
1508 HANDLE_INSTRUCTION_START(SPUT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001509 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimInt, do_access_check,
1510 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001511 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1512 }
1513 HANDLE_INSTRUCTION_END();
1514
1515 HANDLE_INSTRUCTION_START(SPUT_WIDE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001516 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimLong, 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_OBJECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001523 bool success = DoFieldPut<StaticObjectWrite, Primitive::kPrimNot, 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(INVOKE_VIRTUAL) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001530 bool success = DoInvoke<kVirtual, false, do_access_check>(
1531 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001532 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001533 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1534 }
1535 HANDLE_INSTRUCTION_END();
1536
1537 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001538 bool success = DoInvoke<kVirtual, true, do_access_check>(
1539 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001540 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001541 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1542 }
1543 HANDLE_INSTRUCTION_END();
1544
1545 HANDLE_INSTRUCTION_START(INVOKE_SUPER) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001546 bool success = DoInvoke<kSuper, false, do_access_check>(
1547 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001548 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001549 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1550 }
1551 HANDLE_INSTRUCTION_END();
1552
1553 HANDLE_INSTRUCTION_START(INVOKE_SUPER_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001554 bool success = DoInvoke<kSuper, true, do_access_check>(
1555 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001556 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001557 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1558 }
1559 HANDLE_INSTRUCTION_END();
1560
1561 HANDLE_INSTRUCTION_START(INVOKE_DIRECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001562 bool success = DoInvoke<kDirect, false, do_access_check>(
1563 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001564 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001565 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1566 }
1567 HANDLE_INSTRUCTION_END();
1568
1569 HANDLE_INSTRUCTION_START(INVOKE_DIRECT_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001570 bool success = DoInvoke<kDirect, true, do_access_check>(
1571 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001572 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001573 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1574 }
1575 HANDLE_INSTRUCTION_END();
1576
1577 HANDLE_INSTRUCTION_START(INVOKE_INTERFACE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001578 bool success = DoInvoke<kInterface, false, do_access_check>(
1579 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001580 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001581 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1582 }
1583 HANDLE_INSTRUCTION_END();
1584
1585 HANDLE_INSTRUCTION_START(INVOKE_INTERFACE_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001586 bool success = DoInvoke<kInterface, true, do_access_check>(
1587 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001588 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001589 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1590 }
1591 HANDLE_INSTRUCTION_END();
1592
1593 HANDLE_INSTRUCTION_START(INVOKE_STATIC) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001594 bool success = DoInvoke<kStatic, false, do_access_check>(
1595 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001596 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001597 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1598 }
1599 HANDLE_INSTRUCTION_END();
1600
1601 HANDLE_INSTRUCTION_START(INVOKE_STATIC_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001602 bool success = DoInvoke<kStatic, true, do_access_check>(
1603 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001604 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001605 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1606 }
1607 HANDLE_INSTRUCTION_END();
1608
1609 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001610 bool success = DoInvokeVirtualQuick<false>(
1611 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001612 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001613 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1614 }
1615 HANDLE_INSTRUCTION_END();
1616
1617 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_RANGE_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001618 bool success = DoInvokeVirtualQuick<true>(
1619 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001620 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001621 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1622 }
1623 HANDLE_INSTRUCTION_END();
1624
Igor Murashkin158f35c2015-06-10 15:55:30 -07001625 HANDLE_EXPERIMENTAL_INSTRUCTION_START(INVOKE_LAMBDA) {
1626 bool success = DoInvokeLambda<do_access_check>(self, shadow_frame, inst, inst_data,
1627 &result_register);
1628 UPDATE_HANDLER_TABLE();
1629 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1630 }
1631 HANDLE_EXPERIMENTAL_INSTRUCTION_END();
1632
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001633 HANDLE_INSTRUCTION_START(NEG_INT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001634 shadow_frame.SetVReg(
1635 inst->VRegA_12x(inst_data), -shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001636 ADVANCE(1);
1637 HANDLE_INSTRUCTION_END();
1638
1639 HANDLE_INSTRUCTION_START(NOT_INT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001640 shadow_frame.SetVReg(
1641 inst->VRegA_12x(inst_data), ~shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001642 ADVANCE(1);
1643 HANDLE_INSTRUCTION_END();
1644
1645 HANDLE_INSTRUCTION_START(NEG_LONG)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001646 shadow_frame.SetVRegLong(
1647 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001648 ADVANCE(1);
1649 HANDLE_INSTRUCTION_END();
1650
1651 HANDLE_INSTRUCTION_START(NOT_LONG)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001652 shadow_frame.SetVRegLong(
1653 inst->VRegA_12x(inst_data), ~shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001654 ADVANCE(1);
1655 HANDLE_INSTRUCTION_END();
1656
1657 HANDLE_INSTRUCTION_START(NEG_FLOAT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001658 shadow_frame.SetVRegFloat(
1659 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001660 ADVANCE(1);
1661 HANDLE_INSTRUCTION_END();
1662
1663 HANDLE_INSTRUCTION_START(NEG_DOUBLE)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001664 shadow_frame.SetVRegDouble(
1665 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001666 ADVANCE(1);
1667 HANDLE_INSTRUCTION_END();
1668
1669 HANDLE_INSTRUCTION_START(INT_TO_LONG)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001670 shadow_frame.SetVRegLong(
1671 inst->VRegA_12x(inst_data), shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001672 ADVANCE(1);
1673 HANDLE_INSTRUCTION_END();
1674
1675 HANDLE_INSTRUCTION_START(INT_TO_FLOAT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001676 shadow_frame.SetVRegFloat(
1677 inst->VRegA_12x(inst_data), shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001678 ADVANCE(1);
1679 HANDLE_INSTRUCTION_END();
1680
1681 HANDLE_INSTRUCTION_START(INT_TO_DOUBLE)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001682 shadow_frame.SetVRegDouble(
1683 inst->VRegA_12x(inst_data), shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001684 ADVANCE(1);
1685 HANDLE_INSTRUCTION_END();
1686
1687 HANDLE_INSTRUCTION_START(LONG_TO_INT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001688 shadow_frame.SetVReg(
1689 inst->VRegA_12x(inst_data), shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001690 ADVANCE(1);
1691 HANDLE_INSTRUCTION_END();
1692
1693 HANDLE_INSTRUCTION_START(LONG_TO_FLOAT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001694 shadow_frame.SetVRegFloat(
1695 inst->VRegA_12x(inst_data), shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001696 ADVANCE(1);
1697 HANDLE_INSTRUCTION_END();
1698
1699 HANDLE_INSTRUCTION_START(LONG_TO_DOUBLE)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001700 shadow_frame.SetVRegDouble(
1701 inst->VRegA_12x(inst_data), shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001702 ADVANCE(1);
1703 HANDLE_INSTRUCTION_END();
1704
1705 HANDLE_INSTRUCTION_START(FLOAT_TO_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001706 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001707 int32_t result = art_float_to_integral<int32_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001708 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001709 ADVANCE(1);
1710 }
1711 HANDLE_INSTRUCTION_END();
1712
1713 HANDLE_INSTRUCTION_START(FLOAT_TO_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001714 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001715 int64_t result = art_float_to_integral<int64_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001716 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001717 ADVANCE(1);
1718 }
1719 HANDLE_INSTRUCTION_END();
1720
1721 HANDLE_INSTRUCTION_START(FLOAT_TO_DOUBLE)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001722 shadow_frame.SetVRegDouble(
1723 inst->VRegA_12x(inst_data), shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001724 ADVANCE(1);
1725 HANDLE_INSTRUCTION_END();
1726
1727 HANDLE_INSTRUCTION_START(DOUBLE_TO_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001728 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001729 int32_t result = art_float_to_integral<int32_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001730 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001731 ADVANCE(1);
1732 }
1733 HANDLE_INSTRUCTION_END();
1734
1735 HANDLE_INSTRUCTION_START(DOUBLE_TO_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001736 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001737 int64_t result = art_float_to_integral<int64_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001738 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001739 ADVANCE(1);
1740 }
1741 HANDLE_INSTRUCTION_END();
1742
1743 HANDLE_INSTRUCTION_START(DOUBLE_TO_FLOAT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001744 shadow_frame.SetVRegFloat(
1745 inst->VRegA_12x(inst_data), shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001746 ADVANCE(1);
1747 HANDLE_INSTRUCTION_END();
1748
1749 HANDLE_INSTRUCTION_START(INT_TO_BYTE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001750 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1751 static_cast<int8_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001752 ADVANCE(1);
1753 HANDLE_INSTRUCTION_END();
1754
1755 HANDLE_INSTRUCTION_START(INT_TO_CHAR)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001756 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1757 static_cast<uint16_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001758 ADVANCE(1);
1759 HANDLE_INSTRUCTION_END();
1760
1761 HANDLE_INSTRUCTION_START(INT_TO_SHORT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001762 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1763 static_cast<int16_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001764 ADVANCE(1);
1765 HANDLE_INSTRUCTION_END();
1766
1767 HANDLE_INSTRUCTION_START(ADD_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001768 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001769 SafeAdd(shadow_frame.GetVReg(inst->VRegB_23x()),
1770 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001771 ADVANCE(2);
1772 HANDLE_INSTRUCTION_END();
1773
1774 HANDLE_INSTRUCTION_START(SUB_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001775 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001776 SafeSub(shadow_frame.GetVReg(inst->VRegB_23x()),
1777 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001778 ADVANCE(2);
1779 HANDLE_INSTRUCTION_END();
1780
1781 HANDLE_INSTRUCTION_START(MUL_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001782 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001783 SafeMul(shadow_frame.GetVReg(inst->VRegB_23x()),
1784 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001785 ADVANCE(2);
1786 HANDLE_INSTRUCTION_END();
1787
1788 HANDLE_INSTRUCTION_START(DIV_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001789 bool success = DoIntDivide(shadow_frame, inst->VRegA_23x(inst_data),
1790 shadow_frame.GetVReg(inst->VRegB_23x()),
1791 shadow_frame.GetVReg(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001792 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1793 }
1794 HANDLE_INSTRUCTION_END();
1795
1796 HANDLE_INSTRUCTION_START(REM_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001797 bool success = DoIntRemainder(shadow_frame, inst->VRegA_23x(inst_data),
1798 shadow_frame.GetVReg(inst->VRegB_23x()),
1799 shadow_frame.GetVReg(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001800 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1801 }
1802 HANDLE_INSTRUCTION_END();
1803
1804 HANDLE_INSTRUCTION_START(SHL_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001805 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001806 shadow_frame.GetVReg(inst->VRegB_23x()) <<
1807 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1808 ADVANCE(2);
1809 HANDLE_INSTRUCTION_END();
1810
1811 HANDLE_INSTRUCTION_START(SHR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001812 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001813 shadow_frame.GetVReg(inst->VRegB_23x()) >>
1814 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1815 ADVANCE(2);
1816 HANDLE_INSTRUCTION_END();
1817
1818 HANDLE_INSTRUCTION_START(USHR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001819 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001820 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_23x())) >>
1821 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1822 ADVANCE(2);
1823 HANDLE_INSTRUCTION_END();
1824
1825 HANDLE_INSTRUCTION_START(AND_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001826 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001827 shadow_frame.GetVReg(inst->VRegB_23x()) &
1828 shadow_frame.GetVReg(inst->VRegC_23x()));
1829 ADVANCE(2);
1830 HANDLE_INSTRUCTION_END();
1831
1832 HANDLE_INSTRUCTION_START(OR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001833 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001834 shadow_frame.GetVReg(inst->VRegB_23x()) |
1835 shadow_frame.GetVReg(inst->VRegC_23x()));
1836 ADVANCE(2);
1837 HANDLE_INSTRUCTION_END();
1838
1839 HANDLE_INSTRUCTION_START(XOR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001840 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001841 shadow_frame.GetVReg(inst->VRegB_23x()) ^
1842 shadow_frame.GetVReg(inst->VRegC_23x()));
1843 ADVANCE(2);
1844 HANDLE_INSTRUCTION_END();
1845
1846 HANDLE_INSTRUCTION_START(ADD_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001847 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001848 SafeAdd(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1849 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001850 ADVANCE(2);
1851 HANDLE_INSTRUCTION_END();
1852
1853 HANDLE_INSTRUCTION_START(SUB_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001854 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001855 SafeSub(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1856 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001857 ADVANCE(2);
1858 HANDLE_INSTRUCTION_END();
1859
1860 HANDLE_INSTRUCTION_START(MUL_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001861 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001862 SafeMul(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1863 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001864 ADVANCE(2);
1865 HANDLE_INSTRUCTION_END();
1866
1867 HANDLE_INSTRUCTION_START(DIV_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001868 bool success = DoLongDivide(shadow_frame, inst->VRegA_23x(inst_data),
1869 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1870 shadow_frame.GetVRegLong(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001871 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1872 }
1873 HANDLE_INSTRUCTION_END();
1874
1875 HANDLE_INSTRUCTION_START(REM_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001876 bool success = DoLongRemainder(shadow_frame, inst->VRegA_23x(inst_data),
1877 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1878 shadow_frame.GetVRegLong(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001879 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1880 }
1881 HANDLE_INSTRUCTION_END();
1882
1883 HANDLE_INSTRUCTION_START(AND_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001884 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001885 shadow_frame.GetVRegLong(inst->VRegB_23x()) &
1886 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1887 ADVANCE(2);
1888 HANDLE_INSTRUCTION_END();
1889
1890 HANDLE_INSTRUCTION_START(OR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001891 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001892 shadow_frame.GetVRegLong(inst->VRegB_23x()) |
1893 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1894 ADVANCE(2);
1895 HANDLE_INSTRUCTION_END();
1896
1897 HANDLE_INSTRUCTION_START(XOR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001898 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001899 shadow_frame.GetVRegLong(inst->VRegB_23x()) ^
1900 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1901 ADVANCE(2);
1902 HANDLE_INSTRUCTION_END();
1903
1904 HANDLE_INSTRUCTION_START(SHL_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001905 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001906 shadow_frame.GetVRegLong(inst->VRegB_23x()) <<
1907 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1908 ADVANCE(2);
1909 HANDLE_INSTRUCTION_END();
1910
1911 HANDLE_INSTRUCTION_START(SHR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001912 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001913 shadow_frame.GetVRegLong(inst->VRegB_23x()) >>
1914 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1915 ADVANCE(2);
1916 HANDLE_INSTRUCTION_END();
1917
1918 HANDLE_INSTRUCTION_START(USHR_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 static_cast<uint64_t>(shadow_frame.GetVRegLong(inst->VRegB_23x())) >>
1921 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1922 ADVANCE(2);
1923 HANDLE_INSTRUCTION_END();
1924
1925 HANDLE_INSTRUCTION_START(ADD_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001926 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001927 shadow_frame.GetVRegFloat(inst->VRegB_23x()) +
1928 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1929 ADVANCE(2);
1930 HANDLE_INSTRUCTION_END();
1931
1932 HANDLE_INSTRUCTION_START(SUB_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001933 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001934 shadow_frame.GetVRegFloat(inst->VRegB_23x()) -
1935 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1936 ADVANCE(2);
1937 HANDLE_INSTRUCTION_END();
1938
1939 HANDLE_INSTRUCTION_START(MUL_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001940 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001941 shadow_frame.GetVRegFloat(inst->VRegB_23x()) *
1942 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1943 ADVANCE(2);
1944 HANDLE_INSTRUCTION_END();
1945
1946 HANDLE_INSTRUCTION_START(DIV_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001947 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001948 shadow_frame.GetVRegFloat(inst->VRegB_23x()) /
1949 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1950 ADVANCE(2);
1951 HANDLE_INSTRUCTION_END();
1952
1953 HANDLE_INSTRUCTION_START(REM_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001954 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001955 fmodf(shadow_frame.GetVRegFloat(inst->VRegB_23x()),
1956 shadow_frame.GetVRegFloat(inst->VRegC_23x())));
1957 ADVANCE(2);
1958 HANDLE_INSTRUCTION_END();
1959
1960 HANDLE_INSTRUCTION_START(ADD_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001961 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001962 shadow_frame.GetVRegDouble(inst->VRegB_23x()) +
1963 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1964 ADVANCE(2);
1965 HANDLE_INSTRUCTION_END();
1966
1967 HANDLE_INSTRUCTION_START(SUB_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001968 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001969 shadow_frame.GetVRegDouble(inst->VRegB_23x()) -
1970 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1971 ADVANCE(2);
1972 HANDLE_INSTRUCTION_END();
1973
1974 HANDLE_INSTRUCTION_START(MUL_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001975 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001976 shadow_frame.GetVRegDouble(inst->VRegB_23x()) *
1977 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1978 ADVANCE(2);
1979 HANDLE_INSTRUCTION_END();
1980
1981 HANDLE_INSTRUCTION_START(DIV_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001982 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001983 shadow_frame.GetVRegDouble(inst->VRegB_23x()) /
1984 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1985 ADVANCE(2);
1986 HANDLE_INSTRUCTION_END();
1987
1988 HANDLE_INSTRUCTION_START(REM_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001989 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001990 fmod(shadow_frame.GetVRegDouble(inst->VRegB_23x()),
1991 shadow_frame.GetVRegDouble(inst->VRegC_23x())));
1992 ADVANCE(2);
1993 HANDLE_INSTRUCTION_END();
1994
1995 HANDLE_INSTRUCTION_START(ADD_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001996 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001997 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07001998 SafeAdd(shadow_frame.GetVReg(vregA),
1999 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002000 ADVANCE(1);
2001 }
2002 HANDLE_INSTRUCTION_END();
2003
2004 HANDLE_INSTRUCTION_START(SUB_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002005 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002006 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002007 SafeSub(shadow_frame.GetVReg(vregA),
2008 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002009 ADVANCE(1);
2010 }
2011 HANDLE_INSTRUCTION_END();
2012
2013 HANDLE_INSTRUCTION_START(MUL_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002014 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002015 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002016 SafeMul(shadow_frame.GetVReg(vregA),
2017 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002018 ADVANCE(1);
2019 }
2020 HANDLE_INSTRUCTION_END();
2021
2022 HANDLE_INSTRUCTION_START(DIV_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002023 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002024 bool success = DoIntDivide(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002025 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002026 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2027 }
2028 HANDLE_INSTRUCTION_END();
2029
2030 HANDLE_INSTRUCTION_START(REM_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 bool success = DoIntRemainder(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002033 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002034 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2035 }
2036 HANDLE_INSTRUCTION_END();
2037
2038 HANDLE_INSTRUCTION_START(SHL_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002039 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002040 shadow_frame.SetVReg(vregA,
2041 shadow_frame.GetVReg(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002042 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002043 ADVANCE(1);
2044 }
2045 HANDLE_INSTRUCTION_END();
2046
2047 HANDLE_INSTRUCTION_START(SHR_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002048 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002049 shadow_frame.SetVReg(vregA,
2050 shadow_frame.GetVReg(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002051 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002052 ADVANCE(1);
2053 }
2054 HANDLE_INSTRUCTION_END();
2055
2056 HANDLE_INSTRUCTION_START(USHR_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002057 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002058 shadow_frame.SetVReg(vregA,
2059 static_cast<uint32_t>(shadow_frame.GetVReg(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002060 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002061 ADVANCE(1);
2062 }
2063 HANDLE_INSTRUCTION_END();
2064
2065 HANDLE_INSTRUCTION_START(AND_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002066 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002067 shadow_frame.SetVReg(vregA,
2068 shadow_frame.GetVReg(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002069 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002070 ADVANCE(1);
2071 }
2072 HANDLE_INSTRUCTION_END();
2073
2074 HANDLE_INSTRUCTION_START(OR_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002075 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002076 shadow_frame.SetVReg(vregA,
2077 shadow_frame.GetVReg(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002078 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002079 ADVANCE(1);
2080 }
2081 HANDLE_INSTRUCTION_END();
2082
2083 HANDLE_INSTRUCTION_START(XOR_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002084 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002085 shadow_frame.SetVReg(vregA,
2086 shadow_frame.GetVReg(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002087 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002088 ADVANCE(1);
2089 }
2090 HANDLE_INSTRUCTION_END();
2091
2092 HANDLE_INSTRUCTION_START(ADD_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002093 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002094 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002095 SafeAdd(shadow_frame.GetVRegLong(vregA),
2096 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002097 ADVANCE(1);
2098 }
2099 HANDLE_INSTRUCTION_END();
2100
2101 HANDLE_INSTRUCTION_START(SUB_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002102 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002103 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002104 SafeSub(shadow_frame.GetVRegLong(vregA),
2105 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002106 ADVANCE(1);
2107 }
2108 HANDLE_INSTRUCTION_END();
2109
2110 HANDLE_INSTRUCTION_START(MUL_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002111 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002112 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002113 SafeMul(shadow_frame.GetVRegLong(vregA),
2114 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002115 ADVANCE(1);
2116 }
2117 HANDLE_INSTRUCTION_END();
2118
2119 HANDLE_INSTRUCTION_START(DIV_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002120 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002121 bool success = DoLongDivide(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002122 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002123 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2124 }
2125 HANDLE_INSTRUCTION_END();
2126
2127 HANDLE_INSTRUCTION_START(REM_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 bool success = DoLongRemainder(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002130 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002131 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2132 }
2133 HANDLE_INSTRUCTION_END();
2134
2135 HANDLE_INSTRUCTION_START(AND_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002136 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002137 shadow_frame.SetVRegLong(vregA,
2138 shadow_frame.GetVRegLong(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002139 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002140 ADVANCE(1);
2141 }
2142 HANDLE_INSTRUCTION_END();
2143
2144 HANDLE_INSTRUCTION_START(OR_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002145 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002146 shadow_frame.SetVRegLong(vregA,
2147 shadow_frame.GetVRegLong(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002148 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002149 ADVANCE(1);
2150 }
2151 HANDLE_INSTRUCTION_END();
2152
2153 HANDLE_INSTRUCTION_START(XOR_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002154 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002155 shadow_frame.SetVRegLong(vregA,
2156 shadow_frame.GetVRegLong(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002157 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002158 ADVANCE(1);
2159 }
2160 HANDLE_INSTRUCTION_END();
2161
2162 HANDLE_INSTRUCTION_START(SHL_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002163 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002164 shadow_frame.SetVRegLong(vregA,
2165 shadow_frame.GetVRegLong(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002166 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002167 ADVANCE(1);
2168 }
2169 HANDLE_INSTRUCTION_END();
2170
2171 HANDLE_INSTRUCTION_START(SHR_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002172 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002173 shadow_frame.SetVRegLong(vregA,
2174 shadow_frame.GetVRegLong(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002175 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002176 ADVANCE(1);
2177 }
2178 HANDLE_INSTRUCTION_END();
2179
2180 HANDLE_INSTRUCTION_START(USHR_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002181 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002182 shadow_frame.SetVRegLong(vregA,
2183 static_cast<uint64_t>(shadow_frame.GetVRegLong(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002184 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002185 ADVANCE(1);
2186 }
2187 HANDLE_INSTRUCTION_END();
2188
2189 HANDLE_INSTRUCTION_START(ADD_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002190 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002191 shadow_frame.SetVRegFloat(vregA,
2192 shadow_frame.GetVRegFloat(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002193 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002194 ADVANCE(1);
2195 }
2196 HANDLE_INSTRUCTION_END();
2197
2198 HANDLE_INSTRUCTION_START(SUB_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002199 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002200 shadow_frame.SetVRegFloat(vregA,
2201 shadow_frame.GetVRegFloat(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002202 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002203 ADVANCE(1);
2204 }
2205 HANDLE_INSTRUCTION_END();
2206
2207 HANDLE_INSTRUCTION_START(MUL_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002208 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002209 shadow_frame.SetVRegFloat(vregA,
2210 shadow_frame.GetVRegFloat(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002211 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002212 ADVANCE(1);
2213 }
2214 HANDLE_INSTRUCTION_END();
2215
2216 HANDLE_INSTRUCTION_START(DIV_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002217 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002218 shadow_frame.SetVRegFloat(vregA,
2219 shadow_frame.GetVRegFloat(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002220 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002221 ADVANCE(1);
2222 }
2223 HANDLE_INSTRUCTION_END();
2224
2225 HANDLE_INSTRUCTION_START(REM_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002226 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002227 shadow_frame.SetVRegFloat(vregA,
2228 fmodf(shadow_frame.GetVRegFloat(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002229 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002230 ADVANCE(1);
2231 }
2232 HANDLE_INSTRUCTION_END();
2233
2234 HANDLE_INSTRUCTION_START(ADD_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002235 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002236 shadow_frame.SetVRegDouble(vregA,
2237 shadow_frame.GetVRegDouble(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002238 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002239 ADVANCE(1);
2240 }
2241 HANDLE_INSTRUCTION_END();
2242
2243 HANDLE_INSTRUCTION_START(SUB_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002244 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002245 shadow_frame.SetVRegDouble(vregA,
2246 shadow_frame.GetVRegDouble(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002247 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002248 ADVANCE(1);
2249 }
2250 HANDLE_INSTRUCTION_END();
2251
2252 HANDLE_INSTRUCTION_START(MUL_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002253 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002254 shadow_frame.SetVRegDouble(vregA,
2255 shadow_frame.GetVRegDouble(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002256 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002257 ADVANCE(1);
2258 }
2259 HANDLE_INSTRUCTION_END();
2260
2261 HANDLE_INSTRUCTION_START(DIV_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002262 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002263 shadow_frame.SetVRegDouble(vregA,
2264 shadow_frame.GetVRegDouble(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002265 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002266 ADVANCE(1);
2267 }
2268 HANDLE_INSTRUCTION_END();
2269
2270 HANDLE_INSTRUCTION_START(REM_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002271 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002272 shadow_frame.SetVRegDouble(vregA,
2273 fmod(shadow_frame.GetVRegDouble(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002274 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002275 ADVANCE(1);
2276 }
2277 HANDLE_INSTRUCTION_END();
2278
2279 HANDLE_INSTRUCTION_START(ADD_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002280 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002281 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2282 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002283 ADVANCE(2);
2284 HANDLE_INSTRUCTION_END();
2285
2286 HANDLE_INSTRUCTION_START(RSUB_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002287 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002288 SafeSub(inst->VRegC_22s(),
2289 shadow_frame.GetVReg(inst->VRegB_22s(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002290 ADVANCE(2);
2291 HANDLE_INSTRUCTION_END();
2292
2293 HANDLE_INSTRUCTION_START(MUL_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002294 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002295 SafeMul(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2296 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002297 ADVANCE(2);
2298 HANDLE_INSTRUCTION_END();
2299
2300 HANDLE_INSTRUCTION_START(DIV_INT_LIT16) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002301 bool success = DoIntDivide(
2302 shadow_frame, inst->VRegA_22s(inst_data), shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2303 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002304 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2305 }
2306 HANDLE_INSTRUCTION_END();
2307
2308 HANDLE_INSTRUCTION_START(REM_INT_LIT16) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002309 bool success = DoIntRemainder(
2310 shadow_frame, inst->VRegA_22s(inst_data), shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2311 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002312 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2313 }
2314 HANDLE_INSTRUCTION_END();
2315
2316 HANDLE_INSTRUCTION_START(AND_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002317 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2318 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) &
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002319 inst->VRegC_22s());
2320 ADVANCE(2);
2321 HANDLE_INSTRUCTION_END();
2322
2323 HANDLE_INSTRUCTION_START(OR_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002324 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2325 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) |
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002326 inst->VRegC_22s());
2327 ADVANCE(2);
2328 HANDLE_INSTRUCTION_END();
2329
2330 HANDLE_INSTRUCTION_START(XOR_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002331 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2332 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) ^
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002333 inst->VRegC_22s());
2334 ADVANCE(2);
2335 HANDLE_INSTRUCTION_END();
2336
2337 HANDLE_INSTRUCTION_START(ADD_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002338 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002339 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22b()),
2340 inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002341 ADVANCE(2);
2342 HANDLE_INSTRUCTION_END();
2343
2344 HANDLE_INSTRUCTION_START(RSUB_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002345 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002346 SafeSub(inst->VRegC_22b(),
2347 shadow_frame.GetVReg(inst->VRegB_22b())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002348 ADVANCE(2);
2349 HANDLE_INSTRUCTION_END();
2350
2351 HANDLE_INSTRUCTION_START(MUL_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002352 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002353 SafeMul(shadow_frame.GetVReg(inst->VRegB_22b()),
2354 inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002355 ADVANCE(2);
2356 HANDLE_INSTRUCTION_END();
2357
2358 HANDLE_INSTRUCTION_START(DIV_INT_LIT8) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002359 bool success = DoIntDivide(shadow_frame, inst->VRegA_22b(inst_data),
2360 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002361 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2362 }
2363 HANDLE_INSTRUCTION_END();
2364
2365 HANDLE_INSTRUCTION_START(REM_INT_LIT8) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002366 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22b(inst_data),
2367 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002368 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2369 }
2370 HANDLE_INSTRUCTION_END();
2371
2372 HANDLE_INSTRUCTION_START(AND_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002373 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002374 shadow_frame.GetVReg(inst->VRegB_22b()) &
2375 inst->VRegC_22b());
2376 ADVANCE(2);
2377 HANDLE_INSTRUCTION_END();
2378
2379 HANDLE_INSTRUCTION_START(OR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002380 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002381 shadow_frame.GetVReg(inst->VRegB_22b()) |
2382 inst->VRegC_22b());
2383 ADVANCE(2);
2384 HANDLE_INSTRUCTION_END();
2385
2386 HANDLE_INSTRUCTION_START(XOR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002387 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002388 shadow_frame.GetVReg(inst->VRegB_22b()) ^
2389 inst->VRegC_22b());
2390 ADVANCE(2);
2391 HANDLE_INSTRUCTION_END();
2392
2393 HANDLE_INSTRUCTION_START(SHL_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002394 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002395 shadow_frame.GetVReg(inst->VRegB_22b()) <<
2396 (inst->VRegC_22b() & 0x1f));
2397 ADVANCE(2);
2398 HANDLE_INSTRUCTION_END();
2399
2400 HANDLE_INSTRUCTION_START(SHR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002401 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002402 shadow_frame.GetVReg(inst->VRegB_22b()) >>
2403 (inst->VRegC_22b() & 0x1f));
2404 ADVANCE(2);
2405 HANDLE_INSTRUCTION_END();
2406
2407 HANDLE_INSTRUCTION_START(USHR_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 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_22b())) >>
2410 (inst->VRegC_22b() & 0x1f));
2411 ADVANCE(2);
2412 HANDLE_INSTRUCTION_END();
2413
Igor Murashkin158f35c2015-06-10 15:55:30 -07002414 HANDLE_EXPERIMENTAL_INSTRUCTION_START(CREATE_LAMBDA) {
Nicolas Geoffray7bbb80a2015-09-27 19:50:40 +00002415 bool success = DoCreateLambda<true>(self, shadow_frame, inst);
Igor Murashkin158f35c2015-06-10 15:55:30 -07002416 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2417 }
2418 HANDLE_EXPERIMENTAL_INSTRUCTION_END();
2419
Igor Murashkin2ee54e22015-06-18 10:05:11 -07002420 HANDLE_EXPERIMENTAL_INSTRUCTION_START(BOX_LAMBDA) {
2421 bool success = DoBoxLambda<do_access_check>(self, shadow_frame, inst, inst_data);
2422 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2423 }
2424 HANDLE_EXPERIMENTAL_INSTRUCTION_END();
2425
2426 HANDLE_EXPERIMENTAL_INSTRUCTION_START(UNBOX_LAMBDA) {
2427 bool success = DoUnboxLambda<do_access_check>(self, shadow_frame, inst, inst_data);
2428 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2429 }
2430 HANDLE_EXPERIMENTAL_INSTRUCTION_END();
2431
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002432 HANDLE_INSTRUCTION_START(UNUSED_3E)
Ian Rogerse94652f2014-12-02 11:13:19 -08002433 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002434 HANDLE_INSTRUCTION_END();
2435
2436 HANDLE_INSTRUCTION_START(UNUSED_3F)
Ian Rogerse94652f2014-12-02 11:13:19 -08002437 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002438 HANDLE_INSTRUCTION_END();
2439
2440 HANDLE_INSTRUCTION_START(UNUSED_40)
Ian Rogerse94652f2014-12-02 11:13:19 -08002441 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002442 HANDLE_INSTRUCTION_END();
2443
2444 HANDLE_INSTRUCTION_START(UNUSED_41)
Ian Rogerse94652f2014-12-02 11:13:19 -08002445 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002446 HANDLE_INSTRUCTION_END();
2447
2448 HANDLE_INSTRUCTION_START(UNUSED_42)
Ian Rogerse94652f2014-12-02 11:13:19 -08002449 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002450 HANDLE_INSTRUCTION_END();
2451
2452 HANDLE_INSTRUCTION_START(UNUSED_43)
Ian Rogerse94652f2014-12-02 11:13:19 -08002453 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002454 HANDLE_INSTRUCTION_END();
2455
2456 HANDLE_INSTRUCTION_START(UNUSED_79)
Ian Rogerse94652f2014-12-02 11:13:19 -08002457 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002458 HANDLE_INSTRUCTION_END();
2459
2460 HANDLE_INSTRUCTION_START(UNUSED_7A)
Ian Rogerse94652f2014-12-02 11:13:19 -08002461 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002462 HANDLE_INSTRUCTION_END();
2463
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002464 HANDLE_INSTRUCTION_START(UNUSED_F4)
Ian Rogerse94652f2014-12-02 11:13:19 -08002465 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002466 HANDLE_INSTRUCTION_END();
2467
Nicolas Geoffray7bbb80a2015-09-27 19:50:40 +00002468 HANDLE_INSTRUCTION_START(UNUSED_F5)
2469 UnexpectedOpcode(inst, shadow_frame);
2470 HANDLE_INSTRUCTION_END();
2471
2472 HANDLE_INSTRUCTION_START(UNUSED_F7)
2473 UnexpectedOpcode(inst, shadow_frame);
2474 HANDLE_INSTRUCTION_END();
2475
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002476 HANDLE_INSTRUCTION_START(UNUSED_FA)
Ian Rogerse94652f2014-12-02 11:13:19 -08002477 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002478 HANDLE_INSTRUCTION_END();
2479
2480 HANDLE_INSTRUCTION_START(UNUSED_FB)
Ian Rogerse94652f2014-12-02 11:13:19 -08002481 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002482 HANDLE_INSTRUCTION_END();
2483
2484 HANDLE_INSTRUCTION_START(UNUSED_FC)
Ian Rogerse94652f2014-12-02 11:13:19 -08002485 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002486 HANDLE_INSTRUCTION_END();
2487
2488 HANDLE_INSTRUCTION_START(UNUSED_FD)
Ian Rogerse94652f2014-12-02 11:13:19 -08002489 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002490 HANDLE_INSTRUCTION_END();
2491
2492 HANDLE_INSTRUCTION_START(UNUSED_FE)
Ian Rogerse94652f2014-12-02 11:13:19 -08002493 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002494 HANDLE_INSTRUCTION_END();
2495
2496 HANDLE_INSTRUCTION_START(UNUSED_FF)
Ian Rogerse94652f2014-12-02 11:13:19 -08002497 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002498 HANDLE_INSTRUCTION_END();
2499
2500 exception_pending_label: {
2501 CHECK(self->IsExceptionPending());
Sebastien Hertz1eda2262013-09-09 16:53:14 +02002502 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -07002503 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +02002504 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +02002505 }
Sebastien Hertzee1997a2013-09-19 14:47:09 +02002506 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002507 uint32_t found_dex_pc = FindNextInstructionFollowingException(self, shadow_frame, dex_pc,
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002508 instrumentation);
2509 if (found_dex_pc == DexFile::kDexNoIndex) {
2510 return JValue(); /* Handled in caller. */
2511 } else {
2512 int32_t displacement = static_cast<int32_t>(found_dex_pc) - static_cast<int32_t>(dex_pc);
2513 ADVANCE(displacement);
2514 }
2515 }
2516
Sebastien Hertz8379b222014-02-24 17:38:15 +01002517// Create alternative instruction handlers dedicated to instrumentation.
2518// Return instructions must not call Instrumentation::DexPcMovedEvent since they already call
2519// Instrumentation::MethodExited. This is to avoid posting debugger events twice for this location.
Sebastien Hertze713d932014-05-15 10:48:53 +02002520// Note: we do not use the kReturn instruction flag here (to test the instruction is a return). The
2521// compiler seems to not evaluate "(Instruction::FlagsOf(Instruction::code) & kReturn) != 0" to
2522// a constant condition that would remove the "if" statement so the test is free.
Sebastien Hertz9d6bf692015-04-10 12:12:33 +02002523#define INSTRUMENTATION_INSTRUCTION_HANDLER(o, code, n, f, r, i, a, v) \
2524 alt_op_##code: { \
2525 Runtime* const runtime = Runtime::Current(); \
2526 const instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation(); \
2527 if (UNLIKELY(instrumentation->HasDexPcListeners())) { \
2528 Object* this_object = shadow_frame.GetThisObject(code_item->ins_size_); \
2529 instrumentation->DexPcMovedEvent(self, this_object, shadow_frame.GetMethod(), dex_pc); \
2530 } \
2531 UPDATE_HANDLER_TABLE(); \
2532 goto *handlersTable[instrumentation::kMainHandlerTable][Instruction::code]; \
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002533 }
2534#include "dex_instruction_list.h"
2535 DEX_INSTRUCTION_LIST(INSTRUMENTATION_INSTRUCTION_HANDLER)
2536#undef DEX_INSTRUCTION_LIST
2537#undef INSTRUMENTATION_INSTRUCTION_HANDLER
2538} // NOLINT(readability/fn_size)
2539
2540// Explicit definitions of ExecuteGotoImpl.
Mathieu Chartier90443472015-07-16 20:32:27 -07002541template SHARED_REQUIRES(Locks::mutator_lock_) HOT_ATTR
Ian Rogerse94652f2014-12-02 11:13:19 -08002542JValue ExecuteGotoImpl<true, false>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002543 ShadowFrame& shadow_frame, JValue result_register);
Mathieu Chartier90443472015-07-16 20:32:27 -07002544template SHARED_REQUIRES(Locks::mutator_lock_) HOT_ATTR
Ian Rogerse94652f2014-12-02 11:13:19 -08002545JValue ExecuteGotoImpl<false, false>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002546 ShadowFrame& shadow_frame, JValue result_register);
Mathieu Chartier90443472015-07-16 20:32:27 -07002547template SHARED_REQUIRES(Locks::mutator_lock_)
Ian Rogerse94652f2014-12-02 11:13:19 -08002548JValue ExecuteGotoImpl<true, true>(Thread* self, const DexFile::CodeItem* code_item,
2549 ShadowFrame& shadow_frame, JValue result_register);
Mathieu Chartier90443472015-07-16 20:32:27 -07002550template SHARED_REQUIRES(Locks::mutator_lock_)
Ian Rogerse94652f2014-12-02 11:13:19 -08002551JValue ExecuteGotoImpl<false, true>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002552 ShadowFrame& shadow_frame, JValue result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002553
2554} // namespace interpreter
2555} // namespace art
Colin Crosse84e4f72015-03-18 14:01:19 -07002556
2557#endif