blob: 3b6e01540662a6180b131716e0d306aafda23472 [file] [log] [blame]
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Colin Crosse84e4f72015-03-18 14:01:19 -070017#if !defined(__clang__)
18// Clang 3.4 fails to build the goto interpreter implementation.
19
Igor Murashkin6918bf12015-09-27 19:19:06 -070020
21#include "base/stl_util.h" // MakeUnique
Alex Lighteb7c1442015-08-31 13:17:42 -070022#include "experimental_flags.h"
Sebastien Hertz8ece0502013-08-07 11:26:41 +020023#include "interpreter_common.h"
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +000024#include "jit/jit.h"
Ian Rogersf72a11d2014-10-30 15:41:08 -070025#include "safe_math.h"
Sebastien Hertz8ece0502013-08-07 11:26:41 +020026
Igor Murashkin6918bf12015-09-27 19:19:06 -070027#include <memory> // std::unique_ptr
28
Sebastien Hertz8ece0502013-08-07 11:26:41 +020029namespace art {
30namespace interpreter {
31
32// In the following macros, we expect the following local variables exist:
33// - "self": the current Thread*.
34// - "inst" : the current Instruction*.
Sebastien Hertz3b588e02013-09-11 14:33:18 +020035// - "inst_data" : the current instruction's first 16 bits.
Sebastien Hertz8ece0502013-08-07 11:26:41 +020036// - "dex_pc": the current pc.
37// - "shadow_frame": the current shadow frame.
Sebastien Hertz8ece0502013-08-07 11:26:41 +020038// - "currentHandlersTable": the current table of pointer to each instruction handler.
39
40// Advance to the next instruction and updates interpreter state.
Sebastien Hertz8ece0502013-08-07 11:26:41 +020041#define ADVANCE(_offset) \
42 do { \
43 int32_t disp = static_cast<int32_t>(_offset); \
44 inst = inst->RelativeAt(disp); \
45 dex_pc = static_cast<uint32_t>(static_cast<int32_t>(dex_pc) + disp); \
46 shadow_frame.SetDexPC(dex_pc); \
Ian Rogerse94652f2014-12-02 11:13:19 -080047 TraceExecution(shadow_frame, inst, dex_pc); \
Sebastien Hertz3b588e02013-09-11 14:33:18 +020048 inst_data = inst->Fetch16(0); \
49 goto *currentHandlersTable[inst->Opcode(inst_data)]; \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020050 } while (false)
51
52#define HANDLE_PENDING_EXCEPTION() goto exception_pending_label
53
54#define POSSIBLY_HANDLE_PENDING_EXCEPTION(_is_exception_pending, _offset) \
55 do { \
56 if (UNLIKELY(_is_exception_pending)) { \
57 HANDLE_PENDING_EXCEPTION(); \
58 } else { \
59 ADVANCE(_offset); \
60 } \
61 } while (false)
62
Sebastien Hertzee1997a2013-09-19 14:47:09 +020063#define UPDATE_HANDLER_TABLE() \
Mathieu Chartier2cebb242015-04-21 16:50:40 -070064 currentHandlersTable = handlersTable[ \
65 Runtime::Current()->GetInstrumentation()->GetInterpreterHandlerTable()]
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +020066
Bill Buzbee1d011d92016-04-04 16:59:29 +000067#define BRANCH_INSTRUMENTATION(offset) \
68 do { \
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +010069 if (UNLIKELY(instrumentation->HasBranchListeners())) { \
70 instrumentation->Branch(self, method, dex_pc, offset); \
71 } \
Bill Buzbee1d011d92016-04-04 16:59:29 +000072 JValue result; \
73 if (jit::Jit::MaybeDoOnStackReplacement(self, method, dex_pc, offset, &result)) { \
74 return result; \
75 } \
76 } while (false)
77
78#define HOTNESS_UPDATE() \
79 do { \
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +010080 if (jit != nullptr) { \
Nicolas Geoffray71cd50f2016-04-14 15:00:33 +010081 jit->AddSamples(self, method, 1, /*with_backedges*/ true); \
Bill Buzbee1d011d92016-04-04 16:59:29 +000082 } \
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080083 } while (false)
84
Sebastien Hertz8ece0502013-08-07 11:26:41 +020085#define UNREACHABLE_CODE_CHECK() \
86 do { \
87 if (kIsDebugBuild) { \
88 LOG(FATAL) << "We should not be here !"; \
Ian Rogerse94652f2014-12-02 11:13:19 -080089 UNREACHABLE(); \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020090 } \
91 } while (false)
92
93#define HANDLE_INSTRUCTION_START(opcode) op_##opcode: // NOLINT(whitespace/labels)
94#define HANDLE_INSTRUCTION_END() UNREACHABLE_CODE_CHECK()
95
Igor Murashkin158f35c2015-06-10 15:55:30 -070096// Use with instructions labeled with kExperimental flag:
97#define HANDLE_EXPERIMENTAL_INSTRUCTION_START(opcode) \
98 HANDLE_INSTRUCTION_START(opcode); \
99 DCHECK(inst->IsExperimental()); \
Alex Lighteb7c1442015-08-31 13:17:42 -0700100 if (Runtime::Current()->AreExperimentalFlagsEnabled(ExperimentalFlags::kLambdas)) {
Igor Murashkin158f35c2015-06-10 15:55:30 -0700101#define HANDLE_EXPERIMENTAL_INSTRUCTION_END() \
102 } else { \
103 UnexpectedOpcode(inst, shadow_frame); \
104 } HANDLE_INSTRUCTION_END();
105
Andreas Gampe03ec9302015-08-27 17:41:47 -0700106#define HANDLE_MONITOR_CHECKS() \
Andreas Gampe56fdd0e2016-04-28 14:56:54 -0700107 if (!DoMonitorCheckOnExit<do_assignability_check>(self, &shadow_frame)) { \
Andreas Gampe03ec9302015-08-27 17:41:47 -0700108 HANDLE_PENDING_EXCEPTION(); \
109 }
Igor Murashkin158f35c2015-06-10 15:55:30 -0700110
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200111/**
112 * Interpreter based on computed goto tables.
113 *
114 * Each instruction is associated to a handler. This handler is responsible for executing the
115 * instruction and jump to the next instruction's handler.
116 * In order to limit the cost of instrumentation, we have two handler tables:
117 * - the "main" handler table: it contains handlers for normal execution of each instruction without
118 * handling of instrumentation.
119 * - the "alternative" handler table: it contains alternative handlers which first handle
120 * instrumentation before jumping to the corresponding "normal" instruction's handler.
121 *
122 * When instrumentation is active, the interpreter uses the "alternative" handler table. Otherwise
123 * it uses the "main" handler table.
124 *
125 * The current handler table is the handler table being used by the interpreter. It is updated:
126 * - on backward branch (goto, if and switch instructions)
127 * - after invoke
128 * - when an exception is thrown.
129 * This allows to support an attaching debugger to an already running application for instance.
130 *
131 * For a fast handler table update, handler tables are stored in an array of handler tables. Each
132 * handler table is represented by the InterpreterHandlerTable enum which allows to associate it
133 * to an index in this array of handler tables ((see Instrumentation::GetInterpreterHandlerTable).
134 *
135 * Here's the current layout of this array of handler tables:
136 *
137 * ---------------------+---------------+
138 * | NOP | (handler for NOP instruction)
139 * +---------------+
140 * "main" | MOVE | (handler for MOVE instruction)
141 * handler table +---------------+
142 * | ... |
143 * +---------------+
144 * | UNUSED_FF | (handler for UNUSED_FF instruction)
145 * ---------------------+---------------+
146 * | NOP | (alternative handler for NOP instruction)
147 * +---------------+
148 * "alternative" | MOVE | (alternative handler for MOVE instruction)
149 * handler table +---------------+
150 * | ... |
151 * +---------------+
152 * | UNUSED_FF | (alternative handler for UNUSED_FF instruction)
153 * ---------------------+---------------+
154 *
155 */
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100156template<bool do_access_check, bool transaction_active>
Ian Rogerse94652f2014-12-02 11:13:19 -0800157JValue ExecuteGotoImpl(Thread* self, const DexFile::CodeItem* code_item, ShadowFrame& shadow_frame,
158 JValue result_register) {
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200159 // Define handler tables:
160 // - The main handler table contains execution handlers for each instruction.
161 // - The alternative handler table contains prelude handlers which check for thread suspend and
162 // manage instrumentation before jumping to the execution handler.
163 static const void* const handlersTable[instrumentation::kNumHandlerTables][kNumPackedOpcodes] = {
164 {
165 // Main handler table.
Narayan Kamathbd48b342016-08-01 17:32:37 +0100166#define INSTRUCTION_HANDLER(o, code, n, f, i, a, v) &&op_##code,
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200167#include "dex_instruction_list.h"
168 DEX_INSTRUCTION_LIST(INSTRUCTION_HANDLER)
169#undef DEX_INSTRUCTION_LIST
170#undef INSTRUCTION_HANDLER
171 }, {
172 // Alternative handler table.
Narayan Kamathbd48b342016-08-01 17:32:37 +0100173#define INSTRUCTION_HANDLER(o, code, n, f, i, a, v) &&alt_op_##code,
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200174#include "dex_instruction_list.h"
175 DEX_INSTRUCTION_LIST(INSTRUCTION_HANDLER)
176#undef DEX_INSTRUCTION_LIST
177#undef INSTRUCTION_HANDLER
178 }
179 };
180
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800181 constexpr bool do_assignability_check = do_access_check;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200182 if (UNLIKELY(!shadow_frame.HasReferenceArray())) {
183 LOG(FATAL) << "Invalid shadow frame for interpreter use";
184 return JValue();
185 }
186 self->VerifyStack();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200187
188 uint32_t dex_pc = shadow_frame.GetDexPC();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200189 const Instruction* inst = Instruction::At(code_item->insns_ + dex_pc);
190 uint16_t inst_data;
191 const void* const* currentHandlersTable;
192 UPDATE_HANDLER_TABLE();
Igor Murashkin6918bf12015-09-27 19:19:06 -0700193 std::unique_ptr<lambda::ClosureBuilder> lambda_closure_builder;
194 size_t lambda_captured_variable_index = 0;
Bill Buzbee1d011d92016-04-04 16:59:29 +0000195 const auto* const instrumentation = Runtime::Current()->GetInstrumentation();
196 ArtMethod* method = shadow_frame.GetMethod();
197 jit::Jit* jit = Runtime::Current()->GetJit();
Igor Murashkin6918bf12015-09-27 19:19:06 -0700198
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200199 // Jump to first instruction.
200 ADVANCE(0);
201 UNREACHABLE_CODE_CHECK();
202
203 HANDLE_INSTRUCTION_START(NOP)
204 ADVANCE(1);
205 HANDLE_INSTRUCTION_END();
206
207 HANDLE_INSTRUCTION_START(MOVE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200208 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
209 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200210 ADVANCE(1);
211 HANDLE_INSTRUCTION_END();
212
213 HANDLE_INSTRUCTION_START(MOVE_FROM16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200214 shadow_frame.SetVReg(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200215 shadow_frame.GetVReg(inst->VRegB_22x()));
216 ADVANCE(2);
217 HANDLE_INSTRUCTION_END();
218
219 HANDLE_INSTRUCTION_START(MOVE_16)
220 shadow_frame.SetVReg(inst->VRegA_32x(),
221 shadow_frame.GetVReg(inst->VRegB_32x()));
222 ADVANCE(3);
223 HANDLE_INSTRUCTION_END();
224
225 HANDLE_INSTRUCTION_START(MOVE_WIDE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200226 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
227 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200228 ADVANCE(1);
229 HANDLE_INSTRUCTION_END();
230
231 HANDLE_INSTRUCTION_START(MOVE_WIDE_FROM16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200232 shadow_frame.SetVRegLong(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200233 shadow_frame.GetVRegLong(inst->VRegB_22x()));
234 ADVANCE(2);
235 HANDLE_INSTRUCTION_END();
236
237 HANDLE_INSTRUCTION_START(MOVE_WIDE_16)
238 shadow_frame.SetVRegLong(inst->VRegA_32x(),
239 shadow_frame.GetVRegLong(inst->VRegB_32x()));
240 ADVANCE(3);
241 HANDLE_INSTRUCTION_END();
242
243 HANDLE_INSTRUCTION_START(MOVE_OBJECT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200244 shadow_frame.SetVRegReference(inst->VRegA_12x(inst_data),
245 shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200246 ADVANCE(1);
247 HANDLE_INSTRUCTION_END();
248
249 HANDLE_INSTRUCTION_START(MOVE_OBJECT_FROM16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200250 shadow_frame.SetVRegReference(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200251 shadow_frame.GetVRegReference(inst->VRegB_22x()));
252 ADVANCE(2);
253 HANDLE_INSTRUCTION_END();
254
255 HANDLE_INSTRUCTION_START(MOVE_OBJECT_16)
256 shadow_frame.SetVRegReference(inst->VRegA_32x(),
257 shadow_frame.GetVRegReference(inst->VRegB_32x()));
258 ADVANCE(3);
259 HANDLE_INSTRUCTION_END();
260
261 HANDLE_INSTRUCTION_START(MOVE_RESULT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200262 shadow_frame.SetVReg(inst->VRegA_11x(inst_data), result_register.GetI());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200263 ADVANCE(1);
264 HANDLE_INSTRUCTION_END();
265
266 HANDLE_INSTRUCTION_START(MOVE_RESULT_WIDE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200267 shadow_frame.SetVRegLong(inst->VRegA_11x(inst_data), result_register.GetJ());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200268 ADVANCE(1);
269 HANDLE_INSTRUCTION_END();
270
271 HANDLE_INSTRUCTION_START(MOVE_RESULT_OBJECT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200272 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), result_register.GetL());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200273 ADVANCE(1);
274 HANDLE_INSTRUCTION_END();
275
276 HANDLE_INSTRUCTION_START(MOVE_EXCEPTION) {
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000277 Throwable* exception = self->GetException();
Sebastien Hertz270a0e12015-01-16 19:49:09 +0100278 DCHECK(exception != nullptr) << "No pending exception on MOVE_EXCEPTION instruction";
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200279 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), exception);
Sebastien Hertz5c004902014-05-21 10:07:42 +0200280 self->ClearException();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200281 ADVANCE(1);
282 }
283 HANDLE_INSTRUCTION_END();
284
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700285 HANDLE_INSTRUCTION_START(RETURN_VOID_NO_BARRIER) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200286 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700287 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700288 HANDLE_MONITOR_CHECKS();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200289 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200290 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200291 shadow_frame.GetMethod(), dex_pc,
292 result);
293 }
294 return result;
295 }
296 HANDLE_INSTRUCTION_END();
297
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700298 HANDLE_INSTRUCTION_START(RETURN_VOID) {
Hans Boehm30359612014-05-21 17:46:23 -0700299 QuasiAtomic::ThreadFenceForConstructor();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200300 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700301 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700302 HANDLE_MONITOR_CHECKS();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200303 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200304 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200305 shadow_frame.GetMethod(), dex_pc,
306 result);
307 }
308 return result;
309 }
310 HANDLE_INSTRUCTION_END();
311
312 HANDLE_INSTRUCTION_START(RETURN) {
313 JValue result;
314 result.SetJ(0);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200315 result.SetI(shadow_frame.GetVReg(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700316 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700317 HANDLE_MONITOR_CHECKS();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200318 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200319 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200320 shadow_frame.GetMethod(), dex_pc,
321 result);
322 }
323 return result;
324 }
325 HANDLE_INSTRUCTION_END();
326
327 HANDLE_INSTRUCTION_START(RETURN_WIDE) {
328 JValue result;
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200329 result.SetJ(shadow_frame.GetVRegLong(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700330 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700331 HANDLE_MONITOR_CHECKS();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200332 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200333 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200334 shadow_frame.GetMethod(), dex_pc,
335 result);
336 }
337 return result;
338 }
339 HANDLE_INSTRUCTION_END();
340
341 HANDLE_INSTRUCTION_START(RETURN_OBJECT) {
342 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700343 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700344 HANDLE_MONITOR_CHECKS();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700345 const uint8_t vreg_index = inst->VRegA_11x(inst_data);
346 Object* obj_result = shadow_frame.GetVRegReference(vreg_index);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700347 if (do_assignability_check && obj_result != nullptr) {
Vladimir Marko05792b92015-08-03 11:56:49 +0100348 size_t pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
349 Class* return_type = shadow_frame.GetMethod()->GetReturnType(true /* resolve */,
350 pointer_size);
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700351 obj_result = shadow_frame.GetVRegReference(vreg_index);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700352 if (return_type == nullptr) {
Jeff Haoa3faaf42013-09-03 19:07:00 -0700353 // Return the pending exception.
354 HANDLE_PENDING_EXCEPTION();
355 }
356 if (!obj_result->VerifierInstanceOf(return_type)) {
357 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700358 std::string temp1, temp2;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000359 self->ThrowNewExceptionF("Ljava/lang/VirtualMachineError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700360 "Returning '%s' that is not instance of return type '%s'",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700361 obj_result->GetClass()->GetDescriptor(&temp1),
362 return_type->GetDescriptor(&temp2));
Jeff Haoa3faaf42013-09-03 19:07:00 -0700363 HANDLE_PENDING_EXCEPTION();
364 }
365 }
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700366 result.SetL(obj_result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200367 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200368 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200369 shadow_frame.GetMethod(), dex_pc,
370 result);
371 }
372 return result;
373 }
374 HANDLE_INSTRUCTION_END();
375
376 HANDLE_INSTRUCTION_START(CONST_4) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200377 uint32_t dst = inst->VRegA_11n(inst_data);
378 int32_t val = inst->VRegB_11n(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200379 shadow_frame.SetVReg(dst, val);
380 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700381 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200382 }
383 ADVANCE(1);
384 }
385 HANDLE_INSTRUCTION_END();
386
387 HANDLE_INSTRUCTION_START(CONST_16) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200388 uint32_t dst = inst->VRegA_21s(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200389 int32_t val = inst->VRegB_21s();
390 shadow_frame.SetVReg(dst, val);
391 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700392 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200393 }
394 ADVANCE(2);
395 }
396 HANDLE_INSTRUCTION_END();
397
398 HANDLE_INSTRUCTION_START(CONST) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200399 uint32_t dst = inst->VRegA_31i(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200400 int32_t val = inst->VRegB_31i();
401 shadow_frame.SetVReg(dst, val);
402 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700403 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200404 }
405 ADVANCE(3);
406 }
407 HANDLE_INSTRUCTION_END();
408
409 HANDLE_INSTRUCTION_START(CONST_HIGH16) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200410 uint32_t dst = inst->VRegA_21h(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200411 int32_t val = static_cast<int32_t>(inst->VRegB_21h() << 16);
412 shadow_frame.SetVReg(dst, val);
413 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700414 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200415 }
416 ADVANCE(2);
417 }
418 HANDLE_INSTRUCTION_END();
419
420 HANDLE_INSTRUCTION_START(CONST_WIDE_16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200421 shadow_frame.SetVRegLong(inst->VRegA_21s(inst_data), inst->VRegB_21s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200422 ADVANCE(2);
423 HANDLE_INSTRUCTION_END();
424
425 HANDLE_INSTRUCTION_START(CONST_WIDE_32)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200426 shadow_frame.SetVRegLong(inst->VRegA_31i(inst_data), inst->VRegB_31i());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200427 ADVANCE(3);
428 HANDLE_INSTRUCTION_END();
429
430 HANDLE_INSTRUCTION_START(CONST_WIDE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200431 shadow_frame.SetVRegLong(inst->VRegA_51l(inst_data), inst->VRegB_51l());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200432 ADVANCE(5);
433 HANDLE_INSTRUCTION_END();
434
435 HANDLE_INSTRUCTION_START(CONST_WIDE_HIGH16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200436 shadow_frame.SetVRegLong(inst->VRegA_21h(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200437 static_cast<uint64_t>(inst->VRegB_21h()) << 48);
438 ADVANCE(2);
439 HANDLE_INSTRUCTION_END();
440
441 HANDLE_INSTRUCTION_START(CONST_STRING) {
Ian Rogers6786a582014-10-28 12:49:06 -0700442 String* s = ResolveString(self, shadow_frame, inst->VRegB_21c());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700443 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200444 HANDLE_PENDING_EXCEPTION();
445 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200446 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200447 ADVANCE(2);
448 }
449 }
450 HANDLE_INSTRUCTION_END();
451
452 HANDLE_INSTRUCTION_START(CONST_STRING_JUMBO) {
Ian Rogers6786a582014-10-28 12:49:06 -0700453 String* s = ResolveString(self, shadow_frame, inst->VRegB_31c());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700454 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200455 HANDLE_PENDING_EXCEPTION();
456 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200457 shadow_frame.SetVRegReference(inst->VRegA_31c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200458 ADVANCE(3);
459 }
460 }
461 HANDLE_INSTRUCTION_END();
462
463 HANDLE_INSTRUCTION_START(CONST_CLASS) {
464 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
465 self, false, do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700466 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200467 HANDLE_PENDING_EXCEPTION();
468 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200469 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), c);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200470 ADVANCE(2);
471 }
472 }
473 HANDLE_INSTRUCTION_END();
474
475 HANDLE_INSTRUCTION_START(MONITOR_ENTER) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200476 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700477 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000478 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200479 HANDLE_PENDING_EXCEPTION();
480 } else {
Andreas Gampe03ec9302015-08-27 17:41:47 -0700481 DoMonitorEnter<do_access_check>(self, &shadow_frame, obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200482 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), 1);
483 }
484 }
485 HANDLE_INSTRUCTION_END();
486
487 HANDLE_INSTRUCTION_START(MONITOR_EXIT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200488 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700489 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000490 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200491 HANDLE_PENDING_EXCEPTION();
492 } else {
Andreas Gampe03ec9302015-08-27 17:41:47 -0700493 DoMonitorExit<do_access_check>(self, &shadow_frame, obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200494 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), 1);
495 }
496 }
497 HANDLE_INSTRUCTION_END();
498
499 HANDLE_INSTRUCTION_START(CHECK_CAST) {
500 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), 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->VRegA_21c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700506 if (UNLIKELY(obj != nullptr && !obj->InstanceOf(c))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200507 ThrowClassCastException(c, obj->GetClass());
508 HANDLE_PENDING_EXCEPTION();
509 } else {
510 ADVANCE(2);
511 }
512 }
513 }
514 HANDLE_INSTRUCTION_END();
515
516 HANDLE_INSTRUCTION_START(INSTANCE_OF) {
517 Class* c = ResolveVerifyAndClinit(inst->VRegC_22c(), shadow_frame.GetMethod(),
518 self, false, do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700519 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200520 HANDLE_PENDING_EXCEPTION();
521 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200522 Object* obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700523 shadow_frame.SetVReg(inst->VRegA_22c(inst_data), (obj != nullptr && obj->InstanceOf(c)) ? 1 : 0);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200524 ADVANCE(2);
525 }
526 }
527 HANDLE_INSTRUCTION_END();
528
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700529 HANDLE_INSTRUCTION_START(ARRAY_LENGTH) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200530 Object* array = shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700531 if (UNLIKELY(array == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000532 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200533 HANDLE_PENDING_EXCEPTION();
534 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200535 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), array->AsArray()->GetLength());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200536 ADVANCE(1);
537 }
538 }
539 HANDLE_INSTRUCTION_END();
540
541 HANDLE_INSTRUCTION_START(NEW_INSTANCE) {
Jeff Hao848f70a2014-01-15 13:49:50 -0800542 Object* obj = nullptr;
543 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
544 self, false, do_access_check);
545 if (LIKELY(c != nullptr)) {
546 if (UNLIKELY(c->IsStringClass())) {
547 gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
548 mirror::SetStringCountVisitor visitor(0);
549 obj = String::Alloc<true>(self, 0, allocator_type, visitor);
550 } else {
551 obj = AllocObjectFromCode<do_access_check, true>(
552 inst->VRegB_21c(), shadow_frame.GetMethod(), self,
553 Runtime::Current()->GetHeap()->GetCurrentAllocator());
554 }
555 }
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700556 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200557 HANDLE_PENDING_EXCEPTION();
558 } else {
Sebastien Hertz4e99b3d2014-06-24 14:35:40 +0200559 obj->GetClass()->AssertInitializedOrInitializingInThread(self);
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700560 // Don't allow finalizable objects to be allocated during a transaction since these can't be
561 // finalized without a started runtime.
562 if (transaction_active && obj->GetClass()->IsFinalizable()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +0200563 AbortTransactionF(self, "Allocating finalizable object in transaction: %s",
564 PrettyTypeOf(obj).c_str());
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700565 HANDLE_PENDING_EXCEPTION();
566 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200567 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200568 ADVANCE(2);
569 }
570 }
571 HANDLE_INSTRUCTION_END();
572
573 HANDLE_INSTRUCTION_START(NEW_ARRAY) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200574 int32_t length = shadow_frame.GetVReg(inst->VRegB_22c(inst_data));
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800575 Object* obj = AllocArrayFromCode<do_access_check, true>(
Andreas Gampe1cc7dba2014-12-17 18:43:01 -0800576 inst->VRegC_22c(), length, shadow_frame.GetMethod(), self,
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800577 Runtime::Current()->GetHeap()->GetCurrentAllocator());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700578 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200579 HANDLE_PENDING_EXCEPTION();
580 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200581 shadow_frame.SetVRegReference(inst->VRegA_22c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200582 ADVANCE(2);
583 }
584 }
585 HANDLE_INSTRUCTION_END();
586
587 HANDLE_INSTRUCTION_START(FILLED_NEW_ARRAY) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100588 bool success =
589 DoFilledNewArray<false, do_access_check, transaction_active>(inst, shadow_frame,
590 self, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200591 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
592 }
593 HANDLE_INSTRUCTION_END();
594
595 HANDLE_INSTRUCTION_START(FILLED_NEW_ARRAY_RANGE) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100596 bool success =
597 DoFilledNewArray<true, do_access_check, transaction_active>(inst, shadow_frame,
598 self, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200599 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
600 }
601 HANDLE_INSTRUCTION_END();
602
603 HANDLE_INSTRUCTION_START(FILL_ARRAY_DATA) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200604 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_31t(inst_data));
Ian Rogers832336b2014-10-08 15:35:22 -0700605 const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t();
606 const Instruction::ArrayDataPayload* payload =
607 reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr);
608 bool success = FillArrayData(obj, payload);
609 if (transaction_active && success) {
610 RecordArrayElementsInTransaction(obj->AsArray(), payload->element_count);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200611 }
Ian Rogers832336b2014-10-08 15:35:22 -0700612 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200613 }
614 HANDLE_INSTRUCTION_END();
615
616 HANDLE_INSTRUCTION_START(THROW) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200617 Object* exception = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700618 if (UNLIKELY(exception == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000619 ThrowNullPointerException("throw with null exception");
Jeff Haoa3faaf42013-09-03 19:07:00 -0700620 } else if (do_assignability_check && !exception->GetClass()->IsThrowableClass()) {
621 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700622 std::string temp;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000623 self->ThrowNewExceptionF("Ljava/lang/VirtualMachineError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700624 "Throwing '%s' that is not instance of Throwable",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700625 exception->GetClass()->GetDescriptor(&temp));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200626 } else {
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000627 self->SetException(exception->AsThrowable());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200628 }
629 HANDLE_PENDING_EXCEPTION();
630 }
631 HANDLE_INSTRUCTION_END();
632
633 HANDLE_INSTRUCTION_START(GOTO) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200634 int8_t offset = inst->VRegA_10t(inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000635 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200636 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000637 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200638 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700639 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200640 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200641 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200642 }
643 ADVANCE(offset);
644 }
645 HANDLE_INSTRUCTION_END();
646
647 HANDLE_INSTRUCTION_START(GOTO_16) {
648 int16_t offset = inst->VRegA_20t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000649 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200650 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000651 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200652 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700653 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200654 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200655 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200656 }
657 ADVANCE(offset);
658 }
659 HANDLE_INSTRUCTION_END();
660
661 HANDLE_INSTRUCTION_START(GOTO_32) {
662 int32_t offset = inst->VRegA_30t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000663 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200664 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000665 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200666 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700667 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200668 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200669 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200670 }
671 ADVANCE(offset);
672 }
673 HANDLE_INSTRUCTION_END();
674
675 HANDLE_INSTRUCTION_START(PACKED_SWITCH) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200676 int32_t offset = DoPackedSwitch(inst, shadow_frame, inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000677 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200678 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000679 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200680 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700681 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200682 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200683 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200684 }
685 ADVANCE(offset);
686 }
687 HANDLE_INSTRUCTION_END();
688
689 HANDLE_INSTRUCTION_START(SPARSE_SWITCH) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200690 int32_t offset = DoSparseSwitch(inst, shadow_frame, inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000691 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200692 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000693 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200694 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700695 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200696 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200697 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200698 }
699 ADVANCE(offset);
700 }
701 HANDLE_INSTRUCTION_END();
702
Ian Rogers647b1a82014-10-10 11:02:11 -0700703#if defined(__clang__)
704#pragma clang diagnostic push
705#pragma clang diagnostic ignored "-Wfloat-equal"
706#endif
707
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200708 HANDLE_INSTRUCTION_START(CMPL_FLOAT) {
709 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
710 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
711 int32_t result;
712 if (val1 > val2) {
713 result = 1;
714 } else if (val1 == val2) {
715 result = 0;
716 } else {
717 result = -1;
718 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200719 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200720 ADVANCE(2);
721 }
722 HANDLE_INSTRUCTION_END();
723
724 HANDLE_INSTRUCTION_START(CMPG_FLOAT) {
725 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
726 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
727 int32_t result;
728 if (val1 < val2) {
729 result = -1;
730 } else if (val1 == val2) {
731 result = 0;
732 } else {
733 result = 1;
734 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200735 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200736 ADVANCE(2);
737 }
738 HANDLE_INSTRUCTION_END();
739
740 HANDLE_INSTRUCTION_START(CMPL_DOUBLE) {
741 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
742 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
743 int32_t result;
744 if (val1 > val2) {
745 result = 1;
746 } else if (val1 == val2) {
747 result = 0;
748 } else {
749 result = -1;
750 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200751 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200752 ADVANCE(2);
753 }
754 HANDLE_INSTRUCTION_END();
755
756 HANDLE_INSTRUCTION_START(CMPG_DOUBLE) {
757 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
758 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
759 int32_t result;
760 if (val1 < val2) {
761 result = -1;
762 } else if (val1 == val2) {
763 result = 0;
764 } else {
765 result = 1;
766 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200767 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200768 ADVANCE(2);
769 }
770 HANDLE_INSTRUCTION_END();
771
Ian Rogers647b1a82014-10-10 11:02:11 -0700772#if defined(__clang__)
773#pragma clang diagnostic pop
774#endif
775
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200776 HANDLE_INSTRUCTION_START(CMP_LONG) {
777 int64_t val1 = shadow_frame.GetVRegLong(inst->VRegB_23x());
778 int64_t val2 = shadow_frame.GetVRegLong(inst->VRegC_23x());
779 int32_t result;
780 if (val1 > val2) {
781 result = 1;
782 } else if (val1 == val2) {
783 result = 0;
784 } else {
785 result = -1;
786 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200787 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200788 ADVANCE(2);
789 }
790 HANDLE_INSTRUCTION_END();
791
792 HANDLE_INSTRUCTION_START(IF_EQ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200793 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) == shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200794 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000795 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200796 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000797 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200798 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700799 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200800 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200801 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200802 }
803 ADVANCE(offset);
804 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800805 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200806 ADVANCE(2);
807 }
808 }
809 HANDLE_INSTRUCTION_END();
810
811 HANDLE_INSTRUCTION_START(IF_NE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700812 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) !=
813 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200814 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000815 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200816 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000817 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200818 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700819 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200820 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200821 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200822 }
823 ADVANCE(offset);
824 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800825 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200826 ADVANCE(2);
827 }
828 }
829 HANDLE_INSTRUCTION_END();
830
831 HANDLE_INSTRUCTION_START(IF_LT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700832 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <
833 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200834 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000835 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200836 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000837 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200838 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700839 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200840 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200841 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200842 }
843 ADVANCE(offset);
844 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800845 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200846 ADVANCE(2);
847 }
848 }
849 HANDLE_INSTRUCTION_END();
850
851 HANDLE_INSTRUCTION_START(IF_GE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700852 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >=
853 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200854 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000855 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200856 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000857 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200858 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700859 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200860 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200861 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200862 }
863 ADVANCE(offset);
864 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800865 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200866 ADVANCE(2);
867 }
868 }
869 HANDLE_INSTRUCTION_END();
870
871 HANDLE_INSTRUCTION_START(IF_GT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700872 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >
873 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200874 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000875 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200876 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000877 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200878 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700879 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200880 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200881 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200882 }
883 ADVANCE(offset);
884 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800885 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200886 ADVANCE(2);
887 }
888 }
889 HANDLE_INSTRUCTION_END();
890
891 HANDLE_INSTRUCTION_START(IF_LE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700892 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <=
893 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200894 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000895 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200896 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000897 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200898 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700899 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200900 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200901 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200902 }
903 ADVANCE(offset);
904 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800905 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200906 ADVANCE(2);
907 }
908 }
909 HANDLE_INSTRUCTION_END();
910
911 HANDLE_INSTRUCTION_START(IF_EQZ) {
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();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000914 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200915 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000916 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200917 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700918 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200919 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200920 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200921 }
922 ADVANCE(offset);
923 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800924 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200925 ADVANCE(2);
926 }
927 }
928 HANDLE_INSTRUCTION_END();
929
930 HANDLE_INSTRUCTION_START(IF_NEZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200931 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) != 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200932 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000933 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200934 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000935 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200936 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700937 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200938 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200939 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200940 }
941 ADVANCE(offset);
942 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800943 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200944 ADVANCE(2);
945 }
946 }
947 HANDLE_INSTRUCTION_END();
948
949 HANDLE_INSTRUCTION_START(IF_LTZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200950 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) < 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200951 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000952 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200953 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000954 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200955 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700956 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200957 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200958 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200959 }
960 ADVANCE(offset);
961 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800962 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200963 ADVANCE(2);
964 }
965 }
966 HANDLE_INSTRUCTION_END();
967
968 HANDLE_INSTRUCTION_START(IF_GEZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200969 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) >= 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200970 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000971 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200972 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000973 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200974 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700975 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200976 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200977 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200978 }
979 ADVANCE(offset);
980 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800981 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200982 ADVANCE(2);
983 }
984 }
985 HANDLE_INSTRUCTION_END();
986
987 HANDLE_INSTRUCTION_START(IF_GTZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200988 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) > 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200989 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000990 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200991 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000992 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200993 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700994 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200995 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200996 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200997 }
998 ADVANCE(offset);
999 } else {
buzbeef1dcacc2016-02-24 14:24:24 -08001000 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001001 ADVANCE(2);
1002 }
1003 }
1004 HANDLE_INSTRUCTION_END();
1005
1006 HANDLE_INSTRUCTION_START(IF_LEZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001007 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) <= 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001008 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +00001009 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001010 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +00001011 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001012 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -07001013 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +02001014 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001015 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001016 }
1017 ADVANCE(offset);
1018 } else {
buzbeef1dcacc2016-02-24 14:24:24 -08001019 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001020 ADVANCE(2);
1021 }
1022 }
1023 HANDLE_INSTRUCTION_END();
1024
1025 HANDLE_INSTRUCTION_START(AGET_BOOLEAN) {
1026 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001027 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001028 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001029 HANDLE_PENDING_EXCEPTION();
1030 } else {
1031 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1032 BooleanArray* array = a->AsBooleanArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001033 if (LIKELY(array->CheckIsValidIndex(index))) {
1034 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001035 ADVANCE(2);
1036 } else {
1037 HANDLE_PENDING_EXCEPTION();
1038 }
1039 }
1040 }
1041 HANDLE_INSTRUCTION_END();
1042
1043 HANDLE_INSTRUCTION_START(AGET_BYTE) {
1044 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001045 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001046 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001047 HANDLE_PENDING_EXCEPTION();
1048 } else {
1049 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1050 ByteArray* array = a->AsByteArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001051 if (LIKELY(array->CheckIsValidIndex(index))) {
1052 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001053 ADVANCE(2);
1054 } else {
1055 HANDLE_PENDING_EXCEPTION();
1056 }
1057 }
1058 }
1059 HANDLE_INSTRUCTION_END();
1060
1061 HANDLE_INSTRUCTION_START(AGET_CHAR) {
1062 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001063 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001064 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001065 HANDLE_PENDING_EXCEPTION();
1066 } else {
1067 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1068 CharArray* array = a->AsCharArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001069 if (LIKELY(array->CheckIsValidIndex(index))) {
1070 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001071 ADVANCE(2);
1072 } else {
1073 HANDLE_PENDING_EXCEPTION();
1074 }
1075 }
1076 }
1077 HANDLE_INSTRUCTION_END();
1078
1079 HANDLE_INSTRUCTION_START(AGET_SHORT) {
1080 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001081 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001082 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001083 HANDLE_PENDING_EXCEPTION();
1084 } else {
1085 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1086 ShortArray* array = a->AsShortArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001087 if (LIKELY(array->CheckIsValidIndex(index))) {
1088 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001089 ADVANCE(2);
1090 } else {
1091 HANDLE_PENDING_EXCEPTION();
1092 }
1093 }
1094 }
1095 HANDLE_INSTRUCTION_END();
1096
1097 HANDLE_INSTRUCTION_START(AGET) {
1098 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001099 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001100 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001101 HANDLE_PENDING_EXCEPTION();
1102 } else {
1103 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001104 DCHECK(a->IsIntArray() || a->IsFloatArray()) << PrettyTypeOf(a);
1105 auto* array = down_cast<IntArray*>(a);
Sebastien Hertzabff6432014-01-27 18:01:39 +01001106 if (LIKELY(array->CheckIsValidIndex(index))) {
1107 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001108 ADVANCE(2);
1109 } else {
1110 HANDLE_PENDING_EXCEPTION();
1111 }
1112 }
1113 }
1114 HANDLE_INSTRUCTION_END();
1115
1116 HANDLE_INSTRUCTION_START(AGET_WIDE) {
1117 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001118 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001119 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001120 HANDLE_PENDING_EXCEPTION();
1121 } else {
1122 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001123 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << PrettyTypeOf(a);
1124 auto* array = down_cast<LongArray*>(a);
Sebastien Hertzabff6432014-01-27 18:01:39 +01001125 if (LIKELY(array->CheckIsValidIndex(index))) {
1126 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001127 ADVANCE(2);
1128 } else {
1129 HANDLE_PENDING_EXCEPTION();
1130 }
1131 }
1132 }
1133 HANDLE_INSTRUCTION_END();
1134
1135 HANDLE_INSTRUCTION_START(AGET_OBJECT) {
1136 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001137 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001138 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001139 HANDLE_PENDING_EXCEPTION();
1140 } else {
1141 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1142 ObjectArray<Object>* array = a->AsObjectArray<Object>();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001143 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001144 shadow_frame.SetVRegReference(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001145 ADVANCE(2);
1146 } else {
1147 HANDLE_PENDING_EXCEPTION();
1148 }
1149 }
1150 }
1151 HANDLE_INSTRUCTION_END();
1152
1153 HANDLE_INSTRUCTION_START(APUT_BOOLEAN) {
1154 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001155 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001156 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001157 HANDLE_PENDING_EXCEPTION();
1158 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001159 uint8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001160 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1161 BooleanArray* array = a->AsBooleanArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001162 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001163 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001164 ADVANCE(2);
1165 } else {
1166 HANDLE_PENDING_EXCEPTION();
1167 }
1168 }
1169 }
1170 HANDLE_INSTRUCTION_END();
1171
1172 HANDLE_INSTRUCTION_START(APUT_BYTE) {
1173 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001174 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001175 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001176 HANDLE_PENDING_EXCEPTION();
1177 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001178 int8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001179 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1180 ByteArray* array = a->AsByteArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001181 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001182 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001183 ADVANCE(2);
1184 } else {
1185 HANDLE_PENDING_EXCEPTION();
1186 }
1187 }
1188 }
1189 HANDLE_INSTRUCTION_END();
1190
1191 HANDLE_INSTRUCTION_START(APUT_CHAR) {
1192 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001193 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001194 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001195 HANDLE_PENDING_EXCEPTION();
1196 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001197 uint16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001198 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1199 CharArray* array = a->AsCharArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001200 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001201 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001202 ADVANCE(2);
1203 } else {
1204 HANDLE_PENDING_EXCEPTION();
1205 }
1206 }
1207 }
1208 HANDLE_INSTRUCTION_END();
1209
1210 HANDLE_INSTRUCTION_START(APUT_SHORT) {
1211 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001212 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001213 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001214 HANDLE_PENDING_EXCEPTION();
1215 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001216 int16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001217 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1218 ShortArray* array = a->AsShortArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001219 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001220 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001221 ADVANCE(2);
1222 } else {
1223 HANDLE_PENDING_EXCEPTION();
1224 }
1225 }
1226 }
1227 HANDLE_INSTRUCTION_END();
1228
1229 HANDLE_INSTRUCTION_START(APUT) {
1230 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001231 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001232 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001233 HANDLE_PENDING_EXCEPTION();
1234 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001235 int32_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001236 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001237 DCHECK(a->IsIntArray() || a->IsFloatArray()) << PrettyTypeOf(a);
1238 auto* array = down_cast<IntArray*>(a);
Sebastien Hertzabff6432014-01-27 18:01:39 +01001239 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001240 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001241 ADVANCE(2);
1242 } else {
1243 HANDLE_PENDING_EXCEPTION();
1244 }
1245 }
1246 }
1247 HANDLE_INSTRUCTION_END();
1248
1249 HANDLE_INSTRUCTION_START(APUT_WIDE) {
1250 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001251 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001252 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001253 HANDLE_PENDING_EXCEPTION();
1254 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001255 int64_t val = shadow_frame.GetVRegLong(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001256 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001257 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << PrettyTypeOf(a);
1258 auto* array = down_cast<LongArray*>(a);
Sebastien Hertzabff6432014-01-27 18:01:39 +01001259 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001260 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001261 ADVANCE(2);
1262 } else {
1263 HANDLE_PENDING_EXCEPTION();
1264 }
1265 }
1266 }
1267 HANDLE_INSTRUCTION_END();
1268
1269 HANDLE_INSTRUCTION_START(APUT_OBJECT) {
1270 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001271 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001272 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001273 HANDLE_PENDING_EXCEPTION();
1274 } else {
1275 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001276 Object* val = shadow_frame.GetVRegReference(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001277 ObjectArray<Object>* array = a->AsObjectArray<Object>();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001278 if (LIKELY(array->CheckIsValidIndex(index) && array->CheckAssignable(val))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001279 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001280 ADVANCE(2);
1281 } else {
1282 HANDLE_PENDING_EXCEPTION();
1283 }
1284 }
1285 }
1286 HANDLE_INSTRUCTION_END();
1287
1288 HANDLE_INSTRUCTION_START(IGET_BOOLEAN) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001289 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimBoolean, do_access_check>(
1290 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001291 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1292 }
1293 HANDLE_INSTRUCTION_END();
1294
1295 HANDLE_INSTRUCTION_START(IGET_BYTE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001296 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimByte, do_access_check>(
1297 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001298 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1299 }
1300 HANDLE_INSTRUCTION_END();
1301
1302 HANDLE_INSTRUCTION_START(IGET_CHAR) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001303 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimChar, do_access_check>(
1304 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001305 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1306 }
1307 HANDLE_INSTRUCTION_END();
1308
1309 HANDLE_INSTRUCTION_START(IGET_SHORT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001310 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimShort, do_access_check>(
1311 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001312 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1313 }
1314 HANDLE_INSTRUCTION_END();
1315
1316 HANDLE_INSTRUCTION_START(IGET) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001317 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimInt, do_access_check>(
1318 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001319 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1320 }
1321 HANDLE_INSTRUCTION_END();
1322
1323 HANDLE_INSTRUCTION_START(IGET_WIDE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001324 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimLong, do_access_check>(
1325 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001326 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1327 }
1328 HANDLE_INSTRUCTION_END();
1329
1330 HANDLE_INSTRUCTION_START(IGET_OBJECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001331 bool success = DoFieldGet<InstanceObjectRead, Primitive::kPrimNot, do_access_check>(
1332 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001333 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1334 }
1335 HANDLE_INSTRUCTION_END();
1336
1337 HANDLE_INSTRUCTION_START(IGET_QUICK) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001338 bool success = DoIGetQuick<Primitive::kPrimInt>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001339 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1340 }
1341 HANDLE_INSTRUCTION_END();
1342
Mathieu Chartierffc605c2014-12-10 10:35:44 -08001343 HANDLE_INSTRUCTION_START(IGET_BOOLEAN_QUICK) {
1344 bool success = DoIGetQuick<Primitive::kPrimBoolean>(shadow_frame, inst, inst_data);
1345 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1346 }
1347 HANDLE_INSTRUCTION_END();
1348
1349 HANDLE_INSTRUCTION_START(IGET_BYTE_QUICK) {
1350 bool success = DoIGetQuick<Primitive::kPrimByte>(shadow_frame, inst, inst_data);
1351 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1352 }
1353 HANDLE_INSTRUCTION_END();
1354
1355 HANDLE_INSTRUCTION_START(IGET_CHAR_QUICK) {
1356 bool success = DoIGetQuick<Primitive::kPrimChar>(shadow_frame, inst, inst_data);
1357 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1358 }
1359 HANDLE_INSTRUCTION_END();
1360
1361 HANDLE_INSTRUCTION_START(IGET_SHORT_QUICK) {
1362 bool success = DoIGetQuick<Primitive::kPrimShort>(shadow_frame, inst, inst_data);
1363 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1364 }
1365 HANDLE_INSTRUCTION_END();
1366
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001367 HANDLE_INSTRUCTION_START(IGET_WIDE_QUICK) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001368 bool success = DoIGetQuick<Primitive::kPrimLong>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001369 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1370 }
1371 HANDLE_INSTRUCTION_END();
1372
1373 HANDLE_INSTRUCTION_START(IGET_OBJECT_QUICK) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001374 bool success = DoIGetQuick<Primitive::kPrimNot>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001375 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1376 }
1377 HANDLE_INSTRUCTION_END();
1378
1379 HANDLE_INSTRUCTION_START(SGET_BOOLEAN) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001380 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimBoolean, do_access_check>(
1381 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001382 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1383 }
1384 HANDLE_INSTRUCTION_END();
1385
1386 HANDLE_INSTRUCTION_START(SGET_BYTE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001387 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimByte, do_access_check>(
1388 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001389 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1390 }
1391 HANDLE_INSTRUCTION_END();
1392
1393 HANDLE_INSTRUCTION_START(SGET_CHAR) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001394 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimChar, do_access_check>(
1395 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001396 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1397 }
1398 HANDLE_INSTRUCTION_END();
1399
1400 HANDLE_INSTRUCTION_START(SGET_SHORT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001401 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimShort, do_access_check>(
1402 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001403 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1404 }
1405 HANDLE_INSTRUCTION_END();
1406
1407 HANDLE_INSTRUCTION_START(SGET) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001408 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimInt, do_access_check>(
1409 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001410 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1411 }
1412 HANDLE_INSTRUCTION_END();
1413
1414 HANDLE_INSTRUCTION_START(SGET_WIDE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001415 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimLong, do_access_check>(
1416 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001417 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1418 }
1419 HANDLE_INSTRUCTION_END();
1420
1421 HANDLE_INSTRUCTION_START(SGET_OBJECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001422 bool success = DoFieldGet<StaticObjectRead, Primitive::kPrimNot, do_access_check>(
1423 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001424 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1425 }
1426 HANDLE_INSTRUCTION_END();
1427
1428 HANDLE_INSTRUCTION_START(IPUT_BOOLEAN) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001429 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1430 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001431 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1432 }
1433 HANDLE_INSTRUCTION_END();
1434
1435 HANDLE_INSTRUCTION_START(IPUT_BYTE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001436 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimByte, do_access_check,
1437 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001438 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1439 }
1440 HANDLE_INSTRUCTION_END();
1441
1442 HANDLE_INSTRUCTION_START(IPUT_CHAR) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001443 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimChar, do_access_check,
1444 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001445 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1446 }
1447 HANDLE_INSTRUCTION_END();
1448
1449 HANDLE_INSTRUCTION_START(IPUT_SHORT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001450 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimShort, do_access_check,
1451 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001452 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1453 }
1454 HANDLE_INSTRUCTION_END();
1455
1456 HANDLE_INSTRUCTION_START(IPUT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001457 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimInt, do_access_check,
1458 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001459 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1460 }
1461 HANDLE_INSTRUCTION_END();
1462
1463 HANDLE_INSTRUCTION_START(IPUT_WIDE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001464 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimLong, do_access_check,
1465 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001466 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1467 }
1468 HANDLE_INSTRUCTION_END();
1469
1470 HANDLE_INSTRUCTION_START(IPUT_OBJECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001471 bool success = DoFieldPut<InstanceObjectWrite, Primitive::kPrimNot, do_access_check,
1472 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001473 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1474 }
1475 HANDLE_INSTRUCTION_END();
1476
1477 HANDLE_INSTRUCTION_START(IPUT_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001478 bool success = DoIPutQuick<Primitive::kPrimInt, transaction_active>(
1479 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001480 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1481 }
1482 HANDLE_INSTRUCTION_END();
1483
Fred Shih37f05ef2014-07-16 18:38:08 -07001484 HANDLE_INSTRUCTION_START(IPUT_BOOLEAN_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001485 bool success = DoIPutQuick<Primitive::kPrimBoolean, transaction_active>(
1486 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001487 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1488 }
1489 HANDLE_INSTRUCTION_END();
1490
1491 HANDLE_INSTRUCTION_START(IPUT_BYTE_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001492 bool success = DoIPutQuick<Primitive::kPrimByte, transaction_active>(
1493 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001494 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1495 }
1496 HANDLE_INSTRUCTION_END();
1497
1498 HANDLE_INSTRUCTION_START(IPUT_CHAR_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001499 bool success = DoIPutQuick<Primitive::kPrimChar, transaction_active>(
1500 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001501 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1502 }
1503 HANDLE_INSTRUCTION_END();
1504
1505 HANDLE_INSTRUCTION_START(IPUT_SHORT_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001506 bool success = DoIPutQuick<Primitive::kPrimShort, transaction_active>(
1507 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001508 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1509 }
1510 HANDLE_INSTRUCTION_END();
1511
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001512 HANDLE_INSTRUCTION_START(IPUT_WIDE_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001513 bool success = DoIPutQuick<Primitive::kPrimLong, transaction_active>(
1514 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001515 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1516 }
1517 HANDLE_INSTRUCTION_END();
1518
1519 HANDLE_INSTRUCTION_START(IPUT_OBJECT_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001520 bool success = DoIPutQuick<Primitive::kPrimNot, transaction_active>(
1521 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001522 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1523 }
1524 HANDLE_INSTRUCTION_END();
1525
1526 HANDLE_INSTRUCTION_START(SPUT_BOOLEAN) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001527 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1528 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001529 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1530 }
1531 HANDLE_INSTRUCTION_END();
1532
1533 HANDLE_INSTRUCTION_START(SPUT_BYTE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001534 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimByte, do_access_check,
1535 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001536 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1537 }
1538 HANDLE_INSTRUCTION_END();
1539
1540 HANDLE_INSTRUCTION_START(SPUT_CHAR) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001541 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimChar, do_access_check,
1542 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001543 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1544 }
1545 HANDLE_INSTRUCTION_END();
1546
1547 HANDLE_INSTRUCTION_START(SPUT_SHORT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001548 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimShort, do_access_check,
1549 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001550 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1551 }
1552 HANDLE_INSTRUCTION_END();
1553
1554 HANDLE_INSTRUCTION_START(SPUT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001555 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimInt, do_access_check,
1556 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001557 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1558 }
1559 HANDLE_INSTRUCTION_END();
1560
1561 HANDLE_INSTRUCTION_START(SPUT_WIDE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001562 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimLong, do_access_check,
1563 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001564 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1565 }
1566 HANDLE_INSTRUCTION_END();
1567
1568 HANDLE_INSTRUCTION_START(SPUT_OBJECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001569 bool success = DoFieldPut<StaticObjectWrite, Primitive::kPrimNot, do_access_check,
1570 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001571 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1572 }
1573 HANDLE_INSTRUCTION_END();
1574
1575 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001576 bool success = DoInvoke<kVirtual, false, do_access_check>(
1577 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001578 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001579 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1580 }
1581 HANDLE_INSTRUCTION_END();
1582
1583 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001584 bool success = DoInvoke<kVirtual, true, do_access_check>(
1585 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001586 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001587 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1588 }
1589 HANDLE_INSTRUCTION_END();
1590
1591 HANDLE_INSTRUCTION_START(INVOKE_SUPER) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001592 bool success = DoInvoke<kSuper, false, do_access_check>(
1593 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001594 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001595 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1596 }
1597 HANDLE_INSTRUCTION_END();
1598
1599 HANDLE_INSTRUCTION_START(INVOKE_SUPER_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001600 bool success = DoInvoke<kSuper, true, do_access_check>(
1601 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001602 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001603 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1604 }
1605 HANDLE_INSTRUCTION_END();
1606
1607 HANDLE_INSTRUCTION_START(INVOKE_DIRECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001608 bool success = DoInvoke<kDirect, false, do_access_check>(
1609 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001610 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001611 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1612 }
1613 HANDLE_INSTRUCTION_END();
1614
1615 HANDLE_INSTRUCTION_START(INVOKE_DIRECT_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001616 bool success = DoInvoke<kDirect, true, do_access_check>(
1617 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001618 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001619 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1620 }
1621 HANDLE_INSTRUCTION_END();
1622
1623 HANDLE_INSTRUCTION_START(INVOKE_INTERFACE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001624 bool success = DoInvoke<kInterface, false, do_access_check>(
1625 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001626 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001627 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1628 }
1629 HANDLE_INSTRUCTION_END();
1630
1631 HANDLE_INSTRUCTION_START(INVOKE_INTERFACE_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001632 bool success = DoInvoke<kInterface, true, do_access_check>(
1633 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001634 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001635 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1636 }
1637 HANDLE_INSTRUCTION_END();
1638
1639 HANDLE_INSTRUCTION_START(INVOKE_STATIC) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001640 bool success = DoInvoke<kStatic, false, do_access_check>(
1641 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001642 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001643 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1644 }
1645 HANDLE_INSTRUCTION_END();
1646
1647 HANDLE_INSTRUCTION_START(INVOKE_STATIC_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001648 bool success = DoInvoke<kStatic, true, do_access_check>(
1649 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001650 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001651 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1652 }
1653 HANDLE_INSTRUCTION_END();
1654
1655 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001656 bool success = DoInvokeVirtualQuick<false>(
1657 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001658 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001659 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1660 }
1661 HANDLE_INSTRUCTION_END();
1662
1663 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_RANGE_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001664 bool success = DoInvokeVirtualQuick<true>(
1665 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001666 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001667 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1668 }
1669 HANDLE_INSTRUCTION_END();
1670
Igor Murashkin158f35c2015-06-10 15:55:30 -07001671 HANDLE_EXPERIMENTAL_INSTRUCTION_START(INVOKE_LAMBDA) {
1672 bool success = DoInvokeLambda<do_access_check>(self, shadow_frame, inst, inst_data,
1673 &result_register);
1674 UPDATE_HANDLER_TABLE();
1675 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1676 }
1677 HANDLE_EXPERIMENTAL_INSTRUCTION_END();
1678
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001679 HANDLE_INSTRUCTION_START(NEG_INT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001680 shadow_frame.SetVReg(
1681 inst->VRegA_12x(inst_data), -shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001682 ADVANCE(1);
1683 HANDLE_INSTRUCTION_END();
1684
1685 HANDLE_INSTRUCTION_START(NOT_INT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001686 shadow_frame.SetVReg(
1687 inst->VRegA_12x(inst_data), ~shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001688 ADVANCE(1);
1689 HANDLE_INSTRUCTION_END();
1690
1691 HANDLE_INSTRUCTION_START(NEG_LONG)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001692 shadow_frame.SetVRegLong(
1693 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001694 ADVANCE(1);
1695 HANDLE_INSTRUCTION_END();
1696
1697 HANDLE_INSTRUCTION_START(NOT_LONG)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001698 shadow_frame.SetVRegLong(
1699 inst->VRegA_12x(inst_data), ~shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001700 ADVANCE(1);
1701 HANDLE_INSTRUCTION_END();
1702
1703 HANDLE_INSTRUCTION_START(NEG_FLOAT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001704 shadow_frame.SetVRegFloat(
1705 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001706 ADVANCE(1);
1707 HANDLE_INSTRUCTION_END();
1708
1709 HANDLE_INSTRUCTION_START(NEG_DOUBLE)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001710 shadow_frame.SetVRegDouble(
1711 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001712 ADVANCE(1);
1713 HANDLE_INSTRUCTION_END();
1714
1715 HANDLE_INSTRUCTION_START(INT_TO_LONG)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001716 shadow_frame.SetVRegLong(
1717 inst->VRegA_12x(inst_data), shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001718 ADVANCE(1);
1719 HANDLE_INSTRUCTION_END();
1720
1721 HANDLE_INSTRUCTION_START(INT_TO_FLOAT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001722 shadow_frame.SetVRegFloat(
1723 inst->VRegA_12x(inst_data), shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001724 ADVANCE(1);
1725 HANDLE_INSTRUCTION_END();
1726
1727 HANDLE_INSTRUCTION_START(INT_TO_DOUBLE)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001728 shadow_frame.SetVRegDouble(
1729 inst->VRegA_12x(inst_data), shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001730 ADVANCE(1);
1731 HANDLE_INSTRUCTION_END();
1732
1733 HANDLE_INSTRUCTION_START(LONG_TO_INT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001734 shadow_frame.SetVReg(
1735 inst->VRegA_12x(inst_data), shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001736 ADVANCE(1);
1737 HANDLE_INSTRUCTION_END();
1738
1739 HANDLE_INSTRUCTION_START(LONG_TO_FLOAT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001740 shadow_frame.SetVRegFloat(
1741 inst->VRegA_12x(inst_data), shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001742 ADVANCE(1);
1743 HANDLE_INSTRUCTION_END();
1744
1745 HANDLE_INSTRUCTION_START(LONG_TO_DOUBLE)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001746 shadow_frame.SetVRegDouble(
1747 inst->VRegA_12x(inst_data), shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001748 ADVANCE(1);
1749 HANDLE_INSTRUCTION_END();
1750
1751 HANDLE_INSTRUCTION_START(FLOAT_TO_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001752 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001753 int32_t result = art_float_to_integral<int32_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001754 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001755 ADVANCE(1);
1756 }
1757 HANDLE_INSTRUCTION_END();
1758
1759 HANDLE_INSTRUCTION_START(FLOAT_TO_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001760 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001761 int64_t result = art_float_to_integral<int64_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001762 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001763 ADVANCE(1);
1764 }
1765 HANDLE_INSTRUCTION_END();
1766
1767 HANDLE_INSTRUCTION_START(FLOAT_TO_DOUBLE)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001768 shadow_frame.SetVRegDouble(
1769 inst->VRegA_12x(inst_data), shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001770 ADVANCE(1);
1771 HANDLE_INSTRUCTION_END();
1772
1773 HANDLE_INSTRUCTION_START(DOUBLE_TO_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001774 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001775 int32_t result = art_float_to_integral<int32_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001776 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001777 ADVANCE(1);
1778 }
1779 HANDLE_INSTRUCTION_END();
1780
1781 HANDLE_INSTRUCTION_START(DOUBLE_TO_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001782 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001783 int64_t result = art_float_to_integral<int64_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001784 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001785 ADVANCE(1);
1786 }
1787 HANDLE_INSTRUCTION_END();
1788
1789 HANDLE_INSTRUCTION_START(DOUBLE_TO_FLOAT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001790 shadow_frame.SetVRegFloat(
1791 inst->VRegA_12x(inst_data), shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001792 ADVANCE(1);
1793 HANDLE_INSTRUCTION_END();
1794
1795 HANDLE_INSTRUCTION_START(INT_TO_BYTE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001796 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1797 static_cast<int8_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001798 ADVANCE(1);
1799 HANDLE_INSTRUCTION_END();
1800
1801 HANDLE_INSTRUCTION_START(INT_TO_CHAR)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001802 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1803 static_cast<uint16_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001804 ADVANCE(1);
1805 HANDLE_INSTRUCTION_END();
1806
1807 HANDLE_INSTRUCTION_START(INT_TO_SHORT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001808 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1809 static_cast<int16_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001810 ADVANCE(1);
1811 HANDLE_INSTRUCTION_END();
1812
1813 HANDLE_INSTRUCTION_START(ADD_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001814 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001815 SafeAdd(shadow_frame.GetVReg(inst->VRegB_23x()),
1816 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001817 ADVANCE(2);
1818 HANDLE_INSTRUCTION_END();
1819
1820 HANDLE_INSTRUCTION_START(SUB_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001821 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001822 SafeSub(shadow_frame.GetVReg(inst->VRegB_23x()),
1823 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001824 ADVANCE(2);
1825 HANDLE_INSTRUCTION_END();
1826
1827 HANDLE_INSTRUCTION_START(MUL_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001828 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001829 SafeMul(shadow_frame.GetVReg(inst->VRegB_23x()),
1830 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001831 ADVANCE(2);
1832 HANDLE_INSTRUCTION_END();
1833
1834 HANDLE_INSTRUCTION_START(DIV_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001835 bool success = DoIntDivide(shadow_frame, inst->VRegA_23x(inst_data),
1836 shadow_frame.GetVReg(inst->VRegB_23x()),
1837 shadow_frame.GetVReg(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001838 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1839 }
1840 HANDLE_INSTRUCTION_END();
1841
1842 HANDLE_INSTRUCTION_START(REM_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001843 bool success = DoIntRemainder(shadow_frame, inst->VRegA_23x(inst_data),
1844 shadow_frame.GetVReg(inst->VRegB_23x()),
1845 shadow_frame.GetVReg(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001846 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1847 }
1848 HANDLE_INSTRUCTION_END();
1849
1850 HANDLE_INSTRUCTION_START(SHL_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001851 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001852 shadow_frame.GetVReg(inst->VRegB_23x()) <<
1853 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1854 ADVANCE(2);
1855 HANDLE_INSTRUCTION_END();
1856
1857 HANDLE_INSTRUCTION_START(SHR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001858 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001859 shadow_frame.GetVReg(inst->VRegB_23x()) >>
1860 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1861 ADVANCE(2);
1862 HANDLE_INSTRUCTION_END();
1863
1864 HANDLE_INSTRUCTION_START(USHR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001865 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001866 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_23x())) >>
1867 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1868 ADVANCE(2);
1869 HANDLE_INSTRUCTION_END();
1870
1871 HANDLE_INSTRUCTION_START(AND_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001872 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001873 shadow_frame.GetVReg(inst->VRegB_23x()) &
1874 shadow_frame.GetVReg(inst->VRegC_23x()));
1875 ADVANCE(2);
1876 HANDLE_INSTRUCTION_END();
1877
1878 HANDLE_INSTRUCTION_START(OR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001879 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001880 shadow_frame.GetVReg(inst->VRegB_23x()) |
1881 shadow_frame.GetVReg(inst->VRegC_23x()));
1882 ADVANCE(2);
1883 HANDLE_INSTRUCTION_END();
1884
1885 HANDLE_INSTRUCTION_START(XOR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001886 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001887 shadow_frame.GetVReg(inst->VRegB_23x()) ^
1888 shadow_frame.GetVReg(inst->VRegC_23x()));
1889 ADVANCE(2);
1890 HANDLE_INSTRUCTION_END();
1891
1892 HANDLE_INSTRUCTION_START(ADD_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001893 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001894 SafeAdd(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1895 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001896 ADVANCE(2);
1897 HANDLE_INSTRUCTION_END();
1898
1899 HANDLE_INSTRUCTION_START(SUB_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001900 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001901 SafeSub(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1902 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001903 ADVANCE(2);
1904 HANDLE_INSTRUCTION_END();
1905
1906 HANDLE_INSTRUCTION_START(MUL_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001907 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001908 SafeMul(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1909 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001910 ADVANCE(2);
1911 HANDLE_INSTRUCTION_END();
1912
1913 HANDLE_INSTRUCTION_START(DIV_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001914 bool success = DoLongDivide(shadow_frame, inst->VRegA_23x(inst_data),
1915 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1916 shadow_frame.GetVRegLong(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001917 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1918 }
1919 HANDLE_INSTRUCTION_END();
1920
1921 HANDLE_INSTRUCTION_START(REM_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001922 bool success = DoLongRemainder(shadow_frame, inst->VRegA_23x(inst_data),
1923 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1924 shadow_frame.GetVRegLong(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001925 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1926 }
1927 HANDLE_INSTRUCTION_END();
1928
1929 HANDLE_INSTRUCTION_START(AND_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001930 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001931 shadow_frame.GetVRegLong(inst->VRegB_23x()) &
1932 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1933 ADVANCE(2);
1934 HANDLE_INSTRUCTION_END();
1935
1936 HANDLE_INSTRUCTION_START(OR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001937 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001938 shadow_frame.GetVRegLong(inst->VRegB_23x()) |
1939 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1940 ADVANCE(2);
1941 HANDLE_INSTRUCTION_END();
1942
1943 HANDLE_INSTRUCTION_START(XOR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001944 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001945 shadow_frame.GetVRegLong(inst->VRegB_23x()) ^
1946 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1947 ADVANCE(2);
1948 HANDLE_INSTRUCTION_END();
1949
1950 HANDLE_INSTRUCTION_START(SHL_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001951 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001952 shadow_frame.GetVRegLong(inst->VRegB_23x()) <<
1953 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1954 ADVANCE(2);
1955 HANDLE_INSTRUCTION_END();
1956
1957 HANDLE_INSTRUCTION_START(SHR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001958 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001959 shadow_frame.GetVRegLong(inst->VRegB_23x()) >>
1960 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1961 ADVANCE(2);
1962 HANDLE_INSTRUCTION_END();
1963
1964 HANDLE_INSTRUCTION_START(USHR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001965 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001966 static_cast<uint64_t>(shadow_frame.GetVRegLong(inst->VRegB_23x())) >>
1967 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1968 ADVANCE(2);
1969 HANDLE_INSTRUCTION_END();
1970
1971 HANDLE_INSTRUCTION_START(ADD_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001972 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001973 shadow_frame.GetVRegFloat(inst->VRegB_23x()) +
1974 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1975 ADVANCE(2);
1976 HANDLE_INSTRUCTION_END();
1977
1978 HANDLE_INSTRUCTION_START(SUB_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001979 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001980 shadow_frame.GetVRegFloat(inst->VRegB_23x()) -
1981 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1982 ADVANCE(2);
1983 HANDLE_INSTRUCTION_END();
1984
1985 HANDLE_INSTRUCTION_START(MUL_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001986 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001987 shadow_frame.GetVRegFloat(inst->VRegB_23x()) *
1988 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1989 ADVANCE(2);
1990 HANDLE_INSTRUCTION_END();
1991
1992 HANDLE_INSTRUCTION_START(DIV_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001993 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001994 shadow_frame.GetVRegFloat(inst->VRegB_23x()) /
1995 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1996 ADVANCE(2);
1997 HANDLE_INSTRUCTION_END();
1998
1999 HANDLE_INSTRUCTION_START(REM_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002000 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002001 fmodf(shadow_frame.GetVRegFloat(inst->VRegB_23x()),
2002 shadow_frame.GetVRegFloat(inst->VRegC_23x())));
2003 ADVANCE(2);
2004 HANDLE_INSTRUCTION_END();
2005
2006 HANDLE_INSTRUCTION_START(ADD_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002007 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002008 shadow_frame.GetVRegDouble(inst->VRegB_23x()) +
2009 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
2010 ADVANCE(2);
2011 HANDLE_INSTRUCTION_END();
2012
2013 HANDLE_INSTRUCTION_START(SUB_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002014 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002015 shadow_frame.GetVRegDouble(inst->VRegB_23x()) -
2016 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
2017 ADVANCE(2);
2018 HANDLE_INSTRUCTION_END();
2019
2020 HANDLE_INSTRUCTION_START(MUL_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002021 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002022 shadow_frame.GetVRegDouble(inst->VRegB_23x()) *
2023 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
2024 ADVANCE(2);
2025 HANDLE_INSTRUCTION_END();
2026
2027 HANDLE_INSTRUCTION_START(DIV_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002028 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002029 shadow_frame.GetVRegDouble(inst->VRegB_23x()) /
2030 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
2031 ADVANCE(2);
2032 HANDLE_INSTRUCTION_END();
2033
2034 HANDLE_INSTRUCTION_START(REM_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002035 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002036 fmod(shadow_frame.GetVRegDouble(inst->VRegB_23x()),
2037 shadow_frame.GetVRegDouble(inst->VRegC_23x())));
2038 ADVANCE(2);
2039 HANDLE_INSTRUCTION_END();
2040
2041 HANDLE_INSTRUCTION_START(ADD_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002042 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002043 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002044 SafeAdd(shadow_frame.GetVReg(vregA),
2045 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002046 ADVANCE(1);
2047 }
2048 HANDLE_INSTRUCTION_END();
2049
2050 HANDLE_INSTRUCTION_START(SUB_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002051 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002052 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002053 SafeSub(shadow_frame.GetVReg(vregA),
2054 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002055 ADVANCE(1);
2056 }
2057 HANDLE_INSTRUCTION_END();
2058
2059 HANDLE_INSTRUCTION_START(MUL_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002060 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002061 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002062 SafeMul(shadow_frame.GetVReg(vregA),
2063 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002064 ADVANCE(1);
2065 }
2066 HANDLE_INSTRUCTION_END();
2067
2068 HANDLE_INSTRUCTION_START(DIV_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002069 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002070 bool success = DoIntDivide(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002071 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002072 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2073 }
2074 HANDLE_INSTRUCTION_END();
2075
2076 HANDLE_INSTRUCTION_START(REM_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002077 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002078 bool success = DoIntRemainder(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002079 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002080 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2081 }
2082 HANDLE_INSTRUCTION_END();
2083
2084 HANDLE_INSTRUCTION_START(SHL_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002085 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002086 shadow_frame.SetVReg(vregA,
2087 shadow_frame.GetVReg(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002088 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002089 ADVANCE(1);
2090 }
2091 HANDLE_INSTRUCTION_END();
2092
2093 HANDLE_INSTRUCTION_START(SHR_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002094 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002095 shadow_frame.SetVReg(vregA,
2096 shadow_frame.GetVReg(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002097 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002098 ADVANCE(1);
2099 }
2100 HANDLE_INSTRUCTION_END();
2101
2102 HANDLE_INSTRUCTION_START(USHR_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002103 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002104 shadow_frame.SetVReg(vregA,
2105 static_cast<uint32_t>(shadow_frame.GetVReg(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002106 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002107 ADVANCE(1);
2108 }
2109 HANDLE_INSTRUCTION_END();
2110
2111 HANDLE_INSTRUCTION_START(AND_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002112 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002113 shadow_frame.SetVReg(vregA,
2114 shadow_frame.GetVReg(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002115 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002116 ADVANCE(1);
2117 }
2118 HANDLE_INSTRUCTION_END();
2119
2120 HANDLE_INSTRUCTION_START(OR_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002121 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002122 shadow_frame.SetVReg(vregA,
2123 shadow_frame.GetVReg(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002124 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002125 ADVANCE(1);
2126 }
2127 HANDLE_INSTRUCTION_END();
2128
2129 HANDLE_INSTRUCTION_START(XOR_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002130 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002131 shadow_frame.SetVReg(vregA,
2132 shadow_frame.GetVReg(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002133 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002134 ADVANCE(1);
2135 }
2136 HANDLE_INSTRUCTION_END();
2137
2138 HANDLE_INSTRUCTION_START(ADD_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002139 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002140 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002141 SafeAdd(shadow_frame.GetVRegLong(vregA),
2142 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002143 ADVANCE(1);
2144 }
2145 HANDLE_INSTRUCTION_END();
2146
2147 HANDLE_INSTRUCTION_START(SUB_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002148 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002149 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002150 SafeSub(shadow_frame.GetVRegLong(vregA),
2151 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002152 ADVANCE(1);
2153 }
2154 HANDLE_INSTRUCTION_END();
2155
2156 HANDLE_INSTRUCTION_START(MUL_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002157 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002158 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002159 SafeMul(shadow_frame.GetVRegLong(vregA),
2160 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002161 ADVANCE(1);
2162 }
2163 HANDLE_INSTRUCTION_END();
2164
2165 HANDLE_INSTRUCTION_START(DIV_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002166 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002167 bool success = DoLongDivide(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002168 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002169 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2170 }
2171 HANDLE_INSTRUCTION_END();
2172
2173 HANDLE_INSTRUCTION_START(REM_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002174 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002175 bool success = DoLongRemainder(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002176 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002177 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2178 }
2179 HANDLE_INSTRUCTION_END();
2180
2181 HANDLE_INSTRUCTION_START(AND_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002182 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002183 shadow_frame.SetVRegLong(vregA,
2184 shadow_frame.GetVRegLong(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002185 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002186 ADVANCE(1);
2187 }
2188 HANDLE_INSTRUCTION_END();
2189
2190 HANDLE_INSTRUCTION_START(OR_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002191 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002192 shadow_frame.SetVRegLong(vregA,
2193 shadow_frame.GetVRegLong(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002194 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002195 ADVANCE(1);
2196 }
2197 HANDLE_INSTRUCTION_END();
2198
2199 HANDLE_INSTRUCTION_START(XOR_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002200 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002201 shadow_frame.SetVRegLong(vregA,
2202 shadow_frame.GetVRegLong(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002203 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002204 ADVANCE(1);
2205 }
2206 HANDLE_INSTRUCTION_END();
2207
2208 HANDLE_INSTRUCTION_START(SHL_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002209 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002210 shadow_frame.SetVRegLong(vregA,
2211 shadow_frame.GetVRegLong(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002212 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002213 ADVANCE(1);
2214 }
2215 HANDLE_INSTRUCTION_END();
2216
2217 HANDLE_INSTRUCTION_START(SHR_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002218 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002219 shadow_frame.SetVRegLong(vregA,
2220 shadow_frame.GetVRegLong(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002221 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002222 ADVANCE(1);
2223 }
2224 HANDLE_INSTRUCTION_END();
2225
2226 HANDLE_INSTRUCTION_START(USHR_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002227 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002228 shadow_frame.SetVRegLong(vregA,
2229 static_cast<uint64_t>(shadow_frame.GetVRegLong(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002230 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002231 ADVANCE(1);
2232 }
2233 HANDLE_INSTRUCTION_END();
2234
2235 HANDLE_INSTRUCTION_START(ADD_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002236 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002237 shadow_frame.SetVRegFloat(vregA,
2238 shadow_frame.GetVRegFloat(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002239 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002240 ADVANCE(1);
2241 }
2242 HANDLE_INSTRUCTION_END();
2243
2244 HANDLE_INSTRUCTION_START(SUB_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002245 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002246 shadow_frame.SetVRegFloat(vregA,
2247 shadow_frame.GetVRegFloat(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002248 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002249 ADVANCE(1);
2250 }
2251 HANDLE_INSTRUCTION_END();
2252
2253 HANDLE_INSTRUCTION_START(MUL_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002254 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002255 shadow_frame.SetVRegFloat(vregA,
2256 shadow_frame.GetVRegFloat(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002257 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002258 ADVANCE(1);
2259 }
2260 HANDLE_INSTRUCTION_END();
2261
2262 HANDLE_INSTRUCTION_START(DIV_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002263 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002264 shadow_frame.SetVRegFloat(vregA,
2265 shadow_frame.GetVRegFloat(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002266 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002267 ADVANCE(1);
2268 }
2269 HANDLE_INSTRUCTION_END();
2270
2271 HANDLE_INSTRUCTION_START(REM_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002272 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002273 shadow_frame.SetVRegFloat(vregA,
2274 fmodf(shadow_frame.GetVRegFloat(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002275 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002276 ADVANCE(1);
2277 }
2278 HANDLE_INSTRUCTION_END();
2279
2280 HANDLE_INSTRUCTION_START(ADD_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002281 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002282 shadow_frame.SetVRegDouble(vregA,
2283 shadow_frame.GetVRegDouble(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002284 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002285 ADVANCE(1);
2286 }
2287 HANDLE_INSTRUCTION_END();
2288
2289 HANDLE_INSTRUCTION_START(SUB_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002290 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002291 shadow_frame.SetVRegDouble(vregA,
2292 shadow_frame.GetVRegDouble(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002293 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002294 ADVANCE(1);
2295 }
2296 HANDLE_INSTRUCTION_END();
2297
2298 HANDLE_INSTRUCTION_START(MUL_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002299 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002300 shadow_frame.SetVRegDouble(vregA,
2301 shadow_frame.GetVRegDouble(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002302 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002303 ADVANCE(1);
2304 }
2305 HANDLE_INSTRUCTION_END();
2306
2307 HANDLE_INSTRUCTION_START(DIV_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002308 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002309 shadow_frame.SetVRegDouble(vregA,
2310 shadow_frame.GetVRegDouble(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002311 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002312 ADVANCE(1);
2313 }
2314 HANDLE_INSTRUCTION_END();
2315
2316 HANDLE_INSTRUCTION_START(REM_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002317 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002318 shadow_frame.SetVRegDouble(vregA,
2319 fmod(shadow_frame.GetVRegDouble(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002320 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002321 ADVANCE(1);
2322 }
2323 HANDLE_INSTRUCTION_END();
2324
2325 HANDLE_INSTRUCTION_START(ADD_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002326 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002327 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2328 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002329 ADVANCE(2);
2330 HANDLE_INSTRUCTION_END();
2331
2332 HANDLE_INSTRUCTION_START(RSUB_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002333 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002334 SafeSub(inst->VRegC_22s(),
2335 shadow_frame.GetVReg(inst->VRegB_22s(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002336 ADVANCE(2);
2337 HANDLE_INSTRUCTION_END();
2338
2339 HANDLE_INSTRUCTION_START(MUL_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002340 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002341 SafeMul(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2342 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002343 ADVANCE(2);
2344 HANDLE_INSTRUCTION_END();
2345
2346 HANDLE_INSTRUCTION_START(DIV_INT_LIT16) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002347 bool success = DoIntDivide(
2348 shadow_frame, inst->VRegA_22s(inst_data), shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2349 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002350 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2351 }
2352 HANDLE_INSTRUCTION_END();
2353
2354 HANDLE_INSTRUCTION_START(REM_INT_LIT16) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002355 bool success = DoIntRemainder(
2356 shadow_frame, inst->VRegA_22s(inst_data), shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2357 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002358 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2359 }
2360 HANDLE_INSTRUCTION_END();
2361
2362 HANDLE_INSTRUCTION_START(AND_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002363 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2364 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) &
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002365 inst->VRegC_22s());
2366 ADVANCE(2);
2367 HANDLE_INSTRUCTION_END();
2368
2369 HANDLE_INSTRUCTION_START(OR_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002370 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2371 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) |
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002372 inst->VRegC_22s());
2373 ADVANCE(2);
2374 HANDLE_INSTRUCTION_END();
2375
2376 HANDLE_INSTRUCTION_START(XOR_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002377 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2378 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) ^
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002379 inst->VRegC_22s());
2380 ADVANCE(2);
2381 HANDLE_INSTRUCTION_END();
2382
2383 HANDLE_INSTRUCTION_START(ADD_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002384 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002385 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22b()),
2386 inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002387 ADVANCE(2);
2388 HANDLE_INSTRUCTION_END();
2389
2390 HANDLE_INSTRUCTION_START(RSUB_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002391 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002392 SafeSub(inst->VRegC_22b(),
2393 shadow_frame.GetVReg(inst->VRegB_22b())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002394 ADVANCE(2);
2395 HANDLE_INSTRUCTION_END();
2396
2397 HANDLE_INSTRUCTION_START(MUL_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002398 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002399 SafeMul(shadow_frame.GetVReg(inst->VRegB_22b()),
2400 inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002401 ADVANCE(2);
2402 HANDLE_INSTRUCTION_END();
2403
2404 HANDLE_INSTRUCTION_START(DIV_INT_LIT8) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002405 bool success = DoIntDivide(shadow_frame, inst->VRegA_22b(inst_data),
2406 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002407 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2408 }
2409 HANDLE_INSTRUCTION_END();
2410
2411 HANDLE_INSTRUCTION_START(REM_INT_LIT8) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002412 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22b(inst_data),
2413 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002414 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2415 }
2416 HANDLE_INSTRUCTION_END();
2417
2418 HANDLE_INSTRUCTION_START(AND_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002419 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002420 shadow_frame.GetVReg(inst->VRegB_22b()) &
2421 inst->VRegC_22b());
2422 ADVANCE(2);
2423 HANDLE_INSTRUCTION_END();
2424
2425 HANDLE_INSTRUCTION_START(OR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002426 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002427 shadow_frame.GetVReg(inst->VRegB_22b()) |
2428 inst->VRegC_22b());
2429 ADVANCE(2);
2430 HANDLE_INSTRUCTION_END();
2431
2432 HANDLE_INSTRUCTION_START(XOR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002433 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002434 shadow_frame.GetVReg(inst->VRegB_22b()) ^
2435 inst->VRegC_22b());
2436 ADVANCE(2);
2437 HANDLE_INSTRUCTION_END();
2438
2439 HANDLE_INSTRUCTION_START(SHL_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002440 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002441 shadow_frame.GetVReg(inst->VRegB_22b()) <<
2442 (inst->VRegC_22b() & 0x1f));
2443 ADVANCE(2);
2444 HANDLE_INSTRUCTION_END();
2445
2446 HANDLE_INSTRUCTION_START(SHR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002447 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002448 shadow_frame.GetVReg(inst->VRegB_22b()) >>
2449 (inst->VRegC_22b() & 0x1f));
2450 ADVANCE(2);
2451 HANDLE_INSTRUCTION_END();
2452
2453 HANDLE_INSTRUCTION_START(USHR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002454 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002455 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_22b())) >>
2456 (inst->VRegC_22b() & 0x1f));
2457 ADVANCE(2);
2458 HANDLE_INSTRUCTION_END();
2459
Igor Murashkin158f35c2015-06-10 15:55:30 -07002460 HANDLE_EXPERIMENTAL_INSTRUCTION_START(CREATE_LAMBDA) {
Igor Murashkin6918bf12015-09-27 19:19:06 -07002461 if (lambda_closure_builder == nullptr) {
2462 // DoCreateLambda always needs a ClosureBuilder, even if it has 0 captured variables.
2463 lambda_closure_builder = MakeUnique<lambda::ClosureBuilder>();
2464 }
2465
2466 // TODO: these allocations should not leak, and the lambda method should not be local.
2467 lambda::Closure* lambda_closure =
2468 reinterpret_cast<lambda::Closure*>(alloca(lambda_closure_builder->GetSize()));
2469 bool success = DoCreateLambda<do_access_check>(self,
2470 inst,
2471 /*inout*/shadow_frame,
2472 /*inout*/lambda_closure_builder.get(),
2473 /*inout*/lambda_closure);
2474 lambda_closure_builder.reset(nullptr); // reset state of variables captured
Igor Murashkin158f35c2015-06-10 15:55:30 -07002475 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2476 }
2477 HANDLE_EXPERIMENTAL_INSTRUCTION_END();
2478
Igor Murashkin2ee54e22015-06-18 10:05:11 -07002479 HANDLE_EXPERIMENTAL_INSTRUCTION_START(BOX_LAMBDA) {
2480 bool success = DoBoxLambda<do_access_check>(self, shadow_frame, inst, inst_data);
2481 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2482 }
2483 HANDLE_EXPERIMENTAL_INSTRUCTION_END();
2484
2485 HANDLE_EXPERIMENTAL_INSTRUCTION_START(UNBOX_LAMBDA) {
2486 bool success = DoUnboxLambda<do_access_check>(self, shadow_frame, inst, inst_data);
2487 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2488 }
2489 HANDLE_EXPERIMENTAL_INSTRUCTION_END();
2490
Igor Murashkin6918bf12015-09-27 19:19:06 -07002491 HANDLE_EXPERIMENTAL_INSTRUCTION_START(CAPTURE_VARIABLE) {
2492 if (lambda_closure_builder == nullptr) {
2493 lambda_closure_builder = MakeUnique<lambda::ClosureBuilder>();
2494 }
2495
2496 bool success = DoCaptureVariable<do_access_check>(self,
2497 inst,
2498 /*inout*/shadow_frame,
2499 /*inout*/lambda_closure_builder.get());
2500
2501 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2502 }
2503 HANDLE_EXPERIMENTAL_INSTRUCTION_END();
2504
2505 HANDLE_EXPERIMENTAL_INSTRUCTION_START(LIBERATE_VARIABLE) {
2506 bool success = DoLiberateVariable<do_access_check>(self,
2507 inst,
2508 lambda_captured_variable_index,
2509 /*inout*/shadow_frame);
2510 // Temporarily only allow sequences of 'liberate-variable, liberate-variable, ...'
2511 lambda_captured_variable_index++;
2512 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2513 }
2514 HANDLE_EXPERIMENTAL_INSTRUCTION_END();
2515
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002516 HANDLE_INSTRUCTION_START(UNUSED_3E)
Ian Rogerse94652f2014-12-02 11:13:19 -08002517 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002518 HANDLE_INSTRUCTION_END();
2519
2520 HANDLE_INSTRUCTION_START(UNUSED_3F)
Ian Rogerse94652f2014-12-02 11:13:19 -08002521 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002522 HANDLE_INSTRUCTION_END();
2523
2524 HANDLE_INSTRUCTION_START(UNUSED_40)
Ian Rogerse94652f2014-12-02 11:13:19 -08002525 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002526 HANDLE_INSTRUCTION_END();
2527
2528 HANDLE_INSTRUCTION_START(UNUSED_41)
Ian Rogerse94652f2014-12-02 11:13:19 -08002529 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002530 HANDLE_INSTRUCTION_END();
2531
2532 HANDLE_INSTRUCTION_START(UNUSED_42)
Ian Rogerse94652f2014-12-02 11:13:19 -08002533 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002534 HANDLE_INSTRUCTION_END();
2535
2536 HANDLE_INSTRUCTION_START(UNUSED_43)
Ian Rogerse94652f2014-12-02 11:13:19 -08002537 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002538 HANDLE_INSTRUCTION_END();
2539
2540 HANDLE_INSTRUCTION_START(UNUSED_79)
Ian Rogerse94652f2014-12-02 11:13:19 -08002541 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002542 HANDLE_INSTRUCTION_END();
2543
2544 HANDLE_INSTRUCTION_START(UNUSED_7A)
Ian Rogerse94652f2014-12-02 11:13:19 -08002545 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002546 HANDLE_INSTRUCTION_END();
2547
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002548 HANDLE_INSTRUCTION_START(UNUSED_F4)
Ian Rogerse94652f2014-12-02 11:13:19 -08002549 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002550 HANDLE_INSTRUCTION_END();
2551
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002552 HANDLE_INSTRUCTION_START(UNUSED_FA)
Ian Rogerse94652f2014-12-02 11:13:19 -08002553 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002554 HANDLE_INSTRUCTION_END();
2555
2556 HANDLE_INSTRUCTION_START(UNUSED_FB)
Ian Rogerse94652f2014-12-02 11:13:19 -08002557 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002558 HANDLE_INSTRUCTION_END();
2559
2560 HANDLE_INSTRUCTION_START(UNUSED_FC)
Ian Rogerse94652f2014-12-02 11:13:19 -08002561 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002562 HANDLE_INSTRUCTION_END();
2563
2564 HANDLE_INSTRUCTION_START(UNUSED_FD)
Ian Rogerse94652f2014-12-02 11:13:19 -08002565 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002566 HANDLE_INSTRUCTION_END();
2567
2568 HANDLE_INSTRUCTION_START(UNUSED_FE)
Ian Rogerse94652f2014-12-02 11:13:19 -08002569 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002570 HANDLE_INSTRUCTION_END();
2571
2572 HANDLE_INSTRUCTION_START(UNUSED_FF)
Ian Rogerse94652f2014-12-02 11:13:19 -08002573 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002574 HANDLE_INSTRUCTION_END();
2575
2576 exception_pending_label: {
2577 CHECK(self->IsExceptionPending());
Sebastien Hertz1eda2262013-09-09 16:53:14 +02002578 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -07002579 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +02002580 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +02002581 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002582 uint32_t found_dex_pc = FindNextInstructionFollowingException(self, shadow_frame, dex_pc,
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002583 instrumentation);
2584 if (found_dex_pc == DexFile::kDexNoIndex) {
Andreas Gampe03ec9302015-08-27 17:41:47 -07002585 // Structured locking is to be enforced for abnormal termination, too.
Andreas Gampe56fdd0e2016-04-28 14:56:54 -07002586 DoMonitorCheckOnExit<do_assignability_check>(self, &shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002587 return JValue(); /* Handled in caller. */
2588 } else {
2589 int32_t displacement = static_cast<int32_t>(found_dex_pc) - static_cast<int32_t>(dex_pc);
2590 ADVANCE(displacement);
2591 }
2592 }
2593
Sebastien Hertz8379b222014-02-24 17:38:15 +01002594// Create alternative instruction handlers dedicated to instrumentation.
2595// Return instructions must not call Instrumentation::DexPcMovedEvent since they already call
2596// Instrumentation::MethodExited. This is to avoid posting debugger events twice for this location.
Sebastien Hertze713d932014-05-15 10:48:53 +02002597// Note: we do not use the kReturn instruction flag here (to test the instruction is a return). The
2598// compiler seems to not evaluate "(Instruction::FlagsOf(Instruction::code) & kReturn) != 0" to
2599// a constant condition that would remove the "if" statement so the test is free.
Narayan Kamathbd48b342016-08-01 17:32:37 +01002600#define INSTRUMENTATION_INSTRUCTION_HANDLER(o, code, n, f, i, a, v) \
Sebastien Hertz9d6bf692015-04-10 12:12:33 +02002601 alt_op_##code: { \
Sebastien Hertz9d6bf692015-04-10 12:12:33 +02002602 if (UNLIKELY(instrumentation->HasDexPcListeners())) { \
2603 Object* this_object = shadow_frame.GetThisObject(code_item->ins_size_); \
2604 instrumentation->DexPcMovedEvent(self, this_object, shadow_frame.GetMethod(), dex_pc); \
2605 } \
2606 UPDATE_HANDLER_TABLE(); \
2607 goto *handlersTable[instrumentation::kMainHandlerTable][Instruction::code]; \
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002608 }
2609#include "dex_instruction_list.h"
2610 DEX_INSTRUCTION_LIST(INSTRUMENTATION_INSTRUCTION_HANDLER)
2611#undef DEX_INSTRUCTION_LIST
2612#undef INSTRUMENTATION_INSTRUCTION_HANDLER
2613} // NOLINT(readability/fn_size)
2614
2615// Explicit definitions of ExecuteGotoImpl.
Mathieu Chartier90443472015-07-16 20:32:27 -07002616template SHARED_REQUIRES(Locks::mutator_lock_) HOT_ATTR
Ian Rogerse94652f2014-12-02 11:13:19 -08002617JValue ExecuteGotoImpl<true, false>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002618 ShadowFrame& shadow_frame, JValue result_register);
Mathieu Chartier90443472015-07-16 20:32:27 -07002619template SHARED_REQUIRES(Locks::mutator_lock_) HOT_ATTR
Ian Rogerse94652f2014-12-02 11:13:19 -08002620JValue ExecuteGotoImpl<false, false>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002621 ShadowFrame& shadow_frame, JValue result_register);
Mathieu Chartier90443472015-07-16 20:32:27 -07002622template SHARED_REQUIRES(Locks::mutator_lock_)
Ian Rogerse94652f2014-12-02 11:13:19 -08002623JValue ExecuteGotoImpl<true, true>(Thread* self, const DexFile::CodeItem* code_item,
2624 ShadowFrame& shadow_frame, JValue result_register);
Mathieu Chartier90443472015-07-16 20:32:27 -07002625template SHARED_REQUIRES(Locks::mutator_lock_)
Ian Rogerse94652f2014-12-02 11:13:19 -08002626JValue ExecuteGotoImpl<false, true>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002627 ShadowFrame& shadow_frame, JValue result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002628
2629} // namespace interpreter
2630} // namespace art
Colin Crosse84e4f72015-03-18 14:01:19 -07002631
2632#endif