blob: 6aba898412df4059f79d86388ce76d5972211a8e [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();
jessicahandojo3aaa37b2016-07-29 14:46:37 -0700533 obj = mirror::String::AllocEmptyString<true>(self, allocator_type);
Jeff Hao848f70a2014-01-15 13:49:50 -0800534 } else {
535 obj = AllocObjectFromCode<do_access_check, true>(
536 inst->VRegB_21c(), shadow_frame.GetMethod(), self,
537 Runtime::Current()->GetHeap()->GetCurrentAllocator());
538 }
539 }
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700540 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200541 HANDLE_PENDING_EXCEPTION();
542 } else {
Sebastien Hertz4e99b3d2014-06-24 14:35:40 +0200543 obj->GetClass()->AssertInitializedOrInitializingInThread(self);
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700544 // Don't allow finalizable objects to be allocated during a transaction since these can't be
545 // finalized without a started runtime.
546 if (transaction_active && obj->GetClass()->IsFinalizable()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +0200547 AbortTransactionF(self, "Allocating finalizable object in transaction: %s",
548 PrettyTypeOf(obj).c_str());
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700549 HANDLE_PENDING_EXCEPTION();
550 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200551 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200552 ADVANCE(2);
553 }
554 }
555 HANDLE_INSTRUCTION_END();
556
557 HANDLE_INSTRUCTION_START(NEW_ARRAY) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200558 int32_t length = shadow_frame.GetVReg(inst->VRegB_22c(inst_data));
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800559 Object* obj = AllocArrayFromCode<do_access_check, true>(
Andreas Gampe1cc7dba2014-12-17 18:43:01 -0800560 inst->VRegC_22c(), length, shadow_frame.GetMethod(), self,
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800561 Runtime::Current()->GetHeap()->GetCurrentAllocator());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700562 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200563 HANDLE_PENDING_EXCEPTION();
564 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200565 shadow_frame.SetVRegReference(inst->VRegA_22c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200566 ADVANCE(2);
567 }
568 }
569 HANDLE_INSTRUCTION_END();
570
571 HANDLE_INSTRUCTION_START(FILLED_NEW_ARRAY) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100572 bool success =
573 DoFilledNewArray<false, do_access_check, transaction_active>(inst, shadow_frame,
574 self, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200575 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
576 }
577 HANDLE_INSTRUCTION_END();
578
579 HANDLE_INSTRUCTION_START(FILLED_NEW_ARRAY_RANGE) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100580 bool success =
581 DoFilledNewArray<true, do_access_check, transaction_active>(inst, shadow_frame,
582 self, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200583 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
584 }
585 HANDLE_INSTRUCTION_END();
586
587 HANDLE_INSTRUCTION_START(FILL_ARRAY_DATA) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200588 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_31t(inst_data));
Ian Rogers832336b2014-10-08 15:35:22 -0700589 const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t();
590 const Instruction::ArrayDataPayload* payload =
591 reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr);
592 bool success = FillArrayData(obj, payload);
593 if (transaction_active && success) {
594 RecordArrayElementsInTransaction(obj->AsArray(), payload->element_count);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200595 }
Ian Rogers832336b2014-10-08 15:35:22 -0700596 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200597 }
598 HANDLE_INSTRUCTION_END();
599
600 HANDLE_INSTRUCTION_START(THROW) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200601 Object* exception = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700602 if (UNLIKELY(exception == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000603 ThrowNullPointerException("throw with null exception");
Jeff Haoa3faaf42013-09-03 19:07:00 -0700604 } else if (do_assignability_check && !exception->GetClass()->IsThrowableClass()) {
605 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700606 std::string temp;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000607 self->ThrowNewExceptionF("Ljava/lang/VirtualMachineError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700608 "Throwing '%s' that is not instance of Throwable",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700609 exception->GetClass()->GetDescriptor(&temp));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200610 } else {
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000611 self->SetException(exception->AsThrowable());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200612 }
613 HANDLE_PENDING_EXCEPTION();
614 }
615 HANDLE_INSTRUCTION_END();
616
617 HANDLE_INSTRUCTION_START(GOTO) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200618 int8_t offset = inst->VRegA_10t(inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000619 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200620 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000621 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200622 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700623 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200624 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200625 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200626 }
627 ADVANCE(offset);
628 }
629 HANDLE_INSTRUCTION_END();
630
631 HANDLE_INSTRUCTION_START(GOTO_16) {
632 int16_t offset = inst->VRegA_20t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000633 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200634 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000635 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200636 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700637 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200638 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200639 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200640 }
641 ADVANCE(offset);
642 }
643 HANDLE_INSTRUCTION_END();
644
645 HANDLE_INSTRUCTION_START(GOTO_32) {
646 int32_t offset = inst->VRegA_30t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000647 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200648 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000649 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200650 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700651 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200652 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200653 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200654 }
655 ADVANCE(offset);
656 }
657 HANDLE_INSTRUCTION_END();
658
659 HANDLE_INSTRUCTION_START(PACKED_SWITCH) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200660 int32_t offset = DoPackedSwitch(inst, shadow_frame, inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000661 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200662 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000663 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200664 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700665 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200666 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200667 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200668 }
669 ADVANCE(offset);
670 }
671 HANDLE_INSTRUCTION_END();
672
673 HANDLE_INSTRUCTION_START(SPARSE_SWITCH) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200674 int32_t offset = DoSparseSwitch(inst, shadow_frame, inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000675 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200676 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000677 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200678 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700679 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200680 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200681 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200682 }
683 ADVANCE(offset);
684 }
685 HANDLE_INSTRUCTION_END();
686
Ian Rogers647b1a82014-10-10 11:02:11 -0700687#if defined(__clang__)
688#pragma clang diagnostic push
689#pragma clang diagnostic ignored "-Wfloat-equal"
690#endif
691
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200692 HANDLE_INSTRUCTION_START(CMPL_FLOAT) {
693 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
694 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
695 int32_t result;
696 if (val1 > val2) {
697 result = 1;
698 } else if (val1 == val2) {
699 result = 0;
700 } else {
701 result = -1;
702 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200703 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200704 ADVANCE(2);
705 }
706 HANDLE_INSTRUCTION_END();
707
708 HANDLE_INSTRUCTION_START(CMPG_FLOAT) {
709 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
710 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
711 int32_t result;
712 if (val1 < val2) {
713 result = -1;
714 } else if (val1 == val2) {
715 result = 0;
716 } else {
717 result = 1;
718 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200719 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200720 ADVANCE(2);
721 }
722 HANDLE_INSTRUCTION_END();
723
724 HANDLE_INSTRUCTION_START(CMPL_DOUBLE) {
725 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
726 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
727 int32_t result;
728 if (val1 > val2) {
729 result = 1;
730 } else if (val1 == val2) {
731 result = 0;
732 } else {
733 result = -1;
734 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200735 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200736 ADVANCE(2);
737 }
738 HANDLE_INSTRUCTION_END();
739
740 HANDLE_INSTRUCTION_START(CMPG_DOUBLE) {
741 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
742 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
743 int32_t result;
744 if (val1 < val2) {
745 result = -1;
746 } else if (val1 == val2) {
747 result = 0;
748 } else {
749 result = 1;
750 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200751 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200752 ADVANCE(2);
753 }
754 HANDLE_INSTRUCTION_END();
755
Ian Rogers647b1a82014-10-10 11:02:11 -0700756#if defined(__clang__)
757#pragma clang diagnostic pop
758#endif
759
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200760 HANDLE_INSTRUCTION_START(CMP_LONG) {
761 int64_t val1 = shadow_frame.GetVRegLong(inst->VRegB_23x());
762 int64_t val2 = shadow_frame.GetVRegLong(inst->VRegC_23x());
763 int32_t result;
764 if (val1 > val2) {
765 result = 1;
766 } else if (val1 == val2) {
767 result = 0;
768 } else {
769 result = -1;
770 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200771 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200772 ADVANCE(2);
773 }
774 HANDLE_INSTRUCTION_END();
775
776 HANDLE_INSTRUCTION_START(IF_EQ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200777 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) == shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200778 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000779 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200780 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000781 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200782 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700783 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200784 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200785 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200786 }
787 ADVANCE(offset);
788 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800789 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200790 ADVANCE(2);
791 }
792 }
793 HANDLE_INSTRUCTION_END();
794
795 HANDLE_INSTRUCTION_START(IF_NE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700796 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) !=
797 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200798 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000799 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200800 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000801 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200802 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700803 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200804 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200805 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200806 }
807 ADVANCE(offset);
808 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800809 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200810 ADVANCE(2);
811 }
812 }
813 HANDLE_INSTRUCTION_END();
814
815 HANDLE_INSTRUCTION_START(IF_LT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700816 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <
817 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200818 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000819 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200820 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000821 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200822 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700823 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200824 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200825 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200826 }
827 ADVANCE(offset);
828 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800829 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200830 ADVANCE(2);
831 }
832 }
833 HANDLE_INSTRUCTION_END();
834
835 HANDLE_INSTRUCTION_START(IF_GE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700836 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >=
837 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200838 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000839 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200840 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000841 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200842 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700843 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200844 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200845 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200846 }
847 ADVANCE(offset);
848 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800849 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200850 ADVANCE(2);
851 }
852 }
853 HANDLE_INSTRUCTION_END();
854
855 HANDLE_INSTRUCTION_START(IF_GT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700856 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >
857 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200858 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000859 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200860 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000861 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200862 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700863 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200864 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200865 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200866 }
867 ADVANCE(offset);
868 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800869 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200870 ADVANCE(2);
871 }
872 }
873 HANDLE_INSTRUCTION_END();
874
875 HANDLE_INSTRUCTION_START(IF_LE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700876 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <=
877 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200878 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000879 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200880 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000881 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200882 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700883 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200884 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200885 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200886 }
887 ADVANCE(offset);
888 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800889 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200890 ADVANCE(2);
891 }
892 }
893 HANDLE_INSTRUCTION_END();
894
895 HANDLE_INSTRUCTION_START(IF_EQZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200896 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) == 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200897 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000898 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200899 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000900 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200901 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700902 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200903 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200904 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200905 }
906 ADVANCE(offset);
907 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800908 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200909 ADVANCE(2);
910 }
911 }
912 HANDLE_INSTRUCTION_END();
913
914 HANDLE_INSTRUCTION_START(IF_NEZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200915 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) != 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200916 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000917 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200918 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000919 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200920 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700921 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200922 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200923 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200924 }
925 ADVANCE(offset);
926 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800927 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200928 ADVANCE(2);
929 }
930 }
931 HANDLE_INSTRUCTION_END();
932
933 HANDLE_INSTRUCTION_START(IF_LTZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200934 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) < 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200935 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000936 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200937 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000938 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200939 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700940 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200941 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200942 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200943 }
944 ADVANCE(offset);
945 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800946 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200947 ADVANCE(2);
948 }
949 }
950 HANDLE_INSTRUCTION_END();
951
952 HANDLE_INSTRUCTION_START(IF_GEZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200953 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) >= 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200954 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000955 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200956 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000957 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200958 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700959 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200960 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200961 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200962 }
963 ADVANCE(offset);
964 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800965 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200966 ADVANCE(2);
967 }
968 }
969 HANDLE_INSTRUCTION_END();
970
971 HANDLE_INSTRUCTION_START(IF_GTZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200972 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) > 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200973 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000974 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200975 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000976 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200977 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700978 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200979 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200980 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200981 }
982 ADVANCE(offset);
983 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800984 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200985 ADVANCE(2);
986 }
987 }
988 HANDLE_INSTRUCTION_END();
989
990 HANDLE_INSTRUCTION_START(IF_LEZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200991 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) <= 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200992 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000993 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200994 if (IsBackwardBranch(offset)) {
Bill Buzbee1d011d92016-04-04 16:59:29 +0000995 HOTNESS_UPDATE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200996 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700997 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200998 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200999 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001000 }
1001 ADVANCE(offset);
1002 } else {
buzbeef1dcacc2016-02-24 14:24:24 -08001003 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001004 ADVANCE(2);
1005 }
1006 }
1007 HANDLE_INSTRUCTION_END();
1008
1009 HANDLE_INSTRUCTION_START(AGET_BOOLEAN) {
1010 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001011 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001012 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001013 HANDLE_PENDING_EXCEPTION();
1014 } else {
1015 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1016 BooleanArray* array = a->AsBooleanArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001017 if (LIKELY(array->CheckIsValidIndex(index))) {
1018 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001019 ADVANCE(2);
1020 } else {
1021 HANDLE_PENDING_EXCEPTION();
1022 }
1023 }
1024 }
1025 HANDLE_INSTRUCTION_END();
1026
1027 HANDLE_INSTRUCTION_START(AGET_BYTE) {
1028 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001029 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001030 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001031 HANDLE_PENDING_EXCEPTION();
1032 } else {
1033 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1034 ByteArray* array = a->AsByteArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001035 if (LIKELY(array->CheckIsValidIndex(index))) {
1036 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001037 ADVANCE(2);
1038 } else {
1039 HANDLE_PENDING_EXCEPTION();
1040 }
1041 }
1042 }
1043 HANDLE_INSTRUCTION_END();
1044
1045 HANDLE_INSTRUCTION_START(AGET_CHAR) {
1046 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001047 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001048 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001049 HANDLE_PENDING_EXCEPTION();
1050 } else {
1051 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1052 CharArray* array = a->AsCharArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001053 if (LIKELY(array->CheckIsValidIndex(index))) {
1054 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001055 ADVANCE(2);
1056 } else {
1057 HANDLE_PENDING_EXCEPTION();
1058 }
1059 }
1060 }
1061 HANDLE_INSTRUCTION_END();
1062
1063 HANDLE_INSTRUCTION_START(AGET_SHORT) {
1064 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001065 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001066 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001067 HANDLE_PENDING_EXCEPTION();
1068 } else {
1069 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1070 ShortArray* array = a->AsShortArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001071 if (LIKELY(array->CheckIsValidIndex(index))) {
1072 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001073 ADVANCE(2);
1074 } else {
1075 HANDLE_PENDING_EXCEPTION();
1076 }
1077 }
1078 }
1079 HANDLE_INSTRUCTION_END();
1080
1081 HANDLE_INSTRUCTION_START(AGET) {
1082 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001083 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001084 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001085 HANDLE_PENDING_EXCEPTION();
1086 } else {
1087 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001088 DCHECK(a->IsIntArray() || a->IsFloatArray()) << PrettyTypeOf(a);
1089 auto* array = down_cast<IntArray*>(a);
Sebastien Hertzabff6432014-01-27 18:01:39 +01001090 if (LIKELY(array->CheckIsValidIndex(index))) {
1091 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001092 ADVANCE(2);
1093 } else {
1094 HANDLE_PENDING_EXCEPTION();
1095 }
1096 }
1097 }
1098 HANDLE_INSTRUCTION_END();
1099
1100 HANDLE_INSTRUCTION_START(AGET_WIDE) {
1101 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001102 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001103 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001104 HANDLE_PENDING_EXCEPTION();
1105 } else {
1106 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001107 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << PrettyTypeOf(a);
1108 auto* array = down_cast<LongArray*>(a);
Sebastien Hertzabff6432014-01-27 18:01:39 +01001109 if (LIKELY(array->CheckIsValidIndex(index))) {
1110 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001111 ADVANCE(2);
1112 } else {
1113 HANDLE_PENDING_EXCEPTION();
1114 }
1115 }
1116 }
1117 HANDLE_INSTRUCTION_END();
1118
1119 HANDLE_INSTRUCTION_START(AGET_OBJECT) {
1120 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001121 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001122 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001123 HANDLE_PENDING_EXCEPTION();
1124 } else {
1125 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1126 ObjectArray<Object>* array = a->AsObjectArray<Object>();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001127 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001128 shadow_frame.SetVRegReference(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001129 ADVANCE(2);
1130 } else {
1131 HANDLE_PENDING_EXCEPTION();
1132 }
1133 }
1134 }
1135 HANDLE_INSTRUCTION_END();
1136
1137 HANDLE_INSTRUCTION_START(APUT_BOOLEAN) {
1138 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001139 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001140 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001141 HANDLE_PENDING_EXCEPTION();
1142 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001143 uint8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001144 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1145 BooleanArray* array = a->AsBooleanArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001146 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001147 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001148 ADVANCE(2);
1149 } else {
1150 HANDLE_PENDING_EXCEPTION();
1151 }
1152 }
1153 }
1154 HANDLE_INSTRUCTION_END();
1155
1156 HANDLE_INSTRUCTION_START(APUT_BYTE) {
1157 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001158 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001159 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001160 HANDLE_PENDING_EXCEPTION();
1161 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001162 int8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001163 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1164 ByteArray* array = a->AsByteArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001165 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001166 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001167 ADVANCE(2);
1168 } else {
1169 HANDLE_PENDING_EXCEPTION();
1170 }
1171 }
1172 }
1173 HANDLE_INSTRUCTION_END();
1174
1175 HANDLE_INSTRUCTION_START(APUT_CHAR) {
1176 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001177 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001178 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001179 HANDLE_PENDING_EXCEPTION();
1180 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001181 uint16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001182 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1183 CharArray* array = a->AsCharArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001184 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001185 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001186 ADVANCE(2);
1187 } else {
1188 HANDLE_PENDING_EXCEPTION();
1189 }
1190 }
1191 }
1192 HANDLE_INSTRUCTION_END();
1193
1194 HANDLE_INSTRUCTION_START(APUT_SHORT) {
1195 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001196 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001197 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001198 HANDLE_PENDING_EXCEPTION();
1199 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001200 int16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001201 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1202 ShortArray* array = a->AsShortArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001203 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001204 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001205 ADVANCE(2);
1206 } else {
1207 HANDLE_PENDING_EXCEPTION();
1208 }
1209 }
1210 }
1211 HANDLE_INSTRUCTION_END();
1212
1213 HANDLE_INSTRUCTION_START(APUT) {
1214 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001215 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001216 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001217 HANDLE_PENDING_EXCEPTION();
1218 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001219 int32_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001220 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001221 DCHECK(a->IsIntArray() || a->IsFloatArray()) << PrettyTypeOf(a);
1222 auto* array = down_cast<IntArray*>(a);
Sebastien Hertzabff6432014-01-27 18:01:39 +01001223 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001224 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001225 ADVANCE(2);
1226 } else {
1227 HANDLE_PENDING_EXCEPTION();
1228 }
1229 }
1230 }
1231 HANDLE_INSTRUCTION_END();
1232
1233 HANDLE_INSTRUCTION_START(APUT_WIDE) {
1234 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001235 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001236 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001237 HANDLE_PENDING_EXCEPTION();
1238 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001239 int64_t val = shadow_frame.GetVRegLong(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001240 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001241 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << PrettyTypeOf(a);
1242 auto* array = down_cast<LongArray*>(a);
Sebastien Hertzabff6432014-01-27 18:01:39 +01001243 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001244 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001245 ADVANCE(2);
1246 } else {
1247 HANDLE_PENDING_EXCEPTION();
1248 }
1249 }
1250 }
1251 HANDLE_INSTRUCTION_END();
1252
1253 HANDLE_INSTRUCTION_START(APUT_OBJECT) {
1254 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001255 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001256 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001257 HANDLE_PENDING_EXCEPTION();
1258 } else {
1259 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001260 Object* val = shadow_frame.GetVRegReference(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001261 ObjectArray<Object>* array = a->AsObjectArray<Object>();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001262 if (LIKELY(array->CheckIsValidIndex(index) && array->CheckAssignable(val))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001263 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001264 ADVANCE(2);
1265 } else {
1266 HANDLE_PENDING_EXCEPTION();
1267 }
1268 }
1269 }
1270 HANDLE_INSTRUCTION_END();
1271
1272 HANDLE_INSTRUCTION_START(IGET_BOOLEAN) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001273 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimBoolean, do_access_check>(
1274 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001275 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1276 }
1277 HANDLE_INSTRUCTION_END();
1278
1279 HANDLE_INSTRUCTION_START(IGET_BYTE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001280 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimByte, do_access_check>(
1281 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001282 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1283 }
1284 HANDLE_INSTRUCTION_END();
1285
1286 HANDLE_INSTRUCTION_START(IGET_CHAR) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001287 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimChar, do_access_check>(
1288 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001289 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1290 }
1291 HANDLE_INSTRUCTION_END();
1292
1293 HANDLE_INSTRUCTION_START(IGET_SHORT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001294 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimShort, do_access_check>(
1295 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001296 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1297 }
1298 HANDLE_INSTRUCTION_END();
1299
1300 HANDLE_INSTRUCTION_START(IGET) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001301 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimInt, do_access_check>(
1302 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001303 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1304 }
1305 HANDLE_INSTRUCTION_END();
1306
1307 HANDLE_INSTRUCTION_START(IGET_WIDE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001308 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimLong, do_access_check>(
1309 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001310 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1311 }
1312 HANDLE_INSTRUCTION_END();
1313
1314 HANDLE_INSTRUCTION_START(IGET_OBJECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001315 bool success = DoFieldGet<InstanceObjectRead, Primitive::kPrimNot, do_access_check>(
1316 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001317 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1318 }
1319 HANDLE_INSTRUCTION_END();
1320
1321 HANDLE_INSTRUCTION_START(IGET_QUICK) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001322 bool success = DoIGetQuick<Primitive::kPrimInt>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001323 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1324 }
1325 HANDLE_INSTRUCTION_END();
1326
Mathieu Chartierffc605c2014-12-10 10:35:44 -08001327 HANDLE_INSTRUCTION_START(IGET_BOOLEAN_QUICK) {
1328 bool success = DoIGetQuick<Primitive::kPrimBoolean>(shadow_frame, inst, inst_data);
1329 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1330 }
1331 HANDLE_INSTRUCTION_END();
1332
1333 HANDLE_INSTRUCTION_START(IGET_BYTE_QUICK) {
1334 bool success = DoIGetQuick<Primitive::kPrimByte>(shadow_frame, inst, inst_data);
1335 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1336 }
1337 HANDLE_INSTRUCTION_END();
1338
1339 HANDLE_INSTRUCTION_START(IGET_CHAR_QUICK) {
1340 bool success = DoIGetQuick<Primitive::kPrimChar>(shadow_frame, inst, inst_data);
1341 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1342 }
1343 HANDLE_INSTRUCTION_END();
1344
1345 HANDLE_INSTRUCTION_START(IGET_SHORT_QUICK) {
1346 bool success = DoIGetQuick<Primitive::kPrimShort>(shadow_frame, inst, inst_data);
1347 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1348 }
1349 HANDLE_INSTRUCTION_END();
1350
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001351 HANDLE_INSTRUCTION_START(IGET_WIDE_QUICK) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001352 bool success = DoIGetQuick<Primitive::kPrimLong>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001353 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1354 }
1355 HANDLE_INSTRUCTION_END();
1356
1357 HANDLE_INSTRUCTION_START(IGET_OBJECT_QUICK) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001358 bool success = DoIGetQuick<Primitive::kPrimNot>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001359 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1360 }
1361 HANDLE_INSTRUCTION_END();
1362
1363 HANDLE_INSTRUCTION_START(SGET_BOOLEAN) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001364 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimBoolean, do_access_check>(
1365 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001366 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1367 }
1368 HANDLE_INSTRUCTION_END();
1369
1370 HANDLE_INSTRUCTION_START(SGET_BYTE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001371 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimByte, do_access_check>(
1372 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001373 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1374 }
1375 HANDLE_INSTRUCTION_END();
1376
1377 HANDLE_INSTRUCTION_START(SGET_CHAR) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001378 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimChar, do_access_check>(
1379 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001380 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1381 }
1382 HANDLE_INSTRUCTION_END();
1383
1384 HANDLE_INSTRUCTION_START(SGET_SHORT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001385 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimShort, do_access_check>(
1386 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001387 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1388 }
1389 HANDLE_INSTRUCTION_END();
1390
1391 HANDLE_INSTRUCTION_START(SGET) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001392 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimInt, do_access_check>(
1393 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001394 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1395 }
1396 HANDLE_INSTRUCTION_END();
1397
1398 HANDLE_INSTRUCTION_START(SGET_WIDE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001399 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimLong, do_access_check>(
1400 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001401 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1402 }
1403 HANDLE_INSTRUCTION_END();
1404
1405 HANDLE_INSTRUCTION_START(SGET_OBJECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001406 bool success = DoFieldGet<StaticObjectRead, Primitive::kPrimNot, do_access_check>(
1407 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001408 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1409 }
1410 HANDLE_INSTRUCTION_END();
1411
1412 HANDLE_INSTRUCTION_START(IPUT_BOOLEAN) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001413 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1414 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001415 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1416 }
1417 HANDLE_INSTRUCTION_END();
1418
1419 HANDLE_INSTRUCTION_START(IPUT_BYTE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001420 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimByte, do_access_check,
1421 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001422 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1423 }
1424 HANDLE_INSTRUCTION_END();
1425
1426 HANDLE_INSTRUCTION_START(IPUT_CHAR) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001427 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimChar, do_access_check,
1428 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001429 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1430 }
1431 HANDLE_INSTRUCTION_END();
1432
1433 HANDLE_INSTRUCTION_START(IPUT_SHORT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001434 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimShort, do_access_check,
1435 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001436 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1437 }
1438 HANDLE_INSTRUCTION_END();
1439
1440 HANDLE_INSTRUCTION_START(IPUT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001441 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimInt, do_access_check,
1442 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001443 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1444 }
1445 HANDLE_INSTRUCTION_END();
1446
1447 HANDLE_INSTRUCTION_START(IPUT_WIDE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001448 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimLong, do_access_check,
1449 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001450 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1451 }
1452 HANDLE_INSTRUCTION_END();
1453
1454 HANDLE_INSTRUCTION_START(IPUT_OBJECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001455 bool success = DoFieldPut<InstanceObjectWrite, Primitive::kPrimNot, do_access_check,
1456 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001457 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1458 }
1459 HANDLE_INSTRUCTION_END();
1460
1461 HANDLE_INSTRUCTION_START(IPUT_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001462 bool success = DoIPutQuick<Primitive::kPrimInt, transaction_active>(
1463 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001464 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1465 }
1466 HANDLE_INSTRUCTION_END();
1467
Fred Shih37f05ef2014-07-16 18:38:08 -07001468 HANDLE_INSTRUCTION_START(IPUT_BOOLEAN_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001469 bool success = DoIPutQuick<Primitive::kPrimBoolean, transaction_active>(
1470 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001471 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1472 }
1473 HANDLE_INSTRUCTION_END();
1474
1475 HANDLE_INSTRUCTION_START(IPUT_BYTE_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001476 bool success = DoIPutQuick<Primitive::kPrimByte, transaction_active>(
1477 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001478 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1479 }
1480 HANDLE_INSTRUCTION_END();
1481
1482 HANDLE_INSTRUCTION_START(IPUT_CHAR_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001483 bool success = DoIPutQuick<Primitive::kPrimChar, transaction_active>(
1484 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001485 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1486 }
1487 HANDLE_INSTRUCTION_END();
1488
1489 HANDLE_INSTRUCTION_START(IPUT_SHORT_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001490 bool success = DoIPutQuick<Primitive::kPrimShort, transaction_active>(
1491 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001492 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1493 }
1494 HANDLE_INSTRUCTION_END();
1495
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001496 HANDLE_INSTRUCTION_START(IPUT_WIDE_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001497 bool success = DoIPutQuick<Primitive::kPrimLong, transaction_active>(
1498 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001499 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1500 }
1501 HANDLE_INSTRUCTION_END();
1502
1503 HANDLE_INSTRUCTION_START(IPUT_OBJECT_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001504 bool success = DoIPutQuick<Primitive::kPrimNot, transaction_active>(
1505 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001506 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1507 }
1508 HANDLE_INSTRUCTION_END();
1509
1510 HANDLE_INSTRUCTION_START(SPUT_BOOLEAN) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001511 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1512 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001513 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1514 }
1515 HANDLE_INSTRUCTION_END();
1516
1517 HANDLE_INSTRUCTION_START(SPUT_BYTE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001518 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimByte, do_access_check,
1519 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001520 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1521 }
1522 HANDLE_INSTRUCTION_END();
1523
1524 HANDLE_INSTRUCTION_START(SPUT_CHAR) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001525 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimChar, do_access_check,
1526 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001527 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1528 }
1529 HANDLE_INSTRUCTION_END();
1530
1531 HANDLE_INSTRUCTION_START(SPUT_SHORT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001532 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimShort, do_access_check,
1533 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001534 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1535 }
1536 HANDLE_INSTRUCTION_END();
1537
1538 HANDLE_INSTRUCTION_START(SPUT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001539 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimInt, do_access_check,
1540 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001541 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1542 }
1543 HANDLE_INSTRUCTION_END();
1544
1545 HANDLE_INSTRUCTION_START(SPUT_WIDE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001546 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimLong, do_access_check,
1547 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001548 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1549 }
1550 HANDLE_INSTRUCTION_END();
1551
1552 HANDLE_INSTRUCTION_START(SPUT_OBJECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001553 bool success = DoFieldPut<StaticObjectWrite, Primitive::kPrimNot, do_access_check,
1554 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001555 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1556 }
1557 HANDLE_INSTRUCTION_END();
1558
1559 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001560 bool success = DoInvoke<kVirtual, false, do_access_check>(
1561 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001562 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001563 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1564 }
1565 HANDLE_INSTRUCTION_END();
1566
1567 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001568 bool success = DoInvoke<kVirtual, true, do_access_check>(
1569 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001570 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001571 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1572 }
1573 HANDLE_INSTRUCTION_END();
1574
1575 HANDLE_INSTRUCTION_START(INVOKE_SUPER) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001576 bool success = DoInvoke<kSuper, false, do_access_check>(
1577 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001578 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001579 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1580 }
1581 HANDLE_INSTRUCTION_END();
1582
1583 HANDLE_INSTRUCTION_START(INVOKE_SUPER_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001584 bool success = DoInvoke<kSuper, true, do_access_check>(
1585 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001586 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001587 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1588 }
1589 HANDLE_INSTRUCTION_END();
1590
1591 HANDLE_INSTRUCTION_START(INVOKE_DIRECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001592 bool success = DoInvoke<kDirect, false, do_access_check>(
1593 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001594 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001595 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1596 }
1597 HANDLE_INSTRUCTION_END();
1598
1599 HANDLE_INSTRUCTION_START(INVOKE_DIRECT_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001600 bool success = DoInvoke<kDirect, true, do_access_check>(
1601 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001602 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001603 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1604 }
1605 HANDLE_INSTRUCTION_END();
1606
1607 HANDLE_INSTRUCTION_START(INVOKE_INTERFACE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001608 bool success = DoInvoke<kInterface, false, do_access_check>(
1609 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001610 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001611 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1612 }
1613 HANDLE_INSTRUCTION_END();
1614
1615 HANDLE_INSTRUCTION_START(INVOKE_INTERFACE_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001616 bool success = DoInvoke<kInterface, true, do_access_check>(
1617 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001618 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001619 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1620 }
1621 HANDLE_INSTRUCTION_END();
1622
1623 HANDLE_INSTRUCTION_START(INVOKE_STATIC) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001624 bool success = DoInvoke<kStatic, false, do_access_check>(
1625 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001626 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001627 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1628 }
1629 HANDLE_INSTRUCTION_END();
1630
1631 HANDLE_INSTRUCTION_START(INVOKE_STATIC_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001632 bool success = DoInvoke<kStatic, true, do_access_check>(
1633 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001634 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001635 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1636 }
1637 HANDLE_INSTRUCTION_END();
1638
1639 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001640 bool success = DoInvokeVirtualQuick<false>(
1641 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001642 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001643 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1644 }
1645 HANDLE_INSTRUCTION_END();
1646
1647 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_RANGE_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001648 bool success = DoInvokeVirtualQuick<true>(
1649 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001650 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001651 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1652 }
1653 HANDLE_INSTRUCTION_END();
1654
1655 HANDLE_INSTRUCTION_START(NEG_INT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001656 shadow_frame.SetVReg(
1657 inst->VRegA_12x(inst_data), -shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001658 ADVANCE(1);
1659 HANDLE_INSTRUCTION_END();
1660
1661 HANDLE_INSTRUCTION_START(NOT_INT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001662 shadow_frame.SetVReg(
1663 inst->VRegA_12x(inst_data), ~shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001664 ADVANCE(1);
1665 HANDLE_INSTRUCTION_END();
1666
1667 HANDLE_INSTRUCTION_START(NEG_LONG)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001668 shadow_frame.SetVRegLong(
1669 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001670 ADVANCE(1);
1671 HANDLE_INSTRUCTION_END();
1672
1673 HANDLE_INSTRUCTION_START(NOT_LONG)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001674 shadow_frame.SetVRegLong(
1675 inst->VRegA_12x(inst_data), ~shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001676 ADVANCE(1);
1677 HANDLE_INSTRUCTION_END();
1678
1679 HANDLE_INSTRUCTION_START(NEG_FLOAT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001680 shadow_frame.SetVRegFloat(
1681 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001682 ADVANCE(1);
1683 HANDLE_INSTRUCTION_END();
1684
1685 HANDLE_INSTRUCTION_START(NEG_DOUBLE)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001686 shadow_frame.SetVRegDouble(
1687 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001688 ADVANCE(1);
1689 HANDLE_INSTRUCTION_END();
1690
1691 HANDLE_INSTRUCTION_START(INT_TO_LONG)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001692 shadow_frame.SetVRegLong(
1693 inst->VRegA_12x(inst_data), shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001694 ADVANCE(1);
1695 HANDLE_INSTRUCTION_END();
1696
1697 HANDLE_INSTRUCTION_START(INT_TO_FLOAT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001698 shadow_frame.SetVRegFloat(
1699 inst->VRegA_12x(inst_data), shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001700 ADVANCE(1);
1701 HANDLE_INSTRUCTION_END();
1702
1703 HANDLE_INSTRUCTION_START(INT_TO_DOUBLE)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001704 shadow_frame.SetVRegDouble(
1705 inst->VRegA_12x(inst_data), shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001706 ADVANCE(1);
1707 HANDLE_INSTRUCTION_END();
1708
1709 HANDLE_INSTRUCTION_START(LONG_TO_INT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001710 shadow_frame.SetVReg(
1711 inst->VRegA_12x(inst_data), shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001712 ADVANCE(1);
1713 HANDLE_INSTRUCTION_END();
1714
1715 HANDLE_INSTRUCTION_START(LONG_TO_FLOAT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001716 shadow_frame.SetVRegFloat(
1717 inst->VRegA_12x(inst_data), shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001718 ADVANCE(1);
1719 HANDLE_INSTRUCTION_END();
1720
1721 HANDLE_INSTRUCTION_START(LONG_TO_DOUBLE)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001722 shadow_frame.SetVRegDouble(
1723 inst->VRegA_12x(inst_data), shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001724 ADVANCE(1);
1725 HANDLE_INSTRUCTION_END();
1726
1727 HANDLE_INSTRUCTION_START(FLOAT_TO_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001728 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001729 int32_t result = art_float_to_integral<int32_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001730 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001731 ADVANCE(1);
1732 }
1733 HANDLE_INSTRUCTION_END();
1734
1735 HANDLE_INSTRUCTION_START(FLOAT_TO_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001736 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001737 int64_t result = art_float_to_integral<int64_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001738 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001739 ADVANCE(1);
1740 }
1741 HANDLE_INSTRUCTION_END();
1742
1743 HANDLE_INSTRUCTION_START(FLOAT_TO_DOUBLE)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001744 shadow_frame.SetVRegDouble(
1745 inst->VRegA_12x(inst_data), shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001746 ADVANCE(1);
1747 HANDLE_INSTRUCTION_END();
1748
1749 HANDLE_INSTRUCTION_START(DOUBLE_TO_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001750 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001751 int32_t result = art_float_to_integral<int32_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001752 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001753 ADVANCE(1);
1754 }
1755 HANDLE_INSTRUCTION_END();
1756
1757 HANDLE_INSTRUCTION_START(DOUBLE_TO_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001758 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001759 int64_t result = art_float_to_integral<int64_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001760 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001761 ADVANCE(1);
1762 }
1763 HANDLE_INSTRUCTION_END();
1764
1765 HANDLE_INSTRUCTION_START(DOUBLE_TO_FLOAT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001766 shadow_frame.SetVRegFloat(
1767 inst->VRegA_12x(inst_data), shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001768 ADVANCE(1);
1769 HANDLE_INSTRUCTION_END();
1770
1771 HANDLE_INSTRUCTION_START(INT_TO_BYTE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001772 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1773 static_cast<int8_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001774 ADVANCE(1);
1775 HANDLE_INSTRUCTION_END();
1776
1777 HANDLE_INSTRUCTION_START(INT_TO_CHAR)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001778 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1779 static_cast<uint16_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001780 ADVANCE(1);
1781 HANDLE_INSTRUCTION_END();
1782
1783 HANDLE_INSTRUCTION_START(INT_TO_SHORT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001784 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1785 static_cast<int16_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001786 ADVANCE(1);
1787 HANDLE_INSTRUCTION_END();
1788
1789 HANDLE_INSTRUCTION_START(ADD_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001790 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001791 SafeAdd(shadow_frame.GetVReg(inst->VRegB_23x()),
1792 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001793 ADVANCE(2);
1794 HANDLE_INSTRUCTION_END();
1795
1796 HANDLE_INSTRUCTION_START(SUB_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001797 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001798 SafeSub(shadow_frame.GetVReg(inst->VRegB_23x()),
1799 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001800 ADVANCE(2);
1801 HANDLE_INSTRUCTION_END();
1802
1803 HANDLE_INSTRUCTION_START(MUL_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001804 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001805 SafeMul(shadow_frame.GetVReg(inst->VRegB_23x()),
1806 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001807 ADVANCE(2);
1808 HANDLE_INSTRUCTION_END();
1809
1810 HANDLE_INSTRUCTION_START(DIV_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001811 bool success = DoIntDivide(shadow_frame, inst->VRegA_23x(inst_data),
1812 shadow_frame.GetVReg(inst->VRegB_23x()),
1813 shadow_frame.GetVReg(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001814 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1815 }
1816 HANDLE_INSTRUCTION_END();
1817
1818 HANDLE_INSTRUCTION_START(REM_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001819 bool success = DoIntRemainder(shadow_frame, inst->VRegA_23x(inst_data),
1820 shadow_frame.GetVReg(inst->VRegB_23x()),
1821 shadow_frame.GetVReg(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001822 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1823 }
1824 HANDLE_INSTRUCTION_END();
1825
1826 HANDLE_INSTRUCTION_START(SHL_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001827 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001828 shadow_frame.GetVReg(inst->VRegB_23x()) <<
1829 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1830 ADVANCE(2);
1831 HANDLE_INSTRUCTION_END();
1832
1833 HANDLE_INSTRUCTION_START(SHR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001834 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001835 shadow_frame.GetVReg(inst->VRegB_23x()) >>
1836 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1837 ADVANCE(2);
1838 HANDLE_INSTRUCTION_END();
1839
1840 HANDLE_INSTRUCTION_START(USHR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001841 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001842 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_23x())) >>
1843 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1844 ADVANCE(2);
1845 HANDLE_INSTRUCTION_END();
1846
1847 HANDLE_INSTRUCTION_START(AND_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001848 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001849 shadow_frame.GetVReg(inst->VRegB_23x()) &
1850 shadow_frame.GetVReg(inst->VRegC_23x()));
1851 ADVANCE(2);
1852 HANDLE_INSTRUCTION_END();
1853
1854 HANDLE_INSTRUCTION_START(OR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001855 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001856 shadow_frame.GetVReg(inst->VRegB_23x()) |
1857 shadow_frame.GetVReg(inst->VRegC_23x()));
1858 ADVANCE(2);
1859 HANDLE_INSTRUCTION_END();
1860
1861 HANDLE_INSTRUCTION_START(XOR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001862 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001863 shadow_frame.GetVReg(inst->VRegB_23x()) ^
1864 shadow_frame.GetVReg(inst->VRegC_23x()));
1865 ADVANCE(2);
1866 HANDLE_INSTRUCTION_END();
1867
1868 HANDLE_INSTRUCTION_START(ADD_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001869 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001870 SafeAdd(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1871 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001872 ADVANCE(2);
1873 HANDLE_INSTRUCTION_END();
1874
1875 HANDLE_INSTRUCTION_START(SUB_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001876 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001877 SafeSub(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1878 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001879 ADVANCE(2);
1880 HANDLE_INSTRUCTION_END();
1881
1882 HANDLE_INSTRUCTION_START(MUL_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001883 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001884 SafeMul(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1885 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001886 ADVANCE(2);
1887 HANDLE_INSTRUCTION_END();
1888
1889 HANDLE_INSTRUCTION_START(DIV_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001890 bool success = DoLongDivide(shadow_frame, inst->VRegA_23x(inst_data),
1891 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1892 shadow_frame.GetVRegLong(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001893 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1894 }
1895 HANDLE_INSTRUCTION_END();
1896
1897 HANDLE_INSTRUCTION_START(REM_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001898 bool success = DoLongRemainder(shadow_frame, inst->VRegA_23x(inst_data),
1899 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1900 shadow_frame.GetVRegLong(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001901 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1902 }
1903 HANDLE_INSTRUCTION_END();
1904
1905 HANDLE_INSTRUCTION_START(AND_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001906 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001907 shadow_frame.GetVRegLong(inst->VRegB_23x()) &
1908 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1909 ADVANCE(2);
1910 HANDLE_INSTRUCTION_END();
1911
1912 HANDLE_INSTRUCTION_START(OR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001913 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001914 shadow_frame.GetVRegLong(inst->VRegB_23x()) |
1915 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1916 ADVANCE(2);
1917 HANDLE_INSTRUCTION_END();
1918
1919 HANDLE_INSTRUCTION_START(XOR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001920 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001921 shadow_frame.GetVRegLong(inst->VRegB_23x()) ^
1922 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1923 ADVANCE(2);
1924 HANDLE_INSTRUCTION_END();
1925
1926 HANDLE_INSTRUCTION_START(SHL_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001927 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001928 shadow_frame.GetVRegLong(inst->VRegB_23x()) <<
1929 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1930 ADVANCE(2);
1931 HANDLE_INSTRUCTION_END();
1932
1933 HANDLE_INSTRUCTION_START(SHR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001934 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001935 shadow_frame.GetVRegLong(inst->VRegB_23x()) >>
1936 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1937 ADVANCE(2);
1938 HANDLE_INSTRUCTION_END();
1939
1940 HANDLE_INSTRUCTION_START(USHR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001941 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001942 static_cast<uint64_t>(shadow_frame.GetVRegLong(inst->VRegB_23x())) >>
1943 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1944 ADVANCE(2);
1945 HANDLE_INSTRUCTION_END();
1946
1947 HANDLE_INSTRUCTION_START(ADD_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001948 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001949 shadow_frame.GetVRegFloat(inst->VRegB_23x()) +
1950 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1951 ADVANCE(2);
1952 HANDLE_INSTRUCTION_END();
1953
1954 HANDLE_INSTRUCTION_START(SUB_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001955 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001956 shadow_frame.GetVRegFloat(inst->VRegB_23x()) -
1957 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1958 ADVANCE(2);
1959 HANDLE_INSTRUCTION_END();
1960
1961 HANDLE_INSTRUCTION_START(MUL_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001962 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001963 shadow_frame.GetVRegFloat(inst->VRegB_23x()) *
1964 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1965 ADVANCE(2);
1966 HANDLE_INSTRUCTION_END();
1967
1968 HANDLE_INSTRUCTION_START(DIV_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001969 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001970 shadow_frame.GetVRegFloat(inst->VRegB_23x()) /
1971 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1972 ADVANCE(2);
1973 HANDLE_INSTRUCTION_END();
1974
1975 HANDLE_INSTRUCTION_START(REM_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001976 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001977 fmodf(shadow_frame.GetVRegFloat(inst->VRegB_23x()),
1978 shadow_frame.GetVRegFloat(inst->VRegC_23x())));
1979 ADVANCE(2);
1980 HANDLE_INSTRUCTION_END();
1981
1982 HANDLE_INSTRUCTION_START(ADD_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001983 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001984 shadow_frame.GetVRegDouble(inst->VRegB_23x()) +
1985 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1986 ADVANCE(2);
1987 HANDLE_INSTRUCTION_END();
1988
1989 HANDLE_INSTRUCTION_START(SUB_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001990 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001991 shadow_frame.GetVRegDouble(inst->VRegB_23x()) -
1992 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1993 ADVANCE(2);
1994 HANDLE_INSTRUCTION_END();
1995
1996 HANDLE_INSTRUCTION_START(MUL_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001997 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001998 shadow_frame.GetVRegDouble(inst->VRegB_23x()) *
1999 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
2000 ADVANCE(2);
2001 HANDLE_INSTRUCTION_END();
2002
2003 HANDLE_INSTRUCTION_START(DIV_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002004 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002005 shadow_frame.GetVRegDouble(inst->VRegB_23x()) /
2006 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
2007 ADVANCE(2);
2008 HANDLE_INSTRUCTION_END();
2009
2010 HANDLE_INSTRUCTION_START(REM_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002011 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002012 fmod(shadow_frame.GetVRegDouble(inst->VRegB_23x()),
2013 shadow_frame.GetVRegDouble(inst->VRegC_23x())));
2014 ADVANCE(2);
2015 HANDLE_INSTRUCTION_END();
2016
2017 HANDLE_INSTRUCTION_START(ADD_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002018 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002019 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002020 SafeAdd(shadow_frame.GetVReg(vregA),
2021 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002022 ADVANCE(1);
2023 }
2024 HANDLE_INSTRUCTION_END();
2025
2026 HANDLE_INSTRUCTION_START(SUB_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002027 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002028 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002029 SafeSub(shadow_frame.GetVReg(vregA),
2030 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002031 ADVANCE(1);
2032 }
2033 HANDLE_INSTRUCTION_END();
2034
2035 HANDLE_INSTRUCTION_START(MUL_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002036 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002037 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002038 SafeMul(shadow_frame.GetVReg(vregA),
2039 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002040 ADVANCE(1);
2041 }
2042 HANDLE_INSTRUCTION_END();
2043
2044 HANDLE_INSTRUCTION_START(DIV_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002045 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002046 bool success = DoIntDivide(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002047 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002048 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2049 }
2050 HANDLE_INSTRUCTION_END();
2051
2052 HANDLE_INSTRUCTION_START(REM_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002053 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002054 bool success = DoIntRemainder(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002055 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002056 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2057 }
2058 HANDLE_INSTRUCTION_END();
2059
2060 HANDLE_INSTRUCTION_START(SHL_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002061 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002062 shadow_frame.SetVReg(vregA,
2063 shadow_frame.GetVReg(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002064 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002065 ADVANCE(1);
2066 }
2067 HANDLE_INSTRUCTION_END();
2068
2069 HANDLE_INSTRUCTION_START(SHR_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002070 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002071 shadow_frame.SetVReg(vregA,
2072 shadow_frame.GetVReg(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002073 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002074 ADVANCE(1);
2075 }
2076 HANDLE_INSTRUCTION_END();
2077
2078 HANDLE_INSTRUCTION_START(USHR_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002079 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002080 shadow_frame.SetVReg(vregA,
2081 static_cast<uint32_t>(shadow_frame.GetVReg(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002082 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002083 ADVANCE(1);
2084 }
2085 HANDLE_INSTRUCTION_END();
2086
2087 HANDLE_INSTRUCTION_START(AND_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002088 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002089 shadow_frame.SetVReg(vregA,
2090 shadow_frame.GetVReg(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002091 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002092 ADVANCE(1);
2093 }
2094 HANDLE_INSTRUCTION_END();
2095
2096 HANDLE_INSTRUCTION_START(OR_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002097 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002098 shadow_frame.SetVReg(vregA,
2099 shadow_frame.GetVReg(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002100 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002101 ADVANCE(1);
2102 }
2103 HANDLE_INSTRUCTION_END();
2104
2105 HANDLE_INSTRUCTION_START(XOR_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002106 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002107 shadow_frame.SetVReg(vregA,
2108 shadow_frame.GetVReg(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002109 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002110 ADVANCE(1);
2111 }
2112 HANDLE_INSTRUCTION_END();
2113
2114 HANDLE_INSTRUCTION_START(ADD_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002115 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002116 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002117 SafeAdd(shadow_frame.GetVRegLong(vregA),
2118 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002119 ADVANCE(1);
2120 }
2121 HANDLE_INSTRUCTION_END();
2122
2123 HANDLE_INSTRUCTION_START(SUB_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002124 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002125 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002126 SafeSub(shadow_frame.GetVRegLong(vregA),
2127 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002128 ADVANCE(1);
2129 }
2130 HANDLE_INSTRUCTION_END();
2131
2132 HANDLE_INSTRUCTION_START(MUL_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002133 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002134 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002135 SafeMul(shadow_frame.GetVRegLong(vregA),
2136 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002137 ADVANCE(1);
2138 }
2139 HANDLE_INSTRUCTION_END();
2140
2141 HANDLE_INSTRUCTION_START(DIV_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002142 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002143 bool success = DoLongDivide(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002144 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002145 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2146 }
2147 HANDLE_INSTRUCTION_END();
2148
2149 HANDLE_INSTRUCTION_START(REM_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002150 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002151 bool success = DoLongRemainder(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002152 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002153 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2154 }
2155 HANDLE_INSTRUCTION_END();
2156
2157 HANDLE_INSTRUCTION_START(AND_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002158 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002159 shadow_frame.SetVRegLong(vregA,
2160 shadow_frame.GetVRegLong(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002161 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002162 ADVANCE(1);
2163 }
2164 HANDLE_INSTRUCTION_END();
2165
2166 HANDLE_INSTRUCTION_START(OR_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002167 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002168 shadow_frame.SetVRegLong(vregA,
2169 shadow_frame.GetVRegLong(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002170 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002171 ADVANCE(1);
2172 }
2173 HANDLE_INSTRUCTION_END();
2174
2175 HANDLE_INSTRUCTION_START(XOR_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002176 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002177 shadow_frame.SetVRegLong(vregA,
2178 shadow_frame.GetVRegLong(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002179 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002180 ADVANCE(1);
2181 }
2182 HANDLE_INSTRUCTION_END();
2183
2184 HANDLE_INSTRUCTION_START(SHL_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002185 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002186 shadow_frame.SetVRegLong(vregA,
2187 shadow_frame.GetVRegLong(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002188 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002189 ADVANCE(1);
2190 }
2191 HANDLE_INSTRUCTION_END();
2192
2193 HANDLE_INSTRUCTION_START(SHR_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002194 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002195 shadow_frame.SetVRegLong(vregA,
2196 shadow_frame.GetVRegLong(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002197 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002198 ADVANCE(1);
2199 }
2200 HANDLE_INSTRUCTION_END();
2201
2202 HANDLE_INSTRUCTION_START(USHR_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002203 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002204 shadow_frame.SetVRegLong(vregA,
2205 static_cast<uint64_t>(shadow_frame.GetVRegLong(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002206 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002207 ADVANCE(1);
2208 }
2209 HANDLE_INSTRUCTION_END();
2210
2211 HANDLE_INSTRUCTION_START(ADD_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002212 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002213 shadow_frame.SetVRegFloat(vregA,
2214 shadow_frame.GetVRegFloat(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002215 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002216 ADVANCE(1);
2217 }
2218 HANDLE_INSTRUCTION_END();
2219
2220 HANDLE_INSTRUCTION_START(SUB_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002221 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002222 shadow_frame.SetVRegFloat(vregA,
2223 shadow_frame.GetVRegFloat(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002224 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002225 ADVANCE(1);
2226 }
2227 HANDLE_INSTRUCTION_END();
2228
2229 HANDLE_INSTRUCTION_START(MUL_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002230 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002231 shadow_frame.SetVRegFloat(vregA,
2232 shadow_frame.GetVRegFloat(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002233 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002234 ADVANCE(1);
2235 }
2236 HANDLE_INSTRUCTION_END();
2237
2238 HANDLE_INSTRUCTION_START(DIV_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002239 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002240 shadow_frame.SetVRegFloat(vregA,
2241 shadow_frame.GetVRegFloat(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002242 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002243 ADVANCE(1);
2244 }
2245 HANDLE_INSTRUCTION_END();
2246
2247 HANDLE_INSTRUCTION_START(REM_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002248 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002249 shadow_frame.SetVRegFloat(vregA,
2250 fmodf(shadow_frame.GetVRegFloat(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002251 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002252 ADVANCE(1);
2253 }
2254 HANDLE_INSTRUCTION_END();
2255
2256 HANDLE_INSTRUCTION_START(ADD_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002257 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002258 shadow_frame.SetVRegDouble(vregA,
2259 shadow_frame.GetVRegDouble(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002260 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002261 ADVANCE(1);
2262 }
2263 HANDLE_INSTRUCTION_END();
2264
2265 HANDLE_INSTRUCTION_START(SUB_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002266 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002267 shadow_frame.SetVRegDouble(vregA,
2268 shadow_frame.GetVRegDouble(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002269 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002270 ADVANCE(1);
2271 }
2272 HANDLE_INSTRUCTION_END();
2273
2274 HANDLE_INSTRUCTION_START(MUL_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002275 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002276 shadow_frame.SetVRegDouble(vregA,
2277 shadow_frame.GetVRegDouble(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002278 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002279 ADVANCE(1);
2280 }
2281 HANDLE_INSTRUCTION_END();
2282
2283 HANDLE_INSTRUCTION_START(DIV_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002284 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002285 shadow_frame.SetVRegDouble(vregA,
2286 shadow_frame.GetVRegDouble(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002287 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002288 ADVANCE(1);
2289 }
2290 HANDLE_INSTRUCTION_END();
2291
2292 HANDLE_INSTRUCTION_START(REM_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002293 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002294 shadow_frame.SetVRegDouble(vregA,
2295 fmod(shadow_frame.GetVRegDouble(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002296 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002297 ADVANCE(1);
2298 }
2299 HANDLE_INSTRUCTION_END();
2300
2301 HANDLE_INSTRUCTION_START(ADD_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002302 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002303 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2304 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002305 ADVANCE(2);
2306 HANDLE_INSTRUCTION_END();
2307
2308 HANDLE_INSTRUCTION_START(RSUB_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002309 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002310 SafeSub(inst->VRegC_22s(),
2311 shadow_frame.GetVReg(inst->VRegB_22s(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002312 ADVANCE(2);
2313 HANDLE_INSTRUCTION_END();
2314
2315 HANDLE_INSTRUCTION_START(MUL_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002316 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002317 SafeMul(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2318 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002319 ADVANCE(2);
2320 HANDLE_INSTRUCTION_END();
2321
2322 HANDLE_INSTRUCTION_START(DIV_INT_LIT16) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002323 bool success = DoIntDivide(
2324 shadow_frame, inst->VRegA_22s(inst_data), shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2325 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002326 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2327 }
2328 HANDLE_INSTRUCTION_END();
2329
2330 HANDLE_INSTRUCTION_START(REM_INT_LIT16) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002331 bool success = DoIntRemainder(
2332 shadow_frame, inst->VRegA_22s(inst_data), shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2333 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002334 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2335 }
2336 HANDLE_INSTRUCTION_END();
2337
2338 HANDLE_INSTRUCTION_START(AND_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002339 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2340 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) &
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002341 inst->VRegC_22s());
2342 ADVANCE(2);
2343 HANDLE_INSTRUCTION_END();
2344
2345 HANDLE_INSTRUCTION_START(OR_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002346 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2347 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) |
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002348 inst->VRegC_22s());
2349 ADVANCE(2);
2350 HANDLE_INSTRUCTION_END();
2351
2352 HANDLE_INSTRUCTION_START(XOR_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002353 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2354 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) ^
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002355 inst->VRegC_22s());
2356 ADVANCE(2);
2357 HANDLE_INSTRUCTION_END();
2358
2359 HANDLE_INSTRUCTION_START(ADD_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002360 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002361 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22b()),
2362 inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002363 ADVANCE(2);
2364 HANDLE_INSTRUCTION_END();
2365
2366 HANDLE_INSTRUCTION_START(RSUB_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002367 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002368 SafeSub(inst->VRegC_22b(),
2369 shadow_frame.GetVReg(inst->VRegB_22b())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002370 ADVANCE(2);
2371 HANDLE_INSTRUCTION_END();
2372
2373 HANDLE_INSTRUCTION_START(MUL_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002374 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002375 SafeMul(shadow_frame.GetVReg(inst->VRegB_22b()),
2376 inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002377 ADVANCE(2);
2378 HANDLE_INSTRUCTION_END();
2379
2380 HANDLE_INSTRUCTION_START(DIV_INT_LIT8) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002381 bool success = DoIntDivide(shadow_frame, inst->VRegA_22b(inst_data),
2382 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002383 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2384 }
2385 HANDLE_INSTRUCTION_END();
2386
2387 HANDLE_INSTRUCTION_START(REM_INT_LIT8) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002388 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22b(inst_data),
2389 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002390 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2391 }
2392 HANDLE_INSTRUCTION_END();
2393
2394 HANDLE_INSTRUCTION_START(AND_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002395 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002396 shadow_frame.GetVReg(inst->VRegB_22b()) &
2397 inst->VRegC_22b());
2398 ADVANCE(2);
2399 HANDLE_INSTRUCTION_END();
2400
2401 HANDLE_INSTRUCTION_START(OR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002402 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002403 shadow_frame.GetVReg(inst->VRegB_22b()) |
2404 inst->VRegC_22b());
2405 ADVANCE(2);
2406 HANDLE_INSTRUCTION_END();
2407
2408 HANDLE_INSTRUCTION_START(XOR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002409 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002410 shadow_frame.GetVReg(inst->VRegB_22b()) ^
2411 inst->VRegC_22b());
2412 ADVANCE(2);
2413 HANDLE_INSTRUCTION_END();
2414
2415 HANDLE_INSTRUCTION_START(SHL_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002416 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002417 shadow_frame.GetVReg(inst->VRegB_22b()) <<
2418 (inst->VRegC_22b() & 0x1f));
2419 ADVANCE(2);
2420 HANDLE_INSTRUCTION_END();
2421
2422 HANDLE_INSTRUCTION_START(SHR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002423 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002424 shadow_frame.GetVReg(inst->VRegB_22b()) >>
2425 (inst->VRegC_22b() & 0x1f));
2426 ADVANCE(2);
2427 HANDLE_INSTRUCTION_END();
2428
2429 HANDLE_INSTRUCTION_START(USHR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002430 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002431 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_22b())) >>
2432 (inst->VRegC_22b() & 0x1f));
2433 ADVANCE(2);
2434 HANDLE_INSTRUCTION_END();
2435
2436 HANDLE_INSTRUCTION_START(UNUSED_3E)
Ian Rogerse94652f2014-12-02 11:13:19 -08002437 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002438 HANDLE_INSTRUCTION_END();
2439
2440 HANDLE_INSTRUCTION_START(UNUSED_3F)
Ian Rogerse94652f2014-12-02 11:13:19 -08002441 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002442 HANDLE_INSTRUCTION_END();
2443
2444 HANDLE_INSTRUCTION_START(UNUSED_40)
Ian Rogerse94652f2014-12-02 11:13:19 -08002445 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002446 HANDLE_INSTRUCTION_END();
2447
2448 HANDLE_INSTRUCTION_START(UNUSED_41)
Ian Rogerse94652f2014-12-02 11:13:19 -08002449 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002450 HANDLE_INSTRUCTION_END();
2451
2452 HANDLE_INSTRUCTION_START(UNUSED_42)
Ian Rogerse94652f2014-12-02 11:13:19 -08002453 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002454 HANDLE_INSTRUCTION_END();
2455
2456 HANDLE_INSTRUCTION_START(UNUSED_43)
Ian Rogerse94652f2014-12-02 11:13:19 -08002457 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002458 HANDLE_INSTRUCTION_END();
2459
2460 HANDLE_INSTRUCTION_START(UNUSED_79)
Ian Rogerse94652f2014-12-02 11:13:19 -08002461 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002462 HANDLE_INSTRUCTION_END();
2463
2464 HANDLE_INSTRUCTION_START(UNUSED_7A)
Ian Rogerse94652f2014-12-02 11:13:19 -08002465 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002466 HANDLE_INSTRUCTION_END();
2467
Narayan Kamath14832ef2016-08-05 11:44:32 +01002468 HANDLE_INSTRUCTION_START(UNUSED_F3)
2469 UnexpectedOpcode(inst, shadow_frame);
2470 HANDLE_INSTRUCTION_END();
2471
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002472 HANDLE_INSTRUCTION_START(UNUSED_F4)
Ian Rogerse94652f2014-12-02 11:13:19 -08002473 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002474 HANDLE_INSTRUCTION_END();
2475
Narayan Kamath14832ef2016-08-05 11:44:32 +01002476 HANDLE_INSTRUCTION_START(UNUSED_F5)
2477 UnexpectedOpcode(inst, shadow_frame);
2478 HANDLE_INSTRUCTION_END();
2479
2480 HANDLE_INSTRUCTION_START(UNUSED_F6)
2481 UnexpectedOpcode(inst, shadow_frame);
2482 HANDLE_INSTRUCTION_END();
2483
2484 HANDLE_INSTRUCTION_START(UNUSED_F7)
2485 UnexpectedOpcode(inst, shadow_frame);
2486 HANDLE_INSTRUCTION_END();
2487
2488 HANDLE_INSTRUCTION_START(UNUSED_F8)
2489 UnexpectedOpcode(inst, shadow_frame);
2490 HANDLE_INSTRUCTION_END();
2491
2492 HANDLE_INSTRUCTION_START(UNUSED_F9)
2493 UnexpectedOpcode(inst, shadow_frame);
2494 HANDLE_INSTRUCTION_END();
2495
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002496 HANDLE_INSTRUCTION_START(UNUSED_FA)
Ian Rogerse94652f2014-12-02 11:13:19 -08002497 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002498 HANDLE_INSTRUCTION_END();
2499
2500 HANDLE_INSTRUCTION_START(UNUSED_FB)
Ian Rogerse94652f2014-12-02 11:13:19 -08002501 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002502 HANDLE_INSTRUCTION_END();
2503
2504 HANDLE_INSTRUCTION_START(UNUSED_FC)
Ian Rogerse94652f2014-12-02 11:13:19 -08002505 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002506 HANDLE_INSTRUCTION_END();
2507
2508 HANDLE_INSTRUCTION_START(UNUSED_FD)
Ian Rogerse94652f2014-12-02 11:13:19 -08002509 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002510 HANDLE_INSTRUCTION_END();
2511
2512 HANDLE_INSTRUCTION_START(UNUSED_FE)
Ian Rogerse94652f2014-12-02 11:13:19 -08002513 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002514 HANDLE_INSTRUCTION_END();
2515
2516 HANDLE_INSTRUCTION_START(UNUSED_FF)
Ian Rogerse94652f2014-12-02 11:13:19 -08002517 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002518 HANDLE_INSTRUCTION_END();
2519
2520 exception_pending_label: {
2521 CHECK(self->IsExceptionPending());
Sebastien Hertz1eda2262013-09-09 16:53:14 +02002522 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -07002523 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +02002524 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +02002525 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002526 uint32_t found_dex_pc = FindNextInstructionFollowingException(self, shadow_frame, dex_pc,
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002527 instrumentation);
2528 if (found_dex_pc == DexFile::kDexNoIndex) {
Andreas Gampe03ec9302015-08-27 17:41:47 -07002529 // Structured locking is to be enforced for abnormal termination, too.
Andreas Gampe56fdd0e2016-04-28 14:56:54 -07002530 DoMonitorCheckOnExit<do_assignability_check>(self, &shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002531 return JValue(); /* Handled in caller. */
2532 } else {
2533 int32_t displacement = static_cast<int32_t>(found_dex_pc) - static_cast<int32_t>(dex_pc);
2534 ADVANCE(displacement);
2535 }
2536 }
2537
Sebastien Hertz8379b222014-02-24 17:38:15 +01002538// Create alternative instruction handlers dedicated to instrumentation.
2539// Return instructions must not call Instrumentation::DexPcMovedEvent since they already call
2540// Instrumentation::MethodExited. This is to avoid posting debugger events twice for this location.
Sebastien Hertze713d932014-05-15 10:48:53 +02002541// Note: we do not use the kReturn instruction flag here (to test the instruction is a return). The
2542// compiler seems to not evaluate "(Instruction::FlagsOf(Instruction::code) & kReturn) != 0" to
2543// a constant condition that would remove the "if" statement so the test is free.
Narayan Kamathbd48b342016-08-01 17:32:37 +01002544#define INSTRUMENTATION_INSTRUCTION_HANDLER(o, code, n, f, i, a, v) \
Sebastien Hertz9d6bf692015-04-10 12:12:33 +02002545 alt_op_##code: { \
Sebastien Hertz9d6bf692015-04-10 12:12:33 +02002546 if (UNLIKELY(instrumentation->HasDexPcListeners())) { \
2547 Object* this_object = shadow_frame.GetThisObject(code_item->ins_size_); \
2548 instrumentation->DexPcMovedEvent(self, this_object, shadow_frame.GetMethod(), dex_pc); \
2549 } \
2550 UPDATE_HANDLER_TABLE(); \
2551 goto *handlersTable[instrumentation::kMainHandlerTable][Instruction::code]; \
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002552 }
2553#include "dex_instruction_list.h"
2554 DEX_INSTRUCTION_LIST(INSTRUMENTATION_INSTRUCTION_HANDLER)
2555#undef DEX_INSTRUCTION_LIST
2556#undef INSTRUMENTATION_INSTRUCTION_HANDLER
2557} // NOLINT(readability/fn_size)
2558
2559// Explicit definitions of ExecuteGotoImpl.
Mathieu Chartier90443472015-07-16 20:32:27 -07002560template SHARED_REQUIRES(Locks::mutator_lock_) HOT_ATTR
Ian Rogerse94652f2014-12-02 11:13:19 -08002561JValue ExecuteGotoImpl<true, false>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002562 ShadowFrame& shadow_frame, JValue result_register);
Mathieu Chartier90443472015-07-16 20:32:27 -07002563template SHARED_REQUIRES(Locks::mutator_lock_) HOT_ATTR
Ian Rogerse94652f2014-12-02 11:13:19 -08002564JValue ExecuteGotoImpl<false, false>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002565 ShadowFrame& shadow_frame, JValue result_register);
Mathieu Chartier90443472015-07-16 20:32:27 -07002566template SHARED_REQUIRES(Locks::mutator_lock_)
Ian Rogerse94652f2014-12-02 11:13:19 -08002567JValue ExecuteGotoImpl<true, true>(Thread* self, const DexFile::CodeItem* code_item,
2568 ShadowFrame& shadow_frame, JValue result_register);
Mathieu Chartier90443472015-07-16 20:32:27 -07002569template SHARED_REQUIRES(Locks::mutator_lock_)
Ian Rogerse94652f2014-12-02 11:13:19 -08002570JValue ExecuteGotoImpl<false, true>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002571 ShadowFrame& shadow_frame, JValue result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002572
2573} // namespace interpreter
2574} // namespace art
Colin Crosse84e4f72015-03-18 14:01:19 -07002575
2576#endif