blob: dd1f55e6b291a766b7895feb5b4de6f22283d2ca [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());
1045 IntArray* array = a->AsIntArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001046 if (LIKELY(array->CheckIsValidIndex(index))) {
1047 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001048 ADVANCE(2);
1049 } else {
1050 HANDLE_PENDING_EXCEPTION();
1051 }
1052 }
1053 }
1054 HANDLE_INSTRUCTION_END();
1055
1056 HANDLE_INSTRUCTION_START(AGET_WIDE) {
1057 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001058 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001059 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001060 HANDLE_PENDING_EXCEPTION();
1061 } else {
1062 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1063 LongArray* array = a->AsLongArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001064 if (LIKELY(array->CheckIsValidIndex(index))) {
1065 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001066 ADVANCE(2);
1067 } else {
1068 HANDLE_PENDING_EXCEPTION();
1069 }
1070 }
1071 }
1072 HANDLE_INSTRUCTION_END();
1073
1074 HANDLE_INSTRUCTION_START(AGET_OBJECT) {
1075 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001076 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001077 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001078 HANDLE_PENDING_EXCEPTION();
1079 } else {
1080 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1081 ObjectArray<Object>* array = a->AsObjectArray<Object>();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001082 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001083 shadow_frame.SetVRegReference(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001084 ADVANCE(2);
1085 } else {
1086 HANDLE_PENDING_EXCEPTION();
1087 }
1088 }
1089 }
1090 HANDLE_INSTRUCTION_END();
1091
1092 HANDLE_INSTRUCTION_START(APUT_BOOLEAN) {
1093 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001094 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001095 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001096 HANDLE_PENDING_EXCEPTION();
1097 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001098 uint8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001099 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1100 BooleanArray* array = a->AsBooleanArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001101 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001102 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001103 ADVANCE(2);
1104 } else {
1105 HANDLE_PENDING_EXCEPTION();
1106 }
1107 }
1108 }
1109 HANDLE_INSTRUCTION_END();
1110
1111 HANDLE_INSTRUCTION_START(APUT_BYTE) {
1112 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001113 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001114 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001115 HANDLE_PENDING_EXCEPTION();
1116 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001117 int8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001118 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1119 ByteArray* array = a->AsByteArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001120 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001121 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001122 ADVANCE(2);
1123 } else {
1124 HANDLE_PENDING_EXCEPTION();
1125 }
1126 }
1127 }
1128 HANDLE_INSTRUCTION_END();
1129
1130 HANDLE_INSTRUCTION_START(APUT_CHAR) {
1131 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001132 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001133 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001134 HANDLE_PENDING_EXCEPTION();
1135 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001136 uint16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001137 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1138 CharArray* array = a->AsCharArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001139 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001140 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001141 ADVANCE(2);
1142 } else {
1143 HANDLE_PENDING_EXCEPTION();
1144 }
1145 }
1146 }
1147 HANDLE_INSTRUCTION_END();
1148
1149 HANDLE_INSTRUCTION_START(APUT_SHORT) {
1150 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001151 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001152 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001153 HANDLE_PENDING_EXCEPTION();
1154 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001155 int16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001156 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1157 ShortArray* array = a->AsShortArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001158 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001159 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001160 ADVANCE(2);
1161 } else {
1162 HANDLE_PENDING_EXCEPTION();
1163 }
1164 }
1165 }
1166 HANDLE_INSTRUCTION_END();
1167
1168 HANDLE_INSTRUCTION_START(APUT) {
1169 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001170 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001171 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001172 HANDLE_PENDING_EXCEPTION();
1173 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001174 int32_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001175 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1176 IntArray* array = a->AsIntArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001177 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001178 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001179 ADVANCE(2);
1180 } else {
1181 HANDLE_PENDING_EXCEPTION();
1182 }
1183 }
1184 }
1185 HANDLE_INSTRUCTION_END();
1186
1187 HANDLE_INSTRUCTION_START(APUT_WIDE) {
1188 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001189 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001190 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001191 HANDLE_PENDING_EXCEPTION();
1192 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001193 int64_t val = shadow_frame.GetVRegLong(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001194 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1195 LongArray* array = a->AsLongArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001196 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001197 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001198 ADVANCE(2);
1199 } else {
1200 HANDLE_PENDING_EXCEPTION();
1201 }
1202 }
1203 }
1204 HANDLE_INSTRUCTION_END();
1205
1206 HANDLE_INSTRUCTION_START(APUT_OBJECT) {
1207 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001208 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001209 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001210 HANDLE_PENDING_EXCEPTION();
1211 } else {
1212 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001213 Object* val = shadow_frame.GetVRegReference(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001214 ObjectArray<Object>* array = a->AsObjectArray<Object>();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001215 if (LIKELY(array->CheckIsValidIndex(index) && array->CheckAssignable(val))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001216 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001217 ADVANCE(2);
1218 } else {
1219 HANDLE_PENDING_EXCEPTION();
1220 }
1221 }
1222 }
1223 HANDLE_INSTRUCTION_END();
1224
1225 HANDLE_INSTRUCTION_START(IGET_BOOLEAN) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001226 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimBoolean, do_access_check>(
1227 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001228 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1229 }
1230 HANDLE_INSTRUCTION_END();
1231
1232 HANDLE_INSTRUCTION_START(IGET_BYTE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001233 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimByte, do_access_check>(
1234 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001235 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1236 }
1237 HANDLE_INSTRUCTION_END();
1238
1239 HANDLE_INSTRUCTION_START(IGET_CHAR) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001240 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimChar, do_access_check>(
1241 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001242 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1243 }
1244 HANDLE_INSTRUCTION_END();
1245
1246 HANDLE_INSTRUCTION_START(IGET_SHORT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001247 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimShort, do_access_check>(
1248 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001249 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1250 }
1251 HANDLE_INSTRUCTION_END();
1252
1253 HANDLE_INSTRUCTION_START(IGET) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001254 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimInt, do_access_check>(
1255 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001256 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1257 }
1258 HANDLE_INSTRUCTION_END();
1259
1260 HANDLE_INSTRUCTION_START(IGET_WIDE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001261 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimLong, do_access_check>(
1262 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001263 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1264 }
1265 HANDLE_INSTRUCTION_END();
1266
1267 HANDLE_INSTRUCTION_START(IGET_OBJECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001268 bool success = DoFieldGet<InstanceObjectRead, Primitive::kPrimNot, do_access_check>(
1269 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001270 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1271 }
1272 HANDLE_INSTRUCTION_END();
1273
1274 HANDLE_INSTRUCTION_START(IGET_QUICK) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001275 bool success = DoIGetQuick<Primitive::kPrimInt>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001276 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1277 }
1278 HANDLE_INSTRUCTION_END();
1279
Mathieu Chartierffc605c2014-12-10 10:35:44 -08001280 HANDLE_INSTRUCTION_START(IGET_BOOLEAN_QUICK) {
1281 bool success = DoIGetQuick<Primitive::kPrimBoolean>(shadow_frame, inst, inst_data);
1282 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1283 }
1284 HANDLE_INSTRUCTION_END();
1285
1286 HANDLE_INSTRUCTION_START(IGET_BYTE_QUICK) {
1287 bool success = DoIGetQuick<Primitive::kPrimByte>(shadow_frame, inst, inst_data);
1288 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1289 }
1290 HANDLE_INSTRUCTION_END();
1291
1292 HANDLE_INSTRUCTION_START(IGET_CHAR_QUICK) {
1293 bool success = DoIGetQuick<Primitive::kPrimChar>(shadow_frame, inst, inst_data);
1294 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1295 }
1296 HANDLE_INSTRUCTION_END();
1297
1298 HANDLE_INSTRUCTION_START(IGET_SHORT_QUICK) {
1299 bool success = DoIGetQuick<Primitive::kPrimShort>(shadow_frame, inst, inst_data);
1300 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1301 }
1302 HANDLE_INSTRUCTION_END();
1303
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001304 HANDLE_INSTRUCTION_START(IGET_WIDE_QUICK) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001305 bool success = DoIGetQuick<Primitive::kPrimLong>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001306 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1307 }
1308 HANDLE_INSTRUCTION_END();
1309
1310 HANDLE_INSTRUCTION_START(IGET_OBJECT_QUICK) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001311 bool success = DoIGetQuick<Primitive::kPrimNot>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001312 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1313 }
1314 HANDLE_INSTRUCTION_END();
1315
1316 HANDLE_INSTRUCTION_START(SGET_BOOLEAN) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001317 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimBoolean, do_access_check>(
1318 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001319 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1320 }
1321 HANDLE_INSTRUCTION_END();
1322
1323 HANDLE_INSTRUCTION_START(SGET_BYTE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001324 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimByte, do_access_check>(
1325 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001326 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1327 }
1328 HANDLE_INSTRUCTION_END();
1329
1330 HANDLE_INSTRUCTION_START(SGET_CHAR) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001331 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimChar, do_access_check>(
1332 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001333 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1334 }
1335 HANDLE_INSTRUCTION_END();
1336
1337 HANDLE_INSTRUCTION_START(SGET_SHORT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001338 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimShort, do_access_check>(
1339 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001340 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1341 }
1342 HANDLE_INSTRUCTION_END();
1343
1344 HANDLE_INSTRUCTION_START(SGET) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001345 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimInt, do_access_check>(
1346 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001347 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1348 }
1349 HANDLE_INSTRUCTION_END();
1350
1351 HANDLE_INSTRUCTION_START(SGET_WIDE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001352 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimLong, do_access_check>(
1353 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001354 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1355 }
1356 HANDLE_INSTRUCTION_END();
1357
1358 HANDLE_INSTRUCTION_START(SGET_OBJECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001359 bool success = DoFieldGet<StaticObjectRead, Primitive::kPrimNot, do_access_check>(
1360 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001361 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1362 }
1363 HANDLE_INSTRUCTION_END();
1364
1365 HANDLE_INSTRUCTION_START(IPUT_BOOLEAN) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001366 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1367 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001368 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1369 }
1370 HANDLE_INSTRUCTION_END();
1371
1372 HANDLE_INSTRUCTION_START(IPUT_BYTE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001373 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimByte, do_access_check,
1374 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001375 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1376 }
1377 HANDLE_INSTRUCTION_END();
1378
1379 HANDLE_INSTRUCTION_START(IPUT_CHAR) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001380 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimChar, do_access_check,
1381 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001382 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1383 }
1384 HANDLE_INSTRUCTION_END();
1385
1386 HANDLE_INSTRUCTION_START(IPUT_SHORT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001387 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimShort, do_access_check,
1388 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001389 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1390 }
1391 HANDLE_INSTRUCTION_END();
1392
1393 HANDLE_INSTRUCTION_START(IPUT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001394 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimInt, do_access_check,
1395 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001396 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1397 }
1398 HANDLE_INSTRUCTION_END();
1399
1400 HANDLE_INSTRUCTION_START(IPUT_WIDE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001401 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimLong, do_access_check,
1402 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001403 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1404 }
1405 HANDLE_INSTRUCTION_END();
1406
1407 HANDLE_INSTRUCTION_START(IPUT_OBJECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001408 bool success = DoFieldPut<InstanceObjectWrite, Primitive::kPrimNot, do_access_check,
1409 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001410 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1411 }
1412 HANDLE_INSTRUCTION_END();
1413
1414 HANDLE_INSTRUCTION_START(IPUT_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001415 bool success = DoIPutQuick<Primitive::kPrimInt, transaction_active>(
1416 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001417 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1418 }
1419 HANDLE_INSTRUCTION_END();
1420
Fred Shih37f05ef2014-07-16 18:38:08 -07001421 HANDLE_INSTRUCTION_START(IPUT_BOOLEAN_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001422 bool success = DoIPutQuick<Primitive::kPrimBoolean, transaction_active>(
1423 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001424 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1425 }
1426 HANDLE_INSTRUCTION_END();
1427
1428 HANDLE_INSTRUCTION_START(IPUT_BYTE_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001429 bool success = DoIPutQuick<Primitive::kPrimByte, transaction_active>(
1430 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001431 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1432 }
1433 HANDLE_INSTRUCTION_END();
1434
1435 HANDLE_INSTRUCTION_START(IPUT_CHAR_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001436 bool success = DoIPutQuick<Primitive::kPrimChar, transaction_active>(
1437 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001438 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1439 }
1440 HANDLE_INSTRUCTION_END();
1441
1442 HANDLE_INSTRUCTION_START(IPUT_SHORT_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001443 bool success = DoIPutQuick<Primitive::kPrimShort, transaction_active>(
1444 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001445 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1446 }
1447 HANDLE_INSTRUCTION_END();
1448
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001449 HANDLE_INSTRUCTION_START(IPUT_WIDE_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001450 bool success = DoIPutQuick<Primitive::kPrimLong, transaction_active>(
1451 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001452 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1453 }
1454 HANDLE_INSTRUCTION_END();
1455
1456 HANDLE_INSTRUCTION_START(IPUT_OBJECT_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001457 bool success = DoIPutQuick<Primitive::kPrimNot, transaction_active>(
1458 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001459 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1460 }
1461 HANDLE_INSTRUCTION_END();
1462
1463 HANDLE_INSTRUCTION_START(SPUT_BOOLEAN) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001464 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1465 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001466 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1467 }
1468 HANDLE_INSTRUCTION_END();
1469
1470 HANDLE_INSTRUCTION_START(SPUT_BYTE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001471 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimByte, do_access_check,
1472 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001473 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1474 }
1475 HANDLE_INSTRUCTION_END();
1476
1477 HANDLE_INSTRUCTION_START(SPUT_CHAR) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001478 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimChar, do_access_check,
1479 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001480 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1481 }
1482 HANDLE_INSTRUCTION_END();
1483
1484 HANDLE_INSTRUCTION_START(SPUT_SHORT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001485 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimShort, do_access_check,
1486 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001487 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1488 }
1489 HANDLE_INSTRUCTION_END();
1490
1491 HANDLE_INSTRUCTION_START(SPUT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001492 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimInt, do_access_check,
1493 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001494 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1495 }
1496 HANDLE_INSTRUCTION_END();
1497
1498 HANDLE_INSTRUCTION_START(SPUT_WIDE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001499 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimLong, do_access_check,
1500 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001501 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1502 }
1503 HANDLE_INSTRUCTION_END();
1504
1505 HANDLE_INSTRUCTION_START(SPUT_OBJECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001506 bool success = DoFieldPut<StaticObjectWrite, Primitive::kPrimNot, do_access_check,
1507 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001508 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1509 }
1510 HANDLE_INSTRUCTION_END();
1511
1512 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001513 bool success = DoInvoke<kVirtual, false, do_access_check>(
1514 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001515 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001516 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1517 }
1518 HANDLE_INSTRUCTION_END();
1519
1520 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001521 bool success = DoInvoke<kVirtual, true, do_access_check>(
1522 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001523 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001524 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1525 }
1526 HANDLE_INSTRUCTION_END();
1527
1528 HANDLE_INSTRUCTION_START(INVOKE_SUPER) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001529 bool success = DoInvoke<kSuper, false, do_access_check>(
1530 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001531 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001532 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1533 }
1534 HANDLE_INSTRUCTION_END();
1535
1536 HANDLE_INSTRUCTION_START(INVOKE_SUPER_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001537 bool success = DoInvoke<kSuper, true, do_access_check>(
1538 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001539 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001540 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1541 }
1542 HANDLE_INSTRUCTION_END();
1543
1544 HANDLE_INSTRUCTION_START(INVOKE_DIRECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001545 bool success = DoInvoke<kDirect, false, do_access_check>(
1546 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001547 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001548 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1549 }
1550 HANDLE_INSTRUCTION_END();
1551
1552 HANDLE_INSTRUCTION_START(INVOKE_DIRECT_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001553 bool success = DoInvoke<kDirect, true, do_access_check>(
1554 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001555 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001556 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1557 }
1558 HANDLE_INSTRUCTION_END();
1559
1560 HANDLE_INSTRUCTION_START(INVOKE_INTERFACE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001561 bool success = DoInvoke<kInterface, false, do_access_check>(
1562 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001563 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001564 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1565 }
1566 HANDLE_INSTRUCTION_END();
1567
1568 HANDLE_INSTRUCTION_START(INVOKE_INTERFACE_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001569 bool success = DoInvoke<kInterface, true, do_access_check>(
1570 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001571 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001572 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1573 }
1574 HANDLE_INSTRUCTION_END();
1575
1576 HANDLE_INSTRUCTION_START(INVOKE_STATIC) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001577 bool success = DoInvoke<kStatic, false, do_access_check>(
1578 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001579 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001580 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1581 }
1582 HANDLE_INSTRUCTION_END();
1583
1584 HANDLE_INSTRUCTION_START(INVOKE_STATIC_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001585 bool success = DoInvoke<kStatic, true, do_access_check>(
1586 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001587 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001588 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1589 }
1590 HANDLE_INSTRUCTION_END();
1591
1592 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001593 bool success = DoInvokeVirtualQuick<false>(
1594 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001595 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001596 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1597 }
1598 HANDLE_INSTRUCTION_END();
1599
1600 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_RANGE_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001601 bool success = DoInvokeVirtualQuick<true>(
1602 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001603 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001604 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1605 }
1606 HANDLE_INSTRUCTION_END();
1607
1608 HANDLE_INSTRUCTION_START(NEG_INT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001609 shadow_frame.SetVReg(
1610 inst->VRegA_12x(inst_data), -shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001611 ADVANCE(1);
1612 HANDLE_INSTRUCTION_END();
1613
1614 HANDLE_INSTRUCTION_START(NOT_INT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001615 shadow_frame.SetVReg(
1616 inst->VRegA_12x(inst_data), ~shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001617 ADVANCE(1);
1618 HANDLE_INSTRUCTION_END();
1619
1620 HANDLE_INSTRUCTION_START(NEG_LONG)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001621 shadow_frame.SetVRegLong(
1622 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001623 ADVANCE(1);
1624 HANDLE_INSTRUCTION_END();
1625
1626 HANDLE_INSTRUCTION_START(NOT_LONG)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001627 shadow_frame.SetVRegLong(
1628 inst->VRegA_12x(inst_data), ~shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001629 ADVANCE(1);
1630 HANDLE_INSTRUCTION_END();
1631
1632 HANDLE_INSTRUCTION_START(NEG_FLOAT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001633 shadow_frame.SetVRegFloat(
1634 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001635 ADVANCE(1);
1636 HANDLE_INSTRUCTION_END();
1637
1638 HANDLE_INSTRUCTION_START(NEG_DOUBLE)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001639 shadow_frame.SetVRegDouble(
1640 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001641 ADVANCE(1);
1642 HANDLE_INSTRUCTION_END();
1643
1644 HANDLE_INSTRUCTION_START(INT_TO_LONG)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001645 shadow_frame.SetVRegLong(
1646 inst->VRegA_12x(inst_data), shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001647 ADVANCE(1);
1648 HANDLE_INSTRUCTION_END();
1649
1650 HANDLE_INSTRUCTION_START(INT_TO_FLOAT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001651 shadow_frame.SetVRegFloat(
1652 inst->VRegA_12x(inst_data), shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001653 ADVANCE(1);
1654 HANDLE_INSTRUCTION_END();
1655
1656 HANDLE_INSTRUCTION_START(INT_TO_DOUBLE)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001657 shadow_frame.SetVRegDouble(
1658 inst->VRegA_12x(inst_data), shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001659 ADVANCE(1);
1660 HANDLE_INSTRUCTION_END();
1661
1662 HANDLE_INSTRUCTION_START(LONG_TO_INT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001663 shadow_frame.SetVReg(
1664 inst->VRegA_12x(inst_data), shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001665 ADVANCE(1);
1666 HANDLE_INSTRUCTION_END();
1667
1668 HANDLE_INSTRUCTION_START(LONG_TO_FLOAT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001669 shadow_frame.SetVRegFloat(
1670 inst->VRegA_12x(inst_data), shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001671 ADVANCE(1);
1672 HANDLE_INSTRUCTION_END();
1673
1674 HANDLE_INSTRUCTION_START(LONG_TO_DOUBLE)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001675 shadow_frame.SetVRegDouble(
1676 inst->VRegA_12x(inst_data), shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001677 ADVANCE(1);
1678 HANDLE_INSTRUCTION_END();
1679
1680 HANDLE_INSTRUCTION_START(FLOAT_TO_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001681 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001682 int32_t result = art_float_to_integral<int32_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001683 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001684 ADVANCE(1);
1685 }
1686 HANDLE_INSTRUCTION_END();
1687
1688 HANDLE_INSTRUCTION_START(FLOAT_TO_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001689 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001690 int64_t result = art_float_to_integral<int64_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001691 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001692 ADVANCE(1);
1693 }
1694 HANDLE_INSTRUCTION_END();
1695
1696 HANDLE_INSTRUCTION_START(FLOAT_TO_DOUBLE)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001697 shadow_frame.SetVRegDouble(
1698 inst->VRegA_12x(inst_data), shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001699 ADVANCE(1);
1700 HANDLE_INSTRUCTION_END();
1701
1702 HANDLE_INSTRUCTION_START(DOUBLE_TO_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001703 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001704 int32_t result = art_float_to_integral<int32_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001705 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001706 ADVANCE(1);
1707 }
1708 HANDLE_INSTRUCTION_END();
1709
1710 HANDLE_INSTRUCTION_START(DOUBLE_TO_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001711 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001712 int64_t result = art_float_to_integral<int64_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001713 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001714 ADVANCE(1);
1715 }
1716 HANDLE_INSTRUCTION_END();
1717
1718 HANDLE_INSTRUCTION_START(DOUBLE_TO_FLOAT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001719 shadow_frame.SetVRegFloat(
1720 inst->VRegA_12x(inst_data), shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001721 ADVANCE(1);
1722 HANDLE_INSTRUCTION_END();
1723
1724 HANDLE_INSTRUCTION_START(INT_TO_BYTE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001725 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1726 static_cast<int8_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001727 ADVANCE(1);
1728 HANDLE_INSTRUCTION_END();
1729
1730 HANDLE_INSTRUCTION_START(INT_TO_CHAR)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001731 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1732 static_cast<uint16_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001733 ADVANCE(1);
1734 HANDLE_INSTRUCTION_END();
1735
1736 HANDLE_INSTRUCTION_START(INT_TO_SHORT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001737 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1738 static_cast<int16_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001739 ADVANCE(1);
1740 HANDLE_INSTRUCTION_END();
1741
1742 HANDLE_INSTRUCTION_START(ADD_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001743 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001744 SafeAdd(shadow_frame.GetVReg(inst->VRegB_23x()),
1745 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001746 ADVANCE(2);
1747 HANDLE_INSTRUCTION_END();
1748
1749 HANDLE_INSTRUCTION_START(SUB_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001750 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001751 SafeSub(shadow_frame.GetVReg(inst->VRegB_23x()),
1752 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001753 ADVANCE(2);
1754 HANDLE_INSTRUCTION_END();
1755
1756 HANDLE_INSTRUCTION_START(MUL_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001757 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001758 SafeMul(shadow_frame.GetVReg(inst->VRegB_23x()),
1759 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001760 ADVANCE(2);
1761 HANDLE_INSTRUCTION_END();
1762
1763 HANDLE_INSTRUCTION_START(DIV_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001764 bool success = DoIntDivide(shadow_frame, inst->VRegA_23x(inst_data),
1765 shadow_frame.GetVReg(inst->VRegB_23x()),
1766 shadow_frame.GetVReg(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001767 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1768 }
1769 HANDLE_INSTRUCTION_END();
1770
1771 HANDLE_INSTRUCTION_START(REM_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001772 bool success = DoIntRemainder(shadow_frame, inst->VRegA_23x(inst_data),
1773 shadow_frame.GetVReg(inst->VRegB_23x()),
1774 shadow_frame.GetVReg(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001775 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1776 }
1777 HANDLE_INSTRUCTION_END();
1778
1779 HANDLE_INSTRUCTION_START(SHL_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001780 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001781 shadow_frame.GetVReg(inst->VRegB_23x()) <<
1782 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1783 ADVANCE(2);
1784 HANDLE_INSTRUCTION_END();
1785
1786 HANDLE_INSTRUCTION_START(SHR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001787 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001788 shadow_frame.GetVReg(inst->VRegB_23x()) >>
1789 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1790 ADVANCE(2);
1791 HANDLE_INSTRUCTION_END();
1792
1793 HANDLE_INSTRUCTION_START(USHR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001794 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001795 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_23x())) >>
1796 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1797 ADVANCE(2);
1798 HANDLE_INSTRUCTION_END();
1799
1800 HANDLE_INSTRUCTION_START(AND_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001801 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001802 shadow_frame.GetVReg(inst->VRegB_23x()) &
1803 shadow_frame.GetVReg(inst->VRegC_23x()));
1804 ADVANCE(2);
1805 HANDLE_INSTRUCTION_END();
1806
1807 HANDLE_INSTRUCTION_START(OR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001808 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001809 shadow_frame.GetVReg(inst->VRegB_23x()) |
1810 shadow_frame.GetVReg(inst->VRegC_23x()));
1811 ADVANCE(2);
1812 HANDLE_INSTRUCTION_END();
1813
1814 HANDLE_INSTRUCTION_START(XOR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001815 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001816 shadow_frame.GetVReg(inst->VRegB_23x()) ^
1817 shadow_frame.GetVReg(inst->VRegC_23x()));
1818 ADVANCE(2);
1819 HANDLE_INSTRUCTION_END();
1820
1821 HANDLE_INSTRUCTION_START(ADD_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001822 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001823 SafeAdd(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1824 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001825 ADVANCE(2);
1826 HANDLE_INSTRUCTION_END();
1827
1828 HANDLE_INSTRUCTION_START(SUB_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001829 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001830 SafeSub(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1831 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001832 ADVANCE(2);
1833 HANDLE_INSTRUCTION_END();
1834
1835 HANDLE_INSTRUCTION_START(MUL_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001836 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001837 SafeMul(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1838 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001839 ADVANCE(2);
1840 HANDLE_INSTRUCTION_END();
1841
1842 HANDLE_INSTRUCTION_START(DIV_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001843 bool success = DoLongDivide(shadow_frame, inst->VRegA_23x(inst_data),
1844 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1845 shadow_frame.GetVRegLong(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001846 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1847 }
1848 HANDLE_INSTRUCTION_END();
1849
1850 HANDLE_INSTRUCTION_START(REM_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001851 bool success = DoLongRemainder(shadow_frame, inst->VRegA_23x(inst_data),
1852 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1853 shadow_frame.GetVRegLong(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001854 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1855 }
1856 HANDLE_INSTRUCTION_END();
1857
1858 HANDLE_INSTRUCTION_START(AND_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001859 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001860 shadow_frame.GetVRegLong(inst->VRegB_23x()) &
1861 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1862 ADVANCE(2);
1863 HANDLE_INSTRUCTION_END();
1864
1865 HANDLE_INSTRUCTION_START(OR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001866 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001867 shadow_frame.GetVRegLong(inst->VRegB_23x()) |
1868 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1869 ADVANCE(2);
1870 HANDLE_INSTRUCTION_END();
1871
1872 HANDLE_INSTRUCTION_START(XOR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001873 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001874 shadow_frame.GetVRegLong(inst->VRegB_23x()) ^
1875 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1876 ADVANCE(2);
1877 HANDLE_INSTRUCTION_END();
1878
1879 HANDLE_INSTRUCTION_START(SHL_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001880 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001881 shadow_frame.GetVRegLong(inst->VRegB_23x()) <<
1882 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1883 ADVANCE(2);
1884 HANDLE_INSTRUCTION_END();
1885
1886 HANDLE_INSTRUCTION_START(SHR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001887 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001888 shadow_frame.GetVRegLong(inst->VRegB_23x()) >>
1889 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1890 ADVANCE(2);
1891 HANDLE_INSTRUCTION_END();
1892
1893 HANDLE_INSTRUCTION_START(USHR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001894 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001895 static_cast<uint64_t>(shadow_frame.GetVRegLong(inst->VRegB_23x())) >>
1896 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1897 ADVANCE(2);
1898 HANDLE_INSTRUCTION_END();
1899
1900 HANDLE_INSTRUCTION_START(ADD_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001901 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001902 shadow_frame.GetVRegFloat(inst->VRegB_23x()) +
1903 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1904 ADVANCE(2);
1905 HANDLE_INSTRUCTION_END();
1906
1907 HANDLE_INSTRUCTION_START(SUB_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001908 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001909 shadow_frame.GetVRegFloat(inst->VRegB_23x()) -
1910 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1911 ADVANCE(2);
1912 HANDLE_INSTRUCTION_END();
1913
1914 HANDLE_INSTRUCTION_START(MUL_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001915 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001916 shadow_frame.GetVRegFloat(inst->VRegB_23x()) *
1917 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1918 ADVANCE(2);
1919 HANDLE_INSTRUCTION_END();
1920
1921 HANDLE_INSTRUCTION_START(DIV_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001922 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001923 shadow_frame.GetVRegFloat(inst->VRegB_23x()) /
1924 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1925 ADVANCE(2);
1926 HANDLE_INSTRUCTION_END();
1927
1928 HANDLE_INSTRUCTION_START(REM_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001929 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001930 fmodf(shadow_frame.GetVRegFloat(inst->VRegB_23x()),
1931 shadow_frame.GetVRegFloat(inst->VRegC_23x())));
1932 ADVANCE(2);
1933 HANDLE_INSTRUCTION_END();
1934
1935 HANDLE_INSTRUCTION_START(ADD_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001936 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001937 shadow_frame.GetVRegDouble(inst->VRegB_23x()) +
1938 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1939 ADVANCE(2);
1940 HANDLE_INSTRUCTION_END();
1941
1942 HANDLE_INSTRUCTION_START(SUB_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001943 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001944 shadow_frame.GetVRegDouble(inst->VRegB_23x()) -
1945 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1946 ADVANCE(2);
1947 HANDLE_INSTRUCTION_END();
1948
1949 HANDLE_INSTRUCTION_START(MUL_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001950 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001951 shadow_frame.GetVRegDouble(inst->VRegB_23x()) *
1952 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1953 ADVANCE(2);
1954 HANDLE_INSTRUCTION_END();
1955
1956 HANDLE_INSTRUCTION_START(DIV_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001957 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001958 shadow_frame.GetVRegDouble(inst->VRegB_23x()) /
1959 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1960 ADVANCE(2);
1961 HANDLE_INSTRUCTION_END();
1962
1963 HANDLE_INSTRUCTION_START(REM_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001964 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001965 fmod(shadow_frame.GetVRegDouble(inst->VRegB_23x()),
1966 shadow_frame.GetVRegDouble(inst->VRegC_23x())));
1967 ADVANCE(2);
1968 HANDLE_INSTRUCTION_END();
1969
1970 HANDLE_INSTRUCTION_START(ADD_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001971 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001972 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07001973 SafeAdd(shadow_frame.GetVReg(vregA),
1974 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001975 ADVANCE(1);
1976 }
1977 HANDLE_INSTRUCTION_END();
1978
1979 HANDLE_INSTRUCTION_START(SUB_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001980 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001981 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07001982 SafeSub(shadow_frame.GetVReg(vregA),
1983 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001984 ADVANCE(1);
1985 }
1986 HANDLE_INSTRUCTION_END();
1987
1988 HANDLE_INSTRUCTION_START(MUL_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001989 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001990 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07001991 SafeMul(shadow_frame.GetVReg(vregA),
1992 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001993 ADVANCE(1);
1994 }
1995 HANDLE_INSTRUCTION_END();
1996
1997 HANDLE_INSTRUCTION_START(DIV_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001998 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001999 bool success = DoIntDivide(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002000 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002001 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2002 }
2003 HANDLE_INSTRUCTION_END();
2004
2005 HANDLE_INSTRUCTION_START(REM_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002006 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002007 bool success = DoIntRemainder(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002008 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002009 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2010 }
2011 HANDLE_INSTRUCTION_END();
2012
2013 HANDLE_INSTRUCTION_START(SHL_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002014 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002015 shadow_frame.SetVReg(vregA,
2016 shadow_frame.GetVReg(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002017 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002018 ADVANCE(1);
2019 }
2020 HANDLE_INSTRUCTION_END();
2021
2022 HANDLE_INSTRUCTION_START(SHR_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002023 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002024 shadow_frame.SetVReg(vregA,
2025 shadow_frame.GetVReg(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002026 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002027 ADVANCE(1);
2028 }
2029 HANDLE_INSTRUCTION_END();
2030
2031 HANDLE_INSTRUCTION_START(USHR_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002032 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002033 shadow_frame.SetVReg(vregA,
2034 static_cast<uint32_t>(shadow_frame.GetVReg(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002035 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002036 ADVANCE(1);
2037 }
2038 HANDLE_INSTRUCTION_END();
2039
2040 HANDLE_INSTRUCTION_START(AND_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002041 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002042 shadow_frame.SetVReg(vregA,
2043 shadow_frame.GetVReg(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002044 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002045 ADVANCE(1);
2046 }
2047 HANDLE_INSTRUCTION_END();
2048
2049 HANDLE_INSTRUCTION_START(OR_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002050 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002051 shadow_frame.SetVReg(vregA,
2052 shadow_frame.GetVReg(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002053 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002054 ADVANCE(1);
2055 }
2056 HANDLE_INSTRUCTION_END();
2057
2058 HANDLE_INSTRUCTION_START(XOR_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002059 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002060 shadow_frame.SetVReg(vregA,
2061 shadow_frame.GetVReg(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002062 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002063 ADVANCE(1);
2064 }
2065 HANDLE_INSTRUCTION_END();
2066
2067 HANDLE_INSTRUCTION_START(ADD_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002068 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002069 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002070 SafeAdd(shadow_frame.GetVRegLong(vregA),
2071 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002072 ADVANCE(1);
2073 }
2074 HANDLE_INSTRUCTION_END();
2075
2076 HANDLE_INSTRUCTION_START(SUB_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002077 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002078 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002079 SafeSub(shadow_frame.GetVRegLong(vregA),
2080 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002081 ADVANCE(1);
2082 }
2083 HANDLE_INSTRUCTION_END();
2084
2085 HANDLE_INSTRUCTION_START(MUL_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002086 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002087 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002088 SafeMul(shadow_frame.GetVRegLong(vregA),
2089 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002090 ADVANCE(1);
2091 }
2092 HANDLE_INSTRUCTION_END();
2093
2094 HANDLE_INSTRUCTION_START(DIV_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002095 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002096 bool success = DoLongDivide(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002097 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002098 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2099 }
2100 HANDLE_INSTRUCTION_END();
2101
2102 HANDLE_INSTRUCTION_START(REM_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002103 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002104 bool success = DoLongRemainder(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002105 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002106 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2107 }
2108 HANDLE_INSTRUCTION_END();
2109
2110 HANDLE_INSTRUCTION_START(AND_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002111 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002112 shadow_frame.SetVRegLong(vregA,
2113 shadow_frame.GetVRegLong(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002114 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002115 ADVANCE(1);
2116 }
2117 HANDLE_INSTRUCTION_END();
2118
2119 HANDLE_INSTRUCTION_START(OR_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002120 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002121 shadow_frame.SetVRegLong(vregA,
2122 shadow_frame.GetVRegLong(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002123 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002124 ADVANCE(1);
2125 }
2126 HANDLE_INSTRUCTION_END();
2127
2128 HANDLE_INSTRUCTION_START(XOR_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002129 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002130 shadow_frame.SetVRegLong(vregA,
2131 shadow_frame.GetVRegLong(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002132 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002133 ADVANCE(1);
2134 }
2135 HANDLE_INSTRUCTION_END();
2136
2137 HANDLE_INSTRUCTION_START(SHL_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002138 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002139 shadow_frame.SetVRegLong(vregA,
2140 shadow_frame.GetVRegLong(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002141 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002142 ADVANCE(1);
2143 }
2144 HANDLE_INSTRUCTION_END();
2145
2146 HANDLE_INSTRUCTION_START(SHR_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002147 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002148 shadow_frame.SetVRegLong(vregA,
2149 shadow_frame.GetVRegLong(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002150 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002151 ADVANCE(1);
2152 }
2153 HANDLE_INSTRUCTION_END();
2154
2155 HANDLE_INSTRUCTION_START(USHR_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002156 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002157 shadow_frame.SetVRegLong(vregA,
2158 static_cast<uint64_t>(shadow_frame.GetVRegLong(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002159 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002160 ADVANCE(1);
2161 }
2162 HANDLE_INSTRUCTION_END();
2163
2164 HANDLE_INSTRUCTION_START(ADD_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002165 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002166 shadow_frame.SetVRegFloat(vregA,
2167 shadow_frame.GetVRegFloat(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002168 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002169 ADVANCE(1);
2170 }
2171 HANDLE_INSTRUCTION_END();
2172
2173 HANDLE_INSTRUCTION_START(SUB_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002174 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002175 shadow_frame.SetVRegFloat(vregA,
2176 shadow_frame.GetVRegFloat(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002177 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002178 ADVANCE(1);
2179 }
2180 HANDLE_INSTRUCTION_END();
2181
2182 HANDLE_INSTRUCTION_START(MUL_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002183 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002184 shadow_frame.SetVRegFloat(vregA,
2185 shadow_frame.GetVRegFloat(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002186 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002187 ADVANCE(1);
2188 }
2189 HANDLE_INSTRUCTION_END();
2190
2191 HANDLE_INSTRUCTION_START(DIV_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002192 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002193 shadow_frame.SetVRegFloat(vregA,
2194 shadow_frame.GetVRegFloat(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002195 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002196 ADVANCE(1);
2197 }
2198 HANDLE_INSTRUCTION_END();
2199
2200 HANDLE_INSTRUCTION_START(REM_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002201 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002202 shadow_frame.SetVRegFloat(vregA,
2203 fmodf(shadow_frame.GetVRegFloat(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002204 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002205 ADVANCE(1);
2206 }
2207 HANDLE_INSTRUCTION_END();
2208
2209 HANDLE_INSTRUCTION_START(ADD_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002210 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002211 shadow_frame.SetVRegDouble(vregA,
2212 shadow_frame.GetVRegDouble(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002213 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002214 ADVANCE(1);
2215 }
2216 HANDLE_INSTRUCTION_END();
2217
2218 HANDLE_INSTRUCTION_START(SUB_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002219 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002220 shadow_frame.SetVRegDouble(vregA,
2221 shadow_frame.GetVRegDouble(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002222 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002223 ADVANCE(1);
2224 }
2225 HANDLE_INSTRUCTION_END();
2226
2227 HANDLE_INSTRUCTION_START(MUL_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002228 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002229 shadow_frame.SetVRegDouble(vregA,
2230 shadow_frame.GetVRegDouble(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002231 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002232 ADVANCE(1);
2233 }
2234 HANDLE_INSTRUCTION_END();
2235
2236 HANDLE_INSTRUCTION_START(DIV_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002237 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002238 shadow_frame.SetVRegDouble(vregA,
2239 shadow_frame.GetVRegDouble(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002240 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002241 ADVANCE(1);
2242 }
2243 HANDLE_INSTRUCTION_END();
2244
2245 HANDLE_INSTRUCTION_START(REM_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002246 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002247 shadow_frame.SetVRegDouble(vregA,
2248 fmod(shadow_frame.GetVRegDouble(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002249 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002250 ADVANCE(1);
2251 }
2252 HANDLE_INSTRUCTION_END();
2253
2254 HANDLE_INSTRUCTION_START(ADD_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002255 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002256 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2257 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002258 ADVANCE(2);
2259 HANDLE_INSTRUCTION_END();
2260
2261 HANDLE_INSTRUCTION_START(RSUB_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002262 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002263 SafeSub(inst->VRegC_22s(),
2264 shadow_frame.GetVReg(inst->VRegB_22s(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002265 ADVANCE(2);
2266 HANDLE_INSTRUCTION_END();
2267
2268 HANDLE_INSTRUCTION_START(MUL_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002269 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002270 SafeMul(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2271 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002272 ADVANCE(2);
2273 HANDLE_INSTRUCTION_END();
2274
2275 HANDLE_INSTRUCTION_START(DIV_INT_LIT16) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002276 bool success = DoIntDivide(
2277 shadow_frame, inst->VRegA_22s(inst_data), shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2278 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002279 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2280 }
2281 HANDLE_INSTRUCTION_END();
2282
2283 HANDLE_INSTRUCTION_START(REM_INT_LIT16) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002284 bool success = DoIntRemainder(
2285 shadow_frame, inst->VRegA_22s(inst_data), shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2286 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002287 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2288 }
2289 HANDLE_INSTRUCTION_END();
2290
2291 HANDLE_INSTRUCTION_START(AND_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002292 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2293 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) &
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002294 inst->VRegC_22s());
2295 ADVANCE(2);
2296 HANDLE_INSTRUCTION_END();
2297
2298 HANDLE_INSTRUCTION_START(OR_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002299 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2300 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) |
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002301 inst->VRegC_22s());
2302 ADVANCE(2);
2303 HANDLE_INSTRUCTION_END();
2304
2305 HANDLE_INSTRUCTION_START(XOR_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002306 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2307 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) ^
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002308 inst->VRegC_22s());
2309 ADVANCE(2);
2310 HANDLE_INSTRUCTION_END();
2311
2312 HANDLE_INSTRUCTION_START(ADD_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002313 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002314 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22b()),
2315 inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002316 ADVANCE(2);
2317 HANDLE_INSTRUCTION_END();
2318
2319 HANDLE_INSTRUCTION_START(RSUB_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002320 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002321 SafeSub(inst->VRegC_22b(),
2322 shadow_frame.GetVReg(inst->VRegB_22b())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002323 ADVANCE(2);
2324 HANDLE_INSTRUCTION_END();
2325
2326 HANDLE_INSTRUCTION_START(MUL_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002327 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002328 SafeMul(shadow_frame.GetVReg(inst->VRegB_22b()),
2329 inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002330 ADVANCE(2);
2331 HANDLE_INSTRUCTION_END();
2332
2333 HANDLE_INSTRUCTION_START(DIV_INT_LIT8) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002334 bool success = DoIntDivide(shadow_frame, inst->VRegA_22b(inst_data),
2335 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002336 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2337 }
2338 HANDLE_INSTRUCTION_END();
2339
2340 HANDLE_INSTRUCTION_START(REM_INT_LIT8) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002341 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22b(inst_data),
2342 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002343 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2344 }
2345 HANDLE_INSTRUCTION_END();
2346
2347 HANDLE_INSTRUCTION_START(AND_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002348 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002349 shadow_frame.GetVReg(inst->VRegB_22b()) &
2350 inst->VRegC_22b());
2351 ADVANCE(2);
2352 HANDLE_INSTRUCTION_END();
2353
2354 HANDLE_INSTRUCTION_START(OR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002355 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002356 shadow_frame.GetVReg(inst->VRegB_22b()) |
2357 inst->VRegC_22b());
2358 ADVANCE(2);
2359 HANDLE_INSTRUCTION_END();
2360
2361 HANDLE_INSTRUCTION_START(XOR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002362 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002363 shadow_frame.GetVReg(inst->VRegB_22b()) ^
2364 inst->VRegC_22b());
2365 ADVANCE(2);
2366 HANDLE_INSTRUCTION_END();
2367
2368 HANDLE_INSTRUCTION_START(SHL_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002369 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002370 shadow_frame.GetVReg(inst->VRegB_22b()) <<
2371 (inst->VRegC_22b() & 0x1f));
2372 ADVANCE(2);
2373 HANDLE_INSTRUCTION_END();
2374
2375 HANDLE_INSTRUCTION_START(SHR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002376 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002377 shadow_frame.GetVReg(inst->VRegB_22b()) >>
2378 (inst->VRegC_22b() & 0x1f));
2379 ADVANCE(2);
2380 HANDLE_INSTRUCTION_END();
2381
2382 HANDLE_INSTRUCTION_START(USHR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002383 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002384 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_22b())) >>
2385 (inst->VRegC_22b() & 0x1f));
2386 ADVANCE(2);
2387 HANDLE_INSTRUCTION_END();
2388
2389 HANDLE_INSTRUCTION_START(UNUSED_3E)
Ian Rogerse94652f2014-12-02 11:13:19 -08002390 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002391 HANDLE_INSTRUCTION_END();
2392
2393 HANDLE_INSTRUCTION_START(UNUSED_3F)
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_40)
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_41)
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_42)
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_43)
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_79)
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_7A)
Ian Rogerse94652f2014-12-02 11:13:19 -08002418 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002419 HANDLE_INSTRUCTION_END();
2420
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002421 HANDLE_INSTRUCTION_START(UNUSED_F3)
Ian Rogerse94652f2014-12-02 11:13:19 -08002422 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002423 HANDLE_INSTRUCTION_END();
2424
2425 HANDLE_INSTRUCTION_START(UNUSED_F4)
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_F5)
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_F6)
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_F7)
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_F8)
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_F9)
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_FA)
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_FB)
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_FC)
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_FD)
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_FE)
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_FF)
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 exception_pending_label: {
2474 CHECK(self->IsExceptionPending());
Sebastien Hertz1eda2262013-09-09 16:53:14 +02002475 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -07002476 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +02002477 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +02002478 }
Sebastien Hertzee1997a2013-09-19 14:47:09 +02002479 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002480 uint32_t found_dex_pc = FindNextInstructionFollowingException(self, shadow_frame, dex_pc,
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002481 instrumentation);
2482 if (found_dex_pc == DexFile::kDexNoIndex) {
2483 return JValue(); /* Handled in caller. */
2484 } else {
2485 int32_t displacement = static_cast<int32_t>(found_dex_pc) - static_cast<int32_t>(dex_pc);
2486 ADVANCE(displacement);
2487 }
2488 }
2489
Sebastien Hertz8379b222014-02-24 17:38:15 +01002490// Create alternative instruction handlers dedicated to instrumentation.
2491// Return instructions must not call Instrumentation::DexPcMovedEvent since they already call
2492// Instrumentation::MethodExited. This is to avoid posting debugger events twice for this location.
Sebastien Hertze713d932014-05-15 10:48:53 +02002493// Note: we do not use the kReturn instruction flag here (to test the instruction is a return). The
2494// compiler seems to not evaluate "(Instruction::FlagsOf(Instruction::code) & kReturn) != 0" to
2495// a constant condition that would remove the "if" statement so the test is free.
Sebastien Hertz9d6bf692015-04-10 12:12:33 +02002496#define INSTRUMENTATION_INSTRUCTION_HANDLER(o, code, n, f, r, i, a, v) \
2497 alt_op_##code: { \
2498 Runtime* const runtime = Runtime::Current(); \
2499 const instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation(); \
2500 if (UNLIKELY(instrumentation->HasDexPcListeners())) { \
2501 Object* this_object = shadow_frame.GetThisObject(code_item->ins_size_); \
2502 instrumentation->DexPcMovedEvent(self, this_object, shadow_frame.GetMethod(), dex_pc); \
2503 } \
2504 UPDATE_HANDLER_TABLE(); \
2505 goto *handlersTable[instrumentation::kMainHandlerTable][Instruction::code]; \
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002506 }
2507#include "dex_instruction_list.h"
2508 DEX_INSTRUCTION_LIST(INSTRUMENTATION_INSTRUCTION_HANDLER)
2509#undef DEX_INSTRUCTION_LIST
2510#undef INSTRUMENTATION_INSTRUCTION_HANDLER
2511} // NOLINT(readability/fn_size)
2512
2513// Explicit definitions of ExecuteGotoImpl.
Sebastien Hertzc6714852013-09-30 16:42:32 +02002514template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) HOT_ATTR
Ian Rogerse94652f2014-12-02 11:13:19 -08002515JValue ExecuteGotoImpl<true, false>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002516 ShadowFrame& shadow_frame, JValue result_register);
Sebastien Hertzc6714852013-09-30 16:42:32 +02002517template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) HOT_ATTR
Ian Rogerse94652f2014-12-02 11:13:19 -08002518JValue ExecuteGotoImpl<false, false>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002519 ShadowFrame& shadow_frame, JValue result_register);
2520template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
Ian Rogerse94652f2014-12-02 11:13:19 -08002521JValue ExecuteGotoImpl<true, true>(Thread* self, const DexFile::CodeItem* code_item,
2522 ShadowFrame& shadow_frame, JValue result_register);
2523template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
2524JValue ExecuteGotoImpl<false, true>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002525 ShadowFrame& shadow_frame, JValue result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002526
2527} // namespace interpreter
2528} // namespace art
Colin Crosse84e4f72015-03-18 14:01:19 -07002529
2530#endif