blob: 755e1ed81496ccee90ab445d9567207297522399 [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.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700344 std::string temp1, temp2;
Jeff Haoa3faaf42013-09-03 19:07:00 -0700345 self->ThrowNewExceptionF(self->GetCurrentLocationForThrow(),
346 "Ljava/lang/VirtualMachineError;",
347 "Returning '%s' that is not instance of return type '%s'",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700348 obj_result->GetClass()->GetDescriptor(&temp1),
349 return_type->GetDescriptor(&temp2));
Jeff Haoa3faaf42013-09-03 19:07:00 -0700350 HANDLE_PENDING_EXCEPTION();
351 }
352 }
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700353 result.SetL(obj_result);
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200354 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200355 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200356 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200357 shadow_frame.GetMethod(), dex_pc,
358 result);
Sebastien Hertze713d932014-05-15 10:48:53 +0200359 } else if (UNLIKELY(instrumentation->HasDexPcListeners())) {
360 instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
361 shadow_frame.GetMethod(), dex_pc);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200362 }
363 return result;
364 }
365 HANDLE_INSTRUCTION_END();
366
367 HANDLE_INSTRUCTION_START(CONST_4) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200368 uint32_t dst = inst->VRegA_11n(inst_data);
369 int32_t val = inst->VRegB_11n(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200370 shadow_frame.SetVReg(dst, val);
371 if (val == 0) {
372 shadow_frame.SetVRegReference(dst, NULL);
373 }
374 ADVANCE(1);
375 }
376 HANDLE_INSTRUCTION_END();
377
378 HANDLE_INSTRUCTION_START(CONST_16) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200379 uint32_t dst = inst->VRegA_21s(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200380 int32_t val = inst->VRegB_21s();
381 shadow_frame.SetVReg(dst, val);
382 if (val == 0) {
383 shadow_frame.SetVRegReference(dst, NULL);
384 }
385 ADVANCE(2);
386 }
387 HANDLE_INSTRUCTION_END();
388
389 HANDLE_INSTRUCTION_START(CONST) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200390 uint32_t dst = inst->VRegA_31i(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200391 int32_t val = inst->VRegB_31i();
392 shadow_frame.SetVReg(dst, val);
393 if (val == 0) {
394 shadow_frame.SetVRegReference(dst, NULL);
395 }
396 ADVANCE(3);
397 }
398 HANDLE_INSTRUCTION_END();
399
400 HANDLE_INSTRUCTION_START(CONST_HIGH16) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200401 uint32_t dst = inst->VRegA_21h(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200402 int32_t val = static_cast<int32_t>(inst->VRegB_21h() << 16);
403 shadow_frame.SetVReg(dst, val);
404 if (val == 0) {
405 shadow_frame.SetVRegReference(dst, NULL);
406 }
407 ADVANCE(2);
408 }
409 HANDLE_INSTRUCTION_END();
410
411 HANDLE_INSTRUCTION_START(CONST_WIDE_16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200412 shadow_frame.SetVRegLong(inst->VRegA_21s(inst_data), inst->VRegB_21s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200413 ADVANCE(2);
414 HANDLE_INSTRUCTION_END();
415
416 HANDLE_INSTRUCTION_START(CONST_WIDE_32)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200417 shadow_frame.SetVRegLong(inst->VRegA_31i(inst_data), inst->VRegB_31i());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200418 ADVANCE(3);
419 HANDLE_INSTRUCTION_END();
420
421 HANDLE_INSTRUCTION_START(CONST_WIDE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200422 shadow_frame.SetVRegLong(inst->VRegA_51l(inst_data), inst->VRegB_51l());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200423 ADVANCE(5);
424 HANDLE_INSTRUCTION_END();
425
426 HANDLE_INSTRUCTION_START(CONST_WIDE_HIGH16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200427 shadow_frame.SetVRegLong(inst->VRegA_21h(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200428 static_cast<uint64_t>(inst->VRegB_21h()) << 48);
429 ADVANCE(2);
430 HANDLE_INSTRUCTION_END();
431
432 HANDLE_INSTRUCTION_START(CONST_STRING) {
433 String* s = ResolveString(self, mh, inst->VRegB_21c());
434 if (UNLIKELY(s == NULL)) {
435 HANDLE_PENDING_EXCEPTION();
436 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200437 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200438 ADVANCE(2);
439 }
440 }
441 HANDLE_INSTRUCTION_END();
442
443 HANDLE_INSTRUCTION_START(CONST_STRING_JUMBO) {
444 String* s = ResolveString(self, mh, inst->VRegB_31c());
445 if (UNLIKELY(s == NULL)) {
446 HANDLE_PENDING_EXCEPTION();
447 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200448 shadow_frame.SetVRegReference(inst->VRegA_31c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200449 ADVANCE(3);
450 }
451 }
452 HANDLE_INSTRUCTION_END();
453
454 HANDLE_INSTRUCTION_START(CONST_CLASS) {
455 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
456 self, false, do_access_check);
457 if (UNLIKELY(c == NULL)) {
458 HANDLE_PENDING_EXCEPTION();
459 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200460 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), c);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200461 ADVANCE(2);
462 }
463 }
464 HANDLE_INSTRUCTION_END();
465
466 HANDLE_INSTRUCTION_START(MONITOR_ENTER) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200467 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200468 if (UNLIKELY(obj == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +0200469 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200470 HANDLE_PENDING_EXCEPTION();
471 } else {
472 DoMonitorEnter(self, obj);
473 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), 1);
474 }
475 }
476 HANDLE_INSTRUCTION_END();
477
478 HANDLE_INSTRUCTION_START(MONITOR_EXIT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200479 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200480 if (UNLIKELY(obj == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +0200481 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200482 HANDLE_PENDING_EXCEPTION();
483 } else {
484 DoMonitorExit(self, obj);
485 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), 1);
486 }
487 }
488 HANDLE_INSTRUCTION_END();
489
490 HANDLE_INSTRUCTION_START(CHECK_CAST) {
491 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
492 self, false, do_access_check);
493 if (UNLIKELY(c == NULL)) {
494 HANDLE_PENDING_EXCEPTION();
495 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200496 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_21c(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200497 if (UNLIKELY(obj != NULL && !obj->InstanceOf(c))) {
498 ThrowClassCastException(c, obj->GetClass());
499 HANDLE_PENDING_EXCEPTION();
500 } else {
501 ADVANCE(2);
502 }
503 }
504 }
505 HANDLE_INSTRUCTION_END();
506
507 HANDLE_INSTRUCTION_START(INSTANCE_OF) {
508 Class* c = ResolveVerifyAndClinit(inst->VRegC_22c(), shadow_frame.GetMethod(),
509 self, false, do_access_check);
510 if (UNLIKELY(c == NULL)) {
511 HANDLE_PENDING_EXCEPTION();
512 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200513 Object* obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data));
514 shadow_frame.SetVReg(inst->VRegA_22c(inst_data), (obj != NULL && obj->InstanceOf(c)) ? 1 : 0);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200515 ADVANCE(2);
516 }
517 }
518 HANDLE_INSTRUCTION_END();
519
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700520 HANDLE_INSTRUCTION_START(ARRAY_LENGTH) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200521 Object* array = shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200522 if (UNLIKELY(array == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +0200523 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200524 HANDLE_PENDING_EXCEPTION();
525 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200526 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), array->AsArray()->GetLength());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200527 ADVANCE(1);
528 }
529 }
530 HANDLE_INSTRUCTION_END();
531
532 HANDLE_INSTRUCTION_START(NEW_INSTANCE) {
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700533 Runtime* runtime = Runtime::Current();
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800534 Object* obj = AllocObjectFromCode<do_access_check, true>(
535 inst->VRegB_21c(), shadow_frame.GetMethod(), self,
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700536 runtime->GetHeap()->GetCurrentAllocator());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200537 if (UNLIKELY(obj == NULL)) {
538 HANDLE_PENDING_EXCEPTION();
539 } else {
Sebastien Hertz4e99b3d2014-06-24 14:35:40 +0200540 obj->GetClass()->AssertInitializedOrInitializingInThread(self);
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700541 // Don't allow finalizable objects to be allocated during a transaction since these can't be
542 // finalized without a started runtime.
543 if (transaction_active && obj->GetClass()->IsFinalizable()) {
Ian Rogers2fa98e22014-05-06 15:26:39 -0700544 AbortTransaction(self, "Allocating finalizable object in transaction: %s",
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700545 PrettyTypeOf(obj).c_str());
546 HANDLE_PENDING_EXCEPTION();
547 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200548 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200549 ADVANCE(2);
550 }
551 }
552 HANDLE_INSTRUCTION_END();
553
554 HANDLE_INSTRUCTION_START(NEW_ARRAY) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200555 int32_t length = shadow_frame.GetVReg(inst->VRegB_22c(inst_data));
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800556 Object* obj = AllocArrayFromCode<do_access_check, true>(
557 inst->VRegC_22c(), shadow_frame.GetMethod(), length, self,
558 Runtime::Current()->GetHeap()->GetCurrentAllocator());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200559 if (UNLIKELY(obj == NULL)) {
560 HANDLE_PENDING_EXCEPTION();
561 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200562 shadow_frame.SetVRegReference(inst->VRegA_22c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200563 ADVANCE(2);
564 }
565 }
566 HANDLE_INSTRUCTION_END();
567
568 HANDLE_INSTRUCTION_START(FILLED_NEW_ARRAY) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100569 bool success =
570 DoFilledNewArray<false, do_access_check, transaction_active>(inst, shadow_frame,
571 self, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200572 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
573 }
574 HANDLE_INSTRUCTION_END();
575
576 HANDLE_INSTRUCTION_START(FILLED_NEW_ARRAY_RANGE) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100577 bool success =
578 DoFilledNewArray<true, do_access_check, transaction_active>(inst, shadow_frame,
579 self, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200580 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
581 }
582 HANDLE_INSTRUCTION_END();
583
584 HANDLE_INSTRUCTION_START(FILL_ARRAY_DATA) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200585 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_31t(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200586 if (UNLIKELY(obj == NULL)) {
587 ThrowNullPointerException(NULL, "null array in FILL_ARRAY_DATA");
588 HANDLE_PENDING_EXCEPTION();
589 } else {
590 Array* array = obj->AsArray();
591 DCHECK(array->IsArrayInstance() && !array->IsObjectArray());
592 const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t();
593 const Instruction::ArrayDataPayload* payload =
594 reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr);
595 if (UNLIKELY(static_cast<int32_t>(payload->element_count) > array->GetLength())) {
596 self->ThrowNewExceptionF(shadow_frame.GetCurrentLocationForThrow(),
597 "Ljava/lang/ArrayIndexOutOfBoundsException;",
598 "failed FILL_ARRAY_DATA; length=%d, index=%d",
599 array->GetLength(), payload->element_count);
600 HANDLE_PENDING_EXCEPTION();
601 } else {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100602 if (transaction_active) {
603 RecordArrayElementsInTransaction(array, payload->element_count);
604 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200605 uint32_t size_in_bytes = payload->element_count * payload->element_width;
Ian Rogersef7d42f2014-01-06 12:55:46 -0800606 memcpy(array->GetRawData(payload->element_width, 0), payload->data, size_in_bytes);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200607 ADVANCE(3);
608 }
609 }
610 }
611 HANDLE_INSTRUCTION_END();
612
613 HANDLE_INSTRUCTION_START(THROW) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200614 Object* exception = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200615 if (UNLIKELY(exception == NULL)) {
616 ThrowNullPointerException(NULL, "throw with null exception");
Jeff Haoa3faaf42013-09-03 19:07:00 -0700617 } else if (do_assignability_check && !exception->GetClass()->IsThrowableClass()) {
618 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700619 std::string temp;
Jeff Haoa3faaf42013-09-03 19:07:00 -0700620 self->ThrowNewExceptionF(self->GetCurrentLocationForThrow(),
621 "Ljava/lang/VirtualMachineError;",
622 "Throwing '%s' that is not instance of Throwable",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700623 exception->GetClass()->GetDescriptor(&temp));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200624 } else {
625 self->SetException(shadow_frame.GetCurrentLocationForThrow(), exception->AsThrowable());
626 }
627 HANDLE_PENDING_EXCEPTION();
628 }
629 HANDLE_INSTRUCTION_END();
630
631 HANDLE_INSTRUCTION_START(GOTO) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200632 int8_t offset = inst->VRegA_10t(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200633 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200634 if (UNLIKELY(self->TestAllFlags())) {
635 CheckSuspend(self);
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200636 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200637 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200638 }
639 ADVANCE(offset);
640 }
641 HANDLE_INSTRUCTION_END();
642
643 HANDLE_INSTRUCTION_START(GOTO_16) {
644 int16_t offset = inst->VRegA_20t();
645 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200646 if (UNLIKELY(self->TestAllFlags())) {
647 CheckSuspend(self);
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200648 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200649 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200650 }
651 ADVANCE(offset);
652 }
653 HANDLE_INSTRUCTION_END();
654
655 HANDLE_INSTRUCTION_START(GOTO_32) {
656 int32_t offset = inst->VRegA_30t();
657 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200658 if (UNLIKELY(self->TestAllFlags())) {
659 CheckSuspend(self);
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200660 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200661 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200662 }
663 ADVANCE(offset);
664 }
665 HANDLE_INSTRUCTION_END();
666
667 HANDLE_INSTRUCTION_START(PACKED_SWITCH) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200668 int32_t offset = DoPackedSwitch(inst, shadow_frame, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200669 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200670 if (UNLIKELY(self->TestAllFlags())) {
671 CheckSuspend(self);
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200672 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200673 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200674 }
675 ADVANCE(offset);
676 }
677 HANDLE_INSTRUCTION_END();
678
679 HANDLE_INSTRUCTION_START(SPARSE_SWITCH) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200680 int32_t offset = DoSparseSwitch(inst, shadow_frame, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200681 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200682 if (UNLIKELY(self->TestAllFlags())) {
683 CheckSuspend(self);
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200684 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200685 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200686 }
687 ADVANCE(offset);
688 }
689 HANDLE_INSTRUCTION_END();
690
691 HANDLE_INSTRUCTION_START(CMPL_FLOAT) {
692 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
693 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
694 int32_t result;
695 if (val1 > val2) {
696 result = 1;
697 } else if (val1 == val2) {
698 result = 0;
699 } else {
700 result = -1;
701 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200702 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200703 ADVANCE(2);
704 }
705 HANDLE_INSTRUCTION_END();
706
707 HANDLE_INSTRUCTION_START(CMPG_FLOAT) {
708 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
709 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
710 int32_t result;
711 if (val1 < val2) {
712 result = -1;
713 } else if (val1 == val2) {
714 result = 0;
715 } else {
716 result = 1;
717 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200718 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200719 ADVANCE(2);
720 }
721 HANDLE_INSTRUCTION_END();
722
723 HANDLE_INSTRUCTION_START(CMPL_DOUBLE) {
724 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
725 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
726 int32_t result;
727 if (val1 > val2) {
728 result = 1;
729 } else if (val1 == val2) {
730 result = 0;
731 } else {
732 result = -1;
733 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200734 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200735 ADVANCE(2);
736 }
737 HANDLE_INSTRUCTION_END();
738
739 HANDLE_INSTRUCTION_START(CMPG_DOUBLE) {
740 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
741 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
742 int32_t result;
743 if (val1 < val2) {
744 result = -1;
745 } else if (val1 == val2) {
746 result = 0;
747 } else {
748 result = 1;
749 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200750 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200751 ADVANCE(2);
752 }
753 HANDLE_INSTRUCTION_END();
754
755 HANDLE_INSTRUCTION_START(CMP_LONG) {
756 int64_t val1 = shadow_frame.GetVRegLong(inst->VRegB_23x());
757 int64_t val2 = shadow_frame.GetVRegLong(inst->VRegC_23x());
758 int32_t result;
759 if (val1 > val2) {
760 result = 1;
761 } else if (val1 == val2) {
762 result = 0;
763 } else {
764 result = -1;
765 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200766 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200767 ADVANCE(2);
768 }
769 HANDLE_INSTRUCTION_END();
770
771 HANDLE_INSTRUCTION_START(IF_EQ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200772 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) == shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200773 int16_t offset = inst->VRegC_22t();
774 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200775 if (UNLIKELY(self->TestAllFlags())) {
776 CheckSuspend(self);
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200777 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200778 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200779 }
780 ADVANCE(offset);
781 } else {
782 ADVANCE(2);
783 }
784 }
785 HANDLE_INSTRUCTION_END();
786
787 HANDLE_INSTRUCTION_START(IF_NE) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200788 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) != shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200789 int16_t offset = inst->VRegC_22t();
790 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200791 if (UNLIKELY(self->TestAllFlags())) {
792 CheckSuspend(self);
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200793 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200794 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200795 }
796 ADVANCE(offset);
797 } else {
798 ADVANCE(2);
799 }
800 }
801 HANDLE_INSTRUCTION_END();
802
803 HANDLE_INSTRUCTION_START(IF_LT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200804 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) < shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200805 int16_t offset = inst->VRegC_22t();
806 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200807 if (UNLIKELY(self->TestAllFlags())) {
808 CheckSuspend(self);
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200809 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200810 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200811 }
812 ADVANCE(offset);
813 } else {
814 ADVANCE(2);
815 }
816 }
817 HANDLE_INSTRUCTION_END();
818
819 HANDLE_INSTRUCTION_START(IF_GE) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200820 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >= shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200821 int16_t offset = inst->VRegC_22t();
822 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200823 if (UNLIKELY(self->TestAllFlags())) {
824 CheckSuspend(self);
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200825 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200826 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200827 }
828 ADVANCE(offset);
829 } else {
830 ADVANCE(2);
831 }
832 }
833 HANDLE_INSTRUCTION_END();
834
835 HANDLE_INSTRUCTION_START(IF_GT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200836 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) > shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200837 int16_t offset = inst->VRegC_22t();
838 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200839 if (UNLIKELY(self->TestAllFlags())) {
840 CheckSuspend(self);
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200841 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200842 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200843 }
844 ADVANCE(offset);
845 } else {
846 ADVANCE(2);
847 }
848 }
849 HANDLE_INSTRUCTION_END();
850
851 HANDLE_INSTRUCTION_START(IF_LE) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200852 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <= shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200853 int16_t offset = inst->VRegC_22t();
854 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200855 if (UNLIKELY(self->TestAllFlags())) {
856 CheckSuspend(self);
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200857 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200858 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200859 }
860 ADVANCE(offset);
861 } else {
862 ADVANCE(2);
863 }
864 }
865 HANDLE_INSTRUCTION_END();
866
867 HANDLE_INSTRUCTION_START(IF_EQZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200868 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) == 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200869 int16_t offset = inst->VRegB_21t();
870 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200871 if (UNLIKELY(self->TestAllFlags())) {
872 CheckSuspend(self);
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200873 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200874 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200875 }
876 ADVANCE(offset);
877 } else {
878 ADVANCE(2);
879 }
880 }
881 HANDLE_INSTRUCTION_END();
882
883 HANDLE_INSTRUCTION_START(IF_NEZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200884 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) != 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200885 int16_t offset = inst->VRegB_21t();
886 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200887 if (UNLIKELY(self->TestAllFlags())) {
888 CheckSuspend(self);
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200889 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200890 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200891 }
892 ADVANCE(offset);
893 } else {
894 ADVANCE(2);
895 }
896 }
897 HANDLE_INSTRUCTION_END();
898
899 HANDLE_INSTRUCTION_START(IF_LTZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200900 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) < 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200901 int16_t offset = inst->VRegB_21t();
902 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200903 if (UNLIKELY(self->TestAllFlags())) {
904 CheckSuspend(self);
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200905 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200906 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200907 }
908 ADVANCE(offset);
909 } else {
910 ADVANCE(2);
911 }
912 }
913 HANDLE_INSTRUCTION_END();
914
915 HANDLE_INSTRUCTION_START(IF_GEZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200916 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) >= 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200917 int16_t offset = inst->VRegB_21t();
918 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200919 if (UNLIKELY(self->TestAllFlags())) {
920 CheckSuspend(self);
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200921 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200922 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200923 }
924 ADVANCE(offset);
925 } else {
926 ADVANCE(2);
927 }
928 }
929 HANDLE_INSTRUCTION_END();
930
931 HANDLE_INSTRUCTION_START(IF_GTZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200932 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) > 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200933 int16_t offset = inst->VRegB_21t();
934 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200935 if (UNLIKELY(self->TestAllFlags())) {
936 CheckSuspend(self);
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200937 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200938 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200939 }
940 ADVANCE(offset);
941 } else {
942 ADVANCE(2);
943 }
944 }
945 HANDLE_INSTRUCTION_END();
946
947 HANDLE_INSTRUCTION_START(IF_LEZ) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200948 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) <= 0) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200949 int16_t offset = inst->VRegB_21t();
950 if (IsBackwardBranch(offset)) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200951 if (UNLIKELY(self->TestAllFlags())) {
952 CheckSuspend(self);
Sebastien Hertzee1997a2013-09-19 14:47:09 +0200953 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200954 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200955 }
956 ADVANCE(offset);
957 } else {
958 ADVANCE(2);
959 }
960 }
961 HANDLE_INSTRUCTION_END();
962
963 HANDLE_INSTRUCTION_START(AGET_BOOLEAN) {
964 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
965 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +0200966 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200967 HANDLE_PENDING_EXCEPTION();
968 } else {
969 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
970 BooleanArray* array = a->AsBooleanArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +0100971 if (LIKELY(array->CheckIsValidIndex(index))) {
972 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200973 ADVANCE(2);
974 } else {
975 HANDLE_PENDING_EXCEPTION();
976 }
977 }
978 }
979 HANDLE_INSTRUCTION_END();
980
981 HANDLE_INSTRUCTION_START(AGET_BYTE) {
982 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
983 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +0200984 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200985 HANDLE_PENDING_EXCEPTION();
986 } else {
987 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
988 ByteArray* array = a->AsByteArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +0100989 if (LIKELY(array->CheckIsValidIndex(index))) {
990 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200991 ADVANCE(2);
992 } else {
993 HANDLE_PENDING_EXCEPTION();
994 }
995 }
996 }
997 HANDLE_INSTRUCTION_END();
998
999 HANDLE_INSTRUCTION_START(AGET_CHAR) {
1000 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1001 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +02001002 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001003 HANDLE_PENDING_EXCEPTION();
1004 } else {
1005 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1006 CharArray* array = a->AsCharArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001007 if (LIKELY(array->CheckIsValidIndex(index))) {
1008 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001009 ADVANCE(2);
1010 } else {
1011 HANDLE_PENDING_EXCEPTION();
1012 }
1013 }
1014 }
1015 HANDLE_INSTRUCTION_END();
1016
1017 HANDLE_INSTRUCTION_START(AGET_SHORT) {
1018 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1019 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +02001020 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001021 HANDLE_PENDING_EXCEPTION();
1022 } else {
1023 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1024 ShortArray* array = a->AsShortArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001025 if (LIKELY(array->CheckIsValidIndex(index))) {
1026 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001027 ADVANCE(2);
1028 } else {
1029 HANDLE_PENDING_EXCEPTION();
1030 }
1031 }
1032 }
1033 HANDLE_INSTRUCTION_END();
1034
1035 HANDLE_INSTRUCTION_START(AGET) {
1036 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1037 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +02001038 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001039 HANDLE_PENDING_EXCEPTION();
1040 } else {
1041 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1042 IntArray* array = a->AsIntArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001043 if (LIKELY(array->CheckIsValidIndex(index))) {
1044 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001045 ADVANCE(2);
1046 } else {
1047 HANDLE_PENDING_EXCEPTION();
1048 }
1049 }
1050 }
1051 HANDLE_INSTRUCTION_END();
1052
1053 HANDLE_INSTRUCTION_START(AGET_WIDE) {
1054 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1055 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +02001056 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001057 HANDLE_PENDING_EXCEPTION();
1058 } else {
1059 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1060 LongArray* array = a->AsLongArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001061 if (LIKELY(array->CheckIsValidIndex(index))) {
1062 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001063 ADVANCE(2);
1064 } else {
1065 HANDLE_PENDING_EXCEPTION();
1066 }
1067 }
1068 }
1069 HANDLE_INSTRUCTION_END();
1070
1071 HANDLE_INSTRUCTION_START(AGET_OBJECT) {
1072 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1073 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +02001074 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001075 HANDLE_PENDING_EXCEPTION();
1076 } else {
1077 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1078 ObjectArray<Object>* array = a->AsObjectArray<Object>();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001079 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001080 shadow_frame.SetVRegReference(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001081 ADVANCE(2);
1082 } else {
1083 HANDLE_PENDING_EXCEPTION();
1084 }
1085 }
1086 }
1087 HANDLE_INSTRUCTION_END();
1088
1089 HANDLE_INSTRUCTION_START(APUT_BOOLEAN) {
1090 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1091 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +02001092 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001093 HANDLE_PENDING_EXCEPTION();
1094 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001095 uint8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001096 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1097 BooleanArray* array = a->AsBooleanArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001098 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001099 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001100 ADVANCE(2);
1101 } else {
1102 HANDLE_PENDING_EXCEPTION();
1103 }
1104 }
1105 }
1106 HANDLE_INSTRUCTION_END();
1107
1108 HANDLE_INSTRUCTION_START(APUT_BYTE) {
1109 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1110 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +02001111 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001112 HANDLE_PENDING_EXCEPTION();
1113 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001114 int8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001115 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1116 ByteArray* array = a->AsByteArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001117 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001118 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001119 ADVANCE(2);
1120 } else {
1121 HANDLE_PENDING_EXCEPTION();
1122 }
1123 }
1124 }
1125 HANDLE_INSTRUCTION_END();
1126
1127 HANDLE_INSTRUCTION_START(APUT_CHAR) {
1128 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1129 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +02001130 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001131 HANDLE_PENDING_EXCEPTION();
1132 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001133 uint16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001134 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1135 CharArray* array = a->AsCharArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001136 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001137 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001138 ADVANCE(2);
1139 } else {
1140 HANDLE_PENDING_EXCEPTION();
1141 }
1142 }
1143 }
1144 HANDLE_INSTRUCTION_END();
1145
1146 HANDLE_INSTRUCTION_START(APUT_SHORT) {
1147 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1148 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +02001149 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001150 HANDLE_PENDING_EXCEPTION();
1151 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001152 int16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001153 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1154 ShortArray* array = a->AsShortArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001155 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001156 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001157 ADVANCE(2);
1158 } else {
1159 HANDLE_PENDING_EXCEPTION();
1160 }
1161 }
1162 }
1163 HANDLE_INSTRUCTION_END();
1164
1165 HANDLE_INSTRUCTION_START(APUT) {
1166 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1167 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +02001168 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001169 HANDLE_PENDING_EXCEPTION();
1170 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001171 int32_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001172 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1173 IntArray* array = a->AsIntArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001174 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001175 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001176 ADVANCE(2);
1177 } else {
1178 HANDLE_PENDING_EXCEPTION();
1179 }
1180 }
1181 }
1182 HANDLE_INSTRUCTION_END();
1183
1184 HANDLE_INSTRUCTION_START(APUT_WIDE) {
1185 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1186 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +02001187 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001188 HANDLE_PENDING_EXCEPTION();
1189 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001190 int64_t val = shadow_frame.GetVRegLong(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001191 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1192 LongArray* array = a->AsLongArray();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001193 if (LIKELY(array->CheckIsValidIndex(index))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001194 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001195 ADVANCE(2);
1196 } else {
1197 HANDLE_PENDING_EXCEPTION();
1198 }
1199 }
1200 }
1201 HANDLE_INSTRUCTION_END();
1202
1203 HANDLE_INSTRUCTION_START(APUT_OBJECT) {
1204 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
1205 if (UNLIKELY(a == NULL)) {
Sebastien Hertzda843e12014-05-28 19:28:31 +02001206 ThrowNullPointerExceptionFromInterpreter(shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001207 HANDLE_PENDING_EXCEPTION();
1208 } else {
1209 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001210 Object* val = shadow_frame.GetVRegReference(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001211 ObjectArray<Object>* array = a->AsObjectArray<Object>();
Sebastien Hertzabff6432014-01-27 18:01:39 +01001212 if (LIKELY(array->CheckIsValidIndex(index) && array->CheckAssignable(val))) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001213 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001214 ADVANCE(2);
1215 } else {
1216 HANDLE_PENDING_EXCEPTION();
1217 }
1218 }
1219 }
1220 HANDLE_INSTRUCTION_END();
1221
1222 HANDLE_INSTRUCTION_START(IGET_BOOLEAN) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001223 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimBoolean, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001224 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1225 }
1226 HANDLE_INSTRUCTION_END();
1227
1228 HANDLE_INSTRUCTION_START(IGET_BYTE) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001229 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimByte, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001230 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1231 }
1232 HANDLE_INSTRUCTION_END();
1233
1234 HANDLE_INSTRUCTION_START(IGET_CHAR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001235 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimChar, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001236 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1237 }
1238 HANDLE_INSTRUCTION_END();
1239
1240 HANDLE_INSTRUCTION_START(IGET_SHORT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001241 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimShort, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001242 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1243 }
1244 HANDLE_INSTRUCTION_END();
1245
1246 HANDLE_INSTRUCTION_START(IGET) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001247 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimInt, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001248 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1249 }
1250 HANDLE_INSTRUCTION_END();
1251
1252 HANDLE_INSTRUCTION_START(IGET_WIDE) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001253 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimLong, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001254 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1255 }
1256 HANDLE_INSTRUCTION_END();
1257
1258 HANDLE_INSTRUCTION_START(IGET_OBJECT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001259 bool success = DoFieldGet<InstanceObjectRead, Primitive::kPrimNot, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001260 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1261 }
1262 HANDLE_INSTRUCTION_END();
1263
1264 HANDLE_INSTRUCTION_START(IGET_QUICK) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001265 bool success = DoIGetQuick<Primitive::kPrimInt>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001266 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1267 }
1268 HANDLE_INSTRUCTION_END();
1269
1270 HANDLE_INSTRUCTION_START(IGET_WIDE_QUICK) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001271 bool success = DoIGetQuick<Primitive::kPrimLong>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001272 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1273 }
1274 HANDLE_INSTRUCTION_END();
1275
1276 HANDLE_INSTRUCTION_START(IGET_OBJECT_QUICK) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001277 bool success = DoIGetQuick<Primitive::kPrimNot>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001278 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1279 }
1280 HANDLE_INSTRUCTION_END();
1281
1282 HANDLE_INSTRUCTION_START(SGET_BOOLEAN) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001283 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimBoolean, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001284 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1285 }
1286 HANDLE_INSTRUCTION_END();
1287
1288 HANDLE_INSTRUCTION_START(SGET_BYTE) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001289 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimByte, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001290 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1291 }
1292 HANDLE_INSTRUCTION_END();
1293
1294 HANDLE_INSTRUCTION_START(SGET_CHAR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001295 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimChar, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001296 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1297 }
1298 HANDLE_INSTRUCTION_END();
1299
1300 HANDLE_INSTRUCTION_START(SGET_SHORT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001301 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimShort, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001302 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1303 }
1304 HANDLE_INSTRUCTION_END();
1305
1306 HANDLE_INSTRUCTION_START(SGET) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001307 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimInt, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001308 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1309 }
1310 HANDLE_INSTRUCTION_END();
1311
1312 HANDLE_INSTRUCTION_START(SGET_WIDE) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001313 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimLong, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001314 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1315 }
1316 HANDLE_INSTRUCTION_END();
1317
1318 HANDLE_INSTRUCTION_START(SGET_OBJECT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001319 bool success = DoFieldGet<StaticObjectRead, Primitive::kPrimNot, do_access_check>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001320 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1321 }
1322 HANDLE_INSTRUCTION_END();
1323
1324 HANDLE_INSTRUCTION_START(IPUT_BOOLEAN) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001325 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimBoolean, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001326 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1327 }
1328 HANDLE_INSTRUCTION_END();
1329
1330 HANDLE_INSTRUCTION_START(IPUT_BYTE) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001331 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimByte, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001332 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1333 }
1334 HANDLE_INSTRUCTION_END();
1335
1336 HANDLE_INSTRUCTION_START(IPUT_CHAR) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001337 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimChar, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001338 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1339 }
1340 HANDLE_INSTRUCTION_END();
1341
1342 HANDLE_INSTRUCTION_START(IPUT_SHORT) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001343 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimShort, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001344 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1345 }
1346 HANDLE_INSTRUCTION_END();
1347
1348 HANDLE_INSTRUCTION_START(IPUT) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001349 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimInt, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001350 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1351 }
1352 HANDLE_INSTRUCTION_END();
1353
1354 HANDLE_INSTRUCTION_START(IPUT_WIDE) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001355 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimLong, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001356 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1357 }
1358 HANDLE_INSTRUCTION_END();
1359
1360 HANDLE_INSTRUCTION_START(IPUT_OBJECT) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001361 bool success = DoFieldPut<InstanceObjectWrite, Primitive::kPrimNot, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001362 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1363 }
1364 HANDLE_INSTRUCTION_END();
1365
1366 HANDLE_INSTRUCTION_START(IPUT_QUICK) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001367 bool success = DoIPutQuick<Primitive::kPrimInt, transaction_active>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001368 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1369 }
1370 HANDLE_INSTRUCTION_END();
1371
Fred Shih37f05ef2014-07-16 18:38:08 -07001372 HANDLE_INSTRUCTION_START(IPUT_BOOLEAN_QUICK) {
1373 bool success = DoIPutQuick<Primitive::kPrimBoolean, transaction_active>(shadow_frame, inst, inst_data);
1374 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1375 }
1376 HANDLE_INSTRUCTION_END();
1377
1378 HANDLE_INSTRUCTION_START(IPUT_BYTE_QUICK) {
1379 bool success = DoIPutQuick<Primitive::kPrimByte, transaction_active>(shadow_frame, inst, inst_data);
1380 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1381 }
1382 HANDLE_INSTRUCTION_END();
1383
1384 HANDLE_INSTRUCTION_START(IPUT_CHAR_QUICK) {
1385 bool success = DoIPutQuick<Primitive::kPrimChar, transaction_active>(shadow_frame, inst, inst_data);
1386 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1387 }
1388 HANDLE_INSTRUCTION_END();
1389
1390 HANDLE_INSTRUCTION_START(IPUT_SHORT_QUICK) {
1391 bool success = DoIPutQuick<Primitive::kPrimShort, transaction_active>(shadow_frame, inst, inst_data);
1392 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1393 }
1394 HANDLE_INSTRUCTION_END();
1395
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001396 HANDLE_INSTRUCTION_START(IPUT_WIDE_QUICK) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001397 bool success = DoIPutQuick<Primitive::kPrimLong, transaction_active>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001398 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1399 }
1400 HANDLE_INSTRUCTION_END();
1401
1402 HANDLE_INSTRUCTION_START(IPUT_OBJECT_QUICK) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001403 bool success = DoIPutQuick<Primitive::kPrimNot, transaction_active>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001404 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1405 }
1406 HANDLE_INSTRUCTION_END();
1407
1408 HANDLE_INSTRUCTION_START(SPUT_BOOLEAN) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001409 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimBoolean, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001410 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1411 }
1412 HANDLE_INSTRUCTION_END();
1413
1414 HANDLE_INSTRUCTION_START(SPUT_BYTE) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001415 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimByte, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001416 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1417 }
1418 HANDLE_INSTRUCTION_END();
1419
1420 HANDLE_INSTRUCTION_START(SPUT_CHAR) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001421 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimChar, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001422 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1423 }
1424 HANDLE_INSTRUCTION_END();
1425
1426 HANDLE_INSTRUCTION_START(SPUT_SHORT) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001427 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimShort, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001428 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1429 }
1430 HANDLE_INSTRUCTION_END();
1431
1432 HANDLE_INSTRUCTION_START(SPUT) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001433 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimInt, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001434 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1435 }
1436 HANDLE_INSTRUCTION_END();
1437
1438 HANDLE_INSTRUCTION_START(SPUT_WIDE) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001439 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimLong, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001440 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1441 }
1442 HANDLE_INSTRUCTION_END();
1443
1444 HANDLE_INSTRUCTION_START(SPUT_OBJECT) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001445 bool success = DoFieldPut<StaticObjectWrite, Primitive::kPrimNot, do_access_check, transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001446 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1447 }
1448 HANDLE_INSTRUCTION_END();
1449
1450 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL) {
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001451 bool success = DoInvoke<kVirtual, false, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001452 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001453 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1454 }
1455 HANDLE_INSTRUCTION_END();
1456
1457 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_RANGE) {
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001458 bool success = DoInvoke<kVirtual, true, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001459 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001460 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1461 }
1462 HANDLE_INSTRUCTION_END();
1463
1464 HANDLE_INSTRUCTION_START(INVOKE_SUPER) {
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001465 bool success = DoInvoke<kSuper, false, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001466 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001467 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1468 }
1469 HANDLE_INSTRUCTION_END();
1470
1471 HANDLE_INSTRUCTION_START(INVOKE_SUPER_RANGE) {
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001472 bool success = DoInvoke<kSuper, true, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001473 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001474 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1475 }
1476 HANDLE_INSTRUCTION_END();
1477
1478 HANDLE_INSTRUCTION_START(INVOKE_DIRECT) {
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001479 bool success = DoInvoke<kDirect, false, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001480 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001481 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1482 }
1483 HANDLE_INSTRUCTION_END();
1484
1485 HANDLE_INSTRUCTION_START(INVOKE_DIRECT_RANGE) {
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001486 bool success = DoInvoke<kDirect, true, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001487 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001488 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1489 }
1490 HANDLE_INSTRUCTION_END();
1491
1492 HANDLE_INSTRUCTION_START(INVOKE_INTERFACE) {
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001493 bool success = DoInvoke<kInterface, false, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001494 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001495 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1496 }
1497 HANDLE_INSTRUCTION_END();
1498
1499 HANDLE_INSTRUCTION_START(INVOKE_INTERFACE_RANGE) {
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001500 bool success = DoInvoke<kInterface, true, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001501 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001502 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1503 }
1504 HANDLE_INSTRUCTION_END();
1505
1506 HANDLE_INSTRUCTION_START(INVOKE_STATIC) {
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001507 bool success = DoInvoke<kStatic, false, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001508 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001509 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1510 }
1511 HANDLE_INSTRUCTION_END();
1512
1513 HANDLE_INSTRUCTION_START(INVOKE_STATIC_RANGE) {
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001514 bool success = DoInvoke<kStatic, true, do_access_check>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001515 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001516 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1517 }
1518 HANDLE_INSTRUCTION_END();
1519
1520 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_QUICK) {
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001521 bool success = DoInvokeVirtualQuick<false>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001522 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001523 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1524 }
1525 HANDLE_INSTRUCTION_END();
1526
1527 HANDLE_INSTRUCTION_START(INVOKE_VIRTUAL_RANGE_QUICK) {
Sebastien Hertzc61124b2013-09-10 11:44:19 +02001528 bool success = DoInvokeVirtualQuick<true>(self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertzcdf2d4c2013-09-13 14:57:51 +02001529 UPDATE_HANDLER_TABLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001530 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 3);
1531 }
1532 HANDLE_INSTRUCTION_END();
1533
1534 HANDLE_INSTRUCTION_START(NEG_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001535 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), -shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001536 ADVANCE(1);
1537 HANDLE_INSTRUCTION_END();
1538
1539 HANDLE_INSTRUCTION_START(NOT_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001540 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), ~shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001541 ADVANCE(1);
1542 HANDLE_INSTRUCTION_END();
1543
1544 HANDLE_INSTRUCTION_START(NEG_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001545 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), -shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001546 ADVANCE(1);
1547 HANDLE_INSTRUCTION_END();
1548
1549 HANDLE_INSTRUCTION_START(NOT_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001550 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), ~shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001551 ADVANCE(1);
1552 HANDLE_INSTRUCTION_END();
1553
1554 HANDLE_INSTRUCTION_START(NEG_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001555 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data), -shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001556 ADVANCE(1);
1557 HANDLE_INSTRUCTION_END();
1558
1559 HANDLE_INSTRUCTION_START(NEG_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001560 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data), -shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001561 ADVANCE(1);
1562 HANDLE_INSTRUCTION_END();
1563
1564 HANDLE_INSTRUCTION_START(INT_TO_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001565 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001566 ADVANCE(1);
1567 HANDLE_INSTRUCTION_END();
1568
1569 HANDLE_INSTRUCTION_START(INT_TO_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001570 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data), shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001571 ADVANCE(1);
1572 HANDLE_INSTRUCTION_END();
1573
1574 HANDLE_INSTRUCTION_START(INT_TO_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001575 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data), shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001576 ADVANCE(1);
1577 HANDLE_INSTRUCTION_END();
1578
1579 HANDLE_INSTRUCTION_START(LONG_TO_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001580 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001581 ADVANCE(1);
1582 HANDLE_INSTRUCTION_END();
1583
1584 HANDLE_INSTRUCTION_START(LONG_TO_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001585 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data), shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001586 ADVANCE(1);
1587 HANDLE_INSTRUCTION_END();
1588
1589 HANDLE_INSTRUCTION_START(LONG_TO_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001590 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data), shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001591 ADVANCE(1);
1592 HANDLE_INSTRUCTION_END();
1593
1594 HANDLE_INSTRUCTION_START(FLOAT_TO_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001595 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001596 int32_t result = art_float_to_integral<int32_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001597 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001598 ADVANCE(1);
1599 }
1600 HANDLE_INSTRUCTION_END();
1601
1602 HANDLE_INSTRUCTION_START(FLOAT_TO_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001603 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001604 int64_t result = art_float_to_integral<int64_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001605 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001606 ADVANCE(1);
1607 }
1608 HANDLE_INSTRUCTION_END();
1609
1610 HANDLE_INSTRUCTION_START(FLOAT_TO_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001611 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data), shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001612 ADVANCE(1);
1613 HANDLE_INSTRUCTION_END();
1614
1615 HANDLE_INSTRUCTION_START(DOUBLE_TO_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001616 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001617 int32_t result = art_float_to_integral<int32_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001618 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001619 ADVANCE(1);
1620 }
1621 HANDLE_INSTRUCTION_END();
1622
1623 HANDLE_INSTRUCTION_START(DOUBLE_TO_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001624 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001625 int64_t result = art_float_to_integral<int64_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001626 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001627 ADVANCE(1);
1628 }
1629 HANDLE_INSTRUCTION_END();
1630
1631 HANDLE_INSTRUCTION_START(DOUBLE_TO_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001632 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data), shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001633 ADVANCE(1);
1634 HANDLE_INSTRUCTION_END();
1635
1636 HANDLE_INSTRUCTION_START(INT_TO_BYTE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001637 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1638 static_cast<int8_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001639 ADVANCE(1);
1640 HANDLE_INSTRUCTION_END();
1641
1642 HANDLE_INSTRUCTION_START(INT_TO_CHAR)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001643 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1644 static_cast<uint16_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001645 ADVANCE(1);
1646 HANDLE_INSTRUCTION_END();
1647
1648 HANDLE_INSTRUCTION_START(INT_TO_SHORT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001649 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1650 static_cast<int16_t>(shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001651 ADVANCE(1);
1652 HANDLE_INSTRUCTION_END();
1653
1654 HANDLE_INSTRUCTION_START(ADD_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001655 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001656 shadow_frame.GetVReg(inst->VRegB_23x()) +
1657 shadow_frame.GetVReg(inst->VRegC_23x()));
1658 ADVANCE(2);
1659 HANDLE_INSTRUCTION_END();
1660
1661 HANDLE_INSTRUCTION_START(SUB_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001662 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001663 shadow_frame.GetVReg(inst->VRegB_23x()) -
1664 shadow_frame.GetVReg(inst->VRegC_23x()));
1665 ADVANCE(2);
1666 HANDLE_INSTRUCTION_END();
1667
1668 HANDLE_INSTRUCTION_START(MUL_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001669 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001670 shadow_frame.GetVReg(inst->VRegB_23x()) *
1671 shadow_frame.GetVReg(inst->VRegC_23x()));
1672 ADVANCE(2);
1673 HANDLE_INSTRUCTION_END();
1674
1675 HANDLE_INSTRUCTION_START(DIV_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001676 bool success = DoIntDivide(shadow_frame, inst->VRegA_23x(inst_data),
1677 shadow_frame.GetVReg(inst->VRegB_23x()),
1678 shadow_frame.GetVReg(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001679 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1680 }
1681 HANDLE_INSTRUCTION_END();
1682
1683 HANDLE_INSTRUCTION_START(REM_INT) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001684 bool success = DoIntRemainder(shadow_frame, inst->VRegA_23x(inst_data),
1685 shadow_frame.GetVReg(inst->VRegB_23x()),
1686 shadow_frame.GetVReg(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001687 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1688 }
1689 HANDLE_INSTRUCTION_END();
1690
1691 HANDLE_INSTRUCTION_START(SHL_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001692 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001693 shadow_frame.GetVReg(inst->VRegB_23x()) <<
1694 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1695 ADVANCE(2);
1696 HANDLE_INSTRUCTION_END();
1697
1698 HANDLE_INSTRUCTION_START(SHR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001699 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001700 shadow_frame.GetVReg(inst->VRegB_23x()) >>
1701 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1702 ADVANCE(2);
1703 HANDLE_INSTRUCTION_END();
1704
1705 HANDLE_INSTRUCTION_START(USHR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001706 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001707 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_23x())) >>
1708 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1709 ADVANCE(2);
1710 HANDLE_INSTRUCTION_END();
1711
1712 HANDLE_INSTRUCTION_START(AND_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001713 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001714 shadow_frame.GetVReg(inst->VRegB_23x()) &
1715 shadow_frame.GetVReg(inst->VRegC_23x()));
1716 ADVANCE(2);
1717 HANDLE_INSTRUCTION_END();
1718
1719 HANDLE_INSTRUCTION_START(OR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001720 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001721 shadow_frame.GetVReg(inst->VRegB_23x()) |
1722 shadow_frame.GetVReg(inst->VRegC_23x()));
1723 ADVANCE(2);
1724 HANDLE_INSTRUCTION_END();
1725
1726 HANDLE_INSTRUCTION_START(XOR_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001727 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001728 shadow_frame.GetVReg(inst->VRegB_23x()) ^
1729 shadow_frame.GetVReg(inst->VRegC_23x()));
1730 ADVANCE(2);
1731 HANDLE_INSTRUCTION_END();
1732
1733 HANDLE_INSTRUCTION_START(ADD_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001734 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001735 shadow_frame.GetVRegLong(inst->VRegB_23x()) +
1736 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1737 ADVANCE(2);
1738 HANDLE_INSTRUCTION_END();
1739
1740 HANDLE_INSTRUCTION_START(SUB_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001741 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001742 shadow_frame.GetVRegLong(inst->VRegB_23x()) -
1743 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1744 ADVANCE(2);
1745 HANDLE_INSTRUCTION_END();
1746
1747 HANDLE_INSTRUCTION_START(MUL_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001748 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001749 shadow_frame.GetVRegLong(inst->VRegB_23x()) *
1750 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1751 ADVANCE(2);
1752 HANDLE_INSTRUCTION_END();
1753
1754 HANDLE_INSTRUCTION_START(DIV_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001755 bool success = DoLongDivide(shadow_frame, inst->VRegA_23x(inst_data),
1756 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1757 shadow_frame.GetVRegLong(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001758 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1759 }
1760 HANDLE_INSTRUCTION_END();
1761
1762 HANDLE_INSTRUCTION_START(REM_LONG) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001763 bool success = DoLongRemainder(shadow_frame, inst->VRegA_23x(inst_data),
1764 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1765 shadow_frame.GetVRegLong(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001766 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
1767 }
1768 HANDLE_INSTRUCTION_END();
1769
1770 HANDLE_INSTRUCTION_START(AND_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001771 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001772 shadow_frame.GetVRegLong(inst->VRegB_23x()) &
1773 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1774 ADVANCE(2);
1775 HANDLE_INSTRUCTION_END();
1776
1777 HANDLE_INSTRUCTION_START(OR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001778 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001779 shadow_frame.GetVRegLong(inst->VRegB_23x()) |
1780 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1781 ADVANCE(2);
1782 HANDLE_INSTRUCTION_END();
1783
1784 HANDLE_INSTRUCTION_START(XOR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001785 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001786 shadow_frame.GetVRegLong(inst->VRegB_23x()) ^
1787 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1788 ADVANCE(2);
1789 HANDLE_INSTRUCTION_END();
1790
1791 HANDLE_INSTRUCTION_START(SHL_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001792 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001793 shadow_frame.GetVRegLong(inst->VRegB_23x()) <<
1794 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1795 ADVANCE(2);
1796 HANDLE_INSTRUCTION_END();
1797
1798 HANDLE_INSTRUCTION_START(SHR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001799 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001800 shadow_frame.GetVRegLong(inst->VRegB_23x()) >>
1801 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1802 ADVANCE(2);
1803 HANDLE_INSTRUCTION_END();
1804
1805 HANDLE_INSTRUCTION_START(USHR_LONG)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001806 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001807 static_cast<uint64_t>(shadow_frame.GetVRegLong(inst->VRegB_23x())) >>
1808 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1809 ADVANCE(2);
1810 HANDLE_INSTRUCTION_END();
1811
1812 HANDLE_INSTRUCTION_START(ADD_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001813 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001814 shadow_frame.GetVRegFloat(inst->VRegB_23x()) +
1815 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1816 ADVANCE(2);
1817 HANDLE_INSTRUCTION_END();
1818
1819 HANDLE_INSTRUCTION_START(SUB_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001820 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001821 shadow_frame.GetVRegFloat(inst->VRegB_23x()) -
1822 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1823 ADVANCE(2);
1824 HANDLE_INSTRUCTION_END();
1825
1826 HANDLE_INSTRUCTION_START(MUL_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001827 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001828 shadow_frame.GetVRegFloat(inst->VRegB_23x()) *
1829 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1830 ADVANCE(2);
1831 HANDLE_INSTRUCTION_END();
1832
1833 HANDLE_INSTRUCTION_START(DIV_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001834 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001835 shadow_frame.GetVRegFloat(inst->VRegB_23x()) /
1836 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1837 ADVANCE(2);
1838 HANDLE_INSTRUCTION_END();
1839
1840 HANDLE_INSTRUCTION_START(REM_FLOAT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001841 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001842 fmodf(shadow_frame.GetVRegFloat(inst->VRegB_23x()),
1843 shadow_frame.GetVRegFloat(inst->VRegC_23x())));
1844 ADVANCE(2);
1845 HANDLE_INSTRUCTION_END();
1846
1847 HANDLE_INSTRUCTION_START(ADD_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001848 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001849 shadow_frame.GetVRegDouble(inst->VRegB_23x()) +
1850 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1851 ADVANCE(2);
1852 HANDLE_INSTRUCTION_END();
1853
1854 HANDLE_INSTRUCTION_START(SUB_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001855 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001856 shadow_frame.GetVRegDouble(inst->VRegB_23x()) -
1857 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1858 ADVANCE(2);
1859 HANDLE_INSTRUCTION_END();
1860
1861 HANDLE_INSTRUCTION_START(MUL_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001862 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001863 shadow_frame.GetVRegDouble(inst->VRegB_23x()) *
1864 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1865 ADVANCE(2);
1866 HANDLE_INSTRUCTION_END();
1867
1868 HANDLE_INSTRUCTION_START(DIV_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001869 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001870 shadow_frame.GetVRegDouble(inst->VRegB_23x()) /
1871 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1872 ADVANCE(2);
1873 HANDLE_INSTRUCTION_END();
1874
1875 HANDLE_INSTRUCTION_START(REM_DOUBLE)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001876 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001877 fmod(shadow_frame.GetVRegDouble(inst->VRegB_23x()),
1878 shadow_frame.GetVRegDouble(inst->VRegC_23x())));
1879 ADVANCE(2);
1880 HANDLE_INSTRUCTION_END();
1881
1882 HANDLE_INSTRUCTION_START(ADD_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001883 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001884 shadow_frame.SetVReg(vregA,
1885 shadow_frame.GetVReg(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001886 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001887 ADVANCE(1);
1888 }
1889 HANDLE_INSTRUCTION_END();
1890
1891 HANDLE_INSTRUCTION_START(SUB_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001892 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001893 shadow_frame.SetVReg(vregA,
1894 shadow_frame.GetVReg(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001895 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001896 ADVANCE(1);
1897 }
1898 HANDLE_INSTRUCTION_END();
1899
1900 HANDLE_INSTRUCTION_START(MUL_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001901 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001902 shadow_frame.SetVReg(vregA,
1903 shadow_frame.GetVReg(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001904 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001905 ADVANCE(1);
1906 }
1907 HANDLE_INSTRUCTION_END();
1908
1909 HANDLE_INSTRUCTION_START(DIV_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001910 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001911 bool success = DoIntDivide(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001912 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001913 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
1914 }
1915 HANDLE_INSTRUCTION_END();
1916
1917 HANDLE_INSTRUCTION_START(REM_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001918 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001919 bool success = DoIntRemainder(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001920 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001921 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
1922 }
1923 HANDLE_INSTRUCTION_END();
1924
1925 HANDLE_INSTRUCTION_START(SHL_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)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001930 ADVANCE(1);
1931 }
1932 HANDLE_INSTRUCTION_END();
1933
1934 HANDLE_INSTRUCTION_START(SHR_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)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001939 ADVANCE(1);
1940 }
1941 HANDLE_INSTRUCTION_END();
1942
1943 HANDLE_INSTRUCTION_START(USHR_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 static_cast<uint32_t>(shadow_frame.GetVReg(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001947 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001948 ADVANCE(1);
1949 }
1950 HANDLE_INSTRUCTION_END();
1951
1952 HANDLE_INSTRUCTION_START(AND_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001953 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001954 shadow_frame.SetVReg(vregA,
1955 shadow_frame.GetVReg(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001956 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001957 ADVANCE(1);
1958 }
1959 HANDLE_INSTRUCTION_END();
1960
1961 HANDLE_INSTRUCTION_START(OR_INT_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.SetVReg(vregA,
1964 shadow_frame.GetVReg(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001965 shadow_frame.GetVReg(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(XOR_INT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001971 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001972 shadow_frame.SetVReg(vregA,
1973 shadow_frame.GetVReg(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001974 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001975 ADVANCE(1);
1976 }
1977 HANDLE_INSTRUCTION_END();
1978
1979 HANDLE_INSTRUCTION_START(ADD_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001980 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001981 shadow_frame.SetVRegLong(vregA,
1982 shadow_frame.GetVRegLong(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001983 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001984 ADVANCE(1);
1985 }
1986 HANDLE_INSTRUCTION_END();
1987
1988 HANDLE_INSTRUCTION_START(SUB_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001989 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001990 shadow_frame.SetVRegLong(vregA,
1991 shadow_frame.GetVRegLong(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001992 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001993 ADVANCE(1);
1994 }
1995 HANDLE_INSTRUCTION_END();
1996
1997 HANDLE_INSTRUCTION_START(MUL_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001998 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001999 shadow_frame.SetVRegLong(vregA,
2000 shadow_frame.GetVRegLong(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002001 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002002 ADVANCE(1);
2003 }
2004 HANDLE_INSTRUCTION_END();
2005
2006 HANDLE_INSTRUCTION_START(DIV_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002007 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002008 bool success = DoLongDivide(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002009 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002010 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2011 }
2012 HANDLE_INSTRUCTION_END();
2013
2014 HANDLE_INSTRUCTION_START(REM_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002015 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002016 bool success = DoLongRemainder(shadow_frame, vregA, 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 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 1);
2019 }
2020 HANDLE_INSTRUCTION_END();
2021
2022 HANDLE_INSTRUCTION_START(AND_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002023 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002024 shadow_frame.SetVRegLong(vregA,
2025 shadow_frame.GetVRegLong(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002026 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002027 ADVANCE(1);
2028 }
2029 HANDLE_INSTRUCTION_END();
2030
2031 HANDLE_INSTRUCTION_START(OR_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.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002036 ADVANCE(1);
2037 }
2038 HANDLE_INSTRUCTION_END();
2039
2040 HANDLE_INSTRUCTION_START(XOR_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002041 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002042 shadow_frame.SetVRegLong(vregA,
2043 shadow_frame.GetVRegLong(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002044 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002045 ADVANCE(1);
2046 }
2047 HANDLE_INSTRUCTION_END();
2048
2049 HANDLE_INSTRUCTION_START(SHL_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002050 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002051 shadow_frame.SetVRegLong(vregA,
2052 shadow_frame.GetVRegLong(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002053 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002054 ADVANCE(1);
2055 }
2056 HANDLE_INSTRUCTION_END();
2057
2058 HANDLE_INSTRUCTION_START(SHR_LONG_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.SetVRegLong(vregA,
2061 shadow_frame.GetVRegLong(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002062 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002063 ADVANCE(1);
2064 }
2065 HANDLE_INSTRUCTION_END();
2066
2067 HANDLE_INSTRUCTION_START(USHR_LONG_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002068 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002069 shadow_frame.SetVRegLong(vregA,
2070 static_cast<uint64_t>(shadow_frame.GetVRegLong(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002071 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002072 ADVANCE(1);
2073 }
2074 HANDLE_INSTRUCTION_END();
2075
2076 HANDLE_INSTRUCTION_START(ADD_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(SUB_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002086 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002087 shadow_frame.SetVRegFloat(vregA,
2088 shadow_frame.GetVRegFloat(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002089 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002090 ADVANCE(1);
2091 }
2092 HANDLE_INSTRUCTION_END();
2093
2094 HANDLE_INSTRUCTION_START(MUL_FLOAT_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002095 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002096 shadow_frame.SetVRegFloat(vregA,
2097 shadow_frame.GetVRegFloat(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002098 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002099 ADVANCE(1);
2100 }
2101 HANDLE_INSTRUCTION_END();
2102
2103 HANDLE_INSTRUCTION_START(DIV_FLOAT_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.SetVRegFloat(vregA,
2106 shadow_frame.GetVRegFloat(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002107 shadow_frame.GetVRegFloat(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(REM_FLOAT_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.SetVRegFloat(vregA,
2115 fmodf(shadow_frame.GetVRegFloat(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002116 shadow_frame.GetVRegFloat(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(ADD_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(SUB_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002131 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002132 shadow_frame.SetVRegDouble(vregA,
2133 shadow_frame.GetVRegDouble(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002134 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002135 ADVANCE(1);
2136 }
2137 HANDLE_INSTRUCTION_END();
2138
2139 HANDLE_INSTRUCTION_START(MUL_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002140 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002141 shadow_frame.SetVRegDouble(vregA,
2142 shadow_frame.GetVRegDouble(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002143 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002144 ADVANCE(1);
2145 }
2146 HANDLE_INSTRUCTION_END();
2147
2148 HANDLE_INSTRUCTION_START(DIV_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002149 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002150 shadow_frame.SetVRegDouble(vregA,
2151 shadow_frame.GetVRegDouble(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002152 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002153 ADVANCE(1);
2154 }
2155 HANDLE_INSTRUCTION_END();
2156
2157 HANDLE_INSTRUCTION_START(REM_DOUBLE_2ADDR) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002158 uint32_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002159 shadow_frame.SetVRegDouble(vregA,
2160 fmod(shadow_frame.GetVRegDouble(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002161 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002162 ADVANCE(1);
2163 }
2164 HANDLE_INSTRUCTION_END();
2165
2166 HANDLE_INSTRUCTION_START(ADD_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002167 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2168 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) +
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002169 inst->VRegC_22s());
2170 ADVANCE(2);
2171 HANDLE_INSTRUCTION_END();
2172
2173 HANDLE_INSTRUCTION_START(RSUB_INT)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002174 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002175 inst->VRegC_22s() -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002176 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002177 ADVANCE(2);
2178 HANDLE_INSTRUCTION_END();
2179
2180 HANDLE_INSTRUCTION_START(MUL_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002181 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2182 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) *
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002183 inst->VRegC_22s());
2184 ADVANCE(2);
2185 HANDLE_INSTRUCTION_END();
2186
2187 HANDLE_INSTRUCTION_START(DIV_INT_LIT16) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002188 bool success = DoIntDivide(shadow_frame, inst->VRegA_22s(inst_data),
2189 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)), inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002190 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2191 }
2192 HANDLE_INSTRUCTION_END();
2193
2194 HANDLE_INSTRUCTION_START(REM_INT_LIT16) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002195 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22s(inst_data),
2196 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)), inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002197 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2198 }
2199 HANDLE_INSTRUCTION_END();
2200
2201 HANDLE_INSTRUCTION_START(AND_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002202 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2203 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) &
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002204 inst->VRegC_22s());
2205 ADVANCE(2);
2206 HANDLE_INSTRUCTION_END();
2207
2208 HANDLE_INSTRUCTION_START(OR_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002209 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2210 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) |
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002211 inst->VRegC_22s());
2212 ADVANCE(2);
2213 HANDLE_INSTRUCTION_END();
2214
2215 HANDLE_INSTRUCTION_START(XOR_INT_LIT16)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002216 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2217 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) ^
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002218 inst->VRegC_22s());
2219 ADVANCE(2);
2220 HANDLE_INSTRUCTION_END();
2221
2222 HANDLE_INSTRUCTION_START(ADD_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002223 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002224 shadow_frame.GetVReg(inst->VRegB_22b()) +
2225 inst->VRegC_22b());
2226 ADVANCE(2);
2227 HANDLE_INSTRUCTION_END();
2228
2229 HANDLE_INSTRUCTION_START(RSUB_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002230 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002231 inst->VRegC_22b() -
2232 shadow_frame.GetVReg(inst->VRegB_22b()));
2233 ADVANCE(2);
2234 HANDLE_INSTRUCTION_END();
2235
2236 HANDLE_INSTRUCTION_START(MUL_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002237 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002238 shadow_frame.GetVReg(inst->VRegB_22b()) *
2239 inst->VRegC_22b());
2240 ADVANCE(2);
2241 HANDLE_INSTRUCTION_END();
2242
2243 HANDLE_INSTRUCTION_START(DIV_INT_LIT8) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002244 bool success = DoIntDivide(shadow_frame, inst->VRegA_22b(inst_data),
2245 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002246 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2247 }
2248 HANDLE_INSTRUCTION_END();
2249
2250 HANDLE_INSTRUCTION_START(REM_INT_LIT8) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002251 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22b(inst_data),
2252 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002253 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, 2);
2254 }
2255 HANDLE_INSTRUCTION_END();
2256
2257 HANDLE_INSTRUCTION_START(AND_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002258 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002259 shadow_frame.GetVReg(inst->VRegB_22b()) &
2260 inst->VRegC_22b());
2261 ADVANCE(2);
2262 HANDLE_INSTRUCTION_END();
2263
2264 HANDLE_INSTRUCTION_START(OR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002265 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002266 shadow_frame.GetVReg(inst->VRegB_22b()) |
2267 inst->VRegC_22b());
2268 ADVANCE(2);
2269 HANDLE_INSTRUCTION_END();
2270
2271 HANDLE_INSTRUCTION_START(XOR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002272 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002273 shadow_frame.GetVReg(inst->VRegB_22b()) ^
2274 inst->VRegC_22b());
2275 ADVANCE(2);
2276 HANDLE_INSTRUCTION_END();
2277
2278 HANDLE_INSTRUCTION_START(SHL_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002279 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002280 shadow_frame.GetVReg(inst->VRegB_22b()) <<
2281 (inst->VRegC_22b() & 0x1f));
2282 ADVANCE(2);
2283 HANDLE_INSTRUCTION_END();
2284
2285 HANDLE_INSTRUCTION_START(SHR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002286 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002287 shadow_frame.GetVReg(inst->VRegB_22b()) >>
2288 (inst->VRegC_22b() & 0x1f));
2289 ADVANCE(2);
2290 HANDLE_INSTRUCTION_END();
2291
2292 HANDLE_INSTRUCTION_START(USHR_INT_LIT8)
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002293 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002294 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_22b())) >>
2295 (inst->VRegC_22b() & 0x1f));
2296 ADVANCE(2);
2297 HANDLE_INSTRUCTION_END();
2298
2299 HANDLE_INSTRUCTION_START(UNUSED_3E)
2300 UnexpectedOpcode(inst, mh);
2301 HANDLE_INSTRUCTION_END();
2302
2303 HANDLE_INSTRUCTION_START(UNUSED_3F)
2304 UnexpectedOpcode(inst, mh);
2305 HANDLE_INSTRUCTION_END();
2306
2307 HANDLE_INSTRUCTION_START(UNUSED_40)
2308 UnexpectedOpcode(inst, mh);
2309 HANDLE_INSTRUCTION_END();
2310
2311 HANDLE_INSTRUCTION_START(UNUSED_41)
2312 UnexpectedOpcode(inst, mh);
2313 HANDLE_INSTRUCTION_END();
2314
2315 HANDLE_INSTRUCTION_START(UNUSED_42)
2316 UnexpectedOpcode(inst, mh);
2317 HANDLE_INSTRUCTION_END();
2318
2319 HANDLE_INSTRUCTION_START(UNUSED_43)
2320 UnexpectedOpcode(inst, mh);
2321 HANDLE_INSTRUCTION_END();
2322
2323 HANDLE_INSTRUCTION_START(UNUSED_79)
2324 UnexpectedOpcode(inst, mh);
2325 HANDLE_INSTRUCTION_END();
2326
2327 HANDLE_INSTRUCTION_START(UNUSED_7A)
2328 UnexpectedOpcode(inst, mh);
2329 HANDLE_INSTRUCTION_END();
2330
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002331 HANDLE_INSTRUCTION_START(UNUSED_EF)
2332 UnexpectedOpcode(inst, mh);
2333 HANDLE_INSTRUCTION_END();
2334
2335 HANDLE_INSTRUCTION_START(UNUSED_F0)
2336 UnexpectedOpcode(inst, mh);
2337 HANDLE_INSTRUCTION_END();
2338
2339 HANDLE_INSTRUCTION_START(UNUSED_F1)
2340 UnexpectedOpcode(inst, mh);
2341 HANDLE_INSTRUCTION_END();
2342
2343 HANDLE_INSTRUCTION_START(UNUSED_F2)
2344 UnexpectedOpcode(inst, mh);
2345 HANDLE_INSTRUCTION_END();
2346
2347 HANDLE_INSTRUCTION_START(UNUSED_F3)
2348 UnexpectedOpcode(inst, mh);
2349 HANDLE_INSTRUCTION_END();
2350
2351 HANDLE_INSTRUCTION_START(UNUSED_F4)
2352 UnexpectedOpcode(inst, mh);
2353 HANDLE_INSTRUCTION_END();
2354
2355 HANDLE_INSTRUCTION_START(UNUSED_F5)
2356 UnexpectedOpcode(inst, mh);
2357 HANDLE_INSTRUCTION_END();
2358
2359 HANDLE_INSTRUCTION_START(UNUSED_F6)
2360 UnexpectedOpcode(inst, mh);
2361 HANDLE_INSTRUCTION_END();
2362
2363 HANDLE_INSTRUCTION_START(UNUSED_F7)
2364 UnexpectedOpcode(inst, mh);
2365 HANDLE_INSTRUCTION_END();
2366
2367 HANDLE_INSTRUCTION_START(UNUSED_F8)
2368 UnexpectedOpcode(inst, mh);
2369 HANDLE_INSTRUCTION_END();
2370
2371 HANDLE_INSTRUCTION_START(UNUSED_F9)
2372 UnexpectedOpcode(inst, mh);
2373 HANDLE_INSTRUCTION_END();
2374
2375 HANDLE_INSTRUCTION_START(UNUSED_FA)
2376 UnexpectedOpcode(inst, mh);
2377 HANDLE_INSTRUCTION_END();
2378
2379 HANDLE_INSTRUCTION_START(UNUSED_FB)
2380 UnexpectedOpcode(inst, mh);
2381 HANDLE_INSTRUCTION_END();
2382
2383 HANDLE_INSTRUCTION_START(UNUSED_FC)
2384 UnexpectedOpcode(inst, mh);
2385 HANDLE_INSTRUCTION_END();
2386
2387 HANDLE_INSTRUCTION_START(UNUSED_FD)
2388 UnexpectedOpcode(inst, mh);
2389 HANDLE_INSTRUCTION_END();
2390
2391 HANDLE_INSTRUCTION_START(UNUSED_FE)
2392 UnexpectedOpcode(inst, mh);
2393 HANDLE_INSTRUCTION_END();
2394
2395 HANDLE_INSTRUCTION_START(UNUSED_FF)
2396 UnexpectedOpcode(inst, mh);
2397 HANDLE_INSTRUCTION_END();
2398
2399 exception_pending_label: {
2400 CHECK(self->IsExceptionPending());
Sebastien Hertz1eda2262013-09-09 16:53:14 +02002401 if (UNLIKELY(self->TestAllFlags())) {
2402 CheckSuspend(self);
Sebastien Hertzee1997a2013-09-19 14:47:09 +02002403 UPDATE_HANDLER_TABLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +02002404 }
Sebastien Hertzee1997a2013-09-19 14:47:09 +02002405 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002406 uint32_t found_dex_pc = FindNextInstructionFollowingException(self, shadow_frame, dex_pc,
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002407 instrumentation);
2408 if (found_dex_pc == DexFile::kDexNoIndex) {
2409 return JValue(); /* Handled in caller. */
2410 } else {
2411 int32_t displacement = static_cast<int32_t>(found_dex_pc) - static_cast<int32_t>(dex_pc);
2412 ADVANCE(displacement);
2413 }
2414 }
2415
Sebastien Hertz8379b222014-02-24 17:38:15 +01002416// Create alternative instruction handlers dedicated to instrumentation.
2417// Return instructions must not call Instrumentation::DexPcMovedEvent since they already call
2418// Instrumentation::MethodExited. This is to avoid posting debugger events twice for this location.
Sebastien Hertze713d932014-05-15 10:48:53 +02002419// Note: we do not use the kReturn instruction flag here (to test the instruction is a return). The
2420// compiler seems to not evaluate "(Instruction::FlagsOf(Instruction::code) & kReturn) != 0" to
2421// a constant condition that would remove the "if" statement so the test is free.
Sebastien Hertz8379b222014-02-24 17:38:15 +01002422#define INSTRUMENTATION_INSTRUCTION_HANDLER(o, code, n, f, r, i, a, v) \
2423 alt_op_##code: { \
2424 if (Instruction::code != Instruction::RETURN_VOID && \
2425 Instruction::code != Instruction::RETURN_VOID_BARRIER && \
2426 Instruction::code != Instruction::RETURN && \
2427 Instruction::code != Instruction::RETURN_WIDE && \
2428 Instruction::code != Instruction::RETURN_OBJECT) { \
2429 if (LIKELY(!notified_method_entry_event)) { \
2430 Runtime* runtime = Runtime::Current(); \
2431 const instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation(); \
2432 if (UNLIKELY(instrumentation->HasDexPcListeners())) { \
2433 Object* this_object = shadow_frame.GetThisObject(code_item->ins_size_); \
2434 instrumentation->DexPcMovedEvent(self, this_object, shadow_frame.GetMethod(), dex_pc); \
2435 } \
2436 } else { \
2437 notified_method_entry_event = false; \
2438 } \
2439 } \
2440 UPDATE_HANDLER_TABLE(); \
2441 goto *handlersTable[instrumentation::kMainHandlerTable][Instruction::code]; \
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002442 }
2443#include "dex_instruction_list.h"
2444 DEX_INSTRUCTION_LIST(INSTRUMENTATION_INSTRUCTION_HANDLER)
2445#undef DEX_INSTRUCTION_LIST
2446#undef INSTRUMENTATION_INSTRUCTION_HANDLER
2447} // NOLINT(readability/fn_size)
2448
2449// Explicit definitions of ExecuteGotoImpl.
Sebastien Hertzc6714852013-09-30 16:42:32 +02002450template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) HOT_ATTR
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002451JValue ExecuteGotoImpl<true, false>(Thread* self, MethodHelper& mh,
2452 const DexFile::CodeItem* code_item,
2453 ShadowFrame& shadow_frame, JValue result_register);
Sebastien Hertzc6714852013-09-30 16:42:32 +02002454template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) HOT_ATTR
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002455JValue ExecuteGotoImpl<false, false>(Thread* self, MethodHelper& mh,
2456 const DexFile::CodeItem* code_item,
2457 ShadowFrame& shadow_frame, JValue result_register);
2458template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
2459JValue ExecuteGotoImpl<true, true>(Thread* self, MethodHelper& mh,
2460 const DexFile::CodeItem* code_item,
2461 ShadowFrame& shadow_frame, JValue result_register);
2462template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
2463JValue ExecuteGotoImpl<false, true>(Thread* self, MethodHelper& mh,
2464 const DexFile::CodeItem* code_item,
2465 ShadowFrame& shadow_frame, JValue result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002466
2467} // namespace interpreter
2468} // namespace art