blob: 43b27781e4ca759ba4a74c6d43c1f7262ec10881 [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
Alex Lighteb7c1442015-08-31 13:17:42 -070021#include "experimental_flags.h"
Sebastien Hertz8ece0502013-08-07 11:26:41 +020022#include "interpreter_common.h"
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +000023#include "jit/jit.h"
Ian Rogersf72a11d2014-10-30 15:41:08 -070024#include "safe_math.h"
Sebastien Hertz8ece0502013-08-07 11:26:41 +020025
26namespace art {
27namespace interpreter {
28
29// In the following macros, we expect the following local variables exist:
30// - "self": the current Thread*.
31// - "inst" : the current Instruction*.
Sebastien Hertz3b588e02013-09-11 14:33:18 +020032// - "inst_data" : the current instruction's first 16 bits.
Sebastien Hertz8ece0502013-08-07 11:26:41 +020033// - "dex_pc": the current pc.
34// - "shadow_frame": the current shadow frame.
Sebastien Hertz8ece0502013-08-07 11:26:41 +020035// - "currentHandlersTable": the current table of pointer to each instruction handler.
36
37// Advance to the next instruction and updates interpreter state.
Sebastien Hertz8ece0502013-08-07 11:26:41 +020038#define ADVANCE(_offset) \
39 do { \
40 int32_t disp = static_cast<int32_t>(_offset); \
41 inst = inst->RelativeAt(disp); \
42 dex_pc = static_cast<uint32_t>(static_cast<int32_t>(dex_pc) + disp); \
43 shadow_frame.SetDexPC(dex_pc); \
Ian Rogerse94652f2014-12-02 11:13:19 -080044 TraceExecution(shadow_frame, inst, dex_pc); \
Sebastien Hertz3b588e02013-09-11 14:33:18 +020045 inst_data = inst->Fetch16(0); \
46 goto *currentHandlersTable[inst->Opcode(inst_data)]; \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020047 } while (false)
48
49#define HANDLE_PENDING_EXCEPTION() goto exception_pending_label
50
51#define POSSIBLY_HANDLE_PENDING_EXCEPTION(_is_exception_pending, _offset) \
52 do { \
53 if (UNLIKELY(_is_exception_pending)) { \
54 HANDLE_PENDING_EXCEPTION(); \
55 } else { \
56 ADVANCE(_offset); \
57 } \
58 } while (false)
59
Sebastien Hertzee1997a2013-09-19 14:47:09 +020060#define UPDATE_HANDLER_TABLE() \
Mathieu Chartier2cebb242015-04-21 16:50:40 -070061 currentHandlersTable = handlersTable[ \
62 Runtime::Current()->GetInstrumentation()->GetInterpreterHandlerTable()]
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +020063
Bill Buzbee1d011d92016-04-04 16:59:29 +000064#define BRANCH_INSTRUMENTATION(offset) \
65 do { \
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +010066 if (UNLIKELY(instrumentation->HasBranchListeners())) { \
67 instrumentation->Branch(self, method, dex_pc, offset); \
68 } \
Bill Buzbee1d011d92016-04-04 16:59:29 +000069 JValue result; \
70 if (jit::Jit::MaybeDoOnStackReplacement(self, method, dex_pc, offset, &result)) { \
71 return result; \
72 } \
73 } while (false)
74
75#define HOTNESS_UPDATE() \
76 do { \
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +010077 if (jit != nullptr) { \
Nicolas Geoffray71cd50f2016-04-14 15:00:33 +010078 jit->AddSamples(self, method, 1, /*with_backedges*/ true); \
Bill Buzbee1d011d92016-04-04 16:59:29 +000079 } \
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080080 } while (false)
81
Sebastien Hertz8ece0502013-08-07 11:26:41 +020082#define UNREACHABLE_CODE_CHECK() \
83 do { \
84 if (kIsDebugBuild) { \
85 LOG(FATAL) << "We should not be here !"; \
Ian Rogerse94652f2014-12-02 11:13:19 -080086 UNREACHABLE(); \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020087 } \
88 } while (false)
89
90#define HANDLE_INSTRUCTION_START(opcode) op_##opcode: // NOLINT(whitespace/labels)
91#define HANDLE_INSTRUCTION_END() UNREACHABLE_CODE_CHECK()
92
Andreas Gampe03ec9302015-08-27 17:41:47 -070093#define HANDLE_MONITOR_CHECKS() \
Andreas Gampe56fdd0e2016-04-28 14:56:54 -070094 if (!DoMonitorCheckOnExit<do_assignability_check>(self, &shadow_frame)) { \
Andreas Gampe03ec9302015-08-27 17:41:47 -070095 HANDLE_PENDING_EXCEPTION(); \
96 }
Igor Murashkin158f35c2015-06-10 15:55:30 -070097
Sebastien Hertzee1997a2013-09-19 14:47:09 +020098/**
99 * Interpreter based on computed goto tables.
100 *
101 * Each instruction is associated to a handler. This handler is responsible for executing the
102 * instruction and jump to the next instruction's handler.
103 * In order to limit the cost of instrumentation, we have two handler tables:
104 * - the "main" handler table: it contains handlers for normal execution of each instruction without
105 * handling of instrumentation.
106 * - the "alternative" handler table: it contains alternative handlers which first handle
107 * instrumentation before jumping to the corresponding "normal" instruction's handler.
108 *
109 * When instrumentation is active, the interpreter uses the "alternative" handler table. Otherwise
110 * it uses the "main" handler table.
111 *
112 * The current handler table is the handler table being used by the interpreter. It is updated:
113 * - on backward branch (goto, if and switch instructions)
114 * - after invoke
115 * - when an exception is thrown.
116 * This allows to support an attaching debugger to an already running application for instance.
117 *
118 * For a fast handler table update, handler tables are stored in an array of handler tables. Each
119 * handler table is represented by the InterpreterHandlerTable enum which allows to associate it
120 * to an index in this array of handler tables ((see Instrumentation::GetInterpreterHandlerTable).
121 *
122 * Here's the current layout of this array of handler tables:
123 *
124 * ---------------------+---------------+
125 * | NOP | (handler for NOP instruction)
126 * +---------------+
127 * "main" | MOVE | (handler for MOVE instruction)
128 * handler table +---------------+
129 * | ... |
130 * +---------------+
131 * | UNUSED_FF | (handler for UNUSED_FF instruction)
132 * ---------------------+---------------+
133 * | NOP | (alternative handler for NOP instruction)
134 * +---------------+
135 * "alternative" | MOVE | (alternative handler for MOVE instruction)
136 * handler table +---------------+
137 * | ... |
138 * +---------------+
139 * | UNUSED_FF | (alternative handler for UNUSED_FF instruction)
140 * ---------------------+---------------+
141 *
142 */
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100143template<bool do_access_check, bool transaction_active>
Ian Rogerse94652f2014-12-02 11:13:19 -0800144JValue ExecuteGotoImpl(Thread* self, const DexFile::CodeItem* code_item, ShadowFrame& shadow_frame,
145 JValue result_register) {
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200146 // Define handler tables:
147 // - The main handler table contains execution handlers for each instruction.
148 // - The alternative handler table contains prelude handlers which check for thread suspend and
149 // manage instrumentation before jumping to the execution handler.
150 static const void* const handlersTable[instrumentation::kNumHandlerTables][kNumPackedOpcodes] = {
151 {
152 // Main handler table.
Narayan Kamathbd48b342016-08-01 17:32:37 +0100153#define INSTRUCTION_HANDLER(o, code, n, f, i, a, v) &&op_##code,
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200154#include "dex_instruction_list.h"
155 DEX_INSTRUCTION_LIST(INSTRUCTION_HANDLER)
156#undef DEX_INSTRUCTION_LIST
157#undef INSTRUCTION_HANDLER
158 }, {
159 // Alternative handler table.
Narayan Kamathbd48b342016-08-01 17:32:37 +0100160#define INSTRUCTION_HANDLER(o, code, n, f, i, a, v) &&alt_op_##code,
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200161#include "dex_instruction_list.h"
162 DEX_INSTRUCTION_LIST(INSTRUCTION_HANDLER)
163#undef DEX_INSTRUCTION_LIST
164#undef INSTRUCTION_HANDLER
165 }
166 };
167
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800168 constexpr bool do_assignability_check = do_access_check;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200169 if (UNLIKELY(!shadow_frame.HasReferenceArray())) {
170 LOG(FATAL) << "Invalid shadow frame for interpreter use";
171 return JValue();
172 }
173 self->VerifyStack();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200174
175 uint32_t dex_pc = shadow_frame.GetDexPC();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200176 const Instruction* inst = Instruction::At(code_item->insns_ + dex_pc);
177 uint16_t inst_data;
178 const void* const* currentHandlersTable;
179 UPDATE_HANDLER_TABLE();
Bill Buzbee1d011d92016-04-04 16:59:29 +0000180 const auto* const instrumentation = Runtime::Current()->GetInstrumentation();
181 ArtMethod* method = shadow_frame.GetMethod();
182 jit::Jit* jit = Runtime::Current()->GetJit();
Igor Murashkin6918bf12015-09-27 19:19:06 -0700183
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200184 // Jump to first instruction.
185 ADVANCE(0);
186 UNREACHABLE_CODE_CHECK();
187
188 HANDLE_INSTRUCTION_START(NOP)
189 ADVANCE(1);
190 HANDLE_INSTRUCTION_END();
191
192 HANDLE_INSTRUCTION_START(MOVE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200193 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
194 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200195 ADVANCE(1);
196 HANDLE_INSTRUCTION_END();
197
198 HANDLE_INSTRUCTION_START(MOVE_FROM16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200199 shadow_frame.SetVReg(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200200 shadow_frame.GetVReg(inst->VRegB_22x()));
201 ADVANCE(2);
202 HANDLE_INSTRUCTION_END();
203
204 HANDLE_INSTRUCTION_START(MOVE_16)
205 shadow_frame.SetVReg(inst->VRegA_32x(),
206 shadow_frame.GetVReg(inst->VRegB_32x()));
207 ADVANCE(3);
208 HANDLE_INSTRUCTION_END();
209
210 HANDLE_INSTRUCTION_START(MOVE_WIDE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200211 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
212 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200213 ADVANCE(1);
214 HANDLE_INSTRUCTION_END();
215
216 HANDLE_INSTRUCTION_START(MOVE_WIDE_FROM16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200217 shadow_frame.SetVRegLong(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200218 shadow_frame.GetVRegLong(inst->VRegB_22x()));
219 ADVANCE(2);
220 HANDLE_INSTRUCTION_END();
221
222 HANDLE_INSTRUCTION_START(MOVE_WIDE_16)
223 shadow_frame.SetVRegLong(inst->VRegA_32x(),
224 shadow_frame.GetVRegLong(inst->VRegB_32x()));
225 ADVANCE(3);
226 HANDLE_INSTRUCTION_END();
227
228 HANDLE_INSTRUCTION_START(MOVE_OBJECT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200229 shadow_frame.SetVRegReference(inst->VRegA_12x(inst_data),
230 shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200231 ADVANCE(1);
232 HANDLE_INSTRUCTION_END();
233
234 HANDLE_INSTRUCTION_START(MOVE_OBJECT_FROM16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200235 shadow_frame.SetVRegReference(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200236 shadow_frame.GetVRegReference(inst->VRegB_22x()));
237 ADVANCE(2);
238 HANDLE_INSTRUCTION_END();
239
240 HANDLE_INSTRUCTION_START(MOVE_OBJECT_16)
241 shadow_frame.SetVRegReference(inst->VRegA_32x(),
242 shadow_frame.GetVRegReference(inst->VRegB_32x()));
243 ADVANCE(3);
244 HANDLE_INSTRUCTION_END();
245
246 HANDLE_INSTRUCTION_START(MOVE_RESULT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200247 shadow_frame.SetVReg(inst->VRegA_11x(inst_data), result_register.GetI());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200248 ADVANCE(1);
249 HANDLE_INSTRUCTION_END();
250
251 HANDLE_INSTRUCTION_START(MOVE_RESULT_WIDE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200252 shadow_frame.SetVRegLong(inst->VRegA_11x(inst_data), result_register.GetJ());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200253 ADVANCE(1);
254 HANDLE_INSTRUCTION_END();
255
256 HANDLE_INSTRUCTION_START(MOVE_RESULT_OBJECT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200257 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), result_register.GetL());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200258 ADVANCE(1);
259 HANDLE_INSTRUCTION_END();
260
261 HANDLE_INSTRUCTION_START(MOVE_EXCEPTION) {
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000262 Throwable* exception = self->GetException();
Sebastien Hertz270a0e12015-01-16 19:49:09 +0100263 DCHECK(exception != nullptr) << "No pending exception on MOVE_EXCEPTION instruction";
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200264 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), exception);
Sebastien Hertz5c004902014-05-21 10:07:42 +0200265 self->ClearException();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200266 ADVANCE(1);
267 }
268 HANDLE_INSTRUCTION_END();
269
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700270 HANDLE_INSTRUCTION_START(RETURN_VOID_NO_BARRIER) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200271 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700272 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700273 HANDLE_MONITOR_CHECKS();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200274 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200275 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200276 shadow_frame.GetMethod(), dex_pc,
277 result);
278 }
279 return result;
280 }
281 HANDLE_INSTRUCTION_END();
282
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700283 HANDLE_INSTRUCTION_START(RETURN_VOID) {
Hans Boehm30359612014-05-21 17:46:23 -0700284 QuasiAtomic::ThreadFenceForConstructor();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200285 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700286 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700287 HANDLE_MONITOR_CHECKS();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200288 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200289 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200290 shadow_frame.GetMethod(), dex_pc,
291 result);
292 }
293 return result;
294 }
295 HANDLE_INSTRUCTION_END();
296
297 HANDLE_INSTRUCTION_START(RETURN) {
298 JValue result;
299 result.SetJ(0);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200300 result.SetI(shadow_frame.GetVReg(inst->VRegA_11x(inst_data)));
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_WIDE) {
313 JValue result;
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200314 result.SetJ(shadow_frame.GetVRegLong(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700315 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700316 HANDLE_MONITOR_CHECKS();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200317 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200318 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200319 shadow_frame.GetMethod(), dex_pc,
320 result);
321 }
322 return result;
323 }
324 HANDLE_INSTRUCTION_END();
325
326 HANDLE_INSTRUCTION_START(RETURN_OBJECT) {
327 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700328 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700329 HANDLE_MONITOR_CHECKS();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700330 const uint8_t vreg_index = inst->VRegA_11x(inst_data);
331 Object* obj_result = shadow_frame.GetVRegReference(vreg_index);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700332 if (do_assignability_check && obj_result != nullptr) {
Vladimir Marko05792b92015-08-03 11:56:49 +0100333 size_t pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
334 Class* return_type = shadow_frame.GetMethod()->GetReturnType(true /* resolve */,
335 pointer_size);
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700336 obj_result = shadow_frame.GetVRegReference(vreg_index);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700337 if (return_type == nullptr) {
Jeff Haoa3faaf42013-09-03 19:07:00 -0700338 // Return the pending exception.
339 HANDLE_PENDING_EXCEPTION();
340 }
341 if (!obj_result->VerifierInstanceOf(return_type)) {
342 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700343 std::string temp1, temp2;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000344 self->ThrowNewExceptionF("Ljava/lang/VirtualMachineError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700345 "Returning '%s' that is not instance of return type '%s'",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700346 obj_result->GetClass()->GetDescriptor(&temp1),
347 return_type->GetDescriptor(&temp2));
Jeff Haoa3faaf42013-09-03 19:07:00 -0700348 HANDLE_PENDING_EXCEPTION();
349 }
350 }
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700351 result.SetL(obj_result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200352 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200353 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200354 shadow_frame.GetMethod(), dex_pc,
355 result);
356 }
357 return result;
358 }
359 HANDLE_INSTRUCTION_END();
360
361 HANDLE_INSTRUCTION_START(CONST_4) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200362 uint32_t dst = inst->VRegA_11n(inst_data);
363 int32_t val = inst->VRegB_11n(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200364 shadow_frame.SetVReg(dst, val);
365 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700366 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200367 }
368 ADVANCE(1);
369 }
370 HANDLE_INSTRUCTION_END();
371
372 HANDLE_INSTRUCTION_START(CONST_16) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200373 uint32_t dst = inst->VRegA_21s(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200374 int32_t val = inst->VRegB_21s();
375 shadow_frame.SetVReg(dst, val);
376 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700377 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200378 }
379 ADVANCE(2);
380 }
381 HANDLE_INSTRUCTION_END();
382
383 HANDLE_INSTRUCTION_START(CONST) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200384 uint32_t dst = inst->VRegA_31i(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200385 int32_t val = inst->VRegB_31i();
386 shadow_frame.SetVReg(dst, val);
387 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700388 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200389 }
390 ADVANCE(3);
391 }
392 HANDLE_INSTRUCTION_END();
393
394 HANDLE_INSTRUCTION_START(CONST_HIGH16) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200395 uint32_t dst = inst->VRegA_21h(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200396 int32_t val = static_cast<int32_t>(inst->VRegB_21h() << 16);
397 shadow_frame.SetVReg(dst, val);
398 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700399 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200400 }
401 ADVANCE(2);
402 }
403 HANDLE_INSTRUCTION_END();
404
405 HANDLE_INSTRUCTION_START(CONST_WIDE_16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200406 shadow_frame.SetVRegLong(inst->VRegA_21s(inst_data), inst->VRegB_21s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200407 ADVANCE(2);
408 HANDLE_INSTRUCTION_END();
409
410 HANDLE_INSTRUCTION_START(CONST_WIDE_32)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200411 shadow_frame.SetVRegLong(inst->VRegA_31i(inst_data), inst->VRegB_31i());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200412 ADVANCE(3);
413 HANDLE_INSTRUCTION_END();
414
415 HANDLE_INSTRUCTION_START(CONST_WIDE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200416 shadow_frame.SetVRegLong(inst->VRegA_51l(inst_data), inst->VRegB_51l());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200417 ADVANCE(5);
418 HANDLE_INSTRUCTION_END();
419
420 HANDLE_INSTRUCTION_START(CONST_WIDE_HIGH16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200421 shadow_frame.SetVRegLong(inst->VRegA_21h(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200422 static_cast<uint64_t>(inst->VRegB_21h()) << 48);
423 ADVANCE(2);
424 HANDLE_INSTRUCTION_END();
425
426 HANDLE_INSTRUCTION_START(CONST_STRING) {
Ian Rogers6786a582014-10-28 12:49:06 -0700427 String* s = ResolveString(self, shadow_frame, inst->VRegB_21c());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700428 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200429 HANDLE_PENDING_EXCEPTION();
430 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200431 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200432 ADVANCE(2);
433 }
434 }
435 HANDLE_INSTRUCTION_END();
436
437 HANDLE_INSTRUCTION_START(CONST_STRING_JUMBO) {
Ian Rogers6786a582014-10-28 12:49:06 -0700438 String* s = ResolveString(self, shadow_frame, inst->VRegB_31c());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700439 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200440 HANDLE_PENDING_EXCEPTION();
441 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200442 shadow_frame.SetVRegReference(inst->VRegA_31c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200443 ADVANCE(3);
444 }
445 }
446 HANDLE_INSTRUCTION_END();
447
448 HANDLE_INSTRUCTION_START(CONST_CLASS) {
449 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
450 self, false, do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700451 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200452 HANDLE_PENDING_EXCEPTION();
453 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200454 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), c);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200455 ADVANCE(2);
456 }
457 }
458 HANDLE_INSTRUCTION_END();
459
460 HANDLE_INSTRUCTION_START(MONITOR_ENTER) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200461 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700462 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000463 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200464 HANDLE_PENDING_EXCEPTION();
465 } else {
Andreas Gampe03ec9302015-08-27 17:41:47 -0700466 DoMonitorEnter<do_access_check>(self, &shadow_frame, obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200467 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), 1);
468 }
469 }
470 HANDLE_INSTRUCTION_END();
471
472 HANDLE_INSTRUCTION_START(MONITOR_EXIT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200473 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700474 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000475 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200476 HANDLE_PENDING_EXCEPTION();
477 } else {
Andreas Gampe03ec9302015-08-27 17:41:47 -0700478 DoMonitorExit<do_access_check>(self, &shadow_frame, obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200479 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), 1);
480 }
481 }
482 HANDLE_INSTRUCTION_END();
483
484 HANDLE_INSTRUCTION_START(CHECK_CAST) {
485 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
486 self, false, do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700487 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200488 HANDLE_PENDING_EXCEPTION();
489 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200490 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_21c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700491 if (UNLIKELY(obj != nullptr && !obj->InstanceOf(c))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200492 ThrowClassCastException(c, obj->GetClass());
493 HANDLE_PENDING_EXCEPTION();
494 } else {
495 ADVANCE(2);
496 }
497 }
498 }
499 HANDLE_INSTRUCTION_END();
500
501 HANDLE_INSTRUCTION_START(INSTANCE_OF) {
502 Class* c = ResolveVerifyAndClinit(inst->VRegC_22c(), shadow_frame.GetMethod(),
503 self, false, do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700504 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200505 HANDLE_PENDING_EXCEPTION();
506 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200507 Object* obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700508 shadow_frame.SetVReg(inst->VRegA_22c(inst_data), (obj != nullptr && obj->InstanceOf(c)) ? 1 : 0);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200509 ADVANCE(2);
510 }
511 }
512 HANDLE_INSTRUCTION_END();
513
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700514 HANDLE_INSTRUCTION_START(ARRAY_LENGTH) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200515 Object* array = shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700516 if (UNLIKELY(array == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000517 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200518 HANDLE_PENDING_EXCEPTION();
519 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200520 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), array->AsArray()->GetLength());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200521 ADVANCE(1);
522 }
523 }
524 HANDLE_INSTRUCTION_END();
525
526 HANDLE_INSTRUCTION_START(NEW_INSTANCE) {
Jeff Hao848f70a2014-01-15 13:49:50 -0800527 Object* obj = nullptr;
528 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
529 self, false, do_access_check);
530 if (LIKELY(c != nullptr)) {
531 if (UNLIKELY(c->IsStringClass())) {
532 gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
533 mirror::SetStringCountVisitor visitor(0);
534 obj = String::Alloc<true>(self, 0, allocator_type, visitor);
535 } else {
536 obj = AllocObjectFromCode<do_access_check, true>(
537 inst->VRegB_21c(), shadow_frame.GetMethod(), self,
538 Runtime::Current()->GetHeap()->GetCurrentAllocator());
539 }
540 }
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700541 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200542 HANDLE_PENDING_EXCEPTION();
543 } else {
Sebastien Hertz4e99b3d2014-06-24 14:35:40 +0200544 obj->GetClass()->AssertInitializedOrInitializingInThread(self);
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700545 // Don't allow finalizable objects to be allocated during a transaction since these can't be
546 // finalized without a started runtime.
547 if (transaction_active && obj->GetClass()->IsFinalizable()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +0200548 AbortTransactionF(self, "Allocating finalizable object in transaction: %s",
549 PrettyTypeOf(obj).c_str());
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700550 HANDLE_PENDING_EXCEPTION();
551 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200552 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200553 ADVANCE(2);
554 }
555 }
556 HANDLE_INSTRUCTION_END();
557
558 HANDLE_INSTRUCTION_START(NEW_ARRAY) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200559 int32_t length = shadow_frame.GetVReg(inst->VRegB_22c(inst_data));
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800560 Object* obj = AllocArrayFromCode<do_access_check, true>(
Andreas Gampe1cc7dba2014-12-17 18:43:01 -0800561 inst->VRegC_22c(), length, shadow_frame.GetMethod(), self,
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800562 Runtime::Current()->GetHeap()->GetCurrentAllocator());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700563 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200564 HANDLE_PENDING_EXCEPTION();
565 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200566 shadow_frame.SetVRegReference(inst->VRegA_22c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200567 ADVANCE(2);
568 }
569 }
570 HANDLE_INSTRUCTION_END();
571
572 HANDLE_INSTRUCTION_START(FILLED_NEW_ARRAY) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100573 bool success =
574 DoFilledNewArray<false, do_access_check, transaction_active>(inst, shadow_frame,
575 self, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200576 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
577 }
578 HANDLE_INSTRUCTION_END();
579
580 HANDLE_INSTRUCTION_START(FILLED_NEW_ARRAY_RANGE) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100581 bool success =
582 DoFilledNewArray<true, do_access_check, transaction_active>(inst, shadow_frame,
583 self, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200584 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
585 }
586 HANDLE_INSTRUCTION_END();
587
588 HANDLE_INSTRUCTION_START(FILL_ARRAY_DATA) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200589 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_31t(inst_data));
Ian Rogers832336b2014-10-08 15:35:22 -0700590 const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t();
591 const Instruction::ArrayDataPayload* payload =
592 reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr);
593 bool success = FillArrayData(obj, payload);
594 if (transaction_active && success) {
595 RecordArrayElementsInTransaction(obj->AsArray(), payload->element_count);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200596 }
Ian Rogers832336b2014-10-08 15:35:22 -0700597 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200598 }
599 HANDLE_INSTRUCTION_END();
600
601 HANDLE_INSTRUCTION_START(THROW) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200602 Object* exception = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700603 if (UNLIKELY(exception == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000604 ThrowNullPointerException("throw with null exception");
Jeff Haoa3faaf42013-09-03 19:07:00 -0700605 } else if (do_assignability_check && !exception->GetClass()->IsThrowableClass()) {
606 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700607 std::string temp;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000608 self->ThrowNewExceptionF("Ljava/lang/VirtualMachineError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700609 "Throwing '%s' that is not instance of Throwable",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700610 exception->GetClass()->GetDescriptor(&temp));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200611 } else {
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000612 self->SetException(exception->AsThrowable());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200613 }
614 HANDLE_PENDING_EXCEPTION();
615 }
616 HANDLE_INSTRUCTION_END();
617
618 HANDLE_INSTRUCTION_START(GOTO) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200619 int8_t offset = inst->VRegA_10t(inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000620 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200621 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000622 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200623 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700624 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200625 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200626 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200627 }
628 ADVANCE(offset);
629 }
630 HANDLE_INSTRUCTION_END();
631
632 HANDLE_INSTRUCTION_START(GOTO_16) {
633 int16_t offset = inst->VRegA_20t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000634 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200635 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000636 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200637 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700638 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200639 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200640 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200641 }
642 ADVANCE(offset);
643 }
644 HANDLE_INSTRUCTION_END();
645
646 HANDLE_INSTRUCTION_START(GOTO_32) {
647 int32_t offset = inst->VRegA_30t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000648 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200649 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000650 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200651 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700652 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200653 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200654 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200655 }
656 ADVANCE(offset);
657 }
658 HANDLE_INSTRUCTION_END();
659
660 HANDLE_INSTRUCTION_START(PACKED_SWITCH) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200661 int32_t offset = DoPackedSwitch(inst, shadow_frame, inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000662 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200663 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000664 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200665 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700666 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200667 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200668 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200669 }
670 ADVANCE(offset);
671 }
672 HANDLE_INSTRUCTION_END();
673
674 HANDLE_INSTRUCTION_START(SPARSE_SWITCH) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200675 int32_t offset = DoSparseSwitch(inst, shadow_frame, inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000676 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200677 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000678 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200679 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700680 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200681 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200682 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200683 }
684 ADVANCE(offset);
685 }
686 HANDLE_INSTRUCTION_END();
687
Ian Rogers647b1a82014-10-10 11:02:11 -0700688#if defined(__clang__)
689#pragma clang diagnostic push
690#pragma clang diagnostic ignored "-Wfloat-equal"
691#endif
692
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200693 HANDLE_INSTRUCTION_START(CMPL_FLOAT) {
694 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
695 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
696 int32_t result;
697 if (val1 > val2) {
698 result = 1;
699 } else if (val1 == val2) {
700 result = 0;
701 } else {
702 result = -1;
703 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200704 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200705 ADVANCE(2);
706 }
707 HANDLE_INSTRUCTION_END();
708
709 HANDLE_INSTRUCTION_START(CMPG_FLOAT) {
710 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
711 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
712 int32_t result;
713 if (val1 < val2) {
714 result = -1;
715 } else if (val1 == val2) {
716 result = 0;
717 } else {
718 result = 1;
719 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200720 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200721 ADVANCE(2);
722 }
723 HANDLE_INSTRUCTION_END();
724
725 HANDLE_INSTRUCTION_START(CMPL_DOUBLE) {
726 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
727 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
728 int32_t result;
729 if (val1 > val2) {
730 result = 1;
731 } else if (val1 == val2) {
732 result = 0;
733 } else {
734 result = -1;
735 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200736 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200737 ADVANCE(2);
738 }
739 HANDLE_INSTRUCTION_END();
740
741 HANDLE_INSTRUCTION_START(CMPG_DOUBLE) {
742 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
743 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
744 int32_t result;
745 if (val1 < val2) {
746 result = -1;
747 } else if (val1 == val2) {
748 result = 0;
749 } else {
750 result = 1;
751 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200752 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200753 ADVANCE(2);
754 }
755 HANDLE_INSTRUCTION_END();
756
Ian Rogers647b1a82014-10-10 11:02:11 -0700757#if defined(__clang__)
758#pragma clang diagnostic pop
759#endif
760
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200761 HANDLE_INSTRUCTION_START(CMP_LONG) {
762 int64_t val1 = shadow_frame.GetVRegLong(inst->VRegB_23x());
763 int64_t val2 = shadow_frame.GetVRegLong(inst->VRegC_23x());
764 int32_t result;
765 if (val1 > val2) {
766 result = 1;
767 } else if (val1 == val2) {
768 result = 0;
769 } else {
770 result = -1;
771 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200772 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200773 ADVANCE(2);
774 }
775 HANDLE_INSTRUCTION_END();
776
777 HANDLE_INSTRUCTION_START(IF_EQ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200778 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) == shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200779 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000780 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200781 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000782 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200783 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700784 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200785 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200786 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200787 }
788 ADVANCE(offset);
789 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800790 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200791 ADVANCE(2);
792 }
793 }
794 HANDLE_INSTRUCTION_END();
795
796 HANDLE_INSTRUCTION_START(IF_NE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700797 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) !=
798 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200799 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000800 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200801 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000802 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200803 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700804 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200805 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200806 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200807 }
808 ADVANCE(offset);
809 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800810 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200811 ADVANCE(2);
812 }
813 }
814 HANDLE_INSTRUCTION_END();
815
816 HANDLE_INSTRUCTION_START(IF_LT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700817 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <
818 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200819 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000820 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200821 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000822 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200823 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700824 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200825 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200826 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200827 }
828 ADVANCE(offset);
829 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800830 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200831 ADVANCE(2);
832 }
833 }
834 HANDLE_INSTRUCTION_END();
835
836 HANDLE_INSTRUCTION_START(IF_GE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700837 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >=
838 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200839 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000840 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200841 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000842 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200843 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700844 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200845 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200846 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200847 }
848 ADVANCE(offset);
849 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800850 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200851 ADVANCE(2);
852 }
853 }
854 HANDLE_INSTRUCTION_END();
855
856 HANDLE_INSTRUCTION_START(IF_GT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700857 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >
858 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200859 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000860 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200861 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000862 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200863 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700864 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200865 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200866 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200867 }
868 ADVANCE(offset);
869 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800870 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200871 ADVANCE(2);
872 }
873 }
874 HANDLE_INSTRUCTION_END();
875
876 HANDLE_INSTRUCTION_START(IF_LE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700877 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <=
878 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200879 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000880 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200881 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000882 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200883 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700884 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200885 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200886 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200887 }
888 ADVANCE(offset);
889 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800890 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200891 ADVANCE(2);
892 }
893 }
894 HANDLE_INSTRUCTION_END();
895
896 HANDLE_INSTRUCTION_START(IF_EQZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200897 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) == 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200898 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000899 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200900 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000901 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200902 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700903 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200904 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200905 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200906 }
907 ADVANCE(offset);
908 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800909 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200910 ADVANCE(2);
911 }
912 }
913 HANDLE_INSTRUCTION_END();
914
915 HANDLE_INSTRUCTION_START(IF_NEZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200916 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) != 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200917 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000918 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200919 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000920 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200921 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700922 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200923 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200924 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200925 }
926 ADVANCE(offset);
927 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800928 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200929 ADVANCE(2);
930 }
931 }
932 HANDLE_INSTRUCTION_END();
933
934 HANDLE_INSTRUCTION_START(IF_LTZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200935 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) < 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200936 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000937 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200938 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000939 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200940 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700941 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200942 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200943 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200944 }
945 ADVANCE(offset);
946 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800947 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200948 ADVANCE(2);
949 }
950 }
951 HANDLE_INSTRUCTION_END();
952
953 HANDLE_INSTRUCTION_START(IF_GEZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200954 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) >= 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200955 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000956 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200957 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000958 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200959 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700960 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200961 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200962 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200963 }
964 ADVANCE(offset);
965 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800966 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200967 ADVANCE(2);
968 }
969 }
970 HANDLE_INSTRUCTION_END();
971
972 HANDLE_INSTRUCTION_START(IF_GTZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200973 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) > 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200974 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000975 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200976 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000977 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200978 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700979 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200980 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200981 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200982 }
983 ADVANCE(offset);
984 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800985 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200986 ADVANCE(2);
987 }
988 }
989 HANDLE_INSTRUCTION_END();
990
991 HANDLE_INSTRUCTION_START(IF_LEZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200992 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) <= 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200993 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000994 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200995 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000996 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200997 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700998 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200999 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001000 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001001 }
1002 ADVANCE(offset);
1003 } else {
buzbeef1dcacc2016-02-24 14:24:24 -08001004 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001005 ADVANCE(2);
1006 }
1007 }
1008 HANDLE_INSTRUCTION_END();
1009
1010 HANDLE_INSTRUCTION_START(AGET_BOOLEAN) {
1011 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001012 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001013 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001014 HANDLE_PENDING_EXCEPTION();
1015 } else {
1016 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1017 BooleanArray* array = a->AsBooleanArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001018 if (LIKELY(array->CheckIsValidIndex(index))) {
1019 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001020 ADVANCE(2);
1021 } else {
1022 HANDLE_PENDING_EXCEPTION();
1023 }
1024 }
1025 }
1026 HANDLE_INSTRUCTION_END();
1027
1028 HANDLE_INSTRUCTION_START(AGET_BYTE) {
1029 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001030 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001031 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001032 HANDLE_PENDING_EXCEPTION();
1033 } else {
1034 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1035 ByteArray* array = a->AsByteArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001036 if (LIKELY(array->CheckIsValidIndex(index))) {
1037 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001038 ADVANCE(2);
1039 } else {
1040 HANDLE_PENDING_EXCEPTION();
1041 }
1042 }
1043 }
1044 HANDLE_INSTRUCTION_END();
1045
1046 HANDLE_INSTRUCTION_START(AGET_CHAR) {
1047 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001048 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001049 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001050 HANDLE_PENDING_EXCEPTION();
1051 } else {
1052 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1053 CharArray* array = a->AsCharArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001054 if (LIKELY(array->CheckIsValidIndex(index))) {
1055 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001056 ADVANCE(2);
1057 } else {
1058 HANDLE_PENDING_EXCEPTION();
1059 }
1060 }
1061 }
1062 HANDLE_INSTRUCTION_END();
1063
1064 HANDLE_INSTRUCTION_START(AGET_SHORT) {
1065 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001066 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001067 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001068 HANDLE_PENDING_EXCEPTION();
1069 } else {
1070 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1071 ShortArray* array = a->AsShortArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001072 if (LIKELY(array->CheckIsValidIndex(index))) {
1073 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001074 ADVANCE(2);
1075 } else {
1076 HANDLE_PENDING_EXCEPTION();
1077 }
1078 }
1079 }
1080 HANDLE_INSTRUCTION_END();
1081
1082 HANDLE_INSTRUCTION_START(AGET) {
1083 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001084 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001085 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001086 HANDLE_PENDING_EXCEPTION();
1087 } else {
1088 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001089 DCHECK(a->IsIntArray() || a->IsFloatArray()) << PrettyTypeOf(a);
1090 auto* array = down_cast<IntArray*>(a);
Sebastien Hertzabff6432014-01-27 18:01:39 +01001091 if (LIKELY(array->CheckIsValidIndex(index))) {
1092 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001093 ADVANCE(2);
1094 } else {
1095 HANDLE_PENDING_EXCEPTION();
1096 }
1097 }
1098 }
1099 HANDLE_INSTRUCTION_END();
1100
1101 HANDLE_INSTRUCTION_START(AGET_WIDE) {
1102 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001103 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001104 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001105 HANDLE_PENDING_EXCEPTION();
1106 } else {
1107 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001108 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << PrettyTypeOf(a);
1109 auto* array = down_cast<LongArray*>(a);
Sebastien Hertzabff6432014-01-27 18:01:39 +01001110 if (LIKELY(array->CheckIsValidIndex(index))) {
1111 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001112 ADVANCE(2);
1113 } else {
1114 HANDLE_PENDING_EXCEPTION();
1115 }
1116 }
1117 }
1118 HANDLE_INSTRUCTION_END();
1119
1120 HANDLE_INSTRUCTION_START(AGET_OBJECT) {
1121 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001122 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001123 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001124 HANDLE_PENDING_EXCEPTION();
1125 } else {
1126 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1127 ObjectArray<Object>* array = a->AsObjectArray<Object>();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001128 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001129 shadow_frame.SetVRegReference(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001130 ADVANCE(2);
1131 } else {
1132 HANDLE_PENDING_EXCEPTION();
1133 }
1134 }
1135 }
1136 HANDLE_INSTRUCTION_END();
1137
1138 HANDLE_INSTRUCTION_START(APUT_BOOLEAN) {
1139 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001140 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001141 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001142 HANDLE_PENDING_EXCEPTION();
1143 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001144 uint8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001145 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1146 BooleanArray* array = a->AsBooleanArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001147 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001148 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001149 ADVANCE(2);
1150 } else {
1151 HANDLE_PENDING_EXCEPTION();
1152 }
1153 }
1154 }
1155 HANDLE_INSTRUCTION_END();
1156
1157 HANDLE_INSTRUCTION_START(APUT_BYTE) {
1158 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001159 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001160 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001161 HANDLE_PENDING_EXCEPTION();
1162 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001163 int8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001164 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1165 ByteArray* array = a->AsByteArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001166 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001167 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001168 ADVANCE(2);
1169 } else {
1170 HANDLE_PENDING_EXCEPTION();
1171 }
1172 }
1173 }
1174 HANDLE_INSTRUCTION_END();
1175
1176 HANDLE_INSTRUCTION_START(APUT_CHAR) {
1177 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001178 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001179 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001180 HANDLE_PENDING_EXCEPTION();
1181 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001182 uint16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001183 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1184 CharArray* array = a->AsCharArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001185 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001186 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001187 ADVANCE(2);
1188 } else {
1189 HANDLE_PENDING_EXCEPTION();
1190 }
1191 }
1192 }
1193 HANDLE_INSTRUCTION_END();
1194
1195 HANDLE_INSTRUCTION_START(APUT_SHORT) {
1196 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001197 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001198 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001199 HANDLE_PENDING_EXCEPTION();
1200 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001201 int16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001202 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1203 ShortArray* array = a->AsShortArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001204 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001205 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001206 ADVANCE(2);
1207 } else {
1208 HANDLE_PENDING_EXCEPTION();
1209 }
1210 }
1211 }
1212 HANDLE_INSTRUCTION_END();
1213
1214 HANDLE_INSTRUCTION_START(APUT) {
1215 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001216 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001217 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001218 HANDLE_PENDING_EXCEPTION();
1219 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001220 int32_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001221 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001222 DCHECK(a->IsIntArray() || a->IsFloatArray()) << PrettyTypeOf(a);
1223 auto* array = down_cast<IntArray*>(a);
Sebastien Hertzabff6432014-01-27 18:01:39 +01001224 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001225 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001226 ADVANCE(2);
1227 } else {
1228 HANDLE_PENDING_EXCEPTION();
1229 }
1230 }
1231 }
1232 HANDLE_INSTRUCTION_END();
1233
1234 HANDLE_INSTRUCTION_START(APUT_WIDE) {
1235 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001236 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001237 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001238 HANDLE_PENDING_EXCEPTION();
1239 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001240 int64_t val = shadow_frame.GetVRegLong(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001241 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001242 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << PrettyTypeOf(a);
1243 auto* array = down_cast<LongArray*>(a);
Sebastien Hertzabff6432014-01-27 18:01:39 +01001244 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001245 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001246 ADVANCE(2);
1247 } else {
1248 HANDLE_PENDING_EXCEPTION();
1249 }
1250 }
1251 }
1252 HANDLE_INSTRUCTION_END();
1253
1254 HANDLE_INSTRUCTION_START(APUT_OBJECT) {
1255 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001256 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001257 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001258 HANDLE_PENDING_EXCEPTION();
1259 } else {
1260 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001261 Object* val = shadow_frame.GetVRegReference(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001262 ObjectArray<Object>* array = a->AsObjectArray<Object>();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001263 if (LIKELY(array->CheckIsValidIndex(index) && array->CheckAssignable(val))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001264 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001265 ADVANCE(2);
1266 } else {
1267 HANDLE_PENDING_EXCEPTION();
1268 }
1269 }
1270 }
1271 HANDLE_INSTRUCTION_END();
1272
1273 HANDLE_INSTRUCTION_START(IGET_BOOLEAN) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001274 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimBoolean, do_access_check>(
1275 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001276 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1277 }
1278 HANDLE_INSTRUCTION_END();
1279
1280 HANDLE_INSTRUCTION_START(IGET_BYTE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001281 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimByte, do_access_check>(
1282 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001283 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1284 }
1285 HANDLE_INSTRUCTION_END();
1286
1287 HANDLE_INSTRUCTION_START(IGET_CHAR) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001288 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimChar, do_access_check>(
1289 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001290 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1291 }
1292 HANDLE_INSTRUCTION_END();
1293
1294 HANDLE_INSTRUCTION_START(IGET_SHORT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001295 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimShort, do_access_check>(
1296 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001297 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1298 }
1299 HANDLE_INSTRUCTION_END();
1300
1301 HANDLE_INSTRUCTION_START(IGET) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001302 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimInt, do_access_check>(
1303 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001304 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1305 }
1306 HANDLE_INSTRUCTION_END();
1307
1308 HANDLE_INSTRUCTION_START(IGET_WIDE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001309 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimLong, do_access_check>(
1310 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001311 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1312 }
1313 HANDLE_INSTRUCTION_END();
1314
1315 HANDLE_INSTRUCTION_START(IGET_OBJECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001316 bool success = DoFieldGet<InstanceObjectRead, Primitive::kPrimNot, do_access_check>(
1317 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001318 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1319 }
1320 HANDLE_INSTRUCTION_END();
1321
1322 HANDLE_INSTRUCTION_START(IGET_QUICK) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001323 bool success = DoIGetQuick<Primitive::kPrimInt>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001324 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1325 }
1326 HANDLE_INSTRUCTION_END();
1327
Mathieu Chartierffc605c2014-12-10 10:35:44 -08001328 HANDLE_INSTRUCTION_START(IGET_BOOLEAN_QUICK) {
1329 bool success = DoIGetQuick<Primitive::kPrimBoolean>(shadow_frame, inst, inst_data);
1330 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1331 }
1332 HANDLE_INSTRUCTION_END();
1333
1334 HANDLE_INSTRUCTION_START(IGET_BYTE_QUICK) {
1335 bool success = DoIGetQuick<Primitive::kPrimByte>(shadow_frame, inst, inst_data);
1336 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1337 }
1338 HANDLE_INSTRUCTION_END();
1339
1340 HANDLE_INSTRUCTION_START(IGET_CHAR_QUICK) {
1341 bool success = DoIGetQuick<Primitive::kPrimChar>(shadow_frame, inst, inst_data);
1342 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1343 }
1344 HANDLE_INSTRUCTION_END();
1345
1346 HANDLE_INSTRUCTION_START(IGET_SHORT_QUICK) {
1347 bool success = DoIGetQuick<Primitive::kPrimShort>(shadow_frame, inst, inst_data);
1348 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1349 }
1350 HANDLE_INSTRUCTION_END();
1351
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001352 HANDLE_INSTRUCTION_START(IGET_WIDE_QUICK) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001353 bool success = DoIGetQuick<Primitive::kPrimLong>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001354 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1355 }
1356 HANDLE_INSTRUCTION_END();
1357
1358 HANDLE_INSTRUCTION_START(IGET_OBJECT_QUICK) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001359 bool success = DoIGetQuick<Primitive::kPrimNot>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001360 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1361 }
1362 HANDLE_INSTRUCTION_END();
1363
1364 HANDLE_INSTRUCTION_START(SGET_BOOLEAN) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001365 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimBoolean, do_access_check>(
1366 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001367 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1368 }
1369 HANDLE_INSTRUCTION_END();
1370
1371 HANDLE_INSTRUCTION_START(SGET_BYTE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001372 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimByte, do_access_check>(
1373 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001374 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1375 }
1376 HANDLE_INSTRUCTION_END();
1377
1378 HANDLE_INSTRUCTION_START(SGET_CHAR) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001379 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimChar, do_access_check>(
1380 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001381 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1382 }
1383 HANDLE_INSTRUCTION_END();
1384
1385 HANDLE_INSTRUCTION_START(SGET_SHORT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001386 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimShort, do_access_check>(
1387 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001388 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1389 }
1390 HANDLE_INSTRUCTION_END();
1391
1392 HANDLE_INSTRUCTION_START(SGET) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001393 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimInt, do_access_check>(
1394 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001395 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1396 }
1397 HANDLE_INSTRUCTION_END();
1398
1399 HANDLE_INSTRUCTION_START(SGET_WIDE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001400 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimLong, do_access_check>(
1401 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001402 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1403 }
1404 HANDLE_INSTRUCTION_END();
1405
1406 HANDLE_INSTRUCTION_START(SGET_OBJECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001407 bool success = DoFieldGet<StaticObjectRead, Primitive::kPrimNot, do_access_check>(
1408 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001409 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1410 }
1411 HANDLE_INSTRUCTION_END();
1412
1413 HANDLE_INSTRUCTION_START(IPUT_BOOLEAN) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001414 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1415 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001416 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1417 }
1418 HANDLE_INSTRUCTION_END();
1419
1420 HANDLE_INSTRUCTION_START(IPUT_BYTE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001421 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimByte, do_access_check,
1422 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001423 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1424 }
1425 HANDLE_INSTRUCTION_END();
1426
1427 HANDLE_INSTRUCTION_START(IPUT_CHAR) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001428 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimChar, do_access_check,
1429 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001430 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1431 }
1432 HANDLE_INSTRUCTION_END();
1433
1434 HANDLE_INSTRUCTION_START(IPUT_SHORT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001435 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimShort, do_access_check,
1436 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001437 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1438 }
1439 HANDLE_INSTRUCTION_END();
1440
1441 HANDLE_INSTRUCTION_START(IPUT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001442 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimInt, do_access_check,
1443 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001444 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1445 }
1446 HANDLE_INSTRUCTION_END();
1447
1448 HANDLE_INSTRUCTION_START(IPUT_WIDE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001449 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimLong, do_access_check,
1450 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001451 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1452 }
1453 HANDLE_INSTRUCTION_END();
1454
1455 HANDLE_INSTRUCTION_START(IPUT_OBJECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001456 bool success = DoFieldPut<InstanceObjectWrite, Primitive::kPrimNot, do_access_check,
1457 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001458 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1459 }
1460 HANDLE_INSTRUCTION_END();
1461
1462 HANDLE_INSTRUCTION_START(IPUT_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001463 bool success = DoIPutQuick<Primitive::kPrimInt, transaction_active>(
1464 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001465 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1466 }
1467 HANDLE_INSTRUCTION_END();
1468
Fred Shih37f05ef2014-07-16 18:38:08 -07001469 HANDLE_INSTRUCTION_START(IPUT_BOOLEAN_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001470 bool success = DoIPutQuick<Primitive::kPrimBoolean, transaction_active>(
1471 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001472 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1473 }
1474 HANDLE_INSTRUCTION_END();
1475
1476 HANDLE_INSTRUCTION_START(IPUT_BYTE_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001477 bool success = DoIPutQuick<Primitive::kPrimByte, transaction_active>(
1478 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001479 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1480 }
1481 HANDLE_INSTRUCTION_END();
1482
1483 HANDLE_INSTRUCTION_START(IPUT_CHAR_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001484 bool success = DoIPutQuick<Primitive::kPrimChar, transaction_active>(
1485 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001486 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1487 }
1488 HANDLE_INSTRUCTION_END();
1489
1490 HANDLE_INSTRUCTION_START(IPUT_SHORT_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001491 bool success = DoIPutQuick<Primitive::kPrimShort, transaction_active>(
1492 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001493 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1494 }
1495 HANDLE_INSTRUCTION_END();
1496
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001497 HANDLE_INSTRUCTION_START(IPUT_WIDE_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001498 bool success = DoIPutQuick<Primitive::kPrimLong, transaction_active>(
1499 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001500 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1501 }
1502 HANDLE_INSTRUCTION_END();
1503
1504 HANDLE_INSTRUCTION_START(IPUT_OBJECT_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001505 bool success = DoIPutQuick<Primitive::kPrimNot, transaction_active>(
1506 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001507 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1508 }
1509 HANDLE_INSTRUCTION_END();
1510
1511 HANDLE_INSTRUCTION_START(SPUT_BOOLEAN) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001512 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1513 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001514 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1515 }
1516 HANDLE_INSTRUCTION_END();
1517
1518 HANDLE_INSTRUCTION_START(SPUT_BYTE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001519 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimByte, do_access_check,
1520 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001521 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1522 }
1523 HANDLE_INSTRUCTION_END();
1524
1525 HANDLE_INSTRUCTION_START(SPUT_CHAR) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001526 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimChar, do_access_check,
1527 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001528 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1529 }
1530 HANDLE_INSTRUCTION_END();
1531
1532 HANDLE_INSTRUCTION_START(SPUT_SHORT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001533 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimShort, do_access_check,
1534 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001535 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1536 }
1537 HANDLE_INSTRUCTION_END();
1538
1539 HANDLE_INSTRUCTION_START(SPUT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001540 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimInt, do_access_check,
1541 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001542 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1543 }
1544 HANDLE_INSTRUCTION_END();
1545
1546 HANDLE_INSTRUCTION_START(SPUT_WIDE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001547 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimLong, do_access_check,
1548 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001549 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1550 }
1551 HANDLE_INSTRUCTION_END();
1552
1553 HANDLE_INSTRUCTION_START(SPUT_OBJECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001554 bool success = DoFieldPut<StaticObjectWrite, Primitive::kPrimNot, do_access_check,
1555 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001556 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1557 }
1558 HANDLE_INSTRUCTION_END();
1559
1560 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001561 bool success = DoInvoke<kVirtual, false, do_access_check>(
1562 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001563 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001564 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1565 }
1566 HANDLE_INSTRUCTION_END();
1567
1568 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001569 bool success = DoInvoke<kVirtual, true, do_access_check>(
1570 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001571 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001572 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1573 }
1574 HANDLE_INSTRUCTION_END();
1575
1576 HANDLE_INSTRUCTION_START(INVOKE_SUPER) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001577 bool success = DoInvoke<kSuper, false, do_access_check>(
1578 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001579 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001580 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1581 }
1582 HANDLE_INSTRUCTION_END();
1583
1584 HANDLE_INSTRUCTION_START(INVOKE_SUPER_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001585 bool success = DoInvoke<kSuper, true, do_access_check>(
1586 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001587 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001588 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1589 }
1590 HANDLE_INSTRUCTION_END();
1591
1592 HANDLE_INSTRUCTION_START(INVOKE_DIRECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001593 bool success = DoInvoke<kDirect, false, do_access_check>(
1594 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001595 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001596 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1597 }
1598 HANDLE_INSTRUCTION_END();
1599
1600 HANDLE_INSTRUCTION_START(INVOKE_DIRECT_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001601 bool success = DoInvoke<kDirect, true, do_access_check>(
1602 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001603 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001604 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1605 }
1606 HANDLE_INSTRUCTION_END();
1607
1608 HANDLE_INSTRUCTION_START(INVOKE_INTERFACE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001609 bool success = DoInvoke<kInterface, false, do_access_check>(
1610 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001611 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001612 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1613 }
1614 HANDLE_INSTRUCTION_END();
1615
1616 HANDLE_INSTRUCTION_START(INVOKE_INTERFACE_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001617 bool success = DoInvoke<kInterface, true, do_access_check>(
1618 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001619 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001620 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1621 }
1622 HANDLE_INSTRUCTION_END();
1623
1624 HANDLE_INSTRUCTION_START(INVOKE_STATIC) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001625 bool success = DoInvoke<kStatic, false, do_access_check>(
1626 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001627 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001628 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1629 }
1630 HANDLE_INSTRUCTION_END();
1631
1632 HANDLE_INSTRUCTION_START(INVOKE_STATIC_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001633 bool success = DoInvoke<kStatic, true, do_access_check>(
1634 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001635 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001636 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1637 }
1638 HANDLE_INSTRUCTION_END();
1639
1640 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001641 bool success = DoInvokeVirtualQuick<false>(
1642 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001643 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001644 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1645 }
1646 HANDLE_INSTRUCTION_END();
1647
1648 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_RANGE_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001649 bool success = DoInvokeVirtualQuick<true>(
1650 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001651 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001652 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1653 }
1654 HANDLE_INSTRUCTION_END();
1655
1656 HANDLE_INSTRUCTION_START(NEG_INT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001657 shadow_frame.SetVReg(
1658 inst->VRegA_12x(inst_data), -shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001659 ADVANCE(1);
1660 HANDLE_INSTRUCTION_END();
1661
1662 HANDLE_INSTRUCTION_START(NOT_INT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001663 shadow_frame.SetVReg(
1664 inst->VRegA_12x(inst_data), ~shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001665 ADVANCE(1);
1666 HANDLE_INSTRUCTION_END();
1667
1668 HANDLE_INSTRUCTION_START(NEG_LONG)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001669 shadow_frame.SetVRegLong(
1670 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001671 ADVANCE(1);
1672 HANDLE_INSTRUCTION_END();
1673
1674 HANDLE_INSTRUCTION_START(NOT_LONG)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001675 shadow_frame.SetVRegLong(
1676 inst->VRegA_12x(inst_data), ~shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001677 ADVANCE(1);
1678 HANDLE_INSTRUCTION_END();
1679
1680 HANDLE_INSTRUCTION_START(NEG_FLOAT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001681 shadow_frame.SetVRegFloat(
1682 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001683 ADVANCE(1);
1684 HANDLE_INSTRUCTION_END();
1685
1686 HANDLE_INSTRUCTION_START(NEG_DOUBLE)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001687 shadow_frame.SetVRegDouble(
1688 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001689 ADVANCE(1);
1690 HANDLE_INSTRUCTION_END();
1691
1692 HANDLE_INSTRUCTION_START(INT_TO_LONG)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001693 shadow_frame.SetVRegLong(
1694 inst->VRegA_12x(inst_data), shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001695 ADVANCE(1);
1696 HANDLE_INSTRUCTION_END();
1697
1698 HANDLE_INSTRUCTION_START(INT_TO_FLOAT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001699 shadow_frame.SetVRegFloat(
1700 inst->VRegA_12x(inst_data), shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001701 ADVANCE(1);
1702 HANDLE_INSTRUCTION_END();
1703
1704 HANDLE_INSTRUCTION_START(INT_TO_DOUBLE)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001705 shadow_frame.SetVRegDouble(
1706 inst->VRegA_12x(inst_data), shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001707 ADVANCE(1);
1708 HANDLE_INSTRUCTION_END();
1709
1710 HANDLE_INSTRUCTION_START(LONG_TO_INT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001711 shadow_frame.SetVReg(
1712 inst->VRegA_12x(inst_data), shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001713 ADVANCE(1);
1714 HANDLE_INSTRUCTION_END();
1715
1716 HANDLE_INSTRUCTION_START(LONG_TO_FLOAT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001717 shadow_frame.SetVRegFloat(
1718 inst->VRegA_12x(inst_data), shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001719 ADVANCE(1);
1720 HANDLE_INSTRUCTION_END();
1721
1722 HANDLE_INSTRUCTION_START(LONG_TO_DOUBLE)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001723 shadow_frame.SetVRegDouble(
1724 inst->VRegA_12x(inst_data), shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001725 ADVANCE(1);
1726 HANDLE_INSTRUCTION_END();
1727
1728 HANDLE_INSTRUCTION_START(FLOAT_TO_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001729 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001730 int32_t result = art_float_to_integral<int32_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001731 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001732 ADVANCE(1);
1733 }
1734 HANDLE_INSTRUCTION_END();
1735
1736 HANDLE_INSTRUCTION_START(FLOAT_TO_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001737 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001738 int64_t result = art_float_to_integral<int64_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001739 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001740 ADVANCE(1);
1741 }
1742 HANDLE_INSTRUCTION_END();
1743
1744 HANDLE_INSTRUCTION_START(FLOAT_TO_DOUBLE)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001745 shadow_frame.SetVRegDouble(
1746 inst->VRegA_12x(inst_data), shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001747 ADVANCE(1);
1748 HANDLE_INSTRUCTION_END();
1749
1750 HANDLE_INSTRUCTION_START(DOUBLE_TO_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001751 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001752 int32_t result = art_float_to_integral<int32_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001753 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001754 ADVANCE(1);
1755 }
1756 HANDLE_INSTRUCTION_END();
1757
1758 HANDLE_INSTRUCTION_START(DOUBLE_TO_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001759 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001760 int64_t result = art_float_to_integral<int64_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001761 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001762 ADVANCE(1);
1763 }
1764 HANDLE_INSTRUCTION_END();
1765
1766 HANDLE_INSTRUCTION_START(DOUBLE_TO_FLOAT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001767 shadow_frame.SetVRegFloat(
1768 inst->VRegA_12x(inst_data), shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001769 ADVANCE(1);
1770 HANDLE_INSTRUCTION_END();
1771
1772 HANDLE_INSTRUCTION_START(INT_TO_BYTE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001773 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1774 static_cast<int8_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001775 ADVANCE(1);
1776 HANDLE_INSTRUCTION_END();
1777
1778 HANDLE_INSTRUCTION_START(INT_TO_CHAR)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001779 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1780 static_cast<uint16_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001781 ADVANCE(1);
1782 HANDLE_INSTRUCTION_END();
1783
1784 HANDLE_INSTRUCTION_START(INT_TO_SHORT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001785 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1786 static_cast<int16_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001787 ADVANCE(1);
1788 HANDLE_INSTRUCTION_END();
1789
1790 HANDLE_INSTRUCTION_START(ADD_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001791 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001792 SafeAdd(shadow_frame.GetVReg(inst->VRegB_23x()),
1793 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001794 ADVANCE(2);
1795 HANDLE_INSTRUCTION_END();
1796
1797 HANDLE_INSTRUCTION_START(SUB_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001798 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001799 SafeSub(shadow_frame.GetVReg(inst->VRegB_23x()),
1800 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001801 ADVANCE(2);
1802 HANDLE_INSTRUCTION_END();
1803
1804 HANDLE_INSTRUCTION_START(MUL_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001805 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001806 SafeMul(shadow_frame.GetVReg(inst->VRegB_23x()),
1807 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001808 ADVANCE(2);
1809 HANDLE_INSTRUCTION_END();
1810
1811 HANDLE_INSTRUCTION_START(DIV_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001812 bool success = DoIntDivide(shadow_frame, inst->VRegA_23x(inst_data),
1813 shadow_frame.GetVReg(inst->VRegB_23x()),
1814 shadow_frame.GetVReg(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001815 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1816 }
1817 HANDLE_INSTRUCTION_END();
1818
1819 HANDLE_INSTRUCTION_START(REM_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001820 bool success = DoIntRemainder(shadow_frame, inst->VRegA_23x(inst_data),
1821 shadow_frame.GetVReg(inst->VRegB_23x()),
1822 shadow_frame.GetVReg(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001823 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1824 }
1825 HANDLE_INSTRUCTION_END();
1826
1827 HANDLE_INSTRUCTION_START(SHL_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001828 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001829 shadow_frame.GetVReg(inst->VRegB_23x()) <<
1830 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1831 ADVANCE(2);
1832 HANDLE_INSTRUCTION_END();
1833
1834 HANDLE_INSTRUCTION_START(SHR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001835 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001836 shadow_frame.GetVReg(inst->VRegB_23x()) >>
1837 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1838 ADVANCE(2);
1839 HANDLE_INSTRUCTION_END();
1840
1841 HANDLE_INSTRUCTION_START(USHR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001842 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001843 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_23x())) >>
1844 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1845 ADVANCE(2);
1846 HANDLE_INSTRUCTION_END();
1847
1848 HANDLE_INSTRUCTION_START(AND_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001849 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001850 shadow_frame.GetVReg(inst->VRegB_23x()) &
1851 shadow_frame.GetVReg(inst->VRegC_23x()));
1852 ADVANCE(2);
1853 HANDLE_INSTRUCTION_END();
1854
1855 HANDLE_INSTRUCTION_START(OR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001856 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001857 shadow_frame.GetVReg(inst->VRegB_23x()) |
1858 shadow_frame.GetVReg(inst->VRegC_23x()));
1859 ADVANCE(2);
1860 HANDLE_INSTRUCTION_END();
1861
1862 HANDLE_INSTRUCTION_START(XOR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001863 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001864 shadow_frame.GetVReg(inst->VRegB_23x()) ^
1865 shadow_frame.GetVReg(inst->VRegC_23x()));
1866 ADVANCE(2);
1867 HANDLE_INSTRUCTION_END();
1868
1869 HANDLE_INSTRUCTION_START(ADD_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001870 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001871 SafeAdd(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1872 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001873 ADVANCE(2);
1874 HANDLE_INSTRUCTION_END();
1875
1876 HANDLE_INSTRUCTION_START(SUB_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001877 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001878 SafeSub(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1879 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001880 ADVANCE(2);
1881 HANDLE_INSTRUCTION_END();
1882
1883 HANDLE_INSTRUCTION_START(MUL_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001884 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001885 SafeMul(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1886 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001887 ADVANCE(2);
1888 HANDLE_INSTRUCTION_END();
1889
1890 HANDLE_INSTRUCTION_START(DIV_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001891 bool success = DoLongDivide(shadow_frame, inst->VRegA_23x(inst_data),
1892 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1893 shadow_frame.GetVRegLong(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001894 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1895 }
1896 HANDLE_INSTRUCTION_END();
1897
1898 HANDLE_INSTRUCTION_START(REM_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001899 bool success = DoLongRemainder(shadow_frame, inst->VRegA_23x(inst_data),
1900 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1901 shadow_frame.GetVRegLong(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001902 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1903 }
1904 HANDLE_INSTRUCTION_END();
1905
1906 HANDLE_INSTRUCTION_START(AND_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001907 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001908 shadow_frame.GetVRegLong(inst->VRegB_23x()) &
1909 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1910 ADVANCE(2);
1911 HANDLE_INSTRUCTION_END();
1912
1913 HANDLE_INSTRUCTION_START(OR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001914 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001915 shadow_frame.GetVRegLong(inst->VRegB_23x()) |
1916 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1917 ADVANCE(2);
1918 HANDLE_INSTRUCTION_END();
1919
1920 HANDLE_INSTRUCTION_START(XOR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001921 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001922 shadow_frame.GetVRegLong(inst->VRegB_23x()) ^
1923 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1924 ADVANCE(2);
1925 HANDLE_INSTRUCTION_END();
1926
1927 HANDLE_INSTRUCTION_START(SHL_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001928 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001929 shadow_frame.GetVRegLong(inst->VRegB_23x()) <<
1930 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1931 ADVANCE(2);
1932 HANDLE_INSTRUCTION_END();
1933
1934 HANDLE_INSTRUCTION_START(SHR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001935 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001936 shadow_frame.GetVRegLong(inst->VRegB_23x()) >>
1937 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1938 ADVANCE(2);
1939 HANDLE_INSTRUCTION_END();
1940
1941 HANDLE_INSTRUCTION_START(USHR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001942 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001943 static_cast<uint64_t>(shadow_frame.GetVRegLong(inst->VRegB_23x())) >>
1944 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1945 ADVANCE(2);
1946 HANDLE_INSTRUCTION_END();
1947
1948 HANDLE_INSTRUCTION_START(ADD_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001949 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001950 shadow_frame.GetVRegFloat(inst->VRegB_23x()) +
1951 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1952 ADVANCE(2);
1953 HANDLE_INSTRUCTION_END();
1954
1955 HANDLE_INSTRUCTION_START(SUB_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001956 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001957 shadow_frame.GetVRegFloat(inst->VRegB_23x()) -
1958 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1959 ADVANCE(2);
1960 HANDLE_INSTRUCTION_END();
1961
1962 HANDLE_INSTRUCTION_START(MUL_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001963 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001964 shadow_frame.GetVRegFloat(inst->VRegB_23x()) *
1965 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1966 ADVANCE(2);
1967 HANDLE_INSTRUCTION_END();
1968
1969 HANDLE_INSTRUCTION_START(DIV_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001970 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001971 shadow_frame.GetVRegFloat(inst->VRegB_23x()) /
1972 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1973 ADVANCE(2);
1974 HANDLE_INSTRUCTION_END();
1975
1976 HANDLE_INSTRUCTION_START(REM_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001977 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001978 fmodf(shadow_frame.GetVRegFloat(inst->VRegB_23x()),
1979 shadow_frame.GetVRegFloat(inst->VRegC_23x())));
1980 ADVANCE(2);
1981 HANDLE_INSTRUCTION_END();
1982
1983 HANDLE_INSTRUCTION_START(ADD_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001984 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001985 shadow_frame.GetVRegDouble(inst->VRegB_23x()) +
1986 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1987 ADVANCE(2);
1988 HANDLE_INSTRUCTION_END();
1989
1990 HANDLE_INSTRUCTION_START(SUB_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001991 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001992 shadow_frame.GetVRegDouble(inst->VRegB_23x()) -
1993 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1994 ADVANCE(2);
1995 HANDLE_INSTRUCTION_END();
1996
1997 HANDLE_INSTRUCTION_START(MUL_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001998 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001999 shadow_frame.GetVRegDouble(inst->VRegB_23x()) *
2000 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
2001 ADVANCE(2);
2002 HANDLE_INSTRUCTION_END();
2003
2004 HANDLE_INSTRUCTION_START(DIV_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002005 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002006 shadow_frame.GetVRegDouble(inst->VRegB_23x()) /
2007 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
2008 ADVANCE(2);
2009 HANDLE_INSTRUCTION_END();
2010
2011 HANDLE_INSTRUCTION_START(REM_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002012 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002013 fmod(shadow_frame.GetVRegDouble(inst->VRegB_23x()),
2014 shadow_frame.GetVRegDouble(inst->VRegC_23x())));
2015 ADVANCE(2);
2016 HANDLE_INSTRUCTION_END();
2017
2018 HANDLE_INSTRUCTION_START(ADD_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002019 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002020 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002021 SafeAdd(shadow_frame.GetVReg(vregA),
2022 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002023 ADVANCE(1);
2024 }
2025 HANDLE_INSTRUCTION_END();
2026
2027 HANDLE_INSTRUCTION_START(SUB_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002028 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002029 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002030 SafeSub(shadow_frame.GetVReg(vregA),
2031 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002032 ADVANCE(1);
2033 }
2034 HANDLE_INSTRUCTION_END();
2035
2036 HANDLE_INSTRUCTION_START(MUL_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002037 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002038 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002039 SafeMul(shadow_frame.GetVReg(vregA),
2040 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002041 ADVANCE(1);
2042 }
2043 HANDLE_INSTRUCTION_END();
2044
2045 HANDLE_INSTRUCTION_START(DIV_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002046 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002047 bool success = DoIntDivide(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002048 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002049 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2050 }
2051 HANDLE_INSTRUCTION_END();
2052
2053 HANDLE_INSTRUCTION_START(REM_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002054 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002055 bool success = DoIntRemainder(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002056 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002057 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2058 }
2059 HANDLE_INSTRUCTION_END();
2060
2061 HANDLE_INSTRUCTION_START(SHL_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002062 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002063 shadow_frame.SetVReg(vregA,
2064 shadow_frame.GetVReg(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002065 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002066 ADVANCE(1);
2067 }
2068 HANDLE_INSTRUCTION_END();
2069
2070 HANDLE_INSTRUCTION_START(SHR_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002071 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002072 shadow_frame.SetVReg(vregA,
2073 shadow_frame.GetVReg(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002074 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002075 ADVANCE(1);
2076 }
2077 HANDLE_INSTRUCTION_END();
2078
2079 HANDLE_INSTRUCTION_START(USHR_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002080 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002081 shadow_frame.SetVReg(vregA,
2082 static_cast<uint32_t>(shadow_frame.GetVReg(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002083 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002084 ADVANCE(1);
2085 }
2086 HANDLE_INSTRUCTION_END();
2087
2088 HANDLE_INSTRUCTION_START(AND_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002089 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002090 shadow_frame.SetVReg(vregA,
2091 shadow_frame.GetVReg(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002092 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002093 ADVANCE(1);
2094 }
2095 HANDLE_INSTRUCTION_END();
2096
2097 HANDLE_INSTRUCTION_START(OR_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002098 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002099 shadow_frame.SetVReg(vregA,
2100 shadow_frame.GetVReg(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002101 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002102 ADVANCE(1);
2103 }
2104 HANDLE_INSTRUCTION_END();
2105
2106 HANDLE_INSTRUCTION_START(XOR_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002107 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002108 shadow_frame.SetVReg(vregA,
2109 shadow_frame.GetVReg(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002110 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002111 ADVANCE(1);
2112 }
2113 HANDLE_INSTRUCTION_END();
2114
2115 HANDLE_INSTRUCTION_START(ADD_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002116 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002117 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002118 SafeAdd(shadow_frame.GetVRegLong(vregA),
2119 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002120 ADVANCE(1);
2121 }
2122 HANDLE_INSTRUCTION_END();
2123
2124 HANDLE_INSTRUCTION_START(SUB_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002125 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002126 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002127 SafeSub(shadow_frame.GetVRegLong(vregA),
2128 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002129 ADVANCE(1);
2130 }
2131 HANDLE_INSTRUCTION_END();
2132
2133 HANDLE_INSTRUCTION_START(MUL_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002134 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002135 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002136 SafeMul(shadow_frame.GetVRegLong(vregA),
2137 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002138 ADVANCE(1);
2139 }
2140 HANDLE_INSTRUCTION_END();
2141
2142 HANDLE_INSTRUCTION_START(DIV_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002143 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002144 bool success = DoLongDivide(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002145 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002146 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2147 }
2148 HANDLE_INSTRUCTION_END();
2149
2150 HANDLE_INSTRUCTION_START(REM_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002151 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002152 bool success = DoLongRemainder(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002153 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002154 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2155 }
2156 HANDLE_INSTRUCTION_END();
2157
2158 HANDLE_INSTRUCTION_START(AND_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002159 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002160 shadow_frame.SetVRegLong(vregA,
2161 shadow_frame.GetVRegLong(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002162 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002163 ADVANCE(1);
2164 }
2165 HANDLE_INSTRUCTION_END();
2166
2167 HANDLE_INSTRUCTION_START(OR_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002168 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002169 shadow_frame.SetVRegLong(vregA,
2170 shadow_frame.GetVRegLong(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002171 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002172 ADVANCE(1);
2173 }
2174 HANDLE_INSTRUCTION_END();
2175
2176 HANDLE_INSTRUCTION_START(XOR_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002177 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002178 shadow_frame.SetVRegLong(vregA,
2179 shadow_frame.GetVRegLong(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002180 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002181 ADVANCE(1);
2182 }
2183 HANDLE_INSTRUCTION_END();
2184
2185 HANDLE_INSTRUCTION_START(SHL_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002186 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002187 shadow_frame.SetVRegLong(vregA,
2188 shadow_frame.GetVRegLong(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002189 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002190 ADVANCE(1);
2191 }
2192 HANDLE_INSTRUCTION_END();
2193
2194 HANDLE_INSTRUCTION_START(SHR_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002195 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002196 shadow_frame.SetVRegLong(vregA,
2197 shadow_frame.GetVRegLong(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002198 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002199 ADVANCE(1);
2200 }
2201 HANDLE_INSTRUCTION_END();
2202
2203 HANDLE_INSTRUCTION_START(USHR_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002204 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002205 shadow_frame.SetVRegLong(vregA,
2206 static_cast<uint64_t>(shadow_frame.GetVRegLong(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002207 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002208 ADVANCE(1);
2209 }
2210 HANDLE_INSTRUCTION_END();
2211
2212 HANDLE_INSTRUCTION_START(ADD_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002213 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002214 shadow_frame.SetVRegFloat(vregA,
2215 shadow_frame.GetVRegFloat(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002216 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002217 ADVANCE(1);
2218 }
2219 HANDLE_INSTRUCTION_END();
2220
2221 HANDLE_INSTRUCTION_START(SUB_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002222 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002223 shadow_frame.SetVRegFloat(vregA,
2224 shadow_frame.GetVRegFloat(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002225 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002226 ADVANCE(1);
2227 }
2228 HANDLE_INSTRUCTION_END();
2229
2230 HANDLE_INSTRUCTION_START(MUL_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002231 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002232 shadow_frame.SetVRegFloat(vregA,
2233 shadow_frame.GetVRegFloat(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002234 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002235 ADVANCE(1);
2236 }
2237 HANDLE_INSTRUCTION_END();
2238
2239 HANDLE_INSTRUCTION_START(DIV_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002240 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002241 shadow_frame.SetVRegFloat(vregA,
2242 shadow_frame.GetVRegFloat(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002243 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002244 ADVANCE(1);
2245 }
2246 HANDLE_INSTRUCTION_END();
2247
2248 HANDLE_INSTRUCTION_START(REM_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002249 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002250 shadow_frame.SetVRegFloat(vregA,
2251 fmodf(shadow_frame.GetVRegFloat(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002252 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002253 ADVANCE(1);
2254 }
2255 HANDLE_INSTRUCTION_END();
2256
2257 HANDLE_INSTRUCTION_START(ADD_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002258 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002259 shadow_frame.SetVRegDouble(vregA,
2260 shadow_frame.GetVRegDouble(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002261 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002262 ADVANCE(1);
2263 }
2264 HANDLE_INSTRUCTION_END();
2265
2266 HANDLE_INSTRUCTION_START(SUB_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002267 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002268 shadow_frame.SetVRegDouble(vregA,
2269 shadow_frame.GetVRegDouble(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002270 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002271 ADVANCE(1);
2272 }
2273 HANDLE_INSTRUCTION_END();
2274
2275 HANDLE_INSTRUCTION_START(MUL_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002276 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002277 shadow_frame.SetVRegDouble(vregA,
2278 shadow_frame.GetVRegDouble(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002279 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002280 ADVANCE(1);
2281 }
2282 HANDLE_INSTRUCTION_END();
2283
2284 HANDLE_INSTRUCTION_START(DIV_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002285 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002286 shadow_frame.SetVRegDouble(vregA,
2287 shadow_frame.GetVRegDouble(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002288 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002289 ADVANCE(1);
2290 }
2291 HANDLE_INSTRUCTION_END();
2292
2293 HANDLE_INSTRUCTION_START(REM_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002294 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002295 shadow_frame.SetVRegDouble(vregA,
2296 fmod(shadow_frame.GetVRegDouble(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002297 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002298 ADVANCE(1);
2299 }
2300 HANDLE_INSTRUCTION_END();
2301
2302 HANDLE_INSTRUCTION_START(ADD_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002303 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002304 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2305 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002306 ADVANCE(2);
2307 HANDLE_INSTRUCTION_END();
2308
2309 HANDLE_INSTRUCTION_START(RSUB_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002310 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002311 SafeSub(inst->VRegC_22s(),
2312 shadow_frame.GetVReg(inst->VRegB_22s(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002313 ADVANCE(2);
2314 HANDLE_INSTRUCTION_END();
2315
2316 HANDLE_INSTRUCTION_START(MUL_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002317 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002318 SafeMul(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2319 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002320 ADVANCE(2);
2321 HANDLE_INSTRUCTION_END();
2322
2323 HANDLE_INSTRUCTION_START(DIV_INT_LIT16) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002324 bool success = DoIntDivide(
2325 shadow_frame, inst->VRegA_22s(inst_data), shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2326 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002327 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2328 }
2329 HANDLE_INSTRUCTION_END();
2330
2331 HANDLE_INSTRUCTION_START(REM_INT_LIT16) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002332 bool success = DoIntRemainder(
2333 shadow_frame, inst->VRegA_22s(inst_data), shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2334 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002335 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2336 }
2337 HANDLE_INSTRUCTION_END();
2338
2339 HANDLE_INSTRUCTION_START(AND_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002340 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2341 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) &
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002342 inst->VRegC_22s());
2343 ADVANCE(2);
2344 HANDLE_INSTRUCTION_END();
2345
2346 HANDLE_INSTRUCTION_START(OR_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002347 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2348 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) |
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002349 inst->VRegC_22s());
2350 ADVANCE(2);
2351 HANDLE_INSTRUCTION_END();
2352
2353 HANDLE_INSTRUCTION_START(XOR_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002354 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2355 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) ^
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002356 inst->VRegC_22s());
2357 ADVANCE(2);
2358 HANDLE_INSTRUCTION_END();
2359
2360 HANDLE_INSTRUCTION_START(ADD_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002361 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002362 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22b()),
2363 inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002364 ADVANCE(2);
2365 HANDLE_INSTRUCTION_END();
2366
2367 HANDLE_INSTRUCTION_START(RSUB_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002368 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002369 SafeSub(inst->VRegC_22b(),
2370 shadow_frame.GetVReg(inst->VRegB_22b())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002371 ADVANCE(2);
2372 HANDLE_INSTRUCTION_END();
2373
2374 HANDLE_INSTRUCTION_START(MUL_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002375 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002376 SafeMul(shadow_frame.GetVReg(inst->VRegB_22b()),
2377 inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002378 ADVANCE(2);
2379 HANDLE_INSTRUCTION_END();
2380
2381 HANDLE_INSTRUCTION_START(DIV_INT_LIT8) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002382 bool success = DoIntDivide(shadow_frame, inst->VRegA_22b(inst_data),
2383 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002384 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2385 }
2386 HANDLE_INSTRUCTION_END();
2387
2388 HANDLE_INSTRUCTION_START(REM_INT_LIT8) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002389 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22b(inst_data),
2390 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002391 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2392 }
2393 HANDLE_INSTRUCTION_END();
2394
2395 HANDLE_INSTRUCTION_START(AND_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002396 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002397 shadow_frame.GetVReg(inst->VRegB_22b()) &
2398 inst->VRegC_22b());
2399 ADVANCE(2);
2400 HANDLE_INSTRUCTION_END();
2401
2402 HANDLE_INSTRUCTION_START(OR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002403 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002404 shadow_frame.GetVReg(inst->VRegB_22b()) |
2405 inst->VRegC_22b());
2406 ADVANCE(2);
2407 HANDLE_INSTRUCTION_END();
2408
2409 HANDLE_INSTRUCTION_START(XOR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002410 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002411 shadow_frame.GetVReg(inst->VRegB_22b()) ^
2412 inst->VRegC_22b());
2413 ADVANCE(2);
2414 HANDLE_INSTRUCTION_END();
2415
2416 HANDLE_INSTRUCTION_START(SHL_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002417 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002418 shadow_frame.GetVReg(inst->VRegB_22b()) <<
2419 (inst->VRegC_22b() & 0x1f));
2420 ADVANCE(2);
2421 HANDLE_INSTRUCTION_END();
2422
2423 HANDLE_INSTRUCTION_START(SHR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002424 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002425 shadow_frame.GetVReg(inst->VRegB_22b()) >>
2426 (inst->VRegC_22b() & 0x1f));
2427 ADVANCE(2);
2428 HANDLE_INSTRUCTION_END();
2429
2430 HANDLE_INSTRUCTION_START(USHR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002431 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002432 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_22b())) >>
2433 (inst->VRegC_22b() & 0x1f));
2434 ADVANCE(2);
2435 HANDLE_INSTRUCTION_END();
2436
2437 HANDLE_INSTRUCTION_START(UNUSED_3E)
Ian Rogerse94652f2014-12-02 11:13:19 -08002438 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002439 HANDLE_INSTRUCTION_END();
2440
2441 HANDLE_INSTRUCTION_START(UNUSED_3F)
Ian Rogerse94652f2014-12-02 11:13:19 -08002442 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002443 HANDLE_INSTRUCTION_END();
2444
2445 HANDLE_INSTRUCTION_START(UNUSED_40)
Ian Rogerse94652f2014-12-02 11:13:19 -08002446 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002447 HANDLE_INSTRUCTION_END();
2448
2449 HANDLE_INSTRUCTION_START(UNUSED_41)
Ian Rogerse94652f2014-12-02 11:13:19 -08002450 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002451 HANDLE_INSTRUCTION_END();
2452
2453 HANDLE_INSTRUCTION_START(UNUSED_42)
Ian Rogerse94652f2014-12-02 11:13:19 -08002454 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002455 HANDLE_INSTRUCTION_END();
2456
2457 HANDLE_INSTRUCTION_START(UNUSED_43)
Ian Rogerse94652f2014-12-02 11:13:19 -08002458 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002459 HANDLE_INSTRUCTION_END();
2460
2461 HANDLE_INSTRUCTION_START(UNUSED_79)
Ian Rogerse94652f2014-12-02 11:13:19 -08002462 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002463 HANDLE_INSTRUCTION_END();
2464
2465 HANDLE_INSTRUCTION_START(UNUSED_7A)
Ian Rogerse94652f2014-12-02 11:13:19 -08002466 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002467 HANDLE_INSTRUCTION_END();
2468
Narayan Kamath14832ef2016-08-05 11:44:32 +01002469 HANDLE_INSTRUCTION_START(UNUSED_F3)
2470 UnexpectedOpcode(inst, shadow_frame);
2471 HANDLE_INSTRUCTION_END();
2472
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002473 HANDLE_INSTRUCTION_START(UNUSED_F4)
Ian Rogerse94652f2014-12-02 11:13:19 -08002474 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002475 HANDLE_INSTRUCTION_END();
2476
Narayan Kamath14832ef2016-08-05 11:44:32 +01002477 HANDLE_INSTRUCTION_START(UNUSED_F5)
2478 UnexpectedOpcode(inst, shadow_frame);
2479 HANDLE_INSTRUCTION_END();
2480
2481 HANDLE_INSTRUCTION_START(UNUSED_F6)
2482 UnexpectedOpcode(inst, shadow_frame);
2483 HANDLE_INSTRUCTION_END();
2484
2485 HANDLE_INSTRUCTION_START(UNUSED_F7)
2486 UnexpectedOpcode(inst, shadow_frame);
2487 HANDLE_INSTRUCTION_END();
2488
2489 HANDLE_INSTRUCTION_START(UNUSED_F8)
2490 UnexpectedOpcode(inst, shadow_frame);
2491 HANDLE_INSTRUCTION_END();
2492
2493 HANDLE_INSTRUCTION_START(UNUSED_F9)
2494 UnexpectedOpcode(inst, shadow_frame);
2495 HANDLE_INSTRUCTION_END();
2496
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002497 HANDLE_INSTRUCTION_START(UNUSED_FA)
Ian Rogerse94652f2014-12-02 11:13:19 -08002498 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002499 HANDLE_INSTRUCTION_END();
2500
2501 HANDLE_INSTRUCTION_START(UNUSED_FB)
Ian Rogerse94652f2014-12-02 11:13:19 -08002502 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002503 HANDLE_INSTRUCTION_END();
2504
2505 HANDLE_INSTRUCTION_START(UNUSED_FC)
Ian Rogerse94652f2014-12-02 11:13:19 -08002506 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002507 HANDLE_INSTRUCTION_END();
2508
2509 HANDLE_INSTRUCTION_START(UNUSED_FD)
Ian Rogerse94652f2014-12-02 11:13:19 -08002510 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002511 HANDLE_INSTRUCTION_END();
2512
2513 HANDLE_INSTRUCTION_START(UNUSED_FE)
Ian Rogerse94652f2014-12-02 11:13:19 -08002514 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002515 HANDLE_INSTRUCTION_END();
2516
2517 HANDLE_INSTRUCTION_START(UNUSED_FF)
Ian Rogerse94652f2014-12-02 11:13:19 -08002518 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002519 HANDLE_INSTRUCTION_END();
2520
2521 exception_pending_label: {
2522 CHECK(self->IsExceptionPending());
Sebastien Hertz1eda2262013-09-09 16:53:14 +02002523 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -07002524 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +02002525 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +02002526 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002527 uint32_t found_dex_pc = FindNextInstructionFollowingException(self, shadow_frame, dex_pc,
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002528 instrumentation);
2529 if (found_dex_pc == DexFile::kDexNoIndex) {
Andreas Gampe03ec9302015-08-27 17:41:47 -07002530 // Structured locking is to be enforced for abnormal termination, too.
Andreas Gampe56fdd0e2016-04-28 14:56:54 -07002531 DoMonitorCheckOnExit<do_assignability_check>(self, &shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002532 return JValue(); /* Handled in caller. */
2533 } else {
2534 int32_t displacement = static_cast<int32_t>(found_dex_pc) - static_cast<int32_t>(dex_pc);
2535 ADVANCE(displacement);
2536 }
2537 }
2538
Sebastien Hertz8379b222014-02-24 17:38:15 +01002539// Create alternative instruction handlers dedicated to instrumentation.
2540// Return instructions must not call Instrumentation::DexPcMovedEvent since they already call
2541// Instrumentation::MethodExited. This is to avoid posting debugger events twice for this location.
Sebastien Hertze713d932014-05-15 10:48:53 +02002542// Note: we do not use the kReturn instruction flag here (to test the instruction is a return). The
2543// compiler seems to not evaluate "(Instruction::FlagsOf(Instruction::code) & kReturn) != 0" to
2544// a constant condition that would remove the "if" statement so the test is free.
Narayan Kamathbd48b342016-08-01 17:32:37 +01002545#define INSTRUMENTATION_INSTRUCTION_HANDLER(o, code, n, f, i, a, v) \
Sebastien Hertz9d6bf692015-04-10 12:12:33 +02002546 alt_op_##code: { \
Sebastien Hertz9d6bf692015-04-10 12:12:33 +02002547 if (UNLIKELY(instrumentation->HasDexPcListeners())) { \
2548 Object* this_object = shadow_frame.GetThisObject(code_item->ins_size_); \
2549 instrumentation->DexPcMovedEvent(self, this_object, shadow_frame.GetMethod(), dex_pc); \
2550 } \
2551 UPDATE_HANDLER_TABLE(); \
2552 goto *handlersTable[instrumentation::kMainHandlerTable][Instruction::code]; \
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002553 }
2554#include "dex_instruction_list.h"
2555 DEX_INSTRUCTION_LIST(INSTRUMENTATION_INSTRUCTION_HANDLER)
2556#undef DEX_INSTRUCTION_LIST
2557#undef INSTRUMENTATION_INSTRUCTION_HANDLER
2558} // NOLINT(readability/fn_size)
2559
2560// Explicit definitions of ExecuteGotoImpl.
Mathieu Chartier90443472015-07-16 20:32:27 -07002561template SHARED_REQUIRES(Locks::mutator_lock_) HOT_ATTR
Ian Rogerse94652f2014-12-02 11:13:19 -08002562JValue ExecuteGotoImpl<true, false>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002563 ShadowFrame& shadow_frame, JValue result_register);
Mathieu Chartier90443472015-07-16 20:32:27 -07002564template SHARED_REQUIRES(Locks::mutator_lock_) HOT_ATTR
Ian Rogerse94652f2014-12-02 11:13:19 -08002565JValue ExecuteGotoImpl<false, false>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002566 ShadowFrame& shadow_frame, JValue result_register);
Mathieu Chartier90443472015-07-16 20:32:27 -07002567template SHARED_REQUIRES(Locks::mutator_lock_)
Ian Rogerse94652f2014-12-02 11:13:19 -08002568JValue ExecuteGotoImpl<true, true>(Thread* self, const DexFile::CodeItem* code_item,
2569 ShadowFrame& shadow_frame, JValue result_register);
Mathieu Chartier90443472015-07-16 20:32:27 -07002570template SHARED_REQUIRES(Locks::mutator_lock_)
Ian Rogerse94652f2014-12-02 11:13:19 -08002571JValue ExecuteGotoImpl<false, true>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002572 ShadowFrame& shadow_frame, JValue result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002573
2574} // namespace interpreter
2575} // namespace art
Colin Crosse84e4f72015-03-18 14:01:19 -07002576
2577#endif