blob: 6350c56cf9ebf05602bf05d5cc90f2fa615b9253 [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
17#include "interpreter_common.h"
Ian Rogersf72a11d2014-10-30 15:41:08 -070018#include "safe_math.h"
Sebastien Hertz8ece0502013-08-07 11:26:41 +020019
20namespace art {
21namespace interpreter {
22
23// In the following macros, we expect the following local variables exist:
24// - "self": the current Thread*.
25// - "inst" : the current Instruction*.
Sebastien Hertz3b588e02013-09-11 14:33:18 +020026// - "inst_data" : the current instruction's first 16 bits.
Sebastien Hertz8ece0502013-08-07 11:26:41 +020027// - "dex_pc": the current pc.
28// - "shadow_frame": the current shadow frame.
Sebastien Hertz8ece0502013-08-07 11:26:41 +020029// - "mh": the current MethodHelper.
30// - "currentHandlersTable": the current table of pointer to each instruction handler.
31
32// Advance to the next instruction and updates interpreter state.
Sebastien Hertz8ece0502013-08-07 11:26:41 +020033#define ADVANCE(_offset) \
34 do { \
35 int32_t disp = static_cast<int32_t>(_offset); \
36 inst = inst->RelativeAt(disp); \
37 dex_pc = static_cast<uint32_t>(static_cast<int32_t>(dex_pc) + disp); \
38 shadow_frame.SetDexPC(dex_pc); \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020039 TraceExecution(shadow_frame, inst, dex_pc, mh); \
Sebastien Hertz3b588e02013-09-11 14:33:18 +020040 inst_data = inst->Fetch16(0); \
41 goto *currentHandlersTable[inst->Opcode(inst_data)]; \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020042 } while (false)
43
44#define HANDLE_PENDING_EXCEPTION() goto exception_pending_label
45
46#define POSSIBLY_HANDLE_PENDING_EXCEPTION(_is_exception_pending, _offset) \
47 do { \
48 if (UNLIKELY(_is_exception_pending)) { \
49 HANDLE_PENDING_EXCEPTION(); \
50 } else { \
51 ADVANCE(_offset); \
52 } \
53 } while (false)
54
Sebastien Hertzee1997a2013-09-19 14:47:09 +020055#define UPDATE_HANDLER_TABLE() \
56 currentHandlersTable = handlersTable[Runtime::Current()->GetInstrumentation()->GetInterpreterHandlerTable()]
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +020057
Sebastien Hertz8ece0502013-08-07 11:26:41 +020058#define UNREACHABLE_CODE_CHECK() \
59 do { \
60 if (kIsDebugBuild) { \
61 LOG(FATAL) << "We should not be here !"; \
62 } \
63 } while (false)
64
65#define HANDLE_INSTRUCTION_START(opcode) op_##opcode: // NOLINT(whitespace/labels)
66#define HANDLE_INSTRUCTION_END() UNREACHABLE_CODE_CHECK()
67
Sebastien Hertzee1997a2013-09-19 14:47:09 +020068/**
69 * Interpreter based on computed goto tables.
70 *
71 * Each instruction is associated to a handler. This handler is responsible for executing the
72 * instruction and jump to the next instruction's handler.
73 * In order to limit the cost of instrumentation, we have two handler tables:
74 * - the "main" handler table: it contains handlers for normal execution of each instruction without
75 * handling of instrumentation.
76 * - the "alternative" handler table: it contains alternative handlers which first handle
77 * instrumentation before jumping to the corresponding "normal" instruction's handler.
78 *
79 * When instrumentation is active, the interpreter uses the "alternative" handler table. Otherwise
80 * it uses the "main" handler table.
81 *
82 * The current handler table is the handler table being used by the interpreter. It is updated:
83 * - on backward branch (goto, if and switch instructions)
84 * - after invoke
85 * - when an exception is thrown.
86 * This allows to support an attaching debugger to an already running application for instance.
87 *
88 * For a fast handler table update, handler tables are stored in an array of handler tables. Each
89 * handler table is represented by the InterpreterHandlerTable enum which allows to associate it
90 * to an index in this array of handler tables ((see Instrumentation::GetInterpreterHandlerTable).
91 *
92 * Here's the current layout of this array of handler tables:
93 *
94 * ---------------------+---------------+
95 * | NOP | (handler for NOP instruction)
96 * +---------------+
97 * "main" | MOVE | (handler for MOVE instruction)
98 * handler table +---------------+
99 * | ... |
100 * +---------------+
101 * | UNUSED_FF | (handler for UNUSED_FF instruction)
102 * ---------------------+---------------+
103 * | NOP | (alternative handler for NOP instruction)
104 * +---------------+
105 * "alternative" | MOVE | (alternative handler for MOVE instruction)
106 * handler table +---------------+
107 * | ... |
108 * +---------------+
109 * | UNUSED_FF | (alternative handler for UNUSED_FF instruction)
110 * ---------------------+---------------+
111 *
112 */
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100113template<bool do_access_check, bool transaction_active>
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200114JValue ExecuteGotoImpl(Thread* self, MethodHelper& mh, const DexFile::CodeItem* code_item,
115 ShadowFrame& shadow_frame, JValue result_register) {
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200116 // Define handler tables:
117 // - The main handler table contains execution handlers for each instruction.
118 // - The alternative handler table contains prelude handlers which check for thread suspend and
119 // manage instrumentation before jumping to the execution handler.
120 static const void* const handlersTable[instrumentation::kNumHandlerTables][kNumPackedOpcodes] = {
121 {
122 // Main handler table.
123#define INSTRUCTION_HANDLER(o, code, n, f, r, i, a, v) &&op_##code,
124#include "dex_instruction_list.h"
125 DEX_INSTRUCTION_LIST(INSTRUCTION_HANDLER)
126#undef DEX_INSTRUCTION_LIST
127#undef INSTRUCTION_HANDLER
128 }, {
129 // Alternative handler table.
130#define INSTRUCTION_HANDLER(o, code, n, f, r, i, a, v) &&alt_op_##code,
131#include "dex_instruction_list.h"
132 DEX_INSTRUCTION_LIST(INSTRUCTION_HANDLER)
133#undef DEX_INSTRUCTION_LIST
134#undef INSTRUCTION_HANDLER
135 }
136 };
137
138 const bool do_assignability_check = do_access_check;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200139 if (UNLIKELY(!shadow_frame.HasReferenceArray())) {
140 LOG(FATAL) << "Invalid shadow frame for interpreter use";
141 return JValue();
142 }
143 self->VerifyStack();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200144
145 uint32_t dex_pc = shadow_frame.GetDexPC();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200146 const Instruction* inst = Instruction::At(code_item->insns_ + dex_pc);
147 uint16_t inst_data;
148 const void* const* currentHandlersTable;
Sebastien Hertz8379b222014-02-24 17:38:15 +0100149 bool notified_method_entry_event = false;
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200150 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200151 if (LIKELY(dex_pc == 0)) { // We are entering the method as opposed to deoptimizing..
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200152 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200153 if (UNLIKELY(instrumentation->HasMethodEntryListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200154 instrumentation->MethodEnterEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200155 shadow_frame.GetMethod(), 0);
Sebastien Hertz8379b222014-02-24 17:38:15 +0100156 notified_method_entry_event = true;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200157 }
158 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200159
160 // Jump to first instruction.
161 ADVANCE(0);
162 UNREACHABLE_CODE_CHECK();
163
164 HANDLE_INSTRUCTION_START(NOP)
165 ADVANCE(1);
166 HANDLE_INSTRUCTION_END();
167
168 HANDLE_INSTRUCTION_START(MOVE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200169 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
170 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200171 ADVANCE(1);
172 HANDLE_INSTRUCTION_END();
173
174 HANDLE_INSTRUCTION_START(MOVE_FROM16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200175 shadow_frame.SetVReg(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200176 shadow_frame.GetVReg(inst->VRegB_22x()));
177 ADVANCE(2);
178 HANDLE_INSTRUCTION_END();
179
180 HANDLE_INSTRUCTION_START(MOVE_16)
181 shadow_frame.SetVReg(inst->VRegA_32x(),
182 shadow_frame.GetVReg(inst->VRegB_32x()));
183 ADVANCE(3);
184 HANDLE_INSTRUCTION_END();
185
186 HANDLE_INSTRUCTION_START(MOVE_WIDE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200187 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
188 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200189 ADVANCE(1);
190 HANDLE_INSTRUCTION_END();
191
192 HANDLE_INSTRUCTION_START(MOVE_WIDE_FROM16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200193 shadow_frame.SetVRegLong(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200194 shadow_frame.GetVRegLong(inst->VRegB_22x()));
195 ADVANCE(2);
196 HANDLE_INSTRUCTION_END();
197
198 HANDLE_INSTRUCTION_START(MOVE_WIDE_16)
199 shadow_frame.SetVRegLong(inst->VRegA_32x(),
200 shadow_frame.GetVRegLong(inst->VRegB_32x()));
201 ADVANCE(3);
202 HANDLE_INSTRUCTION_END();
203
204 HANDLE_INSTRUCTION_START(MOVE_OBJECT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200205 shadow_frame.SetVRegReference(inst->VRegA_12x(inst_data),
206 shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200207 ADVANCE(1);
208 HANDLE_INSTRUCTION_END();
209
210 HANDLE_INSTRUCTION_START(MOVE_OBJECT_FROM16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200211 shadow_frame.SetVRegReference(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200212 shadow_frame.GetVRegReference(inst->VRegB_22x()));
213 ADVANCE(2);
214 HANDLE_INSTRUCTION_END();
215
216 HANDLE_INSTRUCTION_START(MOVE_OBJECT_16)
217 shadow_frame.SetVRegReference(inst->VRegA_32x(),
218 shadow_frame.GetVRegReference(inst->VRegB_32x()));
219 ADVANCE(3);
220 HANDLE_INSTRUCTION_END();
221
222 HANDLE_INSTRUCTION_START(MOVE_RESULT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200223 shadow_frame.SetVReg(inst->VRegA_11x(inst_data), result_register.GetI());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200224 ADVANCE(1);
225 HANDLE_INSTRUCTION_END();
226
227 HANDLE_INSTRUCTION_START(MOVE_RESULT_WIDE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200228 shadow_frame.SetVRegLong(inst->VRegA_11x(inst_data), result_register.GetJ());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200229 ADVANCE(1);
230 HANDLE_INSTRUCTION_END();
231
232 HANDLE_INSTRUCTION_START(MOVE_RESULT_OBJECT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200233 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), result_register.GetL());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200234 ADVANCE(1);
235 HANDLE_INSTRUCTION_END();
236
237 HANDLE_INSTRUCTION_START(MOVE_EXCEPTION) {
Sebastien Hertz5c004902014-05-21 10:07:42 +0200238 Throwable* exception = self->GetException(nullptr);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200239 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), exception);
Sebastien Hertz5c004902014-05-21 10:07:42 +0200240 self->ClearException();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200241 ADVANCE(1);
242 }
243 HANDLE_INSTRUCTION_END();
244
245 HANDLE_INSTRUCTION_START(RETURN_VOID) {
246 JValue result;
Sebastien Hertz043036f2013-09-09 18:26:48 +0200247 if (do_access_check) {
248 // If access checks are required then the dex-to-dex compiler and analysis of
249 // whether the class has final fields hasn't been performed. Conservatively
250 // perform the memory barrier now.
Hans Boehm30359612014-05-21 17:46:23 -0700251 QuasiAtomic::ThreadFenceForConstructor();
Sebastien Hertz043036f2013-09-09 18:26:48 +0200252 }
Ian Rogers7b078e82014-09-10 14:44:24 -0700253 self->AllowThreadSuspension();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200254 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200255 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200256 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200257 shadow_frame.GetMethod(), dex_pc,
258 result);
Sebastien Hertze713d932014-05-15 10:48:53 +0200259 } else if (UNLIKELY(instrumentation->HasDexPcListeners())) {
260 instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
261 shadow_frame.GetMethod(), dex_pc);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200262 }
263 return result;
264 }
265 HANDLE_INSTRUCTION_END();
266
267 HANDLE_INSTRUCTION_START(RETURN_VOID_BARRIER) {
Hans Boehm30359612014-05-21 17:46:23 -0700268 QuasiAtomic::ThreadFenceForConstructor();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200269 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700270 self->AllowThreadSuspension();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200271 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200272 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200273 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200274 shadow_frame.GetMethod(), dex_pc,
275 result);
Sebastien Hertze713d932014-05-15 10:48:53 +0200276 } else if (UNLIKELY(instrumentation->HasDexPcListeners())) {
277 instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
278 shadow_frame.GetMethod(), dex_pc);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200279 }
280 return result;
281 }
282 HANDLE_INSTRUCTION_END();
283
284 HANDLE_INSTRUCTION_START(RETURN) {
285 JValue result;
286 result.SetJ(0);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200287 result.SetI(shadow_frame.GetVReg(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700288 self->AllowThreadSuspension();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200289 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200290 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200291 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200292 shadow_frame.GetMethod(), dex_pc,
293 result);
Sebastien Hertze713d932014-05-15 10:48:53 +0200294 } else if (UNLIKELY(instrumentation->HasDexPcListeners())) {
295 instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
296 shadow_frame.GetMethod(), dex_pc);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200297 }
298 return result;
299 }
300 HANDLE_INSTRUCTION_END();
301
302 HANDLE_INSTRUCTION_START(RETURN_WIDE) {
303 JValue result;
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200304 result.SetJ(shadow_frame.GetVRegLong(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700305 self->AllowThreadSuspension();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200306 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200307 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200308 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200309 shadow_frame.GetMethod(), dex_pc,
310 result);
Sebastien Hertze713d932014-05-15 10:48:53 +0200311 } else if (UNLIKELY(instrumentation->HasDexPcListeners())) {
312 instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
313 shadow_frame.GetMethod(), dex_pc);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200314 }
315 return result;
316 }
317 HANDLE_INSTRUCTION_END();
318
319 HANDLE_INSTRUCTION_START(RETURN_OBJECT) {
320 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700321 self->AllowThreadSuspension();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700322 const uint8_t vreg_index = inst->VRegA_11x(inst_data);
323 Object* obj_result = shadow_frame.GetVRegReference(vreg_index);
Jeff Haoa3faaf42013-09-03 19:07:00 -0700324 if (do_assignability_check && obj_result != NULL) {
Ian Rogersded66a02014-10-28 18:12:55 -0700325 Class* return_type = shadow_frame.GetMethod()->GetReturnType();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700326 obj_result = shadow_frame.GetVRegReference(vreg_index);
Jeff Haoa3faaf42013-09-03 19:07:00 -0700327 if (return_type == NULL) {
328 // Return the pending exception.
329 HANDLE_PENDING_EXCEPTION();
330 }
331 if (!obj_result->VerifierInstanceOf(return_type)) {
332 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700333 std::string temp1, temp2;
Jeff Haoa3faaf42013-09-03 19:07:00 -0700334 self->ThrowNewExceptionF(self->GetCurrentLocationForThrow(),
335 "Ljava/lang/VirtualMachineError;",
336 "Returning '%s' that is not instance of return type '%s'",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700337 obj_result->GetClass()->GetDescriptor(&temp1),
338 return_type->GetDescriptor(&temp2));
Jeff Haoa3faaf42013-09-03 19:07:00 -0700339 HANDLE_PENDING_EXCEPTION();
340 }
341 }
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700342 result.SetL(obj_result);
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200343 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200344 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200345 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200346 shadow_frame.GetMethod(), dex_pc,
347 result);
Sebastien Hertze713d932014-05-15 10:48:53 +0200348 } else if (UNLIKELY(instrumentation->HasDexPcListeners())) {
349 instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
350 shadow_frame.GetMethod(), dex_pc);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200351 }
352 return result;
353 }
354 HANDLE_INSTRUCTION_END();
355
356 HANDLE_INSTRUCTION_START(CONST_4) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200357 uint32_t dst = inst->VRegA_11n(inst_data);
358 int32_t val = inst->VRegB_11n(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200359 shadow_frame.SetVReg(dst, val);
360 if (val == 0) {
361 shadow_frame.SetVRegReference(dst, NULL);
362 }
363 ADVANCE(1);
364 }
365 HANDLE_INSTRUCTION_END();
366
367 HANDLE_INSTRUCTION_START(CONST_16) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200368 uint32_t dst = inst->VRegA_21s(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200369 int32_t val = inst->VRegB_21s();
370 shadow_frame.SetVReg(dst, val);
371 if (val == 0) {
372 shadow_frame.SetVRegReference(dst, NULL);
373 }
374 ADVANCE(2);
375 }
376 HANDLE_INSTRUCTION_END();
377
378 HANDLE_INSTRUCTION_START(CONST) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200379 uint32_t dst = inst->VRegA_31i(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200380 int32_t val = inst->VRegB_31i();
381 shadow_frame.SetVReg(dst, val);
382 if (val == 0) {
383 shadow_frame.SetVRegReference(dst, NULL);
384 }
385 ADVANCE(3);
386 }
387 HANDLE_INSTRUCTION_END();
388
389 HANDLE_INSTRUCTION_START(CONST_HIGH16) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200390 uint32_t dst = inst->VRegA_21h(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200391 int32_t val = static_cast<int32_t>(inst->VRegB_21h() << 16);
392 shadow_frame.SetVReg(dst, val);
393 if (val == 0) {
394 shadow_frame.SetVRegReference(dst, NULL);
395 }
396 ADVANCE(2);
397 }
398 HANDLE_INSTRUCTION_END();
399
400 HANDLE_INSTRUCTION_START(CONST_WIDE_16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200401 shadow_frame.SetVRegLong(inst->VRegA_21s(inst_data), inst->VRegB_21s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200402 ADVANCE(2);
403 HANDLE_INSTRUCTION_END();
404
405 HANDLE_INSTRUCTION_START(CONST_WIDE_32)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200406 shadow_frame.SetVRegLong(inst->VRegA_31i(inst_data), inst->VRegB_31i());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200407 ADVANCE(3);
408 HANDLE_INSTRUCTION_END();
409
410 HANDLE_INSTRUCTION_START(CONST_WIDE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200411 shadow_frame.SetVRegLong(inst->VRegA_51l(inst_data), inst->VRegB_51l());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200412 ADVANCE(5);
413 HANDLE_INSTRUCTION_END();
414
415 HANDLE_INSTRUCTION_START(CONST_WIDE_HIGH16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200416 shadow_frame.SetVRegLong(inst->VRegA_21h(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200417 static_cast<uint64_t>(inst->VRegB_21h()) << 48);
418 ADVANCE(2);
419 HANDLE_INSTRUCTION_END();
420
421 HANDLE_INSTRUCTION_START(CONST_STRING) {
Ian Rogers6786a582014-10-28 12:49:06 -0700422 String* s = ResolveString(self, shadow_frame, inst->VRegB_21c());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200423 if (UNLIKELY(s == NULL)) {
424 HANDLE_PENDING_EXCEPTION();
425 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200426 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200427 ADVANCE(2);
428 }
429 }
430 HANDLE_INSTRUCTION_END();
431
432 HANDLE_INSTRUCTION_START(CONST_STRING_JUMBO) {
Ian Rogers6786a582014-10-28 12:49:06 -0700433 String* s = ResolveString(self, shadow_frame, inst->VRegB_31c());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200434 if (UNLIKELY(s == NULL)) {
435 HANDLE_PENDING_EXCEPTION();
436 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200437 shadow_frame.SetVRegReference(inst->VRegA_31c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200438 ADVANCE(3);
439 }
440 }
441 HANDLE_INSTRUCTION_END();
442
443 HANDLE_INSTRUCTION_START(CONST_CLASS) {
444 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
445 self, false, do_access_check);
446 if (UNLIKELY(c == NULL)) {
447 HANDLE_PENDING_EXCEPTION();
448 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200449 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), c);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200450 ADVANCE(2);
451 }
452 }
453 HANDLE_INSTRUCTION_END();
454
455 HANDLE_INSTRUCTION_START(MONITOR_ENTER) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200456 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200457 if (UNLIKELY(obj == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +0200458 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200459 HANDLE_PENDING_EXCEPTION();
460 } else {
461 DoMonitorEnter(self, obj);
462 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), 1);
463 }
464 }
465 HANDLE_INSTRUCTION_END();
466
467 HANDLE_INSTRUCTION_START(MONITOR_EXIT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200468 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200469 if (UNLIKELY(obj == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +0200470 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200471 HANDLE_PENDING_EXCEPTION();
472 } else {
473 DoMonitorExit(self, obj);
474 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), 1);
475 }
476 }
477 HANDLE_INSTRUCTION_END();
478
479 HANDLE_INSTRUCTION_START(CHECK_CAST) {
480 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
481 self, false, do_access_check);
482 if (UNLIKELY(c == NULL)) {
483 HANDLE_PENDING_EXCEPTION();
484 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200485 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_21c(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200486 if (UNLIKELY(obj != NULL && !obj->InstanceOf(c))) {
487 ThrowClassCastException(c, obj->GetClass());
488 HANDLE_PENDING_EXCEPTION();
489 } else {
490 ADVANCE(2);
491 }
492 }
493 }
494 HANDLE_INSTRUCTION_END();
495
496 HANDLE_INSTRUCTION_START(INSTANCE_OF) {
497 Class* c = ResolveVerifyAndClinit(inst->VRegC_22c(), shadow_frame.GetMethod(),
498 self, false, do_access_check);
499 if (UNLIKELY(c == NULL)) {
500 HANDLE_PENDING_EXCEPTION();
501 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200502 Object* obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data));
503 shadow_frame.SetVReg(inst->VRegA_22c(inst_data), (obj != NULL && obj->InstanceOf(c)) ? 1 : 0);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200504 ADVANCE(2);
505 }
506 }
507 HANDLE_INSTRUCTION_END();
508
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700509 HANDLE_INSTRUCTION_START(ARRAY_LENGTH) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200510 Object* array = shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200511 if (UNLIKELY(array == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +0200512 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200513 HANDLE_PENDING_EXCEPTION();
514 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200515 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), array->AsArray()->GetLength());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200516 ADVANCE(1);
517 }
518 }
519 HANDLE_INSTRUCTION_END();
520
521 HANDLE_INSTRUCTION_START(NEW_INSTANCE) {
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700522 Runtime* runtime = Runtime::Current();
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800523 Object* obj = AllocObjectFromCode<do_access_check, true>(
524 inst->VRegB_21c(), shadow_frame.GetMethod(), self,
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700525 runtime->GetHeap()->GetCurrentAllocator());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200526 if (UNLIKELY(obj == NULL)) {
527 HANDLE_PENDING_EXCEPTION();
528 } else {
Sebastien Hertz4e99b3d2014-06-24 14:35:40 +0200529 obj->GetClass()->AssertInitializedOrInitializingInThread(self);
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700530 // Don't allow finalizable objects to be allocated during a transaction since these can't be
531 // finalized without a started runtime.
532 if (transaction_active && obj->GetClass()->IsFinalizable()) {
Ian Rogers2fa98e22014-05-06 15:26:39 -0700533 AbortTransaction(self, "Allocating finalizable object in transaction: %s",
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700534 PrettyTypeOf(obj).c_str());
535 HANDLE_PENDING_EXCEPTION();
536 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200537 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200538 ADVANCE(2);
539 }
540 }
541 HANDLE_INSTRUCTION_END();
542
543 HANDLE_INSTRUCTION_START(NEW_ARRAY) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200544 int32_t length = shadow_frame.GetVReg(inst->VRegB_22c(inst_data));
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800545 Object* obj = AllocArrayFromCode<do_access_check, true>(
546 inst->VRegC_22c(), shadow_frame.GetMethod(), length, self,
547 Runtime::Current()->GetHeap()->GetCurrentAllocator());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200548 if (UNLIKELY(obj == NULL)) {
549 HANDLE_PENDING_EXCEPTION();
550 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200551 shadow_frame.SetVRegReference(inst->VRegA_22c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200552 ADVANCE(2);
553 }
554 }
555 HANDLE_INSTRUCTION_END();
556
557 HANDLE_INSTRUCTION_START(FILLED_NEW_ARRAY) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100558 bool success =
559 DoFilledNewArray<false, do_access_check, transaction_active>(inst, shadow_frame,
560 self, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200561 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
562 }
563 HANDLE_INSTRUCTION_END();
564
565 HANDLE_INSTRUCTION_START(FILLED_NEW_ARRAY_RANGE) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100566 bool success =
567 DoFilledNewArray<true, do_access_check, transaction_active>(inst, shadow_frame,
568 self, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200569 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
570 }
571 HANDLE_INSTRUCTION_END();
572
573 HANDLE_INSTRUCTION_START(FILL_ARRAY_DATA) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200574 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_31t(inst_data));
Ian Rogers832336b2014-10-08 15:35:22 -0700575 const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t();
576 const Instruction::ArrayDataPayload* payload =
577 reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr);
578 bool success = FillArrayData(obj, payload);
579 if (transaction_active && success) {
580 RecordArrayElementsInTransaction(obj->AsArray(), payload->element_count);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200581 }
Ian Rogers832336b2014-10-08 15:35:22 -0700582 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200583 }
584 HANDLE_INSTRUCTION_END();
585
586 HANDLE_INSTRUCTION_START(THROW) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200587 Object* exception = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200588 if (UNLIKELY(exception == NULL)) {
589 ThrowNullPointerException(NULL, "throw with null exception");
Jeff Haoa3faaf42013-09-03 19:07:00 -0700590 } else if (do_assignability_check && !exception->GetClass()->IsThrowableClass()) {
591 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700592 std::string temp;
Jeff Haoa3faaf42013-09-03 19:07:00 -0700593 self->ThrowNewExceptionF(self->GetCurrentLocationForThrow(),
594 "Ljava/lang/VirtualMachineError;",
595 "Throwing '%s' that is not instance of Throwable",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700596 exception->GetClass()->GetDescriptor(&temp));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200597 } else {
598 self->SetException(shadow_frame.GetCurrentLocationForThrow(), exception->AsThrowable());
599 }
600 HANDLE_PENDING_EXCEPTION();
601 }
602 HANDLE_INSTRUCTION_END();
603
604 HANDLE_INSTRUCTION_START(GOTO) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200605 int8_t offset = inst->VRegA_10t(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200606 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200607 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700608 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200609 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200610 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200611 }
612 ADVANCE(offset);
613 }
614 HANDLE_INSTRUCTION_END();
615
616 HANDLE_INSTRUCTION_START(GOTO_16) {
617 int16_t offset = inst->VRegA_20t();
618 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200619 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700620 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200621 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200622 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200623 }
624 ADVANCE(offset);
625 }
626 HANDLE_INSTRUCTION_END();
627
628 HANDLE_INSTRUCTION_START(GOTO_32) {
629 int32_t offset = inst->VRegA_30t();
630 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200631 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700632 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200633 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200634 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200635 }
636 ADVANCE(offset);
637 }
638 HANDLE_INSTRUCTION_END();
639
640 HANDLE_INSTRUCTION_START(PACKED_SWITCH) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200641 int32_t offset = DoPackedSwitch(inst, shadow_frame, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200642 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200643 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700644 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200645 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200646 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200647 }
648 ADVANCE(offset);
649 }
650 HANDLE_INSTRUCTION_END();
651
652 HANDLE_INSTRUCTION_START(SPARSE_SWITCH) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200653 int32_t offset = DoSparseSwitch(inst, shadow_frame, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200654 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200655 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700656 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200657 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200658 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200659 }
660 ADVANCE(offset);
661 }
662 HANDLE_INSTRUCTION_END();
663
Ian Rogers647b1a82014-10-10 11:02:11 -0700664#if defined(__clang__)
665#pragma clang diagnostic push
666#pragma clang diagnostic ignored "-Wfloat-equal"
667#endif
668
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200669 HANDLE_INSTRUCTION_START(CMPL_FLOAT) {
670 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
671 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
672 int32_t result;
673 if (val1 > val2) {
674 result = 1;
675 } else if (val1 == val2) {
676 result = 0;
677 } else {
678 result = -1;
679 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200680 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200681 ADVANCE(2);
682 }
683 HANDLE_INSTRUCTION_END();
684
685 HANDLE_INSTRUCTION_START(CMPG_FLOAT) {
686 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
687 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
688 int32_t result;
689 if (val1 < val2) {
690 result = -1;
691 } else if (val1 == val2) {
692 result = 0;
693 } else {
694 result = 1;
695 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200696 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200697 ADVANCE(2);
698 }
699 HANDLE_INSTRUCTION_END();
700
701 HANDLE_INSTRUCTION_START(CMPL_DOUBLE) {
702 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
703 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
704 int32_t result;
705 if (val1 > val2) {
706 result = 1;
707 } else if (val1 == val2) {
708 result = 0;
709 } else {
710 result = -1;
711 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200712 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200713 ADVANCE(2);
714 }
715 HANDLE_INSTRUCTION_END();
716
717 HANDLE_INSTRUCTION_START(CMPG_DOUBLE) {
718 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
719 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
720 int32_t result;
721 if (val1 < val2) {
722 result = -1;
723 } else if (val1 == val2) {
724 result = 0;
725 } else {
726 result = 1;
727 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200728 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200729 ADVANCE(2);
730 }
731 HANDLE_INSTRUCTION_END();
732
Ian Rogers647b1a82014-10-10 11:02:11 -0700733#if defined(__clang__)
734#pragma clang diagnostic pop
735#endif
736
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200737 HANDLE_INSTRUCTION_START(CMP_LONG) {
738 int64_t val1 = shadow_frame.GetVRegLong(inst->VRegB_23x());
739 int64_t val2 = shadow_frame.GetVRegLong(inst->VRegC_23x());
740 int32_t result;
741 if (val1 > val2) {
742 result = 1;
743 } else if (val1 == val2) {
744 result = 0;
745 } else {
746 result = -1;
747 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200748 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200749 ADVANCE(2);
750 }
751 HANDLE_INSTRUCTION_END();
752
753 HANDLE_INSTRUCTION_START(IF_EQ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200754 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) == shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200755 int16_t offset = inst->VRegC_22t();
756 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200757 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700758 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200759 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200760 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200761 }
762 ADVANCE(offset);
763 } else {
764 ADVANCE(2);
765 }
766 }
767 HANDLE_INSTRUCTION_END();
768
769 HANDLE_INSTRUCTION_START(IF_NE) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200770 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) != shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200771 int16_t offset = inst->VRegC_22t();
772 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200773 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700774 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200775 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200776 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200777 }
778 ADVANCE(offset);
779 } else {
780 ADVANCE(2);
781 }
782 }
783 HANDLE_INSTRUCTION_END();
784
785 HANDLE_INSTRUCTION_START(IF_LT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200786 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) < shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200787 int16_t offset = inst->VRegC_22t();
788 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200789 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700790 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200791 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200792 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200793 }
794 ADVANCE(offset);
795 } else {
796 ADVANCE(2);
797 }
798 }
799 HANDLE_INSTRUCTION_END();
800
801 HANDLE_INSTRUCTION_START(IF_GE) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200802 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >= shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200803 int16_t offset = inst->VRegC_22t();
804 if (IsBackwardBranch(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_GT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200818 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) > shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200819 int16_t offset = inst->VRegC_22t();
820 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200821 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700822 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200823 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200824 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200825 }
826 ADVANCE(offset);
827 } else {
828 ADVANCE(2);
829 }
830 }
831 HANDLE_INSTRUCTION_END();
832
833 HANDLE_INSTRUCTION_START(IF_LE) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200834 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <= shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200835 int16_t offset = inst->VRegC_22t();
836 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200837 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700838 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200839 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200840 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200841 }
842 ADVANCE(offset);
843 } else {
844 ADVANCE(2);
845 }
846 }
847 HANDLE_INSTRUCTION_END();
848
849 HANDLE_INSTRUCTION_START(IF_EQZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200850 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) == 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200851 int16_t offset = inst->VRegB_21t();
852 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200853 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700854 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200855 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200856 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200857 }
858 ADVANCE(offset);
859 } else {
860 ADVANCE(2);
861 }
862 }
863 HANDLE_INSTRUCTION_END();
864
865 HANDLE_INSTRUCTION_START(IF_NEZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200866 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) != 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200867 int16_t offset = inst->VRegB_21t();
868 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200869 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700870 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200871 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200872 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200873 }
874 ADVANCE(offset);
875 } else {
876 ADVANCE(2);
877 }
878 }
879 HANDLE_INSTRUCTION_END();
880
881 HANDLE_INSTRUCTION_START(IF_LTZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200882 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) < 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200883 int16_t offset = inst->VRegB_21t();
884 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200885 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700886 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200887 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200888 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200889 }
890 ADVANCE(offset);
891 } else {
892 ADVANCE(2);
893 }
894 }
895 HANDLE_INSTRUCTION_END();
896
897 HANDLE_INSTRUCTION_START(IF_GEZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200898 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) >= 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200899 int16_t offset = inst->VRegB_21t();
900 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200901 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700902 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200903 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200904 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200905 }
906 ADVANCE(offset);
907 } else {
908 ADVANCE(2);
909 }
910 }
911 HANDLE_INSTRUCTION_END();
912
913 HANDLE_INSTRUCTION_START(IF_GTZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200914 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) > 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200915 int16_t offset = inst->VRegB_21t();
916 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200917 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700918 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200919 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200920 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200921 }
922 ADVANCE(offset);
923 } else {
924 ADVANCE(2);
925 }
926 }
927 HANDLE_INSTRUCTION_END();
928
929 HANDLE_INSTRUCTION_START(IF_LEZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200930 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) <= 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200931 int16_t offset = inst->VRegB_21t();
932 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200933 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700934 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200935 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200936 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200937 }
938 ADVANCE(offset);
939 } else {
940 ADVANCE(2);
941 }
942 }
943 HANDLE_INSTRUCTION_END();
944
945 HANDLE_INSTRUCTION_START(AGET_BOOLEAN) {
946 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
947 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +0200948 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200949 HANDLE_PENDING_EXCEPTION();
950 } else {
951 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
952 BooleanArray* array = a->AsBooleanArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +0100953 if (LIKELY(array->CheckIsValidIndex(index))) {
954 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200955 ADVANCE(2);
956 } else {
957 HANDLE_PENDING_EXCEPTION();
958 }
959 }
960 }
961 HANDLE_INSTRUCTION_END();
962
963 HANDLE_INSTRUCTION_START(AGET_BYTE) {
964 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
965 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +0200966 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200967 HANDLE_PENDING_EXCEPTION();
968 } else {
969 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
970 ByteArray* array = a->AsByteArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +0100971 if (LIKELY(array->CheckIsValidIndex(index))) {
972 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200973 ADVANCE(2);
974 } else {
975 HANDLE_PENDING_EXCEPTION();
976 }
977 }
978 }
979 HANDLE_INSTRUCTION_END();
980
981 HANDLE_INSTRUCTION_START(AGET_CHAR) {
982 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
983 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +0200984 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200985 HANDLE_PENDING_EXCEPTION();
986 } else {
987 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
988 CharArray* array = a->AsCharArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +0100989 if (LIKELY(array->CheckIsValidIndex(index))) {
990 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200991 ADVANCE(2);
992 } else {
993 HANDLE_PENDING_EXCEPTION();
994 }
995 }
996 }
997 HANDLE_INSTRUCTION_END();
998
999 HANDLE_INSTRUCTION_START(AGET_SHORT) {
1000 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1001 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +02001002 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001003 HANDLE_PENDING_EXCEPTION();
1004 } else {
1005 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1006 ShortArray* array = a->AsShortArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001007 if (LIKELY(array->CheckIsValidIndex(index))) {
1008 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001009 ADVANCE(2);
1010 } else {
1011 HANDLE_PENDING_EXCEPTION();
1012 }
1013 }
1014 }
1015 HANDLE_INSTRUCTION_END();
1016
1017 HANDLE_INSTRUCTION_START(AGET) {
1018 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1019 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +02001020 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001021 HANDLE_PENDING_EXCEPTION();
1022 } else {
1023 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1024 IntArray* array = a->AsIntArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001025 if (LIKELY(array->CheckIsValidIndex(index))) {
1026 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001027 ADVANCE(2);
1028 } else {
1029 HANDLE_PENDING_EXCEPTION();
1030 }
1031 }
1032 }
1033 HANDLE_INSTRUCTION_END();
1034
1035 HANDLE_INSTRUCTION_START(AGET_WIDE) {
1036 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1037 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +02001038 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001039 HANDLE_PENDING_EXCEPTION();
1040 } else {
1041 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1042 LongArray* array = a->AsLongArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001043 if (LIKELY(array->CheckIsValidIndex(index))) {
1044 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001045 ADVANCE(2);
1046 } else {
1047 HANDLE_PENDING_EXCEPTION();
1048 }
1049 }
1050 }
1051 HANDLE_INSTRUCTION_END();
1052
1053 HANDLE_INSTRUCTION_START(AGET_OBJECT) {
1054 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1055 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +02001056 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001057 HANDLE_PENDING_EXCEPTION();
1058 } else {
1059 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1060 ObjectArray<Object>* array = a->AsObjectArray<Object>();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001061 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001062 shadow_frame.SetVRegReference(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001063 ADVANCE(2);
1064 } else {
1065 HANDLE_PENDING_EXCEPTION();
1066 }
1067 }
1068 }
1069 HANDLE_INSTRUCTION_END();
1070
1071 HANDLE_INSTRUCTION_START(APUT_BOOLEAN) {
1072 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1073 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +02001074 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001075 HANDLE_PENDING_EXCEPTION();
1076 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001077 uint8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001078 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1079 BooleanArray* array = a->AsBooleanArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001080 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001081 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001082 ADVANCE(2);
1083 } else {
1084 HANDLE_PENDING_EXCEPTION();
1085 }
1086 }
1087 }
1088 HANDLE_INSTRUCTION_END();
1089
1090 HANDLE_INSTRUCTION_START(APUT_BYTE) {
1091 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1092 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +02001093 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001094 HANDLE_PENDING_EXCEPTION();
1095 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001096 int8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001097 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1098 ByteArray* array = a->AsByteArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001099 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001100 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001101 ADVANCE(2);
1102 } else {
1103 HANDLE_PENDING_EXCEPTION();
1104 }
1105 }
1106 }
1107 HANDLE_INSTRUCTION_END();
1108
1109 HANDLE_INSTRUCTION_START(APUT_CHAR) {
1110 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1111 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +02001112 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001113 HANDLE_PENDING_EXCEPTION();
1114 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001115 uint16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001116 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1117 CharArray* array = a->AsCharArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001118 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001119 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001120 ADVANCE(2);
1121 } else {
1122 HANDLE_PENDING_EXCEPTION();
1123 }
1124 }
1125 }
1126 HANDLE_INSTRUCTION_END();
1127
1128 HANDLE_INSTRUCTION_START(APUT_SHORT) {
1129 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1130 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +02001131 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001132 HANDLE_PENDING_EXCEPTION();
1133 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001134 int16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001135 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1136 ShortArray* array = a->AsShortArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001137 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001138 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001139 ADVANCE(2);
1140 } else {
1141 HANDLE_PENDING_EXCEPTION();
1142 }
1143 }
1144 }
1145 HANDLE_INSTRUCTION_END();
1146
1147 HANDLE_INSTRUCTION_START(APUT) {
1148 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1149 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +02001150 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001151 HANDLE_PENDING_EXCEPTION();
1152 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001153 int32_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001154 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1155 IntArray* array = a->AsIntArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001156 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001157 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001158 ADVANCE(2);
1159 } else {
1160 HANDLE_PENDING_EXCEPTION();
1161 }
1162 }
1163 }
1164 HANDLE_INSTRUCTION_END();
1165
1166 HANDLE_INSTRUCTION_START(APUT_WIDE) {
1167 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1168 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +02001169 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001170 HANDLE_PENDING_EXCEPTION();
1171 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001172 int64_t val = shadow_frame.GetVRegLong(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001173 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1174 LongArray* array = a->AsLongArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001175 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001176 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001177 ADVANCE(2);
1178 } else {
1179 HANDLE_PENDING_EXCEPTION();
1180 }
1181 }
1182 }
1183 HANDLE_INSTRUCTION_END();
1184
1185 HANDLE_INSTRUCTION_START(APUT_OBJECT) {
1186 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1187 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +02001188 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001189 HANDLE_PENDING_EXCEPTION();
1190 } else {
1191 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001192 Object* val = shadow_frame.GetVRegReference(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001193 ObjectArray<Object>* array = a->AsObjectArray<Object>();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001194 if (LIKELY(array->CheckIsValidIndex(index) && array->CheckAssignable(val))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001195 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001196 ADVANCE(2);
1197 } else {
1198 HANDLE_PENDING_EXCEPTION();
1199 }
1200 }
1201 }
1202 HANDLE_INSTRUCTION_END();
1203
1204 HANDLE_INSTRUCTION_START(IGET_BOOLEAN) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001205 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimBoolean, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001206 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1207 }
1208 HANDLE_INSTRUCTION_END();
1209
1210 HANDLE_INSTRUCTION_START(IGET_BYTE) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001211 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimByte, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001212 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1213 }
1214 HANDLE_INSTRUCTION_END();
1215
1216 HANDLE_INSTRUCTION_START(IGET_CHAR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001217 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimChar, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001218 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1219 }
1220 HANDLE_INSTRUCTION_END();
1221
1222 HANDLE_INSTRUCTION_START(IGET_SHORT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001223 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimShort, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001224 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1225 }
1226 HANDLE_INSTRUCTION_END();
1227
1228 HANDLE_INSTRUCTION_START(IGET) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001229 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimInt, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001230 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1231 }
1232 HANDLE_INSTRUCTION_END();
1233
1234 HANDLE_INSTRUCTION_START(IGET_WIDE) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001235 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimLong, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001236 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1237 }
1238 HANDLE_INSTRUCTION_END();
1239
1240 HANDLE_INSTRUCTION_START(IGET_OBJECT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001241 bool success = DoFieldGet<InstanceObjectRead, Primitive::kPrimNot, do_access_check>(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_QUICK) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001247 bool success = DoIGetQuick<Primitive::kPrimInt>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001248 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1249 }
1250 HANDLE_INSTRUCTION_END();
1251
1252 HANDLE_INSTRUCTION_START(IGET_WIDE_QUICK) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001253 bool success = DoIGetQuick<Primitive::kPrimLong>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001254 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1255 }
1256 HANDLE_INSTRUCTION_END();
1257
1258 HANDLE_INSTRUCTION_START(IGET_OBJECT_QUICK) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001259 bool success = DoIGetQuick<Primitive::kPrimNot>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001260 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1261 }
1262 HANDLE_INSTRUCTION_END();
1263
1264 HANDLE_INSTRUCTION_START(SGET_BOOLEAN) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001265 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimBoolean, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001266 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1267 }
1268 HANDLE_INSTRUCTION_END();
1269
1270 HANDLE_INSTRUCTION_START(SGET_BYTE) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001271 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimByte, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001272 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1273 }
1274 HANDLE_INSTRUCTION_END();
1275
1276 HANDLE_INSTRUCTION_START(SGET_CHAR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001277 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimChar, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001278 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1279 }
1280 HANDLE_INSTRUCTION_END();
1281
1282 HANDLE_INSTRUCTION_START(SGET_SHORT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001283 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimShort, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001284 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1285 }
1286 HANDLE_INSTRUCTION_END();
1287
1288 HANDLE_INSTRUCTION_START(SGET) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001289 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimInt, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001290 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1291 }
1292 HANDLE_INSTRUCTION_END();
1293
1294 HANDLE_INSTRUCTION_START(SGET_WIDE) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001295 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimLong, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001296 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1297 }
1298 HANDLE_INSTRUCTION_END();
1299
1300 HANDLE_INSTRUCTION_START(SGET_OBJECT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001301 bool success = DoFieldGet<StaticObjectRead, Primitive::kPrimNot, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001302 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1303 }
1304 HANDLE_INSTRUCTION_END();
1305
1306 HANDLE_INSTRUCTION_START(IPUT_BOOLEAN) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001307 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimBoolean, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001308 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1309 }
1310 HANDLE_INSTRUCTION_END();
1311
1312 HANDLE_INSTRUCTION_START(IPUT_BYTE) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001313 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimByte, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001314 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1315 }
1316 HANDLE_INSTRUCTION_END();
1317
1318 HANDLE_INSTRUCTION_START(IPUT_CHAR) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001319 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimChar, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001320 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1321 }
1322 HANDLE_INSTRUCTION_END();
1323
1324 HANDLE_INSTRUCTION_START(IPUT_SHORT) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001325 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimShort, do_access_check, transaction_active>(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(IPUT) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001331 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimInt, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001332 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1333 }
1334 HANDLE_INSTRUCTION_END();
1335
1336 HANDLE_INSTRUCTION_START(IPUT_WIDE) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001337 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimLong, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001338 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1339 }
1340 HANDLE_INSTRUCTION_END();
1341
1342 HANDLE_INSTRUCTION_START(IPUT_OBJECT) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001343 bool success = DoFieldPut<InstanceObjectWrite, Primitive::kPrimNot, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001344 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1345 }
1346 HANDLE_INSTRUCTION_END();
1347
1348 HANDLE_INSTRUCTION_START(IPUT_QUICK) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001349 bool success = DoIPutQuick<Primitive::kPrimInt, transaction_active>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001350 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1351 }
1352 HANDLE_INSTRUCTION_END();
1353
Fred Shih37f05ef2014-07-16 18:38:08 -07001354 HANDLE_INSTRUCTION_START(IPUT_BOOLEAN_QUICK) {
1355 bool success = DoIPutQuick<Primitive::kPrimBoolean, transaction_active>(shadow_frame, inst, inst_data);
1356 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1357 }
1358 HANDLE_INSTRUCTION_END();
1359
1360 HANDLE_INSTRUCTION_START(IPUT_BYTE_QUICK) {
1361 bool success = DoIPutQuick<Primitive::kPrimByte, transaction_active>(shadow_frame, inst, inst_data);
1362 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1363 }
1364 HANDLE_INSTRUCTION_END();
1365
1366 HANDLE_INSTRUCTION_START(IPUT_CHAR_QUICK) {
1367 bool success = DoIPutQuick<Primitive::kPrimChar, transaction_active>(shadow_frame, inst, inst_data);
1368 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1369 }
1370 HANDLE_INSTRUCTION_END();
1371
1372 HANDLE_INSTRUCTION_START(IPUT_SHORT_QUICK) {
1373 bool success = DoIPutQuick<Primitive::kPrimShort, transaction_active>(shadow_frame, inst, inst_data);
1374 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1375 }
1376 HANDLE_INSTRUCTION_END();
1377
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001378 HANDLE_INSTRUCTION_START(IPUT_WIDE_QUICK) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001379 bool success = DoIPutQuick<Primitive::kPrimLong, transaction_active>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001380 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1381 }
1382 HANDLE_INSTRUCTION_END();
1383
1384 HANDLE_INSTRUCTION_START(IPUT_OBJECT_QUICK) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001385 bool success = DoIPutQuick<Primitive::kPrimNot, transaction_active>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001386 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1387 }
1388 HANDLE_INSTRUCTION_END();
1389
1390 HANDLE_INSTRUCTION_START(SPUT_BOOLEAN) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001391 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimBoolean, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001392 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1393 }
1394 HANDLE_INSTRUCTION_END();
1395
1396 HANDLE_INSTRUCTION_START(SPUT_BYTE) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001397 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimByte, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001398 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1399 }
1400 HANDLE_INSTRUCTION_END();
1401
1402 HANDLE_INSTRUCTION_START(SPUT_CHAR) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001403 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimChar, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001404 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1405 }
1406 HANDLE_INSTRUCTION_END();
1407
1408 HANDLE_INSTRUCTION_START(SPUT_SHORT) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001409 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimShort, do_access_check, 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(SPUT) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001415 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimInt, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001416 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1417 }
1418 HANDLE_INSTRUCTION_END();
1419
1420 HANDLE_INSTRUCTION_START(SPUT_WIDE) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001421 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimLong, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001422 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1423 }
1424 HANDLE_INSTRUCTION_END();
1425
1426 HANDLE_INSTRUCTION_START(SPUT_OBJECT) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001427 bool success = DoFieldPut<StaticObjectWrite, Primitive::kPrimNot, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001428 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1429 }
1430 HANDLE_INSTRUCTION_END();
1431
1432 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL) {
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001433 bool success = DoInvoke<kVirtual, false, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001434 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001435 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1436 }
1437 HANDLE_INSTRUCTION_END();
1438
1439 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_RANGE) {
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001440 bool success = DoInvoke<kVirtual, true, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001441 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001442 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1443 }
1444 HANDLE_INSTRUCTION_END();
1445
1446 HANDLE_INSTRUCTION_START(INVOKE_SUPER) {
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001447 bool success = DoInvoke<kSuper, false, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001448 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001449 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1450 }
1451 HANDLE_INSTRUCTION_END();
1452
1453 HANDLE_INSTRUCTION_START(INVOKE_SUPER_RANGE) {
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001454 bool success = DoInvoke<kSuper, true, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001455 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001456 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1457 }
1458 HANDLE_INSTRUCTION_END();
1459
1460 HANDLE_INSTRUCTION_START(INVOKE_DIRECT) {
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001461 bool success = DoInvoke<kDirect, false, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001462 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001463 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1464 }
1465 HANDLE_INSTRUCTION_END();
1466
1467 HANDLE_INSTRUCTION_START(INVOKE_DIRECT_RANGE) {
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001468 bool success = DoInvoke<kDirect, true, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001469 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001470 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1471 }
1472 HANDLE_INSTRUCTION_END();
1473
1474 HANDLE_INSTRUCTION_START(INVOKE_INTERFACE) {
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001475 bool success = DoInvoke<kInterface, false, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001476 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001477 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1478 }
1479 HANDLE_INSTRUCTION_END();
1480
1481 HANDLE_INSTRUCTION_START(INVOKE_INTERFACE_RANGE) {
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001482 bool success = DoInvoke<kInterface, true, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001483 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001484 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1485 }
1486 HANDLE_INSTRUCTION_END();
1487
1488 HANDLE_INSTRUCTION_START(INVOKE_STATIC) {
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001489 bool success = DoInvoke<kStatic, false, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001490 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001491 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1492 }
1493 HANDLE_INSTRUCTION_END();
1494
1495 HANDLE_INSTRUCTION_START(INVOKE_STATIC_RANGE) {
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001496 bool success = DoInvoke<kStatic, true, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001497 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001498 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1499 }
1500 HANDLE_INSTRUCTION_END();
1501
1502 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_QUICK) {
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001503 bool success = DoInvokeVirtualQuick<false>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001504 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001505 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1506 }
1507 HANDLE_INSTRUCTION_END();
1508
1509 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_RANGE_QUICK) {
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001510 bool success = DoInvokeVirtualQuick<true>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001511 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001512 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1513 }
1514 HANDLE_INSTRUCTION_END();
1515
1516 HANDLE_INSTRUCTION_START(NEG_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001517 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), -shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001518 ADVANCE(1);
1519 HANDLE_INSTRUCTION_END();
1520
1521 HANDLE_INSTRUCTION_START(NOT_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001522 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), ~shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001523 ADVANCE(1);
1524 HANDLE_INSTRUCTION_END();
1525
1526 HANDLE_INSTRUCTION_START(NEG_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001527 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), -shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001528 ADVANCE(1);
1529 HANDLE_INSTRUCTION_END();
1530
1531 HANDLE_INSTRUCTION_START(NOT_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001532 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), ~shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001533 ADVANCE(1);
1534 HANDLE_INSTRUCTION_END();
1535
1536 HANDLE_INSTRUCTION_START(NEG_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001537 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data), -shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001538 ADVANCE(1);
1539 HANDLE_INSTRUCTION_END();
1540
1541 HANDLE_INSTRUCTION_START(NEG_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001542 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data), -shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001543 ADVANCE(1);
1544 HANDLE_INSTRUCTION_END();
1545
1546 HANDLE_INSTRUCTION_START(INT_TO_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001547 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001548 ADVANCE(1);
1549 HANDLE_INSTRUCTION_END();
1550
1551 HANDLE_INSTRUCTION_START(INT_TO_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001552 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data), shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001553 ADVANCE(1);
1554 HANDLE_INSTRUCTION_END();
1555
1556 HANDLE_INSTRUCTION_START(INT_TO_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001557 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data), shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001558 ADVANCE(1);
1559 HANDLE_INSTRUCTION_END();
1560
1561 HANDLE_INSTRUCTION_START(LONG_TO_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001562 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001563 ADVANCE(1);
1564 HANDLE_INSTRUCTION_END();
1565
1566 HANDLE_INSTRUCTION_START(LONG_TO_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001567 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data), shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001568 ADVANCE(1);
1569 HANDLE_INSTRUCTION_END();
1570
1571 HANDLE_INSTRUCTION_START(LONG_TO_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001572 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data), shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001573 ADVANCE(1);
1574 HANDLE_INSTRUCTION_END();
1575
1576 HANDLE_INSTRUCTION_START(FLOAT_TO_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001577 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001578 int32_t result = art_float_to_integral<int32_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001579 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001580 ADVANCE(1);
1581 }
1582 HANDLE_INSTRUCTION_END();
1583
1584 HANDLE_INSTRUCTION_START(FLOAT_TO_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001585 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001586 int64_t result = art_float_to_integral<int64_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001587 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001588 ADVANCE(1);
1589 }
1590 HANDLE_INSTRUCTION_END();
1591
1592 HANDLE_INSTRUCTION_START(FLOAT_TO_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001593 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data), shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001594 ADVANCE(1);
1595 HANDLE_INSTRUCTION_END();
1596
1597 HANDLE_INSTRUCTION_START(DOUBLE_TO_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001598 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001599 int32_t result = art_float_to_integral<int32_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001600 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001601 ADVANCE(1);
1602 }
1603 HANDLE_INSTRUCTION_END();
1604
1605 HANDLE_INSTRUCTION_START(DOUBLE_TO_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001606 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001607 int64_t result = art_float_to_integral<int64_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001608 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001609 ADVANCE(1);
1610 }
1611 HANDLE_INSTRUCTION_END();
1612
1613 HANDLE_INSTRUCTION_START(DOUBLE_TO_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001614 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data), shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001615 ADVANCE(1);
1616 HANDLE_INSTRUCTION_END();
1617
1618 HANDLE_INSTRUCTION_START(INT_TO_BYTE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001619 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1620 static_cast<int8_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001621 ADVANCE(1);
1622 HANDLE_INSTRUCTION_END();
1623
1624 HANDLE_INSTRUCTION_START(INT_TO_CHAR)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001625 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1626 static_cast<uint16_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001627 ADVANCE(1);
1628 HANDLE_INSTRUCTION_END();
1629
1630 HANDLE_INSTRUCTION_START(INT_TO_SHORT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001631 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1632 static_cast<int16_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001633 ADVANCE(1);
1634 HANDLE_INSTRUCTION_END();
1635
1636 HANDLE_INSTRUCTION_START(ADD_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001637 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001638 SafeAdd(shadow_frame.GetVReg(inst->VRegB_23x()),
1639 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001640 ADVANCE(2);
1641 HANDLE_INSTRUCTION_END();
1642
1643 HANDLE_INSTRUCTION_START(SUB_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001644 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001645 SafeSub(shadow_frame.GetVReg(inst->VRegB_23x()),
1646 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001647 ADVANCE(2);
1648 HANDLE_INSTRUCTION_END();
1649
1650 HANDLE_INSTRUCTION_START(MUL_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001651 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001652 SafeMul(shadow_frame.GetVReg(inst->VRegB_23x()),
1653 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001654 ADVANCE(2);
1655 HANDLE_INSTRUCTION_END();
1656
1657 HANDLE_INSTRUCTION_START(DIV_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001658 bool success = DoIntDivide(shadow_frame, inst->VRegA_23x(inst_data),
1659 shadow_frame.GetVReg(inst->VRegB_23x()),
1660 shadow_frame.GetVReg(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001661 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1662 }
1663 HANDLE_INSTRUCTION_END();
1664
1665 HANDLE_INSTRUCTION_START(REM_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001666 bool success = DoIntRemainder(shadow_frame, inst->VRegA_23x(inst_data),
1667 shadow_frame.GetVReg(inst->VRegB_23x()),
1668 shadow_frame.GetVReg(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001669 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1670 }
1671 HANDLE_INSTRUCTION_END();
1672
1673 HANDLE_INSTRUCTION_START(SHL_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001674 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001675 shadow_frame.GetVReg(inst->VRegB_23x()) <<
1676 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1677 ADVANCE(2);
1678 HANDLE_INSTRUCTION_END();
1679
1680 HANDLE_INSTRUCTION_START(SHR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001681 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001682 shadow_frame.GetVReg(inst->VRegB_23x()) >>
1683 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1684 ADVANCE(2);
1685 HANDLE_INSTRUCTION_END();
1686
1687 HANDLE_INSTRUCTION_START(USHR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001688 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001689 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_23x())) >>
1690 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1691 ADVANCE(2);
1692 HANDLE_INSTRUCTION_END();
1693
1694 HANDLE_INSTRUCTION_START(AND_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001695 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001696 shadow_frame.GetVReg(inst->VRegB_23x()) &
1697 shadow_frame.GetVReg(inst->VRegC_23x()));
1698 ADVANCE(2);
1699 HANDLE_INSTRUCTION_END();
1700
1701 HANDLE_INSTRUCTION_START(OR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001702 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001703 shadow_frame.GetVReg(inst->VRegB_23x()) |
1704 shadow_frame.GetVReg(inst->VRegC_23x()));
1705 ADVANCE(2);
1706 HANDLE_INSTRUCTION_END();
1707
1708 HANDLE_INSTRUCTION_START(XOR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001709 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001710 shadow_frame.GetVReg(inst->VRegB_23x()) ^
1711 shadow_frame.GetVReg(inst->VRegC_23x()));
1712 ADVANCE(2);
1713 HANDLE_INSTRUCTION_END();
1714
1715 HANDLE_INSTRUCTION_START(ADD_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001716 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001717 SafeAdd(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1718 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001719 ADVANCE(2);
1720 HANDLE_INSTRUCTION_END();
1721
1722 HANDLE_INSTRUCTION_START(SUB_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001723 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001724 SafeSub(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1725 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001726 ADVANCE(2);
1727 HANDLE_INSTRUCTION_END();
1728
1729 HANDLE_INSTRUCTION_START(MUL_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001730 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001731 SafeMul(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1732 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001733 ADVANCE(2);
1734 HANDLE_INSTRUCTION_END();
1735
1736 HANDLE_INSTRUCTION_START(DIV_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001737 bool success = DoLongDivide(shadow_frame, inst->VRegA_23x(inst_data),
1738 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1739 shadow_frame.GetVRegLong(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001740 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1741 }
1742 HANDLE_INSTRUCTION_END();
1743
1744 HANDLE_INSTRUCTION_START(REM_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001745 bool success = DoLongRemainder(shadow_frame, inst->VRegA_23x(inst_data),
1746 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1747 shadow_frame.GetVRegLong(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001748 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1749 }
1750 HANDLE_INSTRUCTION_END();
1751
1752 HANDLE_INSTRUCTION_START(AND_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001753 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001754 shadow_frame.GetVRegLong(inst->VRegB_23x()) &
1755 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1756 ADVANCE(2);
1757 HANDLE_INSTRUCTION_END();
1758
1759 HANDLE_INSTRUCTION_START(OR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001760 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001761 shadow_frame.GetVRegLong(inst->VRegB_23x()) |
1762 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1763 ADVANCE(2);
1764 HANDLE_INSTRUCTION_END();
1765
1766 HANDLE_INSTRUCTION_START(XOR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001767 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001768 shadow_frame.GetVRegLong(inst->VRegB_23x()) ^
1769 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1770 ADVANCE(2);
1771 HANDLE_INSTRUCTION_END();
1772
1773 HANDLE_INSTRUCTION_START(SHL_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001774 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001775 shadow_frame.GetVRegLong(inst->VRegB_23x()) <<
1776 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1777 ADVANCE(2);
1778 HANDLE_INSTRUCTION_END();
1779
1780 HANDLE_INSTRUCTION_START(SHR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001781 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001782 shadow_frame.GetVRegLong(inst->VRegB_23x()) >>
1783 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1784 ADVANCE(2);
1785 HANDLE_INSTRUCTION_END();
1786
1787 HANDLE_INSTRUCTION_START(USHR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001788 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001789 static_cast<uint64_t>(shadow_frame.GetVRegLong(inst->VRegB_23x())) >>
1790 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1791 ADVANCE(2);
1792 HANDLE_INSTRUCTION_END();
1793
1794 HANDLE_INSTRUCTION_START(ADD_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001795 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001796 shadow_frame.GetVRegFloat(inst->VRegB_23x()) +
1797 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1798 ADVANCE(2);
1799 HANDLE_INSTRUCTION_END();
1800
1801 HANDLE_INSTRUCTION_START(SUB_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001802 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001803 shadow_frame.GetVRegFloat(inst->VRegB_23x()) -
1804 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1805 ADVANCE(2);
1806 HANDLE_INSTRUCTION_END();
1807
1808 HANDLE_INSTRUCTION_START(MUL_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001809 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001810 shadow_frame.GetVRegFloat(inst->VRegB_23x()) *
1811 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1812 ADVANCE(2);
1813 HANDLE_INSTRUCTION_END();
1814
1815 HANDLE_INSTRUCTION_START(DIV_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001816 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001817 shadow_frame.GetVRegFloat(inst->VRegB_23x()) /
1818 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1819 ADVANCE(2);
1820 HANDLE_INSTRUCTION_END();
1821
1822 HANDLE_INSTRUCTION_START(REM_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001823 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001824 fmodf(shadow_frame.GetVRegFloat(inst->VRegB_23x()),
1825 shadow_frame.GetVRegFloat(inst->VRegC_23x())));
1826 ADVANCE(2);
1827 HANDLE_INSTRUCTION_END();
1828
1829 HANDLE_INSTRUCTION_START(ADD_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001830 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001831 shadow_frame.GetVRegDouble(inst->VRegB_23x()) +
1832 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1833 ADVANCE(2);
1834 HANDLE_INSTRUCTION_END();
1835
1836 HANDLE_INSTRUCTION_START(SUB_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001837 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001838 shadow_frame.GetVRegDouble(inst->VRegB_23x()) -
1839 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1840 ADVANCE(2);
1841 HANDLE_INSTRUCTION_END();
1842
1843 HANDLE_INSTRUCTION_START(MUL_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001844 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001845 shadow_frame.GetVRegDouble(inst->VRegB_23x()) *
1846 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1847 ADVANCE(2);
1848 HANDLE_INSTRUCTION_END();
1849
1850 HANDLE_INSTRUCTION_START(DIV_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001851 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001852 shadow_frame.GetVRegDouble(inst->VRegB_23x()) /
1853 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1854 ADVANCE(2);
1855 HANDLE_INSTRUCTION_END();
1856
1857 HANDLE_INSTRUCTION_START(REM_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001858 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001859 fmod(shadow_frame.GetVRegDouble(inst->VRegB_23x()),
1860 shadow_frame.GetVRegDouble(inst->VRegC_23x())));
1861 ADVANCE(2);
1862 HANDLE_INSTRUCTION_END();
1863
1864 HANDLE_INSTRUCTION_START(ADD_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001865 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001866 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07001867 SafeAdd(shadow_frame.GetVReg(vregA),
1868 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001869 ADVANCE(1);
1870 }
1871 HANDLE_INSTRUCTION_END();
1872
1873 HANDLE_INSTRUCTION_START(SUB_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001874 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001875 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07001876 SafeSub(shadow_frame.GetVReg(vregA),
1877 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001878 ADVANCE(1);
1879 }
1880 HANDLE_INSTRUCTION_END();
1881
1882 HANDLE_INSTRUCTION_START(MUL_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001883 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001884 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07001885 SafeMul(shadow_frame.GetVReg(vregA),
1886 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001887 ADVANCE(1);
1888 }
1889 HANDLE_INSTRUCTION_END();
1890
1891 HANDLE_INSTRUCTION_START(DIV_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001892 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001893 bool success = DoIntDivide(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001894 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001895 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
1896 }
1897 HANDLE_INSTRUCTION_END();
1898
1899 HANDLE_INSTRUCTION_START(REM_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001900 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001901 bool success = DoIntRemainder(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001902 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001903 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
1904 }
1905 HANDLE_INSTRUCTION_END();
1906
1907 HANDLE_INSTRUCTION_START(SHL_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001908 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001909 shadow_frame.SetVReg(vregA,
1910 shadow_frame.GetVReg(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001911 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001912 ADVANCE(1);
1913 }
1914 HANDLE_INSTRUCTION_END();
1915
1916 HANDLE_INSTRUCTION_START(SHR_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001917 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001918 shadow_frame.SetVReg(vregA,
1919 shadow_frame.GetVReg(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001920 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001921 ADVANCE(1);
1922 }
1923 HANDLE_INSTRUCTION_END();
1924
1925 HANDLE_INSTRUCTION_START(USHR_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001926 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001927 shadow_frame.SetVReg(vregA,
1928 static_cast<uint32_t>(shadow_frame.GetVReg(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001929 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001930 ADVANCE(1);
1931 }
1932 HANDLE_INSTRUCTION_END();
1933
1934 HANDLE_INSTRUCTION_START(AND_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001935 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001936 shadow_frame.SetVReg(vregA,
1937 shadow_frame.GetVReg(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001938 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001939 ADVANCE(1);
1940 }
1941 HANDLE_INSTRUCTION_END();
1942
1943 HANDLE_INSTRUCTION_START(OR_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001944 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001945 shadow_frame.SetVReg(vregA,
1946 shadow_frame.GetVReg(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001947 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001948 ADVANCE(1);
1949 }
1950 HANDLE_INSTRUCTION_END();
1951
1952 HANDLE_INSTRUCTION_START(XOR_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001953 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001954 shadow_frame.SetVReg(vregA,
1955 shadow_frame.GetVReg(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001956 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001957 ADVANCE(1);
1958 }
1959 HANDLE_INSTRUCTION_END();
1960
1961 HANDLE_INSTRUCTION_START(ADD_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001962 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001963 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07001964 SafeAdd(shadow_frame.GetVRegLong(vregA),
1965 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001966 ADVANCE(1);
1967 }
1968 HANDLE_INSTRUCTION_END();
1969
1970 HANDLE_INSTRUCTION_START(SUB_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001971 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001972 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07001973 SafeSub(shadow_frame.GetVRegLong(vregA),
1974 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001975 ADVANCE(1);
1976 }
1977 HANDLE_INSTRUCTION_END();
1978
1979 HANDLE_INSTRUCTION_START(MUL_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001980 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001981 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07001982 SafeMul(shadow_frame.GetVRegLong(vregA),
1983 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001984 ADVANCE(1);
1985 }
1986 HANDLE_INSTRUCTION_END();
1987
1988 HANDLE_INSTRUCTION_START(DIV_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001989 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001990 bool success = DoLongDivide(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001991 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001992 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
1993 }
1994 HANDLE_INSTRUCTION_END();
1995
1996 HANDLE_INSTRUCTION_START(REM_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001997 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001998 bool success = DoLongRemainder(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001999 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002000 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2001 }
2002 HANDLE_INSTRUCTION_END();
2003
2004 HANDLE_INSTRUCTION_START(AND_LONG_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 shadow_frame.SetVRegLong(vregA,
2007 shadow_frame.GetVRegLong(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002008 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002009 ADVANCE(1);
2010 }
2011 HANDLE_INSTRUCTION_END();
2012
2013 HANDLE_INSTRUCTION_START(OR_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002014 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002015 shadow_frame.SetVRegLong(vregA,
2016 shadow_frame.GetVRegLong(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002017 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002018 ADVANCE(1);
2019 }
2020 HANDLE_INSTRUCTION_END();
2021
2022 HANDLE_INSTRUCTION_START(XOR_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002023 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002024 shadow_frame.SetVRegLong(vregA,
2025 shadow_frame.GetVRegLong(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002026 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002027 ADVANCE(1);
2028 }
2029 HANDLE_INSTRUCTION_END();
2030
2031 HANDLE_INSTRUCTION_START(SHL_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002032 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002033 shadow_frame.SetVRegLong(vregA,
2034 shadow_frame.GetVRegLong(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002035 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002036 ADVANCE(1);
2037 }
2038 HANDLE_INSTRUCTION_END();
2039
2040 HANDLE_INSTRUCTION_START(SHR_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002041 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002042 shadow_frame.SetVRegLong(vregA,
2043 shadow_frame.GetVRegLong(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002044 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002045 ADVANCE(1);
2046 }
2047 HANDLE_INSTRUCTION_END();
2048
2049 HANDLE_INSTRUCTION_START(USHR_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002050 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002051 shadow_frame.SetVRegLong(vregA,
2052 static_cast<uint64_t>(shadow_frame.GetVRegLong(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002053 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002054 ADVANCE(1);
2055 }
2056 HANDLE_INSTRUCTION_END();
2057
2058 HANDLE_INSTRUCTION_START(ADD_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002059 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002060 shadow_frame.SetVRegFloat(vregA,
2061 shadow_frame.GetVRegFloat(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002062 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002063 ADVANCE(1);
2064 }
2065 HANDLE_INSTRUCTION_END();
2066
2067 HANDLE_INSTRUCTION_START(SUB_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002068 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002069 shadow_frame.SetVRegFloat(vregA,
2070 shadow_frame.GetVRegFloat(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002071 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002072 ADVANCE(1);
2073 }
2074 HANDLE_INSTRUCTION_END();
2075
2076 HANDLE_INSTRUCTION_START(MUL_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002077 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002078 shadow_frame.SetVRegFloat(vregA,
2079 shadow_frame.GetVRegFloat(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002080 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002081 ADVANCE(1);
2082 }
2083 HANDLE_INSTRUCTION_END();
2084
2085 HANDLE_INSTRUCTION_START(DIV_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002086 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002087 shadow_frame.SetVRegFloat(vregA,
2088 shadow_frame.GetVRegFloat(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002089 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002090 ADVANCE(1);
2091 }
2092 HANDLE_INSTRUCTION_END();
2093
2094 HANDLE_INSTRUCTION_START(REM_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002095 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002096 shadow_frame.SetVRegFloat(vregA,
2097 fmodf(shadow_frame.GetVRegFloat(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002098 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002099 ADVANCE(1);
2100 }
2101 HANDLE_INSTRUCTION_END();
2102
2103 HANDLE_INSTRUCTION_START(ADD_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002104 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002105 shadow_frame.SetVRegDouble(vregA,
2106 shadow_frame.GetVRegDouble(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002107 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002108 ADVANCE(1);
2109 }
2110 HANDLE_INSTRUCTION_END();
2111
2112 HANDLE_INSTRUCTION_START(SUB_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002113 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002114 shadow_frame.SetVRegDouble(vregA,
2115 shadow_frame.GetVRegDouble(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002116 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002117 ADVANCE(1);
2118 }
2119 HANDLE_INSTRUCTION_END();
2120
2121 HANDLE_INSTRUCTION_START(MUL_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002122 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002123 shadow_frame.SetVRegDouble(vregA,
2124 shadow_frame.GetVRegDouble(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002125 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002126 ADVANCE(1);
2127 }
2128 HANDLE_INSTRUCTION_END();
2129
2130 HANDLE_INSTRUCTION_START(DIV_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002131 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002132 shadow_frame.SetVRegDouble(vregA,
2133 shadow_frame.GetVRegDouble(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002134 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002135 ADVANCE(1);
2136 }
2137 HANDLE_INSTRUCTION_END();
2138
2139 HANDLE_INSTRUCTION_START(REM_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002140 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002141 shadow_frame.SetVRegDouble(vregA,
2142 fmod(shadow_frame.GetVRegDouble(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002143 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002144 ADVANCE(1);
2145 }
2146 HANDLE_INSTRUCTION_END();
2147
2148 HANDLE_INSTRUCTION_START(ADD_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002149 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002150 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2151 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002152 ADVANCE(2);
2153 HANDLE_INSTRUCTION_END();
2154
2155 HANDLE_INSTRUCTION_START(RSUB_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002156 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002157 SafeSub(inst->VRegC_22s(),
2158 shadow_frame.GetVReg(inst->VRegB_22s(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002159 ADVANCE(2);
2160 HANDLE_INSTRUCTION_END();
2161
2162 HANDLE_INSTRUCTION_START(MUL_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002163 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002164 SafeMul(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2165 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002166 ADVANCE(2);
2167 HANDLE_INSTRUCTION_END();
2168
2169 HANDLE_INSTRUCTION_START(DIV_INT_LIT16) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002170 bool success = DoIntDivide(shadow_frame, inst->VRegA_22s(inst_data),
2171 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)), inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002172 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2173 }
2174 HANDLE_INSTRUCTION_END();
2175
2176 HANDLE_INSTRUCTION_START(REM_INT_LIT16) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002177 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22s(inst_data),
2178 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)), inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002179 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2180 }
2181 HANDLE_INSTRUCTION_END();
2182
2183 HANDLE_INSTRUCTION_START(AND_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002184 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2185 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) &
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002186 inst->VRegC_22s());
2187 ADVANCE(2);
2188 HANDLE_INSTRUCTION_END();
2189
2190 HANDLE_INSTRUCTION_START(OR_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002191 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2192 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) |
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002193 inst->VRegC_22s());
2194 ADVANCE(2);
2195 HANDLE_INSTRUCTION_END();
2196
2197 HANDLE_INSTRUCTION_START(XOR_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002198 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2199 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) ^
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002200 inst->VRegC_22s());
2201 ADVANCE(2);
2202 HANDLE_INSTRUCTION_END();
2203
2204 HANDLE_INSTRUCTION_START(ADD_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002205 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002206 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22b()),
2207 inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002208 ADVANCE(2);
2209 HANDLE_INSTRUCTION_END();
2210
2211 HANDLE_INSTRUCTION_START(RSUB_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002212 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002213 SafeSub(inst->VRegC_22b(),
2214 shadow_frame.GetVReg(inst->VRegB_22b())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002215 ADVANCE(2);
2216 HANDLE_INSTRUCTION_END();
2217
2218 HANDLE_INSTRUCTION_START(MUL_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002219 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002220 SafeMul(shadow_frame.GetVReg(inst->VRegB_22b()),
2221 inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002222 ADVANCE(2);
2223 HANDLE_INSTRUCTION_END();
2224
2225 HANDLE_INSTRUCTION_START(DIV_INT_LIT8) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002226 bool success = DoIntDivide(shadow_frame, inst->VRegA_22b(inst_data),
2227 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002228 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2229 }
2230 HANDLE_INSTRUCTION_END();
2231
2232 HANDLE_INSTRUCTION_START(REM_INT_LIT8) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002233 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22b(inst_data),
2234 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002235 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2236 }
2237 HANDLE_INSTRUCTION_END();
2238
2239 HANDLE_INSTRUCTION_START(AND_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002240 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002241 shadow_frame.GetVReg(inst->VRegB_22b()) &
2242 inst->VRegC_22b());
2243 ADVANCE(2);
2244 HANDLE_INSTRUCTION_END();
2245
2246 HANDLE_INSTRUCTION_START(OR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002247 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002248 shadow_frame.GetVReg(inst->VRegB_22b()) |
2249 inst->VRegC_22b());
2250 ADVANCE(2);
2251 HANDLE_INSTRUCTION_END();
2252
2253 HANDLE_INSTRUCTION_START(XOR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002254 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002255 shadow_frame.GetVReg(inst->VRegB_22b()) ^
2256 inst->VRegC_22b());
2257 ADVANCE(2);
2258 HANDLE_INSTRUCTION_END();
2259
2260 HANDLE_INSTRUCTION_START(SHL_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002261 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002262 shadow_frame.GetVReg(inst->VRegB_22b()) <<
2263 (inst->VRegC_22b() & 0x1f));
2264 ADVANCE(2);
2265 HANDLE_INSTRUCTION_END();
2266
2267 HANDLE_INSTRUCTION_START(SHR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002268 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002269 shadow_frame.GetVReg(inst->VRegB_22b()) >>
2270 (inst->VRegC_22b() & 0x1f));
2271 ADVANCE(2);
2272 HANDLE_INSTRUCTION_END();
2273
2274 HANDLE_INSTRUCTION_START(USHR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002275 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002276 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_22b())) >>
2277 (inst->VRegC_22b() & 0x1f));
2278 ADVANCE(2);
2279 HANDLE_INSTRUCTION_END();
2280
2281 HANDLE_INSTRUCTION_START(UNUSED_3E)
2282 UnexpectedOpcode(inst, mh);
2283 HANDLE_INSTRUCTION_END();
2284
2285 HANDLE_INSTRUCTION_START(UNUSED_3F)
2286 UnexpectedOpcode(inst, mh);
2287 HANDLE_INSTRUCTION_END();
2288
2289 HANDLE_INSTRUCTION_START(UNUSED_40)
2290 UnexpectedOpcode(inst, mh);
2291 HANDLE_INSTRUCTION_END();
2292
2293 HANDLE_INSTRUCTION_START(UNUSED_41)
2294 UnexpectedOpcode(inst, mh);
2295 HANDLE_INSTRUCTION_END();
2296
2297 HANDLE_INSTRUCTION_START(UNUSED_42)
2298 UnexpectedOpcode(inst, mh);
2299 HANDLE_INSTRUCTION_END();
2300
2301 HANDLE_INSTRUCTION_START(UNUSED_43)
2302 UnexpectedOpcode(inst, mh);
2303 HANDLE_INSTRUCTION_END();
2304
2305 HANDLE_INSTRUCTION_START(UNUSED_79)
2306 UnexpectedOpcode(inst, mh);
2307 HANDLE_INSTRUCTION_END();
2308
2309 HANDLE_INSTRUCTION_START(UNUSED_7A)
2310 UnexpectedOpcode(inst, mh);
2311 HANDLE_INSTRUCTION_END();
2312
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002313 HANDLE_INSTRUCTION_START(UNUSED_EF)
2314 UnexpectedOpcode(inst, mh);
2315 HANDLE_INSTRUCTION_END();
2316
2317 HANDLE_INSTRUCTION_START(UNUSED_F0)
2318 UnexpectedOpcode(inst, mh);
2319 HANDLE_INSTRUCTION_END();
2320
2321 HANDLE_INSTRUCTION_START(UNUSED_F1)
2322 UnexpectedOpcode(inst, mh);
2323 HANDLE_INSTRUCTION_END();
2324
2325 HANDLE_INSTRUCTION_START(UNUSED_F2)
2326 UnexpectedOpcode(inst, mh);
2327 HANDLE_INSTRUCTION_END();
2328
2329 HANDLE_INSTRUCTION_START(UNUSED_F3)
2330 UnexpectedOpcode(inst, mh);
2331 HANDLE_INSTRUCTION_END();
2332
2333 HANDLE_INSTRUCTION_START(UNUSED_F4)
2334 UnexpectedOpcode(inst, mh);
2335 HANDLE_INSTRUCTION_END();
2336
2337 HANDLE_INSTRUCTION_START(UNUSED_F5)
2338 UnexpectedOpcode(inst, mh);
2339 HANDLE_INSTRUCTION_END();
2340
2341 HANDLE_INSTRUCTION_START(UNUSED_F6)
2342 UnexpectedOpcode(inst, mh);
2343 HANDLE_INSTRUCTION_END();
2344
2345 HANDLE_INSTRUCTION_START(UNUSED_F7)
2346 UnexpectedOpcode(inst, mh);
2347 HANDLE_INSTRUCTION_END();
2348
2349 HANDLE_INSTRUCTION_START(UNUSED_F8)
2350 UnexpectedOpcode(inst, mh);
2351 HANDLE_INSTRUCTION_END();
2352
2353 HANDLE_INSTRUCTION_START(UNUSED_F9)
2354 UnexpectedOpcode(inst, mh);
2355 HANDLE_INSTRUCTION_END();
2356
2357 HANDLE_INSTRUCTION_START(UNUSED_FA)
2358 UnexpectedOpcode(inst, mh);
2359 HANDLE_INSTRUCTION_END();
2360
2361 HANDLE_INSTRUCTION_START(UNUSED_FB)
2362 UnexpectedOpcode(inst, mh);
2363 HANDLE_INSTRUCTION_END();
2364
2365 HANDLE_INSTRUCTION_START(UNUSED_FC)
2366 UnexpectedOpcode(inst, mh);
2367 HANDLE_INSTRUCTION_END();
2368
2369 HANDLE_INSTRUCTION_START(UNUSED_FD)
2370 UnexpectedOpcode(inst, mh);
2371 HANDLE_INSTRUCTION_END();
2372
2373 HANDLE_INSTRUCTION_START(UNUSED_FE)
2374 UnexpectedOpcode(inst, mh);
2375 HANDLE_INSTRUCTION_END();
2376
2377 HANDLE_INSTRUCTION_START(UNUSED_FF)
2378 UnexpectedOpcode(inst, mh);
2379 HANDLE_INSTRUCTION_END();
2380
2381 exception_pending_label: {
2382 CHECK(self->IsExceptionPending());
Sebastien Hertz1eda2262013-09-09 16:53:14 +02002383 if (UNLIKELY(self->TestAllFlags())) {
Ian Rogers7b078e82014-09-10 14:44:24 -07002384 self->CheckSuspend();
Sebastien Hertzee1997a2013-09-19 14:47:09 +02002385 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +02002386 }
Sebastien Hertzee1997a2013-09-19 14:47:09 +02002387 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002388 uint32_t found_dex_pc = FindNextInstructionFollowingException(self, shadow_frame, dex_pc,
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002389 instrumentation);
2390 if (found_dex_pc == DexFile::kDexNoIndex) {
2391 return JValue(); /* Handled in caller. */
2392 } else {
2393 int32_t displacement = static_cast<int32_t>(found_dex_pc) - static_cast<int32_t>(dex_pc);
2394 ADVANCE(displacement);
2395 }
2396 }
2397
Sebastien Hertz8379b222014-02-24 17:38:15 +01002398// Create alternative instruction handlers dedicated to instrumentation.
2399// Return instructions must not call Instrumentation::DexPcMovedEvent since they already call
2400// Instrumentation::MethodExited. This is to avoid posting debugger events twice for this location.
Sebastien Hertze713d932014-05-15 10:48:53 +02002401// Note: we do not use the kReturn instruction flag here (to test the instruction is a return). The
2402// compiler seems to not evaluate "(Instruction::FlagsOf(Instruction::code) & kReturn) != 0" to
2403// a constant condition that would remove the "if" statement so the test is free.
Sebastien Hertz8379b222014-02-24 17:38:15 +01002404#define INSTRUMENTATION_INSTRUCTION_HANDLER(o, code, n, f, r, i, a, v) \
2405 alt_op_##code: { \
2406 if (Instruction::code != Instruction::RETURN_VOID && \
2407 Instruction::code != Instruction::RETURN_VOID_BARRIER && \
2408 Instruction::code != Instruction::RETURN && \
2409 Instruction::code != Instruction::RETURN_WIDE && \
2410 Instruction::code != Instruction::RETURN_OBJECT) { \
2411 if (LIKELY(!notified_method_entry_event)) { \
2412 Runtime* runtime = Runtime::Current(); \
2413 const instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation(); \
2414 if (UNLIKELY(instrumentation->HasDexPcListeners())) { \
2415 Object* this_object = shadow_frame.GetThisObject(code_item->ins_size_); \
2416 instrumentation->DexPcMovedEvent(self, this_object, shadow_frame.GetMethod(), dex_pc); \
2417 } \
2418 } else { \
2419 notified_method_entry_event = false; \
2420 } \
2421 } \
2422 UPDATE_HANDLER_TABLE(); \
2423 goto *handlersTable[instrumentation::kMainHandlerTable][Instruction::code]; \
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002424 }
2425#include "dex_instruction_list.h"
2426 DEX_INSTRUCTION_LIST(INSTRUMENTATION_INSTRUCTION_HANDLER)
2427#undef DEX_INSTRUCTION_LIST
2428#undef INSTRUMENTATION_INSTRUCTION_HANDLER
2429} // NOLINT(readability/fn_size)
2430
2431// Explicit definitions of ExecuteGotoImpl.
Sebastien Hertzc6714852013-09-30 16:42:32 +02002432template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) HOT_ATTR
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002433JValue ExecuteGotoImpl<true, false>(Thread* self, MethodHelper& mh,
2434 const DexFile::CodeItem* code_item,
2435 ShadowFrame& shadow_frame, JValue result_register);
Sebastien Hertzc6714852013-09-30 16:42:32 +02002436template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) HOT_ATTR
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002437JValue ExecuteGotoImpl<false, false>(Thread* self, MethodHelper& mh,
2438 const DexFile::CodeItem* code_item,
2439 ShadowFrame& shadow_frame, JValue result_register);
2440template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
2441JValue ExecuteGotoImpl<true, true>(Thread* self, MethodHelper& mh,
2442 const DexFile::CodeItem* code_item,
2443 ShadowFrame& shadow_frame, JValue result_register);
2444template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
2445JValue ExecuteGotoImpl<false, true>(Thread* self, MethodHelper& mh,
2446 const DexFile::CodeItem* code_item,
2447 ShadowFrame& shadow_frame, JValue result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002448
2449} // namespace interpreter
2450} // namespace art