blob: cb4868c957eef93927d3f963a4f8e5dae9f5137f [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"
18
19namespace art {
20namespace interpreter {
21
22// In the following macros, we expect the following local variables exist:
23// - "self": the current Thread*.
24// - "inst" : the current Instruction*.
Sebastien Hertz3b588e02013-09-11 14:33:18 +020025// - "inst_data" : the current instruction's first 16 bits.
Sebastien Hertz8ece0502013-08-07 11:26:41 +020026// - "dex_pc": the current pc.
27// - "shadow_frame": the current shadow frame.
Sebastien Hertz8ece0502013-08-07 11:26:41 +020028// - "mh": the current MethodHelper.
29// - "currentHandlersTable": the current table of pointer to each instruction handler.
30
31// Advance to the next instruction and updates interpreter state.
Sebastien Hertz8ece0502013-08-07 11:26:41 +020032#define ADVANCE(_offset) \
33 do { \
34 int32_t disp = static_cast<int32_t>(_offset); \
35 inst = inst->RelativeAt(disp); \
36 dex_pc = static_cast<uint32_t>(static_cast<int32_t>(dex_pc) + disp); \
37 shadow_frame.SetDexPC(dex_pc); \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020038 TraceExecution(shadow_frame, inst, dex_pc, mh); \
Sebastien Hertz3b588e02013-09-11 14:33:18 +020039 inst_data = inst->Fetch16(0); \
40 goto *currentHandlersTable[inst->Opcode(inst_data)]; \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020041 } while (false)
42
43#define HANDLE_PENDING_EXCEPTION() goto exception_pending_label
44
45#define POSSIBLY_HANDLE_PENDING_EXCEPTION(_is_exception_pending, _offset) \
46 do { \
47 if (UNLIKELY(_is_exception_pending)) { \
48 HANDLE_PENDING_EXCEPTION(); \
49 } else { \
50 ADVANCE(_offset); \
51 } \
52 } while (false)
53
Sebastien Hertzee1997a2013-09-19 14:47:09 +020054#define UPDATE_HANDLER_TABLE() \
55 currentHandlersTable = handlersTable[Runtime::Current()->GetInstrumentation()->GetInterpreterHandlerTable()]
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +020056
Sebastien Hertz8ece0502013-08-07 11:26:41 +020057#define UNREACHABLE_CODE_CHECK() \
58 do { \
59 if (kIsDebugBuild) { \
60 LOG(FATAL) << "We should not be here !"; \
61 } \
62 } while (false)
63
64#define HANDLE_INSTRUCTION_START(opcode) op_##opcode: // NOLINT(whitespace/labels)
65#define HANDLE_INSTRUCTION_END() UNREACHABLE_CODE_CHECK()
66
Sebastien Hertzee1997a2013-09-19 14:47:09 +020067/**
68 * Interpreter based on computed goto tables.
69 *
70 * Each instruction is associated to a handler. This handler is responsible for executing the
71 * instruction and jump to the next instruction's handler.
72 * In order to limit the cost of instrumentation, we have two handler tables:
73 * - the "main" handler table: it contains handlers for normal execution of each instruction without
74 * handling of instrumentation.
75 * - the "alternative" handler table: it contains alternative handlers which first handle
76 * instrumentation before jumping to the corresponding "normal" instruction's handler.
77 *
78 * When instrumentation is active, the interpreter uses the "alternative" handler table. Otherwise
79 * it uses the "main" handler table.
80 *
81 * The current handler table is the handler table being used by the interpreter. It is updated:
82 * - on backward branch (goto, if and switch instructions)
83 * - after invoke
84 * - when an exception is thrown.
85 * This allows to support an attaching debugger to an already running application for instance.
86 *
87 * For a fast handler table update, handler tables are stored in an array of handler tables. Each
88 * handler table is represented by the InterpreterHandlerTable enum which allows to associate it
89 * to an index in this array of handler tables ((see Instrumentation::GetInterpreterHandlerTable).
90 *
91 * Here's the current layout of this array of handler tables:
92 *
93 * ---------------------+---------------+
94 * | NOP | (handler for NOP instruction)
95 * +---------------+
96 * "main" | MOVE | (handler for MOVE instruction)
97 * handler table +---------------+
98 * | ... |
99 * +---------------+
100 * | UNUSED_FF | (handler for UNUSED_FF instruction)
101 * ---------------------+---------------+
102 * | NOP | (alternative handler for NOP instruction)
103 * +---------------+
104 * "alternative" | MOVE | (alternative handler for MOVE instruction)
105 * handler table +---------------+
106 * | ... |
107 * +---------------+
108 * | UNUSED_FF | (alternative handler for UNUSED_FF instruction)
109 * ---------------------+---------------+
110 *
111 */
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100112template<bool do_access_check, bool transaction_active>
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200113JValue ExecuteGotoImpl(Thread* self, MethodHelper& mh, const DexFile::CodeItem* code_item,
114 ShadowFrame& shadow_frame, JValue result_register) {
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200115 // Define handler tables:
116 // - The main handler table contains execution handlers for each instruction.
117 // - The alternative handler table contains prelude handlers which check for thread suspend and
118 // manage instrumentation before jumping to the execution handler.
119 static const void* const handlersTable[instrumentation::kNumHandlerTables][kNumPackedOpcodes] = {
120 {
121 // Main handler table.
122#define INSTRUCTION_HANDLER(o, code, n, f, r, i, a, v) &&op_##code,
123#include "dex_instruction_list.h"
124 DEX_INSTRUCTION_LIST(INSTRUCTION_HANDLER)
125#undef DEX_INSTRUCTION_LIST
126#undef INSTRUCTION_HANDLER
127 }, {
128 // Alternative handler table.
129#define INSTRUCTION_HANDLER(o, code, n, f, r, i, a, v) &&alt_op_##code,
130#include "dex_instruction_list.h"
131 DEX_INSTRUCTION_LIST(INSTRUCTION_HANDLER)
132#undef DEX_INSTRUCTION_LIST
133#undef INSTRUCTION_HANDLER
134 }
135 };
136
137 const bool do_assignability_check = do_access_check;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200138 if (UNLIKELY(!shadow_frame.HasReferenceArray())) {
139 LOG(FATAL) << "Invalid shadow frame for interpreter use";
140 return JValue();
141 }
142 self->VerifyStack();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200143
144 uint32_t dex_pc = shadow_frame.GetDexPC();
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200145 const Instruction* inst = Instruction::At(code_item->insns_ + dex_pc);
146 uint16_t inst_data;
147 const void* const* currentHandlersTable;
Sebastien Hertz8379b222014-02-24 17:38:15 +0100148 bool notified_method_entry_event = false;
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200149 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200150 if (LIKELY(dex_pc == 0)) { // We are entering the method as opposed to deoptimizing..
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200151 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200152 if (UNLIKELY(instrumentation->HasMethodEntryListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200153 instrumentation->MethodEnterEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200154 shadow_frame.GetMethod(), 0);
Sebastien Hertz8379b222014-02-24 17:38:15 +0100155 notified_method_entry_event = true;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200156 }
157 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200158
159 // Jump to first instruction.
160 ADVANCE(0);
161 UNREACHABLE_CODE_CHECK();
162
163 HANDLE_INSTRUCTION_START(NOP)
164 ADVANCE(1);
165 HANDLE_INSTRUCTION_END();
166
167 HANDLE_INSTRUCTION_START(MOVE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200168 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
169 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200170 ADVANCE(1);
171 HANDLE_INSTRUCTION_END();
172
173 HANDLE_INSTRUCTION_START(MOVE_FROM16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200174 shadow_frame.SetVReg(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200175 shadow_frame.GetVReg(inst->VRegB_22x()));
176 ADVANCE(2);
177 HANDLE_INSTRUCTION_END();
178
179 HANDLE_INSTRUCTION_START(MOVE_16)
180 shadow_frame.SetVReg(inst->VRegA_32x(),
181 shadow_frame.GetVReg(inst->VRegB_32x()));
182 ADVANCE(3);
183 HANDLE_INSTRUCTION_END();
184
185 HANDLE_INSTRUCTION_START(MOVE_WIDE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200186 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
187 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200188 ADVANCE(1);
189 HANDLE_INSTRUCTION_END();
190
191 HANDLE_INSTRUCTION_START(MOVE_WIDE_FROM16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200192 shadow_frame.SetVRegLong(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200193 shadow_frame.GetVRegLong(inst->VRegB_22x()));
194 ADVANCE(2);
195 HANDLE_INSTRUCTION_END();
196
197 HANDLE_INSTRUCTION_START(MOVE_WIDE_16)
198 shadow_frame.SetVRegLong(inst->VRegA_32x(),
199 shadow_frame.GetVRegLong(inst->VRegB_32x()));
200 ADVANCE(3);
201 HANDLE_INSTRUCTION_END();
202
203 HANDLE_INSTRUCTION_START(MOVE_OBJECT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200204 shadow_frame.SetVRegReference(inst->VRegA_12x(inst_data),
205 shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200206 ADVANCE(1);
207 HANDLE_INSTRUCTION_END();
208
209 HANDLE_INSTRUCTION_START(MOVE_OBJECT_FROM16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200210 shadow_frame.SetVRegReference(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200211 shadow_frame.GetVRegReference(inst->VRegB_22x()));
212 ADVANCE(2);
213 HANDLE_INSTRUCTION_END();
214
215 HANDLE_INSTRUCTION_START(MOVE_OBJECT_16)
216 shadow_frame.SetVRegReference(inst->VRegA_32x(),
217 shadow_frame.GetVRegReference(inst->VRegB_32x()));
218 ADVANCE(3);
219 HANDLE_INSTRUCTION_END();
220
221 HANDLE_INSTRUCTION_START(MOVE_RESULT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200222 shadow_frame.SetVReg(inst->VRegA_11x(inst_data), result_register.GetI());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200223 ADVANCE(1);
224 HANDLE_INSTRUCTION_END();
225
226 HANDLE_INSTRUCTION_START(MOVE_RESULT_WIDE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200227 shadow_frame.SetVRegLong(inst->VRegA_11x(inst_data), result_register.GetJ());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200228 ADVANCE(1);
229 HANDLE_INSTRUCTION_END();
230
231 HANDLE_INSTRUCTION_START(MOVE_RESULT_OBJECT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200232 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), result_register.GetL());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200233 ADVANCE(1);
234 HANDLE_INSTRUCTION_END();
235
236 HANDLE_INSTRUCTION_START(MOVE_EXCEPTION) {
Sebastien Hertz5c004902014-05-21 10:07:42 +0200237 Throwable* exception = self->GetException(nullptr);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200238 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), exception);
Sebastien Hertz5c004902014-05-21 10:07:42 +0200239 self->ClearException();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200240 ADVANCE(1);
241 }
242 HANDLE_INSTRUCTION_END();
243
244 HANDLE_INSTRUCTION_START(RETURN_VOID) {
245 JValue result;
Sebastien Hertz043036f2013-09-09 18:26:48 +0200246 if (do_access_check) {
247 // If access checks are required then the dex-to-dex compiler and analysis of
248 // whether the class has final fields hasn't been performed. Conservatively
249 // perform the memory barrier now.
Hans Boehm30359612014-05-21 17:46:23 -0700250 QuasiAtomic::ThreadFenceForConstructor();
Sebastien Hertz043036f2013-09-09 18:26:48 +0200251 }
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200252 if (UNLIKELY(self->TestAllFlags())) {
253 CheckSuspend(self);
254 }
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200255 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200256 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200257 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200258 shadow_frame.GetMethod(), dex_pc,
259 result);
Sebastien Hertze713d932014-05-15 10:48:53 +0200260 } else if (UNLIKELY(instrumentation->HasDexPcListeners())) {
261 instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
262 shadow_frame.GetMethod(), dex_pc);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200263 }
264 return result;
265 }
266 HANDLE_INSTRUCTION_END();
267
268 HANDLE_INSTRUCTION_START(RETURN_VOID_BARRIER) {
Hans Boehm30359612014-05-21 17:46:23 -0700269 QuasiAtomic::ThreadFenceForConstructor();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200270 JValue result;
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200271 if (UNLIKELY(self->TestAllFlags())) {
272 CheckSuspend(self);
273 }
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200274 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200275 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200276 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200277 shadow_frame.GetMethod(), dex_pc,
278 result);
Sebastien Hertze713d932014-05-15 10:48:53 +0200279 } else if (UNLIKELY(instrumentation->HasDexPcListeners())) {
280 instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
281 shadow_frame.GetMethod(), dex_pc);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200282 }
283 return result;
284 }
285 HANDLE_INSTRUCTION_END();
286
287 HANDLE_INSTRUCTION_START(RETURN) {
288 JValue result;
289 result.SetJ(0);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200290 result.SetI(shadow_frame.GetVReg(inst->VRegA_11x(inst_data)));
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200291 if (UNLIKELY(self->TestAllFlags())) {
292 CheckSuspend(self);
293 }
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200294 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200295 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200296 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200297 shadow_frame.GetMethod(), dex_pc,
298 result);
Sebastien Hertze713d932014-05-15 10:48:53 +0200299 } else if (UNLIKELY(instrumentation->HasDexPcListeners())) {
300 instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
301 shadow_frame.GetMethod(), dex_pc);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200302 }
303 return result;
304 }
305 HANDLE_INSTRUCTION_END();
306
307 HANDLE_INSTRUCTION_START(RETURN_WIDE) {
308 JValue result;
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200309 result.SetJ(shadow_frame.GetVRegLong(inst->VRegA_11x(inst_data)));
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200310 if (UNLIKELY(self->TestAllFlags())) {
311 CheckSuspend(self);
312 }
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200313 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200314 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200315 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200316 shadow_frame.GetMethod(), dex_pc,
317 result);
Sebastien Hertze713d932014-05-15 10:48:53 +0200318 } else if (UNLIKELY(instrumentation->HasDexPcListeners())) {
319 instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
320 shadow_frame.GetMethod(), dex_pc);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200321 }
322 return result;
323 }
324 HANDLE_INSTRUCTION_END();
325
326 HANDLE_INSTRUCTION_START(RETURN_OBJECT) {
327 JValue result;
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200328 if (UNLIKELY(self->TestAllFlags())) {
329 CheckSuspend(self);
330 }
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700331 const uint8_t vreg_index = inst->VRegA_11x(inst_data);
332 Object* obj_result = shadow_frame.GetVRegReference(vreg_index);
Jeff Haoa3faaf42013-09-03 19:07:00 -0700333 if (do_assignability_check && obj_result != NULL) {
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700334 StackHandleScope<1> hs(self);
335 MethodHelper mh(hs.NewHandle(shadow_frame.GetMethod()));
336 Class* return_type = mh.GetReturnType();
337 obj_result = shadow_frame.GetVRegReference(vreg_index);
Jeff Haoa3faaf42013-09-03 19:07:00 -0700338 if (return_type == NULL) {
339 // Return the pending exception.
340 HANDLE_PENDING_EXCEPTION();
341 }
342 if (!obj_result->VerifierInstanceOf(return_type)) {
343 // This should never happen.
344 self->ThrowNewExceptionF(self->GetCurrentLocationForThrow(),
345 "Ljava/lang/VirtualMachineError;",
346 "Returning '%s' that is not instance of return type '%s'",
Mathieu Chartierf8322842014-05-16 10:59:25 -0700347 obj_result->GetClass()->GetDescriptor().c_str(),
348 return_type->GetDescriptor().c_str());
Jeff Haoa3faaf42013-09-03 19:07:00 -0700349 HANDLE_PENDING_EXCEPTION();
350 }
351 }
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700352 result.SetL(obj_result);
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200353 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200354 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200355 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200356 shadow_frame.GetMethod(), dex_pc,
357 result);
Sebastien Hertze713d932014-05-15 10:48:53 +0200358 } else if (UNLIKELY(instrumentation->HasDexPcListeners())) {
359 instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
360 shadow_frame.GetMethod(), dex_pc);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200361 }
362 return result;
363 }
364 HANDLE_INSTRUCTION_END();
365
366 HANDLE_INSTRUCTION_START(CONST_4) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200367 uint32_t dst = inst->VRegA_11n(inst_data);
368 int32_t val = inst->VRegB_11n(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200369 shadow_frame.SetVReg(dst, val);
370 if (val == 0) {
371 shadow_frame.SetVRegReference(dst, NULL);
372 }
373 ADVANCE(1);
374 }
375 HANDLE_INSTRUCTION_END();
376
377 HANDLE_INSTRUCTION_START(CONST_16) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200378 uint32_t dst = inst->VRegA_21s(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200379 int32_t val = inst->VRegB_21s();
380 shadow_frame.SetVReg(dst, val);
381 if (val == 0) {
382 shadow_frame.SetVRegReference(dst, NULL);
383 }
384 ADVANCE(2);
385 }
386 HANDLE_INSTRUCTION_END();
387
388 HANDLE_INSTRUCTION_START(CONST) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200389 uint32_t dst = inst->VRegA_31i(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200390 int32_t val = inst->VRegB_31i();
391 shadow_frame.SetVReg(dst, val);
392 if (val == 0) {
393 shadow_frame.SetVRegReference(dst, NULL);
394 }
395 ADVANCE(3);
396 }
397 HANDLE_INSTRUCTION_END();
398
399 HANDLE_INSTRUCTION_START(CONST_HIGH16) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200400 uint32_t dst = inst->VRegA_21h(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200401 int32_t val = static_cast<int32_t>(inst->VRegB_21h() << 16);
402 shadow_frame.SetVReg(dst, val);
403 if (val == 0) {
404 shadow_frame.SetVRegReference(dst, NULL);
405 }
406 ADVANCE(2);
407 }
408 HANDLE_INSTRUCTION_END();
409
410 HANDLE_INSTRUCTION_START(CONST_WIDE_16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200411 shadow_frame.SetVRegLong(inst->VRegA_21s(inst_data), inst->VRegB_21s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200412 ADVANCE(2);
413 HANDLE_INSTRUCTION_END();
414
415 HANDLE_INSTRUCTION_START(CONST_WIDE_32)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200416 shadow_frame.SetVRegLong(inst->VRegA_31i(inst_data), inst->VRegB_31i());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200417 ADVANCE(3);
418 HANDLE_INSTRUCTION_END();
419
420 HANDLE_INSTRUCTION_START(CONST_WIDE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200421 shadow_frame.SetVRegLong(inst->VRegA_51l(inst_data), inst->VRegB_51l());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200422 ADVANCE(5);
423 HANDLE_INSTRUCTION_END();
424
425 HANDLE_INSTRUCTION_START(CONST_WIDE_HIGH16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200426 shadow_frame.SetVRegLong(inst->VRegA_21h(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200427 static_cast<uint64_t>(inst->VRegB_21h()) << 48);
428 ADVANCE(2);
429 HANDLE_INSTRUCTION_END();
430
431 HANDLE_INSTRUCTION_START(CONST_STRING) {
432 String* s = ResolveString(self, mh, inst->VRegB_21c());
433 if (UNLIKELY(s == NULL)) {
434 HANDLE_PENDING_EXCEPTION();
435 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200436 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200437 ADVANCE(2);
438 }
439 }
440 HANDLE_INSTRUCTION_END();
441
442 HANDLE_INSTRUCTION_START(CONST_STRING_JUMBO) {
443 String* s = ResolveString(self, mh, inst->VRegB_31c());
444 if (UNLIKELY(s == NULL)) {
445 HANDLE_PENDING_EXCEPTION();
446 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200447 shadow_frame.SetVRegReference(inst->VRegA_31c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200448 ADVANCE(3);
449 }
450 }
451 HANDLE_INSTRUCTION_END();
452
453 HANDLE_INSTRUCTION_START(CONST_CLASS) {
454 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
455 self, false, do_access_check);
456 if (UNLIKELY(c == NULL)) {
457 HANDLE_PENDING_EXCEPTION();
458 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200459 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), c);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200460 ADVANCE(2);
461 }
462 }
463 HANDLE_INSTRUCTION_END();
464
465 HANDLE_INSTRUCTION_START(MONITOR_ENTER) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200466 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200467 if (UNLIKELY(obj == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +0200468 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200469 HANDLE_PENDING_EXCEPTION();
470 } else {
471 DoMonitorEnter(self, obj);
472 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), 1);
473 }
474 }
475 HANDLE_INSTRUCTION_END();
476
477 HANDLE_INSTRUCTION_START(MONITOR_EXIT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200478 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200479 if (UNLIKELY(obj == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +0200480 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200481 HANDLE_PENDING_EXCEPTION();
482 } else {
483 DoMonitorExit(self, obj);
484 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), 1);
485 }
486 }
487 HANDLE_INSTRUCTION_END();
488
489 HANDLE_INSTRUCTION_START(CHECK_CAST) {
490 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
491 self, false, do_access_check);
492 if (UNLIKELY(c == NULL)) {
493 HANDLE_PENDING_EXCEPTION();
494 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200495 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_21c(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200496 if (UNLIKELY(obj != NULL && !obj->InstanceOf(c))) {
497 ThrowClassCastException(c, obj->GetClass());
498 HANDLE_PENDING_EXCEPTION();
499 } else {
500 ADVANCE(2);
501 }
502 }
503 }
504 HANDLE_INSTRUCTION_END();
505
506 HANDLE_INSTRUCTION_START(INSTANCE_OF) {
507 Class* c = ResolveVerifyAndClinit(inst->VRegC_22c(), shadow_frame.GetMethod(),
508 self, false, do_access_check);
509 if (UNLIKELY(c == NULL)) {
510 HANDLE_PENDING_EXCEPTION();
511 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200512 Object* obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data));
513 shadow_frame.SetVReg(inst->VRegA_22c(inst_data), (obj != NULL && obj->InstanceOf(c)) ? 1 : 0);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200514 ADVANCE(2);
515 }
516 }
517 HANDLE_INSTRUCTION_END();
518
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700519 HANDLE_INSTRUCTION_START(ARRAY_LENGTH) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200520 Object* array = shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200521 if (UNLIKELY(array == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +0200522 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200523 HANDLE_PENDING_EXCEPTION();
524 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200525 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), array->AsArray()->GetLength());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200526 ADVANCE(1);
527 }
528 }
529 HANDLE_INSTRUCTION_END();
530
531 HANDLE_INSTRUCTION_START(NEW_INSTANCE) {
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700532 Runtime* runtime = Runtime::Current();
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800533 Object* obj = AllocObjectFromCode<do_access_check, true>(
534 inst->VRegB_21c(), shadow_frame.GetMethod(), self,
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700535 runtime->GetHeap()->GetCurrentAllocator());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200536 if (UNLIKELY(obj == NULL)) {
537 HANDLE_PENDING_EXCEPTION();
538 } else {
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700539 // Don't allow finalizable objects to be allocated during a transaction since these can't be
540 // finalized without a started runtime.
541 if (transaction_active && obj->GetClass()->IsFinalizable()) {
Ian Rogers2fa98e22014-05-06 15:26:39 -0700542 AbortTransaction(self, "Allocating finalizable object in transaction: %s",
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700543 PrettyTypeOf(obj).c_str());
544 HANDLE_PENDING_EXCEPTION();
545 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200546 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200547 ADVANCE(2);
548 }
549 }
550 HANDLE_INSTRUCTION_END();
551
552 HANDLE_INSTRUCTION_START(NEW_ARRAY) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200553 int32_t length = shadow_frame.GetVReg(inst->VRegB_22c(inst_data));
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800554 Object* obj = AllocArrayFromCode<do_access_check, true>(
555 inst->VRegC_22c(), shadow_frame.GetMethod(), length, self,
556 Runtime::Current()->GetHeap()->GetCurrentAllocator());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200557 if (UNLIKELY(obj == NULL)) {
558 HANDLE_PENDING_EXCEPTION();
559 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200560 shadow_frame.SetVRegReference(inst->VRegA_22c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200561 ADVANCE(2);
562 }
563 }
564 HANDLE_INSTRUCTION_END();
565
566 HANDLE_INSTRUCTION_START(FILLED_NEW_ARRAY) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100567 bool success =
568 DoFilledNewArray<false, do_access_check, transaction_active>(inst, shadow_frame,
569 self, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200570 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
571 }
572 HANDLE_INSTRUCTION_END();
573
574 HANDLE_INSTRUCTION_START(FILLED_NEW_ARRAY_RANGE) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100575 bool success =
576 DoFilledNewArray<true, do_access_check, transaction_active>(inst, shadow_frame,
577 self, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200578 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
579 }
580 HANDLE_INSTRUCTION_END();
581
582 HANDLE_INSTRUCTION_START(FILL_ARRAY_DATA) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200583 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_31t(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200584 if (UNLIKELY(obj == NULL)) {
585 ThrowNullPointerException(NULL, "null array in FILL_ARRAY_DATA");
586 HANDLE_PENDING_EXCEPTION();
587 } else {
588 Array* array = obj->AsArray();
589 DCHECK(array->IsArrayInstance() && !array->IsObjectArray());
590 const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t();
591 const Instruction::ArrayDataPayload* payload =
592 reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr);
593 if (UNLIKELY(static_cast<int32_t>(payload->element_count) > array->GetLength())) {
594 self->ThrowNewExceptionF(shadow_frame.GetCurrentLocationForThrow(),
595 "Ljava/lang/ArrayIndexOutOfBoundsException;",
596 "failed FILL_ARRAY_DATA; length=%d, index=%d",
597 array->GetLength(), payload->element_count);
598 HANDLE_PENDING_EXCEPTION();
599 } else {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100600 if (transaction_active) {
601 RecordArrayElementsInTransaction(array, payload->element_count);
602 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200603 uint32_t size_in_bytes = payload->element_count * payload->element_width;
Ian Rogersef7d42f2014-01-06 12:55:46 -0800604 memcpy(array->GetRawData(payload->element_width, 0), payload->data, size_in_bytes);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200605 ADVANCE(3);
606 }
607 }
608 }
609 HANDLE_INSTRUCTION_END();
610
611 HANDLE_INSTRUCTION_START(THROW) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200612 Object* exception = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200613 if (UNLIKELY(exception == NULL)) {
614 ThrowNullPointerException(NULL, "throw with null exception");
Jeff Haoa3faaf42013-09-03 19:07:00 -0700615 } else if (do_assignability_check && !exception->GetClass()->IsThrowableClass()) {
616 // This should never happen.
617 self->ThrowNewExceptionF(self->GetCurrentLocationForThrow(),
618 "Ljava/lang/VirtualMachineError;",
619 "Throwing '%s' that is not instance of Throwable",
Mathieu Chartierf8322842014-05-16 10:59:25 -0700620 exception->GetClass()->GetDescriptor().c_str());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200621 } else {
622 self->SetException(shadow_frame.GetCurrentLocationForThrow(), exception->AsThrowable());
623 }
624 HANDLE_PENDING_EXCEPTION();
625 }
626 HANDLE_INSTRUCTION_END();
627
628 HANDLE_INSTRUCTION_START(GOTO) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200629 int8_t offset = inst->VRegA_10t(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200630 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200631 if (UNLIKELY(self->TestAllFlags())) {
632 CheckSuspend(self);
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(GOTO_16) {
641 int16_t offset = inst->VRegA_20t();
642 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200643 if (UNLIKELY(self->TestAllFlags())) {
644 CheckSuspend(self);
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(GOTO_32) {
653 int32_t offset = inst->VRegA_30t();
654 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200655 if (UNLIKELY(self->TestAllFlags())) {
656 CheckSuspend(self);
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
664 HANDLE_INSTRUCTION_START(PACKED_SWITCH) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200665 int32_t offset = DoPackedSwitch(inst, shadow_frame, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200666 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200667 if (UNLIKELY(self->TestAllFlags())) {
668 CheckSuspend(self);
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200669 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200670 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200671 }
672 ADVANCE(offset);
673 }
674 HANDLE_INSTRUCTION_END();
675
676 HANDLE_INSTRUCTION_START(SPARSE_SWITCH) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200677 int32_t offset = DoSparseSwitch(inst, shadow_frame, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200678 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200679 if (UNLIKELY(self->TestAllFlags())) {
680 CheckSuspend(self);
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200681 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200682 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200683 }
684 ADVANCE(offset);
685 }
686 HANDLE_INSTRUCTION_END();
687
688 HANDLE_INSTRUCTION_START(CMPL_FLOAT) {
689 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
690 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
691 int32_t result;
692 if (val1 > val2) {
693 result = 1;
694 } else if (val1 == val2) {
695 result = 0;
696 } else {
697 result = -1;
698 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200699 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200700 ADVANCE(2);
701 }
702 HANDLE_INSTRUCTION_END();
703
704 HANDLE_INSTRUCTION_START(CMPG_FLOAT) {
705 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
706 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
707 int32_t result;
708 if (val1 < val2) {
709 result = -1;
710 } else if (val1 == val2) {
711 result = 0;
712 } else {
713 result = 1;
714 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200715 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200716 ADVANCE(2);
717 }
718 HANDLE_INSTRUCTION_END();
719
720 HANDLE_INSTRUCTION_START(CMPL_DOUBLE) {
721 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
722 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
723 int32_t result;
724 if (val1 > val2) {
725 result = 1;
726 } else if (val1 == val2) {
727 result = 0;
728 } else {
729 result = -1;
730 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200731 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200732 ADVANCE(2);
733 }
734 HANDLE_INSTRUCTION_END();
735
736 HANDLE_INSTRUCTION_START(CMPG_DOUBLE) {
737 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
738 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
739 int32_t result;
740 if (val1 < val2) {
741 result = -1;
742 } else if (val1 == val2) {
743 result = 0;
744 } else {
745 result = 1;
746 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200747 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200748 ADVANCE(2);
749 }
750 HANDLE_INSTRUCTION_END();
751
752 HANDLE_INSTRUCTION_START(CMP_LONG) {
753 int64_t val1 = shadow_frame.GetVRegLong(inst->VRegB_23x());
754 int64_t val2 = shadow_frame.GetVRegLong(inst->VRegC_23x());
755 int32_t result;
756 if (val1 > val2) {
757 result = 1;
758 } else if (val1 == val2) {
759 result = 0;
760 } else {
761 result = -1;
762 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200763 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200764 ADVANCE(2);
765 }
766 HANDLE_INSTRUCTION_END();
767
768 HANDLE_INSTRUCTION_START(IF_EQ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200769 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) == shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200770 int16_t offset = inst->VRegC_22t();
771 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200772 if (UNLIKELY(self->TestAllFlags())) {
773 CheckSuspend(self);
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200774 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200775 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200776 }
777 ADVANCE(offset);
778 } else {
779 ADVANCE(2);
780 }
781 }
782 HANDLE_INSTRUCTION_END();
783
784 HANDLE_INSTRUCTION_START(IF_NE) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200785 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) != shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200786 int16_t offset = inst->VRegC_22t();
787 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200788 if (UNLIKELY(self->TestAllFlags())) {
789 CheckSuspend(self);
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200790 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200791 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200792 }
793 ADVANCE(offset);
794 } else {
795 ADVANCE(2);
796 }
797 }
798 HANDLE_INSTRUCTION_END();
799
800 HANDLE_INSTRUCTION_START(IF_LT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200801 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) < shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200802 int16_t offset = inst->VRegC_22t();
803 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200804 if (UNLIKELY(self->TestAllFlags())) {
805 CheckSuspend(self);
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200806 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200807 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200808 }
809 ADVANCE(offset);
810 } else {
811 ADVANCE(2);
812 }
813 }
814 HANDLE_INSTRUCTION_END();
815
816 HANDLE_INSTRUCTION_START(IF_GE) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200817 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >= shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200818 int16_t offset = inst->VRegC_22t();
819 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200820 if (UNLIKELY(self->TestAllFlags())) {
821 CheckSuspend(self);
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200822 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200823 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200824 }
825 ADVANCE(offset);
826 } else {
827 ADVANCE(2);
828 }
829 }
830 HANDLE_INSTRUCTION_END();
831
832 HANDLE_INSTRUCTION_START(IF_GT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200833 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) > shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200834 int16_t offset = inst->VRegC_22t();
835 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200836 if (UNLIKELY(self->TestAllFlags())) {
837 CheckSuspend(self);
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200838 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200839 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200840 }
841 ADVANCE(offset);
842 } else {
843 ADVANCE(2);
844 }
845 }
846 HANDLE_INSTRUCTION_END();
847
848 HANDLE_INSTRUCTION_START(IF_LE) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200849 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <= shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200850 int16_t offset = inst->VRegC_22t();
851 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200852 if (UNLIKELY(self->TestAllFlags())) {
853 CheckSuspend(self);
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200854 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200855 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200856 }
857 ADVANCE(offset);
858 } else {
859 ADVANCE(2);
860 }
861 }
862 HANDLE_INSTRUCTION_END();
863
864 HANDLE_INSTRUCTION_START(IF_EQZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200865 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) == 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200866 int16_t offset = inst->VRegB_21t();
867 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200868 if (UNLIKELY(self->TestAllFlags())) {
869 CheckSuspend(self);
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200870 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200871 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200872 }
873 ADVANCE(offset);
874 } else {
875 ADVANCE(2);
876 }
877 }
878 HANDLE_INSTRUCTION_END();
879
880 HANDLE_INSTRUCTION_START(IF_NEZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200881 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) != 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200882 int16_t offset = inst->VRegB_21t();
883 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200884 if (UNLIKELY(self->TestAllFlags())) {
885 CheckSuspend(self);
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200886 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200887 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200888 }
889 ADVANCE(offset);
890 } else {
891 ADVANCE(2);
892 }
893 }
894 HANDLE_INSTRUCTION_END();
895
896 HANDLE_INSTRUCTION_START(IF_LTZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200897 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) < 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200898 int16_t offset = inst->VRegB_21t();
899 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200900 if (UNLIKELY(self->TestAllFlags())) {
901 CheckSuspend(self);
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200902 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200903 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200904 }
905 ADVANCE(offset);
906 } else {
907 ADVANCE(2);
908 }
909 }
910 HANDLE_INSTRUCTION_END();
911
912 HANDLE_INSTRUCTION_START(IF_GEZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200913 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) >= 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200914 int16_t offset = inst->VRegB_21t();
915 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200916 if (UNLIKELY(self->TestAllFlags())) {
917 CheckSuspend(self);
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200918 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200919 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200920 }
921 ADVANCE(offset);
922 } else {
923 ADVANCE(2);
924 }
925 }
926 HANDLE_INSTRUCTION_END();
927
928 HANDLE_INSTRUCTION_START(IF_GTZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200929 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) > 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200930 int16_t offset = inst->VRegB_21t();
931 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200932 if (UNLIKELY(self->TestAllFlags())) {
933 CheckSuspend(self);
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200934 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200935 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200936 }
937 ADVANCE(offset);
938 } else {
939 ADVANCE(2);
940 }
941 }
942 HANDLE_INSTRUCTION_END();
943
944 HANDLE_INSTRUCTION_START(IF_LEZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200945 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) <= 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200946 int16_t offset = inst->VRegB_21t();
947 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200948 if (UNLIKELY(self->TestAllFlags())) {
949 CheckSuspend(self);
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200950 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200951 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200952 }
953 ADVANCE(offset);
954 } else {
955 ADVANCE(2);
956 }
957 }
958 HANDLE_INSTRUCTION_END();
959
960 HANDLE_INSTRUCTION_START(AGET_BOOLEAN) {
961 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
962 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +0200963 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200964 HANDLE_PENDING_EXCEPTION();
965 } else {
966 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
967 BooleanArray* array = a->AsBooleanArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +0100968 if (LIKELY(array->CheckIsValidIndex(index))) {
969 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200970 ADVANCE(2);
971 } else {
972 HANDLE_PENDING_EXCEPTION();
973 }
974 }
975 }
976 HANDLE_INSTRUCTION_END();
977
978 HANDLE_INSTRUCTION_START(AGET_BYTE) {
979 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
980 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +0200981 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200982 HANDLE_PENDING_EXCEPTION();
983 } else {
984 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
985 ByteArray* array = a->AsByteArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +0100986 if (LIKELY(array->CheckIsValidIndex(index))) {
987 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200988 ADVANCE(2);
989 } else {
990 HANDLE_PENDING_EXCEPTION();
991 }
992 }
993 }
994 HANDLE_INSTRUCTION_END();
995
996 HANDLE_INSTRUCTION_START(AGET_CHAR) {
997 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
998 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +0200999 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001000 HANDLE_PENDING_EXCEPTION();
1001 } else {
1002 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1003 CharArray* array = a->AsCharArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001004 if (LIKELY(array->CheckIsValidIndex(index))) {
1005 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001006 ADVANCE(2);
1007 } else {
1008 HANDLE_PENDING_EXCEPTION();
1009 }
1010 }
1011 }
1012 HANDLE_INSTRUCTION_END();
1013
1014 HANDLE_INSTRUCTION_START(AGET_SHORT) {
1015 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1016 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +02001017 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001018 HANDLE_PENDING_EXCEPTION();
1019 } else {
1020 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1021 ShortArray* array = a->AsShortArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001022 if (LIKELY(array->CheckIsValidIndex(index))) {
1023 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001024 ADVANCE(2);
1025 } else {
1026 HANDLE_PENDING_EXCEPTION();
1027 }
1028 }
1029 }
1030 HANDLE_INSTRUCTION_END();
1031
1032 HANDLE_INSTRUCTION_START(AGET) {
1033 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1034 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +02001035 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001036 HANDLE_PENDING_EXCEPTION();
1037 } else {
1038 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1039 IntArray* array = a->AsIntArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001040 if (LIKELY(array->CheckIsValidIndex(index))) {
1041 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001042 ADVANCE(2);
1043 } else {
1044 HANDLE_PENDING_EXCEPTION();
1045 }
1046 }
1047 }
1048 HANDLE_INSTRUCTION_END();
1049
1050 HANDLE_INSTRUCTION_START(AGET_WIDE) {
1051 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1052 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +02001053 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001054 HANDLE_PENDING_EXCEPTION();
1055 } else {
1056 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1057 LongArray* array = a->AsLongArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001058 if (LIKELY(array->CheckIsValidIndex(index))) {
1059 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001060 ADVANCE(2);
1061 } else {
1062 HANDLE_PENDING_EXCEPTION();
1063 }
1064 }
1065 }
1066 HANDLE_INSTRUCTION_END();
1067
1068 HANDLE_INSTRUCTION_START(AGET_OBJECT) {
1069 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1070 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +02001071 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001072 HANDLE_PENDING_EXCEPTION();
1073 } else {
1074 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1075 ObjectArray<Object>* array = a->AsObjectArray<Object>();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001076 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001077 shadow_frame.SetVRegReference(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001078 ADVANCE(2);
1079 } else {
1080 HANDLE_PENDING_EXCEPTION();
1081 }
1082 }
1083 }
1084 HANDLE_INSTRUCTION_END();
1085
1086 HANDLE_INSTRUCTION_START(APUT_BOOLEAN) {
1087 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1088 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +02001089 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001090 HANDLE_PENDING_EXCEPTION();
1091 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001092 uint8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001093 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1094 BooleanArray* array = a->AsBooleanArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001095 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001096 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001097 ADVANCE(2);
1098 } else {
1099 HANDLE_PENDING_EXCEPTION();
1100 }
1101 }
1102 }
1103 HANDLE_INSTRUCTION_END();
1104
1105 HANDLE_INSTRUCTION_START(APUT_BYTE) {
1106 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1107 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +02001108 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001109 HANDLE_PENDING_EXCEPTION();
1110 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001111 int8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001112 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1113 ByteArray* array = a->AsByteArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001114 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001115 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001116 ADVANCE(2);
1117 } else {
1118 HANDLE_PENDING_EXCEPTION();
1119 }
1120 }
1121 }
1122 HANDLE_INSTRUCTION_END();
1123
1124 HANDLE_INSTRUCTION_START(APUT_CHAR) {
1125 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1126 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +02001127 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001128 HANDLE_PENDING_EXCEPTION();
1129 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001130 uint16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001131 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1132 CharArray* array = a->AsCharArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001133 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001134 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001135 ADVANCE(2);
1136 } else {
1137 HANDLE_PENDING_EXCEPTION();
1138 }
1139 }
1140 }
1141 HANDLE_INSTRUCTION_END();
1142
1143 HANDLE_INSTRUCTION_START(APUT_SHORT) {
1144 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1145 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +02001146 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001147 HANDLE_PENDING_EXCEPTION();
1148 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001149 int16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001150 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1151 ShortArray* array = a->AsShortArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001152 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001153 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001154 ADVANCE(2);
1155 } else {
1156 HANDLE_PENDING_EXCEPTION();
1157 }
1158 }
1159 }
1160 HANDLE_INSTRUCTION_END();
1161
1162 HANDLE_INSTRUCTION_START(APUT) {
1163 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1164 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +02001165 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001166 HANDLE_PENDING_EXCEPTION();
1167 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001168 int32_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001169 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1170 IntArray* array = a->AsIntArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001171 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001172 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001173 ADVANCE(2);
1174 } else {
1175 HANDLE_PENDING_EXCEPTION();
1176 }
1177 }
1178 }
1179 HANDLE_INSTRUCTION_END();
1180
1181 HANDLE_INSTRUCTION_START(APUT_WIDE) {
1182 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1183 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +02001184 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001185 HANDLE_PENDING_EXCEPTION();
1186 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001187 int64_t val = shadow_frame.GetVRegLong(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001188 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1189 LongArray* array = a->AsLongArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001190 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001191 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001192 ADVANCE(2);
1193 } else {
1194 HANDLE_PENDING_EXCEPTION();
1195 }
1196 }
1197 }
1198 HANDLE_INSTRUCTION_END();
1199
1200 HANDLE_INSTRUCTION_START(APUT_OBJECT) {
1201 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1202 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +02001203 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001204 HANDLE_PENDING_EXCEPTION();
1205 } else {
1206 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001207 Object* val = shadow_frame.GetVRegReference(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001208 ObjectArray<Object>* array = a->AsObjectArray<Object>();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001209 if (LIKELY(array->CheckIsValidIndex(index) && array->CheckAssignable(val))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001210 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001211 ADVANCE(2);
1212 } else {
1213 HANDLE_PENDING_EXCEPTION();
1214 }
1215 }
1216 }
1217 HANDLE_INSTRUCTION_END();
1218
1219 HANDLE_INSTRUCTION_START(IGET_BOOLEAN) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001220 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimBoolean, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001221 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1222 }
1223 HANDLE_INSTRUCTION_END();
1224
1225 HANDLE_INSTRUCTION_START(IGET_BYTE) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001226 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimByte, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001227 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1228 }
1229 HANDLE_INSTRUCTION_END();
1230
1231 HANDLE_INSTRUCTION_START(IGET_CHAR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001232 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimChar, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001233 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1234 }
1235 HANDLE_INSTRUCTION_END();
1236
1237 HANDLE_INSTRUCTION_START(IGET_SHORT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001238 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimShort, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001239 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1240 }
1241 HANDLE_INSTRUCTION_END();
1242
1243 HANDLE_INSTRUCTION_START(IGET) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001244 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimInt, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001245 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1246 }
1247 HANDLE_INSTRUCTION_END();
1248
1249 HANDLE_INSTRUCTION_START(IGET_WIDE) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001250 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimLong, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001251 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1252 }
1253 HANDLE_INSTRUCTION_END();
1254
1255 HANDLE_INSTRUCTION_START(IGET_OBJECT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001256 bool success = DoFieldGet<InstanceObjectRead, Primitive::kPrimNot, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001257 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1258 }
1259 HANDLE_INSTRUCTION_END();
1260
1261 HANDLE_INSTRUCTION_START(IGET_QUICK) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001262 bool success = DoIGetQuick<Primitive::kPrimInt>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001263 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1264 }
1265 HANDLE_INSTRUCTION_END();
1266
1267 HANDLE_INSTRUCTION_START(IGET_WIDE_QUICK) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001268 bool success = DoIGetQuick<Primitive::kPrimLong>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001269 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1270 }
1271 HANDLE_INSTRUCTION_END();
1272
1273 HANDLE_INSTRUCTION_START(IGET_OBJECT_QUICK) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001274 bool success = DoIGetQuick<Primitive::kPrimNot>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001275 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1276 }
1277 HANDLE_INSTRUCTION_END();
1278
1279 HANDLE_INSTRUCTION_START(SGET_BOOLEAN) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001280 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimBoolean, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001281 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1282 }
1283 HANDLE_INSTRUCTION_END();
1284
1285 HANDLE_INSTRUCTION_START(SGET_BYTE) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001286 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimByte, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001287 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1288 }
1289 HANDLE_INSTRUCTION_END();
1290
1291 HANDLE_INSTRUCTION_START(SGET_CHAR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001292 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimChar, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001293 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1294 }
1295 HANDLE_INSTRUCTION_END();
1296
1297 HANDLE_INSTRUCTION_START(SGET_SHORT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001298 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimShort, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001299 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1300 }
1301 HANDLE_INSTRUCTION_END();
1302
1303 HANDLE_INSTRUCTION_START(SGET) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001304 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimInt, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001305 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1306 }
1307 HANDLE_INSTRUCTION_END();
1308
1309 HANDLE_INSTRUCTION_START(SGET_WIDE) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001310 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimLong, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001311 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1312 }
1313 HANDLE_INSTRUCTION_END();
1314
1315 HANDLE_INSTRUCTION_START(SGET_OBJECT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001316 bool success = DoFieldGet<StaticObjectRead, Primitive::kPrimNot, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001317 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1318 }
1319 HANDLE_INSTRUCTION_END();
1320
1321 HANDLE_INSTRUCTION_START(IPUT_BOOLEAN) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001322 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimBoolean, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001323 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1324 }
1325 HANDLE_INSTRUCTION_END();
1326
1327 HANDLE_INSTRUCTION_START(IPUT_BYTE) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001328 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimByte, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001329 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1330 }
1331 HANDLE_INSTRUCTION_END();
1332
1333 HANDLE_INSTRUCTION_START(IPUT_CHAR) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001334 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimChar, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001335 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1336 }
1337 HANDLE_INSTRUCTION_END();
1338
1339 HANDLE_INSTRUCTION_START(IPUT_SHORT) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001340 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimShort, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001341 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1342 }
1343 HANDLE_INSTRUCTION_END();
1344
1345 HANDLE_INSTRUCTION_START(IPUT) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001346 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimInt, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001347 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1348 }
1349 HANDLE_INSTRUCTION_END();
1350
1351 HANDLE_INSTRUCTION_START(IPUT_WIDE) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001352 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimLong, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001353 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1354 }
1355 HANDLE_INSTRUCTION_END();
1356
1357 HANDLE_INSTRUCTION_START(IPUT_OBJECT) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001358 bool success = DoFieldPut<InstanceObjectWrite, Primitive::kPrimNot, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001359 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1360 }
1361 HANDLE_INSTRUCTION_END();
1362
1363 HANDLE_INSTRUCTION_START(IPUT_QUICK) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001364 bool success = DoIPutQuick<Primitive::kPrimInt, transaction_active>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001365 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1366 }
1367 HANDLE_INSTRUCTION_END();
1368
1369 HANDLE_INSTRUCTION_START(IPUT_WIDE_QUICK) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001370 bool success = DoIPutQuick<Primitive::kPrimLong, transaction_active>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001371 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1372 }
1373 HANDLE_INSTRUCTION_END();
1374
1375 HANDLE_INSTRUCTION_START(IPUT_OBJECT_QUICK) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001376 bool success = DoIPutQuick<Primitive::kPrimNot, transaction_active>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001377 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1378 }
1379 HANDLE_INSTRUCTION_END();
1380
1381 HANDLE_INSTRUCTION_START(SPUT_BOOLEAN) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001382 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimBoolean, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001383 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1384 }
1385 HANDLE_INSTRUCTION_END();
1386
1387 HANDLE_INSTRUCTION_START(SPUT_BYTE) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001388 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimByte, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001389 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1390 }
1391 HANDLE_INSTRUCTION_END();
1392
1393 HANDLE_INSTRUCTION_START(SPUT_CHAR) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001394 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimChar, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001395 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1396 }
1397 HANDLE_INSTRUCTION_END();
1398
1399 HANDLE_INSTRUCTION_START(SPUT_SHORT) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001400 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimShort, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001401 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1402 }
1403 HANDLE_INSTRUCTION_END();
1404
1405 HANDLE_INSTRUCTION_START(SPUT) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001406 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimInt, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001407 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1408 }
1409 HANDLE_INSTRUCTION_END();
1410
1411 HANDLE_INSTRUCTION_START(SPUT_WIDE) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001412 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimLong, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001413 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1414 }
1415 HANDLE_INSTRUCTION_END();
1416
1417 HANDLE_INSTRUCTION_START(SPUT_OBJECT) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001418 bool success = DoFieldPut<StaticObjectWrite, Primitive::kPrimNot, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001419 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1420 }
1421 HANDLE_INSTRUCTION_END();
1422
1423 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL) {
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001424 bool success = DoInvoke<kVirtual, false, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001425 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001426 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1427 }
1428 HANDLE_INSTRUCTION_END();
1429
1430 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_RANGE) {
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001431 bool success = DoInvoke<kVirtual, true, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001432 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001433 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1434 }
1435 HANDLE_INSTRUCTION_END();
1436
1437 HANDLE_INSTRUCTION_START(INVOKE_SUPER) {
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001438 bool success = DoInvoke<kSuper, false, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001439 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001440 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1441 }
1442 HANDLE_INSTRUCTION_END();
1443
1444 HANDLE_INSTRUCTION_START(INVOKE_SUPER_RANGE) {
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001445 bool success = DoInvoke<kSuper, true, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001446 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001447 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1448 }
1449 HANDLE_INSTRUCTION_END();
1450
1451 HANDLE_INSTRUCTION_START(INVOKE_DIRECT) {
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001452 bool success = DoInvoke<kDirect, false, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001453 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001454 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1455 }
1456 HANDLE_INSTRUCTION_END();
1457
1458 HANDLE_INSTRUCTION_START(INVOKE_DIRECT_RANGE) {
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001459 bool success = DoInvoke<kDirect, true, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001460 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001461 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1462 }
1463 HANDLE_INSTRUCTION_END();
1464
1465 HANDLE_INSTRUCTION_START(INVOKE_INTERFACE) {
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001466 bool success = DoInvoke<kInterface, false, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001467 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001468 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1469 }
1470 HANDLE_INSTRUCTION_END();
1471
1472 HANDLE_INSTRUCTION_START(INVOKE_INTERFACE_RANGE) {
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001473 bool success = DoInvoke<kInterface, true, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001474 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001475 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1476 }
1477 HANDLE_INSTRUCTION_END();
1478
1479 HANDLE_INSTRUCTION_START(INVOKE_STATIC) {
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001480 bool success = DoInvoke<kStatic, false, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001481 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001482 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1483 }
1484 HANDLE_INSTRUCTION_END();
1485
1486 HANDLE_INSTRUCTION_START(INVOKE_STATIC_RANGE) {
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001487 bool success = DoInvoke<kStatic, true, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001488 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001489 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1490 }
1491 HANDLE_INSTRUCTION_END();
1492
1493 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_QUICK) {
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001494 bool success = DoInvokeVirtualQuick<false>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001495 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001496 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1497 }
1498 HANDLE_INSTRUCTION_END();
1499
1500 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_RANGE_QUICK) {
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001501 bool success = DoInvokeVirtualQuick<true>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001502 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001503 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1504 }
1505 HANDLE_INSTRUCTION_END();
1506
1507 HANDLE_INSTRUCTION_START(NEG_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001508 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), -shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001509 ADVANCE(1);
1510 HANDLE_INSTRUCTION_END();
1511
1512 HANDLE_INSTRUCTION_START(NOT_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001513 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), ~shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001514 ADVANCE(1);
1515 HANDLE_INSTRUCTION_END();
1516
1517 HANDLE_INSTRUCTION_START(NEG_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001518 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), -shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001519 ADVANCE(1);
1520 HANDLE_INSTRUCTION_END();
1521
1522 HANDLE_INSTRUCTION_START(NOT_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001523 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), ~shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001524 ADVANCE(1);
1525 HANDLE_INSTRUCTION_END();
1526
1527 HANDLE_INSTRUCTION_START(NEG_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001528 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data), -shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001529 ADVANCE(1);
1530 HANDLE_INSTRUCTION_END();
1531
1532 HANDLE_INSTRUCTION_START(NEG_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001533 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data), -shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001534 ADVANCE(1);
1535 HANDLE_INSTRUCTION_END();
1536
1537 HANDLE_INSTRUCTION_START(INT_TO_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001538 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001539 ADVANCE(1);
1540 HANDLE_INSTRUCTION_END();
1541
1542 HANDLE_INSTRUCTION_START(INT_TO_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001543 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data), shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001544 ADVANCE(1);
1545 HANDLE_INSTRUCTION_END();
1546
1547 HANDLE_INSTRUCTION_START(INT_TO_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001548 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data), shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001549 ADVANCE(1);
1550 HANDLE_INSTRUCTION_END();
1551
1552 HANDLE_INSTRUCTION_START(LONG_TO_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001553 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001554 ADVANCE(1);
1555 HANDLE_INSTRUCTION_END();
1556
1557 HANDLE_INSTRUCTION_START(LONG_TO_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001558 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data), shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001559 ADVANCE(1);
1560 HANDLE_INSTRUCTION_END();
1561
1562 HANDLE_INSTRUCTION_START(LONG_TO_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001563 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data), shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001564 ADVANCE(1);
1565 HANDLE_INSTRUCTION_END();
1566
1567 HANDLE_INSTRUCTION_START(FLOAT_TO_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001568 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001569 int32_t result = art_float_to_integral<int32_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001570 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001571 ADVANCE(1);
1572 }
1573 HANDLE_INSTRUCTION_END();
1574
1575 HANDLE_INSTRUCTION_START(FLOAT_TO_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001576 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001577 int64_t result = art_float_to_integral<int64_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001578 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001579 ADVANCE(1);
1580 }
1581 HANDLE_INSTRUCTION_END();
1582
1583 HANDLE_INSTRUCTION_START(FLOAT_TO_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001584 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data), shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001585 ADVANCE(1);
1586 HANDLE_INSTRUCTION_END();
1587
1588 HANDLE_INSTRUCTION_START(DOUBLE_TO_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001589 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001590 int32_t result = art_float_to_integral<int32_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001591 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001592 ADVANCE(1);
1593 }
1594 HANDLE_INSTRUCTION_END();
1595
1596 HANDLE_INSTRUCTION_START(DOUBLE_TO_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001597 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001598 int64_t result = art_float_to_integral<int64_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001599 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001600 ADVANCE(1);
1601 }
1602 HANDLE_INSTRUCTION_END();
1603
1604 HANDLE_INSTRUCTION_START(DOUBLE_TO_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001605 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data), shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001606 ADVANCE(1);
1607 HANDLE_INSTRUCTION_END();
1608
1609 HANDLE_INSTRUCTION_START(INT_TO_BYTE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001610 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1611 static_cast<int8_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001612 ADVANCE(1);
1613 HANDLE_INSTRUCTION_END();
1614
1615 HANDLE_INSTRUCTION_START(INT_TO_CHAR)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001616 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1617 static_cast<uint16_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001618 ADVANCE(1);
1619 HANDLE_INSTRUCTION_END();
1620
1621 HANDLE_INSTRUCTION_START(INT_TO_SHORT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001622 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1623 static_cast<int16_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001624 ADVANCE(1);
1625 HANDLE_INSTRUCTION_END();
1626
1627 HANDLE_INSTRUCTION_START(ADD_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001628 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001629 shadow_frame.GetVReg(inst->VRegB_23x()) +
1630 shadow_frame.GetVReg(inst->VRegC_23x()));
1631 ADVANCE(2);
1632 HANDLE_INSTRUCTION_END();
1633
1634 HANDLE_INSTRUCTION_START(SUB_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001635 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001636 shadow_frame.GetVReg(inst->VRegB_23x()) -
1637 shadow_frame.GetVReg(inst->VRegC_23x()));
1638 ADVANCE(2);
1639 HANDLE_INSTRUCTION_END();
1640
1641 HANDLE_INSTRUCTION_START(MUL_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001642 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001643 shadow_frame.GetVReg(inst->VRegB_23x()) *
1644 shadow_frame.GetVReg(inst->VRegC_23x()));
1645 ADVANCE(2);
1646 HANDLE_INSTRUCTION_END();
1647
1648 HANDLE_INSTRUCTION_START(DIV_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001649 bool success = DoIntDivide(shadow_frame, inst->VRegA_23x(inst_data),
1650 shadow_frame.GetVReg(inst->VRegB_23x()),
1651 shadow_frame.GetVReg(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001652 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1653 }
1654 HANDLE_INSTRUCTION_END();
1655
1656 HANDLE_INSTRUCTION_START(REM_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001657 bool success = DoIntRemainder(shadow_frame, inst->VRegA_23x(inst_data),
1658 shadow_frame.GetVReg(inst->VRegB_23x()),
1659 shadow_frame.GetVReg(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001660 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1661 }
1662 HANDLE_INSTRUCTION_END();
1663
1664 HANDLE_INSTRUCTION_START(SHL_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001665 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001666 shadow_frame.GetVReg(inst->VRegB_23x()) <<
1667 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1668 ADVANCE(2);
1669 HANDLE_INSTRUCTION_END();
1670
1671 HANDLE_INSTRUCTION_START(SHR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001672 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001673 shadow_frame.GetVReg(inst->VRegB_23x()) >>
1674 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1675 ADVANCE(2);
1676 HANDLE_INSTRUCTION_END();
1677
1678 HANDLE_INSTRUCTION_START(USHR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001679 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001680 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_23x())) >>
1681 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1682 ADVANCE(2);
1683 HANDLE_INSTRUCTION_END();
1684
1685 HANDLE_INSTRUCTION_START(AND_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001686 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001687 shadow_frame.GetVReg(inst->VRegB_23x()) &
1688 shadow_frame.GetVReg(inst->VRegC_23x()));
1689 ADVANCE(2);
1690 HANDLE_INSTRUCTION_END();
1691
1692 HANDLE_INSTRUCTION_START(OR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001693 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001694 shadow_frame.GetVReg(inst->VRegB_23x()) |
1695 shadow_frame.GetVReg(inst->VRegC_23x()));
1696 ADVANCE(2);
1697 HANDLE_INSTRUCTION_END();
1698
1699 HANDLE_INSTRUCTION_START(XOR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001700 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001701 shadow_frame.GetVReg(inst->VRegB_23x()) ^
1702 shadow_frame.GetVReg(inst->VRegC_23x()));
1703 ADVANCE(2);
1704 HANDLE_INSTRUCTION_END();
1705
1706 HANDLE_INSTRUCTION_START(ADD_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001707 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001708 shadow_frame.GetVRegLong(inst->VRegB_23x()) +
1709 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1710 ADVANCE(2);
1711 HANDLE_INSTRUCTION_END();
1712
1713 HANDLE_INSTRUCTION_START(SUB_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001714 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001715 shadow_frame.GetVRegLong(inst->VRegB_23x()) -
1716 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1717 ADVANCE(2);
1718 HANDLE_INSTRUCTION_END();
1719
1720 HANDLE_INSTRUCTION_START(MUL_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001721 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001722 shadow_frame.GetVRegLong(inst->VRegB_23x()) *
1723 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1724 ADVANCE(2);
1725 HANDLE_INSTRUCTION_END();
1726
1727 HANDLE_INSTRUCTION_START(DIV_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001728 bool success = DoLongDivide(shadow_frame, inst->VRegA_23x(inst_data),
1729 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1730 shadow_frame.GetVRegLong(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001731 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1732 }
1733 HANDLE_INSTRUCTION_END();
1734
1735 HANDLE_INSTRUCTION_START(REM_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001736 bool success = DoLongRemainder(shadow_frame, inst->VRegA_23x(inst_data),
1737 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1738 shadow_frame.GetVRegLong(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001739 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1740 }
1741 HANDLE_INSTRUCTION_END();
1742
1743 HANDLE_INSTRUCTION_START(AND_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001744 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001745 shadow_frame.GetVRegLong(inst->VRegB_23x()) &
1746 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1747 ADVANCE(2);
1748 HANDLE_INSTRUCTION_END();
1749
1750 HANDLE_INSTRUCTION_START(OR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001751 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001752 shadow_frame.GetVRegLong(inst->VRegB_23x()) |
1753 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1754 ADVANCE(2);
1755 HANDLE_INSTRUCTION_END();
1756
1757 HANDLE_INSTRUCTION_START(XOR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001758 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001759 shadow_frame.GetVRegLong(inst->VRegB_23x()) ^
1760 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1761 ADVANCE(2);
1762 HANDLE_INSTRUCTION_END();
1763
1764 HANDLE_INSTRUCTION_START(SHL_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001765 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001766 shadow_frame.GetVRegLong(inst->VRegB_23x()) <<
1767 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1768 ADVANCE(2);
1769 HANDLE_INSTRUCTION_END();
1770
1771 HANDLE_INSTRUCTION_START(SHR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001772 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001773 shadow_frame.GetVRegLong(inst->VRegB_23x()) >>
1774 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1775 ADVANCE(2);
1776 HANDLE_INSTRUCTION_END();
1777
1778 HANDLE_INSTRUCTION_START(USHR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001779 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001780 static_cast<uint64_t>(shadow_frame.GetVRegLong(inst->VRegB_23x())) >>
1781 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1782 ADVANCE(2);
1783 HANDLE_INSTRUCTION_END();
1784
1785 HANDLE_INSTRUCTION_START(ADD_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001786 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001787 shadow_frame.GetVRegFloat(inst->VRegB_23x()) +
1788 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1789 ADVANCE(2);
1790 HANDLE_INSTRUCTION_END();
1791
1792 HANDLE_INSTRUCTION_START(SUB_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001793 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001794 shadow_frame.GetVRegFloat(inst->VRegB_23x()) -
1795 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1796 ADVANCE(2);
1797 HANDLE_INSTRUCTION_END();
1798
1799 HANDLE_INSTRUCTION_START(MUL_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001800 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001801 shadow_frame.GetVRegFloat(inst->VRegB_23x()) *
1802 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1803 ADVANCE(2);
1804 HANDLE_INSTRUCTION_END();
1805
1806 HANDLE_INSTRUCTION_START(DIV_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001807 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001808 shadow_frame.GetVRegFloat(inst->VRegB_23x()) /
1809 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1810 ADVANCE(2);
1811 HANDLE_INSTRUCTION_END();
1812
1813 HANDLE_INSTRUCTION_START(REM_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001814 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001815 fmodf(shadow_frame.GetVRegFloat(inst->VRegB_23x()),
1816 shadow_frame.GetVRegFloat(inst->VRegC_23x())));
1817 ADVANCE(2);
1818 HANDLE_INSTRUCTION_END();
1819
1820 HANDLE_INSTRUCTION_START(ADD_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001821 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001822 shadow_frame.GetVRegDouble(inst->VRegB_23x()) +
1823 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1824 ADVANCE(2);
1825 HANDLE_INSTRUCTION_END();
1826
1827 HANDLE_INSTRUCTION_START(SUB_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001828 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001829 shadow_frame.GetVRegDouble(inst->VRegB_23x()) -
1830 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1831 ADVANCE(2);
1832 HANDLE_INSTRUCTION_END();
1833
1834 HANDLE_INSTRUCTION_START(MUL_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001835 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001836 shadow_frame.GetVRegDouble(inst->VRegB_23x()) *
1837 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1838 ADVANCE(2);
1839 HANDLE_INSTRUCTION_END();
1840
1841 HANDLE_INSTRUCTION_START(DIV_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001842 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001843 shadow_frame.GetVRegDouble(inst->VRegB_23x()) /
1844 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1845 ADVANCE(2);
1846 HANDLE_INSTRUCTION_END();
1847
1848 HANDLE_INSTRUCTION_START(REM_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001849 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001850 fmod(shadow_frame.GetVRegDouble(inst->VRegB_23x()),
1851 shadow_frame.GetVRegDouble(inst->VRegC_23x())));
1852 ADVANCE(2);
1853 HANDLE_INSTRUCTION_END();
1854
1855 HANDLE_INSTRUCTION_START(ADD_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001856 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001857 shadow_frame.SetVReg(vregA,
1858 shadow_frame.GetVReg(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001859 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001860 ADVANCE(1);
1861 }
1862 HANDLE_INSTRUCTION_END();
1863
1864 HANDLE_INSTRUCTION_START(SUB_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,
1867 shadow_frame.GetVReg(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001868 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(MUL_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,
1876 shadow_frame.GetVReg(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001877 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(DIV_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 bool success = DoIntDivide(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001885 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001886 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
1887 }
1888 HANDLE_INSTRUCTION_END();
1889
1890 HANDLE_INSTRUCTION_START(REM_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001891 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001892 bool success = DoIntRemainder(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001893 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001894 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
1895 }
1896 HANDLE_INSTRUCTION_END();
1897
1898 HANDLE_INSTRUCTION_START(SHL_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001899 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001900 shadow_frame.SetVReg(vregA,
1901 shadow_frame.GetVReg(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001902 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001903 ADVANCE(1);
1904 }
1905 HANDLE_INSTRUCTION_END();
1906
1907 HANDLE_INSTRUCTION_START(SHR_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(USHR_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 static_cast<uint32_t>(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(AND_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 shadow_frame.GetVReg(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001929 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001930 ADVANCE(1);
1931 }
1932 HANDLE_INSTRUCTION_END();
1933
1934 HANDLE_INSTRUCTION_START(OR_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(XOR_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(ADD_LONG_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.SetVRegLong(vregA,
1955 shadow_frame.GetVRegLong(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001956 shadow_frame.GetVRegLong(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(SUB_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,
1964 shadow_frame.GetVRegLong(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001965 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(MUL_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,
1973 shadow_frame.GetVRegLong(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001974 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(DIV_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 bool success = DoLongDivide(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001982 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001983 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
1984 }
1985 HANDLE_INSTRUCTION_END();
1986
1987 HANDLE_INSTRUCTION_START(REM_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001988 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001989 bool success = DoLongRemainder(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001990 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001991 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
1992 }
1993 HANDLE_INSTRUCTION_END();
1994
1995 HANDLE_INSTRUCTION_START(AND_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001996 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001997 shadow_frame.SetVRegLong(vregA,
1998 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 ADVANCE(1);
2001 }
2002 HANDLE_INSTRUCTION_END();
2003
2004 HANDLE_INSTRUCTION_START(OR_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(XOR_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(SHL_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.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002027 ADVANCE(1);
2028 }
2029 HANDLE_INSTRUCTION_END();
2030
2031 HANDLE_INSTRUCTION_START(SHR_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(USHR_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 static_cast<uint64_t>(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(ADD_FLOAT_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.SetVRegFloat(vregA,
2052 shadow_frame.GetVRegFloat(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002053 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002054 ADVANCE(1);
2055 }
2056 HANDLE_INSTRUCTION_END();
2057
2058 HANDLE_INSTRUCTION_START(SUB_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(MUL_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(DIV_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(REM_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 fmodf(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(ADD_DOUBLE_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.SetVRegDouble(vregA,
2097 shadow_frame.GetVRegDouble(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002098 shadow_frame.GetVRegDouble(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(SUB_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(MUL_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(DIV_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(REM_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 fmod(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(ADD_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002140 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2141 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) +
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002142 inst->VRegC_22s());
2143 ADVANCE(2);
2144 HANDLE_INSTRUCTION_END();
2145
2146 HANDLE_INSTRUCTION_START(RSUB_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002147 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002148 inst->VRegC_22s() -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002149 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002150 ADVANCE(2);
2151 HANDLE_INSTRUCTION_END();
2152
2153 HANDLE_INSTRUCTION_START(MUL_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002154 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2155 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) *
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002156 inst->VRegC_22s());
2157 ADVANCE(2);
2158 HANDLE_INSTRUCTION_END();
2159
2160 HANDLE_INSTRUCTION_START(DIV_INT_LIT16) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002161 bool success = DoIntDivide(shadow_frame, inst->VRegA_22s(inst_data),
2162 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)), inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002163 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2164 }
2165 HANDLE_INSTRUCTION_END();
2166
2167 HANDLE_INSTRUCTION_START(REM_INT_LIT16) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002168 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22s(inst_data),
2169 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)), inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002170 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2171 }
2172 HANDLE_INSTRUCTION_END();
2173
2174 HANDLE_INSTRUCTION_START(AND_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002175 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2176 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) &
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002177 inst->VRegC_22s());
2178 ADVANCE(2);
2179 HANDLE_INSTRUCTION_END();
2180
2181 HANDLE_INSTRUCTION_START(OR_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002182 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2183 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) |
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002184 inst->VRegC_22s());
2185 ADVANCE(2);
2186 HANDLE_INSTRUCTION_END();
2187
2188 HANDLE_INSTRUCTION_START(XOR_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002189 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2190 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) ^
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002191 inst->VRegC_22s());
2192 ADVANCE(2);
2193 HANDLE_INSTRUCTION_END();
2194
2195 HANDLE_INSTRUCTION_START(ADD_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002196 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002197 shadow_frame.GetVReg(inst->VRegB_22b()) +
2198 inst->VRegC_22b());
2199 ADVANCE(2);
2200 HANDLE_INSTRUCTION_END();
2201
2202 HANDLE_INSTRUCTION_START(RSUB_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002203 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002204 inst->VRegC_22b() -
2205 shadow_frame.GetVReg(inst->VRegB_22b()));
2206 ADVANCE(2);
2207 HANDLE_INSTRUCTION_END();
2208
2209 HANDLE_INSTRUCTION_START(MUL_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002210 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002211 shadow_frame.GetVReg(inst->VRegB_22b()) *
2212 inst->VRegC_22b());
2213 ADVANCE(2);
2214 HANDLE_INSTRUCTION_END();
2215
2216 HANDLE_INSTRUCTION_START(DIV_INT_LIT8) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002217 bool success = DoIntDivide(shadow_frame, inst->VRegA_22b(inst_data),
2218 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002219 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2220 }
2221 HANDLE_INSTRUCTION_END();
2222
2223 HANDLE_INSTRUCTION_START(REM_INT_LIT8) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002224 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22b(inst_data),
2225 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002226 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2227 }
2228 HANDLE_INSTRUCTION_END();
2229
2230 HANDLE_INSTRUCTION_START(AND_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002231 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002232 shadow_frame.GetVReg(inst->VRegB_22b()) &
2233 inst->VRegC_22b());
2234 ADVANCE(2);
2235 HANDLE_INSTRUCTION_END();
2236
2237 HANDLE_INSTRUCTION_START(OR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002238 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002239 shadow_frame.GetVReg(inst->VRegB_22b()) |
2240 inst->VRegC_22b());
2241 ADVANCE(2);
2242 HANDLE_INSTRUCTION_END();
2243
2244 HANDLE_INSTRUCTION_START(XOR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002245 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002246 shadow_frame.GetVReg(inst->VRegB_22b()) ^
2247 inst->VRegC_22b());
2248 ADVANCE(2);
2249 HANDLE_INSTRUCTION_END();
2250
2251 HANDLE_INSTRUCTION_START(SHL_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002252 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002253 shadow_frame.GetVReg(inst->VRegB_22b()) <<
2254 (inst->VRegC_22b() & 0x1f));
2255 ADVANCE(2);
2256 HANDLE_INSTRUCTION_END();
2257
2258 HANDLE_INSTRUCTION_START(SHR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002259 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002260 shadow_frame.GetVReg(inst->VRegB_22b()) >>
2261 (inst->VRegC_22b() & 0x1f));
2262 ADVANCE(2);
2263 HANDLE_INSTRUCTION_END();
2264
2265 HANDLE_INSTRUCTION_START(USHR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002266 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002267 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_22b())) >>
2268 (inst->VRegC_22b() & 0x1f));
2269 ADVANCE(2);
2270 HANDLE_INSTRUCTION_END();
2271
2272 HANDLE_INSTRUCTION_START(UNUSED_3E)
2273 UnexpectedOpcode(inst, mh);
2274 HANDLE_INSTRUCTION_END();
2275
2276 HANDLE_INSTRUCTION_START(UNUSED_3F)
2277 UnexpectedOpcode(inst, mh);
2278 HANDLE_INSTRUCTION_END();
2279
2280 HANDLE_INSTRUCTION_START(UNUSED_40)
2281 UnexpectedOpcode(inst, mh);
2282 HANDLE_INSTRUCTION_END();
2283
2284 HANDLE_INSTRUCTION_START(UNUSED_41)
2285 UnexpectedOpcode(inst, mh);
2286 HANDLE_INSTRUCTION_END();
2287
2288 HANDLE_INSTRUCTION_START(UNUSED_42)
2289 UnexpectedOpcode(inst, mh);
2290 HANDLE_INSTRUCTION_END();
2291
2292 HANDLE_INSTRUCTION_START(UNUSED_43)
2293 UnexpectedOpcode(inst, mh);
2294 HANDLE_INSTRUCTION_END();
2295
2296 HANDLE_INSTRUCTION_START(UNUSED_79)
2297 UnexpectedOpcode(inst, mh);
2298 HANDLE_INSTRUCTION_END();
2299
2300 HANDLE_INSTRUCTION_START(UNUSED_7A)
2301 UnexpectedOpcode(inst, mh);
2302 HANDLE_INSTRUCTION_END();
2303
2304 HANDLE_INSTRUCTION_START(UNUSED_EB)
2305 UnexpectedOpcode(inst, mh);
2306 HANDLE_INSTRUCTION_END();
2307
2308 HANDLE_INSTRUCTION_START(UNUSED_EC)
2309 UnexpectedOpcode(inst, mh);
2310 HANDLE_INSTRUCTION_END();
2311
2312 HANDLE_INSTRUCTION_START(UNUSED_ED)
2313 UnexpectedOpcode(inst, mh);
2314 HANDLE_INSTRUCTION_END();
2315
2316 HANDLE_INSTRUCTION_START(UNUSED_EE)
2317 UnexpectedOpcode(inst, mh);
2318 HANDLE_INSTRUCTION_END();
2319
2320 HANDLE_INSTRUCTION_START(UNUSED_EF)
2321 UnexpectedOpcode(inst, mh);
2322 HANDLE_INSTRUCTION_END();
2323
2324 HANDLE_INSTRUCTION_START(UNUSED_F0)
2325 UnexpectedOpcode(inst, mh);
2326 HANDLE_INSTRUCTION_END();
2327
2328 HANDLE_INSTRUCTION_START(UNUSED_F1)
2329 UnexpectedOpcode(inst, mh);
2330 HANDLE_INSTRUCTION_END();
2331
2332 HANDLE_INSTRUCTION_START(UNUSED_F2)
2333 UnexpectedOpcode(inst, mh);
2334 HANDLE_INSTRUCTION_END();
2335
2336 HANDLE_INSTRUCTION_START(UNUSED_F3)
2337 UnexpectedOpcode(inst, mh);
2338 HANDLE_INSTRUCTION_END();
2339
2340 HANDLE_INSTRUCTION_START(UNUSED_F4)
2341 UnexpectedOpcode(inst, mh);
2342 HANDLE_INSTRUCTION_END();
2343
2344 HANDLE_INSTRUCTION_START(UNUSED_F5)
2345 UnexpectedOpcode(inst, mh);
2346 HANDLE_INSTRUCTION_END();
2347
2348 HANDLE_INSTRUCTION_START(UNUSED_F6)
2349 UnexpectedOpcode(inst, mh);
2350 HANDLE_INSTRUCTION_END();
2351
2352 HANDLE_INSTRUCTION_START(UNUSED_F7)
2353 UnexpectedOpcode(inst, mh);
2354 HANDLE_INSTRUCTION_END();
2355
2356 HANDLE_INSTRUCTION_START(UNUSED_F8)
2357 UnexpectedOpcode(inst, mh);
2358 HANDLE_INSTRUCTION_END();
2359
2360 HANDLE_INSTRUCTION_START(UNUSED_F9)
2361 UnexpectedOpcode(inst, mh);
2362 HANDLE_INSTRUCTION_END();
2363
2364 HANDLE_INSTRUCTION_START(UNUSED_FA)
2365 UnexpectedOpcode(inst, mh);
2366 HANDLE_INSTRUCTION_END();
2367
2368 HANDLE_INSTRUCTION_START(UNUSED_FB)
2369 UnexpectedOpcode(inst, mh);
2370 HANDLE_INSTRUCTION_END();
2371
2372 HANDLE_INSTRUCTION_START(UNUSED_FC)
2373 UnexpectedOpcode(inst, mh);
2374 HANDLE_INSTRUCTION_END();
2375
2376 HANDLE_INSTRUCTION_START(UNUSED_FD)
2377 UnexpectedOpcode(inst, mh);
2378 HANDLE_INSTRUCTION_END();
2379
2380 HANDLE_INSTRUCTION_START(UNUSED_FE)
2381 UnexpectedOpcode(inst, mh);
2382 HANDLE_INSTRUCTION_END();
2383
2384 HANDLE_INSTRUCTION_START(UNUSED_FF)
2385 UnexpectedOpcode(inst, mh);
2386 HANDLE_INSTRUCTION_END();
2387
2388 exception_pending_label: {
2389 CHECK(self->IsExceptionPending());
Sebastien Hertz1eda2262013-09-09 16:53:14 +02002390 if (UNLIKELY(self->TestAllFlags())) {
2391 CheckSuspend(self);
Sebastien Hertzee1997a2013-09-19 14:47:09 +02002392 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +02002393 }
Sebastien Hertzee1997a2013-09-19 14:47:09 +02002394 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002395 uint32_t found_dex_pc = FindNextInstructionFollowingException(self, shadow_frame, dex_pc,
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002396 instrumentation);
2397 if (found_dex_pc == DexFile::kDexNoIndex) {
2398 return JValue(); /* Handled in caller. */
2399 } else {
2400 int32_t displacement = static_cast<int32_t>(found_dex_pc) - static_cast<int32_t>(dex_pc);
2401 ADVANCE(displacement);
2402 }
2403 }
2404
Sebastien Hertz8379b222014-02-24 17:38:15 +01002405// Create alternative instruction handlers dedicated to instrumentation.
2406// Return instructions must not call Instrumentation::DexPcMovedEvent since they already call
2407// Instrumentation::MethodExited. This is to avoid posting debugger events twice for this location.
Sebastien Hertze713d932014-05-15 10:48:53 +02002408// Note: we do not use the kReturn instruction flag here (to test the instruction is a return). The
2409// compiler seems to not evaluate "(Instruction::FlagsOf(Instruction::code) & kReturn) != 0" to
2410// a constant condition that would remove the "if" statement so the test is free.
Sebastien Hertz8379b222014-02-24 17:38:15 +01002411#define INSTRUMENTATION_INSTRUCTION_HANDLER(o, code, n, f, r, i, a, v) \
2412 alt_op_##code: { \
2413 if (Instruction::code != Instruction::RETURN_VOID && \
2414 Instruction::code != Instruction::RETURN_VOID_BARRIER && \
2415 Instruction::code != Instruction::RETURN && \
2416 Instruction::code != Instruction::RETURN_WIDE && \
2417 Instruction::code != Instruction::RETURN_OBJECT) { \
2418 if (LIKELY(!notified_method_entry_event)) { \
2419 Runtime* runtime = Runtime::Current(); \
2420 const instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation(); \
2421 if (UNLIKELY(instrumentation->HasDexPcListeners())) { \
2422 Object* this_object = shadow_frame.GetThisObject(code_item->ins_size_); \
2423 instrumentation->DexPcMovedEvent(self, this_object, shadow_frame.GetMethod(), dex_pc); \
2424 } \
2425 } else { \
2426 notified_method_entry_event = false; \
2427 } \
2428 } \
2429 UPDATE_HANDLER_TABLE(); \
2430 goto *handlersTable[instrumentation::kMainHandlerTable][Instruction::code]; \
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002431 }
2432#include "dex_instruction_list.h"
2433 DEX_INSTRUCTION_LIST(INSTRUMENTATION_INSTRUCTION_HANDLER)
2434#undef DEX_INSTRUCTION_LIST
2435#undef INSTRUMENTATION_INSTRUCTION_HANDLER
2436} // NOLINT(readability/fn_size)
2437
2438// Explicit definitions of ExecuteGotoImpl.
Sebastien Hertzc6714852013-09-30 16:42:32 +02002439template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) HOT_ATTR
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002440JValue ExecuteGotoImpl<true, false>(Thread* self, MethodHelper& mh,
2441 const DexFile::CodeItem* code_item,
2442 ShadowFrame& shadow_frame, JValue result_register);
Sebastien Hertzc6714852013-09-30 16:42:32 +02002443template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) HOT_ATTR
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002444JValue ExecuteGotoImpl<false, false>(Thread* self, MethodHelper& mh,
2445 const DexFile::CodeItem* code_item,
2446 ShadowFrame& shadow_frame, JValue result_register);
2447template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
2448JValue ExecuteGotoImpl<true, true>(Thread* self, MethodHelper& mh,
2449 const DexFile::CodeItem* code_item,
2450 ShadowFrame& shadow_frame, JValue result_register);
2451template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
2452JValue ExecuteGotoImpl<false, true>(Thread* self, MethodHelper& mh,
2453 const DexFile::CodeItem* code_item,
2454 ShadowFrame& shadow_frame, JValue result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002455
2456} // namespace interpreter
2457} // namespace art