blob: dc0b6870a0a900fc2cba5489a4038359d7ea0af9 [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) {
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700529 Runtime* runtime = Runtime::Current();
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800530 Object* obj = AllocObjectFromCode<do_access_check, true>(
531 inst->VRegB_21c(), shadow_frame.GetMethod(), self,
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700532 runtime->GetHeap()->GetCurrentAllocator());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700533 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200534 HANDLE_PENDING_EXCEPTION();
535 } else {
Sebastien Hertz4e99b3d2014-06-24 14:35:40 +0200536 obj->GetClass()->AssertInitializedOrInitializingInThread(self);
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700537 // Don't allow finalizable objects to be allocated during a transaction since these can't be
538 // finalized without a started runtime.
539 if (transaction_active && obj->GetClass()->IsFinalizable()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +0200540 AbortTransactionF(self, "Allocating finalizable object in transaction: %s",
541 PrettyTypeOf(obj).c_str());
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700542 HANDLE_PENDING_EXCEPTION();
543 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200544 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200545 ADVANCE(2);
546 }
547 }
548 HANDLE_INSTRUCTION_END();
549
550 HANDLE_INSTRUCTION_START(NEW_ARRAY) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200551 int32_t length = shadow_frame.GetVReg(inst->VRegB_22c(inst_data));
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800552 Object* obj = AllocArrayFromCode<do_access_check, true>(
Andreas Gampe1cc7dba2014-12-17 18:43:01 -0800553 inst->VRegC_22c(), length, shadow_frame.GetMethod(), self,
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800554 Runtime::Current()->GetHeap()->GetCurrentAllocator());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700555 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200556 HANDLE_PENDING_EXCEPTION();
557 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200558 shadow_frame.SetVRegReference(inst->VRegA_22c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200559 ADVANCE(2);
560 }
561 }
562 HANDLE_INSTRUCTION_END();
563
564 HANDLE_INSTRUCTION_START(FILLED_NEW_ARRAY) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100565 bool success =
566 DoFilledNewArray<false, do_access_check, transaction_active>(inst, shadow_frame,
567 self, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200568 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
569 }
570 HANDLE_INSTRUCTION_END();
571
572 HANDLE_INSTRUCTION_START(FILLED_NEW_ARRAY_RANGE) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100573 bool success =
574 DoFilledNewArray<true, do_access_check, transaction_active>(inst, shadow_frame,
575 self, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200576 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
577 }
578 HANDLE_INSTRUCTION_END();
579
580 HANDLE_INSTRUCTION_START(FILL_ARRAY_DATA) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200581 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_31t(inst_data));
Ian Rogers832336b2014-10-08 15:35:22 -0700582 const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t();
583 const Instruction::ArrayDataPayload* payload =
584 reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr);
585 bool success = FillArrayData(obj, payload);
586 if (transaction_active && success) {
587 RecordArrayElementsInTransaction(obj->AsArray(), payload->element_count);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200588 }
Ian Rogers832336b2014-10-08 15:35:22 -0700589 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200590 }
591 HANDLE_INSTRUCTION_END();
592
593 HANDLE_INSTRUCTION_START(THROW) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200594 Object* exception = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700595 if (UNLIKELY(exception == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000596 ThrowNullPointerException("throw with null exception");
Jeff Haoa3faaf42013-09-03 19:07:00 -0700597 } else if (do_assignability_check && !exception->GetClass()->IsThrowableClass()) {
598 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700599 std::string temp;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000600 self->ThrowNewExceptionF("Ljava/lang/VirtualMachineError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700601 "Throwing '%s' that is not instance of Throwable",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700602 exception->GetClass()->GetDescriptor(&temp));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200603 } else {
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000604 self->SetException(exception->AsThrowable());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200605 }
606 HANDLE_PENDING_EXCEPTION();
607 }
608 HANDLE_INSTRUCTION_END();
609
610 HANDLE_INSTRUCTION_START(GOTO) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200611 int8_t offset = inst->VRegA_10t(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200612 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800613 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200614 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700615 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200616 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200617 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200618 }
619 ADVANCE(offset);
620 }
621 HANDLE_INSTRUCTION_END();
622
623 HANDLE_INSTRUCTION_START(GOTO_16) {
624 int16_t offset = inst->VRegA_20t();
625 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800626 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200627 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700628 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200629 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200630 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200631 }
632 ADVANCE(offset);
633 }
634 HANDLE_INSTRUCTION_END();
635
636 HANDLE_INSTRUCTION_START(GOTO_32) {
637 int32_t offset = inst->VRegA_30t();
638 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800639 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200640 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700641 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200642 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200643 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200644 }
645 ADVANCE(offset);
646 }
647 HANDLE_INSTRUCTION_END();
648
649 HANDLE_INSTRUCTION_START(PACKED_SWITCH) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200650 int32_t offset = DoPackedSwitch(inst, shadow_frame, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200651 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800652 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200653 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700654 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200655 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200656 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200657 }
658 ADVANCE(offset);
659 }
660 HANDLE_INSTRUCTION_END();
661
662 HANDLE_INSTRUCTION_START(SPARSE_SWITCH) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200663 int32_t offset = DoSparseSwitch(inst, shadow_frame, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200664 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800665 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200666 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700667 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200668 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200669 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200670 }
671 ADVANCE(offset);
672 }
673 HANDLE_INSTRUCTION_END();
674
Ian Rogers647b1a82014-10-10 11:02:11 -0700675#if defined(__clang__)
676#pragma clang diagnostic push
677#pragma clang diagnostic ignored "-Wfloat-equal"
678#endif
679
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200680 HANDLE_INSTRUCTION_START(CMPL_FLOAT) {
681 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
682 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
683 int32_t result;
684 if (val1 > val2) {
685 result = 1;
686 } else if (val1 == val2) {
687 result = 0;
688 } else {
689 result = -1;
690 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200691 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200692 ADVANCE(2);
693 }
694 HANDLE_INSTRUCTION_END();
695
696 HANDLE_INSTRUCTION_START(CMPG_FLOAT) {
697 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
698 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
699 int32_t result;
700 if (val1 < val2) {
701 result = -1;
702 } else if (val1 == val2) {
703 result = 0;
704 } else {
705 result = 1;
706 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200707 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200708 ADVANCE(2);
709 }
710 HANDLE_INSTRUCTION_END();
711
712 HANDLE_INSTRUCTION_START(CMPL_DOUBLE) {
713 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
714 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
715 int32_t result;
716 if (val1 > val2) {
717 result = 1;
718 } else if (val1 == val2) {
719 result = 0;
720 } else {
721 result = -1;
722 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200723 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200724 ADVANCE(2);
725 }
726 HANDLE_INSTRUCTION_END();
727
728 HANDLE_INSTRUCTION_START(CMPG_DOUBLE) {
729 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
730 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
731 int32_t result;
732 if (val1 < val2) {
733 result = -1;
734 } else if (val1 == val2) {
735 result = 0;
736 } else {
737 result = 1;
738 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200739 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200740 ADVANCE(2);
741 }
742 HANDLE_INSTRUCTION_END();
743
Ian Rogers647b1a82014-10-10 11:02:11 -0700744#if defined(__clang__)
745#pragma clang diagnostic pop
746#endif
747
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200748 HANDLE_INSTRUCTION_START(CMP_LONG) {
749 int64_t val1 = shadow_frame.GetVRegLong(inst->VRegB_23x());
750 int64_t val2 = shadow_frame.GetVRegLong(inst->VRegC_23x());
751 int32_t result;
752 if (val1 > val2) {
753 result = 1;
754 } else if (val1 == val2) {
755 result = 0;
756 } else {
757 result = -1;
758 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200759 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200760 ADVANCE(2);
761 }
762 HANDLE_INSTRUCTION_END();
763
764 HANDLE_INSTRUCTION_START(IF_EQ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200765 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) == shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200766 int16_t offset = inst->VRegC_22t();
767 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800768 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200769 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700770 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200771 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200772 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200773 }
774 ADVANCE(offset);
775 } else {
776 ADVANCE(2);
777 }
778 }
779 HANDLE_INSTRUCTION_END();
780
781 HANDLE_INSTRUCTION_START(IF_NE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700782 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) !=
783 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200784 int16_t offset = inst->VRegC_22t();
785 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800786 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200787 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700788 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200789 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200790 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200791 }
792 ADVANCE(offset);
793 } else {
794 ADVANCE(2);
795 }
796 }
797 HANDLE_INSTRUCTION_END();
798
799 HANDLE_INSTRUCTION_START(IF_LT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700800 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <
801 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200802 int16_t offset = inst->VRegC_22t();
803 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800804 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200805 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700806 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200807 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200808 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200809 }
810 ADVANCE(offset);
811 } else {
812 ADVANCE(2);
813 }
814 }
815 HANDLE_INSTRUCTION_END();
816
817 HANDLE_INSTRUCTION_START(IF_GE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700818 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >=
819 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200820 int16_t offset = inst->VRegC_22t();
821 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800822 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200823 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700824 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200825 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200826 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200827 }
828 ADVANCE(offset);
829 } else {
830 ADVANCE(2);
831 }
832 }
833 HANDLE_INSTRUCTION_END();
834
835 HANDLE_INSTRUCTION_START(IF_GT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700836 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >
837 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200838 int16_t offset = inst->VRegC_22t();
839 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800840 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200841 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700842 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200843 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200844 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200845 }
846 ADVANCE(offset);
847 } else {
848 ADVANCE(2);
849 }
850 }
851 HANDLE_INSTRUCTION_END();
852
853 HANDLE_INSTRUCTION_START(IF_LE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700854 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <=
855 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200856 int16_t offset = inst->VRegC_22t();
857 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800858 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200859 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700860 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200861 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200862 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200863 }
864 ADVANCE(offset);
865 } else {
866 ADVANCE(2);
867 }
868 }
869 HANDLE_INSTRUCTION_END();
870
871 HANDLE_INSTRUCTION_START(IF_EQZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200872 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) == 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200873 int16_t offset = inst->VRegB_21t();
874 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800875 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200876 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700877 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200878 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200879 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200880 }
881 ADVANCE(offset);
882 } else {
883 ADVANCE(2);
884 }
885 }
886 HANDLE_INSTRUCTION_END();
887
888 HANDLE_INSTRUCTION_START(IF_NEZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200889 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) != 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200890 int16_t offset = inst->VRegB_21t();
891 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800892 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200893 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700894 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200895 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200896 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200897 }
898 ADVANCE(offset);
899 } else {
900 ADVANCE(2);
901 }
902 }
903 HANDLE_INSTRUCTION_END();
904
905 HANDLE_INSTRUCTION_START(IF_LTZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200906 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) < 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200907 int16_t offset = inst->VRegB_21t();
908 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800909 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200910 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700911 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200912 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200913 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200914 }
915 ADVANCE(offset);
916 } else {
917 ADVANCE(2);
918 }
919 }
920 HANDLE_INSTRUCTION_END();
921
922 HANDLE_INSTRUCTION_START(IF_GEZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200923 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) >= 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200924 int16_t offset = inst->VRegB_21t();
925 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800926 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200927 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700928 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200929 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200930 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200931 }
932 ADVANCE(offset);
933 } else {
934 ADVANCE(2);
935 }
936 }
937 HANDLE_INSTRUCTION_END();
938
939 HANDLE_INSTRUCTION_START(IF_GTZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200940 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) > 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200941 int16_t offset = inst->VRegB_21t();
942 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800943 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200944 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700945 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200946 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200947 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200948 }
949 ADVANCE(offset);
950 } else {
951 ADVANCE(2);
952 }
953 }
954 HANDLE_INSTRUCTION_END();
955
956 HANDLE_INSTRUCTION_START(IF_LEZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200957 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) <= 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200958 int16_t offset = inst->VRegB_21t();
959 if (IsBackwardBranch(offset)) {
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800960 BACKWARD_BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200961 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700962 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200963 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200964 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200965 }
966 ADVANCE(offset);
967 } else {
968 ADVANCE(2);
969 }
970 }
971 HANDLE_INSTRUCTION_END();
972
973 HANDLE_INSTRUCTION_START(AGET_BOOLEAN) {
974 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700975 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000976 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200977 HANDLE_PENDING_EXCEPTION();
978 } else {
979 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
980 BooleanArray* array = a->AsBooleanArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +0100981 if (LIKELY(array->CheckIsValidIndex(index))) {
982 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200983 ADVANCE(2);
984 } else {
985 HANDLE_PENDING_EXCEPTION();
986 }
987 }
988 }
989 HANDLE_INSTRUCTION_END();
990
991 HANDLE_INSTRUCTION_START(AGET_BYTE) {
992 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700993 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000994 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200995 HANDLE_PENDING_EXCEPTION();
996 } else {
997 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
998 ByteArray* array = a->AsByteArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +0100999 if (LIKELY(array->CheckIsValidIndex(index))) {
1000 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001001 ADVANCE(2);
1002 } else {
1003 HANDLE_PENDING_EXCEPTION();
1004 }
1005 }
1006 }
1007 HANDLE_INSTRUCTION_END();
1008
1009 HANDLE_INSTRUCTION_START(AGET_CHAR) {
1010 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001011 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001012 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001013 HANDLE_PENDING_EXCEPTION();
1014 } else {
1015 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1016 CharArray* array = a->AsCharArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001017 if (LIKELY(array->CheckIsValidIndex(index))) {
1018 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001019 ADVANCE(2);
1020 } else {
1021 HANDLE_PENDING_EXCEPTION();
1022 }
1023 }
1024 }
1025 HANDLE_INSTRUCTION_END();
1026
1027 HANDLE_INSTRUCTION_START(AGET_SHORT) {
1028 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001029 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001030 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001031 HANDLE_PENDING_EXCEPTION();
1032 } else {
1033 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1034 ShortArray* array = a->AsShortArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001035 if (LIKELY(array->CheckIsValidIndex(index))) {
1036 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001037 ADVANCE(2);
1038 } else {
1039 HANDLE_PENDING_EXCEPTION();
1040 }
1041 }
1042 }
1043 HANDLE_INSTRUCTION_END();
1044
1045 HANDLE_INSTRUCTION_START(AGET) {
1046 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001047 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001048 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001049 HANDLE_PENDING_EXCEPTION();
1050 } else {
1051 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1052 IntArray* array = a->AsIntArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001053 if (LIKELY(array->CheckIsValidIndex(index))) {
1054 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001055 ADVANCE(2);
1056 } else {
1057 HANDLE_PENDING_EXCEPTION();
1058 }
1059 }
1060 }
1061 HANDLE_INSTRUCTION_END();
1062
1063 HANDLE_INSTRUCTION_START(AGET_WIDE) {
1064 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001065 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001066 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001067 HANDLE_PENDING_EXCEPTION();
1068 } else {
1069 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1070 LongArray* array = a->AsLongArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001071 if (LIKELY(array->CheckIsValidIndex(index))) {
1072 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001073 ADVANCE(2);
1074 } else {
1075 HANDLE_PENDING_EXCEPTION();
1076 }
1077 }
1078 }
1079 HANDLE_INSTRUCTION_END();
1080
1081 HANDLE_INSTRUCTION_START(AGET_OBJECT) {
1082 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001083 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001084 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001085 HANDLE_PENDING_EXCEPTION();
1086 } else {
1087 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1088 ObjectArray<Object>* array = a->AsObjectArray<Object>();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001089 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001090 shadow_frame.SetVRegReference(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001091 ADVANCE(2);
1092 } else {
1093 HANDLE_PENDING_EXCEPTION();
1094 }
1095 }
1096 }
1097 HANDLE_INSTRUCTION_END();
1098
1099 HANDLE_INSTRUCTION_START(APUT_BOOLEAN) {
1100 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001101 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001102 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001103 HANDLE_PENDING_EXCEPTION();
1104 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001105 uint8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001106 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1107 BooleanArray* array = a->AsBooleanArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001108 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001109 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001110 ADVANCE(2);
1111 } else {
1112 HANDLE_PENDING_EXCEPTION();
1113 }
1114 }
1115 }
1116 HANDLE_INSTRUCTION_END();
1117
1118 HANDLE_INSTRUCTION_START(APUT_BYTE) {
1119 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001120 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001121 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001122 HANDLE_PENDING_EXCEPTION();
1123 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001124 int8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001125 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1126 ByteArray* array = a->AsByteArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001127 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001128 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001129 ADVANCE(2);
1130 } else {
1131 HANDLE_PENDING_EXCEPTION();
1132 }
1133 }
1134 }
1135 HANDLE_INSTRUCTION_END();
1136
1137 HANDLE_INSTRUCTION_START(APUT_CHAR) {
1138 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001139 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001140 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001141 HANDLE_PENDING_EXCEPTION();
1142 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001143 uint16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001144 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1145 CharArray* array = a->AsCharArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001146 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001147 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001148 ADVANCE(2);
1149 } else {
1150 HANDLE_PENDING_EXCEPTION();
1151 }
1152 }
1153 }
1154 HANDLE_INSTRUCTION_END();
1155
1156 HANDLE_INSTRUCTION_START(APUT_SHORT) {
1157 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001158 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001159 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001160 HANDLE_PENDING_EXCEPTION();
1161 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001162 int16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001163 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1164 ShortArray* array = a->AsShortArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001165 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001166 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001167 ADVANCE(2);
1168 } else {
1169 HANDLE_PENDING_EXCEPTION();
1170 }
1171 }
1172 }
1173 HANDLE_INSTRUCTION_END();
1174
1175 HANDLE_INSTRUCTION_START(APUT) {
1176 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001177 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001178 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001179 HANDLE_PENDING_EXCEPTION();
1180 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001181 int32_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001182 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1183 IntArray* array = a->AsIntArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001184 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001185 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001186 ADVANCE(2);
1187 } else {
1188 HANDLE_PENDING_EXCEPTION();
1189 }
1190 }
1191 }
1192 HANDLE_INSTRUCTION_END();
1193
1194 HANDLE_INSTRUCTION_START(APUT_WIDE) {
1195 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001196 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001197 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001198 HANDLE_PENDING_EXCEPTION();
1199 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001200 int64_t val = shadow_frame.GetVRegLong(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001201 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1202 LongArray* array = a->AsLongArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001203 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001204 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001205 ADVANCE(2);
1206 } else {
1207 HANDLE_PENDING_EXCEPTION();
1208 }
1209 }
1210 }
1211 HANDLE_INSTRUCTION_END();
1212
1213 HANDLE_INSTRUCTION_START(APUT_OBJECT) {
1214 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001215 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001216 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001217 HANDLE_PENDING_EXCEPTION();
1218 } else {
1219 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001220 Object* val = shadow_frame.GetVRegReference(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001221 ObjectArray<Object>* array = a->AsObjectArray<Object>();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001222 if (LIKELY(array->CheckIsValidIndex(index) && array->CheckAssignable(val))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001223 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001224 ADVANCE(2);
1225 } else {
1226 HANDLE_PENDING_EXCEPTION();
1227 }
1228 }
1229 }
1230 HANDLE_INSTRUCTION_END();
1231
1232 HANDLE_INSTRUCTION_START(IGET_BOOLEAN) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001233 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimBoolean, do_access_check>(
1234 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001235 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1236 }
1237 HANDLE_INSTRUCTION_END();
1238
1239 HANDLE_INSTRUCTION_START(IGET_BYTE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001240 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimByte, do_access_check>(
1241 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001242 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1243 }
1244 HANDLE_INSTRUCTION_END();
1245
1246 HANDLE_INSTRUCTION_START(IGET_CHAR) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001247 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimChar, do_access_check>(
1248 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001249 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1250 }
1251 HANDLE_INSTRUCTION_END();
1252
1253 HANDLE_INSTRUCTION_START(IGET_SHORT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001254 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimShort, do_access_check>(
1255 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001256 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1257 }
1258 HANDLE_INSTRUCTION_END();
1259
1260 HANDLE_INSTRUCTION_START(IGET) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001261 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimInt, do_access_check>(
1262 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001263 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1264 }
1265 HANDLE_INSTRUCTION_END();
1266
1267 HANDLE_INSTRUCTION_START(IGET_WIDE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001268 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimLong, do_access_check>(
1269 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001270 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1271 }
1272 HANDLE_INSTRUCTION_END();
1273
1274 HANDLE_INSTRUCTION_START(IGET_OBJECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001275 bool success = DoFieldGet<InstanceObjectRead, Primitive::kPrimNot, do_access_check>(
1276 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001277 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1278 }
1279 HANDLE_INSTRUCTION_END();
1280
1281 HANDLE_INSTRUCTION_START(IGET_QUICK) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001282 bool success = DoIGetQuick<Primitive::kPrimInt>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001283 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1284 }
1285 HANDLE_INSTRUCTION_END();
1286
Mathieu Chartierffc605c2014-12-10 10:35:44 -08001287 HANDLE_INSTRUCTION_START(IGET_BOOLEAN_QUICK) {
1288 bool success = DoIGetQuick<Primitive::kPrimBoolean>(shadow_frame, inst, inst_data);
1289 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1290 }
1291 HANDLE_INSTRUCTION_END();
1292
1293 HANDLE_INSTRUCTION_START(IGET_BYTE_QUICK) {
1294 bool success = DoIGetQuick<Primitive::kPrimByte>(shadow_frame, inst, inst_data);
1295 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1296 }
1297 HANDLE_INSTRUCTION_END();
1298
1299 HANDLE_INSTRUCTION_START(IGET_CHAR_QUICK) {
1300 bool success = DoIGetQuick<Primitive::kPrimChar>(shadow_frame, inst, inst_data);
1301 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1302 }
1303 HANDLE_INSTRUCTION_END();
1304
1305 HANDLE_INSTRUCTION_START(IGET_SHORT_QUICK) {
1306 bool success = DoIGetQuick<Primitive::kPrimShort>(shadow_frame, inst, inst_data);
1307 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1308 }
1309 HANDLE_INSTRUCTION_END();
1310
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001311 HANDLE_INSTRUCTION_START(IGET_WIDE_QUICK) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001312 bool success = DoIGetQuick<Primitive::kPrimLong>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001313 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1314 }
1315 HANDLE_INSTRUCTION_END();
1316
1317 HANDLE_INSTRUCTION_START(IGET_OBJECT_QUICK) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001318 bool success = DoIGetQuick<Primitive::kPrimNot>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001319 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1320 }
1321 HANDLE_INSTRUCTION_END();
1322
1323 HANDLE_INSTRUCTION_START(SGET_BOOLEAN) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001324 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimBoolean, do_access_check>(
1325 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001326 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1327 }
1328 HANDLE_INSTRUCTION_END();
1329
1330 HANDLE_INSTRUCTION_START(SGET_BYTE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001331 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimByte, do_access_check>(
1332 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001333 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1334 }
1335 HANDLE_INSTRUCTION_END();
1336
1337 HANDLE_INSTRUCTION_START(SGET_CHAR) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001338 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimChar, do_access_check>(
1339 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001340 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1341 }
1342 HANDLE_INSTRUCTION_END();
1343
1344 HANDLE_INSTRUCTION_START(SGET_SHORT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001345 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimShort, do_access_check>(
1346 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001347 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1348 }
1349 HANDLE_INSTRUCTION_END();
1350
1351 HANDLE_INSTRUCTION_START(SGET) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001352 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimInt, do_access_check>(
1353 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001354 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1355 }
1356 HANDLE_INSTRUCTION_END();
1357
1358 HANDLE_INSTRUCTION_START(SGET_WIDE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001359 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimLong, do_access_check>(
1360 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001361 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1362 }
1363 HANDLE_INSTRUCTION_END();
1364
1365 HANDLE_INSTRUCTION_START(SGET_OBJECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001366 bool success = DoFieldGet<StaticObjectRead, Primitive::kPrimNot, do_access_check>(
1367 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001368 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1369 }
1370 HANDLE_INSTRUCTION_END();
1371
1372 HANDLE_INSTRUCTION_START(IPUT_BOOLEAN) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001373 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1374 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001375 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1376 }
1377 HANDLE_INSTRUCTION_END();
1378
1379 HANDLE_INSTRUCTION_START(IPUT_BYTE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001380 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimByte, do_access_check,
1381 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001382 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1383 }
1384 HANDLE_INSTRUCTION_END();
1385
1386 HANDLE_INSTRUCTION_START(IPUT_CHAR) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001387 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimChar, do_access_check,
1388 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001389 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1390 }
1391 HANDLE_INSTRUCTION_END();
1392
1393 HANDLE_INSTRUCTION_START(IPUT_SHORT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001394 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimShort, do_access_check,
1395 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001396 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1397 }
1398 HANDLE_INSTRUCTION_END();
1399
1400 HANDLE_INSTRUCTION_START(IPUT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001401 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimInt, do_access_check,
1402 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001403 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1404 }
1405 HANDLE_INSTRUCTION_END();
1406
1407 HANDLE_INSTRUCTION_START(IPUT_WIDE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001408 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimLong, do_access_check,
1409 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001410 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1411 }
1412 HANDLE_INSTRUCTION_END();
1413
1414 HANDLE_INSTRUCTION_START(IPUT_OBJECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001415 bool success = DoFieldPut<InstanceObjectWrite, Primitive::kPrimNot, do_access_check,
1416 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001417 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1418 }
1419 HANDLE_INSTRUCTION_END();
1420
1421 HANDLE_INSTRUCTION_START(IPUT_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001422 bool success = DoIPutQuick<Primitive::kPrimInt, transaction_active>(
1423 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001424 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1425 }
1426 HANDLE_INSTRUCTION_END();
1427
Fred Shih37f05ef2014-07-16 18:38:08 -07001428 HANDLE_INSTRUCTION_START(IPUT_BOOLEAN_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001429 bool success = DoIPutQuick<Primitive::kPrimBoolean, transaction_active>(
1430 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001431 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1432 }
1433 HANDLE_INSTRUCTION_END();
1434
1435 HANDLE_INSTRUCTION_START(IPUT_BYTE_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001436 bool success = DoIPutQuick<Primitive::kPrimByte, transaction_active>(
1437 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001438 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1439 }
1440 HANDLE_INSTRUCTION_END();
1441
1442 HANDLE_INSTRUCTION_START(IPUT_CHAR_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001443 bool success = DoIPutQuick<Primitive::kPrimChar, transaction_active>(
1444 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001445 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1446 }
1447 HANDLE_INSTRUCTION_END();
1448
1449 HANDLE_INSTRUCTION_START(IPUT_SHORT_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001450 bool success = DoIPutQuick<Primitive::kPrimShort, transaction_active>(
1451 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001452 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1453 }
1454 HANDLE_INSTRUCTION_END();
1455
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001456 HANDLE_INSTRUCTION_START(IPUT_WIDE_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001457 bool success = DoIPutQuick<Primitive::kPrimLong, transaction_active>(
1458 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001459 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1460 }
1461 HANDLE_INSTRUCTION_END();
1462
1463 HANDLE_INSTRUCTION_START(IPUT_OBJECT_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001464 bool success = DoIPutQuick<Primitive::kPrimNot, transaction_active>(
1465 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001466 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1467 }
1468 HANDLE_INSTRUCTION_END();
1469
1470 HANDLE_INSTRUCTION_START(SPUT_BOOLEAN) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001471 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1472 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001473 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1474 }
1475 HANDLE_INSTRUCTION_END();
1476
1477 HANDLE_INSTRUCTION_START(SPUT_BYTE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001478 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimByte, do_access_check,
1479 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001480 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1481 }
1482 HANDLE_INSTRUCTION_END();
1483
1484 HANDLE_INSTRUCTION_START(SPUT_CHAR) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001485 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimChar, do_access_check,
1486 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001487 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1488 }
1489 HANDLE_INSTRUCTION_END();
1490
1491 HANDLE_INSTRUCTION_START(SPUT_SHORT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001492 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimShort, do_access_check,
1493 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001494 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1495 }
1496 HANDLE_INSTRUCTION_END();
1497
1498 HANDLE_INSTRUCTION_START(SPUT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001499 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimInt, do_access_check,
1500 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001501 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1502 }
1503 HANDLE_INSTRUCTION_END();
1504
1505 HANDLE_INSTRUCTION_START(SPUT_WIDE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001506 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimLong, do_access_check,
1507 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001508 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1509 }
1510 HANDLE_INSTRUCTION_END();
1511
1512 HANDLE_INSTRUCTION_START(SPUT_OBJECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001513 bool success = DoFieldPut<StaticObjectWrite, Primitive::kPrimNot, do_access_check,
1514 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001515 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1516 }
1517 HANDLE_INSTRUCTION_END();
1518
1519 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001520 bool success = DoInvoke<kVirtual, false, do_access_check>(
1521 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001522 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001523 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1524 }
1525 HANDLE_INSTRUCTION_END();
1526
1527 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001528 bool success = DoInvoke<kVirtual, true, do_access_check>(
1529 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001530 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001531 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1532 }
1533 HANDLE_INSTRUCTION_END();
1534
1535 HANDLE_INSTRUCTION_START(INVOKE_SUPER) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001536 bool success = DoInvoke<kSuper, false, do_access_check>(
1537 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001538 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001539 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1540 }
1541 HANDLE_INSTRUCTION_END();
1542
1543 HANDLE_INSTRUCTION_START(INVOKE_SUPER_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001544 bool success = DoInvoke<kSuper, true, do_access_check>(
1545 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001546 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001547 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1548 }
1549 HANDLE_INSTRUCTION_END();
1550
1551 HANDLE_INSTRUCTION_START(INVOKE_DIRECT) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001552 bool success = DoInvoke<kDirect, false, do_access_check>(
1553 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001554 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001555 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1556 }
1557 HANDLE_INSTRUCTION_END();
1558
1559 HANDLE_INSTRUCTION_START(INVOKE_DIRECT_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001560 bool success = DoInvoke<kDirect, true, do_access_check>(
1561 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001562 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001563 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1564 }
1565 HANDLE_INSTRUCTION_END();
1566
1567 HANDLE_INSTRUCTION_START(INVOKE_INTERFACE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001568 bool success = DoInvoke<kInterface, false, do_access_check>(
1569 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001570 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001571 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1572 }
1573 HANDLE_INSTRUCTION_END();
1574
1575 HANDLE_INSTRUCTION_START(INVOKE_INTERFACE_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001576 bool success = DoInvoke<kInterface, true, do_access_check>(
1577 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001578 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001579 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1580 }
1581 HANDLE_INSTRUCTION_END();
1582
1583 HANDLE_INSTRUCTION_START(INVOKE_STATIC) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001584 bool success = DoInvoke<kStatic, false, do_access_check>(
1585 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001586 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001587 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1588 }
1589 HANDLE_INSTRUCTION_END();
1590
1591 HANDLE_INSTRUCTION_START(INVOKE_STATIC_RANGE) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001592 bool success = DoInvoke<kStatic, true, do_access_check>(
1593 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001594 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001595 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1596 }
1597 HANDLE_INSTRUCTION_END();
1598
1599 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001600 bool success = DoInvokeVirtualQuick<false>(
1601 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001602 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001603 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1604 }
1605 HANDLE_INSTRUCTION_END();
1606
1607 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_RANGE_QUICK) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001608 bool success = DoInvokeVirtualQuick<true>(
1609 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001610 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001611 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1612 }
1613 HANDLE_INSTRUCTION_END();
1614
1615 HANDLE_INSTRUCTION_START(NEG_INT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001616 shadow_frame.SetVReg(
1617 inst->VRegA_12x(inst_data), -shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001618 ADVANCE(1);
1619 HANDLE_INSTRUCTION_END();
1620
1621 HANDLE_INSTRUCTION_START(NOT_INT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001622 shadow_frame.SetVReg(
1623 inst->VRegA_12x(inst_data), ~shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001624 ADVANCE(1);
1625 HANDLE_INSTRUCTION_END();
1626
1627 HANDLE_INSTRUCTION_START(NEG_LONG)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001628 shadow_frame.SetVRegLong(
1629 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001630 ADVANCE(1);
1631 HANDLE_INSTRUCTION_END();
1632
1633 HANDLE_INSTRUCTION_START(NOT_LONG)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001634 shadow_frame.SetVRegLong(
1635 inst->VRegA_12x(inst_data), ~shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001636 ADVANCE(1);
1637 HANDLE_INSTRUCTION_END();
1638
1639 HANDLE_INSTRUCTION_START(NEG_FLOAT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001640 shadow_frame.SetVRegFloat(
1641 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001642 ADVANCE(1);
1643 HANDLE_INSTRUCTION_END();
1644
1645 HANDLE_INSTRUCTION_START(NEG_DOUBLE)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001646 shadow_frame.SetVRegDouble(
1647 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001648 ADVANCE(1);
1649 HANDLE_INSTRUCTION_END();
1650
1651 HANDLE_INSTRUCTION_START(INT_TO_LONG)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001652 shadow_frame.SetVRegLong(
1653 inst->VRegA_12x(inst_data), shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001654 ADVANCE(1);
1655 HANDLE_INSTRUCTION_END();
1656
1657 HANDLE_INSTRUCTION_START(INT_TO_FLOAT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001658 shadow_frame.SetVRegFloat(
1659 inst->VRegA_12x(inst_data), shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001660 ADVANCE(1);
1661 HANDLE_INSTRUCTION_END();
1662
1663 HANDLE_INSTRUCTION_START(INT_TO_DOUBLE)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001664 shadow_frame.SetVRegDouble(
1665 inst->VRegA_12x(inst_data), shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001666 ADVANCE(1);
1667 HANDLE_INSTRUCTION_END();
1668
1669 HANDLE_INSTRUCTION_START(LONG_TO_INT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001670 shadow_frame.SetVReg(
1671 inst->VRegA_12x(inst_data), shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001672 ADVANCE(1);
1673 HANDLE_INSTRUCTION_END();
1674
1675 HANDLE_INSTRUCTION_START(LONG_TO_FLOAT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001676 shadow_frame.SetVRegFloat(
1677 inst->VRegA_12x(inst_data), shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001678 ADVANCE(1);
1679 HANDLE_INSTRUCTION_END();
1680
1681 HANDLE_INSTRUCTION_START(LONG_TO_DOUBLE)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001682 shadow_frame.SetVRegDouble(
1683 inst->VRegA_12x(inst_data), shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001684 ADVANCE(1);
1685 HANDLE_INSTRUCTION_END();
1686
1687 HANDLE_INSTRUCTION_START(FLOAT_TO_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001688 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001689 int32_t result = art_float_to_integral<int32_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001690 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001691 ADVANCE(1);
1692 }
1693 HANDLE_INSTRUCTION_END();
1694
1695 HANDLE_INSTRUCTION_START(FLOAT_TO_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001696 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001697 int64_t result = art_float_to_integral<int64_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001698 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001699 ADVANCE(1);
1700 }
1701 HANDLE_INSTRUCTION_END();
1702
1703 HANDLE_INSTRUCTION_START(FLOAT_TO_DOUBLE)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001704 shadow_frame.SetVRegDouble(
1705 inst->VRegA_12x(inst_data), shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001706 ADVANCE(1);
1707 HANDLE_INSTRUCTION_END();
1708
1709 HANDLE_INSTRUCTION_START(DOUBLE_TO_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001710 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001711 int32_t result = art_float_to_integral<int32_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001712 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001713 ADVANCE(1);
1714 }
1715 HANDLE_INSTRUCTION_END();
1716
1717 HANDLE_INSTRUCTION_START(DOUBLE_TO_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001718 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001719 int64_t result = art_float_to_integral<int64_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001720 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001721 ADVANCE(1);
1722 }
1723 HANDLE_INSTRUCTION_END();
1724
1725 HANDLE_INSTRUCTION_START(DOUBLE_TO_FLOAT)
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001726 shadow_frame.SetVRegFloat(
1727 inst->VRegA_12x(inst_data), shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001728 ADVANCE(1);
1729 HANDLE_INSTRUCTION_END();
1730
1731 HANDLE_INSTRUCTION_START(INT_TO_BYTE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001732 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1733 static_cast<int8_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001734 ADVANCE(1);
1735 HANDLE_INSTRUCTION_END();
1736
1737 HANDLE_INSTRUCTION_START(INT_TO_CHAR)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001738 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1739 static_cast<uint16_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001740 ADVANCE(1);
1741 HANDLE_INSTRUCTION_END();
1742
1743 HANDLE_INSTRUCTION_START(INT_TO_SHORT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001744 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1745 static_cast<int16_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001746 ADVANCE(1);
1747 HANDLE_INSTRUCTION_END();
1748
1749 HANDLE_INSTRUCTION_START(ADD_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001750 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001751 SafeAdd(shadow_frame.GetVReg(inst->VRegB_23x()),
1752 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001753 ADVANCE(2);
1754 HANDLE_INSTRUCTION_END();
1755
1756 HANDLE_INSTRUCTION_START(SUB_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001757 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001758 SafeSub(shadow_frame.GetVReg(inst->VRegB_23x()),
1759 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001760 ADVANCE(2);
1761 HANDLE_INSTRUCTION_END();
1762
1763 HANDLE_INSTRUCTION_START(MUL_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001764 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001765 SafeMul(shadow_frame.GetVReg(inst->VRegB_23x()),
1766 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001767 ADVANCE(2);
1768 HANDLE_INSTRUCTION_END();
1769
1770 HANDLE_INSTRUCTION_START(DIV_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001771 bool success = DoIntDivide(shadow_frame, inst->VRegA_23x(inst_data),
1772 shadow_frame.GetVReg(inst->VRegB_23x()),
1773 shadow_frame.GetVReg(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001774 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1775 }
1776 HANDLE_INSTRUCTION_END();
1777
1778 HANDLE_INSTRUCTION_START(REM_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001779 bool success = DoIntRemainder(shadow_frame, inst->VRegA_23x(inst_data),
1780 shadow_frame.GetVReg(inst->VRegB_23x()),
1781 shadow_frame.GetVReg(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001782 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1783 }
1784 HANDLE_INSTRUCTION_END();
1785
1786 HANDLE_INSTRUCTION_START(SHL_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001787 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001788 shadow_frame.GetVReg(inst->VRegB_23x()) <<
1789 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1790 ADVANCE(2);
1791 HANDLE_INSTRUCTION_END();
1792
1793 HANDLE_INSTRUCTION_START(SHR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001794 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001795 shadow_frame.GetVReg(inst->VRegB_23x()) >>
1796 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1797 ADVANCE(2);
1798 HANDLE_INSTRUCTION_END();
1799
1800 HANDLE_INSTRUCTION_START(USHR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001801 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001802 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_23x())) >>
1803 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1804 ADVANCE(2);
1805 HANDLE_INSTRUCTION_END();
1806
1807 HANDLE_INSTRUCTION_START(AND_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001808 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001809 shadow_frame.GetVReg(inst->VRegB_23x()) &
1810 shadow_frame.GetVReg(inst->VRegC_23x()));
1811 ADVANCE(2);
1812 HANDLE_INSTRUCTION_END();
1813
1814 HANDLE_INSTRUCTION_START(OR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001815 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001816 shadow_frame.GetVReg(inst->VRegB_23x()) |
1817 shadow_frame.GetVReg(inst->VRegC_23x()));
1818 ADVANCE(2);
1819 HANDLE_INSTRUCTION_END();
1820
1821 HANDLE_INSTRUCTION_START(XOR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001822 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001823 shadow_frame.GetVReg(inst->VRegB_23x()) ^
1824 shadow_frame.GetVReg(inst->VRegC_23x()));
1825 ADVANCE(2);
1826 HANDLE_INSTRUCTION_END();
1827
1828 HANDLE_INSTRUCTION_START(ADD_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001829 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001830 SafeAdd(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1831 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001832 ADVANCE(2);
1833 HANDLE_INSTRUCTION_END();
1834
1835 HANDLE_INSTRUCTION_START(SUB_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001836 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001837 SafeSub(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1838 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001839 ADVANCE(2);
1840 HANDLE_INSTRUCTION_END();
1841
1842 HANDLE_INSTRUCTION_START(MUL_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001843 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001844 SafeMul(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1845 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001846 ADVANCE(2);
1847 HANDLE_INSTRUCTION_END();
1848
1849 HANDLE_INSTRUCTION_START(DIV_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001850 bool success = DoLongDivide(shadow_frame, inst->VRegA_23x(inst_data),
1851 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1852 shadow_frame.GetVRegLong(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001853 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1854 }
1855 HANDLE_INSTRUCTION_END();
1856
1857 HANDLE_INSTRUCTION_START(REM_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001858 bool success = DoLongRemainder(shadow_frame, inst->VRegA_23x(inst_data),
1859 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1860 shadow_frame.GetVRegLong(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001861 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1862 }
1863 HANDLE_INSTRUCTION_END();
1864
1865 HANDLE_INSTRUCTION_START(AND_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001866 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001867 shadow_frame.GetVRegLong(inst->VRegB_23x()) &
1868 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1869 ADVANCE(2);
1870 HANDLE_INSTRUCTION_END();
1871
1872 HANDLE_INSTRUCTION_START(OR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001873 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001874 shadow_frame.GetVRegLong(inst->VRegB_23x()) |
1875 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1876 ADVANCE(2);
1877 HANDLE_INSTRUCTION_END();
1878
1879 HANDLE_INSTRUCTION_START(XOR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001880 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001881 shadow_frame.GetVRegLong(inst->VRegB_23x()) ^
1882 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1883 ADVANCE(2);
1884 HANDLE_INSTRUCTION_END();
1885
1886 HANDLE_INSTRUCTION_START(SHL_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001887 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001888 shadow_frame.GetVRegLong(inst->VRegB_23x()) <<
1889 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1890 ADVANCE(2);
1891 HANDLE_INSTRUCTION_END();
1892
1893 HANDLE_INSTRUCTION_START(SHR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001894 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001895 shadow_frame.GetVRegLong(inst->VRegB_23x()) >>
1896 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1897 ADVANCE(2);
1898 HANDLE_INSTRUCTION_END();
1899
1900 HANDLE_INSTRUCTION_START(USHR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001901 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001902 static_cast<uint64_t>(shadow_frame.GetVRegLong(inst->VRegB_23x())) >>
1903 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1904 ADVANCE(2);
1905 HANDLE_INSTRUCTION_END();
1906
1907 HANDLE_INSTRUCTION_START(ADD_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001908 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001909 shadow_frame.GetVRegFloat(inst->VRegB_23x()) +
1910 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1911 ADVANCE(2);
1912 HANDLE_INSTRUCTION_END();
1913
1914 HANDLE_INSTRUCTION_START(SUB_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001915 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001916 shadow_frame.GetVRegFloat(inst->VRegB_23x()) -
1917 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1918 ADVANCE(2);
1919 HANDLE_INSTRUCTION_END();
1920
1921 HANDLE_INSTRUCTION_START(MUL_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001922 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001923 shadow_frame.GetVRegFloat(inst->VRegB_23x()) *
1924 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1925 ADVANCE(2);
1926 HANDLE_INSTRUCTION_END();
1927
1928 HANDLE_INSTRUCTION_START(DIV_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001929 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001930 shadow_frame.GetVRegFloat(inst->VRegB_23x()) /
1931 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1932 ADVANCE(2);
1933 HANDLE_INSTRUCTION_END();
1934
1935 HANDLE_INSTRUCTION_START(REM_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001936 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001937 fmodf(shadow_frame.GetVRegFloat(inst->VRegB_23x()),
1938 shadow_frame.GetVRegFloat(inst->VRegC_23x())));
1939 ADVANCE(2);
1940 HANDLE_INSTRUCTION_END();
1941
1942 HANDLE_INSTRUCTION_START(ADD_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001943 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001944 shadow_frame.GetVRegDouble(inst->VRegB_23x()) +
1945 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1946 ADVANCE(2);
1947 HANDLE_INSTRUCTION_END();
1948
1949 HANDLE_INSTRUCTION_START(SUB_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001950 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001951 shadow_frame.GetVRegDouble(inst->VRegB_23x()) -
1952 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1953 ADVANCE(2);
1954 HANDLE_INSTRUCTION_END();
1955
1956 HANDLE_INSTRUCTION_START(MUL_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001957 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001958 shadow_frame.GetVRegDouble(inst->VRegB_23x()) *
1959 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1960 ADVANCE(2);
1961 HANDLE_INSTRUCTION_END();
1962
1963 HANDLE_INSTRUCTION_START(DIV_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001964 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001965 shadow_frame.GetVRegDouble(inst->VRegB_23x()) /
1966 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1967 ADVANCE(2);
1968 HANDLE_INSTRUCTION_END();
1969
1970 HANDLE_INSTRUCTION_START(REM_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001971 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001972 fmod(shadow_frame.GetVRegDouble(inst->VRegB_23x()),
1973 shadow_frame.GetVRegDouble(inst->VRegC_23x())));
1974 ADVANCE(2);
1975 HANDLE_INSTRUCTION_END();
1976
1977 HANDLE_INSTRUCTION_START(ADD_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001978 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001979 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07001980 SafeAdd(shadow_frame.GetVReg(vregA),
1981 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001982 ADVANCE(1);
1983 }
1984 HANDLE_INSTRUCTION_END();
1985
1986 HANDLE_INSTRUCTION_START(SUB_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001987 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001988 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07001989 SafeSub(shadow_frame.GetVReg(vregA),
1990 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001991 ADVANCE(1);
1992 }
1993 HANDLE_INSTRUCTION_END();
1994
1995 HANDLE_INSTRUCTION_START(MUL_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001996 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001997 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07001998 SafeMul(shadow_frame.GetVReg(vregA),
1999 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002000 ADVANCE(1);
2001 }
2002 HANDLE_INSTRUCTION_END();
2003
2004 HANDLE_INSTRUCTION_START(DIV_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002005 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002006 bool success = DoIntDivide(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002007 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002008 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2009 }
2010 HANDLE_INSTRUCTION_END();
2011
2012 HANDLE_INSTRUCTION_START(REM_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002013 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002014 bool success = DoIntRemainder(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002015 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002016 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2017 }
2018 HANDLE_INSTRUCTION_END();
2019
2020 HANDLE_INSTRUCTION_START(SHL_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002021 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002022 shadow_frame.SetVReg(vregA,
2023 shadow_frame.GetVReg(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002024 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002025 ADVANCE(1);
2026 }
2027 HANDLE_INSTRUCTION_END();
2028
2029 HANDLE_INSTRUCTION_START(SHR_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002030 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002031 shadow_frame.SetVReg(vregA,
2032 shadow_frame.GetVReg(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002033 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002034 ADVANCE(1);
2035 }
2036 HANDLE_INSTRUCTION_END();
2037
2038 HANDLE_INSTRUCTION_START(USHR_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002039 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002040 shadow_frame.SetVReg(vregA,
2041 static_cast<uint32_t>(shadow_frame.GetVReg(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002042 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002043 ADVANCE(1);
2044 }
2045 HANDLE_INSTRUCTION_END();
2046
2047 HANDLE_INSTRUCTION_START(AND_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002048 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002049 shadow_frame.SetVReg(vregA,
2050 shadow_frame.GetVReg(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002051 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002052 ADVANCE(1);
2053 }
2054 HANDLE_INSTRUCTION_END();
2055
2056 HANDLE_INSTRUCTION_START(OR_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002057 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002058 shadow_frame.SetVReg(vregA,
2059 shadow_frame.GetVReg(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002060 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002061 ADVANCE(1);
2062 }
2063 HANDLE_INSTRUCTION_END();
2064
2065 HANDLE_INSTRUCTION_START(XOR_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002066 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002067 shadow_frame.SetVReg(vregA,
2068 shadow_frame.GetVReg(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002069 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002070 ADVANCE(1);
2071 }
2072 HANDLE_INSTRUCTION_END();
2073
2074 HANDLE_INSTRUCTION_START(ADD_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002075 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002076 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002077 SafeAdd(shadow_frame.GetVRegLong(vregA),
2078 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002079 ADVANCE(1);
2080 }
2081 HANDLE_INSTRUCTION_END();
2082
2083 HANDLE_INSTRUCTION_START(SUB_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002084 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002085 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002086 SafeSub(shadow_frame.GetVRegLong(vregA),
2087 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002088 ADVANCE(1);
2089 }
2090 HANDLE_INSTRUCTION_END();
2091
2092 HANDLE_INSTRUCTION_START(MUL_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002093 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002094 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002095 SafeMul(shadow_frame.GetVRegLong(vregA),
2096 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002097 ADVANCE(1);
2098 }
2099 HANDLE_INSTRUCTION_END();
2100
2101 HANDLE_INSTRUCTION_START(DIV_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002102 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002103 bool success = DoLongDivide(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002104 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002105 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2106 }
2107 HANDLE_INSTRUCTION_END();
2108
2109 HANDLE_INSTRUCTION_START(REM_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002110 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002111 bool success = DoLongRemainder(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002112 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002113 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2114 }
2115 HANDLE_INSTRUCTION_END();
2116
2117 HANDLE_INSTRUCTION_START(AND_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002118 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002119 shadow_frame.SetVRegLong(vregA,
2120 shadow_frame.GetVRegLong(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002121 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002122 ADVANCE(1);
2123 }
2124 HANDLE_INSTRUCTION_END();
2125
2126 HANDLE_INSTRUCTION_START(OR_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002127 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002128 shadow_frame.SetVRegLong(vregA,
2129 shadow_frame.GetVRegLong(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002130 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002131 ADVANCE(1);
2132 }
2133 HANDLE_INSTRUCTION_END();
2134
2135 HANDLE_INSTRUCTION_START(XOR_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002136 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002137 shadow_frame.SetVRegLong(vregA,
2138 shadow_frame.GetVRegLong(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002139 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002140 ADVANCE(1);
2141 }
2142 HANDLE_INSTRUCTION_END();
2143
2144 HANDLE_INSTRUCTION_START(SHL_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002145 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002146 shadow_frame.SetVRegLong(vregA,
2147 shadow_frame.GetVRegLong(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002148 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002149 ADVANCE(1);
2150 }
2151 HANDLE_INSTRUCTION_END();
2152
2153 HANDLE_INSTRUCTION_START(SHR_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002154 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002155 shadow_frame.SetVRegLong(vregA,
2156 shadow_frame.GetVRegLong(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002157 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002158 ADVANCE(1);
2159 }
2160 HANDLE_INSTRUCTION_END();
2161
2162 HANDLE_INSTRUCTION_START(USHR_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002163 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002164 shadow_frame.SetVRegLong(vregA,
2165 static_cast<uint64_t>(shadow_frame.GetVRegLong(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002166 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002167 ADVANCE(1);
2168 }
2169 HANDLE_INSTRUCTION_END();
2170
2171 HANDLE_INSTRUCTION_START(ADD_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002172 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002173 shadow_frame.SetVRegFloat(vregA,
2174 shadow_frame.GetVRegFloat(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002175 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002176 ADVANCE(1);
2177 }
2178 HANDLE_INSTRUCTION_END();
2179
2180 HANDLE_INSTRUCTION_START(SUB_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002181 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002182 shadow_frame.SetVRegFloat(vregA,
2183 shadow_frame.GetVRegFloat(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002184 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002185 ADVANCE(1);
2186 }
2187 HANDLE_INSTRUCTION_END();
2188
2189 HANDLE_INSTRUCTION_START(MUL_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002190 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002191 shadow_frame.SetVRegFloat(vregA,
2192 shadow_frame.GetVRegFloat(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002193 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002194 ADVANCE(1);
2195 }
2196 HANDLE_INSTRUCTION_END();
2197
2198 HANDLE_INSTRUCTION_START(DIV_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002199 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002200 shadow_frame.SetVRegFloat(vregA,
2201 shadow_frame.GetVRegFloat(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002202 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002203 ADVANCE(1);
2204 }
2205 HANDLE_INSTRUCTION_END();
2206
2207 HANDLE_INSTRUCTION_START(REM_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002208 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002209 shadow_frame.SetVRegFloat(vregA,
2210 fmodf(shadow_frame.GetVRegFloat(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002211 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002212 ADVANCE(1);
2213 }
2214 HANDLE_INSTRUCTION_END();
2215
2216 HANDLE_INSTRUCTION_START(ADD_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002217 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002218 shadow_frame.SetVRegDouble(vregA,
2219 shadow_frame.GetVRegDouble(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002220 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002221 ADVANCE(1);
2222 }
2223 HANDLE_INSTRUCTION_END();
2224
2225 HANDLE_INSTRUCTION_START(SUB_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002226 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002227 shadow_frame.SetVRegDouble(vregA,
2228 shadow_frame.GetVRegDouble(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002229 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002230 ADVANCE(1);
2231 }
2232 HANDLE_INSTRUCTION_END();
2233
2234 HANDLE_INSTRUCTION_START(MUL_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002235 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002236 shadow_frame.SetVRegDouble(vregA,
2237 shadow_frame.GetVRegDouble(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002238 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002239 ADVANCE(1);
2240 }
2241 HANDLE_INSTRUCTION_END();
2242
2243 HANDLE_INSTRUCTION_START(DIV_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002244 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002245 shadow_frame.SetVRegDouble(vregA,
2246 shadow_frame.GetVRegDouble(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002247 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002248 ADVANCE(1);
2249 }
2250 HANDLE_INSTRUCTION_END();
2251
2252 HANDLE_INSTRUCTION_START(REM_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002253 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002254 shadow_frame.SetVRegDouble(vregA,
2255 fmod(shadow_frame.GetVRegDouble(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002256 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002257 ADVANCE(1);
2258 }
2259 HANDLE_INSTRUCTION_END();
2260
2261 HANDLE_INSTRUCTION_START(ADD_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002262 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002263 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2264 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002265 ADVANCE(2);
2266 HANDLE_INSTRUCTION_END();
2267
2268 HANDLE_INSTRUCTION_START(RSUB_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002269 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002270 SafeSub(inst->VRegC_22s(),
2271 shadow_frame.GetVReg(inst->VRegB_22s(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002272 ADVANCE(2);
2273 HANDLE_INSTRUCTION_END();
2274
2275 HANDLE_INSTRUCTION_START(MUL_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002276 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002277 SafeMul(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2278 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002279 ADVANCE(2);
2280 HANDLE_INSTRUCTION_END();
2281
2282 HANDLE_INSTRUCTION_START(DIV_INT_LIT16) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002283 bool success = DoIntDivide(
2284 shadow_frame, inst->VRegA_22s(inst_data), shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2285 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002286 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2287 }
2288 HANDLE_INSTRUCTION_END();
2289
2290 HANDLE_INSTRUCTION_START(REM_INT_LIT16) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002291 bool success = DoIntRemainder(
2292 shadow_frame, inst->VRegA_22s(inst_data), shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2293 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002294 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2295 }
2296 HANDLE_INSTRUCTION_END();
2297
2298 HANDLE_INSTRUCTION_START(AND_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002299 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2300 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) &
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002301 inst->VRegC_22s());
2302 ADVANCE(2);
2303 HANDLE_INSTRUCTION_END();
2304
2305 HANDLE_INSTRUCTION_START(OR_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002306 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2307 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) |
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002308 inst->VRegC_22s());
2309 ADVANCE(2);
2310 HANDLE_INSTRUCTION_END();
2311
2312 HANDLE_INSTRUCTION_START(XOR_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002313 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2314 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) ^
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002315 inst->VRegC_22s());
2316 ADVANCE(2);
2317 HANDLE_INSTRUCTION_END();
2318
2319 HANDLE_INSTRUCTION_START(ADD_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002320 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002321 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22b()),
2322 inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002323 ADVANCE(2);
2324 HANDLE_INSTRUCTION_END();
2325
2326 HANDLE_INSTRUCTION_START(RSUB_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002327 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002328 SafeSub(inst->VRegC_22b(),
2329 shadow_frame.GetVReg(inst->VRegB_22b())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002330 ADVANCE(2);
2331 HANDLE_INSTRUCTION_END();
2332
2333 HANDLE_INSTRUCTION_START(MUL_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002334 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002335 SafeMul(shadow_frame.GetVReg(inst->VRegB_22b()),
2336 inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002337 ADVANCE(2);
2338 HANDLE_INSTRUCTION_END();
2339
2340 HANDLE_INSTRUCTION_START(DIV_INT_LIT8) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002341 bool success = DoIntDivide(shadow_frame, inst->VRegA_22b(inst_data),
2342 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002343 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2344 }
2345 HANDLE_INSTRUCTION_END();
2346
2347 HANDLE_INSTRUCTION_START(REM_INT_LIT8) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002348 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22b(inst_data),
2349 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002350 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2351 }
2352 HANDLE_INSTRUCTION_END();
2353
2354 HANDLE_INSTRUCTION_START(AND_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002355 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002356 shadow_frame.GetVReg(inst->VRegB_22b()) &
2357 inst->VRegC_22b());
2358 ADVANCE(2);
2359 HANDLE_INSTRUCTION_END();
2360
2361 HANDLE_INSTRUCTION_START(OR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002362 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002363 shadow_frame.GetVReg(inst->VRegB_22b()) |
2364 inst->VRegC_22b());
2365 ADVANCE(2);
2366 HANDLE_INSTRUCTION_END();
2367
2368 HANDLE_INSTRUCTION_START(XOR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002369 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002370 shadow_frame.GetVReg(inst->VRegB_22b()) ^
2371 inst->VRegC_22b());
2372 ADVANCE(2);
2373 HANDLE_INSTRUCTION_END();
2374
2375 HANDLE_INSTRUCTION_START(SHL_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002376 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002377 shadow_frame.GetVReg(inst->VRegB_22b()) <<
2378 (inst->VRegC_22b() & 0x1f));
2379 ADVANCE(2);
2380 HANDLE_INSTRUCTION_END();
2381
2382 HANDLE_INSTRUCTION_START(SHR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002383 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002384 shadow_frame.GetVReg(inst->VRegB_22b()) >>
2385 (inst->VRegC_22b() & 0x1f));
2386 ADVANCE(2);
2387 HANDLE_INSTRUCTION_END();
2388
2389 HANDLE_INSTRUCTION_START(USHR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002390 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002391 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_22b())) >>
2392 (inst->VRegC_22b() & 0x1f));
2393 ADVANCE(2);
2394 HANDLE_INSTRUCTION_END();
2395
2396 HANDLE_INSTRUCTION_START(UNUSED_3E)
Ian Rogerse94652f2014-12-02 11:13:19 -08002397 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002398 HANDLE_INSTRUCTION_END();
2399
2400 HANDLE_INSTRUCTION_START(UNUSED_3F)
Ian Rogerse94652f2014-12-02 11:13:19 -08002401 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002402 HANDLE_INSTRUCTION_END();
2403
2404 HANDLE_INSTRUCTION_START(UNUSED_40)
Ian Rogerse94652f2014-12-02 11:13:19 -08002405 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002406 HANDLE_INSTRUCTION_END();
2407
2408 HANDLE_INSTRUCTION_START(UNUSED_41)
Ian Rogerse94652f2014-12-02 11:13:19 -08002409 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002410 HANDLE_INSTRUCTION_END();
2411
2412 HANDLE_INSTRUCTION_START(UNUSED_42)
Ian Rogerse94652f2014-12-02 11:13:19 -08002413 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002414 HANDLE_INSTRUCTION_END();
2415
2416 HANDLE_INSTRUCTION_START(UNUSED_43)
Ian Rogerse94652f2014-12-02 11:13:19 -08002417 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002418 HANDLE_INSTRUCTION_END();
2419
2420 HANDLE_INSTRUCTION_START(UNUSED_79)
Ian Rogerse94652f2014-12-02 11:13:19 -08002421 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002422 HANDLE_INSTRUCTION_END();
2423
2424 HANDLE_INSTRUCTION_START(UNUSED_7A)
Ian Rogerse94652f2014-12-02 11:13:19 -08002425 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002426 HANDLE_INSTRUCTION_END();
2427
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002428 HANDLE_INSTRUCTION_START(UNUSED_F3)
Ian Rogerse94652f2014-12-02 11:13:19 -08002429 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002430 HANDLE_INSTRUCTION_END();
2431
2432 HANDLE_INSTRUCTION_START(UNUSED_F4)
Ian Rogerse94652f2014-12-02 11:13:19 -08002433 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002434 HANDLE_INSTRUCTION_END();
2435
2436 HANDLE_INSTRUCTION_START(UNUSED_F5)
Ian Rogerse94652f2014-12-02 11:13:19 -08002437 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002438 HANDLE_INSTRUCTION_END();
2439
2440 HANDLE_INSTRUCTION_START(UNUSED_F6)
Ian Rogerse94652f2014-12-02 11:13:19 -08002441 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002442 HANDLE_INSTRUCTION_END();
2443
2444 HANDLE_INSTRUCTION_START(UNUSED_F7)
Ian Rogerse94652f2014-12-02 11:13:19 -08002445 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002446 HANDLE_INSTRUCTION_END();
2447
2448 HANDLE_INSTRUCTION_START(UNUSED_F8)
Ian Rogerse94652f2014-12-02 11:13:19 -08002449 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002450 HANDLE_INSTRUCTION_END();
2451
2452 HANDLE_INSTRUCTION_START(UNUSED_F9)
Ian Rogerse94652f2014-12-02 11:13:19 -08002453 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002454 HANDLE_INSTRUCTION_END();
2455
2456 HANDLE_INSTRUCTION_START(UNUSED_FA)
Ian Rogerse94652f2014-12-02 11:13:19 -08002457 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002458 HANDLE_INSTRUCTION_END();
2459
2460 HANDLE_INSTRUCTION_START(UNUSED_FB)
Ian Rogerse94652f2014-12-02 11:13:19 -08002461 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002462 HANDLE_INSTRUCTION_END();
2463
2464 HANDLE_INSTRUCTION_START(UNUSED_FC)
Ian Rogerse94652f2014-12-02 11:13:19 -08002465 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002466 HANDLE_INSTRUCTION_END();
2467
2468 HANDLE_INSTRUCTION_START(UNUSED_FD)
Ian Rogerse94652f2014-12-02 11:13:19 -08002469 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002470 HANDLE_INSTRUCTION_END();
2471
2472 HANDLE_INSTRUCTION_START(UNUSED_FE)
Ian Rogerse94652f2014-12-02 11:13:19 -08002473 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002474 HANDLE_INSTRUCTION_END();
2475
2476 HANDLE_INSTRUCTION_START(UNUSED_FF)
Ian Rogerse94652f2014-12-02 11:13:19 -08002477 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002478 HANDLE_INSTRUCTION_END();
2479
2480 exception_pending_label: {
2481 CHECK(self->IsExceptionPending());
Sebastien Hertz1eda2262013-09-09 16:53:14 +02002482 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -07002483 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +02002484 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +02002485 }
Sebastien Hertzee1997a2013-09-19 14:47:09 +02002486 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002487 uint32_t found_dex_pc = FindNextInstructionFollowingException(self, shadow_frame, dex_pc,
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002488 instrumentation);
2489 if (found_dex_pc == DexFile::kDexNoIndex) {
2490 return JValue(); /* Handled in caller. */
2491 } else {
2492 int32_t displacement = static_cast<int32_t>(found_dex_pc) - static_cast<int32_t>(dex_pc);
2493 ADVANCE(displacement);
2494 }
2495 }
2496
Sebastien Hertz8379b222014-02-24 17:38:15 +01002497// Create alternative instruction handlers dedicated to instrumentation.
2498// Return instructions must not call Instrumentation::DexPcMovedEvent since they already call
2499// Instrumentation::MethodExited. This is to avoid posting debugger events twice for this location.
Sebastien Hertze713d932014-05-15 10:48:53 +02002500// Note: we do not use the kReturn instruction flag here (to test the instruction is a return). The
2501// compiler seems to not evaluate "(Instruction::FlagsOf(Instruction::code) & kReturn) != 0" to
2502// a constant condition that would remove the "if" statement so the test is free.
Sebastien Hertz8379b222014-02-24 17:38:15 +01002503#define INSTRUMENTATION_INSTRUCTION_HANDLER(o, code, n, f, r, i, a, v) \
2504 alt_op_##code: { \
2505 if (Instruction::code != Instruction::RETURN_VOID && \
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -07002506 Instruction::code != Instruction::RETURN_VOID_NO_BARRIER && \
Sebastien Hertz8379b222014-02-24 17:38:15 +01002507 Instruction::code != Instruction::RETURN && \
2508 Instruction::code != Instruction::RETURN_WIDE && \
2509 Instruction::code != Instruction::RETURN_OBJECT) { \
2510 if (LIKELY(!notified_method_entry_event)) { \
2511 Runtime* runtime = Runtime::Current(); \
2512 const instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation(); \
2513 if (UNLIKELY(instrumentation->HasDexPcListeners())) { \
2514 Object* this_object = shadow_frame.GetThisObject(code_item->ins_size_); \
2515 instrumentation->DexPcMovedEvent(self, this_object, shadow_frame.GetMethod(), dex_pc); \
2516 } \
2517 } else { \
2518 notified_method_entry_event = false; \
2519 } \
2520 } \
2521 UPDATE_HANDLER_TABLE(); \
2522 goto *handlersTable[instrumentation::kMainHandlerTable][Instruction::code]; \
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002523 }
2524#include "dex_instruction_list.h"
2525 DEX_INSTRUCTION_LIST(INSTRUMENTATION_INSTRUCTION_HANDLER)
2526#undef DEX_INSTRUCTION_LIST
2527#undef INSTRUMENTATION_INSTRUCTION_HANDLER
2528} // NOLINT(readability/fn_size)
2529
2530// Explicit definitions of ExecuteGotoImpl.
Sebastien Hertzc6714852013-09-30 16:42:32 +02002531template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) HOT_ATTR
Ian Rogerse94652f2014-12-02 11:13:19 -08002532JValue ExecuteGotoImpl<true, false>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002533 ShadowFrame& shadow_frame, JValue result_register);
Sebastien Hertzc6714852013-09-30 16:42:32 +02002534template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) HOT_ATTR
Ian Rogerse94652f2014-12-02 11:13:19 -08002535JValue ExecuteGotoImpl<false, false>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002536 ShadowFrame& shadow_frame, JValue result_register);
2537template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
Ian Rogerse94652f2014-12-02 11:13:19 -08002538JValue ExecuteGotoImpl<true, true>(Thread* self, const DexFile::CodeItem* code_item,
2539 ShadowFrame& shadow_frame, JValue result_register);
2540template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
2541JValue ExecuteGotoImpl<false, true>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002542 ShadowFrame& shadow_frame, JValue result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002543
2544} // namespace interpreter
2545} // namespace art
Colin Crosse84e4f72015-03-18 14:01:19 -07002546
2547#endif