blob: be4b807267494fab76fc9e7fb3603a11d6021ba5 [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
David Srbecky2ee09ff2018-10-24 13:24:22 +010017#ifndef ART_RUNTIME_INTERPRETER_INTERPRETER_SWITCH_IMPL_INL_H_
18#define ART_RUNTIME_INTERPRETER_INTERPRETER_SWITCH_IMPL_INL_H_
19
Andreas Gampe5e26eb12016-08-22 17:54:17 -070020#include "interpreter_switch_impl.h"
21
Andreas Gampe542451c2016-07-26 09:02:02 -070022#include "base/enums.h"
Alex Light49af7042019-05-29 18:30:33 -070023#include "base/globals.h"
Alex Light6f22e062018-10-05 15:05:12 -070024#include "base/memory_tool.h"
David Sehrc431b9d2018-03-02 12:01:51 -080025#include "base/quasi_atomic.h"
David Sehr9e734c72018-01-04 17:56:19 -080026#include "dex/dex_file_types.h"
David Srbecky6da82472018-10-23 14:03:08 +010027#include "dex/dex_instruction_list.h"
Alex Lighteb7c1442015-08-31 13:17:42 -070028#include "experimental_flags.h"
Alex Light49af7042019-05-29 18:30:33 -070029#include "handle_scope.h"
Sebastien Hertz8ece0502013-08-07 11:26:41 +020030#include "interpreter_common.h"
Alex Light49af7042019-05-29 18:30:33 -070031#include "interpreter/shadow_frame.h"
David Srbeckye3fc2d12018-11-30 13:41:14 +000032#include "jit/jit-inl.h"
Mathieu Chartier28bd2e42016-10-04 13:54:57 -070033#include "jvalue-inl.h"
Andreas Gampefd63bbf2018-10-29 12:55:35 -070034#include "mirror/string-alloc-inl.h"
Alex Light49af7042019-05-29 18:30:33 -070035#include "mirror/throwable.h"
Alex Lightb7c640d2019-03-20 15:52:13 -070036#include "monitor.h"
Alex Light0aa7a5a2018-10-10 15:58:14 +000037#include "nth_caller_visitor.h"
Ian Rogersf72a11d2014-10-30 15:41:08 -070038#include "safe_math.h"
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +010039#include "shadow_frame-inl.h"
Alex Light0aa7a5a2018-10-10 15:58:14 +000040#include "thread.h"
Alex Light49af7042019-05-29 18:30:33 -070041#include "verifier/method_verifier.h"
Sebastien Hertz8ece0502013-08-07 11:26:41 +020042
43namespace art {
44namespace interpreter {
45
David Srbecky6da82472018-10-23 14:03:08 +010046// Short-lived helper class which executes single DEX bytecode. It is inlined by compiler.
David Srbecky8d335b62019-06-06 14:25:42 +010047// Any relevant execution information is stored in the fields - it should be kept to minimum.
48// All instance functions must be inlined so that the fields can be stored in registers.
David Srbecky6da82472018-10-23 14:03:08 +010049//
50// The function names must match the names from dex_instruction_list.h and have no arguments.
David Srbecky8d335b62019-06-06 14:25:42 +010051// Return value: The handlers must return false if the instruction throws or returns (exits).
David Srbecky47ad3762018-10-31 12:43:40 +000052//
David Srbecky436f6c12019-05-22 13:28:42 +010053template<bool do_access_check, bool transaction_active, Instruction::Format kFormat>
David Srbecky6da82472018-10-23 14:03:08 +010054class InstructionHandler {
55 public:
David Srbecky27351be2019-07-12 13:39:34 +010056#define HANDLER_ATTRIBUTES ALWAYS_INLINE FLATTEN WARN_UNUSED REQUIRES_SHARED(Locks::mutator_lock_)
57
58 HANDLER_ATTRIBUTES bool CheckForceReturn() {
Alex Lightb7c640d2019-03-20 15:52:13 -070059 if (PerformNonStandardReturn<kMonitorState>(self,
60 shadow_frame,
61 ctx->result,
62 instrumentation,
63 Accessor().InsSize(),
64 inst->GetDexPc(Insns()))) {
David Srbecky47ad3762018-10-31 12:43:40 +000065 exit_interpreter_loop = true;
66 return false;
67 }
68 return true;
69 }
70
David Srbecky27351be2019-07-12 13:39:34 +010071 HANDLER_ATTRIBUTES bool HandlePendingException() {
David Srbecky47ad3762018-10-31 12:43:40 +000072 DCHECK(self->IsExceptionPending());
73 self->AllowThreadSuspension();
74 if (!CheckForceReturn()) {
75 return false;
76 }
David Srbecky8d335b62019-06-06 14:25:42 +010077 bool skip_event = shadow_frame.GetSkipNextExceptionEvent();
78 shadow_frame.SetSkipNextExceptionEvent(false);
79 if (!MoveToExceptionHandler(self, shadow_frame, skip_event ? nullptr : instrumentation)) {
David Srbecky47ad3762018-10-31 12:43:40 +000080 /* Structured locking is to be enforced for abnormal termination, too. */
81 DoMonitorCheckOnExit<do_assignability_check>(self, &shadow_frame);
David Srbecky47ad3762018-10-31 12:43:40 +000082 ctx->result = JValue(); /* Handled in caller. */
83 exit_interpreter_loop = true;
84 return false; // Return to caller.
85 }
86 if (!CheckForceReturn()) {
87 return false;
88 }
89 int32_t displacement =
90 static_cast<int32_t>(shadow_frame.GetDexPC()) - static_cast<int32_t>(dex_pc);
David Srbecky8867f3b2019-05-31 20:01:46 +010091 SetNextInstruction(inst->RelativeAt(displacement));
David Srbecky8d335b62019-06-06 14:25:42 +010092 return true;
David Srbecky47ad3762018-10-31 12:43:40 +000093 }
94
David Srbecky27351be2019-07-12 13:39:34 +010095 HANDLER_ATTRIBUTES bool PossiblyHandlePendingExceptionOnInvoke(bool is_exception_pending) {
David Srbecky47ad3762018-10-31 12:43:40 +000096 if (UNLIKELY(shadow_frame.GetForceRetryInstruction())) {
97 /* Don't need to do anything except clear the flag and exception. We leave the */
98 /* instruction the same so it will be re-executed on the next go-around. */
99 DCHECK(inst->IsInvoke());
100 shadow_frame.SetForceRetryInstruction(false);
101 if (UNLIKELY(is_exception_pending)) {
102 DCHECK(self->IsExceptionPending());
103 if (kIsDebugBuild) {
104 LOG(WARNING) << "Suppressing exception for instruction-retry: "
105 << self->GetException()->Dump();
106 }
107 self->ClearException();
108 }
David Srbecky8867f3b2019-05-31 20:01:46 +0100109 SetNextInstruction(inst);
David Srbecky47ad3762018-10-31 12:43:40 +0000110 } else if (UNLIKELY(is_exception_pending)) {
111 /* Should have succeeded. */
112 DCHECK(!shadow_frame.GetForceRetryInstruction());
David Srbecky8d335b62019-06-06 14:25:42 +0100113 return false; // Pending exception.
David Srbecky47ad3762018-10-31 12:43:40 +0000114 }
115 return true;
116 }
117
David Srbecky27351be2019-07-12 13:39:34 +0100118 HANDLER_ATTRIBUTES bool HandleMonitorChecks() {
David Srbecky47ad3762018-10-31 12:43:40 +0000119 if (!DoMonitorCheckOnExit<do_assignability_check>(self, &shadow_frame)) {
David Srbecky8d335b62019-06-06 14:25:42 +0100120 return false; // Pending exception.
David Srbecky47ad3762018-10-31 12:43:40 +0000121 }
122 return true;
123 }
124
125 // Code to run before each dex instruction.
David Srbecky27351be2019-07-12 13:39:34 +0100126 HANDLER_ATTRIBUTES bool Preamble() {
David Srbecky47ad3762018-10-31 12:43:40 +0000127 /* We need to put this before & after the instrumentation to avoid having to put in a */
128 /* post-script macro. */
129 if (!CheckForceReturn()) {
130 return false;
131 }
132 if (UNLIKELY(instrumentation->HasDexPcListeners())) {
David Srbeckya4a96af2018-10-31 16:34:58 +0000133 uint8_t opcode = inst->Opcode(inst_data);
134 bool is_move_result_object = (opcode == Instruction::MOVE_RESULT_OBJECT);
135 JValue* save_ref = is_move_result_object ? &ctx->result_register : nullptr;
David Srbecky47ad3762018-10-31 12:43:40 +0000136 if (UNLIKELY(!DoDexPcMoveEvent(self,
137 Accessor(),
138 shadow_frame,
139 dex_pc,
140 instrumentation,
141 save_ref))) {
David Srbecky8d335b62019-06-06 14:25:42 +0100142 DCHECK(self->IsExceptionPending());
143 // Do not raise exception event if it is caused by other instrumentation event.
144 shadow_frame.SetSkipNextExceptionEvent(true);
145 return false; // Pending exception.
David Srbecky47ad3762018-10-31 12:43:40 +0000146 }
147 if (!CheckForceReturn()) {
148 return false;
149 }
150 }
151 return true;
152 }
153
David Srbecky27351be2019-07-12 13:39:34 +0100154 HANDLER_ATTRIBUTES bool BranchInstrumentation(int32_t offset) {
David Srbecky47ad3762018-10-31 12:43:40 +0000155 if (UNLIKELY(instrumentation->HasBranchListeners())) {
156 instrumentation->Branch(self, shadow_frame.GetMethod(), dex_pc, offset);
157 }
158 JValue result;
159 if (jit::Jit::MaybeDoOnStackReplacement(self,
160 shadow_frame.GetMethod(),
161 dex_pc,
162 offset,
163 &result)) {
David Srbecky47ad3762018-10-31 12:43:40 +0000164 ctx->result = result;
165 exit_interpreter_loop = true;
166 return false;
167 }
168 return true;
169 }
170
171 ALWAYS_INLINE void HotnessUpdate()
172 REQUIRES_SHARED(Locks::mutator_lock_) {
173 jit::Jit* jit = Runtime::Current()->GetJit();
174 if (jit != nullptr) {
175 jit->AddSamples(self, shadow_frame.GetMethod(), 1, /*with_backedges=*/ true);
176 }
177 }
178
David Srbecky27351be2019-07-12 13:39:34 +0100179 HANDLER_ATTRIBUTES bool HandleAsyncException() {
David Srbecky47ad3762018-10-31 12:43:40 +0000180 if (UNLIKELY(self->ObserveAsyncException())) {
David Srbecky8d335b62019-06-06 14:25:42 +0100181 return false; // Pending exception.
David Srbecky47ad3762018-10-31 12:43:40 +0000182 }
183 return true;
184 }
185
186 ALWAYS_INLINE void HandleBackwardBranch(int32_t offset)
187 REQUIRES_SHARED(Locks::mutator_lock_) {
188 if (IsBackwardBranch(offset)) {
189 HotnessUpdate();
190 /* Record new dex pc early to have consistent suspend point at loop header. */
David Srbeckyc56a23e2019-06-05 17:45:49 +0100191 shadow_frame.SetDexPC(next->GetDexPc(Insns()));
David Srbecky47ad3762018-10-31 12:43:40 +0000192 self->AllowThreadSuspension();
193 }
194 }
195
196 // Unlike most other events the DexPcMovedEvent can be sent when there is a pending exception (if
197 // the next instruction is MOVE_EXCEPTION). This means it needs to be handled carefully to be able
198 // to detect exceptions thrown by the DexPcMovedEvent itself. These exceptions could be thrown by
199 // jvmti-agents while handling breakpoint or single step events. We had to move this into its own
200 // function because it was making ExecuteSwitchImpl have too large a stack.
201 NO_INLINE static bool DoDexPcMoveEvent(Thread* self,
202 const CodeItemDataAccessor& accessor,
203 const ShadowFrame& shadow_frame,
204 uint32_t dex_pc,
205 const instrumentation::Instrumentation* instrumentation,
206 JValue* save_ref)
207 REQUIRES_SHARED(Locks::mutator_lock_) {
208 DCHECK(instrumentation->HasDexPcListeners());
209 StackHandleScope<2> hs(self);
210 Handle<mirror::Throwable> thr(hs.NewHandle(self->GetException()));
211 mirror::Object* null_obj = nullptr;
212 HandleWrapper<mirror::Object> h(
213 hs.NewHandleWrapper(LIKELY(save_ref == nullptr) ? &null_obj : save_ref->GetGCRoot()));
214 self->ClearException();
215 instrumentation->DexPcMovedEvent(self,
216 shadow_frame.GetThisObject(accessor.InsSize()),
217 shadow_frame.GetMethod(),
218 dex_pc);
219 if (UNLIKELY(self->IsExceptionPending())) {
220 // We got a new exception in the dex-pc-moved event.
221 // We just let this exception replace the old one.
222 // TODO It would be good to add the old exception to the
223 // suppressed exceptions of the new one if possible.
David Srbecky8d335b62019-06-06 14:25:42 +0100224 return false; // Pending exception.
David Srbecky47ad3762018-10-31 12:43:40 +0000225 } else {
226 if (UNLIKELY(!thr.IsNull())) {
227 self->SetException(thr.Get());
228 }
229 return true;
230 }
231 }
232
David Srbecky27351be2019-07-12 13:39:34 +0100233 HANDLER_ATTRIBUTES bool HandleReturn(JValue result) {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100234 self->AllowThreadSuspension();
235 if (!HandleMonitorChecks()) {
236 return false;
237 }
238 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
239 !SendMethodExitEvents(self,
240 instrumentation,
241 shadow_frame,
242 shadow_frame.GetThisObject(Accessor().InsSize()),
243 shadow_frame.GetMethod(),
244 inst->GetDexPc(Insns()),
245 result))) {
David Srbecky8d335b62019-06-06 14:25:42 +0100246 DCHECK(self->IsExceptionPending());
247 // Do not raise exception event if it is caused by other instrumentation event.
248 shadow_frame.SetSkipNextExceptionEvent(true);
249 return false; // Pending exception.
David Srbeckyee12e3a2019-06-03 15:18:57 +0100250 }
251 ctx->result = result;
252 exit_interpreter_loop = true;
David Srbecky8d335b62019-06-06 14:25:42 +0100253 return false;
David Srbeckyee12e3a2019-06-03 15:18:57 +0100254 }
255
David Srbecky27351be2019-07-12 13:39:34 +0100256 HANDLER_ATTRIBUTES bool HandleGoto(int32_t offset) {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100257 if (!HandleAsyncException()) {
258 return false;
259 }
David Srbecky8d335b62019-06-06 14:25:42 +0100260 if (!BranchInstrumentation(offset)) {
261 return false;
262 }
David Srbecky8867f3b2019-05-31 20:01:46 +0100263 SetNextInstruction(inst->RelativeAt(offset));
David Srbeckyee12e3a2019-06-03 15:18:57 +0100264 HandleBackwardBranch(offset);
265 return true;
266 }
267
268#pragma clang diagnostic push
269#pragma clang diagnostic ignored "-Wfloat-equal"
270
271 template<typename T>
David Srbecky27351be2019-07-12 13:39:34 +0100272 HANDLER_ATTRIBUTES bool HandleCmpl(T val1, T val2) {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100273 int32_t result;
274 if (val1 > val2) {
275 result = 1;
276 } else if (val1 == val2) {
277 result = 0;
278 } else {
279 result = -1;
280 }
281 SetVReg(A(), result);
David Srbeckyee12e3a2019-06-03 15:18:57 +0100282 return true;
283 }
284
285 // Returns the same result as the function above. It only differs for NaN values.
286 template<typename T>
David Srbecky27351be2019-07-12 13:39:34 +0100287 HANDLER_ATTRIBUTES bool HandleCmpg(T val1, T val2) {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100288 int32_t result;
289 if (val1 < val2) {
290 result = -1;
291 } else if (val1 == val2) {
292 result = 0;
293 } else {
294 result = 1;
295 }
296 SetVReg(A(), result);
David Srbeckyee12e3a2019-06-03 15:18:57 +0100297 return true;
298 }
299
300#pragma clang diagnostic pop
301
David Srbecky27351be2019-07-12 13:39:34 +0100302 HANDLER_ATTRIBUTES bool HandleIf(bool cond, int32_t offset) {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100303 if (cond) {
David Srbecky8d335b62019-06-06 14:25:42 +0100304 if (!BranchInstrumentation(offset)) {
305 return false;
306 }
David Srbecky8867f3b2019-05-31 20:01:46 +0100307 SetNextInstruction(inst->RelativeAt(offset));
David Srbeckyee12e3a2019-06-03 15:18:57 +0100308 HandleBackwardBranch(offset);
309 } else {
David Srbecky8d335b62019-06-06 14:25:42 +0100310 if (!BranchInstrumentation(2)) {
311 return false;
312 }
David Srbeckyee12e3a2019-06-03 15:18:57 +0100313 }
314 return true;
315 }
316
David Srbecky1332c262019-06-04 13:13:37 +0100317 template<typename ArrayType, typename SetVRegFn>
David Srbecky27351be2019-07-12 13:39:34 +0100318 HANDLER_ATTRIBUTES bool HandleAGet(SetVRegFn setVReg) {
David Srbecky1332c262019-06-04 13:13:37 +0100319 ObjPtr<mirror::Object> a = GetVRegReference(B());
320 if (UNLIKELY(a == nullptr)) {
321 ThrowNullPointerExceptionFromInterpreter();
David Srbecky8d335b62019-06-06 14:25:42 +0100322 return false; // Pending exception.
David Srbecky1332c262019-06-04 13:13:37 +0100323 }
324 int32_t index = GetVReg(C());
325 ObjPtr<ArrayType> array = ObjPtr<ArrayType>::DownCast(a);
326 if (UNLIKELY(!array->CheckIsValidIndex(index))) {
David Srbecky8d335b62019-06-06 14:25:42 +0100327 return false; // Pending exception.
David Srbecky1332c262019-06-04 13:13:37 +0100328 } else {
329 (this->*setVReg)(A(), array->GetWithoutChecks(index));
David Srbecky1332c262019-06-04 13:13:37 +0100330 }
331 return true;
332 }
333
334 template<typename ArrayType, typename T>
David Srbecky27351be2019-07-12 13:39:34 +0100335 HANDLER_ATTRIBUTES bool HandleAPut(T value) {
David Srbecky1332c262019-06-04 13:13:37 +0100336 ObjPtr<mirror::Object> a = GetVRegReference(B());
337 if (UNLIKELY(a == nullptr)) {
338 ThrowNullPointerExceptionFromInterpreter();
David Srbecky8d335b62019-06-06 14:25:42 +0100339 return false; // Pending exception.
David Srbecky1332c262019-06-04 13:13:37 +0100340 }
341 int32_t index = GetVReg(C());
342 ObjPtr<ArrayType> array = ObjPtr<ArrayType>::DownCast(a);
343 if (UNLIKELY(!array->CheckIsValidIndex(index))) {
David Srbecky8d335b62019-06-06 14:25:42 +0100344 return false; // Pending exception.
David Srbecky1332c262019-06-04 13:13:37 +0100345 } else {
346 array->template SetWithoutChecks<transaction_active>(index, value);
David Srbecky1332c262019-06-04 13:13:37 +0100347 }
348 return true;
349 }
350
David Srbeckyee12e3a2019-06-03 15:18:57 +0100351 template<FindFieldType find_type, Primitive::Type field_type>
David Srbecky27351be2019-07-12 13:39:34 +0100352 HANDLER_ATTRIBUTES bool HandleGet() {
David Srbecky8d335b62019-06-06 14:25:42 +0100353 return DoFieldGet<find_type, field_type, do_access_check, transaction_active>(
David Srbeckyee12e3a2019-06-03 15:18:57 +0100354 self, shadow_frame, inst, inst_data);
David Srbeckyee12e3a2019-06-03 15:18:57 +0100355 }
356
357 template<Primitive::Type field_type>
David Srbecky27351be2019-07-12 13:39:34 +0100358 HANDLER_ATTRIBUTES bool HandleGetQuick() {
David Srbecky8d335b62019-06-06 14:25:42 +0100359 return DoIGetQuick<field_type>(shadow_frame, inst, inst_data);
David Srbeckyee12e3a2019-06-03 15:18:57 +0100360 }
361
362 template<FindFieldType find_type, Primitive::Type field_type>
David Srbecky27351be2019-07-12 13:39:34 +0100363 HANDLER_ATTRIBUTES bool HandlePut() {
David Srbecky8d335b62019-06-06 14:25:42 +0100364 return DoFieldPut<find_type, field_type, do_access_check, transaction_active>(
David Srbeckyee12e3a2019-06-03 15:18:57 +0100365 self, shadow_frame, inst, inst_data);
David Srbeckyee12e3a2019-06-03 15:18:57 +0100366 }
367
368 template<Primitive::Type field_type>
David Srbecky27351be2019-07-12 13:39:34 +0100369 HANDLER_ATTRIBUTES bool HandlePutQuick() {
David Srbecky8d335b62019-06-06 14:25:42 +0100370 return DoIPutQuick<field_type, transaction_active>(
David Srbeckyee12e3a2019-06-03 15:18:57 +0100371 shadow_frame, inst, inst_data);
David Srbeckyee12e3a2019-06-03 15:18:57 +0100372 }
373
374 template<InvokeType type, bool is_range, bool is_quick = false>
David Srbecky27351be2019-07-12 13:39:34 +0100375 HANDLER_ATTRIBUTES bool HandleInvoke() {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100376 bool success = DoInvoke<type, is_range, do_access_check, /*is_mterp=*/ false, is_quick>(
377 self, shadow_frame, inst, inst_data, ResultRegister());
David Srbecky8d335b62019-06-06 14:25:42 +0100378 return PossiblyHandlePendingExceptionOnInvoke(!success);
David Srbeckyee12e3a2019-06-03 15:18:57 +0100379 }
380
David Srbecky27351be2019-07-12 13:39:34 +0100381 HANDLER_ATTRIBUTES bool HandleUnused() {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100382 UnexpectedOpcode(inst, shadow_frame);
383 return true;
384 }
385
David Srbecky27351be2019-07-12 13:39:34 +0100386 HANDLER_ATTRIBUTES bool NOP() {
David Srbeckybd613ec2019-05-30 15:39:38 +0100387 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100388 }
389
David Srbecky27351be2019-07-12 13:39:34 +0100390 HANDLER_ATTRIBUTES bool MOVE() {
David Srbecky6baf6442019-05-30 14:57:43 +0100391 SetVReg(A(), GetVReg(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +0100392 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100393 }
394
David Srbecky27351be2019-07-12 13:39:34 +0100395 HANDLER_ATTRIBUTES bool MOVE_FROM16() {
David Srbecky6baf6442019-05-30 14:57:43 +0100396 SetVReg(A(), GetVReg(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +0100397 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100398 }
399
David Srbecky27351be2019-07-12 13:39:34 +0100400 HANDLER_ATTRIBUTES bool MOVE_16() {
David Srbecky6baf6442019-05-30 14:57:43 +0100401 SetVReg(A(), GetVReg(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +0100402 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100403 }
404
David Srbecky27351be2019-07-12 13:39:34 +0100405 HANDLER_ATTRIBUTES bool MOVE_WIDE() {
David Srbecky6baf6442019-05-30 14:57:43 +0100406 SetVRegLong(A(), GetVRegLong(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +0100407 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100408 }
409
David Srbecky27351be2019-07-12 13:39:34 +0100410 HANDLER_ATTRIBUTES bool MOVE_WIDE_FROM16() {
David Srbecky6baf6442019-05-30 14:57:43 +0100411 SetVRegLong(A(), GetVRegLong(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +0100412 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100413 }
414
David Srbecky27351be2019-07-12 13:39:34 +0100415 HANDLER_ATTRIBUTES bool MOVE_WIDE_16() {
David Srbecky6baf6442019-05-30 14:57:43 +0100416 SetVRegLong(A(), GetVRegLong(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +0100417 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100418 }
419
David Srbecky27351be2019-07-12 13:39:34 +0100420 HANDLER_ATTRIBUTES bool MOVE_OBJECT() {
David Srbecky6baf6442019-05-30 14:57:43 +0100421 SetVRegReference(A(), GetVRegReference(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +0100422 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100423 }
424
David Srbecky27351be2019-07-12 13:39:34 +0100425 HANDLER_ATTRIBUTES bool MOVE_OBJECT_FROM16() {
David Srbecky6baf6442019-05-30 14:57:43 +0100426 SetVRegReference(A(), GetVRegReference(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +0100427 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100428 }
429
David Srbecky27351be2019-07-12 13:39:34 +0100430 HANDLER_ATTRIBUTES bool MOVE_OBJECT_16() {
David Srbecky6baf6442019-05-30 14:57:43 +0100431 SetVRegReference(A(), GetVRegReference(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +0100432 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100433 }
434
David Srbecky27351be2019-07-12 13:39:34 +0100435 HANDLER_ATTRIBUTES bool MOVE_RESULT() {
David Srbecky6baf6442019-05-30 14:57:43 +0100436 SetVReg(A(), ResultRegister()->GetI());
David Srbeckybd613ec2019-05-30 15:39:38 +0100437 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100438 }
439
David Srbecky27351be2019-07-12 13:39:34 +0100440 HANDLER_ATTRIBUTES bool MOVE_RESULT_WIDE() {
David Srbecky6baf6442019-05-30 14:57:43 +0100441 SetVRegLong(A(), ResultRegister()->GetJ());
David Srbeckybd613ec2019-05-30 15:39:38 +0100442 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100443 }
444
David Srbecky27351be2019-07-12 13:39:34 +0100445 HANDLER_ATTRIBUTES bool MOVE_RESULT_OBJECT() {
David Srbecky6baf6442019-05-30 14:57:43 +0100446 SetVRegReference(A(), ResultRegister()->GetL());
David Srbeckybd613ec2019-05-30 15:39:38 +0100447 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100448 }
449
David Srbecky27351be2019-07-12 13:39:34 +0100450 HANDLER_ATTRIBUTES bool MOVE_EXCEPTION() {
David Srbecky6da82472018-10-23 14:03:08 +0100451 ObjPtr<mirror::Throwable> exception = self->GetException();
452 DCHECK(exception != nullptr) << "No pending exception on MOVE_EXCEPTION instruction";
David Srbecky6baf6442019-05-30 14:57:43 +0100453 SetVRegReference(A(), exception);
David Srbecky6da82472018-10-23 14:03:08 +0100454 self->ClearException();
David Srbeckybd613ec2019-05-30 15:39:38 +0100455 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100456 }
457
David Srbecky27351be2019-07-12 13:39:34 +0100458 HANDLER_ATTRIBUTES bool RETURN_VOID_NO_BARRIER() {
David Srbecky6da82472018-10-23 14:03:08 +0100459 JValue result;
David Srbeckyee12e3a2019-06-03 15:18:57 +0100460 return HandleReturn(result);
David Srbecky6da82472018-10-23 14:03:08 +0100461 }
462
David Srbecky27351be2019-07-12 13:39:34 +0100463 HANDLER_ATTRIBUTES bool RETURN_VOID() {
David Srbecky6da82472018-10-23 14:03:08 +0100464 QuasiAtomic::ThreadFenceForConstructor();
465 JValue result;
David Srbeckyee12e3a2019-06-03 15:18:57 +0100466 return HandleReturn(result);
David Srbecky6da82472018-10-23 14:03:08 +0100467 }
468
David Srbecky27351be2019-07-12 13:39:34 +0100469 HANDLER_ATTRIBUTES bool RETURN() {
David Srbecky6da82472018-10-23 14:03:08 +0100470 JValue result;
471 result.SetJ(0);
David Srbecky6baf6442019-05-30 14:57:43 +0100472 result.SetI(GetVReg(A()));
David Srbeckyee12e3a2019-06-03 15:18:57 +0100473 return HandleReturn(result);
David Srbecky6da82472018-10-23 14:03:08 +0100474 }
475
David Srbecky27351be2019-07-12 13:39:34 +0100476 HANDLER_ATTRIBUTES bool RETURN_WIDE() {
David Srbecky6da82472018-10-23 14:03:08 +0100477 JValue result;
David Srbecky6baf6442019-05-30 14:57:43 +0100478 result.SetJ(GetVRegLong(A()));
David Srbeckyee12e3a2019-06-03 15:18:57 +0100479 return HandleReturn(result);
David Srbecky6da82472018-10-23 14:03:08 +0100480 }
481
David Srbecky27351be2019-07-12 13:39:34 +0100482 HANDLER_ATTRIBUTES bool RETURN_OBJECT() {
David Srbecky6da82472018-10-23 14:03:08 +0100483 JValue result;
484 self->AllowThreadSuspension();
David Srbecky47ad3762018-10-31 12:43:40 +0000485 if (!HandleMonitorChecks()) {
David Srbeckybd613ec2019-05-30 15:39:38 +0100486 return false;
David Srbecky47ad3762018-10-31 12:43:40 +0000487 }
David Srbeckyd6f579c2019-05-29 18:09:30 +0100488 const size_t ref_idx = A();
David Srbecky6baf6442019-05-30 14:57:43 +0100489 ObjPtr<mirror::Object> obj_result = GetVRegReference(ref_idx);
David Srbecky6da82472018-10-23 14:03:08 +0100490 if (do_assignability_check && obj_result != nullptr) {
491 ObjPtr<mirror::Class> return_type = shadow_frame.GetMethod()->ResolveReturnType();
492 // Re-load since it might have moved.
David Srbecky6baf6442019-05-30 14:57:43 +0100493 obj_result = GetVRegReference(ref_idx);
David Srbecky6da82472018-10-23 14:03:08 +0100494 if (return_type == nullptr) {
495 // Return the pending exception.
David Srbecky8d335b62019-06-06 14:25:42 +0100496 return false; // Pending exception.
David Srbecky6da82472018-10-23 14:03:08 +0100497 }
498 if (!obj_result->VerifierInstanceOf(return_type)) {
Andreas Gampebc919af2019-07-10 14:09:51 -0700499 CHECK_LE(Runtime::Current()->GetTargetSdkVersion(), 29u);
David Srbecky6da82472018-10-23 14:03:08 +0100500 // This should never happen.
501 std::string temp1, temp2;
502 self->ThrowNewExceptionF("Ljava/lang/InternalError;",
503 "Returning '%s' that is not instance of return type '%s'",
504 obj_result->GetClass()->GetDescriptor(&temp1),
505 return_type->GetDescriptor(&temp2));
David Srbecky8d335b62019-06-06 14:25:42 +0100506 return false; // Pending exception.
David Srbecky6da82472018-10-23 14:03:08 +0100507 }
508 }
Alex Lightb7c640d2019-03-20 15:52:13 -0700509 StackHandleScope<1> hs(self);
510 MutableHandle<mirror::Object> h_result(hs.NewHandle(obj_result));
David Srbecky6da82472018-10-23 14:03:08 +0100511 result.SetL(obj_result);
512 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
513 !SendMethodExitEvents(self,
514 instrumentation,
515 shadow_frame,
516 shadow_frame.GetThisObject(Accessor().InsSize()),
517 shadow_frame.GetMethod(),
518 inst->GetDexPc(Insns()),
Alex Lightb7c640d2019-03-20 15:52:13 -0700519 h_result))) {
David Srbecky8d335b62019-06-06 14:25:42 +0100520 DCHECK(self->IsExceptionPending());
521 // Do not raise exception event if it is caused by other instrumentation event.
522 shadow_frame.SetSkipNextExceptionEvent(true);
523 return false; // Pending exception.
David Srbecky6da82472018-10-23 14:03:08 +0100524 }
Alex Lightb7c640d2019-03-20 15:52:13 -0700525 // Re-load since it might have moved or been replaced during the MethodExitEvent.
526 result.SetL(h_result.Get());
David Srbecky6da82472018-10-23 14:03:08 +0100527 ctx->result = result;
528 exit_interpreter_loop = true;
David Srbecky8d335b62019-06-06 14:25:42 +0100529 return false;
David Srbecky6da82472018-10-23 14:03:08 +0100530 }
531
David Srbecky27351be2019-07-12 13:39:34 +0100532 HANDLER_ATTRIBUTES bool CONST_4() {
David Srbecky6da82472018-10-23 14:03:08 +0100533 uint4_t dst = inst->VRegA_11n(inst_data);
534 int4_t val = inst->VRegB_11n(inst_data);
David Srbecky6baf6442019-05-30 14:57:43 +0100535 SetVReg(dst, val);
David Srbecky6da82472018-10-23 14:03:08 +0100536 if (val == 0) {
David Srbecky6baf6442019-05-30 14:57:43 +0100537 SetVRegReference(dst, nullptr);
David Srbecky6da82472018-10-23 14:03:08 +0100538 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100539 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100540 }
541
David Srbecky27351be2019-07-12 13:39:34 +0100542 HANDLER_ATTRIBUTES bool CONST_16() {
David Srbeckyd6f579c2019-05-29 18:09:30 +0100543 uint8_t dst = A();
544 int16_t val = B();
David Srbecky6baf6442019-05-30 14:57:43 +0100545 SetVReg(dst, val);
David Srbecky6da82472018-10-23 14:03:08 +0100546 if (val == 0) {
David Srbecky6baf6442019-05-30 14:57:43 +0100547 SetVRegReference(dst, nullptr);
David Srbecky6da82472018-10-23 14:03:08 +0100548 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100549 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100550 }
551
David Srbecky27351be2019-07-12 13:39:34 +0100552 HANDLER_ATTRIBUTES bool CONST() {
David Srbeckyd6f579c2019-05-29 18:09:30 +0100553 uint8_t dst = A();
554 int32_t val = B();
David Srbecky6baf6442019-05-30 14:57:43 +0100555 SetVReg(dst, val);
David Srbecky6da82472018-10-23 14:03:08 +0100556 if (val == 0) {
David Srbecky6baf6442019-05-30 14:57:43 +0100557 SetVRegReference(dst, nullptr);
David Srbecky6da82472018-10-23 14:03:08 +0100558 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100559 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100560 }
561
David Srbecky27351be2019-07-12 13:39:34 +0100562 HANDLER_ATTRIBUTES bool CONST_HIGH16() {
David Srbeckyd6f579c2019-05-29 18:09:30 +0100563 uint8_t dst = A();
564 int32_t val = static_cast<int32_t>(B() << 16);
David Srbecky6baf6442019-05-30 14:57:43 +0100565 SetVReg(dst, val);
David Srbecky6da82472018-10-23 14:03:08 +0100566 if (val == 0) {
David Srbecky6baf6442019-05-30 14:57:43 +0100567 SetVRegReference(dst, nullptr);
David Srbecky6da82472018-10-23 14:03:08 +0100568 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100569 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100570 }
571
David Srbecky27351be2019-07-12 13:39:34 +0100572 HANDLER_ATTRIBUTES bool CONST_WIDE_16() {
David Srbecky6baf6442019-05-30 14:57:43 +0100573 SetVRegLong(A(), B());
David Srbeckybd613ec2019-05-30 15:39:38 +0100574 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100575 }
576
David Srbecky27351be2019-07-12 13:39:34 +0100577 HANDLER_ATTRIBUTES bool CONST_WIDE_32() {
David Srbecky6baf6442019-05-30 14:57:43 +0100578 SetVRegLong(A(), B());
David Srbeckybd613ec2019-05-30 15:39:38 +0100579 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100580 }
581
David Srbecky27351be2019-07-12 13:39:34 +0100582 HANDLER_ATTRIBUTES bool CONST_WIDE() {
David Srbecky6baf6442019-05-30 14:57:43 +0100583 SetVRegLong(A(), inst->WideVRegB());
David Srbeckybd613ec2019-05-30 15:39:38 +0100584 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100585 }
586
David Srbecky27351be2019-07-12 13:39:34 +0100587 HANDLER_ATTRIBUTES bool CONST_WIDE_HIGH16() {
David Srbecky6baf6442019-05-30 14:57:43 +0100588 SetVRegLong(A(), static_cast<uint64_t>(B()) << 48);
David Srbeckybd613ec2019-05-30 15:39:38 +0100589 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100590 }
591
David Srbecky27351be2019-07-12 13:39:34 +0100592 HANDLER_ATTRIBUTES bool CONST_STRING() {
David Srbecky6baf6442019-05-30 14:57:43 +0100593 ObjPtr<mirror::String> s = ResolveString(self, shadow_frame, dex::StringIndex(B()));
David Srbecky6da82472018-10-23 14:03:08 +0100594 if (UNLIKELY(s == nullptr)) {
David Srbecky8d335b62019-06-06 14:25:42 +0100595 return false; // Pending exception.
David Srbecky6da82472018-10-23 14:03:08 +0100596 } else {
David Srbecky6baf6442019-05-30 14:57:43 +0100597 SetVRegReference(A(), s);
David Srbecky6da82472018-10-23 14:03:08 +0100598 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100599 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100600 }
601
David Srbecky27351be2019-07-12 13:39:34 +0100602 HANDLER_ATTRIBUTES bool CONST_STRING_JUMBO() {
David Srbecky6baf6442019-05-30 14:57:43 +0100603 ObjPtr<mirror::String> s = ResolveString(self, shadow_frame, dex::StringIndex(B()));
David Srbecky6da82472018-10-23 14:03:08 +0100604 if (UNLIKELY(s == nullptr)) {
David Srbecky8d335b62019-06-06 14:25:42 +0100605 return false; // Pending exception.
David Srbecky6da82472018-10-23 14:03:08 +0100606 } else {
David Srbecky6baf6442019-05-30 14:57:43 +0100607 SetVRegReference(A(), s);
David Srbecky6da82472018-10-23 14:03:08 +0100608 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100609 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100610 }
611
David Srbecky27351be2019-07-12 13:39:34 +0100612 HANDLER_ATTRIBUTES bool CONST_CLASS() {
David Srbeckyd6f579c2019-05-29 18:09:30 +0100613 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(B()),
David Srbecky6da82472018-10-23 14:03:08 +0100614 shadow_frame.GetMethod(),
615 self,
616 false,
617 do_access_check);
618 if (UNLIKELY(c == nullptr)) {
David Srbecky8d335b62019-06-06 14:25:42 +0100619 return false; // Pending exception.
David Srbecky6da82472018-10-23 14:03:08 +0100620 } else {
David Srbecky6baf6442019-05-30 14:57:43 +0100621 SetVRegReference(A(), c);
David Srbecky6da82472018-10-23 14:03:08 +0100622 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100623 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100624 }
625
David Srbecky27351be2019-07-12 13:39:34 +0100626 HANDLER_ATTRIBUTES bool CONST_METHOD_HANDLE() {
David Srbecky6da82472018-10-23 14:03:08 +0100627 ClassLinker* cl = Runtime::Current()->GetClassLinker();
628 ObjPtr<mirror::MethodHandle> mh = cl->ResolveMethodHandle(self,
David Srbeckyd6f579c2019-05-29 18:09:30 +0100629 B(),
David Srbecky6da82472018-10-23 14:03:08 +0100630 shadow_frame.GetMethod());
631 if (UNLIKELY(mh == nullptr)) {
David Srbecky8d335b62019-06-06 14:25:42 +0100632 return false; // Pending exception.
David Srbecky6da82472018-10-23 14:03:08 +0100633 } else {
David Srbecky6baf6442019-05-30 14:57:43 +0100634 SetVRegReference(A(), mh);
David Srbecky6da82472018-10-23 14:03:08 +0100635 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100636 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100637 }
638
David Srbecky27351be2019-07-12 13:39:34 +0100639 HANDLER_ATTRIBUTES bool CONST_METHOD_TYPE() {
David Srbecky6da82472018-10-23 14:03:08 +0100640 ClassLinker* cl = Runtime::Current()->GetClassLinker();
641 ObjPtr<mirror::MethodType> mt = cl->ResolveMethodType(self,
David Srbeckyd6f579c2019-05-29 18:09:30 +0100642 dex::ProtoIndex(B()),
David Srbecky6da82472018-10-23 14:03:08 +0100643 shadow_frame.GetMethod());
644 if (UNLIKELY(mt == nullptr)) {
David Srbecky8d335b62019-06-06 14:25:42 +0100645 return false; // Pending exception.
David Srbecky6da82472018-10-23 14:03:08 +0100646 } else {
David Srbecky6baf6442019-05-30 14:57:43 +0100647 SetVRegReference(A(), mt);
David Srbecky6da82472018-10-23 14:03:08 +0100648 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100649 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100650 }
651
David Srbecky27351be2019-07-12 13:39:34 +0100652 HANDLER_ATTRIBUTES bool MONITOR_ENTER() {
David Srbecky47ad3762018-10-31 12:43:40 +0000653 if (!HandleAsyncException()) {
David Srbeckybd613ec2019-05-30 15:39:38 +0100654 return false;
David Srbecky47ad3762018-10-31 12:43:40 +0000655 }
David Srbecky6baf6442019-05-30 14:57:43 +0100656 ObjPtr<mirror::Object> obj = GetVRegReference(A());
David Srbecky6da82472018-10-23 14:03:08 +0100657 if (UNLIKELY(obj == nullptr)) {
658 ThrowNullPointerExceptionFromInterpreter();
David Srbecky8d335b62019-06-06 14:25:42 +0100659 return false; // Pending exception.
David Srbecky6da82472018-10-23 14:03:08 +0100660 } else {
661 DoMonitorEnter<do_assignability_check>(self, &shadow_frame, obj);
David Srbecky8d335b62019-06-06 14:25:42 +0100662 return !self->IsExceptionPending();
David Srbecky6da82472018-10-23 14:03:08 +0100663 }
664 }
665
David Srbecky27351be2019-07-12 13:39:34 +0100666 HANDLER_ATTRIBUTES bool MONITOR_EXIT() {
David Srbecky47ad3762018-10-31 12:43:40 +0000667 if (!HandleAsyncException()) {
David Srbeckybd613ec2019-05-30 15:39:38 +0100668 return false;
David Srbecky47ad3762018-10-31 12:43:40 +0000669 }
David Srbecky6baf6442019-05-30 14:57:43 +0100670 ObjPtr<mirror::Object> obj = GetVRegReference(A());
David Srbecky6da82472018-10-23 14:03:08 +0100671 if (UNLIKELY(obj == nullptr)) {
672 ThrowNullPointerExceptionFromInterpreter();
David Srbecky8d335b62019-06-06 14:25:42 +0100673 return false; // Pending exception.
David Srbecky6da82472018-10-23 14:03:08 +0100674 } else {
675 DoMonitorExit<do_assignability_check>(self, &shadow_frame, obj);
David Srbecky8d335b62019-06-06 14:25:42 +0100676 return !self->IsExceptionPending();
David Srbecky6da82472018-10-23 14:03:08 +0100677 }
678 }
679
David Srbecky27351be2019-07-12 13:39:34 +0100680 HANDLER_ATTRIBUTES bool CHECK_CAST() {
David Srbeckyd6f579c2019-05-29 18:09:30 +0100681 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(B()),
David Srbecky6da82472018-10-23 14:03:08 +0100682 shadow_frame.GetMethod(),
683 self,
684 false,
685 do_access_check);
686 if (UNLIKELY(c == nullptr)) {
David Srbecky8d335b62019-06-06 14:25:42 +0100687 return false; // Pending exception.
David Srbecky6da82472018-10-23 14:03:08 +0100688 } else {
David Srbecky6baf6442019-05-30 14:57:43 +0100689 ObjPtr<mirror::Object> obj = GetVRegReference(A());
David Srbecky6da82472018-10-23 14:03:08 +0100690 if (UNLIKELY(obj != nullptr && !obj->InstanceOf(c))) {
691 ThrowClassCastException(c, obj->GetClass());
David Srbecky8d335b62019-06-06 14:25:42 +0100692 return false; // Pending exception.
David Srbecky6da82472018-10-23 14:03:08 +0100693 }
694 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100695 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100696 }
697
David Srbecky27351be2019-07-12 13:39:34 +0100698 HANDLER_ATTRIBUTES bool INSTANCE_OF() {
David Srbeckyd6f579c2019-05-29 18:09:30 +0100699 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(C()),
David Srbecky6da82472018-10-23 14:03:08 +0100700 shadow_frame.GetMethod(),
701 self,
702 false,
703 do_access_check);
704 if (UNLIKELY(c == nullptr)) {
David Srbecky8d335b62019-06-06 14:25:42 +0100705 return false; // Pending exception.
David Srbecky6da82472018-10-23 14:03:08 +0100706 } else {
David Srbecky6baf6442019-05-30 14:57:43 +0100707 ObjPtr<mirror::Object> obj = GetVRegReference(B());
708 SetVReg(A(), (obj != nullptr && obj->InstanceOf(c)) ? 1 : 0);
David Srbecky6da82472018-10-23 14:03:08 +0100709 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100710 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100711 }
712
David Srbecky27351be2019-07-12 13:39:34 +0100713 HANDLER_ATTRIBUTES bool ARRAY_LENGTH() {
David Srbecky6baf6442019-05-30 14:57:43 +0100714 ObjPtr<mirror::Object> array = GetVRegReference(B());
David Srbecky6da82472018-10-23 14:03:08 +0100715 if (UNLIKELY(array == nullptr)) {
716 ThrowNullPointerExceptionFromInterpreter();
David Srbecky8d335b62019-06-06 14:25:42 +0100717 return false; // Pending exception.
David Srbecky6da82472018-10-23 14:03:08 +0100718 } else {
David Srbecky6baf6442019-05-30 14:57:43 +0100719 SetVReg(A(), array->AsArray()->GetLength());
David Srbecky6da82472018-10-23 14:03:08 +0100720 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100721 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100722 }
723
David Srbecky27351be2019-07-12 13:39:34 +0100724 HANDLER_ATTRIBUTES bool NEW_INSTANCE() {
David Srbecky6da82472018-10-23 14:03:08 +0100725 ObjPtr<mirror::Object> obj = nullptr;
David Srbeckyd6f579c2019-05-29 18:09:30 +0100726 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(B()),
David Srbecky6da82472018-10-23 14:03:08 +0100727 shadow_frame.GetMethod(),
728 self,
729 false,
730 do_access_check);
731 if (LIKELY(c != nullptr)) {
Vladimir Marko64b56032019-06-20 15:52:39 +0100732 // Don't allow finalizable objects to be allocated during a transaction since these can't
733 // be finalized without a started runtime.
734 if (transaction_active && c->IsFinalizable()) {
735 AbortTransactionF(self,
736 "Allocating finalizable object in transaction: %s",
737 c->PrettyDescriptor().c_str());
David Srbecky8d335b62019-06-06 14:25:42 +0100738 return false; // Pending exception.
Vladimir Marko64b56032019-06-20 15:52:39 +0100739 }
Vladimir Marko9b81ac32019-05-16 16:47:08 +0100740 gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
David Srbecky6da82472018-10-23 14:03:08 +0100741 if (UNLIKELY(c->IsStringClass())) {
Vladimir Marko9b81ac32019-05-16 16:47:08 +0100742 obj = mirror::String::AllocEmptyString(self, allocator_type);
David Srbecky6da82472018-10-23 14:03:08 +0100743 } else {
Vladimir Marko9b81ac32019-05-16 16:47:08 +0100744 obj = AllocObjectFromCode(c, self, allocator_type);
David Srbecky6da82472018-10-23 14:03:08 +0100745 }
746 }
747 if (UNLIKELY(obj == nullptr)) {
David Srbecky8d335b62019-06-06 14:25:42 +0100748 return false; // Pending exception.
David Srbecky6da82472018-10-23 14:03:08 +0100749 } else {
750 obj->GetClass()->AssertInitializedOrInitializingInThread(self);
David Srbecky6baf6442019-05-30 14:57:43 +0100751 SetVRegReference(A(), obj);
David Srbecky6da82472018-10-23 14:03:08 +0100752 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100753 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100754 }
755
David Srbecky27351be2019-07-12 13:39:34 +0100756 HANDLER_ATTRIBUTES bool NEW_ARRAY() {
David Srbecky6baf6442019-05-30 14:57:43 +0100757 int32_t length = GetVReg(B());
Vladimir Marko9b81ac32019-05-16 16:47:08 +0100758 ObjPtr<mirror::Object> obj = AllocArrayFromCode<do_access_check>(
David Srbeckyd6f579c2019-05-29 18:09:30 +0100759 dex::TypeIndex(C()),
David Srbecky6da82472018-10-23 14:03:08 +0100760 length,
761 shadow_frame.GetMethod(),
762 self,
763 Runtime::Current()->GetHeap()->GetCurrentAllocator());
764 if (UNLIKELY(obj == nullptr)) {
David Srbecky8d335b62019-06-06 14:25:42 +0100765 return false; // Pending exception.
David Srbecky6da82472018-10-23 14:03:08 +0100766 } else {
David Srbecky6baf6442019-05-30 14:57:43 +0100767 SetVRegReference(A(), obj);
David Srbecky6da82472018-10-23 14:03:08 +0100768 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100769 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100770 }
771
David Srbecky27351be2019-07-12 13:39:34 +0100772 HANDLER_ATTRIBUTES bool FILLED_NEW_ARRAY() {
David Srbecky8d335b62019-06-06 14:25:42 +0100773 return DoFilledNewArray<false, do_access_check, transaction_active>(
774 inst, shadow_frame, self, ResultRegister());
David Srbecky6da82472018-10-23 14:03:08 +0100775 }
776
David Srbecky27351be2019-07-12 13:39:34 +0100777 HANDLER_ATTRIBUTES bool FILLED_NEW_ARRAY_RANGE() {
David Srbecky8d335b62019-06-06 14:25:42 +0100778 return DoFilledNewArray<true, do_access_check, transaction_active>(
779 inst, shadow_frame, self, ResultRegister());
David Srbecky6da82472018-10-23 14:03:08 +0100780 }
781
David Srbecky27351be2019-07-12 13:39:34 +0100782 HANDLER_ATTRIBUTES bool FILL_ARRAY_DATA() {
David Srbeckyd6f579c2019-05-29 18:09:30 +0100783 const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst) + B();
David Srbecky6da82472018-10-23 14:03:08 +0100784 const Instruction::ArrayDataPayload* payload =
785 reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr);
David Srbecky6baf6442019-05-30 14:57:43 +0100786 ObjPtr<mirror::Object> obj = GetVRegReference(A());
David Srbecky8d335b62019-06-06 14:25:42 +0100787 if (!FillArrayData(obj, payload)) {
788 return false; // Pending exception.
David Srbecky6da82472018-10-23 14:03:08 +0100789 }
790 if (transaction_active) {
791 RecordArrayElementsInTransaction(obj->AsArray(), payload->element_count);
792 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100793 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100794 }
795
David Srbecky27351be2019-07-12 13:39:34 +0100796 HANDLER_ATTRIBUTES bool THROW() {
David Srbecky47ad3762018-10-31 12:43:40 +0000797 if (!HandleAsyncException()) {
David Srbeckybd613ec2019-05-30 15:39:38 +0100798 return false;
David Srbecky47ad3762018-10-31 12:43:40 +0000799 }
David Srbecky6baf6442019-05-30 14:57:43 +0100800 ObjPtr<mirror::Object> exception = GetVRegReference(A());
David Srbecky6da82472018-10-23 14:03:08 +0100801 if (UNLIKELY(exception == nullptr)) {
Nicolas Geoffray635967b2019-08-07 10:15:39 +0100802 ThrowNullPointerException();
David Srbecky6da82472018-10-23 14:03:08 +0100803 } else if (do_assignability_check && !exception->GetClass()->IsThrowableClass()) {
804 // This should never happen.
805 std::string temp;
806 self->ThrowNewExceptionF("Ljava/lang/InternalError;",
807 "Throwing '%s' that is not instance of Throwable",
808 exception->GetClass()->GetDescriptor(&temp));
809 } else {
810 self->SetException(exception->AsThrowable());
811 }
David Srbecky8d335b62019-06-06 14:25:42 +0100812 return false; // Pending exception.
David Srbecky6da82472018-10-23 14:03:08 +0100813 }
814
David Srbecky27351be2019-07-12 13:39:34 +0100815 HANDLER_ATTRIBUTES bool GOTO() {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100816 return HandleGoto(A());
David Srbecky6da82472018-10-23 14:03:08 +0100817 }
818
David Srbecky27351be2019-07-12 13:39:34 +0100819 HANDLER_ATTRIBUTES bool GOTO_16() {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100820 return HandleGoto(A());
David Srbecky6da82472018-10-23 14:03:08 +0100821 }
822
David Srbecky27351be2019-07-12 13:39:34 +0100823 HANDLER_ATTRIBUTES bool GOTO_32() {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100824 return HandleGoto(A());
David Srbecky6da82472018-10-23 14:03:08 +0100825 }
826
David Srbecky27351be2019-07-12 13:39:34 +0100827 HANDLER_ATTRIBUTES bool PACKED_SWITCH() {
David Srbecky6da82472018-10-23 14:03:08 +0100828 int32_t offset = DoPackedSwitch(inst, shadow_frame, inst_data);
David Srbecky8d335b62019-06-06 14:25:42 +0100829 if (!BranchInstrumentation(offset)) {
830 return false;
831 }
David Srbecky8867f3b2019-05-31 20:01:46 +0100832 SetNextInstruction(inst->RelativeAt(offset));
David Srbecky47ad3762018-10-31 12:43:40 +0000833 HandleBackwardBranch(offset);
David Srbeckybd613ec2019-05-30 15:39:38 +0100834 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100835 }
836
David Srbecky27351be2019-07-12 13:39:34 +0100837 HANDLER_ATTRIBUTES bool SPARSE_SWITCH() {
David Srbecky6da82472018-10-23 14:03:08 +0100838 int32_t offset = DoSparseSwitch(inst, shadow_frame, inst_data);
David Srbecky8d335b62019-06-06 14:25:42 +0100839 if (!BranchInstrumentation(offset)) {
840 return false;
841 }
David Srbecky8867f3b2019-05-31 20:01:46 +0100842 SetNextInstruction(inst->RelativeAt(offset));
David Srbecky47ad3762018-10-31 12:43:40 +0000843 HandleBackwardBranch(offset);
David Srbeckybd613ec2019-05-30 15:39:38 +0100844 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100845 }
846
David Srbecky27351be2019-07-12 13:39:34 +0100847 HANDLER_ATTRIBUTES bool CMPL_FLOAT() {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100848 return HandleCmpl<float>(GetVRegFloat(B()), GetVRegFloat(C()));
David Srbecky6da82472018-10-23 14:03:08 +0100849 }
850
David Srbecky27351be2019-07-12 13:39:34 +0100851 HANDLER_ATTRIBUTES bool CMPG_FLOAT() {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100852 return HandleCmpg<float>(GetVRegFloat(B()), GetVRegFloat(C()));
David Srbecky6da82472018-10-23 14:03:08 +0100853 }
854
David Srbecky27351be2019-07-12 13:39:34 +0100855 HANDLER_ATTRIBUTES bool CMPL_DOUBLE() {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100856 return HandleCmpl<double>(GetVRegDouble(B()), GetVRegDouble(C()));
David Srbecky6da82472018-10-23 14:03:08 +0100857 }
858
David Srbecky27351be2019-07-12 13:39:34 +0100859 HANDLER_ATTRIBUTES bool CMPG_DOUBLE() {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100860 return HandleCmpg<double>(GetVRegDouble(B()), GetVRegDouble(C()));
David Srbecky6da82472018-10-23 14:03:08 +0100861 }
862
David Srbecky27351be2019-07-12 13:39:34 +0100863 HANDLER_ATTRIBUTES bool CMP_LONG() {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100864 return HandleCmpl<int64_t>(GetVRegLong(B()), GetVRegLong(C()));
David Srbecky6da82472018-10-23 14:03:08 +0100865 }
866
David Srbecky27351be2019-07-12 13:39:34 +0100867 HANDLER_ATTRIBUTES bool IF_EQ() {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100868 return HandleIf(GetVReg(A()) == GetVReg(B()), C());
David Srbecky6da82472018-10-23 14:03:08 +0100869 }
870
David Srbecky27351be2019-07-12 13:39:34 +0100871 HANDLER_ATTRIBUTES bool IF_NE() {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100872 return HandleIf(GetVReg(A()) != GetVReg(B()), C());
David Srbecky6da82472018-10-23 14:03:08 +0100873 }
874
David Srbecky27351be2019-07-12 13:39:34 +0100875 HANDLER_ATTRIBUTES bool IF_LT() {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100876 return HandleIf(GetVReg(A()) < GetVReg(B()), C());
David Srbecky6da82472018-10-23 14:03:08 +0100877 }
878
David Srbecky27351be2019-07-12 13:39:34 +0100879 HANDLER_ATTRIBUTES bool IF_GE() {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100880 return HandleIf(GetVReg(A()) >= GetVReg(B()), C());
David Srbecky6da82472018-10-23 14:03:08 +0100881 }
882
David Srbecky27351be2019-07-12 13:39:34 +0100883 HANDLER_ATTRIBUTES bool IF_GT() {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100884 return HandleIf(GetVReg(A()) > GetVReg(B()), C());
David Srbecky6da82472018-10-23 14:03:08 +0100885 }
886
David Srbecky27351be2019-07-12 13:39:34 +0100887 HANDLER_ATTRIBUTES bool IF_LE() {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100888 return HandleIf(GetVReg(A()) <= GetVReg(B()), C());
David Srbecky6da82472018-10-23 14:03:08 +0100889 }
890
David Srbecky27351be2019-07-12 13:39:34 +0100891 HANDLER_ATTRIBUTES bool IF_EQZ() {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100892 return HandleIf(GetVReg(A()) == 0, B());
David Srbecky6da82472018-10-23 14:03:08 +0100893 }
894
David Srbecky27351be2019-07-12 13:39:34 +0100895 HANDLER_ATTRIBUTES bool IF_NEZ() {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100896 return HandleIf(GetVReg(A()) != 0, B());
David Srbecky6da82472018-10-23 14:03:08 +0100897 }
898
David Srbecky27351be2019-07-12 13:39:34 +0100899 HANDLER_ATTRIBUTES bool IF_LTZ() {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100900 return HandleIf(GetVReg(A()) < 0, B());
David Srbecky6da82472018-10-23 14:03:08 +0100901 }
902
David Srbecky27351be2019-07-12 13:39:34 +0100903 HANDLER_ATTRIBUTES bool IF_GEZ() {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100904 return HandleIf(GetVReg(A()) >= 0, B());
David Srbecky6da82472018-10-23 14:03:08 +0100905 }
906
David Srbecky27351be2019-07-12 13:39:34 +0100907 HANDLER_ATTRIBUTES bool IF_GTZ() {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100908 return HandleIf(GetVReg(A()) > 0, B());
David Srbecky6da82472018-10-23 14:03:08 +0100909 }
910
David Srbecky27351be2019-07-12 13:39:34 +0100911 HANDLER_ATTRIBUTES bool IF_LEZ() {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100912 return HandleIf(GetVReg(A()) <= 0, B());
David Srbecky6da82472018-10-23 14:03:08 +0100913 }
914
David Srbecky27351be2019-07-12 13:39:34 +0100915 HANDLER_ATTRIBUTES bool AGET_BOOLEAN() {
David Srbecky1332c262019-06-04 13:13:37 +0100916 return HandleAGet<mirror::BooleanArray>(&InstructionHandler::SetVReg);
David Srbecky6da82472018-10-23 14:03:08 +0100917 }
918
David Srbecky27351be2019-07-12 13:39:34 +0100919 HANDLER_ATTRIBUTES bool AGET_BYTE() {
David Srbecky1332c262019-06-04 13:13:37 +0100920 return HandleAGet<mirror::ByteArray>(&InstructionHandler::SetVReg);
David Srbecky6da82472018-10-23 14:03:08 +0100921 }
922
David Srbecky27351be2019-07-12 13:39:34 +0100923 HANDLER_ATTRIBUTES bool AGET_CHAR() {
David Srbecky1332c262019-06-04 13:13:37 +0100924 return HandleAGet<mirror::CharArray>(&InstructionHandler::SetVReg);
David Srbecky6da82472018-10-23 14:03:08 +0100925 }
926
David Srbecky27351be2019-07-12 13:39:34 +0100927 HANDLER_ATTRIBUTES bool AGET_SHORT() {
David Srbecky1332c262019-06-04 13:13:37 +0100928 return HandleAGet<mirror::ShortArray>(&InstructionHandler::SetVReg);
David Srbecky6da82472018-10-23 14:03:08 +0100929 }
930
David Srbecky27351be2019-07-12 13:39:34 +0100931 HANDLER_ATTRIBUTES bool AGET() {
David Srbecky1332c262019-06-04 13:13:37 +0100932 return HandleAGet<mirror::IntArray>(&InstructionHandler::SetVReg);
David Srbecky6da82472018-10-23 14:03:08 +0100933 }
934
David Srbecky27351be2019-07-12 13:39:34 +0100935 HANDLER_ATTRIBUTES bool AGET_WIDE() {
David Srbecky1332c262019-06-04 13:13:37 +0100936 return HandleAGet<mirror::LongArray>(&InstructionHandler::SetVRegLong);
David Srbecky6da82472018-10-23 14:03:08 +0100937 }
938
David Srbecky27351be2019-07-12 13:39:34 +0100939 HANDLER_ATTRIBUTES bool AGET_OBJECT() {
David Srbecky1332c262019-06-04 13:13:37 +0100940 return HandleAGet<mirror::ObjectArray<mirror::Object>>(&InstructionHandler::SetVRegReference);
David Srbecky6da82472018-10-23 14:03:08 +0100941 }
942
David Srbecky27351be2019-07-12 13:39:34 +0100943 HANDLER_ATTRIBUTES bool APUT_BOOLEAN() {
David Srbecky1332c262019-06-04 13:13:37 +0100944 return HandleAPut<mirror::BooleanArray>(GetVReg(A()));
David Srbecky6da82472018-10-23 14:03:08 +0100945 }
946
David Srbecky27351be2019-07-12 13:39:34 +0100947 HANDLER_ATTRIBUTES bool APUT_BYTE() {
David Srbecky1332c262019-06-04 13:13:37 +0100948 return HandleAPut<mirror::ByteArray>(GetVReg(A()));
David Srbecky6da82472018-10-23 14:03:08 +0100949 }
950
David Srbecky27351be2019-07-12 13:39:34 +0100951 HANDLER_ATTRIBUTES bool APUT_CHAR() {
David Srbecky1332c262019-06-04 13:13:37 +0100952 return HandleAPut<mirror::CharArray>(GetVReg(A()));
David Srbecky6da82472018-10-23 14:03:08 +0100953 }
954
David Srbecky27351be2019-07-12 13:39:34 +0100955 HANDLER_ATTRIBUTES bool APUT_SHORT() {
David Srbecky1332c262019-06-04 13:13:37 +0100956 return HandleAPut<mirror::ShortArray>(GetVReg(A()));
David Srbecky6da82472018-10-23 14:03:08 +0100957 }
958
David Srbecky27351be2019-07-12 13:39:34 +0100959 HANDLER_ATTRIBUTES bool APUT() {
David Srbecky1332c262019-06-04 13:13:37 +0100960 return HandleAPut<mirror::IntArray>(GetVReg(A()));
David Srbecky6da82472018-10-23 14:03:08 +0100961 }
962
David Srbecky27351be2019-07-12 13:39:34 +0100963 HANDLER_ATTRIBUTES bool APUT_WIDE() {
David Srbecky1332c262019-06-04 13:13:37 +0100964 return HandleAPut<mirror::LongArray>(GetVRegLong(A()));
David Srbecky6da82472018-10-23 14:03:08 +0100965 }
966
David Srbecky27351be2019-07-12 13:39:34 +0100967 HANDLER_ATTRIBUTES bool APUT_OBJECT() {
David Srbecky6baf6442019-05-30 14:57:43 +0100968 ObjPtr<mirror::Object> a = GetVRegReference(B());
David Srbecky6da82472018-10-23 14:03:08 +0100969 if (UNLIKELY(a == nullptr)) {
970 ThrowNullPointerExceptionFromInterpreter();
David Srbecky8d335b62019-06-06 14:25:42 +0100971 return false; // Pending exception.
David Srbecky6da82472018-10-23 14:03:08 +0100972 }
David Srbecky6baf6442019-05-30 14:57:43 +0100973 int32_t index = GetVReg(C());
974 ObjPtr<mirror::Object> val = GetVRegReference(A());
David Srbecky6da82472018-10-23 14:03:08 +0100975 ObjPtr<mirror::ObjectArray<mirror::Object>> array = a->AsObjectArray<mirror::Object>();
976 if (array->CheckIsValidIndex(index) && array->CheckAssignable(val)) {
977 array->SetWithoutChecks<transaction_active>(index, val);
David Srbecky6da82472018-10-23 14:03:08 +0100978 } else {
David Srbecky8d335b62019-06-06 14:25:42 +0100979 return false; // Pending exception.
David Srbecky6da82472018-10-23 14:03:08 +0100980 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100981 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100982 }
983
David Srbecky27351be2019-07-12 13:39:34 +0100984 HANDLER_ATTRIBUTES bool IGET_BOOLEAN() {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100985 return HandleGet<InstancePrimitiveRead, Primitive::kPrimBoolean>();
David Srbecky6da82472018-10-23 14:03:08 +0100986 }
987
David Srbecky27351be2019-07-12 13:39:34 +0100988 HANDLER_ATTRIBUTES bool IGET_BYTE() {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100989 return HandleGet<InstancePrimitiveRead, Primitive::kPrimByte>();
David Srbecky6da82472018-10-23 14:03:08 +0100990 }
991
David Srbecky27351be2019-07-12 13:39:34 +0100992 HANDLER_ATTRIBUTES bool IGET_CHAR() {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100993 return HandleGet<InstancePrimitiveRead, Primitive::kPrimChar>();
David Srbecky6da82472018-10-23 14:03:08 +0100994 }
995
David Srbecky27351be2019-07-12 13:39:34 +0100996 HANDLER_ATTRIBUTES bool IGET_SHORT() {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100997 return HandleGet<InstancePrimitiveRead, Primitive::kPrimShort>();
David Srbecky6da82472018-10-23 14:03:08 +0100998 }
999
David Srbecky27351be2019-07-12 13:39:34 +01001000 HANDLER_ATTRIBUTES bool IGET() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001001 return HandleGet<InstancePrimitiveRead, Primitive::kPrimInt>();
David Srbecky6da82472018-10-23 14:03:08 +01001002 }
1003
David Srbecky27351be2019-07-12 13:39:34 +01001004 HANDLER_ATTRIBUTES bool IGET_WIDE() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001005 return HandleGet<InstancePrimitiveRead, Primitive::kPrimLong>();
David Srbecky6da82472018-10-23 14:03:08 +01001006 }
1007
David Srbecky27351be2019-07-12 13:39:34 +01001008 HANDLER_ATTRIBUTES bool IGET_OBJECT() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001009 return HandleGet<InstanceObjectRead, Primitive::kPrimNot>();
David Srbecky6da82472018-10-23 14:03:08 +01001010 }
1011
David Srbecky27351be2019-07-12 13:39:34 +01001012 HANDLER_ATTRIBUTES bool IGET_QUICK() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001013 return HandleGetQuick<Primitive::kPrimInt>();
David Srbecky6da82472018-10-23 14:03:08 +01001014 }
1015
David Srbecky27351be2019-07-12 13:39:34 +01001016 HANDLER_ATTRIBUTES bool IGET_WIDE_QUICK() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001017 return HandleGetQuick<Primitive::kPrimLong>();
David Srbecky6da82472018-10-23 14:03:08 +01001018 }
1019
David Srbecky27351be2019-07-12 13:39:34 +01001020 HANDLER_ATTRIBUTES bool IGET_OBJECT_QUICK() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001021 return HandleGetQuick<Primitive::kPrimNot>();
David Srbecky6da82472018-10-23 14:03:08 +01001022 }
1023
David Srbecky27351be2019-07-12 13:39:34 +01001024 HANDLER_ATTRIBUTES bool IGET_BOOLEAN_QUICK() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001025 return HandleGetQuick<Primitive::kPrimBoolean>();
David Srbecky6da82472018-10-23 14:03:08 +01001026 }
1027
David Srbecky27351be2019-07-12 13:39:34 +01001028 HANDLER_ATTRIBUTES bool IGET_BYTE_QUICK() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001029 return HandleGetQuick<Primitive::kPrimByte>();
David Srbecky6da82472018-10-23 14:03:08 +01001030 }
1031
David Srbecky27351be2019-07-12 13:39:34 +01001032 HANDLER_ATTRIBUTES bool IGET_CHAR_QUICK() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001033 return HandleGetQuick<Primitive::kPrimChar>();
David Srbecky6da82472018-10-23 14:03:08 +01001034 }
1035
David Srbecky27351be2019-07-12 13:39:34 +01001036 HANDLER_ATTRIBUTES bool IGET_SHORT_QUICK() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001037 return HandleGetQuick<Primitive::kPrimShort>();
David Srbecky6da82472018-10-23 14:03:08 +01001038 }
1039
David Srbecky27351be2019-07-12 13:39:34 +01001040 HANDLER_ATTRIBUTES bool SGET_BOOLEAN() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001041 return HandleGet<StaticPrimitiveRead, Primitive::kPrimBoolean>();
David Srbecky6da82472018-10-23 14:03:08 +01001042 }
1043
David Srbecky27351be2019-07-12 13:39:34 +01001044 HANDLER_ATTRIBUTES bool SGET_BYTE() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001045 return HandleGet<StaticPrimitiveRead, Primitive::kPrimByte>();
David Srbecky6da82472018-10-23 14:03:08 +01001046 }
1047
David Srbecky27351be2019-07-12 13:39:34 +01001048 HANDLER_ATTRIBUTES bool SGET_CHAR() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001049 return HandleGet<StaticPrimitiveRead, Primitive::kPrimChar>();
David Srbecky6da82472018-10-23 14:03:08 +01001050 }
1051
David Srbecky27351be2019-07-12 13:39:34 +01001052 HANDLER_ATTRIBUTES bool SGET_SHORT() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001053 return HandleGet<StaticPrimitiveRead, Primitive::kPrimShort>();
David Srbecky6da82472018-10-23 14:03:08 +01001054 }
1055
David Srbecky27351be2019-07-12 13:39:34 +01001056 HANDLER_ATTRIBUTES bool SGET() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001057 return HandleGet<StaticPrimitiveRead, Primitive::kPrimInt>();
David Srbecky6da82472018-10-23 14:03:08 +01001058 }
1059
David Srbecky27351be2019-07-12 13:39:34 +01001060 HANDLER_ATTRIBUTES bool SGET_WIDE() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001061 return HandleGet<StaticPrimitiveRead, Primitive::kPrimLong>();
David Srbecky6da82472018-10-23 14:03:08 +01001062 }
1063
David Srbecky27351be2019-07-12 13:39:34 +01001064 HANDLER_ATTRIBUTES bool SGET_OBJECT() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001065 return HandleGet<StaticObjectRead, Primitive::kPrimNot>();
David Srbecky6da82472018-10-23 14:03:08 +01001066 }
1067
David Srbecky27351be2019-07-12 13:39:34 +01001068 HANDLER_ATTRIBUTES bool IPUT_BOOLEAN() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001069 return HandlePut<InstancePrimitiveWrite, Primitive::kPrimBoolean>();
David Srbecky6da82472018-10-23 14:03:08 +01001070 }
1071
David Srbecky27351be2019-07-12 13:39:34 +01001072 HANDLER_ATTRIBUTES bool IPUT_BYTE() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001073 return HandlePut<InstancePrimitiveWrite, Primitive::kPrimByte>();
David Srbecky6da82472018-10-23 14:03:08 +01001074 }
1075
David Srbecky27351be2019-07-12 13:39:34 +01001076 HANDLER_ATTRIBUTES bool IPUT_CHAR() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001077 return HandlePut<InstancePrimitiveWrite, Primitive::kPrimChar>();
David Srbecky6da82472018-10-23 14:03:08 +01001078 }
1079
David Srbecky27351be2019-07-12 13:39:34 +01001080 HANDLER_ATTRIBUTES bool IPUT_SHORT() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001081 return HandlePut<InstancePrimitiveWrite, Primitive::kPrimShort>();
David Srbecky6da82472018-10-23 14:03:08 +01001082 }
1083
David Srbecky27351be2019-07-12 13:39:34 +01001084 HANDLER_ATTRIBUTES bool IPUT() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001085 return HandlePut<InstancePrimitiveWrite, Primitive::kPrimInt>();
David Srbecky6da82472018-10-23 14:03:08 +01001086 }
1087
David Srbecky27351be2019-07-12 13:39:34 +01001088 HANDLER_ATTRIBUTES bool IPUT_WIDE() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001089 return HandlePut<InstancePrimitiveWrite, Primitive::kPrimLong>();
David Srbecky6da82472018-10-23 14:03:08 +01001090 }
1091
David Srbecky27351be2019-07-12 13:39:34 +01001092 HANDLER_ATTRIBUTES bool IPUT_OBJECT() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001093 return HandlePut<InstanceObjectWrite, Primitive::kPrimNot>();
David Srbecky6da82472018-10-23 14:03:08 +01001094 }
1095
David Srbecky27351be2019-07-12 13:39:34 +01001096 HANDLER_ATTRIBUTES bool IPUT_QUICK() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001097 return HandlePutQuick<Primitive::kPrimInt>();
David Srbecky6da82472018-10-23 14:03:08 +01001098 }
1099
David Srbecky27351be2019-07-12 13:39:34 +01001100 HANDLER_ATTRIBUTES bool IPUT_BOOLEAN_QUICK() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001101 return HandlePutQuick<Primitive::kPrimBoolean>();
David Srbecky6da82472018-10-23 14:03:08 +01001102 }
1103
David Srbecky27351be2019-07-12 13:39:34 +01001104 HANDLER_ATTRIBUTES bool IPUT_BYTE_QUICK() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001105 return HandlePutQuick<Primitive::kPrimByte>();
David Srbecky6da82472018-10-23 14:03:08 +01001106 }
1107
David Srbecky27351be2019-07-12 13:39:34 +01001108 HANDLER_ATTRIBUTES bool IPUT_CHAR_QUICK() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001109 return HandlePutQuick<Primitive::kPrimChar>();
David Srbecky6da82472018-10-23 14:03:08 +01001110 }
1111
David Srbecky27351be2019-07-12 13:39:34 +01001112 HANDLER_ATTRIBUTES bool IPUT_SHORT_QUICK() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001113 return HandlePutQuick<Primitive::kPrimShort>();
David Srbecky6da82472018-10-23 14:03:08 +01001114 }
1115
David Srbecky27351be2019-07-12 13:39:34 +01001116 HANDLER_ATTRIBUTES bool IPUT_WIDE_QUICK() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001117 return HandlePutQuick<Primitive::kPrimLong>();
David Srbecky6da82472018-10-23 14:03:08 +01001118 }
1119
David Srbecky27351be2019-07-12 13:39:34 +01001120 HANDLER_ATTRIBUTES bool IPUT_OBJECT_QUICK() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001121 return HandlePutQuick<Primitive::kPrimNot>();
David Srbecky6da82472018-10-23 14:03:08 +01001122 }
1123
David Srbecky27351be2019-07-12 13:39:34 +01001124 HANDLER_ATTRIBUTES bool SPUT_BOOLEAN() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001125 return HandlePut<StaticPrimitiveWrite, Primitive::kPrimBoolean>();
David Srbecky6da82472018-10-23 14:03:08 +01001126 }
1127
David Srbecky27351be2019-07-12 13:39:34 +01001128 HANDLER_ATTRIBUTES bool SPUT_BYTE() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001129 return HandlePut<StaticPrimitiveWrite, Primitive::kPrimByte>();
David Srbecky6da82472018-10-23 14:03:08 +01001130 }
1131
David Srbecky27351be2019-07-12 13:39:34 +01001132 HANDLER_ATTRIBUTES bool SPUT_CHAR() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001133 return HandlePut<StaticPrimitiveWrite, Primitive::kPrimChar>();
David Srbecky6da82472018-10-23 14:03:08 +01001134 }
1135
David Srbecky27351be2019-07-12 13:39:34 +01001136 HANDLER_ATTRIBUTES bool SPUT_SHORT() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001137 return HandlePut<StaticPrimitiveWrite, Primitive::kPrimShort>();
David Srbecky6da82472018-10-23 14:03:08 +01001138 }
1139
David Srbecky27351be2019-07-12 13:39:34 +01001140 HANDLER_ATTRIBUTES bool SPUT() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001141 return HandlePut<StaticPrimitiveWrite, Primitive::kPrimInt>();
David Srbecky6da82472018-10-23 14:03:08 +01001142 }
1143
David Srbecky27351be2019-07-12 13:39:34 +01001144 HANDLER_ATTRIBUTES bool SPUT_WIDE() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001145 return HandlePut<StaticPrimitiveWrite, Primitive::kPrimLong>();
David Srbecky6da82472018-10-23 14:03:08 +01001146 }
1147
David Srbecky27351be2019-07-12 13:39:34 +01001148 HANDLER_ATTRIBUTES bool SPUT_OBJECT() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001149 return HandlePut<StaticObjectWrite, Primitive::kPrimNot>();
David Srbecky6da82472018-10-23 14:03:08 +01001150 }
1151
David Srbecky27351be2019-07-12 13:39:34 +01001152 HANDLER_ATTRIBUTES bool INVOKE_VIRTUAL() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001153 return HandleInvoke<kVirtual, /*is_range=*/ false>();
David Srbecky6da82472018-10-23 14:03:08 +01001154 }
1155
David Srbecky27351be2019-07-12 13:39:34 +01001156 HANDLER_ATTRIBUTES bool INVOKE_VIRTUAL_RANGE() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001157 return HandleInvoke<kVirtual, /*is_range=*/ true>();
David Srbecky6da82472018-10-23 14:03:08 +01001158 }
1159
David Srbecky27351be2019-07-12 13:39:34 +01001160 HANDLER_ATTRIBUTES bool INVOKE_SUPER() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001161 return HandleInvoke<kSuper, /*is_range=*/ false>();
David Srbecky6da82472018-10-23 14:03:08 +01001162 }
1163
David Srbecky27351be2019-07-12 13:39:34 +01001164 HANDLER_ATTRIBUTES bool INVOKE_SUPER_RANGE() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001165 return HandleInvoke<kSuper, /*is_range=*/ true>();
David Srbecky6da82472018-10-23 14:03:08 +01001166 }
1167
David Srbecky27351be2019-07-12 13:39:34 +01001168 HANDLER_ATTRIBUTES bool INVOKE_DIRECT() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001169 return HandleInvoke<kDirect, /*is_range=*/ false>();
David Srbecky6da82472018-10-23 14:03:08 +01001170 }
1171
David Srbecky27351be2019-07-12 13:39:34 +01001172 HANDLER_ATTRIBUTES bool INVOKE_DIRECT_RANGE() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001173 return HandleInvoke<kDirect, /*is_range=*/ true>();
David Srbecky6da82472018-10-23 14:03:08 +01001174 }
1175
David Srbecky27351be2019-07-12 13:39:34 +01001176 HANDLER_ATTRIBUTES bool INVOKE_INTERFACE() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001177 return HandleInvoke<kInterface, /*is_range=*/ false>();
David Srbecky6da82472018-10-23 14:03:08 +01001178 }
1179
David Srbecky27351be2019-07-12 13:39:34 +01001180 HANDLER_ATTRIBUTES bool INVOKE_INTERFACE_RANGE() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001181 return HandleInvoke<kInterface, /*is_range=*/ true>();
David Srbecky6da82472018-10-23 14:03:08 +01001182 }
1183
David Srbecky27351be2019-07-12 13:39:34 +01001184 HANDLER_ATTRIBUTES bool INVOKE_STATIC() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001185 return HandleInvoke<kStatic, /*is_range=*/ false>();
David Srbecky6da82472018-10-23 14:03:08 +01001186 }
1187
David Srbecky27351be2019-07-12 13:39:34 +01001188 HANDLER_ATTRIBUTES bool INVOKE_STATIC_RANGE() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001189 return HandleInvoke<kStatic, /*is_range=*/ true>();
David Srbecky6da82472018-10-23 14:03:08 +01001190 }
1191
David Srbecky27351be2019-07-12 13:39:34 +01001192 HANDLER_ATTRIBUTES bool INVOKE_VIRTUAL_QUICK() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001193 return HandleInvoke<kVirtual, /*is_range=*/ false, /*is_quick=*/ true>();
David Srbecky6da82472018-10-23 14:03:08 +01001194 }
1195
David Srbecky27351be2019-07-12 13:39:34 +01001196 HANDLER_ATTRIBUTES bool INVOKE_VIRTUAL_RANGE_QUICK() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001197 return HandleInvoke<kVirtual, /*is_range=*/ true, /*is_quick=*/ true>();
David Srbecky6da82472018-10-23 14:03:08 +01001198 }
1199
David Srbecky27351be2019-07-12 13:39:34 +01001200 HANDLER_ATTRIBUTES bool INVOKE_POLYMORPHIC() {
David Srbecky6da82472018-10-23 14:03:08 +01001201 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
1202 bool success = DoInvokePolymorphic</* is_range= */ false>(
1203 self, shadow_frame, inst, inst_data, ResultRegister());
David Srbecky8d335b62019-06-06 14:25:42 +01001204 return PossiblyHandlePendingExceptionOnInvoke(!success);
David Srbecky6da82472018-10-23 14:03:08 +01001205 }
1206
David Srbecky27351be2019-07-12 13:39:34 +01001207 HANDLER_ATTRIBUTES bool INVOKE_POLYMORPHIC_RANGE() {
David Srbecky6da82472018-10-23 14:03:08 +01001208 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
1209 bool success = DoInvokePolymorphic</* is_range= */ true>(
1210 self, shadow_frame, inst, inst_data, ResultRegister());
David Srbecky8d335b62019-06-06 14:25:42 +01001211 return PossiblyHandlePendingExceptionOnInvoke(!success);
David Srbecky6da82472018-10-23 14:03:08 +01001212 }
1213
David Srbecky27351be2019-07-12 13:39:34 +01001214 HANDLER_ATTRIBUTES bool INVOKE_CUSTOM() {
David Srbecky6da82472018-10-23 14:03:08 +01001215 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
1216 bool success = DoInvokeCustom</* is_range= */ false>(
1217 self, shadow_frame, inst, inst_data, ResultRegister());
David Srbecky8d335b62019-06-06 14:25:42 +01001218 return PossiblyHandlePendingExceptionOnInvoke(!success);
David Srbecky6da82472018-10-23 14:03:08 +01001219 }
1220
David Srbecky27351be2019-07-12 13:39:34 +01001221 HANDLER_ATTRIBUTES bool INVOKE_CUSTOM_RANGE() {
David Srbecky6da82472018-10-23 14:03:08 +01001222 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
1223 bool success = DoInvokeCustom</* is_range= */ true>(
1224 self, shadow_frame, inst, inst_data, ResultRegister());
David Srbecky8d335b62019-06-06 14:25:42 +01001225 return PossiblyHandlePendingExceptionOnInvoke(!success);
David Srbecky6da82472018-10-23 14:03:08 +01001226 }
1227
David Srbecky27351be2019-07-12 13:39:34 +01001228 HANDLER_ATTRIBUTES bool NEG_INT() {
David Srbecky6baf6442019-05-30 14:57:43 +01001229 SetVReg(A(), -GetVReg(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001230 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001231 }
1232
David Srbecky27351be2019-07-12 13:39:34 +01001233 HANDLER_ATTRIBUTES bool NOT_INT() {
David Srbecky6baf6442019-05-30 14:57:43 +01001234 SetVReg(A(), ~GetVReg(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001235 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001236 }
1237
David Srbecky27351be2019-07-12 13:39:34 +01001238 HANDLER_ATTRIBUTES bool NEG_LONG() {
David Srbecky6baf6442019-05-30 14:57:43 +01001239 SetVRegLong(A(), -GetVRegLong(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001240 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001241 }
1242
David Srbecky27351be2019-07-12 13:39:34 +01001243 HANDLER_ATTRIBUTES bool NOT_LONG() {
David Srbecky6baf6442019-05-30 14:57:43 +01001244 SetVRegLong(A(), ~GetVRegLong(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001245 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001246 }
1247
David Srbecky27351be2019-07-12 13:39:34 +01001248 HANDLER_ATTRIBUTES bool NEG_FLOAT() {
David Srbecky6baf6442019-05-30 14:57:43 +01001249 SetVRegFloat(A(), -GetVRegFloat(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001250 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001251 }
1252
David Srbecky27351be2019-07-12 13:39:34 +01001253 HANDLER_ATTRIBUTES bool NEG_DOUBLE() {
David Srbecky6baf6442019-05-30 14:57:43 +01001254 SetVRegDouble(A(), -GetVRegDouble(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001255 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001256 }
1257
David Srbecky27351be2019-07-12 13:39:34 +01001258 HANDLER_ATTRIBUTES bool INT_TO_LONG() {
David Srbecky6baf6442019-05-30 14:57:43 +01001259 SetVRegLong(A(), GetVReg(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001260 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001261 }
1262
David Srbecky27351be2019-07-12 13:39:34 +01001263 HANDLER_ATTRIBUTES bool INT_TO_FLOAT() {
David Srbecky6baf6442019-05-30 14:57:43 +01001264 SetVRegFloat(A(), GetVReg(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001265 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001266 }
1267
David Srbecky27351be2019-07-12 13:39:34 +01001268 HANDLER_ATTRIBUTES bool INT_TO_DOUBLE() {
David Srbecky6baf6442019-05-30 14:57:43 +01001269 SetVRegDouble(A(), GetVReg(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001270 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001271 }
1272
David Srbecky27351be2019-07-12 13:39:34 +01001273 HANDLER_ATTRIBUTES bool LONG_TO_INT() {
David Srbecky6baf6442019-05-30 14:57:43 +01001274 SetVReg(A(), GetVRegLong(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001275 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001276 }
1277
David Srbecky27351be2019-07-12 13:39:34 +01001278 HANDLER_ATTRIBUTES bool LONG_TO_FLOAT() {
David Srbecky6baf6442019-05-30 14:57:43 +01001279 SetVRegFloat(A(), GetVRegLong(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001280 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001281 }
1282
David Srbecky27351be2019-07-12 13:39:34 +01001283 HANDLER_ATTRIBUTES bool LONG_TO_DOUBLE() {
David Srbecky6baf6442019-05-30 14:57:43 +01001284 SetVRegDouble(A(), GetVRegLong(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001285 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001286 }
1287
David Srbecky27351be2019-07-12 13:39:34 +01001288 HANDLER_ATTRIBUTES bool FLOAT_TO_INT() {
David Srbecky6baf6442019-05-30 14:57:43 +01001289 float val = GetVRegFloat(B());
David Srbecky6da82472018-10-23 14:03:08 +01001290 int32_t result = art_float_to_integral<int32_t, float>(val);
David Srbecky6baf6442019-05-30 14:57:43 +01001291 SetVReg(A(), result);
David Srbeckybd613ec2019-05-30 15:39:38 +01001292 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001293 }
1294
David Srbecky27351be2019-07-12 13:39:34 +01001295 HANDLER_ATTRIBUTES bool FLOAT_TO_LONG() {
David Srbecky6baf6442019-05-30 14:57:43 +01001296 float val = GetVRegFloat(B());
David Srbecky6da82472018-10-23 14:03:08 +01001297 int64_t result = art_float_to_integral<int64_t, float>(val);
David Srbecky6baf6442019-05-30 14:57:43 +01001298 SetVRegLong(A(), result);
David Srbeckybd613ec2019-05-30 15:39:38 +01001299 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001300 }
1301
David Srbecky27351be2019-07-12 13:39:34 +01001302 HANDLER_ATTRIBUTES bool FLOAT_TO_DOUBLE() {
David Srbecky6baf6442019-05-30 14:57:43 +01001303 SetVRegDouble(A(), GetVRegFloat(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001304 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001305 }
1306
David Srbecky27351be2019-07-12 13:39:34 +01001307 HANDLER_ATTRIBUTES bool DOUBLE_TO_INT() {
David Srbecky6baf6442019-05-30 14:57:43 +01001308 double val = GetVRegDouble(B());
David Srbecky6da82472018-10-23 14:03:08 +01001309 int32_t result = art_float_to_integral<int32_t, double>(val);
David Srbecky6baf6442019-05-30 14:57:43 +01001310 SetVReg(A(), result);
David Srbeckybd613ec2019-05-30 15:39:38 +01001311 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001312 }
1313
David Srbecky27351be2019-07-12 13:39:34 +01001314 HANDLER_ATTRIBUTES bool DOUBLE_TO_LONG() {
David Srbecky6baf6442019-05-30 14:57:43 +01001315 double val = GetVRegDouble(B());
David Srbecky6da82472018-10-23 14:03:08 +01001316 int64_t result = art_float_to_integral<int64_t, double>(val);
David Srbecky6baf6442019-05-30 14:57:43 +01001317 SetVRegLong(A(), result);
David Srbeckybd613ec2019-05-30 15:39:38 +01001318 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001319 }
1320
David Srbecky27351be2019-07-12 13:39:34 +01001321 HANDLER_ATTRIBUTES bool DOUBLE_TO_FLOAT() {
David Srbecky6baf6442019-05-30 14:57:43 +01001322 SetVRegFloat(A(), GetVRegDouble(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001323 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001324 }
1325
David Srbecky27351be2019-07-12 13:39:34 +01001326 HANDLER_ATTRIBUTES bool INT_TO_BYTE() {
David Srbecky6baf6442019-05-30 14:57:43 +01001327 SetVReg(A(), static_cast<int8_t>(GetVReg(B())));
David Srbeckybd613ec2019-05-30 15:39:38 +01001328 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001329 }
1330
David Srbecky27351be2019-07-12 13:39:34 +01001331 HANDLER_ATTRIBUTES bool INT_TO_CHAR() {
David Srbecky6baf6442019-05-30 14:57:43 +01001332 SetVReg(A(), static_cast<uint16_t>(GetVReg(B())));
David Srbeckybd613ec2019-05-30 15:39:38 +01001333 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001334 }
1335
David Srbecky27351be2019-07-12 13:39:34 +01001336 HANDLER_ATTRIBUTES bool INT_TO_SHORT() {
David Srbecky6baf6442019-05-30 14:57:43 +01001337 SetVReg(A(), static_cast<int16_t>(GetVReg(B())));
David Srbeckybd613ec2019-05-30 15:39:38 +01001338 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001339 }
1340
David Srbecky27351be2019-07-12 13:39:34 +01001341 HANDLER_ATTRIBUTES bool ADD_INT() {
David Srbecky6baf6442019-05-30 14:57:43 +01001342 SetVReg(A(), SafeAdd(GetVReg(B()), GetVReg(C())));
David Srbeckybd613ec2019-05-30 15:39:38 +01001343 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001344 }
1345
David Srbecky27351be2019-07-12 13:39:34 +01001346 HANDLER_ATTRIBUTES bool SUB_INT() {
David Srbecky6baf6442019-05-30 14:57:43 +01001347 SetVReg(A(), SafeSub(GetVReg(B()), GetVReg(C())));
David Srbeckybd613ec2019-05-30 15:39:38 +01001348 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001349 }
1350
David Srbecky27351be2019-07-12 13:39:34 +01001351 HANDLER_ATTRIBUTES bool MUL_INT() {
David Srbecky6baf6442019-05-30 14:57:43 +01001352 SetVReg(A(), SafeMul(GetVReg(B()), GetVReg(C())));
David Srbeckybd613ec2019-05-30 15:39:38 +01001353 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001354 }
1355
David Srbecky27351be2019-07-12 13:39:34 +01001356 HANDLER_ATTRIBUTES bool DIV_INT() {
David Srbecky8d335b62019-06-06 14:25:42 +01001357 return DoIntDivide(shadow_frame, A(), GetVReg(B()), GetVReg(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001358 }
1359
David Srbecky27351be2019-07-12 13:39:34 +01001360 HANDLER_ATTRIBUTES bool REM_INT() {
David Srbecky8d335b62019-06-06 14:25:42 +01001361 return DoIntRemainder(shadow_frame, A(), GetVReg(B()), GetVReg(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001362 }
1363
David Srbecky27351be2019-07-12 13:39:34 +01001364 HANDLER_ATTRIBUTES bool SHL_INT() {
David Srbecky6baf6442019-05-30 14:57:43 +01001365 SetVReg(A(), GetVReg(B()) << (GetVReg(C()) & 0x1f));
David Srbeckybd613ec2019-05-30 15:39:38 +01001366 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001367 }
1368
David Srbecky27351be2019-07-12 13:39:34 +01001369 HANDLER_ATTRIBUTES bool SHR_INT() {
David Srbecky6baf6442019-05-30 14:57:43 +01001370 SetVReg(A(), GetVReg(B()) >> (GetVReg(C()) & 0x1f));
David Srbeckybd613ec2019-05-30 15:39:38 +01001371 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001372 }
1373
David Srbecky27351be2019-07-12 13:39:34 +01001374 HANDLER_ATTRIBUTES bool USHR_INT() {
David Srbecky6baf6442019-05-30 14:57:43 +01001375 SetVReg(A(), static_cast<uint32_t>(GetVReg(B())) >> (GetVReg(C()) & 0x1f));
David Srbeckybd613ec2019-05-30 15:39:38 +01001376 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001377 }
1378
David Srbecky27351be2019-07-12 13:39:34 +01001379 HANDLER_ATTRIBUTES bool AND_INT() {
David Srbecky6baf6442019-05-30 14:57:43 +01001380 SetVReg(A(), GetVReg(B()) & GetVReg(C()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001381 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001382 }
1383
David Srbecky27351be2019-07-12 13:39:34 +01001384 HANDLER_ATTRIBUTES bool OR_INT() {
David Srbecky6baf6442019-05-30 14:57:43 +01001385 SetVReg(A(), GetVReg(B()) | GetVReg(C()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001386 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001387 }
1388
David Srbecky27351be2019-07-12 13:39:34 +01001389 HANDLER_ATTRIBUTES bool XOR_INT() {
David Srbecky6baf6442019-05-30 14:57:43 +01001390 SetVReg(A(), GetVReg(B()) ^ GetVReg(C()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001391 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001392 }
1393
David Srbecky27351be2019-07-12 13:39:34 +01001394 HANDLER_ATTRIBUTES bool ADD_LONG() {
David Srbecky6baf6442019-05-30 14:57:43 +01001395 SetVRegLong(A(), SafeAdd(GetVRegLong(B()), GetVRegLong(C())));
David Srbeckybd613ec2019-05-30 15:39:38 +01001396 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001397 }
1398
David Srbecky27351be2019-07-12 13:39:34 +01001399 HANDLER_ATTRIBUTES bool SUB_LONG() {
David Srbecky6baf6442019-05-30 14:57:43 +01001400 SetVRegLong(A(), SafeSub(GetVRegLong(B()), GetVRegLong(C())));
David Srbeckybd613ec2019-05-30 15:39:38 +01001401 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001402 }
1403
David Srbecky27351be2019-07-12 13:39:34 +01001404 HANDLER_ATTRIBUTES bool MUL_LONG() {
David Srbecky6baf6442019-05-30 14:57:43 +01001405 SetVRegLong(A(), SafeMul(GetVRegLong(B()), GetVRegLong(C())));
David Srbeckybd613ec2019-05-30 15:39:38 +01001406 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001407 }
1408
David Srbecky27351be2019-07-12 13:39:34 +01001409 HANDLER_ATTRIBUTES bool DIV_LONG() {
David Srbecky8d335b62019-06-06 14:25:42 +01001410 return DoLongDivide(shadow_frame, A(), GetVRegLong(B()), GetVRegLong(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001411 }
1412
David Srbecky27351be2019-07-12 13:39:34 +01001413 HANDLER_ATTRIBUTES bool REM_LONG() {
David Srbecky8d335b62019-06-06 14:25:42 +01001414 return DoLongRemainder(shadow_frame, A(), GetVRegLong(B()), GetVRegLong(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001415 }
1416
David Srbecky27351be2019-07-12 13:39:34 +01001417 HANDLER_ATTRIBUTES bool AND_LONG() {
David Srbecky6baf6442019-05-30 14:57:43 +01001418 SetVRegLong(A(), GetVRegLong(B()) & GetVRegLong(C()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001419 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001420 }
1421
David Srbecky27351be2019-07-12 13:39:34 +01001422 HANDLER_ATTRIBUTES bool OR_LONG() {
David Srbecky6baf6442019-05-30 14:57:43 +01001423 SetVRegLong(A(), GetVRegLong(B()) | GetVRegLong(C()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001424 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001425 }
1426
David Srbecky27351be2019-07-12 13:39:34 +01001427 HANDLER_ATTRIBUTES bool XOR_LONG() {
David Srbecky6baf6442019-05-30 14:57:43 +01001428 SetVRegLong(A(), GetVRegLong(B()) ^ GetVRegLong(C()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001429 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001430 }
1431
David Srbecky27351be2019-07-12 13:39:34 +01001432 HANDLER_ATTRIBUTES bool SHL_LONG() {
David Srbecky6baf6442019-05-30 14:57:43 +01001433 SetVRegLong(A(), GetVRegLong(B()) << (GetVReg(C()) & 0x3f));
David Srbeckybd613ec2019-05-30 15:39:38 +01001434 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001435 }
1436
David Srbecky27351be2019-07-12 13:39:34 +01001437 HANDLER_ATTRIBUTES bool SHR_LONG() {
David Srbecky6baf6442019-05-30 14:57:43 +01001438 SetVRegLong(A(), GetVRegLong(B()) >> (GetVReg(C()) & 0x3f));
David Srbeckybd613ec2019-05-30 15:39:38 +01001439 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001440 }
1441
David Srbecky27351be2019-07-12 13:39:34 +01001442 HANDLER_ATTRIBUTES bool USHR_LONG() {
David Srbecky6baf6442019-05-30 14:57:43 +01001443 SetVRegLong(A(), static_cast<uint64_t>(GetVRegLong(B())) >> (GetVReg(C()) & 0x3f));
David Srbeckybd613ec2019-05-30 15:39:38 +01001444 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001445 }
1446
David Srbecky27351be2019-07-12 13:39:34 +01001447 HANDLER_ATTRIBUTES bool ADD_FLOAT() {
David Srbecky6baf6442019-05-30 14:57:43 +01001448 SetVRegFloat(A(), GetVRegFloat(B()) + GetVRegFloat(C()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001449 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001450 }
1451
David Srbecky27351be2019-07-12 13:39:34 +01001452 HANDLER_ATTRIBUTES bool SUB_FLOAT() {
David Srbecky6baf6442019-05-30 14:57:43 +01001453 SetVRegFloat(A(), GetVRegFloat(B()) - GetVRegFloat(C()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001454 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001455 }
1456
David Srbecky27351be2019-07-12 13:39:34 +01001457 HANDLER_ATTRIBUTES bool MUL_FLOAT() {
David Srbecky6baf6442019-05-30 14:57:43 +01001458 SetVRegFloat(A(), GetVRegFloat(B()) * GetVRegFloat(C()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001459 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001460 }
1461
David Srbecky27351be2019-07-12 13:39:34 +01001462 HANDLER_ATTRIBUTES bool DIV_FLOAT() {
David Srbecky6baf6442019-05-30 14:57:43 +01001463 SetVRegFloat(A(), GetVRegFloat(B()) / GetVRegFloat(C()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001464 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001465 }
1466
David Srbecky27351be2019-07-12 13:39:34 +01001467 HANDLER_ATTRIBUTES bool REM_FLOAT() {
David Srbecky6baf6442019-05-30 14:57:43 +01001468 SetVRegFloat(A(), fmodf(GetVRegFloat(B()), GetVRegFloat(C())));
David Srbeckybd613ec2019-05-30 15:39:38 +01001469 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001470 }
1471
David Srbecky27351be2019-07-12 13:39:34 +01001472 HANDLER_ATTRIBUTES bool ADD_DOUBLE() {
David Srbecky6baf6442019-05-30 14:57:43 +01001473 SetVRegDouble(A(), GetVRegDouble(B()) + GetVRegDouble(C()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001474 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001475 }
1476
David Srbecky27351be2019-07-12 13:39:34 +01001477 HANDLER_ATTRIBUTES bool SUB_DOUBLE() {
David Srbecky6baf6442019-05-30 14:57:43 +01001478 SetVRegDouble(A(), GetVRegDouble(B()) - GetVRegDouble(C()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001479 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001480 }
1481
David Srbecky27351be2019-07-12 13:39:34 +01001482 HANDLER_ATTRIBUTES bool MUL_DOUBLE() {
David Srbecky6baf6442019-05-30 14:57:43 +01001483 SetVRegDouble(A(), GetVRegDouble(B()) * GetVRegDouble(C()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001484 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001485 }
1486
David Srbecky27351be2019-07-12 13:39:34 +01001487 HANDLER_ATTRIBUTES bool DIV_DOUBLE() {
David Srbecky6baf6442019-05-30 14:57:43 +01001488 SetVRegDouble(A(), GetVRegDouble(B()) / GetVRegDouble(C()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001489 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001490 }
1491
David Srbecky27351be2019-07-12 13:39:34 +01001492 HANDLER_ATTRIBUTES bool REM_DOUBLE() {
David Srbecky6baf6442019-05-30 14:57:43 +01001493 SetVRegDouble(A(), fmod(GetVRegDouble(B()), GetVRegDouble(C())));
David Srbeckybd613ec2019-05-30 15:39:38 +01001494 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001495 }
1496
David Srbecky27351be2019-07-12 13:39:34 +01001497 HANDLER_ATTRIBUTES bool ADD_INT_2ADDR() {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001498 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001499 SetVReg(vregA, SafeAdd(GetVReg(vregA), GetVReg(B())));
David Srbeckybd613ec2019-05-30 15:39:38 +01001500 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001501 }
1502
David Srbecky27351be2019-07-12 13:39:34 +01001503 HANDLER_ATTRIBUTES bool SUB_INT_2ADDR() {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001504 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001505 SetVReg(vregA, SafeSub(GetVReg(vregA), GetVReg(B())));
David Srbeckybd613ec2019-05-30 15:39:38 +01001506 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001507 }
1508
David Srbecky27351be2019-07-12 13:39:34 +01001509 HANDLER_ATTRIBUTES bool MUL_INT_2ADDR() {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001510 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001511 SetVReg(vregA, SafeMul(GetVReg(vregA), GetVReg(B())));
David Srbeckybd613ec2019-05-30 15:39:38 +01001512 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001513 }
1514
David Srbecky27351be2019-07-12 13:39:34 +01001515 HANDLER_ATTRIBUTES bool DIV_INT_2ADDR() {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001516 uint4_t vregA = A();
David Srbecky8d335b62019-06-06 14:25:42 +01001517 return DoIntDivide(shadow_frame, vregA, GetVReg(vregA), GetVReg(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001518 }
1519
David Srbecky27351be2019-07-12 13:39:34 +01001520 HANDLER_ATTRIBUTES bool REM_INT_2ADDR() {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001521 uint4_t vregA = A();
David Srbecky8d335b62019-06-06 14:25:42 +01001522 return DoIntRemainder(shadow_frame, vregA, GetVReg(vregA), GetVReg(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001523 }
1524
David Srbecky27351be2019-07-12 13:39:34 +01001525 HANDLER_ATTRIBUTES bool SHL_INT_2ADDR() {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001526 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001527 SetVReg(vregA, GetVReg(vregA) << (GetVReg(B()) & 0x1f));
David Srbeckybd613ec2019-05-30 15:39:38 +01001528 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001529 }
1530
David Srbecky27351be2019-07-12 13:39:34 +01001531 HANDLER_ATTRIBUTES bool SHR_INT_2ADDR() {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001532 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001533 SetVReg(vregA, GetVReg(vregA) >> (GetVReg(B()) & 0x1f));
David Srbeckybd613ec2019-05-30 15:39:38 +01001534 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001535 }
1536
David Srbecky27351be2019-07-12 13:39:34 +01001537 HANDLER_ATTRIBUTES bool USHR_INT_2ADDR() {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001538 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001539 SetVReg(vregA, static_cast<uint32_t>(GetVReg(vregA)) >> (GetVReg(B()) & 0x1f));
David Srbeckybd613ec2019-05-30 15:39:38 +01001540 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001541 }
1542
David Srbecky27351be2019-07-12 13:39:34 +01001543 HANDLER_ATTRIBUTES bool AND_INT_2ADDR() {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001544 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001545 SetVReg(vregA, GetVReg(vregA) & GetVReg(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001546 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001547 }
1548
David Srbecky27351be2019-07-12 13:39:34 +01001549 HANDLER_ATTRIBUTES bool OR_INT_2ADDR() {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001550 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001551 SetVReg(vregA, GetVReg(vregA) | GetVReg(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001552 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001553 }
1554
David Srbecky27351be2019-07-12 13:39:34 +01001555 HANDLER_ATTRIBUTES bool XOR_INT_2ADDR() {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001556 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001557 SetVReg(vregA, GetVReg(vregA) ^ GetVReg(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001558 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001559 }
1560
David Srbecky27351be2019-07-12 13:39:34 +01001561 HANDLER_ATTRIBUTES bool ADD_LONG_2ADDR() {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001562 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001563 SetVRegLong(vregA, SafeAdd(GetVRegLong(vregA), GetVRegLong(B())));
David Srbeckybd613ec2019-05-30 15:39:38 +01001564 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001565 }
1566
David Srbecky27351be2019-07-12 13:39:34 +01001567 HANDLER_ATTRIBUTES bool SUB_LONG_2ADDR() {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001568 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001569 SetVRegLong(vregA, SafeSub(GetVRegLong(vregA), GetVRegLong(B())));
David Srbeckybd613ec2019-05-30 15:39:38 +01001570 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001571 }
1572
David Srbecky27351be2019-07-12 13:39:34 +01001573 HANDLER_ATTRIBUTES bool MUL_LONG_2ADDR() {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001574 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001575 SetVRegLong(vregA, SafeMul(GetVRegLong(vregA), GetVRegLong(B())));
David Srbeckybd613ec2019-05-30 15:39:38 +01001576 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001577 }
1578
David Srbecky27351be2019-07-12 13:39:34 +01001579 HANDLER_ATTRIBUTES bool DIV_LONG_2ADDR() {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001580 uint4_t vregA = A();
David Srbecky8d335b62019-06-06 14:25:42 +01001581 return DoLongDivide(shadow_frame, vregA, GetVRegLong(vregA), GetVRegLong(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001582 }
1583
David Srbecky27351be2019-07-12 13:39:34 +01001584 HANDLER_ATTRIBUTES bool REM_LONG_2ADDR() {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001585 uint4_t vregA = A();
David Srbecky8d335b62019-06-06 14:25:42 +01001586 return DoLongRemainder(shadow_frame, vregA, GetVRegLong(vregA), GetVRegLong(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001587 }
1588
David Srbecky27351be2019-07-12 13:39:34 +01001589 HANDLER_ATTRIBUTES bool AND_LONG_2ADDR() {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001590 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001591 SetVRegLong(vregA, GetVRegLong(vregA) & GetVRegLong(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001592 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001593 }
1594
David Srbecky27351be2019-07-12 13:39:34 +01001595 HANDLER_ATTRIBUTES bool OR_LONG_2ADDR() {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001596 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001597 SetVRegLong(vregA, GetVRegLong(vregA) | GetVRegLong(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001598 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001599 }
1600
David Srbecky27351be2019-07-12 13:39:34 +01001601 HANDLER_ATTRIBUTES bool XOR_LONG_2ADDR() {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001602 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001603 SetVRegLong(vregA, GetVRegLong(vregA) ^ GetVRegLong(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001604 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001605 }
1606
David Srbecky27351be2019-07-12 13:39:34 +01001607 HANDLER_ATTRIBUTES bool SHL_LONG_2ADDR() {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001608 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001609 SetVRegLong(vregA, GetVRegLong(vregA) << (GetVReg(B()) & 0x3f));
David Srbeckybd613ec2019-05-30 15:39:38 +01001610 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001611 }
1612
David Srbecky27351be2019-07-12 13:39:34 +01001613 HANDLER_ATTRIBUTES bool SHR_LONG_2ADDR() {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001614 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001615 SetVRegLong(vregA, GetVRegLong(vregA) >> (GetVReg(B()) & 0x3f));
David Srbeckybd613ec2019-05-30 15:39:38 +01001616 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001617 }
1618
David Srbecky27351be2019-07-12 13:39:34 +01001619 HANDLER_ATTRIBUTES bool USHR_LONG_2ADDR() {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001620 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001621 SetVRegLong(vregA, static_cast<uint64_t>(GetVRegLong(vregA)) >> (GetVReg(B()) & 0x3f));
David Srbeckybd613ec2019-05-30 15:39:38 +01001622 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001623 }
1624
David Srbecky27351be2019-07-12 13:39:34 +01001625 HANDLER_ATTRIBUTES bool ADD_FLOAT_2ADDR() {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001626 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001627 SetVRegFloat(vregA, GetVRegFloat(vregA) + GetVRegFloat(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001628 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001629 }
1630
David Srbecky27351be2019-07-12 13:39:34 +01001631 HANDLER_ATTRIBUTES bool SUB_FLOAT_2ADDR() {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001632 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001633 SetVRegFloat(vregA, GetVRegFloat(vregA) - GetVRegFloat(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001634 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001635 }
1636
David Srbecky27351be2019-07-12 13:39:34 +01001637 HANDLER_ATTRIBUTES bool MUL_FLOAT_2ADDR() {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001638 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001639 SetVRegFloat(vregA, GetVRegFloat(vregA) * GetVRegFloat(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001640 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001641 }
1642
David Srbecky27351be2019-07-12 13:39:34 +01001643 HANDLER_ATTRIBUTES bool DIV_FLOAT_2ADDR() {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001644 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001645 SetVRegFloat(vregA, GetVRegFloat(vregA) / GetVRegFloat(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001646 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001647 }
1648
David Srbecky27351be2019-07-12 13:39:34 +01001649 HANDLER_ATTRIBUTES bool REM_FLOAT_2ADDR() {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001650 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001651 SetVRegFloat(vregA, fmodf(GetVRegFloat(vregA), GetVRegFloat(B())));
David Srbeckybd613ec2019-05-30 15:39:38 +01001652 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001653 }
1654
David Srbecky27351be2019-07-12 13:39:34 +01001655 HANDLER_ATTRIBUTES bool ADD_DOUBLE_2ADDR() {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001656 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001657 SetVRegDouble(vregA, GetVRegDouble(vregA) + GetVRegDouble(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001658 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001659 }
1660
David Srbecky27351be2019-07-12 13:39:34 +01001661 HANDLER_ATTRIBUTES bool SUB_DOUBLE_2ADDR() {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001662 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001663 SetVRegDouble(vregA, GetVRegDouble(vregA) - GetVRegDouble(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001664 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001665 }
1666
David Srbecky27351be2019-07-12 13:39:34 +01001667 HANDLER_ATTRIBUTES bool MUL_DOUBLE_2ADDR() {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001668 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001669 SetVRegDouble(vregA, GetVRegDouble(vregA) * GetVRegDouble(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001670 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001671 }
1672
David Srbecky27351be2019-07-12 13:39:34 +01001673 HANDLER_ATTRIBUTES bool DIV_DOUBLE_2ADDR() {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001674 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001675 SetVRegDouble(vregA, GetVRegDouble(vregA) / GetVRegDouble(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001676 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001677 }
1678
David Srbecky27351be2019-07-12 13:39:34 +01001679 HANDLER_ATTRIBUTES bool REM_DOUBLE_2ADDR() {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001680 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001681 SetVRegDouble(vregA, fmod(GetVRegDouble(vregA), GetVRegDouble(B())));
David Srbeckybd613ec2019-05-30 15:39:38 +01001682 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001683 }
1684
David Srbecky27351be2019-07-12 13:39:34 +01001685 HANDLER_ATTRIBUTES bool ADD_INT_LIT16() {
David Srbecky6baf6442019-05-30 14:57:43 +01001686 SetVReg(A(), SafeAdd(GetVReg(B()), C()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001687 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001688 }
1689
David Srbecky27351be2019-07-12 13:39:34 +01001690 HANDLER_ATTRIBUTES bool RSUB_INT() {
David Srbecky6baf6442019-05-30 14:57:43 +01001691 SetVReg(A(), SafeSub(C(), GetVReg(B())));
David Srbeckybd613ec2019-05-30 15:39:38 +01001692 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001693 }
1694
David Srbecky27351be2019-07-12 13:39:34 +01001695 HANDLER_ATTRIBUTES bool MUL_INT_LIT16() {
David Srbecky6baf6442019-05-30 14:57:43 +01001696 SetVReg(A(), SafeMul(GetVReg(B()), C()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001697 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001698 }
1699
David Srbecky27351be2019-07-12 13:39:34 +01001700 HANDLER_ATTRIBUTES bool DIV_INT_LIT16() {
David Srbecky8d335b62019-06-06 14:25:42 +01001701 return DoIntDivide(shadow_frame, A(), GetVReg(B()), C());
David Srbecky6da82472018-10-23 14:03:08 +01001702 }
1703
David Srbecky27351be2019-07-12 13:39:34 +01001704 HANDLER_ATTRIBUTES bool REM_INT_LIT16() {
David Srbecky8d335b62019-06-06 14:25:42 +01001705 return DoIntRemainder(shadow_frame, A(), GetVReg(B()), C());
David Srbecky6da82472018-10-23 14:03:08 +01001706 }
1707
David Srbecky27351be2019-07-12 13:39:34 +01001708 HANDLER_ATTRIBUTES bool AND_INT_LIT16() {
David Srbecky6baf6442019-05-30 14:57:43 +01001709 SetVReg(A(), GetVReg(B()) & C());
David Srbeckybd613ec2019-05-30 15:39:38 +01001710 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001711 }
1712
David Srbecky27351be2019-07-12 13:39:34 +01001713 HANDLER_ATTRIBUTES bool OR_INT_LIT16() {
David Srbecky6baf6442019-05-30 14:57:43 +01001714 SetVReg(A(), GetVReg(B()) | C());
David Srbeckybd613ec2019-05-30 15:39:38 +01001715 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001716 }
1717
David Srbecky27351be2019-07-12 13:39:34 +01001718 HANDLER_ATTRIBUTES bool XOR_INT_LIT16() {
David Srbecky6baf6442019-05-30 14:57:43 +01001719 SetVReg(A(), GetVReg(B()) ^ C());
David Srbeckybd613ec2019-05-30 15:39:38 +01001720 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001721 }
1722
David Srbecky27351be2019-07-12 13:39:34 +01001723 HANDLER_ATTRIBUTES bool ADD_INT_LIT8() {
David Srbecky6baf6442019-05-30 14:57:43 +01001724 SetVReg(A(), SafeAdd(GetVReg(B()), C()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001725 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001726 }
1727
David Srbecky27351be2019-07-12 13:39:34 +01001728 HANDLER_ATTRIBUTES bool RSUB_INT_LIT8() {
David Srbecky6baf6442019-05-30 14:57:43 +01001729 SetVReg(A(), SafeSub(C(), GetVReg(B())));
David Srbeckybd613ec2019-05-30 15:39:38 +01001730 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001731 }
1732
David Srbecky27351be2019-07-12 13:39:34 +01001733 HANDLER_ATTRIBUTES bool MUL_INT_LIT8() {
David Srbecky6baf6442019-05-30 14:57:43 +01001734 SetVReg(A(), SafeMul(GetVReg(B()), C()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001735 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001736 }
1737
David Srbecky27351be2019-07-12 13:39:34 +01001738 HANDLER_ATTRIBUTES bool DIV_INT_LIT8() {
David Srbecky8d335b62019-06-06 14:25:42 +01001739 return DoIntDivide(shadow_frame, A(), GetVReg(B()), C());
David Srbecky6da82472018-10-23 14:03:08 +01001740 }
1741
David Srbecky27351be2019-07-12 13:39:34 +01001742 HANDLER_ATTRIBUTES bool REM_INT_LIT8() {
David Srbecky8d335b62019-06-06 14:25:42 +01001743 return DoIntRemainder(shadow_frame, A(), GetVReg(B()), C());
David Srbecky6da82472018-10-23 14:03:08 +01001744 }
1745
David Srbecky27351be2019-07-12 13:39:34 +01001746 HANDLER_ATTRIBUTES bool AND_INT_LIT8() {
David Srbecky6baf6442019-05-30 14:57:43 +01001747 SetVReg(A(), GetVReg(B()) & C());
David Srbeckybd613ec2019-05-30 15:39:38 +01001748 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001749 }
1750
David Srbecky27351be2019-07-12 13:39:34 +01001751 HANDLER_ATTRIBUTES bool OR_INT_LIT8() {
David Srbecky6baf6442019-05-30 14:57:43 +01001752 SetVReg(A(), GetVReg(B()) | C());
David Srbeckybd613ec2019-05-30 15:39:38 +01001753 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001754 }
1755
David Srbecky27351be2019-07-12 13:39:34 +01001756 HANDLER_ATTRIBUTES bool XOR_INT_LIT8() {
David Srbecky6baf6442019-05-30 14:57:43 +01001757 SetVReg(A(), GetVReg(B()) ^ C());
David Srbeckybd613ec2019-05-30 15:39:38 +01001758 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001759 }
1760
David Srbecky27351be2019-07-12 13:39:34 +01001761 HANDLER_ATTRIBUTES bool SHL_INT_LIT8() {
David Srbecky6baf6442019-05-30 14:57:43 +01001762 SetVReg(A(), GetVReg(B()) << (C() & 0x1f));
David Srbeckybd613ec2019-05-30 15:39:38 +01001763 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001764 }
1765
David Srbecky27351be2019-07-12 13:39:34 +01001766 HANDLER_ATTRIBUTES bool SHR_INT_LIT8() {
David Srbecky6baf6442019-05-30 14:57:43 +01001767 SetVReg(A(), GetVReg(B()) >> (C() & 0x1f));
David Srbeckybd613ec2019-05-30 15:39:38 +01001768 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001769 }
1770
David Srbecky27351be2019-07-12 13:39:34 +01001771 HANDLER_ATTRIBUTES bool USHR_INT_LIT8() {
David Srbecky6baf6442019-05-30 14:57:43 +01001772 SetVReg(A(), static_cast<uint32_t>(GetVReg(B())) >> (C() & 0x1f));
David Srbeckybd613ec2019-05-30 15:39:38 +01001773 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001774 }
1775
David Srbecky27351be2019-07-12 13:39:34 +01001776 HANDLER_ATTRIBUTES bool UNUSED_3E() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001777 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01001778 }
1779
David Srbecky27351be2019-07-12 13:39:34 +01001780 HANDLER_ATTRIBUTES bool UNUSED_3F() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001781 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01001782 }
1783
David Srbecky27351be2019-07-12 13:39:34 +01001784 HANDLER_ATTRIBUTES bool UNUSED_40() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001785 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01001786 }
1787
David Srbecky27351be2019-07-12 13:39:34 +01001788 HANDLER_ATTRIBUTES bool UNUSED_41() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001789 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01001790 }
1791
David Srbecky27351be2019-07-12 13:39:34 +01001792 HANDLER_ATTRIBUTES bool UNUSED_42() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001793 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01001794 }
1795
David Srbecky27351be2019-07-12 13:39:34 +01001796 HANDLER_ATTRIBUTES bool UNUSED_43() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001797 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01001798 }
1799
David Srbecky27351be2019-07-12 13:39:34 +01001800 HANDLER_ATTRIBUTES bool UNUSED_79() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001801 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01001802 }
1803
David Srbecky27351be2019-07-12 13:39:34 +01001804 HANDLER_ATTRIBUTES bool UNUSED_7A() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001805 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01001806 }
1807
David Srbecky27351be2019-07-12 13:39:34 +01001808 HANDLER_ATTRIBUTES bool UNUSED_F3() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001809 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01001810 }
1811
David Srbecky27351be2019-07-12 13:39:34 +01001812 HANDLER_ATTRIBUTES bool UNUSED_F4() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001813 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01001814 }
1815
David Srbecky27351be2019-07-12 13:39:34 +01001816 HANDLER_ATTRIBUTES bool UNUSED_F5() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001817 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01001818 }
1819
David Srbecky27351be2019-07-12 13:39:34 +01001820 HANDLER_ATTRIBUTES bool UNUSED_F6() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001821 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01001822 }
1823
David Srbecky27351be2019-07-12 13:39:34 +01001824 HANDLER_ATTRIBUTES bool UNUSED_F7() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001825 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01001826 }
1827
David Srbecky27351be2019-07-12 13:39:34 +01001828 HANDLER_ATTRIBUTES bool UNUSED_F8() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001829 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01001830 }
1831
David Srbecky27351be2019-07-12 13:39:34 +01001832 HANDLER_ATTRIBUTES bool UNUSED_F9() {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001833 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01001834 }
1835
1836 ALWAYS_INLINE InstructionHandler(SwitchImplContext* ctx,
1837 const instrumentation::Instrumentation* instrumentation,
1838 Thread* self,
1839 ShadowFrame& shadow_frame,
1840 uint16_t dex_pc,
David Srbeckyc56a23e2019-06-05 17:45:49 +01001841 const Instruction* inst,
David Srbecky6da82472018-10-23 14:03:08 +01001842 uint16_t inst_data,
David Srbecky8867f3b2019-05-31 20:01:46 +01001843 const Instruction*& next,
David Srbecky6da82472018-10-23 14:03:08 +01001844 bool& exit_interpreter_loop)
1845 : ctx(ctx),
1846 instrumentation(instrumentation),
1847 self(self),
1848 shadow_frame(shadow_frame),
1849 dex_pc(dex_pc),
1850 inst(inst),
1851 inst_data(inst_data),
David Srbecky8867f3b2019-05-31 20:01:46 +01001852 next(next),
David Srbecky6da82472018-10-23 14:03:08 +01001853 exit_interpreter_loop(exit_interpreter_loop) {
1854 }
1855
1856 private:
1857 static constexpr bool do_assignability_check = do_access_check;
Alex Lightb7c640d2019-03-20 15:52:13 -07001858 static constexpr MonitorState kMonitorState =
1859 do_assignability_check ? MonitorState::kCountingMonitors : MonitorState::kNormalMonitors;
David Srbecky6da82472018-10-23 14:03:08 +01001860
1861 const CodeItemDataAccessor& Accessor() { return ctx->accessor; }
1862 const uint16_t* Insns() { return ctx->accessor.Insns(); }
1863 JValue* ResultRegister() { return &ctx->result_register; }
1864
David Srbecky436f6c12019-05-22 13:28:42 +01001865 ALWAYS_INLINE int32_t A() { return inst->VRegA(kFormat, inst_data); }
1866 ALWAYS_INLINE int32_t B() { return inst->VRegB(kFormat, inst_data); }
1867 ALWAYS_INLINE int32_t C() { return inst->VRegC(kFormat); }
1868
David Srbecky6baf6442019-05-30 14:57:43 +01001869 int32_t GetVReg(size_t i) const { return shadow_frame.GetVReg(i); }
1870 int64_t GetVRegLong(size_t i) const { return shadow_frame.GetVRegLong(i); }
1871 float GetVRegFloat(size_t i) const { return shadow_frame.GetVRegFloat(i); }
1872 double GetVRegDouble(size_t i) const { return shadow_frame.GetVRegDouble(i); }
1873 ObjPtr<mirror::Object> GetVRegReference(size_t i) const REQUIRES_SHARED(Locks::mutator_lock_) {
1874 return shadow_frame.GetVRegReference(i);
1875 }
1876
1877 void SetVReg(size_t i, int32_t val) { shadow_frame.SetVReg(i, val); }
1878 void SetVRegLong(size_t i, int64_t val) { shadow_frame.SetVRegLong(i, val); }
1879 void SetVRegFloat(size_t i, float val) { shadow_frame.SetVRegFloat(i, val); }
1880 void SetVRegDouble(size_t i, double val) { shadow_frame.SetVRegDouble(i, val); }
1881 void SetVRegReference(size_t i, ObjPtr<mirror::Object> val)
1882 REQUIRES_SHARED(Locks::mutator_lock_) {
1883 shadow_frame.SetVRegReference(i, val);
1884 }
1885
David Srbecky8867f3b2019-05-31 20:01:46 +01001886 // Set the next instruction to be executed. It is the 'fall-through' instruction by default.
1887 ALWAYS_INLINE void SetNextInstruction(const Instruction* next_inst) {
1888 DCHECK_LT(next_inst->GetDexPc(Insns()), Accessor().InsnsSizeInCodeUnits());
1889 next = next_inst;
1890 }
1891
David Srbecky6da82472018-10-23 14:03:08 +01001892 SwitchImplContext* const ctx;
1893 const instrumentation::Instrumentation* const instrumentation;
1894 Thread* const self;
1895 ShadowFrame& shadow_frame;
1896 uint32_t const dex_pc;
David Srbeckyc56a23e2019-06-05 17:45:49 +01001897 const Instruction* const inst;
David Srbecky6da82472018-10-23 14:03:08 +01001898 uint16_t const inst_data;
David Srbecky8867f3b2019-05-31 20:01:46 +01001899 const Instruction*& next;
1900
David Srbecky6da82472018-10-23 14:03:08 +01001901 bool& exit_interpreter_loop;
1902};
1903
Alex Light6f22e062018-10-05 15:05:12 -07001904// TODO On ASAN builds this function gets a huge stack frame. Since normally we run in the mterp
1905// this shouldn't cause any problems for stack overflow detection. Remove this once b/117341496 is
1906// fixed.
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001907template<bool do_access_check, bool transaction_active>
Alex Light6f22e062018-10-05 15:05:12 -07001908ATTRIBUTE_NO_SANITIZE_ADDRESS void ExecuteSwitchImplCpp(SwitchImplContext* ctx) {
David Srbecky946bb092018-03-09 17:23:01 +00001909 Thread* self = ctx->self;
1910 const CodeItemDataAccessor& accessor = ctx->accessor;
1911 ShadowFrame& shadow_frame = ctx->shadow_frame;
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001912 self->VerifyStack();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001913
1914 uint32_t dex_pc = shadow_frame.GetDexPC();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001915 const auto* const instrumentation = Runtime::Current()->GetInstrumentation();
Mathieu Chartier808c7a52017-12-15 11:19:33 -08001916 const uint16_t* const insns = accessor.Insns();
David Srbeckyc56a23e2019-06-05 17:45:49 +01001917 const Instruction* next = Instruction::At(insns + dex_pc);
Igor Murashkin6918bf12015-09-27 19:19:06 -07001918
Alex Light0aa7a5a2018-10-10 15:58:14 +00001919 DCHECK(!shadow_frame.GetForceRetryInstruction())
1920 << "Entered interpreter from invoke without retry instruction being handled!";
1921
David Srbecky6da82472018-10-23 14:03:08 +01001922 bool const interpret_one_instruction = ctx->interpret_one_instruction;
1923 while (true) {
David Srbeckyc56a23e2019-06-05 17:45:49 +01001924 const Instruction* const inst = next;
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001925 dex_pc = inst->GetDexPc(insns);
1926 shadow_frame.SetDexPC(dex_pc);
Ian Rogerse94652f2014-12-02 11:13:19 -08001927 TraceExecution(shadow_frame, inst, dex_pc);
David Srbecky8d335b62019-06-06 14:25:42 +01001928 uint16_t inst_data = inst->Fetch16(0);
1929 bool exit = false;
1930 if (InstructionHandler<do_access_check, transaction_active, Instruction::kInvalidFormat>(
1931 ctx, instrumentation, self, shadow_frame, dex_pc, inst, inst_data, next, exit).
1932 Preamble()) {
1933 switch (inst->Opcode(inst_data)) {
David Srbecky8867f3b2019-05-31 20:01:46 +01001934#define OPCODE_CASE(OPCODE, OPCODE_NAME, NAME, FORMAT, i, a, e, v) \
David Srbecky8d335b62019-06-06 14:25:42 +01001935 case OPCODE: { \
1936 DCHECK_EQ(self->IsExceptionPending(), (OPCODE == Instruction::MOVE_EXCEPTION)); \
1937 next = inst->RelativeAt(Instruction::SizeInCodeUnits(Instruction::FORMAT)); \
1938 InstructionHandler<do_access_check, transaction_active, Instruction::FORMAT> handler( \
1939 ctx, instrumentation, self, shadow_frame, dex_pc, inst, inst_data, next, exit); \
1940 if (handler.OPCODE_NAME() && LIKELY(!interpret_one_instruction)) { \
1941 DCHECK(!exit) << NAME; \
1942 continue; \
1943 } \
1944 if (exit) { \
1945 shadow_frame.SetDexPC(dex::kDexNoIndex); \
1946 return; \
1947 } \
1948 break; \
1949 }
1950 DEX_INSTRUCTION_LIST(OPCODE_CASE)
David Srbecky6da82472018-10-23 14:03:08 +01001951#undef OPCODE_CASE
David Srbecky8d335b62019-06-06 14:25:42 +01001952 }
1953 } else {
1954 // Preamble returned false due to debugger event.
1955 if (exit) {
1956 shadow_frame.SetDexPC(dex::kDexNoIndex);
1957 return; // Return statement or debugger forced exit.
1958 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001959 }
David Srbecky8d335b62019-06-06 14:25:42 +01001960 if (self->IsExceptionPending()) {
1961 if (!InstructionHandler<do_access_check, transaction_active, Instruction::kInvalidFormat>(
1962 ctx, instrumentation, self, shadow_frame, dex_pc, inst, inst_data, next, exit).
1963 HandlePendingException()) {
1964 shadow_frame.SetDexPC(dex::kDexNoIndex);
1965 return; // Locally unhandled exception - return to caller.
1966 }
1967 // Continue execution in the catch block.
1968 }
1969 if (interpret_one_instruction) {
1970 shadow_frame.SetDexPC(next->GetDexPc(insns)); // Record where we stopped.
1971 ctx->result = ctx->result_register;
1972 return;
David Srbecky6da82472018-10-23 14:03:08 +01001973 }
1974 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001975} // NOLINT(readability/fn_size)
1976
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001977} // namespace interpreter
1978} // namespace art
David Srbecky2ee09ff2018-10-24 13:24:22 +01001979
1980#endif // ART_RUNTIME_INTERPRETER_INTERPRETER_SWITCH_IMPL_INL_H_