blob: 86027c542f9653b9d3e24a52f897b7eb731d7622 [file] [log] [blame]
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Colin Crosse84e4f72015-03-18 14:01:19 -070017#if !defined(__clang__)
18// Clang 3.4 fails to build the goto interpreter implementation.
19
Sebastien Hertz8ece0502013-08-07 11:26:41 +020020#include "interpreter_common.h"
Ian Rogersf72a11d2014-10-30 15:41:08 -070021#include "safe_math.h"
Sebastien Hertz8ece0502013-08-07 11:26:41 +020022
23namespace art {
24namespace interpreter {
25
26// In the following macros, we expect the following local variables exist:
27// - "self": the current Thread*.
28// - "inst" : the current Instruction*.
Sebastien Hertz3b588e02013-09-11 14:33:18 +020029// - "inst_data" : the current instruction's first 16 bits.
Sebastien Hertz8ece0502013-08-07 11:26:41 +020030// - "dex_pc": the current pc.
31// - "shadow_frame": the current shadow frame.
Sebastien Hertz8ece0502013-08-07 11:26:41 +020032// - "currentHandlersTable": the current table of pointer to each instruction handler.
33
34// Advance to the next instruction and updates interpreter state.
Sebastien Hertz8ece0502013-08-07 11:26:41 +020035#define ADVANCE(_offset) \
36 do { \
37 int32_t disp = static_cast<int32_t>(_offset); \
38 inst = inst->RelativeAt(disp); \
39 dex_pc = static_cast<uint32_t>(static_cast<int32_t>(dex_pc) + disp); \
40 shadow_frame.SetDexPC(dex_pc); \
Ian Rogerse94652f2014-12-02 11:13:19 -080041 TraceExecution(shadow_frame, inst, dex_pc); \
Sebastien Hertz3b588e02013-09-11 14:33:18 +020042 inst_data = inst->Fetch16(0); \
43 goto *currentHandlersTable[inst->Opcode(inst_data)]; \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020044 } while (false)
45
46#define HANDLE_PENDING_EXCEPTION() goto exception_pending_label
47
48#define POSSIBLY_HANDLE_PENDING_EXCEPTION(_is_exception_pending, _offset) \
49 do { \
50 if (UNLIKELY(_is_exception_pending)) { \
51 HANDLE_PENDING_EXCEPTION(); \
52 } else { \
53 ADVANCE(_offset); \
54 } \
55 } while (false)
56
Sebastien Hertzee1997a2013-09-19 14:47:09 +020057#define UPDATE_HANDLER_TABLE() \
Mathieu Chartier2cebb242015-04-21 16:50:40 -070058 currentHandlersTable = handlersTable[ \
59 Runtime::Current()->GetInstrumentation()->GetInterpreterHandlerTable()]
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +020060
Mathieu Chartiere5f13e52015-02-24 09:37:21 -080061#define BACKWARD_BRANCH_INSTRUMENTATION(offset) \
62 do { \
63 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation(); \
64 instrumentation->BackwardBranch(self, shadow_frame.GetMethod(), offset); \
65 } while (false)
66
Sebastien Hertz8ece0502013-08-07 11:26:41 +020067#define UNREACHABLE_CODE_CHECK() \
68 do { \
69 if (kIsDebugBuild) { \
70 LOG(FATAL) << "We should not be here !"; \
Ian Rogerse94652f2014-12-02 11:13:19 -080071 UNREACHABLE(); \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020072 } \
73 } while (false)
74
75#define HANDLE_INSTRUCTION_START(opcode) op_##opcode: // NOLINT(whitespace/labels)
76#define HANDLE_INSTRUCTION_END() UNREACHABLE_CODE_CHECK()
77
Sebastien Hertzee1997a2013-09-19 14:47:09 +020078/**
79 * Interpreter based on computed goto tables.
80 *
81 * Each instruction is associated to a handler. This handler is responsible for executing the
82 * instruction and jump to the next instruction's handler.
83 * In order to limit the cost of instrumentation, we have two handler tables:
84 * - the "main" handler table: it contains handlers for normal execution of each instruction without
85 * handling of instrumentation.
86 * - the "alternative" handler table: it contains alternative handlers which first handle
87 * instrumentation before jumping to the corresponding "normal" instruction's handler.
88 *
89 * When instrumentation is active, the interpreter uses the "alternative" handler table. Otherwise
90 * it uses the "main" handler table.
91 *
92 * The current handler table is the handler table being used by the interpreter. It is updated:
93 * - on backward branch (goto, if and switch instructions)
94 * - after invoke
95 * - when an exception is thrown.
96 * This allows to support an attaching debugger to an already running application for instance.
97 *
98 * For a fast handler table update, handler tables are stored in an array of handler tables. Each
99 * handler table is represented by the InterpreterHandlerTable enum which allows to associate it
100 * to an index in this array of handler tables ((see Instrumentation::GetInterpreterHandlerTable).
101 *
102 * Here's the current layout of this array of handler tables:
103 *
104 * ---------------------+---------------+
105 * | NOP | (handler for NOP instruction)
106 * +---------------+
107 * "main" | MOVE | (handler for MOVE instruction)
108 * handler table +---------------+
109 * | ... |
110 * +---------------+
111 * | UNUSED_FF | (handler for UNUSED_FF instruction)
112 * ---------------------+---------------+
113 * | NOP | (alternative handler for NOP instruction)
114 * +---------------+
115 * "alternative" | MOVE | (alternative handler for MOVE instruction)
116 * handler table +---------------+
117 * | ... |
118 * +---------------+
119 * | UNUSED_FF | (alternative handler for UNUSED_FF instruction)
120 * ---------------------+---------------+
121 *
122 */
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100123template<bool do_access_check, bool transaction_active>
Ian Rogerse94652f2014-12-02 11:13:19 -0800124JValue ExecuteGotoImpl(Thread* self, const DexFile::CodeItem* code_item, ShadowFrame& shadow_frame,
125 JValue result_register) {
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200126 // Define handler tables:
127 // - The main handler table contains execution handlers for each instruction.
128 // - The alternative handler table contains prelude handlers which check for thread suspend and
129 // manage instrumentation before jumping to the execution handler.
130 static const void* const handlersTable[instrumentation::kNumHandlerTables][kNumPackedOpcodes] = {
131 {
132 // Main handler table.
133#define INSTRUCTION_HANDLER(o, code, n, f, r, i, a, v) &&op_##code,
134#include "dex_instruction_list.h"
135 DEX_INSTRUCTION_LIST(INSTRUCTION_HANDLER)
136#undef DEX_INSTRUCTION_LIST
137#undef INSTRUCTION_HANDLER
138 }, {
139 // Alternative handler table.
140#define INSTRUCTION_HANDLER(o, code, n, f, r, i, a, v) &&alt_op_##code,
141#include "dex_instruction_list.h"
142 DEX_INSTRUCTION_LIST(INSTRUCTION_HANDLER)
143#undef DEX_INSTRUCTION_LIST
144#undef INSTRUCTION_HANDLER
145 }
146 };
147
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800148 constexpr bool do_assignability_check = do_access_check;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200149 if (UNLIKELY(!shadow_frame.HasReferenceArray())) {
150 LOG(FATAL) << "Invalid shadow frame for interpreter use";
151 return JValue();
152 }
153 self->VerifyStack();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200154
155 uint32_t dex_pc = shadow_frame.GetDexPC();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200156 const Instruction* inst = Instruction::At(code_item->insns_ + dex_pc);
157 uint16_t inst_data;
158 const void* const* currentHandlersTable;
159 UPDATE_HANDLER_TABLE();
Sebastien Hertz270a0e12015-01-16 19:49:09 +0100160 if (LIKELY(dex_pc == 0)) { // We are entering the method as opposed to deoptimizing.
161 if (kIsDebugBuild) {
162 self->AssertNoPendingException();
163 }
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200164 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200165 if (UNLIKELY(instrumentation->HasMethodEntryListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200166 instrumentation->MethodEnterEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200167 shadow_frame.GetMethod(), 0);
168 }
169 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200170
171 // Jump to first instruction.
172 ADVANCE(0);
173 UNREACHABLE_CODE_CHECK();
174
175 HANDLE_INSTRUCTION_START(NOP)
176 ADVANCE(1);
177 HANDLE_INSTRUCTION_END();
178
179 HANDLE_INSTRUCTION_START(MOVE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200180 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
181 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200182 ADVANCE(1);
183 HANDLE_INSTRUCTION_END();
184
185 HANDLE_INSTRUCTION_START(MOVE_FROM16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200186 shadow_frame.SetVReg(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200187 shadow_frame.GetVReg(inst->VRegB_22x()));
188 ADVANCE(2);
189 HANDLE_INSTRUCTION_END();
190
191 HANDLE_INSTRUCTION_START(MOVE_16)
192 shadow_frame.SetVReg(inst->VRegA_32x(),
193 shadow_frame.GetVReg(inst->VRegB_32x()));
194 ADVANCE(3);
195 HANDLE_INSTRUCTION_END();
196
197 HANDLE_INSTRUCTION_START(MOVE_WIDE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200198 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
199 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200200 ADVANCE(1);
201 HANDLE_INSTRUCTION_END();
202
203 HANDLE_INSTRUCTION_START(MOVE_WIDE_FROM16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200204 shadow_frame.SetVRegLong(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200205 shadow_frame.GetVRegLong(inst->VRegB_22x()));
206 ADVANCE(2);
207 HANDLE_INSTRUCTION_END();
208
209 HANDLE_INSTRUCTION_START(MOVE_WIDE_16)
210 shadow_frame.SetVRegLong(inst->VRegA_32x(),
211 shadow_frame.GetVRegLong(inst->VRegB_32x()));
212 ADVANCE(3);
213 HANDLE_INSTRUCTION_END();
214
215 HANDLE_INSTRUCTION_START(MOVE_OBJECT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200216 shadow_frame.SetVRegReference(inst->VRegA_12x(inst_data),
217 shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200218 ADVANCE(1);
219 HANDLE_INSTRUCTION_END();
220
221 HANDLE_INSTRUCTION_START(MOVE_OBJECT_FROM16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200222 shadow_frame.SetVRegReference(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200223 shadow_frame.GetVRegReference(inst->VRegB_22x()));
224 ADVANCE(2);
225 HANDLE_INSTRUCTION_END();
226
227 HANDLE_INSTRUCTION_START(MOVE_OBJECT_16)
228 shadow_frame.SetVRegReference(inst->VRegA_32x(),
229 shadow_frame.GetVRegReference(inst->VRegB_32x()));
230 ADVANCE(3);
231 HANDLE_INSTRUCTION_END();
232
233 HANDLE_INSTRUCTION_START(MOVE_RESULT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200234 shadow_frame.SetVReg(inst->VRegA_11x(inst_data), result_register.GetI());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200235 ADVANCE(1);
236 HANDLE_INSTRUCTION_END();
237
238 HANDLE_INSTRUCTION_START(MOVE_RESULT_WIDE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200239 shadow_frame.SetVRegLong(inst->VRegA_11x(inst_data), result_register.GetJ());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200240 ADVANCE(1);
241 HANDLE_INSTRUCTION_END();
242
243 HANDLE_INSTRUCTION_START(MOVE_RESULT_OBJECT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200244 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), result_register.GetL());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200245 ADVANCE(1);
246 HANDLE_INSTRUCTION_END();
247
248 HANDLE_INSTRUCTION_START(MOVE_EXCEPTION) {
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000249 Throwable* exception = self->GetException();
Sebastien Hertz270a0e12015-01-16 19:49:09 +0100250 DCHECK(exception != nullptr) << "No pending exception on MOVE_EXCEPTION instruction";
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200251 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), exception);
Sebastien Hertz5c004902014-05-21 10:07:42 +0200252 self->ClearException();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200253 ADVANCE(1);
254 }
255 HANDLE_INSTRUCTION_END();
256
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700257 HANDLE_INSTRUCTION_START(RETURN_VOID_NO_BARRIER) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200258 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700259 self->AllowThreadSuspension();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200260 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200261 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200262 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200263 shadow_frame.GetMethod(), dex_pc,
264 result);
265 }
266 return result;
267 }
268 HANDLE_INSTRUCTION_END();
269
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700270 HANDLE_INSTRUCTION_START(RETURN_VOID) {
Hans Boehm30359612014-05-21 17:46:23 -0700271 QuasiAtomic::ThreadFenceForConstructor();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200272 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700273 self->AllowThreadSuspension();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200274 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200275 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200276 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200277 shadow_frame.GetMethod(), dex_pc,
278 result);
279 }
280 return result;
281 }
282 HANDLE_INSTRUCTION_END();
283
284 HANDLE_INSTRUCTION_START(RETURN) {
285 JValue result;
286 result.SetJ(0);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200287 result.SetI(shadow_frame.GetVReg(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700288 self->AllowThreadSuspension();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200289 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200290 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200291 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200292 shadow_frame.GetMethod(), dex_pc,
293 result);
294 }
295 return result;
296 }
297 HANDLE_INSTRUCTION_END();
298
299 HANDLE_INSTRUCTION_START(RETURN_WIDE) {
300 JValue result;
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200301 result.SetJ(shadow_frame.GetVRegLong(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700302 self->AllowThreadSuspension();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200303 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200304 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200305 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200306 shadow_frame.GetMethod(), dex_pc,
307 result);
308 }
309 return result;
310 }
311 HANDLE_INSTRUCTION_END();
312
313 HANDLE_INSTRUCTION_START(RETURN_OBJECT) {
314 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700315 self->AllowThreadSuspension();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700316 const uint8_t vreg_index = inst->VRegA_11x(inst_data);
317 Object* obj_result = shadow_frame.GetVRegReference(vreg_index);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700318 if (do_assignability_check && obj_result != nullptr) {
Ian Rogersded66a02014-10-28 18:12:55 -0700319 Class* return_type = shadow_frame.GetMethod()->GetReturnType();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700320 obj_result = shadow_frame.GetVRegReference(vreg_index);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700321 if (return_type == nullptr) {
Jeff Haoa3faaf42013-09-03 19:07:00 -0700322 // Return the pending exception.
323 HANDLE_PENDING_EXCEPTION();
324 }
325 if (!obj_result->VerifierInstanceOf(return_type)) {
326 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700327 std::string temp1, temp2;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000328 self->ThrowNewExceptionF("Ljava/lang/VirtualMachineError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700329 "Returning '%s' that is not instance of return type '%s'",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700330 obj_result->GetClass()->GetDescriptor(&temp1),
331 return_type->GetDescriptor(&temp2));
Jeff Haoa3faaf42013-09-03 19:07:00 -0700332 HANDLE_PENDING_EXCEPTION();
333 }
334 }
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700335 result.SetL(obj_result);
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200336 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200337 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200338 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200339 shadow_frame.GetMethod(), dex_pc,
340 result);
341 }
342 return result;
343 }
344 HANDLE_INSTRUCTION_END();
345
346 HANDLE_INSTRUCTION_START(CONST_4) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200347 uint32_t dst = inst->VRegA_11n(inst_data);
348 int32_t val = inst->VRegB_11n(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200349 shadow_frame.SetVReg(dst, val);
350 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700351 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200352 }
353 ADVANCE(1);
354 }
355 HANDLE_INSTRUCTION_END();
356
357 HANDLE_INSTRUCTION_START(CONST_16) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200358 uint32_t dst = inst->VRegA_21s(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200359 int32_t val = inst->VRegB_21s();
360 shadow_frame.SetVReg(dst, val);
361 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700362 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200363 }
364 ADVANCE(2);
365 }
366 HANDLE_INSTRUCTION_END();
367
368 HANDLE_INSTRUCTION_START(CONST) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200369 uint32_t dst = inst->VRegA_31i(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200370 int32_t val = inst->VRegB_31i();
371 shadow_frame.SetVReg(dst, val);
372 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700373 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200374 }
375 ADVANCE(3);
376 }
377 HANDLE_INSTRUCTION_END();
378
379 HANDLE_INSTRUCTION_START(CONST_HIGH16) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200380 uint32_t dst = inst->VRegA_21h(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200381 int32_t val = static_cast<int32_t>(inst->VRegB_21h() << 16);
382 shadow_frame.SetVReg(dst, val);
383 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700384 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200385 }
386 ADVANCE(2);
387 }
388 HANDLE_INSTRUCTION_END();
389
390 HANDLE_INSTRUCTION_START(CONST_WIDE_16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200391 shadow_frame.SetVRegLong(inst->VRegA_21s(inst_data), inst->VRegB_21s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200392 ADVANCE(2);
393 HANDLE_INSTRUCTION_END();
394
395 HANDLE_INSTRUCTION_START(CONST_WIDE_32)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200396 shadow_frame.SetVRegLong(inst->VRegA_31i(inst_data), inst->VRegB_31i());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200397 ADVANCE(3);
398 HANDLE_INSTRUCTION_END();
399
400 HANDLE_INSTRUCTION_START(CONST_WIDE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200401 shadow_frame.SetVRegLong(inst->VRegA_51l(inst_data), inst->VRegB_51l());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200402 ADVANCE(5);
403 HANDLE_INSTRUCTION_END();
404
405 HANDLE_INSTRUCTION_START(CONST_WIDE_HIGH16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200406 shadow_frame.SetVRegLong(inst->VRegA_21h(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200407 static_cast<uint64_t>(inst->VRegB_21h()) << 48);
408 ADVANCE(2);
409 HANDLE_INSTRUCTION_END();
410
411 HANDLE_INSTRUCTION_START(CONST_STRING) {
Ian Rogers6786a582014-10-28 12:49:06 -0700412 String* s = ResolveString(self, shadow_frame, inst->VRegB_21c());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700413 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200414 HANDLE_PENDING_EXCEPTION();
415 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200416 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200417 ADVANCE(2);
418 }
419 }
420 HANDLE_INSTRUCTION_END();
421
422 HANDLE_INSTRUCTION_START(CONST_STRING_JUMBO) {
Ian Rogers6786a582014-10-28 12:49:06 -0700423 String* s = ResolveString(self, shadow_frame, inst->VRegB_31c());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700424 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200425 HANDLE_PENDING_EXCEPTION();
426 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200427 shadow_frame.SetVRegReference(inst->VRegA_31c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200428 ADVANCE(3);
429 }
430 }
431 HANDLE_INSTRUCTION_END();
432
433 HANDLE_INSTRUCTION_START(CONST_CLASS) {
434 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
435 self, false, do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700436 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200437 HANDLE_PENDING_EXCEPTION();
438 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200439 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), c);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200440 ADVANCE(2);
441 }
442 }
443 HANDLE_INSTRUCTION_END();
444
445 HANDLE_INSTRUCTION_START(MONITOR_ENTER) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200446 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700447 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000448 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200449 HANDLE_PENDING_EXCEPTION();
450 } else {
451 DoMonitorEnter(self, obj);
452 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), 1);
453 }
454 }
455 HANDLE_INSTRUCTION_END();
456
457 HANDLE_INSTRUCTION_START(MONITOR_EXIT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200458 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700459 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000460 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200461 HANDLE_PENDING_EXCEPTION();
462 } else {
463 DoMonitorExit(self, obj);
464 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), 1);
465 }
466 }
467 HANDLE_INSTRUCTION_END();
468
469 HANDLE_INSTRUCTION_START(CHECK_CAST) {
470 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
471 self, false, do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700472 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200473 HANDLE_PENDING_EXCEPTION();
474 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200475 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_21c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700476 if (UNLIKELY(obj != nullptr && !obj->InstanceOf(c))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200477 ThrowClassCastException(c, obj->GetClass());
478 HANDLE_PENDING_EXCEPTION();
479 } else {
480 ADVANCE(2);
481 }
482 }
483 }
484 HANDLE_INSTRUCTION_END();
485
486 HANDLE_INSTRUCTION_START(INSTANCE_OF) {
487 Class* c = ResolveVerifyAndClinit(inst->VRegC_22c(), shadow_frame.GetMethod(),
488 self, false, do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700489 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200490 HANDLE_PENDING_EXCEPTION();
491 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200492 Object* obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700493 shadow_frame.SetVReg(inst->VRegA_22c(inst_data), (obj != nullptr && obj->InstanceOf(c)) ? 1 : 0);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200494 ADVANCE(2);
495 }
496 }
497 HANDLE_INSTRUCTION_END();
498
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700499 HANDLE_INSTRUCTION_START(ARRAY_LENGTH) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200500 Object* array = shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700501 if (UNLIKELY(array == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000502 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200503 HANDLE_PENDING_EXCEPTION();
504 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200505 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), array->AsArray()->GetLength());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200506 ADVANCE(1);
507 }
508 }
509 HANDLE_INSTRUCTION_END();
510
511 HANDLE_INSTRUCTION_START(NEW_INSTANCE) {
Jeff Hao848f70a2014-01-15 13:49:50 -0800512 Object* obj = nullptr;
513 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
514 self, false, do_access_check);
515 if (LIKELY(c != nullptr)) {
516 if (UNLIKELY(c->IsStringClass())) {
517 gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
518 mirror::SetStringCountVisitor visitor(0);
519 obj = String::Alloc<true>(self, 0, allocator_type, visitor);
520 } else {
521 obj = AllocObjectFromCode<do_access_check, true>(
522 inst->VRegB_21c(), shadow_frame.GetMethod(), self,
523 Runtime::Current()->GetHeap()->GetCurrentAllocator());
524 }
525 }
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700526 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200527 HANDLE_PENDING_EXCEPTION();
528 } else {
Sebastien Hertz4e99b3d2014-06-24 14:35:40 +0200529 obj->GetClass()->AssertInitializedOrInitializingInThread(self);
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700530 // Don't allow finalizable objects to be allocated during a transaction since these can't be
531 // finalized without a started runtime.
532 if (transaction_active && obj->GetClass()->IsFinalizable()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +0200533 AbortTransactionF(self, "Allocating finalizable object in transaction: %s",
534 PrettyTypeOf(obj).c_str());
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700535 HANDLE_PENDING_EXCEPTION();
536 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200537 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200538 ADVANCE(2);
539 }
540 }
541 HANDLE_INSTRUCTION_END();
542
543 HANDLE_INSTRUCTION_START(NEW_ARRAY) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200544 int32_t length = shadow_frame.GetVReg(inst->VRegB_22c(inst_data));
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800545 Object* obj = AllocArrayFromCode<do_access_check, true>(
Andreas Gampe1cc7dba2014-12-17 18:43:01 -0800546 inst->VRegC_22c(), length, shadow_frame.GetMethod(), self,
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800547 Runtime::Current()->GetHeap()->GetCurrentAllocator());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700548 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200549 HANDLE_PENDING_EXCEPTION();
550 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200551 shadow_frame.SetVRegReference(inst->VRegA_22c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200552 ADVANCE(2);
553 }
554 }
555 HANDLE_INSTRUCTION_END();
556
557 HANDLE_INSTRUCTION_START(FILLED_NEW_ARRAY) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100558 bool success =
559 DoFilledNewArray<false, do_access_check, transaction_active>(inst, shadow_frame,
560 self, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200561 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
562 }
563 HANDLE_INSTRUCTION_END();
564
565 HANDLE_INSTRUCTION_START(FILLED_NEW_ARRAY_RANGE) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100566 bool success =
567 DoFilledNewArray<true, do_access_check, transaction_active>(inst, shadow_frame,
568 self, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200569 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
570 }
571 HANDLE_INSTRUCTION_END();
572
573 HANDLE_INSTRUCTION_START(FILL_ARRAY_DATA) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200574 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_31t(inst_data));
Ian Rogers832336b2014-10-08 15:35:22 -0700575 const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t();
576 const Instruction::ArrayDataPayload* payload =
577 reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr);
578 bool success = FillArrayData(obj, payload);
579 if (transaction_active && success) {
580 RecordArrayElementsInTransaction(obj->AsArray(), payload->element_count);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200581 }
Ian Rogers832336b2014-10-08 15:35:22 -0700582 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200583 }
584 HANDLE_INSTRUCTION_END();
585
586 HANDLE_INSTRUCTION_START(THROW) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200587 Object* exception = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700588 if (UNLIKELY(exception == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000589 ThrowNullPointerException("throw with null exception");
Jeff Haoa3faaf42013-09-03 19:07:00 -0700590 } else if (do_assignability_check && !exception->GetClass()->IsThrowableClass()) {
591 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700592 std::string temp;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000593 self->ThrowNewExceptionF("Ljava/lang/VirtualMachineError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700594 "Throwing '%s' that is not instance of Throwable",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700595 exception->GetClass()->GetDescriptor(&temp));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200596 } else {
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000597 self->SetException(exception->AsThrowable());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200598 }
599 HANDLE_PENDING_EXCEPTION();
600 }
601 HANDLE_INSTRUCTION_END();
602
603 HANDLE_INSTRUCTION_START(GOTO) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200604 int8_t offset = inst->VRegA_10t(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200605 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800606 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200607 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700608 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200609 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200610 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200611 }
612 ADVANCE(offset);
613 }
614 HANDLE_INSTRUCTION_END();
615
616 HANDLE_INSTRUCTION_START(GOTO_16) {
617 int16_t offset = inst->VRegA_20t();
618 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800619 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200620 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700621 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200622 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200623 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200624 }
625 ADVANCE(offset);
626 }
627 HANDLE_INSTRUCTION_END();
628
629 HANDLE_INSTRUCTION_START(GOTO_32) {
630 int32_t offset = inst->VRegA_30t();
631 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800632 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200633 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700634 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200635 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200636 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200637 }
638 ADVANCE(offset);
639 }
640 HANDLE_INSTRUCTION_END();
641
642 HANDLE_INSTRUCTION_START(PACKED_SWITCH) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200643 int32_t offset = DoPackedSwitch(inst, shadow_frame, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200644 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800645 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200646 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700647 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200648 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200649 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200650 }
651 ADVANCE(offset);
652 }
653 HANDLE_INSTRUCTION_END();
654
655 HANDLE_INSTRUCTION_START(SPARSE_SWITCH) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200656 int32_t offset = DoSparseSwitch(inst, shadow_frame, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200657 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800658 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200659 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700660 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200661 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200662 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200663 }
664 ADVANCE(offset);
665 }
666 HANDLE_INSTRUCTION_END();
667
Ian Rogers647b1a82014-10-10 11:02:11 -0700668#if defined(__clang__)
669#pragma clang diagnostic push
670#pragma clang diagnostic ignored "-Wfloat-equal"
671#endif
672
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200673 HANDLE_INSTRUCTION_START(CMPL_FLOAT) {
674 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
675 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
676 int32_t result;
677 if (val1 > val2) {
678 result = 1;
679 } else if (val1 == val2) {
680 result = 0;
681 } else {
682 result = -1;
683 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200684 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200685 ADVANCE(2);
686 }
687 HANDLE_INSTRUCTION_END();
688
689 HANDLE_INSTRUCTION_START(CMPG_FLOAT) {
690 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
691 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
692 int32_t result;
693 if (val1 < val2) {
694 result = -1;
695 } else if (val1 == val2) {
696 result = 0;
697 } else {
698 result = 1;
699 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200700 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200701 ADVANCE(2);
702 }
703 HANDLE_INSTRUCTION_END();
704
705 HANDLE_INSTRUCTION_START(CMPL_DOUBLE) {
706 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
707 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
708 int32_t result;
709 if (val1 > val2) {
710 result = 1;
711 } else if (val1 == val2) {
712 result = 0;
713 } else {
714 result = -1;
715 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200716 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200717 ADVANCE(2);
718 }
719 HANDLE_INSTRUCTION_END();
720
721 HANDLE_INSTRUCTION_START(CMPG_DOUBLE) {
722 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
723 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
724 int32_t result;
725 if (val1 < val2) {
726 result = -1;
727 } else if (val1 == val2) {
728 result = 0;
729 } else {
730 result = 1;
731 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200732 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200733 ADVANCE(2);
734 }
735 HANDLE_INSTRUCTION_END();
736
Ian Rogers647b1a82014-10-10 11:02:11 -0700737#if defined(__clang__)
738#pragma clang diagnostic pop
739#endif
740
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200741 HANDLE_INSTRUCTION_START(CMP_LONG) {
742 int64_t val1 = shadow_frame.GetVRegLong(inst->VRegB_23x());
743 int64_t val2 = shadow_frame.GetVRegLong(inst->VRegC_23x());
744 int32_t result;
745 if (val1 > val2) {
746 result = 1;
747 } else if (val1 == val2) {
748 result = 0;
749 } else {
750 result = -1;
751 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200752 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200753 ADVANCE(2);
754 }
755 HANDLE_INSTRUCTION_END();
756
757 HANDLE_INSTRUCTION_START(IF_EQ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200758 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) == shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200759 int16_t offset = inst->VRegC_22t();
760 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800761 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200762 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700763 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200764 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200765 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200766 }
767 ADVANCE(offset);
768 } else {
769 ADVANCE(2);
770 }
771 }
772 HANDLE_INSTRUCTION_END();
773
774 HANDLE_INSTRUCTION_START(IF_NE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700775 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) !=
776 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200777 int16_t offset = inst->VRegC_22t();
778 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800779 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200780 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700781 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200782 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200783 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200784 }
785 ADVANCE(offset);
786 } else {
787 ADVANCE(2);
788 }
789 }
790 HANDLE_INSTRUCTION_END();
791
792 HANDLE_INSTRUCTION_START(IF_LT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700793 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <
794 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200795 int16_t offset = inst->VRegC_22t();
796 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800797 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200798 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700799 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200800 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200801 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200802 }
803 ADVANCE(offset);
804 } else {
805 ADVANCE(2);
806 }
807 }
808 HANDLE_INSTRUCTION_END();
809
810 HANDLE_INSTRUCTION_START(IF_GE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700811 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >=
812 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200813 int16_t offset = inst->VRegC_22t();
814 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800815 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200816 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700817 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200818 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200819 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200820 }
821 ADVANCE(offset);
822 } else {
823 ADVANCE(2);
824 }
825 }
826 HANDLE_INSTRUCTION_END();
827
828 HANDLE_INSTRUCTION_START(IF_GT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700829 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >
830 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200831 int16_t offset = inst->VRegC_22t();
832 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800833 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200834 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700835 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200836 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200837 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200838 }
839 ADVANCE(offset);
840 } else {
841 ADVANCE(2);
842 }
843 }
844 HANDLE_INSTRUCTION_END();
845
846 HANDLE_INSTRUCTION_START(IF_LE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700847 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <=
848 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200849 int16_t offset = inst->VRegC_22t();
850 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800851 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200852 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700853 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200854 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200855 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200856 }
857 ADVANCE(offset);
858 } else {
859 ADVANCE(2);
860 }
861 }
862 HANDLE_INSTRUCTION_END();
863
864 HANDLE_INSTRUCTION_START(IF_EQZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200865 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) == 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200866 int16_t offset = inst->VRegB_21t();
867 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800868 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200869 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700870 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200871 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200872 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200873 }
874 ADVANCE(offset);
875 } else {
876 ADVANCE(2);
877 }
878 }
879 HANDLE_INSTRUCTION_END();
880
881 HANDLE_INSTRUCTION_START(IF_NEZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200882 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) != 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200883 int16_t offset = inst->VRegB_21t();
884 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800885 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200886 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700887 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200888 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200889 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200890 }
891 ADVANCE(offset);
892 } else {
893 ADVANCE(2);
894 }
895 }
896 HANDLE_INSTRUCTION_END();
897
898 HANDLE_INSTRUCTION_START(IF_LTZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200899 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) < 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200900 int16_t offset = inst->VRegB_21t();
901 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800902 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200903 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700904 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200905 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200906 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200907 }
908 ADVANCE(offset);
909 } else {
910 ADVANCE(2);
911 }
912 }
913 HANDLE_INSTRUCTION_END();
914
915 HANDLE_INSTRUCTION_START(IF_GEZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200916 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) >= 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200917 int16_t offset = inst->VRegB_21t();
918 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800919 BACKWARD_BRANCH_INSTRUMENTATION(offset);
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 {
927 ADVANCE(2);
928 }
929 }
930 HANDLE_INSTRUCTION_END();
931
932 HANDLE_INSTRUCTION_START(IF_GTZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200933 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) > 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200934 int16_t offset = inst->VRegB_21t();
935 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800936 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200937 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700938 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200939 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200940 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200941 }
942 ADVANCE(offset);
943 } else {
944 ADVANCE(2);
945 }
946 }
947 HANDLE_INSTRUCTION_END();
948
949 HANDLE_INSTRUCTION_START(IF_LEZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200950 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) <= 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200951 int16_t offset = inst->VRegB_21t();
952 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800953 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200954 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700955 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200956 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200957 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200958 }
959 ADVANCE(offset);
960 } else {
961 ADVANCE(2);
962 }
963 }
964 HANDLE_INSTRUCTION_END();
965
966 HANDLE_INSTRUCTION_START(AGET_BOOLEAN) {
967 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700968 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000969 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200970 HANDLE_PENDING_EXCEPTION();
971 } else {
972 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
973 BooleanArray* array = a->AsBooleanArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +0100974 if (LIKELY(array->CheckIsValidIndex(index))) {
975 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200976 ADVANCE(2);
977 } else {
978 HANDLE_PENDING_EXCEPTION();
979 }
980 }
981 }
982 HANDLE_INSTRUCTION_END();
983
984 HANDLE_INSTRUCTION_START(AGET_BYTE) {
985 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700986 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000987 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200988 HANDLE_PENDING_EXCEPTION();
989 } else {
990 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
991 ByteArray* array = a->AsByteArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +0100992 if (LIKELY(array->CheckIsValidIndex(index))) {
993 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200994 ADVANCE(2);
995 } else {
996 HANDLE_PENDING_EXCEPTION();
997 }
998 }
999 }
1000 HANDLE_INSTRUCTION_END();
1001
1002 HANDLE_INSTRUCTION_START(AGET_CHAR) {
1003 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001004 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001005 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001006 HANDLE_PENDING_EXCEPTION();
1007 } else {
1008 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1009 CharArray* array = a->AsCharArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001010 if (LIKELY(array->CheckIsValidIndex(index))) {
1011 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001012 ADVANCE(2);
1013 } else {
1014 HANDLE_PENDING_EXCEPTION();
1015 }
1016 }
1017 }
1018 HANDLE_INSTRUCTION_END();
1019
1020 HANDLE_INSTRUCTION_START(AGET_SHORT) {
1021 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001022 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001023 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001024 HANDLE_PENDING_EXCEPTION();
1025 } else {
1026 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1027 ShortArray* array = a->AsShortArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001028 if (LIKELY(array->CheckIsValidIndex(index))) {
1029 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001030 ADVANCE(2);
1031 } else {
1032 HANDLE_PENDING_EXCEPTION();
1033 }
1034 }
1035 }
1036 HANDLE_INSTRUCTION_END();
1037
1038 HANDLE_INSTRUCTION_START(AGET) {
1039 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001040 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001041 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001042 HANDLE_PENDING_EXCEPTION();
1043 } else {
1044 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001045 DCHECK(a->IsIntArray() || a->IsFloatArray()) << PrettyTypeOf(a);
1046 auto* array = down_cast<IntArray*>(a);
Sebastien Hertzabff6432014-01-27 18:01:39 +01001047 if (LIKELY(array->CheckIsValidIndex(index))) {
1048 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001049 ADVANCE(2);
1050 } else {
1051 HANDLE_PENDING_EXCEPTION();
1052 }
1053 }
1054 }
1055 HANDLE_INSTRUCTION_END();
1056
1057 HANDLE_INSTRUCTION_START(AGET_WIDE) {
1058 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001059 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001060 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001061 HANDLE_PENDING_EXCEPTION();
1062 } else {
1063 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001064 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << PrettyTypeOf(a);
1065 auto* array = down_cast<LongArray*>(a);
Sebastien Hertzabff6432014-01-27 18:01:39 +01001066 if (LIKELY(array->CheckIsValidIndex(index))) {
1067 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001068 ADVANCE(2);
1069 } else {
1070 HANDLE_PENDING_EXCEPTION();
1071 }
1072 }
1073 }
1074 HANDLE_INSTRUCTION_END();
1075
1076 HANDLE_INSTRUCTION_START(AGET_OBJECT) {
1077 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001078 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001079 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001080 HANDLE_PENDING_EXCEPTION();
1081 } else {
1082 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1083 ObjectArray<Object>* array = a->AsObjectArray<Object>();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001084 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001085 shadow_frame.SetVRegReference(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001086 ADVANCE(2);
1087 } else {
1088 HANDLE_PENDING_EXCEPTION();
1089 }
1090 }
1091 }
1092 HANDLE_INSTRUCTION_END();
1093
1094 HANDLE_INSTRUCTION_START(APUT_BOOLEAN) {
1095 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001096 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001097 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001098 HANDLE_PENDING_EXCEPTION();
1099 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001100 uint8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001101 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1102 BooleanArray* array = a->AsBooleanArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001103 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001104 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001105 ADVANCE(2);
1106 } else {
1107 HANDLE_PENDING_EXCEPTION();
1108 }
1109 }
1110 }
1111 HANDLE_INSTRUCTION_END();
1112
1113 HANDLE_INSTRUCTION_START(APUT_BYTE) {
1114 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001115 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001116 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001117 HANDLE_PENDING_EXCEPTION();
1118 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001119 int8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001120 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1121 ByteArray* array = a->AsByteArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001122 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001123 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001124 ADVANCE(2);
1125 } else {
1126 HANDLE_PENDING_EXCEPTION();
1127 }
1128 }
1129 }
1130 HANDLE_INSTRUCTION_END();
1131
1132 HANDLE_INSTRUCTION_START(APUT_CHAR) {
1133 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001134 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001135 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001136 HANDLE_PENDING_EXCEPTION();
1137 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001138 uint16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001139 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1140 CharArray* array = a->AsCharArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001141 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001142 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001143 ADVANCE(2);
1144 } else {
1145 HANDLE_PENDING_EXCEPTION();
1146 }
1147 }
1148 }
1149 HANDLE_INSTRUCTION_END();
1150
1151 HANDLE_INSTRUCTION_START(APUT_SHORT) {
1152 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001153 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001154 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001155 HANDLE_PENDING_EXCEPTION();
1156 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001157 int16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001158 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1159 ShortArray* array = a->AsShortArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001160 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001161 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001162 ADVANCE(2);
1163 } else {
1164 HANDLE_PENDING_EXCEPTION();
1165 }
1166 }
1167 }
1168 HANDLE_INSTRUCTION_END();
1169
1170 HANDLE_INSTRUCTION_START(APUT) {
1171 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001172 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001173 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001174 HANDLE_PENDING_EXCEPTION();
1175 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001176 int32_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001177 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001178 DCHECK(a->IsIntArray() || a->IsFloatArray()) << PrettyTypeOf(a);
1179 auto* array = down_cast<IntArray*>(a);
Sebastien Hertzabff6432014-01-27 18:01:39 +01001180 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001181 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001182 ADVANCE(2);
1183 } else {
1184 HANDLE_PENDING_EXCEPTION();
1185 }
1186 }
1187 }
1188 HANDLE_INSTRUCTION_END();
1189
1190 HANDLE_INSTRUCTION_START(APUT_WIDE) {
1191 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001192 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001193 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001194 HANDLE_PENDING_EXCEPTION();
1195 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001196 int64_t val = shadow_frame.GetVRegLong(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001197 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001198 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << PrettyTypeOf(a);
1199 auto* array = down_cast<LongArray*>(a);
Sebastien Hertzabff6432014-01-27 18:01:39 +01001200 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001201 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001202 ADVANCE(2);
1203 } else {
1204 HANDLE_PENDING_EXCEPTION();
1205 }
1206 }
1207 }
1208 HANDLE_INSTRUCTION_END();
1209
1210 HANDLE_INSTRUCTION_START(APUT_OBJECT) {
1211 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001212 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001213 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001214 HANDLE_PENDING_EXCEPTION();
1215 } else {
1216 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001217 Object* val = shadow_frame.GetVRegReference(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001218 ObjectArray<Object>* array = a->AsObjectArray<Object>();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001219 if (LIKELY(array->CheckIsValidIndex(index) && array->CheckAssignable(val))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001220 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001221 ADVANCE(2);
1222 } else {
1223 HANDLE_PENDING_EXCEPTION();
1224 }
1225 }
1226 }
1227 HANDLE_INSTRUCTION_END();
1228
1229 HANDLE_INSTRUCTION_START(IGET_BOOLEAN) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001230 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimBoolean, do_access_check>(
1231 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001232 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1233 }
1234 HANDLE_INSTRUCTION_END();
1235
1236 HANDLE_INSTRUCTION_START(IGET_BYTE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001237 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimByte, do_access_check>(
1238 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001239 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1240 }
1241 HANDLE_INSTRUCTION_END();
1242
1243 HANDLE_INSTRUCTION_START(IGET_CHAR) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001244 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimChar, do_access_check>(
1245 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001246 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1247 }
1248 HANDLE_INSTRUCTION_END();
1249
1250 HANDLE_INSTRUCTION_START(IGET_SHORT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001251 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimShort, do_access_check>(
1252 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001253 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1254 }
1255 HANDLE_INSTRUCTION_END();
1256
1257 HANDLE_INSTRUCTION_START(IGET) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001258 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimInt, do_access_check>(
1259 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001260 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1261 }
1262 HANDLE_INSTRUCTION_END();
1263
1264 HANDLE_INSTRUCTION_START(IGET_WIDE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001265 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimLong, do_access_check>(
1266 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001267 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1268 }
1269 HANDLE_INSTRUCTION_END();
1270
1271 HANDLE_INSTRUCTION_START(IGET_OBJECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001272 bool success = DoFieldGet<InstanceObjectRead, Primitive::kPrimNot, do_access_check>(
1273 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001274 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1275 }
1276 HANDLE_INSTRUCTION_END();
1277
1278 HANDLE_INSTRUCTION_START(IGET_QUICK) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001279 bool success = DoIGetQuick<Primitive::kPrimInt>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001280 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1281 }
1282 HANDLE_INSTRUCTION_END();
1283
Mathieu Chartierffc605c2014-12-10 10:35:44 -08001284 HANDLE_INSTRUCTION_START(IGET_BOOLEAN_QUICK) {
1285 bool success = DoIGetQuick<Primitive::kPrimBoolean>(shadow_frame, inst, inst_data);
1286 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1287 }
1288 HANDLE_INSTRUCTION_END();
1289
1290 HANDLE_INSTRUCTION_START(IGET_BYTE_QUICK) {
1291 bool success = DoIGetQuick<Primitive::kPrimByte>(shadow_frame, inst, inst_data);
1292 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1293 }
1294 HANDLE_INSTRUCTION_END();
1295
1296 HANDLE_INSTRUCTION_START(IGET_CHAR_QUICK) {
1297 bool success = DoIGetQuick<Primitive::kPrimChar>(shadow_frame, inst, inst_data);
1298 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1299 }
1300 HANDLE_INSTRUCTION_END();
1301
1302 HANDLE_INSTRUCTION_START(IGET_SHORT_QUICK) {
1303 bool success = DoIGetQuick<Primitive::kPrimShort>(shadow_frame, inst, inst_data);
1304 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1305 }
1306 HANDLE_INSTRUCTION_END();
1307
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001308 HANDLE_INSTRUCTION_START(IGET_WIDE_QUICK) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001309 bool success = DoIGetQuick<Primitive::kPrimLong>(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_QUICK) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001315 bool success = DoIGetQuick<Primitive::kPrimNot>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001316 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1317 }
1318 HANDLE_INSTRUCTION_END();
1319
1320 HANDLE_INSTRUCTION_START(SGET_BOOLEAN) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001321 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimBoolean, do_access_check>(
1322 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001323 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1324 }
1325 HANDLE_INSTRUCTION_END();
1326
1327 HANDLE_INSTRUCTION_START(SGET_BYTE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001328 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimByte, do_access_check>(
1329 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001330 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1331 }
1332 HANDLE_INSTRUCTION_END();
1333
1334 HANDLE_INSTRUCTION_START(SGET_CHAR) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001335 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimChar, do_access_check>(
1336 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001337 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1338 }
1339 HANDLE_INSTRUCTION_END();
1340
1341 HANDLE_INSTRUCTION_START(SGET_SHORT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001342 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimShort, do_access_check>(
1343 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001344 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1345 }
1346 HANDLE_INSTRUCTION_END();
1347
1348 HANDLE_INSTRUCTION_START(SGET) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001349 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimInt, do_access_check>(
1350 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001351 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1352 }
1353 HANDLE_INSTRUCTION_END();
1354
1355 HANDLE_INSTRUCTION_START(SGET_WIDE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001356 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimLong, do_access_check>(
1357 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001358 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1359 }
1360 HANDLE_INSTRUCTION_END();
1361
1362 HANDLE_INSTRUCTION_START(SGET_OBJECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001363 bool success = DoFieldGet<StaticObjectRead, Primitive::kPrimNot, do_access_check>(
1364 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001365 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1366 }
1367 HANDLE_INSTRUCTION_END();
1368
1369 HANDLE_INSTRUCTION_START(IPUT_BOOLEAN) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001370 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1371 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001372 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1373 }
1374 HANDLE_INSTRUCTION_END();
1375
1376 HANDLE_INSTRUCTION_START(IPUT_BYTE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001377 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimByte, do_access_check,
1378 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001379 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1380 }
1381 HANDLE_INSTRUCTION_END();
1382
1383 HANDLE_INSTRUCTION_START(IPUT_CHAR) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001384 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimChar, do_access_check,
1385 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001386 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1387 }
1388 HANDLE_INSTRUCTION_END();
1389
1390 HANDLE_INSTRUCTION_START(IPUT_SHORT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001391 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimShort, do_access_check,
1392 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001393 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1394 }
1395 HANDLE_INSTRUCTION_END();
1396
1397 HANDLE_INSTRUCTION_START(IPUT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001398 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimInt, do_access_check,
1399 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001400 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1401 }
1402 HANDLE_INSTRUCTION_END();
1403
1404 HANDLE_INSTRUCTION_START(IPUT_WIDE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001405 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimLong, do_access_check,
1406 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001407 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1408 }
1409 HANDLE_INSTRUCTION_END();
1410
1411 HANDLE_INSTRUCTION_START(IPUT_OBJECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001412 bool success = DoFieldPut<InstanceObjectWrite, Primitive::kPrimNot, do_access_check,
1413 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001414 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1415 }
1416 HANDLE_INSTRUCTION_END();
1417
1418 HANDLE_INSTRUCTION_START(IPUT_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001419 bool success = DoIPutQuick<Primitive::kPrimInt, transaction_active>(
1420 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001421 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1422 }
1423 HANDLE_INSTRUCTION_END();
1424
Fred Shih37f05ef2014-07-16 18:38:08 -07001425 HANDLE_INSTRUCTION_START(IPUT_BOOLEAN_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001426 bool success = DoIPutQuick<Primitive::kPrimBoolean, transaction_active>(
1427 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001428 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1429 }
1430 HANDLE_INSTRUCTION_END();
1431
1432 HANDLE_INSTRUCTION_START(IPUT_BYTE_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001433 bool success = DoIPutQuick<Primitive::kPrimByte, transaction_active>(
1434 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001435 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1436 }
1437 HANDLE_INSTRUCTION_END();
1438
1439 HANDLE_INSTRUCTION_START(IPUT_CHAR_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001440 bool success = DoIPutQuick<Primitive::kPrimChar, transaction_active>(
1441 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001442 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1443 }
1444 HANDLE_INSTRUCTION_END();
1445
1446 HANDLE_INSTRUCTION_START(IPUT_SHORT_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001447 bool success = DoIPutQuick<Primitive::kPrimShort, transaction_active>(
1448 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001449 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1450 }
1451 HANDLE_INSTRUCTION_END();
1452
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001453 HANDLE_INSTRUCTION_START(IPUT_WIDE_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001454 bool success = DoIPutQuick<Primitive::kPrimLong, transaction_active>(
1455 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001456 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1457 }
1458 HANDLE_INSTRUCTION_END();
1459
1460 HANDLE_INSTRUCTION_START(IPUT_OBJECT_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001461 bool success = DoIPutQuick<Primitive::kPrimNot, transaction_active>(
1462 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001463 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1464 }
1465 HANDLE_INSTRUCTION_END();
1466
1467 HANDLE_INSTRUCTION_START(SPUT_BOOLEAN) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001468 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1469 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001470 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1471 }
1472 HANDLE_INSTRUCTION_END();
1473
1474 HANDLE_INSTRUCTION_START(SPUT_BYTE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001475 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimByte, do_access_check,
1476 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001477 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1478 }
1479 HANDLE_INSTRUCTION_END();
1480
1481 HANDLE_INSTRUCTION_START(SPUT_CHAR) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001482 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimChar, do_access_check,
1483 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001484 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1485 }
1486 HANDLE_INSTRUCTION_END();
1487
1488 HANDLE_INSTRUCTION_START(SPUT_SHORT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001489 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimShort, do_access_check,
1490 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001491 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1492 }
1493 HANDLE_INSTRUCTION_END();
1494
1495 HANDLE_INSTRUCTION_START(SPUT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001496 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimInt, do_access_check,
1497 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001498 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1499 }
1500 HANDLE_INSTRUCTION_END();
1501
1502 HANDLE_INSTRUCTION_START(SPUT_WIDE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001503 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimLong, do_access_check,
1504 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001505 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1506 }
1507 HANDLE_INSTRUCTION_END();
1508
1509 HANDLE_INSTRUCTION_START(SPUT_OBJECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001510 bool success = DoFieldPut<StaticObjectWrite, Primitive::kPrimNot, do_access_check,
1511 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001512 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1513 }
1514 HANDLE_INSTRUCTION_END();
1515
1516 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001517 bool success = DoInvoke<kVirtual, false, do_access_check>(
1518 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001519 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001520 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1521 }
1522 HANDLE_INSTRUCTION_END();
1523
1524 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001525 bool success = DoInvoke<kVirtual, true, do_access_check>(
1526 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001527 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001528 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1529 }
1530 HANDLE_INSTRUCTION_END();
1531
1532 HANDLE_INSTRUCTION_START(INVOKE_SUPER) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001533 bool success = DoInvoke<kSuper, false, do_access_check>(
1534 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001535 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001536 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1537 }
1538 HANDLE_INSTRUCTION_END();
1539
1540 HANDLE_INSTRUCTION_START(INVOKE_SUPER_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001541 bool success = DoInvoke<kSuper, true, do_access_check>(
1542 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001543 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001544 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1545 }
1546 HANDLE_INSTRUCTION_END();
1547
1548 HANDLE_INSTRUCTION_START(INVOKE_DIRECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001549 bool success = DoInvoke<kDirect, false, do_access_check>(
1550 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001551 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001552 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1553 }
1554 HANDLE_INSTRUCTION_END();
1555
1556 HANDLE_INSTRUCTION_START(INVOKE_DIRECT_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001557 bool success = DoInvoke<kDirect, true, do_access_check>(
1558 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001559 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001560 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1561 }
1562 HANDLE_INSTRUCTION_END();
1563
1564 HANDLE_INSTRUCTION_START(INVOKE_INTERFACE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001565 bool success = DoInvoke<kInterface, false, do_access_check>(
1566 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001567 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001568 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1569 }
1570 HANDLE_INSTRUCTION_END();
1571
1572 HANDLE_INSTRUCTION_START(INVOKE_INTERFACE_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001573 bool success = DoInvoke<kInterface, true, do_access_check>(
1574 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001575 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001576 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1577 }
1578 HANDLE_INSTRUCTION_END();
1579
1580 HANDLE_INSTRUCTION_START(INVOKE_STATIC) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001581 bool success = DoInvoke<kStatic, false, do_access_check>(
1582 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001583 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001584 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1585 }
1586 HANDLE_INSTRUCTION_END();
1587
1588 HANDLE_INSTRUCTION_START(INVOKE_STATIC_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001589 bool success = DoInvoke<kStatic, true, do_access_check>(
1590 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001591 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001592 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1593 }
1594 HANDLE_INSTRUCTION_END();
1595
1596 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001597 bool success = DoInvokeVirtualQuick<false>(
1598 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001599 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001600 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1601 }
1602 HANDLE_INSTRUCTION_END();
1603
1604 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_RANGE_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001605 bool success = DoInvokeVirtualQuick<true>(
1606 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001607 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001608 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1609 }
1610 HANDLE_INSTRUCTION_END();
1611
1612 HANDLE_INSTRUCTION_START(NEG_INT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001613 shadow_frame.SetVReg(
1614 inst->VRegA_12x(inst_data), -shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001615 ADVANCE(1);
1616 HANDLE_INSTRUCTION_END();
1617
1618 HANDLE_INSTRUCTION_START(NOT_INT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001619 shadow_frame.SetVReg(
1620 inst->VRegA_12x(inst_data), ~shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001621 ADVANCE(1);
1622 HANDLE_INSTRUCTION_END();
1623
1624 HANDLE_INSTRUCTION_START(NEG_LONG)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001625 shadow_frame.SetVRegLong(
1626 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001627 ADVANCE(1);
1628 HANDLE_INSTRUCTION_END();
1629
1630 HANDLE_INSTRUCTION_START(NOT_LONG)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001631 shadow_frame.SetVRegLong(
1632 inst->VRegA_12x(inst_data), ~shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001633 ADVANCE(1);
1634 HANDLE_INSTRUCTION_END();
1635
1636 HANDLE_INSTRUCTION_START(NEG_FLOAT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001637 shadow_frame.SetVRegFloat(
1638 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001639 ADVANCE(1);
1640 HANDLE_INSTRUCTION_END();
1641
1642 HANDLE_INSTRUCTION_START(NEG_DOUBLE)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001643 shadow_frame.SetVRegDouble(
1644 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001645 ADVANCE(1);
1646 HANDLE_INSTRUCTION_END();
1647
1648 HANDLE_INSTRUCTION_START(INT_TO_LONG)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001649 shadow_frame.SetVRegLong(
1650 inst->VRegA_12x(inst_data), shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001651 ADVANCE(1);
1652 HANDLE_INSTRUCTION_END();
1653
1654 HANDLE_INSTRUCTION_START(INT_TO_FLOAT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001655 shadow_frame.SetVRegFloat(
1656 inst->VRegA_12x(inst_data), shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001657 ADVANCE(1);
1658 HANDLE_INSTRUCTION_END();
1659
1660 HANDLE_INSTRUCTION_START(INT_TO_DOUBLE)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001661 shadow_frame.SetVRegDouble(
1662 inst->VRegA_12x(inst_data), shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001663 ADVANCE(1);
1664 HANDLE_INSTRUCTION_END();
1665
1666 HANDLE_INSTRUCTION_START(LONG_TO_INT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001667 shadow_frame.SetVReg(
1668 inst->VRegA_12x(inst_data), shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001669 ADVANCE(1);
1670 HANDLE_INSTRUCTION_END();
1671
1672 HANDLE_INSTRUCTION_START(LONG_TO_FLOAT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001673 shadow_frame.SetVRegFloat(
1674 inst->VRegA_12x(inst_data), shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001675 ADVANCE(1);
1676 HANDLE_INSTRUCTION_END();
1677
1678 HANDLE_INSTRUCTION_START(LONG_TO_DOUBLE)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001679 shadow_frame.SetVRegDouble(
1680 inst->VRegA_12x(inst_data), shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001681 ADVANCE(1);
1682 HANDLE_INSTRUCTION_END();
1683
1684 HANDLE_INSTRUCTION_START(FLOAT_TO_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001685 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001686 int32_t result = art_float_to_integral<int32_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001687 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001688 ADVANCE(1);
1689 }
1690 HANDLE_INSTRUCTION_END();
1691
1692 HANDLE_INSTRUCTION_START(FLOAT_TO_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001693 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001694 int64_t result = art_float_to_integral<int64_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001695 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001696 ADVANCE(1);
1697 }
1698 HANDLE_INSTRUCTION_END();
1699
1700 HANDLE_INSTRUCTION_START(FLOAT_TO_DOUBLE)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001701 shadow_frame.SetVRegDouble(
1702 inst->VRegA_12x(inst_data), shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001703 ADVANCE(1);
1704 HANDLE_INSTRUCTION_END();
1705
1706 HANDLE_INSTRUCTION_START(DOUBLE_TO_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001707 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001708 int32_t result = art_float_to_integral<int32_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001709 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001710 ADVANCE(1);
1711 }
1712 HANDLE_INSTRUCTION_END();
1713
1714 HANDLE_INSTRUCTION_START(DOUBLE_TO_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001715 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001716 int64_t result = art_float_to_integral<int64_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001717 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001718 ADVANCE(1);
1719 }
1720 HANDLE_INSTRUCTION_END();
1721
1722 HANDLE_INSTRUCTION_START(DOUBLE_TO_FLOAT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001723 shadow_frame.SetVRegFloat(
1724 inst->VRegA_12x(inst_data), shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001725 ADVANCE(1);
1726 HANDLE_INSTRUCTION_END();
1727
1728 HANDLE_INSTRUCTION_START(INT_TO_BYTE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001729 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1730 static_cast<int8_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001731 ADVANCE(1);
1732 HANDLE_INSTRUCTION_END();
1733
1734 HANDLE_INSTRUCTION_START(INT_TO_CHAR)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001735 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1736 static_cast<uint16_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001737 ADVANCE(1);
1738 HANDLE_INSTRUCTION_END();
1739
1740 HANDLE_INSTRUCTION_START(INT_TO_SHORT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001741 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1742 static_cast<int16_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001743 ADVANCE(1);
1744 HANDLE_INSTRUCTION_END();
1745
1746 HANDLE_INSTRUCTION_START(ADD_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001747 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001748 SafeAdd(shadow_frame.GetVReg(inst->VRegB_23x()),
1749 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001750 ADVANCE(2);
1751 HANDLE_INSTRUCTION_END();
1752
1753 HANDLE_INSTRUCTION_START(SUB_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001754 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001755 SafeSub(shadow_frame.GetVReg(inst->VRegB_23x()),
1756 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001757 ADVANCE(2);
1758 HANDLE_INSTRUCTION_END();
1759
1760 HANDLE_INSTRUCTION_START(MUL_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001761 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001762 SafeMul(shadow_frame.GetVReg(inst->VRegB_23x()),
1763 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001764 ADVANCE(2);
1765 HANDLE_INSTRUCTION_END();
1766
1767 HANDLE_INSTRUCTION_START(DIV_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001768 bool success = DoIntDivide(shadow_frame, inst->VRegA_23x(inst_data),
1769 shadow_frame.GetVReg(inst->VRegB_23x()),
1770 shadow_frame.GetVReg(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001771 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1772 }
1773 HANDLE_INSTRUCTION_END();
1774
1775 HANDLE_INSTRUCTION_START(REM_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001776 bool success = DoIntRemainder(shadow_frame, inst->VRegA_23x(inst_data),
1777 shadow_frame.GetVReg(inst->VRegB_23x()),
1778 shadow_frame.GetVReg(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001779 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1780 }
1781 HANDLE_INSTRUCTION_END();
1782
1783 HANDLE_INSTRUCTION_START(SHL_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001784 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001785 shadow_frame.GetVReg(inst->VRegB_23x()) <<
1786 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1787 ADVANCE(2);
1788 HANDLE_INSTRUCTION_END();
1789
1790 HANDLE_INSTRUCTION_START(SHR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001791 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001792 shadow_frame.GetVReg(inst->VRegB_23x()) >>
1793 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1794 ADVANCE(2);
1795 HANDLE_INSTRUCTION_END();
1796
1797 HANDLE_INSTRUCTION_START(USHR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001798 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001799 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_23x())) >>
1800 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1801 ADVANCE(2);
1802 HANDLE_INSTRUCTION_END();
1803
1804 HANDLE_INSTRUCTION_START(AND_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001805 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001806 shadow_frame.GetVReg(inst->VRegB_23x()) &
1807 shadow_frame.GetVReg(inst->VRegC_23x()));
1808 ADVANCE(2);
1809 HANDLE_INSTRUCTION_END();
1810
1811 HANDLE_INSTRUCTION_START(OR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001812 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001813 shadow_frame.GetVReg(inst->VRegB_23x()) |
1814 shadow_frame.GetVReg(inst->VRegC_23x()));
1815 ADVANCE(2);
1816 HANDLE_INSTRUCTION_END();
1817
1818 HANDLE_INSTRUCTION_START(XOR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001819 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001820 shadow_frame.GetVReg(inst->VRegB_23x()) ^
1821 shadow_frame.GetVReg(inst->VRegC_23x()));
1822 ADVANCE(2);
1823 HANDLE_INSTRUCTION_END();
1824
1825 HANDLE_INSTRUCTION_START(ADD_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001826 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001827 SafeAdd(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1828 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001829 ADVANCE(2);
1830 HANDLE_INSTRUCTION_END();
1831
1832 HANDLE_INSTRUCTION_START(SUB_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001833 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001834 SafeSub(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1835 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001836 ADVANCE(2);
1837 HANDLE_INSTRUCTION_END();
1838
1839 HANDLE_INSTRUCTION_START(MUL_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001840 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001841 SafeMul(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1842 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001843 ADVANCE(2);
1844 HANDLE_INSTRUCTION_END();
1845
1846 HANDLE_INSTRUCTION_START(DIV_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001847 bool success = DoLongDivide(shadow_frame, inst->VRegA_23x(inst_data),
1848 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1849 shadow_frame.GetVRegLong(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001850 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1851 }
1852 HANDLE_INSTRUCTION_END();
1853
1854 HANDLE_INSTRUCTION_START(REM_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001855 bool success = DoLongRemainder(shadow_frame, inst->VRegA_23x(inst_data),
1856 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1857 shadow_frame.GetVRegLong(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001858 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1859 }
1860 HANDLE_INSTRUCTION_END();
1861
1862 HANDLE_INSTRUCTION_START(AND_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001863 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001864 shadow_frame.GetVRegLong(inst->VRegB_23x()) &
1865 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1866 ADVANCE(2);
1867 HANDLE_INSTRUCTION_END();
1868
1869 HANDLE_INSTRUCTION_START(OR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001870 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001871 shadow_frame.GetVRegLong(inst->VRegB_23x()) |
1872 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1873 ADVANCE(2);
1874 HANDLE_INSTRUCTION_END();
1875
1876 HANDLE_INSTRUCTION_START(XOR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001877 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001878 shadow_frame.GetVRegLong(inst->VRegB_23x()) ^
1879 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1880 ADVANCE(2);
1881 HANDLE_INSTRUCTION_END();
1882
1883 HANDLE_INSTRUCTION_START(SHL_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001884 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001885 shadow_frame.GetVRegLong(inst->VRegB_23x()) <<
1886 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1887 ADVANCE(2);
1888 HANDLE_INSTRUCTION_END();
1889
1890 HANDLE_INSTRUCTION_START(SHR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001891 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001892 shadow_frame.GetVRegLong(inst->VRegB_23x()) >>
1893 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1894 ADVANCE(2);
1895 HANDLE_INSTRUCTION_END();
1896
1897 HANDLE_INSTRUCTION_START(USHR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001898 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001899 static_cast<uint64_t>(shadow_frame.GetVRegLong(inst->VRegB_23x())) >>
1900 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1901 ADVANCE(2);
1902 HANDLE_INSTRUCTION_END();
1903
1904 HANDLE_INSTRUCTION_START(ADD_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001905 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001906 shadow_frame.GetVRegFloat(inst->VRegB_23x()) +
1907 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1908 ADVANCE(2);
1909 HANDLE_INSTRUCTION_END();
1910
1911 HANDLE_INSTRUCTION_START(SUB_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001912 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001913 shadow_frame.GetVRegFloat(inst->VRegB_23x()) -
1914 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1915 ADVANCE(2);
1916 HANDLE_INSTRUCTION_END();
1917
1918 HANDLE_INSTRUCTION_START(MUL_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001919 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001920 shadow_frame.GetVRegFloat(inst->VRegB_23x()) *
1921 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1922 ADVANCE(2);
1923 HANDLE_INSTRUCTION_END();
1924
1925 HANDLE_INSTRUCTION_START(DIV_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001926 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001927 shadow_frame.GetVRegFloat(inst->VRegB_23x()) /
1928 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1929 ADVANCE(2);
1930 HANDLE_INSTRUCTION_END();
1931
1932 HANDLE_INSTRUCTION_START(REM_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001933 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001934 fmodf(shadow_frame.GetVRegFloat(inst->VRegB_23x()),
1935 shadow_frame.GetVRegFloat(inst->VRegC_23x())));
1936 ADVANCE(2);
1937 HANDLE_INSTRUCTION_END();
1938
1939 HANDLE_INSTRUCTION_START(ADD_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001940 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001941 shadow_frame.GetVRegDouble(inst->VRegB_23x()) +
1942 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1943 ADVANCE(2);
1944 HANDLE_INSTRUCTION_END();
1945
1946 HANDLE_INSTRUCTION_START(SUB_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001947 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001948 shadow_frame.GetVRegDouble(inst->VRegB_23x()) -
1949 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1950 ADVANCE(2);
1951 HANDLE_INSTRUCTION_END();
1952
1953 HANDLE_INSTRUCTION_START(MUL_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001954 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001955 shadow_frame.GetVRegDouble(inst->VRegB_23x()) *
1956 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1957 ADVANCE(2);
1958 HANDLE_INSTRUCTION_END();
1959
1960 HANDLE_INSTRUCTION_START(DIV_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001961 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001962 shadow_frame.GetVRegDouble(inst->VRegB_23x()) /
1963 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1964 ADVANCE(2);
1965 HANDLE_INSTRUCTION_END();
1966
1967 HANDLE_INSTRUCTION_START(REM_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001968 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001969 fmod(shadow_frame.GetVRegDouble(inst->VRegB_23x()),
1970 shadow_frame.GetVRegDouble(inst->VRegC_23x())));
1971 ADVANCE(2);
1972 HANDLE_INSTRUCTION_END();
1973
1974 HANDLE_INSTRUCTION_START(ADD_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001975 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001976 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07001977 SafeAdd(shadow_frame.GetVReg(vregA),
1978 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001979 ADVANCE(1);
1980 }
1981 HANDLE_INSTRUCTION_END();
1982
1983 HANDLE_INSTRUCTION_START(SUB_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001984 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001985 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07001986 SafeSub(shadow_frame.GetVReg(vregA),
1987 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001988 ADVANCE(1);
1989 }
1990 HANDLE_INSTRUCTION_END();
1991
1992 HANDLE_INSTRUCTION_START(MUL_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001993 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001994 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07001995 SafeMul(shadow_frame.GetVReg(vregA),
1996 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001997 ADVANCE(1);
1998 }
1999 HANDLE_INSTRUCTION_END();
2000
2001 HANDLE_INSTRUCTION_START(DIV_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002002 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002003 bool success = DoIntDivide(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002004 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002005 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2006 }
2007 HANDLE_INSTRUCTION_END();
2008
2009 HANDLE_INSTRUCTION_START(REM_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002010 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002011 bool success = DoIntRemainder(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002012 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002013 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2014 }
2015 HANDLE_INSTRUCTION_END();
2016
2017 HANDLE_INSTRUCTION_START(SHL_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,
2020 shadow_frame.GetVReg(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002021 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002022 ADVANCE(1);
2023 }
2024 HANDLE_INSTRUCTION_END();
2025
2026 HANDLE_INSTRUCTION_START(SHR_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,
2029 shadow_frame.GetVReg(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002030 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002031 ADVANCE(1);
2032 }
2033 HANDLE_INSTRUCTION_END();
2034
2035 HANDLE_INSTRUCTION_START(USHR_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,
2038 static_cast<uint32_t>(shadow_frame.GetVReg(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002039 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002040 ADVANCE(1);
2041 }
2042 HANDLE_INSTRUCTION_END();
2043
2044 HANDLE_INSTRUCTION_START(AND_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 shadow_frame.SetVReg(vregA,
2047 shadow_frame.GetVReg(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002048 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002049 ADVANCE(1);
2050 }
2051 HANDLE_INSTRUCTION_END();
2052
2053 HANDLE_INSTRUCTION_START(OR_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002054 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002055 shadow_frame.SetVReg(vregA,
2056 shadow_frame.GetVReg(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002057 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002058 ADVANCE(1);
2059 }
2060 HANDLE_INSTRUCTION_END();
2061
2062 HANDLE_INSTRUCTION_START(XOR_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002063 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002064 shadow_frame.SetVReg(vregA,
2065 shadow_frame.GetVReg(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002066 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002067 ADVANCE(1);
2068 }
2069 HANDLE_INSTRUCTION_END();
2070
2071 HANDLE_INSTRUCTION_START(ADD_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002072 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002073 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002074 SafeAdd(shadow_frame.GetVRegLong(vregA),
2075 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002076 ADVANCE(1);
2077 }
2078 HANDLE_INSTRUCTION_END();
2079
2080 HANDLE_INSTRUCTION_START(SUB_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002081 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002082 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002083 SafeSub(shadow_frame.GetVRegLong(vregA),
2084 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002085 ADVANCE(1);
2086 }
2087 HANDLE_INSTRUCTION_END();
2088
2089 HANDLE_INSTRUCTION_START(MUL_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002090 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002091 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002092 SafeMul(shadow_frame.GetVRegLong(vregA),
2093 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002094 ADVANCE(1);
2095 }
2096 HANDLE_INSTRUCTION_END();
2097
2098 HANDLE_INSTRUCTION_START(DIV_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002099 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002100 bool success = DoLongDivide(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002101 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002102 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2103 }
2104 HANDLE_INSTRUCTION_END();
2105
2106 HANDLE_INSTRUCTION_START(REM_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002107 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002108 bool success = DoLongRemainder(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002109 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002110 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2111 }
2112 HANDLE_INSTRUCTION_END();
2113
2114 HANDLE_INSTRUCTION_START(AND_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,
2117 shadow_frame.GetVRegLong(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002118 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(OR_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,
2126 shadow_frame.GetVRegLong(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002127 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(XOR_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,
2135 shadow_frame.GetVRegLong(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002136 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(SHL_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 shadow_frame.SetVRegLong(vregA,
2144 shadow_frame.GetVRegLong(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002145 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002146 ADVANCE(1);
2147 }
2148 HANDLE_INSTRUCTION_END();
2149
2150 HANDLE_INSTRUCTION_START(SHR_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002151 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002152 shadow_frame.SetVRegLong(vregA,
2153 shadow_frame.GetVRegLong(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002154 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002155 ADVANCE(1);
2156 }
2157 HANDLE_INSTRUCTION_END();
2158
2159 HANDLE_INSTRUCTION_START(USHR_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002160 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002161 shadow_frame.SetVRegLong(vregA,
2162 static_cast<uint64_t>(shadow_frame.GetVRegLong(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002163 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002164 ADVANCE(1);
2165 }
2166 HANDLE_INSTRUCTION_END();
2167
2168 HANDLE_INSTRUCTION_START(ADD_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002169 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002170 shadow_frame.SetVRegFloat(vregA,
2171 shadow_frame.GetVRegFloat(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002172 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002173 ADVANCE(1);
2174 }
2175 HANDLE_INSTRUCTION_END();
2176
2177 HANDLE_INSTRUCTION_START(SUB_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002178 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002179 shadow_frame.SetVRegFloat(vregA,
2180 shadow_frame.GetVRegFloat(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002181 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002182 ADVANCE(1);
2183 }
2184 HANDLE_INSTRUCTION_END();
2185
2186 HANDLE_INSTRUCTION_START(MUL_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002187 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002188 shadow_frame.SetVRegFloat(vregA,
2189 shadow_frame.GetVRegFloat(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002190 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002191 ADVANCE(1);
2192 }
2193 HANDLE_INSTRUCTION_END();
2194
2195 HANDLE_INSTRUCTION_START(DIV_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002196 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002197 shadow_frame.SetVRegFloat(vregA,
2198 shadow_frame.GetVRegFloat(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002199 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002200 ADVANCE(1);
2201 }
2202 HANDLE_INSTRUCTION_END();
2203
2204 HANDLE_INSTRUCTION_START(REM_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002205 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002206 shadow_frame.SetVRegFloat(vregA,
2207 fmodf(shadow_frame.GetVRegFloat(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002208 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002209 ADVANCE(1);
2210 }
2211 HANDLE_INSTRUCTION_END();
2212
2213 HANDLE_INSTRUCTION_START(ADD_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002214 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002215 shadow_frame.SetVRegDouble(vregA,
2216 shadow_frame.GetVRegDouble(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002217 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002218 ADVANCE(1);
2219 }
2220 HANDLE_INSTRUCTION_END();
2221
2222 HANDLE_INSTRUCTION_START(SUB_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002223 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002224 shadow_frame.SetVRegDouble(vregA,
2225 shadow_frame.GetVRegDouble(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002226 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002227 ADVANCE(1);
2228 }
2229 HANDLE_INSTRUCTION_END();
2230
2231 HANDLE_INSTRUCTION_START(MUL_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002232 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002233 shadow_frame.SetVRegDouble(vregA,
2234 shadow_frame.GetVRegDouble(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002235 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002236 ADVANCE(1);
2237 }
2238 HANDLE_INSTRUCTION_END();
2239
2240 HANDLE_INSTRUCTION_START(DIV_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002241 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002242 shadow_frame.SetVRegDouble(vregA,
2243 shadow_frame.GetVRegDouble(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002244 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002245 ADVANCE(1);
2246 }
2247 HANDLE_INSTRUCTION_END();
2248
2249 HANDLE_INSTRUCTION_START(REM_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002250 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002251 shadow_frame.SetVRegDouble(vregA,
2252 fmod(shadow_frame.GetVRegDouble(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002253 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002254 ADVANCE(1);
2255 }
2256 HANDLE_INSTRUCTION_END();
2257
2258 HANDLE_INSTRUCTION_START(ADD_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002259 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002260 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2261 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002262 ADVANCE(2);
2263 HANDLE_INSTRUCTION_END();
2264
2265 HANDLE_INSTRUCTION_START(RSUB_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002266 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002267 SafeSub(inst->VRegC_22s(),
2268 shadow_frame.GetVReg(inst->VRegB_22s(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002269 ADVANCE(2);
2270 HANDLE_INSTRUCTION_END();
2271
2272 HANDLE_INSTRUCTION_START(MUL_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002273 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002274 SafeMul(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2275 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002276 ADVANCE(2);
2277 HANDLE_INSTRUCTION_END();
2278
2279 HANDLE_INSTRUCTION_START(DIV_INT_LIT16) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002280 bool success = DoIntDivide(
2281 shadow_frame, inst->VRegA_22s(inst_data), shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2282 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002283 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2284 }
2285 HANDLE_INSTRUCTION_END();
2286
2287 HANDLE_INSTRUCTION_START(REM_INT_LIT16) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002288 bool success = DoIntRemainder(
2289 shadow_frame, inst->VRegA_22s(inst_data), shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2290 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002291 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2292 }
2293 HANDLE_INSTRUCTION_END();
2294
2295 HANDLE_INSTRUCTION_START(AND_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002296 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2297 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) &
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002298 inst->VRegC_22s());
2299 ADVANCE(2);
2300 HANDLE_INSTRUCTION_END();
2301
2302 HANDLE_INSTRUCTION_START(OR_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002303 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2304 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) |
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002305 inst->VRegC_22s());
2306 ADVANCE(2);
2307 HANDLE_INSTRUCTION_END();
2308
2309 HANDLE_INSTRUCTION_START(XOR_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002310 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2311 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) ^
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002312 inst->VRegC_22s());
2313 ADVANCE(2);
2314 HANDLE_INSTRUCTION_END();
2315
2316 HANDLE_INSTRUCTION_START(ADD_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002317 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002318 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22b()),
2319 inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002320 ADVANCE(2);
2321 HANDLE_INSTRUCTION_END();
2322
2323 HANDLE_INSTRUCTION_START(RSUB_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002324 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002325 SafeSub(inst->VRegC_22b(),
2326 shadow_frame.GetVReg(inst->VRegB_22b())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002327 ADVANCE(2);
2328 HANDLE_INSTRUCTION_END();
2329
2330 HANDLE_INSTRUCTION_START(MUL_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002331 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002332 SafeMul(shadow_frame.GetVReg(inst->VRegB_22b()),
2333 inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002334 ADVANCE(2);
2335 HANDLE_INSTRUCTION_END();
2336
2337 HANDLE_INSTRUCTION_START(DIV_INT_LIT8) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002338 bool success = DoIntDivide(shadow_frame, inst->VRegA_22b(inst_data),
2339 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002340 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2341 }
2342 HANDLE_INSTRUCTION_END();
2343
2344 HANDLE_INSTRUCTION_START(REM_INT_LIT8) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002345 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22b(inst_data),
2346 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002347 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2348 }
2349 HANDLE_INSTRUCTION_END();
2350
2351 HANDLE_INSTRUCTION_START(AND_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002352 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002353 shadow_frame.GetVReg(inst->VRegB_22b()) &
2354 inst->VRegC_22b());
2355 ADVANCE(2);
2356 HANDLE_INSTRUCTION_END();
2357
2358 HANDLE_INSTRUCTION_START(OR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002359 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002360 shadow_frame.GetVReg(inst->VRegB_22b()) |
2361 inst->VRegC_22b());
2362 ADVANCE(2);
2363 HANDLE_INSTRUCTION_END();
2364
2365 HANDLE_INSTRUCTION_START(XOR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002366 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002367 shadow_frame.GetVReg(inst->VRegB_22b()) ^
2368 inst->VRegC_22b());
2369 ADVANCE(2);
2370 HANDLE_INSTRUCTION_END();
2371
2372 HANDLE_INSTRUCTION_START(SHL_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002373 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002374 shadow_frame.GetVReg(inst->VRegB_22b()) <<
2375 (inst->VRegC_22b() & 0x1f));
2376 ADVANCE(2);
2377 HANDLE_INSTRUCTION_END();
2378
2379 HANDLE_INSTRUCTION_START(SHR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002380 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002381 shadow_frame.GetVReg(inst->VRegB_22b()) >>
2382 (inst->VRegC_22b() & 0x1f));
2383 ADVANCE(2);
2384 HANDLE_INSTRUCTION_END();
2385
2386 HANDLE_INSTRUCTION_START(USHR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002387 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002388 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_22b())) >>
2389 (inst->VRegC_22b() & 0x1f));
2390 ADVANCE(2);
2391 HANDLE_INSTRUCTION_END();
2392
2393 HANDLE_INSTRUCTION_START(UNUSED_3E)
Ian Rogerse94652f2014-12-02 11:13:19 -08002394 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002395 HANDLE_INSTRUCTION_END();
2396
2397 HANDLE_INSTRUCTION_START(UNUSED_3F)
Ian Rogerse94652f2014-12-02 11:13:19 -08002398 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002399 HANDLE_INSTRUCTION_END();
2400
2401 HANDLE_INSTRUCTION_START(UNUSED_40)
Ian Rogerse94652f2014-12-02 11:13:19 -08002402 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002403 HANDLE_INSTRUCTION_END();
2404
2405 HANDLE_INSTRUCTION_START(UNUSED_41)
Ian Rogerse94652f2014-12-02 11:13:19 -08002406 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002407 HANDLE_INSTRUCTION_END();
2408
2409 HANDLE_INSTRUCTION_START(UNUSED_42)
Ian Rogerse94652f2014-12-02 11:13:19 -08002410 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002411 HANDLE_INSTRUCTION_END();
2412
2413 HANDLE_INSTRUCTION_START(UNUSED_43)
Ian Rogerse94652f2014-12-02 11:13:19 -08002414 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002415 HANDLE_INSTRUCTION_END();
2416
2417 HANDLE_INSTRUCTION_START(UNUSED_79)
Ian Rogerse94652f2014-12-02 11:13:19 -08002418 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002419 HANDLE_INSTRUCTION_END();
2420
2421 HANDLE_INSTRUCTION_START(UNUSED_7A)
Ian Rogerse94652f2014-12-02 11:13:19 -08002422 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002423 HANDLE_INSTRUCTION_END();
2424
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002425 HANDLE_INSTRUCTION_START(UNUSED_F3)
Ian Rogerse94652f2014-12-02 11:13:19 -08002426 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002427 HANDLE_INSTRUCTION_END();
2428
2429 HANDLE_INSTRUCTION_START(UNUSED_F4)
Ian Rogerse94652f2014-12-02 11:13:19 -08002430 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002431 HANDLE_INSTRUCTION_END();
2432
2433 HANDLE_INSTRUCTION_START(UNUSED_F5)
Ian Rogerse94652f2014-12-02 11:13:19 -08002434 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002435 HANDLE_INSTRUCTION_END();
2436
2437 HANDLE_INSTRUCTION_START(UNUSED_F6)
Ian Rogerse94652f2014-12-02 11:13:19 -08002438 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002439 HANDLE_INSTRUCTION_END();
2440
2441 HANDLE_INSTRUCTION_START(UNUSED_F7)
Ian Rogerse94652f2014-12-02 11:13:19 -08002442 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002443 HANDLE_INSTRUCTION_END();
2444
2445 HANDLE_INSTRUCTION_START(UNUSED_F8)
Ian Rogerse94652f2014-12-02 11:13:19 -08002446 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002447 HANDLE_INSTRUCTION_END();
2448
2449 HANDLE_INSTRUCTION_START(UNUSED_F9)
Ian Rogerse94652f2014-12-02 11:13:19 -08002450 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002451 HANDLE_INSTRUCTION_END();
2452
2453 HANDLE_INSTRUCTION_START(UNUSED_FA)
Ian Rogerse94652f2014-12-02 11:13:19 -08002454 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002455 HANDLE_INSTRUCTION_END();
2456
2457 HANDLE_INSTRUCTION_START(UNUSED_FB)
Ian Rogerse94652f2014-12-02 11:13:19 -08002458 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002459 HANDLE_INSTRUCTION_END();
2460
2461 HANDLE_INSTRUCTION_START(UNUSED_FC)
Ian Rogerse94652f2014-12-02 11:13:19 -08002462 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002463 HANDLE_INSTRUCTION_END();
2464
2465 HANDLE_INSTRUCTION_START(UNUSED_FD)
Ian Rogerse94652f2014-12-02 11:13:19 -08002466 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002467 HANDLE_INSTRUCTION_END();
2468
2469 HANDLE_INSTRUCTION_START(UNUSED_FE)
Ian Rogerse94652f2014-12-02 11:13:19 -08002470 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002471 HANDLE_INSTRUCTION_END();
2472
2473 HANDLE_INSTRUCTION_START(UNUSED_FF)
Ian Rogerse94652f2014-12-02 11:13:19 -08002474 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002475 HANDLE_INSTRUCTION_END();
2476
2477 exception_pending_label: {
2478 CHECK(self->IsExceptionPending());
Sebastien Hertz1eda2262013-09-09 16:53:14 +02002479 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -07002480 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +02002481 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +02002482 }
Sebastien Hertzee1997a2013-09-19 14:47:09 +02002483 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002484 uint32_t found_dex_pc = FindNextInstructionFollowingException(self, shadow_frame, dex_pc,
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002485 instrumentation);
2486 if (found_dex_pc == DexFile::kDexNoIndex) {
2487 return JValue(); /* Handled in caller. */
2488 } else {
2489 int32_t displacement = static_cast<int32_t>(found_dex_pc) - static_cast<int32_t>(dex_pc);
2490 ADVANCE(displacement);
2491 }
2492 }
2493
Sebastien Hertz8379b222014-02-24 17:38:15 +01002494// Create alternative instruction handlers dedicated to instrumentation.
2495// Return instructions must not call Instrumentation::DexPcMovedEvent since they already call
2496// Instrumentation::MethodExited. This is to avoid posting debugger events twice for this location.
Sebastien Hertze713d932014-05-15 10:48:53 +02002497// Note: we do not use the kReturn instruction flag here (to test the instruction is a return). The
2498// compiler seems to not evaluate "(Instruction::FlagsOf(Instruction::code) & kReturn) != 0" to
2499// a constant condition that would remove the "if" statement so the test is free.
Sebastien Hertz9d6bf692015-04-10 12:12:33 +02002500#define INSTRUMENTATION_INSTRUCTION_HANDLER(o, code, n, f, r, i, a, v) \
2501 alt_op_##code: { \
2502 Runtime* const runtime = Runtime::Current(); \
2503 const instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation(); \
2504 if (UNLIKELY(instrumentation->HasDexPcListeners())) { \
2505 Object* this_object = shadow_frame.GetThisObject(code_item->ins_size_); \
2506 instrumentation->DexPcMovedEvent(self, this_object, shadow_frame.GetMethod(), dex_pc); \
2507 } \
2508 UPDATE_HANDLER_TABLE(); \
2509 goto *handlersTable[instrumentation::kMainHandlerTable][Instruction::code]; \
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002510 }
2511#include "dex_instruction_list.h"
2512 DEX_INSTRUCTION_LIST(INSTRUMENTATION_INSTRUCTION_HANDLER)
2513#undef DEX_INSTRUCTION_LIST
2514#undef INSTRUMENTATION_INSTRUCTION_HANDLER
2515} // NOLINT(readability/fn_size)
2516
2517// Explicit definitions of ExecuteGotoImpl.
Sebastien Hertzc6714852013-09-30 16:42:32 +02002518template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) HOT_ATTR
Ian Rogerse94652f2014-12-02 11:13:19 -08002519JValue ExecuteGotoImpl<true, false>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002520 ShadowFrame& shadow_frame, JValue result_register);
Sebastien Hertzc6714852013-09-30 16:42:32 +02002521template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) HOT_ATTR
Ian Rogerse94652f2014-12-02 11:13:19 -08002522JValue ExecuteGotoImpl<false, false>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002523 ShadowFrame& shadow_frame, JValue result_register);
2524template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
Ian Rogerse94652f2014-12-02 11:13:19 -08002525JValue ExecuteGotoImpl<true, true>(Thread* self, const DexFile::CodeItem* code_item,
2526 ShadowFrame& shadow_frame, JValue result_register);
2527template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
2528JValue ExecuteGotoImpl<false, true>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002529 ShadowFrame& shadow_frame, JValue result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002530
2531} // namespace interpreter
2532} // namespace art
Colin Crosse84e4f72015-03-18 14:01:19 -07002533
2534#endif