blob: 878efba1a55aedbc8ae7e0a20ba5776b9feac815 [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;
Sebastien Hertz8379b222014-02-24 17:38:15 +0100159 bool notified_method_entry_event = false;
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200160 UPDATE_HANDLER_TABLE();
Sebastien Hertz270a0e12015-01-16 19:49:09 +0100161 if (LIKELY(dex_pc == 0)) { // We are entering the method as opposed to deoptimizing.
162 if (kIsDebugBuild) {
163 self->AssertNoPendingException();
164 }
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200165 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200166 if (UNLIKELY(instrumentation->HasMethodEntryListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200167 instrumentation->MethodEnterEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200168 shadow_frame.GetMethod(), 0);
Sebastien Hertz8379b222014-02-24 17:38:15 +0100169 notified_method_entry_event = true;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200170 }
171 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200172
173 // Jump to first instruction.
174 ADVANCE(0);
175 UNREACHABLE_CODE_CHECK();
176
177 HANDLE_INSTRUCTION_START(NOP)
178 ADVANCE(1);
179 HANDLE_INSTRUCTION_END();
180
181 HANDLE_INSTRUCTION_START(MOVE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200182 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
183 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200184 ADVANCE(1);
185 HANDLE_INSTRUCTION_END();
186
187 HANDLE_INSTRUCTION_START(MOVE_FROM16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200188 shadow_frame.SetVReg(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200189 shadow_frame.GetVReg(inst->VRegB_22x()));
190 ADVANCE(2);
191 HANDLE_INSTRUCTION_END();
192
193 HANDLE_INSTRUCTION_START(MOVE_16)
194 shadow_frame.SetVReg(inst->VRegA_32x(),
195 shadow_frame.GetVReg(inst->VRegB_32x()));
196 ADVANCE(3);
197 HANDLE_INSTRUCTION_END();
198
199 HANDLE_INSTRUCTION_START(MOVE_WIDE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200200 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
201 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200202 ADVANCE(1);
203 HANDLE_INSTRUCTION_END();
204
205 HANDLE_INSTRUCTION_START(MOVE_WIDE_FROM16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200206 shadow_frame.SetVRegLong(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200207 shadow_frame.GetVRegLong(inst->VRegB_22x()));
208 ADVANCE(2);
209 HANDLE_INSTRUCTION_END();
210
211 HANDLE_INSTRUCTION_START(MOVE_WIDE_16)
212 shadow_frame.SetVRegLong(inst->VRegA_32x(),
213 shadow_frame.GetVRegLong(inst->VRegB_32x()));
214 ADVANCE(3);
215 HANDLE_INSTRUCTION_END();
216
217 HANDLE_INSTRUCTION_START(MOVE_OBJECT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200218 shadow_frame.SetVRegReference(inst->VRegA_12x(inst_data),
219 shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200220 ADVANCE(1);
221 HANDLE_INSTRUCTION_END();
222
223 HANDLE_INSTRUCTION_START(MOVE_OBJECT_FROM16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200224 shadow_frame.SetVRegReference(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200225 shadow_frame.GetVRegReference(inst->VRegB_22x()));
226 ADVANCE(2);
227 HANDLE_INSTRUCTION_END();
228
229 HANDLE_INSTRUCTION_START(MOVE_OBJECT_16)
230 shadow_frame.SetVRegReference(inst->VRegA_32x(),
231 shadow_frame.GetVRegReference(inst->VRegB_32x()));
232 ADVANCE(3);
233 HANDLE_INSTRUCTION_END();
234
235 HANDLE_INSTRUCTION_START(MOVE_RESULT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200236 shadow_frame.SetVReg(inst->VRegA_11x(inst_data), result_register.GetI());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200237 ADVANCE(1);
238 HANDLE_INSTRUCTION_END();
239
240 HANDLE_INSTRUCTION_START(MOVE_RESULT_WIDE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200241 shadow_frame.SetVRegLong(inst->VRegA_11x(inst_data), result_register.GetJ());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200242 ADVANCE(1);
243 HANDLE_INSTRUCTION_END();
244
245 HANDLE_INSTRUCTION_START(MOVE_RESULT_OBJECT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200246 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), result_register.GetL());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200247 ADVANCE(1);
248 HANDLE_INSTRUCTION_END();
249
250 HANDLE_INSTRUCTION_START(MOVE_EXCEPTION) {
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000251 Throwable* exception = self->GetException();
Sebastien Hertz270a0e12015-01-16 19:49:09 +0100252 DCHECK(exception != nullptr) << "No pending exception on MOVE_EXCEPTION instruction";
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200253 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), exception);
Sebastien Hertz5c004902014-05-21 10:07:42 +0200254 self->ClearException();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200255 ADVANCE(1);
256 }
257 HANDLE_INSTRUCTION_END();
258
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700259 HANDLE_INSTRUCTION_START(RETURN_VOID_NO_BARRIER) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200260 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700261 self->AllowThreadSuspension();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200262 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200263 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200264 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200265 shadow_frame.GetMethod(), dex_pc,
266 result);
Sebastien Hertze713d932014-05-15 10:48:53 +0200267 } else if (UNLIKELY(instrumentation->HasDexPcListeners())) {
268 instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
269 shadow_frame.GetMethod(), dex_pc);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200270 }
271 return result;
272 }
273 HANDLE_INSTRUCTION_END();
274
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700275 HANDLE_INSTRUCTION_START(RETURN_VOID) {
Hans Boehm30359612014-05-21 17:46:23 -0700276 QuasiAtomic::ThreadFenceForConstructor();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200277 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700278 self->AllowThreadSuspension();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200279 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200280 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200281 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200282 shadow_frame.GetMethod(), dex_pc,
283 result);
Sebastien Hertze713d932014-05-15 10:48:53 +0200284 } else if (UNLIKELY(instrumentation->HasDexPcListeners())) {
285 instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
286 shadow_frame.GetMethod(), dex_pc);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200287 }
288 return result;
289 }
290 HANDLE_INSTRUCTION_END();
291
292 HANDLE_INSTRUCTION_START(RETURN) {
293 JValue result;
294 result.SetJ(0);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200295 result.SetI(shadow_frame.GetVReg(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700296 self->AllowThreadSuspension();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200297 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200298 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200299 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200300 shadow_frame.GetMethod(), dex_pc,
301 result);
Sebastien Hertze713d932014-05-15 10:48:53 +0200302 } else if (UNLIKELY(instrumentation->HasDexPcListeners())) {
303 instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
304 shadow_frame.GetMethod(), dex_pc);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200305 }
306 return result;
307 }
308 HANDLE_INSTRUCTION_END();
309
310 HANDLE_INSTRUCTION_START(RETURN_WIDE) {
311 JValue result;
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200312 result.SetJ(shadow_frame.GetVRegLong(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700313 self->AllowThreadSuspension();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200314 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200315 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200316 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200317 shadow_frame.GetMethod(), dex_pc,
318 result);
Sebastien Hertze713d932014-05-15 10:48:53 +0200319 } else if (UNLIKELY(instrumentation->HasDexPcListeners())) {
320 instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
321 shadow_frame.GetMethod(), dex_pc);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200322 }
323 return result;
324 }
325 HANDLE_INSTRUCTION_END();
326
327 HANDLE_INSTRUCTION_START(RETURN_OBJECT) {
328 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700329 self->AllowThreadSuspension();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700330 const uint8_t vreg_index = inst->VRegA_11x(inst_data);
331 Object* obj_result = shadow_frame.GetVRegReference(vreg_index);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700332 if (do_assignability_check && obj_result != nullptr) {
Ian Rogersded66a02014-10-28 18:12:55 -0700333 Class* return_type = shadow_frame.GetMethod()->GetReturnType();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700334 obj_result = shadow_frame.GetVRegReference(vreg_index);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700335 if (return_type == nullptr) {
Jeff Haoa3faaf42013-09-03 19:07:00 -0700336 // Return the pending exception.
337 HANDLE_PENDING_EXCEPTION();
338 }
339 if (!obj_result->VerifierInstanceOf(return_type)) {
340 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700341 std::string temp1, temp2;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000342 self->ThrowNewExceptionF("Ljava/lang/VirtualMachineError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700343 "Returning '%s' that is not instance of return type '%s'",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700344 obj_result->GetClass()->GetDescriptor(&temp1),
345 return_type->GetDescriptor(&temp2));
Jeff Haoa3faaf42013-09-03 19:07:00 -0700346 HANDLE_PENDING_EXCEPTION();
347 }
348 }
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700349 result.SetL(obj_result);
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200350 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200351 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200352 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200353 shadow_frame.GetMethod(), dex_pc,
354 result);
Sebastien Hertze713d932014-05-15 10:48:53 +0200355 } else if (UNLIKELY(instrumentation->HasDexPcListeners())) {
356 instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
357 shadow_frame.GetMethod(), dex_pc);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200358 }
359 return result;
360 }
361 HANDLE_INSTRUCTION_END();
362
363 HANDLE_INSTRUCTION_START(CONST_4) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200364 uint32_t dst = inst->VRegA_11n(inst_data);
365 int32_t val = inst->VRegB_11n(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200366 shadow_frame.SetVReg(dst, val);
367 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700368 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200369 }
370 ADVANCE(1);
371 }
372 HANDLE_INSTRUCTION_END();
373
374 HANDLE_INSTRUCTION_START(CONST_16) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200375 uint32_t dst = inst->VRegA_21s(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200376 int32_t val = inst->VRegB_21s();
377 shadow_frame.SetVReg(dst, val);
378 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700379 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200380 }
381 ADVANCE(2);
382 }
383 HANDLE_INSTRUCTION_END();
384
385 HANDLE_INSTRUCTION_START(CONST) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200386 uint32_t dst = inst->VRegA_31i(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200387 int32_t val = inst->VRegB_31i();
388 shadow_frame.SetVReg(dst, val);
389 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700390 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200391 }
392 ADVANCE(3);
393 }
394 HANDLE_INSTRUCTION_END();
395
396 HANDLE_INSTRUCTION_START(CONST_HIGH16) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200397 uint32_t dst = inst->VRegA_21h(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200398 int32_t val = static_cast<int32_t>(inst->VRegB_21h() << 16);
399 shadow_frame.SetVReg(dst, val);
400 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700401 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200402 }
403 ADVANCE(2);
404 }
405 HANDLE_INSTRUCTION_END();
406
407 HANDLE_INSTRUCTION_START(CONST_WIDE_16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200408 shadow_frame.SetVRegLong(inst->VRegA_21s(inst_data), inst->VRegB_21s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200409 ADVANCE(2);
410 HANDLE_INSTRUCTION_END();
411
412 HANDLE_INSTRUCTION_START(CONST_WIDE_32)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200413 shadow_frame.SetVRegLong(inst->VRegA_31i(inst_data), inst->VRegB_31i());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200414 ADVANCE(3);
415 HANDLE_INSTRUCTION_END();
416
417 HANDLE_INSTRUCTION_START(CONST_WIDE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200418 shadow_frame.SetVRegLong(inst->VRegA_51l(inst_data), inst->VRegB_51l());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200419 ADVANCE(5);
420 HANDLE_INSTRUCTION_END();
421
422 HANDLE_INSTRUCTION_START(CONST_WIDE_HIGH16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200423 shadow_frame.SetVRegLong(inst->VRegA_21h(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200424 static_cast<uint64_t>(inst->VRegB_21h()) << 48);
425 ADVANCE(2);
426 HANDLE_INSTRUCTION_END();
427
428 HANDLE_INSTRUCTION_START(CONST_STRING) {
Ian Rogers6786a582014-10-28 12:49:06 -0700429 String* s = ResolveString(self, shadow_frame, inst->VRegB_21c());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700430 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200431 HANDLE_PENDING_EXCEPTION();
432 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200433 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200434 ADVANCE(2);
435 }
436 }
437 HANDLE_INSTRUCTION_END();
438
439 HANDLE_INSTRUCTION_START(CONST_STRING_JUMBO) {
Ian Rogers6786a582014-10-28 12:49:06 -0700440 String* s = ResolveString(self, shadow_frame, inst->VRegB_31c());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700441 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200442 HANDLE_PENDING_EXCEPTION();
443 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200444 shadow_frame.SetVRegReference(inst->VRegA_31c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200445 ADVANCE(3);
446 }
447 }
448 HANDLE_INSTRUCTION_END();
449
450 HANDLE_INSTRUCTION_START(CONST_CLASS) {
451 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
452 self, false, do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700453 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200454 HANDLE_PENDING_EXCEPTION();
455 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200456 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), c);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200457 ADVANCE(2);
458 }
459 }
460 HANDLE_INSTRUCTION_END();
461
462 HANDLE_INSTRUCTION_START(MONITOR_ENTER) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200463 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700464 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000465 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200466 HANDLE_PENDING_EXCEPTION();
467 } else {
468 DoMonitorEnter(self, obj);
469 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), 1);
470 }
471 }
472 HANDLE_INSTRUCTION_END();
473
474 HANDLE_INSTRUCTION_START(MONITOR_EXIT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200475 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700476 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000477 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200478 HANDLE_PENDING_EXCEPTION();
479 } else {
480 DoMonitorExit(self, obj);
481 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), 1);
482 }
483 }
484 HANDLE_INSTRUCTION_END();
485
486 HANDLE_INSTRUCTION_START(CHECK_CAST) {
487 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), 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->VRegA_21c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700493 if (UNLIKELY(obj != nullptr && !obj->InstanceOf(c))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200494 ThrowClassCastException(c, obj->GetClass());
495 HANDLE_PENDING_EXCEPTION();
496 } else {
497 ADVANCE(2);
498 }
499 }
500 }
501 HANDLE_INSTRUCTION_END();
502
503 HANDLE_INSTRUCTION_START(INSTANCE_OF) {
504 Class* c = ResolveVerifyAndClinit(inst->VRegC_22c(), shadow_frame.GetMethod(),
505 self, false, do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700506 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200507 HANDLE_PENDING_EXCEPTION();
508 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200509 Object* obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700510 shadow_frame.SetVReg(inst->VRegA_22c(inst_data), (obj != nullptr && obj->InstanceOf(c)) ? 1 : 0);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200511 ADVANCE(2);
512 }
513 }
514 HANDLE_INSTRUCTION_END();
515
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700516 HANDLE_INSTRUCTION_START(ARRAY_LENGTH) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200517 Object* array = shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700518 if (UNLIKELY(array == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000519 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200520 HANDLE_PENDING_EXCEPTION();
521 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200522 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), array->AsArray()->GetLength());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200523 ADVANCE(1);
524 }
525 }
526 HANDLE_INSTRUCTION_END();
527
528 HANDLE_INSTRUCTION_START(NEW_INSTANCE) {
Jeff Hao848f70a2014-01-15 13:49:50 -0800529 Object* obj = nullptr;
530 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
531 self, false, do_access_check);
532 if (LIKELY(c != nullptr)) {
533 if (UNLIKELY(c->IsStringClass())) {
534 gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
535 mirror::SetStringCountVisitor visitor(0);
536 obj = String::Alloc<true>(self, 0, allocator_type, visitor);
537 } else {
538 obj = AllocObjectFromCode<do_access_check, true>(
539 inst->VRegB_21c(), shadow_frame.GetMethod(), self,
540 Runtime::Current()->GetHeap()->GetCurrentAllocator());
541 }
542 }
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700543 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200544 HANDLE_PENDING_EXCEPTION();
545 } else {
Sebastien Hertz4e99b3d2014-06-24 14:35:40 +0200546 obj->GetClass()->AssertInitializedOrInitializingInThread(self);
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700547 // Don't allow finalizable objects to be allocated during a transaction since these can't be
548 // finalized without a started runtime.
549 if (transaction_active && obj->GetClass()->IsFinalizable()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +0200550 AbortTransactionF(self, "Allocating finalizable object in transaction: %s",
551 PrettyTypeOf(obj).c_str());
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700552 HANDLE_PENDING_EXCEPTION();
553 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200554 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200555 ADVANCE(2);
556 }
557 }
558 HANDLE_INSTRUCTION_END();
559
560 HANDLE_INSTRUCTION_START(NEW_ARRAY) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200561 int32_t length = shadow_frame.GetVReg(inst->VRegB_22c(inst_data));
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800562 Object* obj = AllocArrayFromCode<do_access_check, true>(
Andreas Gampe1cc7dba2014-12-17 18:43:01 -0800563 inst->VRegC_22c(), length, shadow_frame.GetMethod(), self,
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800564 Runtime::Current()->GetHeap()->GetCurrentAllocator());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700565 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200566 HANDLE_PENDING_EXCEPTION();
567 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200568 shadow_frame.SetVRegReference(inst->VRegA_22c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200569 ADVANCE(2);
570 }
571 }
572 HANDLE_INSTRUCTION_END();
573
574 HANDLE_INSTRUCTION_START(FILLED_NEW_ARRAY) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100575 bool success =
576 DoFilledNewArray<false, do_access_check, transaction_active>(inst, shadow_frame,
577 self, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200578 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
579 }
580 HANDLE_INSTRUCTION_END();
581
582 HANDLE_INSTRUCTION_START(FILLED_NEW_ARRAY_RANGE) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100583 bool success =
584 DoFilledNewArray<true, do_access_check, transaction_active>(inst, shadow_frame,
585 self, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200586 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
587 }
588 HANDLE_INSTRUCTION_END();
589
590 HANDLE_INSTRUCTION_START(FILL_ARRAY_DATA) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200591 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_31t(inst_data));
Ian Rogers832336b2014-10-08 15:35:22 -0700592 const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t();
593 const Instruction::ArrayDataPayload* payload =
594 reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr);
595 bool success = FillArrayData(obj, payload);
596 if (transaction_active && success) {
597 RecordArrayElementsInTransaction(obj->AsArray(), payload->element_count);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200598 }
Ian Rogers832336b2014-10-08 15:35:22 -0700599 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200600 }
601 HANDLE_INSTRUCTION_END();
602
603 HANDLE_INSTRUCTION_START(THROW) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200604 Object* exception = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700605 if (UNLIKELY(exception == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000606 ThrowNullPointerException("throw with null exception");
Jeff Haoa3faaf42013-09-03 19:07:00 -0700607 } else if (do_assignability_check && !exception->GetClass()->IsThrowableClass()) {
608 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700609 std::string temp;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000610 self->ThrowNewExceptionF("Ljava/lang/VirtualMachineError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700611 "Throwing '%s' that is not instance of Throwable",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700612 exception->GetClass()->GetDescriptor(&temp));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200613 } else {
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000614 self->SetException(exception->AsThrowable());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200615 }
616 HANDLE_PENDING_EXCEPTION();
617 }
618 HANDLE_INSTRUCTION_END();
619
620 HANDLE_INSTRUCTION_START(GOTO) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200621 int8_t offset = inst->VRegA_10t(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200622 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800623 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200624 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700625 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200626 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200627 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200628 }
629 ADVANCE(offset);
630 }
631 HANDLE_INSTRUCTION_END();
632
633 HANDLE_INSTRUCTION_START(GOTO_16) {
634 int16_t offset = inst->VRegA_20t();
635 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800636 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200637 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700638 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200639 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200640 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200641 }
642 ADVANCE(offset);
643 }
644 HANDLE_INSTRUCTION_END();
645
646 HANDLE_INSTRUCTION_START(GOTO_32) {
647 int32_t offset = inst->VRegA_30t();
648 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800649 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200650 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700651 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200652 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200653 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200654 }
655 ADVANCE(offset);
656 }
657 HANDLE_INSTRUCTION_END();
658
659 HANDLE_INSTRUCTION_START(PACKED_SWITCH) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200660 int32_t offset = DoPackedSwitch(inst, shadow_frame, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200661 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800662 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200663 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700664 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200665 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200666 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200667 }
668 ADVANCE(offset);
669 }
670 HANDLE_INSTRUCTION_END();
671
672 HANDLE_INSTRUCTION_START(SPARSE_SWITCH) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200673 int32_t offset = DoSparseSwitch(inst, shadow_frame, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200674 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800675 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200676 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700677 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200678 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200679 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200680 }
681 ADVANCE(offset);
682 }
683 HANDLE_INSTRUCTION_END();
684
Ian Rogers647b1a82014-10-10 11:02:11 -0700685#if defined(__clang__)
686#pragma clang diagnostic push
687#pragma clang diagnostic ignored "-Wfloat-equal"
688#endif
689
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200690 HANDLE_INSTRUCTION_START(CMPL_FLOAT) {
691 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
692 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
693 int32_t result;
694 if (val1 > val2) {
695 result = 1;
696 } else if (val1 == val2) {
697 result = 0;
698 } else {
699 result = -1;
700 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200701 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200702 ADVANCE(2);
703 }
704 HANDLE_INSTRUCTION_END();
705
706 HANDLE_INSTRUCTION_START(CMPG_FLOAT) {
707 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
708 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
709 int32_t result;
710 if (val1 < val2) {
711 result = -1;
712 } else if (val1 == val2) {
713 result = 0;
714 } else {
715 result = 1;
716 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200717 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200718 ADVANCE(2);
719 }
720 HANDLE_INSTRUCTION_END();
721
722 HANDLE_INSTRUCTION_START(CMPL_DOUBLE) {
723 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
724 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
725 int32_t result;
726 if (val1 > val2) {
727 result = 1;
728 } else if (val1 == val2) {
729 result = 0;
730 } else {
731 result = -1;
732 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200733 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200734 ADVANCE(2);
735 }
736 HANDLE_INSTRUCTION_END();
737
738 HANDLE_INSTRUCTION_START(CMPG_DOUBLE) {
739 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
740 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
741 int32_t result;
742 if (val1 < val2) {
743 result = -1;
744 } else if (val1 == val2) {
745 result = 0;
746 } else {
747 result = 1;
748 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200749 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200750 ADVANCE(2);
751 }
752 HANDLE_INSTRUCTION_END();
753
Ian Rogers647b1a82014-10-10 11:02:11 -0700754#if defined(__clang__)
755#pragma clang diagnostic pop
756#endif
757
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200758 HANDLE_INSTRUCTION_START(CMP_LONG) {
759 int64_t val1 = shadow_frame.GetVRegLong(inst->VRegB_23x());
760 int64_t val2 = shadow_frame.GetVRegLong(inst->VRegC_23x());
761 int32_t result;
762 if (val1 > val2) {
763 result = 1;
764 } else if (val1 == val2) {
765 result = 0;
766 } else {
767 result = -1;
768 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200769 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200770 ADVANCE(2);
771 }
772 HANDLE_INSTRUCTION_END();
773
774 HANDLE_INSTRUCTION_START(IF_EQ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200775 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) == shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200776 int16_t offset = inst->VRegC_22t();
777 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800778 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200779 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700780 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200781 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200782 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200783 }
784 ADVANCE(offset);
785 } else {
786 ADVANCE(2);
787 }
788 }
789 HANDLE_INSTRUCTION_END();
790
791 HANDLE_INSTRUCTION_START(IF_NE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700792 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) !=
793 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200794 int16_t offset = inst->VRegC_22t();
795 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800796 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200797 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700798 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200799 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200800 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200801 }
802 ADVANCE(offset);
803 } else {
804 ADVANCE(2);
805 }
806 }
807 HANDLE_INSTRUCTION_END();
808
809 HANDLE_INSTRUCTION_START(IF_LT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700810 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <
811 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200812 int16_t offset = inst->VRegC_22t();
813 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800814 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200815 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700816 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200817 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200818 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200819 }
820 ADVANCE(offset);
821 } else {
822 ADVANCE(2);
823 }
824 }
825 HANDLE_INSTRUCTION_END();
826
827 HANDLE_INSTRUCTION_START(IF_GE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700828 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >=
829 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200830 int16_t offset = inst->VRegC_22t();
831 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800832 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200833 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700834 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200835 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200836 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200837 }
838 ADVANCE(offset);
839 } else {
840 ADVANCE(2);
841 }
842 }
843 HANDLE_INSTRUCTION_END();
844
845 HANDLE_INSTRUCTION_START(IF_GT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700846 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >
847 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200848 int16_t offset = inst->VRegC_22t();
849 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800850 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200851 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700852 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200853 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200854 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200855 }
856 ADVANCE(offset);
857 } else {
858 ADVANCE(2);
859 }
860 }
861 HANDLE_INSTRUCTION_END();
862
863 HANDLE_INSTRUCTION_START(IF_LE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700864 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <=
865 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200866 int16_t offset = inst->VRegC_22t();
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_EQZ) {
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_NEZ) {
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_LTZ) {
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_GEZ) {
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_GTZ) {
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(IF_LEZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200967 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) <= 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200968 int16_t offset = inst->VRegB_21t();
969 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800970 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200971 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700972 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200973 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200974 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200975 }
976 ADVANCE(offset);
977 } else {
978 ADVANCE(2);
979 }
980 }
981 HANDLE_INSTRUCTION_END();
982
983 HANDLE_INSTRUCTION_START(AGET_BOOLEAN) {
984 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700985 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000986 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200987 HANDLE_PENDING_EXCEPTION();
988 } else {
989 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
990 BooleanArray* array = a->AsBooleanArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +0100991 if (LIKELY(array->CheckIsValidIndex(index))) {
992 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200993 ADVANCE(2);
994 } else {
995 HANDLE_PENDING_EXCEPTION();
996 }
997 }
998 }
999 HANDLE_INSTRUCTION_END();
1000
1001 HANDLE_INSTRUCTION_START(AGET_BYTE) {
1002 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001003 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001004 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001005 HANDLE_PENDING_EXCEPTION();
1006 } else {
1007 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1008 ByteArray* array = a->AsByteArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001009 if (LIKELY(array->CheckIsValidIndex(index))) {
1010 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001011 ADVANCE(2);
1012 } else {
1013 HANDLE_PENDING_EXCEPTION();
1014 }
1015 }
1016 }
1017 HANDLE_INSTRUCTION_END();
1018
1019 HANDLE_INSTRUCTION_START(AGET_CHAR) {
1020 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001021 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001022 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001023 HANDLE_PENDING_EXCEPTION();
1024 } else {
1025 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1026 CharArray* array = a->AsCharArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001027 if (LIKELY(array->CheckIsValidIndex(index))) {
1028 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001029 ADVANCE(2);
1030 } else {
1031 HANDLE_PENDING_EXCEPTION();
1032 }
1033 }
1034 }
1035 HANDLE_INSTRUCTION_END();
1036
1037 HANDLE_INSTRUCTION_START(AGET_SHORT) {
1038 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001039 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001040 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001041 HANDLE_PENDING_EXCEPTION();
1042 } else {
1043 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1044 ShortArray* array = a->AsShortArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001045 if (LIKELY(array->CheckIsValidIndex(index))) {
1046 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001047 ADVANCE(2);
1048 } else {
1049 HANDLE_PENDING_EXCEPTION();
1050 }
1051 }
1052 }
1053 HANDLE_INSTRUCTION_END();
1054
1055 HANDLE_INSTRUCTION_START(AGET) {
1056 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001057 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001058 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001059 HANDLE_PENDING_EXCEPTION();
1060 } else {
1061 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1062 IntArray* array = a->AsIntArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001063 if (LIKELY(array->CheckIsValidIndex(index))) {
1064 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001065 ADVANCE(2);
1066 } else {
1067 HANDLE_PENDING_EXCEPTION();
1068 }
1069 }
1070 }
1071 HANDLE_INSTRUCTION_END();
1072
1073 HANDLE_INSTRUCTION_START(AGET_WIDE) {
1074 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001075 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001076 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001077 HANDLE_PENDING_EXCEPTION();
1078 } else {
1079 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1080 LongArray* array = a->AsLongArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001081 if (LIKELY(array->CheckIsValidIndex(index))) {
1082 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001083 ADVANCE(2);
1084 } else {
1085 HANDLE_PENDING_EXCEPTION();
1086 }
1087 }
1088 }
1089 HANDLE_INSTRUCTION_END();
1090
1091 HANDLE_INSTRUCTION_START(AGET_OBJECT) {
1092 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001093 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001094 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001095 HANDLE_PENDING_EXCEPTION();
1096 } else {
1097 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1098 ObjectArray<Object>* array = a->AsObjectArray<Object>();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001099 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001100 shadow_frame.SetVRegReference(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001101 ADVANCE(2);
1102 } else {
1103 HANDLE_PENDING_EXCEPTION();
1104 }
1105 }
1106 }
1107 HANDLE_INSTRUCTION_END();
1108
1109 HANDLE_INSTRUCTION_START(APUT_BOOLEAN) {
1110 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001111 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001112 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001113 HANDLE_PENDING_EXCEPTION();
1114 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001115 uint8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001116 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1117 BooleanArray* array = a->AsBooleanArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001118 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001119 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001120 ADVANCE(2);
1121 } else {
1122 HANDLE_PENDING_EXCEPTION();
1123 }
1124 }
1125 }
1126 HANDLE_INSTRUCTION_END();
1127
1128 HANDLE_INSTRUCTION_START(APUT_BYTE) {
1129 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001130 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001131 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001132 HANDLE_PENDING_EXCEPTION();
1133 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001134 int8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001135 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1136 ByteArray* array = a->AsByteArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001137 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001138 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001139 ADVANCE(2);
1140 } else {
1141 HANDLE_PENDING_EXCEPTION();
1142 }
1143 }
1144 }
1145 HANDLE_INSTRUCTION_END();
1146
1147 HANDLE_INSTRUCTION_START(APUT_CHAR) {
1148 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001149 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001150 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001151 HANDLE_PENDING_EXCEPTION();
1152 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001153 uint16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001154 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1155 CharArray* array = a->AsCharArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001156 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001157 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001158 ADVANCE(2);
1159 } else {
1160 HANDLE_PENDING_EXCEPTION();
1161 }
1162 }
1163 }
1164 HANDLE_INSTRUCTION_END();
1165
1166 HANDLE_INSTRUCTION_START(APUT_SHORT) {
1167 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001168 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001169 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001170 HANDLE_PENDING_EXCEPTION();
1171 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001172 int16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001173 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1174 ShortArray* array = a->AsShortArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001175 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001176 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001177 ADVANCE(2);
1178 } else {
1179 HANDLE_PENDING_EXCEPTION();
1180 }
1181 }
1182 }
1183 HANDLE_INSTRUCTION_END();
1184
1185 HANDLE_INSTRUCTION_START(APUT) {
1186 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001187 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001188 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001189 HANDLE_PENDING_EXCEPTION();
1190 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001191 int32_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001192 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1193 IntArray* array = a->AsIntArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001194 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001195 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001196 ADVANCE(2);
1197 } else {
1198 HANDLE_PENDING_EXCEPTION();
1199 }
1200 }
1201 }
1202 HANDLE_INSTRUCTION_END();
1203
1204 HANDLE_INSTRUCTION_START(APUT_WIDE) {
1205 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001206 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001207 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001208 HANDLE_PENDING_EXCEPTION();
1209 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001210 int64_t val = shadow_frame.GetVRegLong(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001211 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1212 LongArray* array = a->AsLongArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001213 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001214 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001215 ADVANCE(2);
1216 } else {
1217 HANDLE_PENDING_EXCEPTION();
1218 }
1219 }
1220 }
1221 HANDLE_INSTRUCTION_END();
1222
1223 HANDLE_INSTRUCTION_START(APUT_OBJECT) {
1224 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001225 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001226 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001227 HANDLE_PENDING_EXCEPTION();
1228 } else {
1229 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001230 Object* val = shadow_frame.GetVRegReference(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001231 ObjectArray<Object>* array = a->AsObjectArray<Object>();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001232 if (LIKELY(array->CheckIsValidIndex(index) && array->CheckAssignable(val))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001233 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001234 ADVANCE(2);
1235 } else {
1236 HANDLE_PENDING_EXCEPTION();
1237 }
1238 }
1239 }
1240 HANDLE_INSTRUCTION_END();
1241
1242 HANDLE_INSTRUCTION_START(IGET_BOOLEAN) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001243 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimBoolean, do_access_check>(
1244 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001245 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1246 }
1247 HANDLE_INSTRUCTION_END();
1248
1249 HANDLE_INSTRUCTION_START(IGET_BYTE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001250 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimByte, do_access_check>(
1251 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001252 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1253 }
1254 HANDLE_INSTRUCTION_END();
1255
1256 HANDLE_INSTRUCTION_START(IGET_CHAR) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001257 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimChar, do_access_check>(
1258 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001259 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1260 }
1261 HANDLE_INSTRUCTION_END();
1262
1263 HANDLE_INSTRUCTION_START(IGET_SHORT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001264 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimShort, do_access_check>(
1265 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001266 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1267 }
1268 HANDLE_INSTRUCTION_END();
1269
1270 HANDLE_INSTRUCTION_START(IGET) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001271 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimInt, do_access_check>(
1272 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001273 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1274 }
1275 HANDLE_INSTRUCTION_END();
1276
1277 HANDLE_INSTRUCTION_START(IGET_WIDE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001278 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimLong, do_access_check>(
1279 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001280 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1281 }
1282 HANDLE_INSTRUCTION_END();
1283
1284 HANDLE_INSTRUCTION_START(IGET_OBJECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001285 bool success = DoFieldGet<InstanceObjectRead, Primitive::kPrimNot, do_access_check>(
1286 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001287 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1288 }
1289 HANDLE_INSTRUCTION_END();
1290
1291 HANDLE_INSTRUCTION_START(IGET_QUICK) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001292 bool success = DoIGetQuick<Primitive::kPrimInt>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001293 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1294 }
1295 HANDLE_INSTRUCTION_END();
1296
Mathieu Chartierffc605c2014-12-10 10:35:44 -08001297 HANDLE_INSTRUCTION_START(IGET_BOOLEAN_QUICK) {
1298 bool success = DoIGetQuick<Primitive::kPrimBoolean>(shadow_frame, inst, inst_data);
1299 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1300 }
1301 HANDLE_INSTRUCTION_END();
1302
1303 HANDLE_INSTRUCTION_START(IGET_BYTE_QUICK) {
1304 bool success = DoIGetQuick<Primitive::kPrimByte>(shadow_frame, inst, inst_data);
1305 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1306 }
1307 HANDLE_INSTRUCTION_END();
1308
1309 HANDLE_INSTRUCTION_START(IGET_CHAR_QUICK) {
1310 bool success = DoIGetQuick<Primitive::kPrimChar>(shadow_frame, inst, inst_data);
1311 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1312 }
1313 HANDLE_INSTRUCTION_END();
1314
1315 HANDLE_INSTRUCTION_START(IGET_SHORT_QUICK) {
1316 bool success = DoIGetQuick<Primitive::kPrimShort>(shadow_frame, inst, inst_data);
1317 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1318 }
1319 HANDLE_INSTRUCTION_END();
1320
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001321 HANDLE_INSTRUCTION_START(IGET_WIDE_QUICK) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001322 bool success = DoIGetQuick<Primitive::kPrimLong>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001323 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1324 }
1325 HANDLE_INSTRUCTION_END();
1326
1327 HANDLE_INSTRUCTION_START(IGET_OBJECT_QUICK) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001328 bool success = DoIGetQuick<Primitive::kPrimNot>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001329 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1330 }
1331 HANDLE_INSTRUCTION_END();
1332
1333 HANDLE_INSTRUCTION_START(SGET_BOOLEAN) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001334 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimBoolean, do_access_check>(
1335 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001336 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1337 }
1338 HANDLE_INSTRUCTION_END();
1339
1340 HANDLE_INSTRUCTION_START(SGET_BYTE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001341 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimByte, do_access_check>(
1342 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001343 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1344 }
1345 HANDLE_INSTRUCTION_END();
1346
1347 HANDLE_INSTRUCTION_START(SGET_CHAR) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001348 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimChar, do_access_check>(
1349 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001350 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1351 }
1352 HANDLE_INSTRUCTION_END();
1353
1354 HANDLE_INSTRUCTION_START(SGET_SHORT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001355 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimShort, do_access_check>(
1356 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001357 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1358 }
1359 HANDLE_INSTRUCTION_END();
1360
1361 HANDLE_INSTRUCTION_START(SGET) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001362 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimInt, do_access_check>(
1363 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001364 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1365 }
1366 HANDLE_INSTRUCTION_END();
1367
1368 HANDLE_INSTRUCTION_START(SGET_WIDE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001369 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimLong, do_access_check>(
1370 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001371 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1372 }
1373 HANDLE_INSTRUCTION_END();
1374
1375 HANDLE_INSTRUCTION_START(SGET_OBJECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001376 bool success = DoFieldGet<StaticObjectRead, Primitive::kPrimNot, do_access_check>(
1377 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001378 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1379 }
1380 HANDLE_INSTRUCTION_END();
1381
1382 HANDLE_INSTRUCTION_START(IPUT_BOOLEAN) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001383 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1384 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001385 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1386 }
1387 HANDLE_INSTRUCTION_END();
1388
1389 HANDLE_INSTRUCTION_START(IPUT_BYTE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001390 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimByte, do_access_check,
1391 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001392 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1393 }
1394 HANDLE_INSTRUCTION_END();
1395
1396 HANDLE_INSTRUCTION_START(IPUT_CHAR) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001397 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimChar, do_access_check,
1398 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001399 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1400 }
1401 HANDLE_INSTRUCTION_END();
1402
1403 HANDLE_INSTRUCTION_START(IPUT_SHORT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001404 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimShort, do_access_check,
1405 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001406 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1407 }
1408 HANDLE_INSTRUCTION_END();
1409
1410 HANDLE_INSTRUCTION_START(IPUT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001411 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimInt, do_access_check,
1412 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001413 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1414 }
1415 HANDLE_INSTRUCTION_END();
1416
1417 HANDLE_INSTRUCTION_START(IPUT_WIDE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001418 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimLong, do_access_check,
1419 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001420 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1421 }
1422 HANDLE_INSTRUCTION_END();
1423
1424 HANDLE_INSTRUCTION_START(IPUT_OBJECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001425 bool success = DoFieldPut<InstanceObjectWrite, Primitive::kPrimNot, do_access_check,
1426 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001427 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1428 }
1429 HANDLE_INSTRUCTION_END();
1430
1431 HANDLE_INSTRUCTION_START(IPUT_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001432 bool success = DoIPutQuick<Primitive::kPrimInt, transaction_active>(
1433 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001434 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1435 }
1436 HANDLE_INSTRUCTION_END();
1437
Fred Shih37f05ef2014-07-16 18:38:08 -07001438 HANDLE_INSTRUCTION_START(IPUT_BOOLEAN_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001439 bool success = DoIPutQuick<Primitive::kPrimBoolean, transaction_active>(
1440 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001441 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1442 }
1443 HANDLE_INSTRUCTION_END();
1444
1445 HANDLE_INSTRUCTION_START(IPUT_BYTE_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001446 bool success = DoIPutQuick<Primitive::kPrimByte, transaction_active>(
1447 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001448 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1449 }
1450 HANDLE_INSTRUCTION_END();
1451
1452 HANDLE_INSTRUCTION_START(IPUT_CHAR_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001453 bool success = DoIPutQuick<Primitive::kPrimChar, transaction_active>(
1454 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001455 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1456 }
1457 HANDLE_INSTRUCTION_END();
1458
1459 HANDLE_INSTRUCTION_START(IPUT_SHORT_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001460 bool success = DoIPutQuick<Primitive::kPrimShort, transaction_active>(
1461 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001462 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1463 }
1464 HANDLE_INSTRUCTION_END();
1465
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001466 HANDLE_INSTRUCTION_START(IPUT_WIDE_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001467 bool success = DoIPutQuick<Primitive::kPrimLong, transaction_active>(
1468 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001469 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1470 }
1471 HANDLE_INSTRUCTION_END();
1472
1473 HANDLE_INSTRUCTION_START(IPUT_OBJECT_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001474 bool success = DoIPutQuick<Primitive::kPrimNot, transaction_active>(
1475 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001476 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1477 }
1478 HANDLE_INSTRUCTION_END();
1479
1480 HANDLE_INSTRUCTION_START(SPUT_BOOLEAN) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001481 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1482 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001483 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1484 }
1485 HANDLE_INSTRUCTION_END();
1486
1487 HANDLE_INSTRUCTION_START(SPUT_BYTE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001488 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimByte, do_access_check,
1489 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001490 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1491 }
1492 HANDLE_INSTRUCTION_END();
1493
1494 HANDLE_INSTRUCTION_START(SPUT_CHAR) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001495 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimChar, do_access_check,
1496 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001497 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1498 }
1499 HANDLE_INSTRUCTION_END();
1500
1501 HANDLE_INSTRUCTION_START(SPUT_SHORT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001502 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimShort, do_access_check,
1503 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001504 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1505 }
1506 HANDLE_INSTRUCTION_END();
1507
1508 HANDLE_INSTRUCTION_START(SPUT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001509 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimInt, do_access_check,
1510 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001511 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1512 }
1513 HANDLE_INSTRUCTION_END();
1514
1515 HANDLE_INSTRUCTION_START(SPUT_WIDE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001516 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimLong, do_access_check,
1517 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001518 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1519 }
1520 HANDLE_INSTRUCTION_END();
1521
1522 HANDLE_INSTRUCTION_START(SPUT_OBJECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001523 bool success = DoFieldPut<StaticObjectWrite, Primitive::kPrimNot, do_access_check,
1524 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001525 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1526 }
1527 HANDLE_INSTRUCTION_END();
1528
1529 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001530 bool success = DoInvoke<kVirtual, false, do_access_check>(
1531 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001532 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001533 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1534 }
1535 HANDLE_INSTRUCTION_END();
1536
1537 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001538 bool success = DoInvoke<kVirtual, true, do_access_check>(
1539 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001540 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001541 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1542 }
1543 HANDLE_INSTRUCTION_END();
1544
1545 HANDLE_INSTRUCTION_START(INVOKE_SUPER) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001546 bool success = DoInvoke<kSuper, false, do_access_check>(
1547 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001548 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001549 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1550 }
1551 HANDLE_INSTRUCTION_END();
1552
1553 HANDLE_INSTRUCTION_START(INVOKE_SUPER_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001554 bool success = DoInvoke<kSuper, true, do_access_check>(
1555 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001556 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001557 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1558 }
1559 HANDLE_INSTRUCTION_END();
1560
1561 HANDLE_INSTRUCTION_START(INVOKE_DIRECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001562 bool success = DoInvoke<kDirect, false, do_access_check>(
1563 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001564 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001565 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1566 }
1567 HANDLE_INSTRUCTION_END();
1568
1569 HANDLE_INSTRUCTION_START(INVOKE_DIRECT_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001570 bool success = DoInvoke<kDirect, true, do_access_check>(
1571 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001572 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001573 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1574 }
1575 HANDLE_INSTRUCTION_END();
1576
1577 HANDLE_INSTRUCTION_START(INVOKE_INTERFACE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001578 bool success = DoInvoke<kInterface, false, do_access_check>(
1579 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001580 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001581 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1582 }
1583 HANDLE_INSTRUCTION_END();
1584
1585 HANDLE_INSTRUCTION_START(INVOKE_INTERFACE_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001586 bool success = DoInvoke<kInterface, true, do_access_check>(
1587 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001588 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001589 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1590 }
1591 HANDLE_INSTRUCTION_END();
1592
1593 HANDLE_INSTRUCTION_START(INVOKE_STATIC) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001594 bool success = DoInvoke<kStatic, false, do_access_check>(
1595 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001596 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001597 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1598 }
1599 HANDLE_INSTRUCTION_END();
1600
1601 HANDLE_INSTRUCTION_START(INVOKE_STATIC_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001602 bool success = DoInvoke<kStatic, true, do_access_check>(
1603 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001604 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001605 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1606 }
1607 HANDLE_INSTRUCTION_END();
1608
1609 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001610 bool success = DoInvokeVirtualQuick<false>(
1611 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001612 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001613 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1614 }
1615 HANDLE_INSTRUCTION_END();
1616
1617 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_RANGE_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001618 bool success = DoInvokeVirtualQuick<true>(
1619 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001620 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001621 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1622 }
1623 HANDLE_INSTRUCTION_END();
1624
1625 HANDLE_INSTRUCTION_START(NEG_INT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001626 shadow_frame.SetVReg(
1627 inst->VRegA_12x(inst_data), -shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001628 ADVANCE(1);
1629 HANDLE_INSTRUCTION_END();
1630
1631 HANDLE_INSTRUCTION_START(NOT_INT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001632 shadow_frame.SetVReg(
1633 inst->VRegA_12x(inst_data), ~shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001634 ADVANCE(1);
1635 HANDLE_INSTRUCTION_END();
1636
1637 HANDLE_INSTRUCTION_START(NEG_LONG)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001638 shadow_frame.SetVRegLong(
1639 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001640 ADVANCE(1);
1641 HANDLE_INSTRUCTION_END();
1642
1643 HANDLE_INSTRUCTION_START(NOT_LONG)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001644 shadow_frame.SetVRegLong(
1645 inst->VRegA_12x(inst_data), ~shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001646 ADVANCE(1);
1647 HANDLE_INSTRUCTION_END();
1648
1649 HANDLE_INSTRUCTION_START(NEG_FLOAT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001650 shadow_frame.SetVRegFloat(
1651 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001652 ADVANCE(1);
1653 HANDLE_INSTRUCTION_END();
1654
1655 HANDLE_INSTRUCTION_START(NEG_DOUBLE)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001656 shadow_frame.SetVRegDouble(
1657 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001658 ADVANCE(1);
1659 HANDLE_INSTRUCTION_END();
1660
1661 HANDLE_INSTRUCTION_START(INT_TO_LONG)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001662 shadow_frame.SetVRegLong(
1663 inst->VRegA_12x(inst_data), shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001664 ADVANCE(1);
1665 HANDLE_INSTRUCTION_END();
1666
1667 HANDLE_INSTRUCTION_START(INT_TO_FLOAT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001668 shadow_frame.SetVRegFloat(
1669 inst->VRegA_12x(inst_data), shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001670 ADVANCE(1);
1671 HANDLE_INSTRUCTION_END();
1672
1673 HANDLE_INSTRUCTION_START(INT_TO_DOUBLE)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001674 shadow_frame.SetVRegDouble(
1675 inst->VRegA_12x(inst_data), shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001676 ADVANCE(1);
1677 HANDLE_INSTRUCTION_END();
1678
1679 HANDLE_INSTRUCTION_START(LONG_TO_INT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001680 shadow_frame.SetVReg(
1681 inst->VRegA_12x(inst_data), shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001682 ADVANCE(1);
1683 HANDLE_INSTRUCTION_END();
1684
1685 HANDLE_INSTRUCTION_START(LONG_TO_FLOAT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001686 shadow_frame.SetVRegFloat(
1687 inst->VRegA_12x(inst_data), shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001688 ADVANCE(1);
1689 HANDLE_INSTRUCTION_END();
1690
1691 HANDLE_INSTRUCTION_START(LONG_TO_DOUBLE)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001692 shadow_frame.SetVRegDouble(
1693 inst->VRegA_12x(inst_data), shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001694 ADVANCE(1);
1695 HANDLE_INSTRUCTION_END();
1696
1697 HANDLE_INSTRUCTION_START(FLOAT_TO_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001698 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001699 int32_t result = art_float_to_integral<int32_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001700 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001701 ADVANCE(1);
1702 }
1703 HANDLE_INSTRUCTION_END();
1704
1705 HANDLE_INSTRUCTION_START(FLOAT_TO_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001706 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001707 int64_t result = art_float_to_integral<int64_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001708 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001709 ADVANCE(1);
1710 }
1711 HANDLE_INSTRUCTION_END();
1712
1713 HANDLE_INSTRUCTION_START(FLOAT_TO_DOUBLE)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001714 shadow_frame.SetVRegDouble(
1715 inst->VRegA_12x(inst_data), shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001716 ADVANCE(1);
1717 HANDLE_INSTRUCTION_END();
1718
1719 HANDLE_INSTRUCTION_START(DOUBLE_TO_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001720 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001721 int32_t result = art_float_to_integral<int32_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001722 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001723 ADVANCE(1);
1724 }
1725 HANDLE_INSTRUCTION_END();
1726
1727 HANDLE_INSTRUCTION_START(DOUBLE_TO_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001728 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001729 int64_t result = art_float_to_integral<int64_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001730 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001731 ADVANCE(1);
1732 }
1733 HANDLE_INSTRUCTION_END();
1734
1735 HANDLE_INSTRUCTION_START(DOUBLE_TO_FLOAT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001736 shadow_frame.SetVRegFloat(
1737 inst->VRegA_12x(inst_data), shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001738 ADVANCE(1);
1739 HANDLE_INSTRUCTION_END();
1740
1741 HANDLE_INSTRUCTION_START(INT_TO_BYTE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001742 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1743 static_cast<int8_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001744 ADVANCE(1);
1745 HANDLE_INSTRUCTION_END();
1746
1747 HANDLE_INSTRUCTION_START(INT_TO_CHAR)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001748 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1749 static_cast<uint16_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001750 ADVANCE(1);
1751 HANDLE_INSTRUCTION_END();
1752
1753 HANDLE_INSTRUCTION_START(INT_TO_SHORT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001754 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1755 static_cast<int16_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001756 ADVANCE(1);
1757 HANDLE_INSTRUCTION_END();
1758
1759 HANDLE_INSTRUCTION_START(ADD_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001760 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001761 SafeAdd(shadow_frame.GetVReg(inst->VRegB_23x()),
1762 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001763 ADVANCE(2);
1764 HANDLE_INSTRUCTION_END();
1765
1766 HANDLE_INSTRUCTION_START(SUB_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001767 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001768 SafeSub(shadow_frame.GetVReg(inst->VRegB_23x()),
1769 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001770 ADVANCE(2);
1771 HANDLE_INSTRUCTION_END();
1772
1773 HANDLE_INSTRUCTION_START(MUL_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001774 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001775 SafeMul(shadow_frame.GetVReg(inst->VRegB_23x()),
1776 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001777 ADVANCE(2);
1778 HANDLE_INSTRUCTION_END();
1779
1780 HANDLE_INSTRUCTION_START(DIV_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001781 bool success = DoIntDivide(shadow_frame, inst->VRegA_23x(inst_data),
1782 shadow_frame.GetVReg(inst->VRegB_23x()),
1783 shadow_frame.GetVReg(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001784 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1785 }
1786 HANDLE_INSTRUCTION_END();
1787
1788 HANDLE_INSTRUCTION_START(REM_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001789 bool success = DoIntRemainder(shadow_frame, inst->VRegA_23x(inst_data),
1790 shadow_frame.GetVReg(inst->VRegB_23x()),
1791 shadow_frame.GetVReg(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001792 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1793 }
1794 HANDLE_INSTRUCTION_END();
1795
1796 HANDLE_INSTRUCTION_START(SHL_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001797 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001798 shadow_frame.GetVReg(inst->VRegB_23x()) <<
1799 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1800 ADVANCE(2);
1801 HANDLE_INSTRUCTION_END();
1802
1803 HANDLE_INSTRUCTION_START(SHR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001804 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001805 shadow_frame.GetVReg(inst->VRegB_23x()) >>
1806 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1807 ADVANCE(2);
1808 HANDLE_INSTRUCTION_END();
1809
1810 HANDLE_INSTRUCTION_START(USHR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001811 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001812 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_23x())) >>
1813 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1814 ADVANCE(2);
1815 HANDLE_INSTRUCTION_END();
1816
1817 HANDLE_INSTRUCTION_START(AND_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001818 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001819 shadow_frame.GetVReg(inst->VRegB_23x()) &
1820 shadow_frame.GetVReg(inst->VRegC_23x()));
1821 ADVANCE(2);
1822 HANDLE_INSTRUCTION_END();
1823
1824 HANDLE_INSTRUCTION_START(OR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001825 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001826 shadow_frame.GetVReg(inst->VRegB_23x()) |
1827 shadow_frame.GetVReg(inst->VRegC_23x()));
1828 ADVANCE(2);
1829 HANDLE_INSTRUCTION_END();
1830
1831 HANDLE_INSTRUCTION_START(XOR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001832 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001833 shadow_frame.GetVReg(inst->VRegB_23x()) ^
1834 shadow_frame.GetVReg(inst->VRegC_23x()));
1835 ADVANCE(2);
1836 HANDLE_INSTRUCTION_END();
1837
1838 HANDLE_INSTRUCTION_START(ADD_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001839 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001840 SafeAdd(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1841 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001842 ADVANCE(2);
1843 HANDLE_INSTRUCTION_END();
1844
1845 HANDLE_INSTRUCTION_START(SUB_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001846 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001847 SafeSub(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1848 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001849 ADVANCE(2);
1850 HANDLE_INSTRUCTION_END();
1851
1852 HANDLE_INSTRUCTION_START(MUL_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001853 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001854 SafeMul(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1855 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001856 ADVANCE(2);
1857 HANDLE_INSTRUCTION_END();
1858
1859 HANDLE_INSTRUCTION_START(DIV_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001860 bool success = DoLongDivide(shadow_frame, inst->VRegA_23x(inst_data),
1861 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1862 shadow_frame.GetVRegLong(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001863 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1864 }
1865 HANDLE_INSTRUCTION_END();
1866
1867 HANDLE_INSTRUCTION_START(REM_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001868 bool success = DoLongRemainder(shadow_frame, inst->VRegA_23x(inst_data),
1869 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1870 shadow_frame.GetVRegLong(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001871 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1872 }
1873 HANDLE_INSTRUCTION_END();
1874
1875 HANDLE_INSTRUCTION_START(AND_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001876 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001877 shadow_frame.GetVRegLong(inst->VRegB_23x()) &
1878 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1879 ADVANCE(2);
1880 HANDLE_INSTRUCTION_END();
1881
1882 HANDLE_INSTRUCTION_START(OR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001883 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001884 shadow_frame.GetVRegLong(inst->VRegB_23x()) |
1885 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1886 ADVANCE(2);
1887 HANDLE_INSTRUCTION_END();
1888
1889 HANDLE_INSTRUCTION_START(XOR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001890 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001891 shadow_frame.GetVRegLong(inst->VRegB_23x()) ^
1892 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1893 ADVANCE(2);
1894 HANDLE_INSTRUCTION_END();
1895
1896 HANDLE_INSTRUCTION_START(SHL_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001897 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001898 shadow_frame.GetVRegLong(inst->VRegB_23x()) <<
1899 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1900 ADVANCE(2);
1901 HANDLE_INSTRUCTION_END();
1902
1903 HANDLE_INSTRUCTION_START(SHR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001904 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001905 shadow_frame.GetVRegLong(inst->VRegB_23x()) >>
1906 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1907 ADVANCE(2);
1908 HANDLE_INSTRUCTION_END();
1909
1910 HANDLE_INSTRUCTION_START(USHR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001911 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001912 static_cast<uint64_t>(shadow_frame.GetVRegLong(inst->VRegB_23x())) >>
1913 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1914 ADVANCE(2);
1915 HANDLE_INSTRUCTION_END();
1916
1917 HANDLE_INSTRUCTION_START(ADD_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001918 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001919 shadow_frame.GetVRegFloat(inst->VRegB_23x()) +
1920 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1921 ADVANCE(2);
1922 HANDLE_INSTRUCTION_END();
1923
1924 HANDLE_INSTRUCTION_START(SUB_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001925 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001926 shadow_frame.GetVRegFloat(inst->VRegB_23x()) -
1927 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1928 ADVANCE(2);
1929 HANDLE_INSTRUCTION_END();
1930
1931 HANDLE_INSTRUCTION_START(MUL_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001932 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001933 shadow_frame.GetVRegFloat(inst->VRegB_23x()) *
1934 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1935 ADVANCE(2);
1936 HANDLE_INSTRUCTION_END();
1937
1938 HANDLE_INSTRUCTION_START(DIV_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001939 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001940 shadow_frame.GetVRegFloat(inst->VRegB_23x()) /
1941 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1942 ADVANCE(2);
1943 HANDLE_INSTRUCTION_END();
1944
1945 HANDLE_INSTRUCTION_START(REM_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001946 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001947 fmodf(shadow_frame.GetVRegFloat(inst->VRegB_23x()),
1948 shadow_frame.GetVRegFloat(inst->VRegC_23x())));
1949 ADVANCE(2);
1950 HANDLE_INSTRUCTION_END();
1951
1952 HANDLE_INSTRUCTION_START(ADD_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001953 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001954 shadow_frame.GetVRegDouble(inst->VRegB_23x()) +
1955 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1956 ADVANCE(2);
1957 HANDLE_INSTRUCTION_END();
1958
1959 HANDLE_INSTRUCTION_START(SUB_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001960 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001961 shadow_frame.GetVRegDouble(inst->VRegB_23x()) -
1962 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1963 ADVANCE(2);
1964 HANDLE_INSTRUCTION_END();
1965
1966 HANDLE_INSTRUCTION_START(MUL_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001967 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001968 shadow_frame.GetVRegDouble(inst->VRegB_23x()) *
1969 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1970 ADVANCE(2);
1971 HANDLE_INSTRUCTION_END();
1972
1973 HANDLE_INSTRUCTION_START(DIV_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001974 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001975 shadow_frame.GetVRegDouble(inst->VRegB_23x()) /
1976 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1977 ADVANCE(2);
1978 HANDLE_INSTRUCTION_END();
1979
1980 HANDLE_INSTRUCTION_START(REM_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001981 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001982 fmod(shadow_frame.GetVRegDouble(inst->VRegB_23x()),
1983 shadow_frame.GetVRegDouble(inst->VRegC_23x())));
1984 ADVANCE(2);
1985 HANDLE_INSTRUCTION_END();
1986
1987 HANDLE_INSTRUCTION_START(ADD_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001988 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001989 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07001990 SafeAdd(shadow_frame.GetVReg(vregA),
1991 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001992 ADVANCE(1);
1993 }
1994 HANDLE_INSTRUCTION_END();
1995
1996 HANDLE_INSTRUCTION_START(SUB_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001997 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001998 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07001999 SafeSub(shadow_frame.GetVReg(vregA),
2000 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002001 ADVANCE(1);
2002 }
2003 HANDLE_INSTRUCTION_END();
2004
2005 HANDLE_INSTRUCTION_START(MUL_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 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002008 SafeMul(shadow_frame.GetVReg(vregA),
2009 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002010 ADVANCE(1);
2011 }
2012 HANDLE_INSTRUCTION_END();
2013
2014 HANDLE_INSTRUCTION_START(DIV_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002015 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002016 bool success = DoIntDivide(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002017 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002018 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2019 }
2020 HANDLE_INSTRUCTION_END();
2021
2022 HANDLE_INSTRUCTION_START(REM_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 bool success = DoIntRemainder(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002025 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002026 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2027 }
2028 HANDLE_INSTRUCTION_END();
2029
2030 HANDLE_INSTRUCTION_START(SHL_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002031 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002032 shadow_frame.SetVReg(vregA,
2033 shadow_frame.GetVReg(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002034 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002035 ADVANCE(1);
2036 }
2037 HANDLE_INSTRUCTION_END();
2038
2039 HANDLE_INSTRUCTION_START(SHR_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002040 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002041 shadow_frame.SetVReg(vregA,
2042 shadow_frame.GetVReg(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002043 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002044 ADVANCE(1);
2045 }
2046 HANDLE_INSTRUCTION_END();
2047
2048 HANDLE_INSTRUCTION_START(USHR_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002049 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002050 shadow_frame.SetVReg(vregA,
2051 static_cast<uint32_t>(shadow_frame.GetVReg(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002052 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002053 ADVANCE(1);
2054 }
2055 HANDLE_INSTRUCTION_END();
2056
2057 HANDLE_INSTRUCTION_START(AND_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002058 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002059 shadow_frame.SetVReg(vregA,
2060 shadow_frame.GetVReg(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002061 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002062 ADVANCE(1);
2063 }
2064 HANDLE_INSTRUCTION_END();
2065
2066 HANDLE_INSTRUCTION_START(OR_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002067 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002068 shadow_frame.SetVReg(vregA,
2069 shadow_frame.GetVReg(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002070 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002071 ADVANCE(1);
2072 }
2073 HANDLE_INSTRUCTION_END();
2074
2075 HANDLE_INSTRUCTION_START(XOR_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002076 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002077 shadow_frame.SetVReg(vregA,
2078 shadow_frame.GetVReg(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002079 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002080 ADVANCE(1);
2081 }
2082 HANDLE_INSTRUCTION_END();
2083
2084 HANDLE_INSTRUCTION_START(ADD_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002085 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002086 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002087 SafeAdd(shadow_frame.GetVRegLong(vregA),
2088 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002089 ADVANCE(1);
2090 }
2091 HANDLE_INSTRUCTION_END();
2092
2093 HANDLE_INSTRUCTION_START(SUB_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002094 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002095 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002096 SafeSub(shadow_frame.GetVRegLong(vregA),
2097 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002098 ADVANCE(1);
2099 }
2100 HANDLE_INSTRUCTION_END();
2101
2102 HANDLE_INSTRUCTION_START(MUL_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 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002105 SafeMul(shadow_frame.GetVRegLong(vregA),
2106 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002107 ADVANCE(1);
2108 }
2109 HANDLE_INSTRUCTION_END();
2110
2111 HANDLE_INSTRUCTION_START(DIV_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002112 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002113 bool success = DoLongDivide(shadow_frame, vregA, 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 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2116 }
2117 HANDLE_INSTRUCTION_END();
2118
2119 HANDLE_INSTRUCTION_START(REM_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 bool success = DoLongRemainder(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002122 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002123 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2124 }
2125 HANDLE_INSTRUCTION_END();
2126
2127 HANDLE_INSTRUCTION_START(AND_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002128 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002129 shadow_frame.SetVRegLong(vregA,
2130 shadow_frame.GetVRegLong(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002131 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002132 ADVANCE(1);
2133 }
2134 HANDLE_INSTRUCTION_END();
2135
2136 HANDLE_INSTRUCTION_START(OR_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002137 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002138 shadow_frame.SetVRegLong(vregA,
2139 shadow_frame.GetVRegLong(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002140 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002141 ADVANCE(1);
2142 }
2143 HANDLE_INSTRUCTION_END();
2144
2145 HANDLE_INSTRUCTION_START(XOR_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002146 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002147 shadow_frame.SetVRegLong(vregA,
2148 shadow_frame.GetVRegLong(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002149 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002150 ADVANCE(1);
2151 }
2152 HANDLE_INSTRUCTION_END();
2153
2154 HANDLE_INSTRUCTION_START(SHL_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002155 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002156 shadow_frame.SetVRegLong(vregA,
2157 shadow_frame.GetVRegLong(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002158 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002159 ADVANCE(1);
2160 }
2161 HANDLE_INSTRUCTION_END();
2162
2163 HANDLE_INSTRUCTION_START(SHR_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002164 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002165 shadow_frame.SetVRegLong(vregA,
2166 shadow_frame.GetVRegLong(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002167 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002168 ADVANCE(1);
2169 }
2170 HANDLE_INSTRUCTION_END();
2171
2172 HANDLE_INSTRUCTION_START(USHR_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002173 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002174 shadow_frame.SetVRegLong(vregA,
2175 static_cast<uint64_t>(shadow_frame.GetVRegLong(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002176 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002177 ADVANCE(1);
2178 }
2179 HANDLE_INSTRUCTION_END();
2180
2181 HANDLE_INSTRUCTION_START(ADD_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002182 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002183 shadow_frame.SetVRegFloat(vregA,
2184 shadow_frame.GetVRegFloat(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002185 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002186 ADVANCE(1);
2187 }
2188 HANDLE_INSTRUCTION_END();
2189
2190 HANDLE_INSTRUCTION_START(SUB_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002191 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002192 shadow_frame.SetVRegFloat(vregA,
2193 shadow_frame.GetVRegFloat(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002194 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002195 ADVANCE(1);
2196 }
2197 HANDLE_INSTRUCTION_END();
2198
2199 HANDLE_INSTRUCTION_START(MUL_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002200 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002201 shadow_frame.SetVRegFloat(vregA,
2202 shadow_frame.GetVRegFloat(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002203 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002204 ADVANCE(1);
2205 }
2206 HANDLE_INSTRUCTION_END();
2207
2208 HANDLE_INSTRUCTION_START(DIV_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002209 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002210 shadow_frame.SetVRegFloat(vregA,
2211 shadow_frame.GetVRegFloat(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002212 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002213 ADVANCE(1);
2214 }
2215 HANDLE_INSTRUCTION_END();
2216
2217 HANDLE_INSTRUCTION_START(REM_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002218 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002219 shadow_frame.SetVRegFloat(vregA,
2220 fmodf(shadow_frame.GetVRegFloat(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002221 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002222 ADVANCE(1);
2223 }
2224 HANDLE_INSTRUCTION_END();
2225
2226 HANDLE_INSTRUCTION_START(ADD_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002227 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002228 shadow_frame.SetVRegDouble(vregA,
2229 shadow_frame.GetVRegDouble(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002230 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002231 ADVANCE(1);
2232 }
2233 HANDLE_INSTRUCTION_END();
2234
2235 HANDLE_INSTRUCTION_START(SUB_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002236 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002237 shadow_frame.SetVRegDouble(vregA,
2238 shadow_frame.GetVRegDouble(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002239 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002240 ADVANCE(1);
2241 }
2242 HANDLE_INSTRUCTION_END();
2243
2244 HANDLE_INSTRUCTION_START(MUL_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002245 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002246 shadow_frame.SetVRegDouble(vregA,
2247 shadow_frame.GetVRegDouble(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002248 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002249 ADVANCE(1);
2250 }
2251 HANDLE_INSTRUCTION_END();
2252
2253 HANDLE_INSTRUCTION_START(DIV_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002254 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002255 shadow_frame.SetVRegDouble(vregA,
2256 shadow_frame.GetVRegDouble(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002257 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002258 ADVANCE(1);
2259 }
2260 HANDLE_INSTRUCTION_END();
2261
2262 HANDLE_INSTRUCTION_START(REM_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002263 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002264 shadow_frame.SetVRegDouble(vregA,
2265 fmod(shadow_frame.GetVRegDouble(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002266 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002267 ADVANCE(1);
2268 }
2269 HANDLE_INSTRUCTION_END();
2270
2271 HANDLE_INSTRUCTION_START(ADD_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002272 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002273 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2274 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002275 ADVANCE(2);
2276 HANDLE_INSTRUCTION_END();
2277
2278 HANDLE_INSTRUCTION_START(RSUB_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002279 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002280 SafeSub(inst->VRegC_22s(),
2281 shadow_frame.GetVReg(inst->VRegB_22s(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002282 ADVANCE(2);
2283 HANDLE_INSTRUCTION_END();
2284
2285 HANDLE_INSTRUCTION_START(MUL_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002286 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002287 SafeMul(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2288 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002289 ADVANCE(2);
2290 HANDLE_INSTRUCTION_END();
2291
2292 HANDLE_INSTRUCTION_START(DIV_INT_LIT16) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002293 bool success = DoIntDivide(
2294 shadow_frame, inst->VRegA_22s(inst_data), shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2295 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002296 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2297 }
2298 HANDLE_INSTRUCTION_END();
2299
2300 HANDLE_INSTRUCTION_START(REM_INT_LIT16) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002301 bool success = DoIntRemainder(
2302 shadow_frame, inst->VRegA_22s(inst_data), shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2303 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002304 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2305 }
2306 HANDLE_INSTRUCTION_END();
2307
2308 HANDLE_INSTRUCTION_START(AND_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002309 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2310 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) &
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002311 inst->VRegC_22s());
2312 ADVANCE(2);
2313 HANDLE_INSTRUCTION_END();
2314
2315 HANDLE_INSTRUCTION_START(OR_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002316 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2317 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) |
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002318 inst->VRegC_22s());
2319 ADVANCE(2);
2320 HANDLE_INSTRUCTION_END();
2321
2322 HANDLE_INSTRUCTION_START(XOR_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002323 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2324 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) ^
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002325 inst->VRegC_22s());
2326 ADVANCE(2);
2327 HANDLE_INSTRUCTION_END();
2328
2329 HANDLE_INSTRUCTION_START(ADD_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002330 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002331 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22b()),
2332 inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002333 ADVANCE(2);
2334 HANDLE_INSTRUCTION_END();
2335
2336 HANDLE_INSTRUCTION_START(RSUB_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002337 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002338 SafeSub(inst->VRegC_22b(),
2339 shadow_frame.GetVReg(inst->VRegB_22b())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002340 ADVANCE(2);
2341 HANDLE_INSTRUCTION_END();
2342
2343 HANDLE_INSTRUCTION_START(MUL_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002344 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002345 SafeMul(shadow_frame.GetVReg(inst->VRegB_22b()),
2346 inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002347 ADVANCE(2);
2348 HANDLE_INSTRUCTION_END();
2349
2350 HANDLE_INSTRUCTION_START(DIV_INT_LIT8) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002351 bool success = DoIntDivide(shadow_frame, inst->VRegA_22b(inst_data),
2352 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002353 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2354 }
2355 HANDLE_INSTRUCTION_END();
2356
2357 HANDLE_INSTRUCTION_START(REM_INT_LIT8) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002358 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22b(inst_data),
2359 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002360 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2361 }
2362 HANDLE_INSTRUCTION_END();
2363
2364 HANDLE_INSTRUCTION_START(AND_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002365 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002366 shadow_frame.GetVReg(inst->VRegB_22b()) &
2367 inst->VRegC_22b());
2368 ADVANCE(2);
2369 HANDLE_INSTRUCTION_END();
2370
2371 HANDLE_INSTRUCTION_START(OR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002372 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002373 shadow_frame.GetVReg(inst->VRegB_22b()) |
2374 inst->VRegC_22b());
2375 ADVANCE(2);
2376 HANDLE_INSTRUCTION_END();
2377
2378 HANDLE_INSTRUCTION_START(XOR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002379 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002380 shadow_frame.GetVReg(inst->VRegB_22b()) ^
2381 inst->VRegC_22b());
2382 ADVANCE(2);
2383 HANDLE_INSTRUCTION_END();
2384
2385 HANDLE_INSTRUCTION_START(SHL_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002386 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002387 shadow_frame.GetVReg(inst->VRegB_22b()) <<
2388 (inst->VRegC_22b() & 0x1f));
2389 ADVANCE(2);
2390 HANDLE_INSTRUCTION_END();
2391
2392 HANDLE_INSTRUCTION_START(SHR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002393 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002394 shadow_frame.GetVReg(inst->VRegB_22b()) >>
2395 (inst->VRegC_22b() & 0x1f));
2396 ADVANCE(2);
2397 HANDLE_INSTRUCTION_END();
2398
2399 HANDLE_INSTRUCTION_START(USHR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002400 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002401 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_22b())) >>
2402 (inst->VRegC_22b() & 0x1f));
2403 ADVANCE(2);
2404 HANDLE_INSTRUCTION_END();
2405
2406 HANDLE_INSTRUCTION_START(UNUSED_3E)
Ian Rogerse94652f2014-12-02 11:13:19 -08002407 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002408 HANDLE_INSTRUCTION_END();
2409
2410 HANDLE_INSTRUCTION_START(UNUSED_3F)
Ian Rogerse94652f2014-12-02 11:13:19 -08002411 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002412 HANDLE_INSTRUCTION_END();
2413
2414 HANDLE_INSTRUCTION_START(UNUSED_40)
Ian Rogerse94652f2014-12-02 11:13:19 -08002415 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002416 HANDLE_INSTRUCTION_END();
2417
2418 HANDLE_INSTRUCTION_START(UNUSED_41)
Ian Rogerse94652f2014-12-02 11:13:19 -08002419 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002420 HANDLE_INSTRUCTION_END();
2421
2422 HANDLE_INSTRUCTION_START(UNUSED_42)
Ian Rogerse94652f2014-12-02 11:13:19 -08002423 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002424 HANDLE_INSTRUCTION_END();
2425
2426 HANDLE_INSTRUCTION_START(UNUSED_43)
Ian Rogerse94652f2014-12-02 11:13:19 -08002427 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002428 HANDLE_INSTRUCTION_END();
2429
2430 HANDLE_INSTRUCTION_START(UNUSED_79)
Ian Rogerse94652f2014-12-02 11:13:19 -08002431 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002432 HANDLE_INSTRUCTION_END();
2433
2434 HANDLE_INSTRUCTION_START(UNUSED_7A)
Ian Rogerse94652f2014-12-02 11:13:19 -08002435 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002436 HANDLE_INSTRUCTION_END();
2437
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002438 HANDLE_INSTRUCTION_START(UNUSED_F3)
Ian Rogerse94652f2014-12-02 11:13:19 -08002439 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002440 HANDLE_INSTRUCTION_END();
2441
2442 HANDLE_INSTRUCTION_START(UNUSED_F4)
Ian Rogerse94652f2014-12-02 11:13:19 -08002443 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002444 HANDLE_INSTRUCTION_END();
2445
2446 HANDLE_INSTRUCTION_START(UNUSED_F5)
Ian Rogerse94652f2014-12-02 11:13:19 -08002447 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002448 HANDLE_INSTRUCTION_END();
2449
2450 HANDLE_INSTRUCTION_START(UNUSED_F6)
Ian Rogerse94652f2014-12-02 11:13:19 -08002451 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002452 HANDLE_INSTRUCTION_END();
2453
2454 HANDLE_INSTRUCTION_START(UNUSED_F7)
Ian Rogerse94652f2014-12-02 11:13:19 -08002455 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002456 HANDLE_INSTRUCTION_END();
2457
2458 HANDLE_INSTRUCTION_START(UNUSED_F8)
Ian Rogerse94652f2014-12-02 11:13:19 -08002459 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002460 HANDLE_INSTRUCTION_END();
2461
2462 HANDLE_INSTRUCTION_START(UNUSED_F9)
Ian Rogerse94652f2014-12-02 11:13:19 -08002463 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002464 HANDLE_INSTRUCTION_END();
2465
2466 HANDLE_INSTRUCTION_START(UNUSED_FA)
Ian Rogerse94652f2014-12-02 11:13:19 -08002467 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002468 HANDLE_INSTRUCTION_END();
2469
2470 HANDLE_INSTRUCTION_START(UNUSED_FB)
Ian Rogerse94652f2014-12-02 11:13:19 -08002471 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002472 HANDLE_INSTRUCTION_END();
2473
2474 HANDLE_INSTRUCTION_START(UNUSED_FC)
Ian Rogerse94652f2014-12-02 11:13:19 -08002475 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002476 HANDLE_INSTRUCTION_END();
2477
2478 HANDLE_INSTRUCTION_START(UNUSED_FD)
Ian Rogerse94652f2014-12-02 11:13:19 -08002479 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002480 HANDLE_INSTRUCTION_END();
2481
2482 HANDLE_INSTRUCTION_START(UNUSED_FE)
Ian Rogerse94652f2014-12-02 11:13:19 -08002483 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002484 HANDLE_INSTRUCTION_END();
2485
2486 HANDLE_INSTRUCTION_START(UNUSED_FF)
Ian Rogerse94652f2014-12-02 11:13:19 -08002487 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002488 HANDLE_INSTRUCTION_END();
2489
2490 exception_pending_label: {
2491 CHECK(self->IsExceptionPending());
Sebastien Hertz1eda2262013-09-09 16:53:14 +02002492 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -07002493 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +02002494 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +02002495 }
Sebastien Hertzee1997a2013-09-19 14:47:09 +02002496 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002497 uint32_t found_dex_pc = FindNextInstructionFollowingException(self, shadow_frame, dex_pc,
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002498 instrumentation);
2499 if (found_dex_pc == DexFile::kDexNoIndex) {
2500 return JValue(); /* Handled in caller. */
2501 } else {
2502 int32_t displacement = static_cast<int32_t>(found_dex_pc) - static_cast<int32_t>(dex_pc);
2503 ADVANCE(displacement);
2504 }
2505 }
2506
Sebastien Hertz8379b222014-02-24 17:38:15 +01002507// Create alternative instruction handlers dedicated to instrumentation.
2508// Return instructions must not call Instrumentation::DexPcMovedEvent since they already call
2509// Instrumentation::MethodExited. This is to avoid posting debugger events twice for this location.
Sebastien Hertze713d932014-05-15 10:48:53 +02002510// Note: we do not use the kReturn instruction flag here (to test the instruction is a return). The
2511// compiler seems to not evaluate "(Instruction::FlagsOf(Instruction::code) & kReturn) != 0" to
2512// a constant condition that would remove the "if" statement so the test is free.
Sebastien Hertz8379b222014-02-24 17:38:15 +01002513#define INSTRUMENTATION_INSTRUCTION_HANDLER(o, code, n, f, r, i, a, v) \
2514 alt_op_##code: { \
2515 if (Instruction::code != Instruction::RETURN_VOID && \
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -07002516 Instruction::code != Instruction::RETURN_VOID_NO_BARRIER && \
Sebastien Hertz8379b222014-02-24 17:38:15 +01002517 Instruction::code != Instruction::RETURN && \
2518 Instruction::code != Instruction::RETURN_WIDE && \
2519 Instruction::code != Instruction::RETURN_OBJECT) { \
2520 if (LIKELY(!notified_method_entry_event)) { \
2521 Runtime* runtime = Runtime::Current(); \
2522 const instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation(); \
2523 if (UNLIKELY(instrumentation->HasDexPcListeners())) { \
2524 Object* this_object = shadow_frame.GetThisObject(code_item->ins_size_); \
2525 instrumentation->DexPcMovedEvent(self, this_object, shadow_frame.GetMethod(), dex_pc); \
2526 } \
2527 } else { \
2528 notified_method_entry_event = false; \
2529 } \
2530 } \
2531 UPDATE_HANDLER_TABLE(); \
2532 goto *handlersTable[instrumentation::kMainHandlerTable][Instruction::code]; \
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002533 }
2534#include "dex_instruction_list.h"
2535 DEX_INSTRUCTION_LIST(INSTRUMENTATION_INSTRUCTION_HANDLER)
2536#undef DEX_INSTRUCTION_LIST
2537#undef INSTRUMENTATION_INSTRUCTION_HANDLER
2538} // NOLINT(readability/fn_size)
2539
2540// Explicit definitions of ExecuteGotoImpl.
Sebastien Hertzc6714852013-09-30 16:42:32 +02002541template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) HOT_ATTR
Ian Rogerse94652f2014-12-02 11:13:19 -08002542JValue ExecuteGotoImpl<true, false>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002543 ShadowFrame& shadow_frame, JValue result_register);
Sebastien Hertzc6714852013-09-30 16:42:32 +02002544template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) HOT_ATTR
Ian Rogerse94652f2014-12-02 11:13:19 -08002545JValue ExecuteGotoImpl<false, false>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002546 ShadowFrame& shadow_frame, JValue result_register);
2547template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
Ian Rogerse94652f2014-12-02 11:13:19 -08002548JValue ExecuteGotoImpl<true, true>(Thread* self, const DexFile::CodeItem* code_item,
2549 ShadowFrame& shadow_frame, JValue result_register);
2550template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
2551JValue ExecuteGotoImpl<false, true>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002552 ShadowFrame& shadow_frame, JValue result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002553
2554} // namespace interpreter
2555} // namespace art
Colin Crosse84e4f72015-03-18 14:01:19 -07002556
2557#endif