1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2012 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker *
4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker *
8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker *
10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker */
16*795d594fSAndroid Build Coastguard Worker
17*795d594fSAndroid Build Coastguard Worker #ifndef ART_RUNTIME_INTERPRETER_INTERPRETER_SWITCH_IMPL_INL_H_
18*795d594fSAndroid Build Coastguard Worker #define ART_RUNTIME_INTERPRETER_INTERPRETER_SWITCH_IMPL_INL_H_
19*795d594fSAndroid Build Coastguard Worker
20*795d594fSAndroid Build Coastguard Worker #include "interpreter_switch_impl.h"
21*795d594fSAndroid Build Coastguard Worker
22*795d594fSAndroid Build Coastguard Worker #include "base/globals.h"
23*795d594fSAndroid Build Coastguard Worker #include "base/memory_tool.h"
24*795d594fSAndroid Build Coastguard Worker #include "base/pointer_size.h"
25*795d594fSAndroid Build Coastguard Worker #include "base/quasi_atomic.h"
26*795d594fSAndroid Build Coastguard Worker #include "common_throws.h"
27*795d594fSAndroid Build Coastguard Worker #include "dex/dex_file_types.h"
28*795d594fSAndroid Build Coastguard Worker #include "dex/dex_instruction_list.h"
29*795d594fSAndroid Build Coastguard Worker #include "experimental_flags.h"
30*795d594fSAndroid Build Coastguard Worker #include "handle_scope.h"
31*795d594fSAndroid Build Coastguard Worker #include "interpreter_common.h"
32*795d594fSAndroid Build Coastguard Worker #include "interpreter/shadow_frame.h"
33*795d594fSAndroid Build Coastguard Worker #include "jit/jit-inl.h"
34*795d594fSAndroid Build Coastguard Worker #include "jvalue-inl.h"
35*795d594fSAndroid Build Coastguard Worker #include "mirror/string-alloc-inl.h"
36*795d594fSAndroid Build Coastguard Worker #include "mirror/throwable.h"
37*795d594fSAndroid Build Coastguard Worker #include "monitor.h"
38*795d594fSAndroid Build Coastguard Worker #include "nth_caller_visitor.h"
39*795d594fSAndroid Build Coastguard Worker #include "safe_math.h"
40*795d594fSAndroid Build Coastguard Worker #include "shadow_frame-inl.h"
41*795d594fSAndroid Build Coastguard Worker #include "thread.h"
42*795d594fSAndroid Build Coastguard Worker #include "verifier/method_verifier.h"
43*795d594fSAndroid Build Coastguard Worker
44*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN {
45*795d594fSAndroid Build Coastguard Worker namespace interpreter {
46*795d594fSAndroid Build Coastguard Worker
47*795d594fSAndroid Build Coastguard Worker // We declare the helpers classes for transaction checks here but they shall be defined
48*795d594fSAndroid Build Coastguard Worker // only when compiling the transactional and non-transactional interpreter.
49*795d594fSAndroid Build Coastguard Worker class ActiveTransactionChecker; // For transactional interpreter.
50*795d594fSAndroid Build Coastguard Worker class InactiveTransactionChecker; // For non-transactional interpreter.
51*795d594fSAndroid Build Coastguard Worker
52*795d594fSAndroid Build Coastguard Worker // We declare the helpers classes for instrumentation handling here but they shall be defined
53*795d594fSAndroid Build Coastguard Worker // only when compiling the transactional and non-transactional interpreter.
54*795d594fSAndroid Build Coastguard Worker class ActiveInstrumentationHandler; // For non-transactional interpreter.
55*795d594fSAndroid Build Coastguard Worker class InactiveInstrumentationHandler; // For transactional interpreter.
56*795d594fSAndroid Build Coastguard Worker
57*795d594fSAndroid Build Coastguard Worker // Handles iget-XXX and sget-XXX instructions.
58*795d594fSAndroid Build Coastguard Worker // Returns true on success, otherwise throws an exception and returns false.
59*795d594fSAndroid Build Coastguard Worker template<FindFieldType find_type,
60*795d594fSAndroid Build Coastguard Worker Primitive::Type field_type,
61*795d594fSAndroid Build Coastguard Worker bool transaction_active = false>
DoFieldGet(Thread * self,ShadowFrame & shadow_frame,const Instruction * inst,uint16_t inst_data,const instrumentation::Instrumentation * instrumentation)62*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE bool DoFieldGet(Thread* self,
63*795d594fSAndroid Build Coastguard Worker ShadowFrame& shadow_frame,
64*795d594fSAndroid Build Coastguard Worker const Instruction* inst,
65*795d594fSAndroid Build Coastguard Worker uint16_t inst_data,
66*795d594fSAndroid Build Coastguard Worker const instrumentation::Instrumentation* instrumentation)
67*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
68*795d594fSAndroid Build Coastguard Worker using InstrumentationHandler = typename std::conditional_t<
69*795d594fSAndroid Build Coastguard Worker transaction_active, InactiveInstrumentationHandler, ActiveInstrumentationHandler>;
70*795d594fSAndroid Build Coastguard Worker bool should_report = InstrumentationHandler::HasFieldReadListeners(instrumentation);
71*795d594fSAndroid Build Coastguard Worker const bool is_static = (find_type == StaticObjectRead) || (find_type == StaticPrimitiveRead);
72*795d594fSAndroid Build Coastguard Worker ArtField* field = nullptr;
73*795d594fSAndroid Build Coastguard Worker MemberOffset offset(0u);
74*795d594fSAndroid Build Coastguard Worker bool is_volatile;
75*795d594fSAndroid Build Coastguard Worker GetFieldInfo(self,
76*795d594fSAndroid Build Coastguard Worker shadow_frame.GetMethod(),
77*795d594fSAndroid Build Coastguard Worker reinterpret_cast<const uint16_t*>(inst),
78*795d594fSAndroid Build Coastguard Worker is_static,
79*795d594fSAndroid Build Coastguard Worker /*resolve_field_type=*/ false,
80*795d594fSAndroid Build Coastguard Worker &field,
81*795d594fSAndroid Build Coastguard Worker &is_volatile,
82*795d594fSAndroid Build Coastguard Worker &offset);
83*795d594fSAndroid Build Coastguard Worker if (self->IsExceptionPending()) {
84*795d594fSAndroid Build Coastguard Worker return false;
85*795d594fSAndroid Build Coastguard Worker }
86*795d594fSAndroid Build Coastguard Worker
87*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> obj;
88*795d594fSAndroid Build Coastguard Worker if (is_static) {
89*795d594fSAndroid Build Coastguard Worker obj = field->GetDeclaringClass();
90*795d594fSAndroid Build Coastguard Worker using TransactionChecker = typename std::conditional_t<
91*795d594fSAndroid Build Coastguard Worker transaction_active, ActiveTransactionChecker, InactiveTransactionChecker>;
92*795d594fSAndroid Build Coastguard Worker if (TransactionChecker::ReadConstraint(self, obj)) {
93*795d594fSAndroid Build Coastguard Worker return false;
94*795d594fSAndroid Build Coastguard Worker }
95*795d594fSAndroid Build Coastguard Worker } else {
96*795d594fSAndroid Build Coastguard Worker obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data));
97*795d594fSAndroid Build Coastguard Worker if (should_report || obj == nullptr) {
98*795d594fSAndroid Build Coastguard Worker field = ResolveFieldWithAccessChecks(self,
99*795d594fSAndroid Build Coastguard Worker Runtime::Current()->GetClassLinker(),
100*795d594fSAndroid Build Coastguard Worker inst->VRegC_22c(),
101*795d594fSAndroid Build Coastguard Worker shadow_frame.GetMethod(),
102*795d594fSAndroid Build Coastguard Worker /* is_static= */ false,
103*795d594fSAndroid Build Coastguard Worker /* is_put= */ false,
104*795d594fSAndroid Build Coastguard Worker /* resolve_field_type= */ false);
105*795d594fSAndroid Build Coastguard Worker if (obj == nullptr) {
106*795d594fSAndroid Build Coastguard Worker ThrowNullPointerExceptionForFieldAccess(
107*795d594fSAndroid Build Coastguard Worker field, shadow_frame.GetMethod(), /* is_read= */ true);
108*795d594fSAndroid Build Coastguard Worker return false;
109*795d594fSAndroid Build Coastguard Worker }
110*795d594fSAndroid Build Coastguard Worker // Reload in case suspension happened during field resolution.
111*795d594fSAndroid Build Coastguard Worker obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data));
112*795d594fSAndroid Build Coastguard Worker }
113*795d594fSAndroid Build Coastguard Worker }
114*795d594fSAndroid Build Coastguard Worker
115*795d594fSAndroid Build Coastguard Worker uint32_t vregA = is_static ? inst->VRegA_21c(inst_data) : inst->VRegA_22c(inst_data);
116*795d594fSAndroid Build Coastguard Worker JValue result;
117*795d594fSAndroid Build Coastguard Worker if (should_report) {
118*795d594fSAndroid Build Coastguard Worker DCHECK(field != nullptr);
119*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(!DoFieldGetCommon<field_type>(self, shadow_frame, obj, field, &result))) {
120*795d594fSAndroid Build Coastguard Worker // Instrumentation threw an error!
121*795d594fSAndroid Build Coastguard Worker CHECK(self->IsExceptionPending());
122*795d594fSAndroid Build Coastguard Worker return false;
123*795d594fSAndroid Build Coastguard Worker }
124*795d594fSAndroid Build Coastguard Worker }
125*795d594fSAndroid Build Coastguard Worker
126*795d594fSAndroid Build Coastguard Worker #define FIELD_GET(prim, type, jtype, vreg) \
127*795d594fSAndroid Build Coastguard Worker case Primitive::kPrim ##prim: \
128*795d594fSAndroid Build Coastguard Worker shadow_frame.SetVReg ##vreg(vregA, \
129*795d594fSAndroid Build Coastguard Worker should_report ? result.Get ##jtype() \
130*795d594fSAndroid Build Coastguard Worker : is_volatile ? obj->GetField ## type ## Volatile(offset) \
131*795d594fSAndroid Build Coastguard Worker : obj->GetField ##type(offset)); \
132*795d594fSAndroid Build Coastguard Worker break;
133*795d594fSAndroid Build Coastguard Worker
134*795d594fSAndroid Build Coastguard Worker switch (field_type) {
135*795d594fSAndroid Build Coastguard Worker FIELD_GET(Boolean, Boolean, Z, )
136*795d594fSAndroid Build Coastguard Worker FIELD_GET(Byte, Byte, B, )
137*795d594fSAndroid Build Coastguard Worker FIELD_GET(Char, Char, C, )
138*795d594fSAndroid Build Coastguard Worker FIELD_GET(Short, Short, S, )
139*795d594fSAndroid Build Coastguard Worker FIELD_GET(Int, 32, I, )
140*795d594fSAndroid Build Coastguard Worker FIELD_GET(Long, 64, J, Long)
141*795d594fSAndroid Build Coastguard Worker #undef FIELD_GET
142*795d594fSAndroid Build Coastguard Worker case Primitive::kPrimNot:
143*795d594fSAndroid Build Coastguard Worker shadow_frame.SetVRegReference(
144*795d594fSAndroid Build Coastguard Worker vregA,
145*795d594fSAndroid Build Coastguard Worker should_report ? result.GetL()
146*795d594fSAndroid Build Coastguard Worker : is_volatile ? obj->GetFieldObjectVolatile<mirror::Object>(offset)
147*795d594fSAndroid Build Coastguard Worker : obj->GetFieldObject<mirror::Object>(offset));
148*795d594fSAndroid Build Coastguard Worker break;
149*795d594fSAndroid Build Coastguard Worker default:
150*795d594fSAndroid Build Coastguard Worker LOG(FATAL) << "Unreachable: " << field_type;
151*795d594fSAndroid Build Coastguard Worker UNREACHABLE();
152*795d594fSAndroid Build Coastguard Worker }
153*795d594fSAndroid Build Coastguard Worker return true;
154*795d594fSAndroid Build Coastguard Worker }
155*795d594fSAndroid Build Coastguard Worker
156*795d594fSAndroid Build Coastguard Worker // Handles iput-XXX and sput-XXX instructions.
157*795d594fSAndroid Build Coastguard Worker // Returns true on success, otherwise throws an exception and returns false.
158*795d594fSAndroid Build Coastguard Worker template<FindFieldType find_type, Primitive::Type field_type, bool transaction_active>
DoFieldPut(Thread * self,const ShadowFrame & shadow_frame,const Instruction * inst,uint16_t inst_data,const instrumentation::Instrumentation * instrumentation)159*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE bool DoFieldPut(Thread* self,
160*795d594fSAndroid Build Coastguard Worker const ShadowFrame& shadow_frame,
161*795d594fSAndroid Build Coastguard Worker const Instruction* inst,
162*795d594fSAndroid Build Coastguard Worker uint16_t inst_data,
163*795d594fSAndroid Build Coastguard Worker const instrumentation::Instrumentation* instrumentation)
164*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
165*795d594fSAndroid Build Coastguard Worker using InstrumentationHandler = typename std::conditional_t<
166*795d594fSAndroid Build Coastguard Worker transaction_active, InactiveInstrumentationHandler, ActiveInstrumentationHandler>;
167*795d594fSAndroid Build Coastguard Worker bool should_report = InstrumentationHandler::HasFieldWriteListeners(instrumentation);
168*795d594fSAndroid Build Coastguard Worker bool is_static = (find_type == StaticObjectWrite) || (find_type == StaticPrimitiveWrite);
169*795d594fSAndroid Build Coastguard Worker uint32_t vregA = is_static ? inst->VRegA_21c(inst_data) : inst->VRegA_22c(inst_data);
170*795d594fSAndroid Build Coastguard Worker bool resolve_field_type = (shadow_frame.GetVRegReference(vregA) != nullptr);
171*795d594fSAndroid Build Coastguard Worker ArtField* field = nullptr;
172*795d594fSAndroid Build Coastguard Worker MemberOffset offset(0u);
173*795d594fSAndroid Build Coastguard Worker bool is_volatile;
174*795d594fSAndroid Build Coastguard Worker GetFieldInfo(self,
175*795d594fSAndroid Build Coastguard Worker shadow_frame.GetMethod(),
176*795d594fSAndroid Build Coastguard Worker reinterpret_cast<const uint16_t*>(inst),
177*795d594fSAndroid Build Coastguard Worker is_static,
178*795d594fSAndroid Build Coastguard Worker resolve_field_type,
179*795d594fSAndroid Build Coastguard Worker &field,
180*795d594fSAndroid Build Coastguard Worker &is_volatile,
181*795d594fSAndroid Build Coastguard Worker &offset);
182*795d594fSAndroid Build Coastguard Worker if (self->IsExceptionPending()) {
183*795d594fSAndroid Build Coastguard Worker return false;
184*795d594fSAndroid Build Coastguard Worker }
185*795d594fSAndroid Build Coastguard Worker
186*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> obj;
187*795d594fSAndroid Build Coastguard Worker if (is_static) {
188*795d594fSAndroid Build Coastguard Worker obj = field->GetDeclaringClass();
189*795d594fSAndroid Build Coastguard Worker } else {
190*795d594fSAndroid Build Coastguard Worker obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data));
191*795d594fSAndroid Build Coastguard Worker if (should_report || obj == nullptr) {
192*795d594fSAndroid Build Coastguard Worker field = ResolveFieldWithAccessChecks(self,
193*795d594fSAndroid Build Coastguard Worker Runtime::Current()->GetClassLinker(),
194*795d594fSAndroid Build Coastguard Worker inst->VRegC_22c(),
195*795d594fSAndroid Build Coastguard Worker shadow_frame.GetMethod(),
196*795d594fSAndroid Build Coastguard Worker /* is_static= */ false,
197*795d594fSAndroid Build Coastguard Worker /* is_put= */ true,
198*795d594fSAndroid Build Coastguard Worker resolve_field_type);
199*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(obj == nullptr)) {
200*795d594fSAndroid Build Coastguard Worker ThrowNullPointerExceptionForFieldAccess(
201*795d594fSAndroid Build Coastguard Worker field, shadow_frame.GetMethod(), /* is_read= */ false);
202*795d594fSAndroid Build Coastguard Worker return false;
203*795d594fSAndroid Build Coastguard Worker }
204*795d594fSAndroid Build Coastguard Worker // Reload in case suspension happened during field resolution.
205*795d594fSAndroid Build Coastguard Worker obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data));
206*795d594fSAndroid Build Coastguard Worker }
207*795d594fSAndroid Build Coastguard Worker }
208*795d594fSAndroid Build Coastguard Worker using TransactionChecker = typename std::conditional_t<
209*795d594fSAndroid Build Coastguard Worker transaction_active, ActiveTransactionChecker, InactiveTransactionChecker>;
210*795d594fSAndroid Build Coastguard Worker if (TransactionChecker::WriteConstraint(self, obj)) {
211*795d594fSAndroid Build Coastguard Worker return false;
212*795d594fSAndroid Build Coastguard Worker }
213*795d594fSAndroid Build Coastguard Worker
214*795d594fSAndroid Build Coastguard Worker JValue value = GetFieldValue<field_type>(shadow_frame, vregA);
215*795d594fSAndroid Build Coastguard Worker
216*795d594fSAndroid Build Coastguard Worker if (field_type == Primitive::kPrimNot &&
217*795d594fSAndroid Build Coastguard Worker TransactionChecker::WriteValueConstraint(self, value.GetL())) {
218*795d594fSAndroid Build Coastguard Worker return false;
219*795d594fSAndroid Build Coastguard Worker }
220*795d594fSAndroid Build Coastguard Worker if (should_report) {
221*795d594fSAndroid Build Coastguard Worker return DoFieldPutCommon<field_type, transaction_active>(self,
222*795d594fSAndroid Build Coastguard Worker shadow_frame,
223*795d594fSAndroid Build Coastguard Worker obj,
224*795d594fSAndroid Build Coastguard Worker field,
225*795d594fSAndroid Build Coastguard Worker value);
226*795d594fSAndroid Build Coastguard Worker }
227*795d594fSAndroid Build Coastguard Worker #define FIELD_SET(prim, type, jtype) \
228*795d594fSAndroid Build Coastguard Worker case Primitive::kPrim ## prim: \
229*795d594fSAndroid Build Coastguard Worker if (is_volatile) { \
230*795d594fSAndroid Build Coastguard Worker obj->SetField ## type ## Volatile<transaction_active>(offset, value.Get ## jtype()); \
231*795d594fSAndroid Build Coastguard Worker } else { \
232*795d594fSAndroid Build Coastguard Worker obj->SetField ## type<transaction_active>(offset, value.Get ## jtype()); \
233*795d594fSAndroid Build Coastguard Worker } \
234*795d594fSAndroid Build Coastguard Worker break;
235*795d594fSAndroid Build Coastguard Worker
236*795d594fSAndroid Build Coastguard Worker switch (field_type) {
237*795d594fSAndroid Build Coastguard Worker FIELD_SET(Boolean, Boolean, Z)
238*795d594fSAndroid Build Coastguard Worker FIELD_SET(Byte, Byte, B)
239*795d594fSAndroid Build Coastguard Worker FIELD_SET(Char, Char, C)
240*795d594fSAndroid Build Coastguard Worker FIELD_SET(Short, Short, S)
241*795d594fSAndroid Build Coastguard Worker FIELD_SET(Int, 32, I)
242*795d594fSAndroid Build Coastguard Worker FIELD_SET(Long, 64, J)
243*795d594fSAndroid Build Coastguard Worker FIELD_SET(Not, Object, L)
244*795d594fSAndroid Build Coastguard Worker case Primitive::kPrimVoid: {
245*795d594fSAndroid Build Coastguard Worker LOG(FATAL) << "Unreachable " << field_type;
246*795d594fSAndroid Build Coastguard Worker break;
247*795d594fSAndroid Build Coastguard Worker }
248*795d594fSAndroid Build Coastguard Worker }
249*795d594fSAndroid Build Coastguard Worker #undef FIELD_SET
250*795d594fSAndroid Build Coastguard Worker
251*795d594fSAndroid Build Coastguard Worker if (transaction_active) {
252*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(self->IsExceptionPending())) {
253*795d594fSAndroid Build Coastguard Worker return false;
254*795d594fSAndroid Build Coastguard Worker }
255*795d594fSAndroid Build Coastguard Worker }
256*795d594fSAndroid Build Coastguard Worker return true;
257*795d594fSAndroid Build Coastguard Worker }
258*795d594fSAndroid Build Coastguard Worker
259*795d594fSAndroid Build Coastguard Worker // Short-lived helper class which executes single DEX bytecode. It is inlined by compiler.
260*795d594fSAndroid Build Coastguard Worker // Any relevant execution information is stored in the fields - it should be kept to minimum.
261*795d594fSAndroid Build Coastguard Worker // All instance functions must be inlined so that the fields can be stored in registers.
262*795d594fSAndroid Build Coastguard Worker //
263*795d594fSAndroid Build Coastguard Worker // The function names must match the names from dex_instruction_list.h and have no arguments.
264*795d594fSAndroid Build Coastguard Worker // Return value: The handlers must return false if the instruction throws or returns (exits).
265*795d594fSAndroid Build Coastguard Worker //
266*795d594fSAndroid Build Coastguard Worker template<bool transaction_active, Instruction::Format kFormat>
267*795d594fSAndroid Build Coastguard Worker class InstructionHandler {
268*795d594fSAndroid Build Coastguard Worker public:
269*795d594fSAndroid Build Coastguard Worker using InstrumentationHandler = typename std::conditional_t<
270*795d594fSAndroid Build Coastguard Worker transaction_active, InactiveInstrumentationHandler, ActiveInstrumentationHandler>;
271*795d594fSAndroid Build Coastguard Worker using TransactionChecker = typename std::conditional_t<
272*795d594fSAndroid Build Coastguard Worker transaction_active, ActiveTransactionChecker, InactiveTransactionChecker>;
273*795d594fSAndroid Build Coastguard Worker
274*795d594fSAndroid Build Coastguard Worker #define HANDLER_ATTRIBUTES ALWAYS_INLINE FLATTEN WARN_UNUSED REQUIRES_SHARED(Locks::mutator_lock_)
275*795d594fSAndroid Build Coastguard Worker
CheckTransactionAbort()276*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool CheckTransactionAbort() {
277*795d594fSAndroid Build Coastguard Worker if (TransactionChecker::IsTransactionAborted()) {
278*795d594fSAndroid Build Coastguard Worker // Transaction abort cannot be caught by catch handlers.
279*795d594fSAndroid Build Coastguard Worker // Preserve the abort exception while doing non-standard return.
280*795d594fSAndroid Build Coastguard Worker StackHandleScope<1u> hs(Self());
281*795d594fSAndroid Build Coastguard Worker Handle<mirror::Throwable> abort_exception = hs.NewHandle(Self()->GetException());
282*795d594fSAndroid Build Coastguard Worker DCHECK(abort_exception != nullptr);
283*795d594fSAndroid Build Coastguard Worker DCHECK(abort_exception->GetClass()->DescriptorEquals(kTransactionAbortErrorDescriptor));
284*795d594fSAndroid Build Coastguard Worker Self()->ClearException();
285*795d594fSAndroid Build Coastguard Worker PerformNonStandardReturn(Self(), shadow_frame_, ctx_->result, Instrumentation());
286*795d594fSAndroid Build Coastguard Worker Self()->SetException(abort_exception.Get());
287*795d594fSAndroid Build Coastguard Worker ExitInterpreterLoop();
288*795d594fSAndroid Build Coastguard Worker return false;
289*795d594fSAndroid Build Coastguard Worker }
290*795d594fSAndroid Build Coastguard Worker return true;
291*795d594fSAndroid Build Coastguard Worker }
292*795d594fSAndroid Build Coastguard Worker
CheckForceReturn()293*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool CheckForceReturn() {
294*795d594fSAndroid Build Coastguard Worker if (InstrumentationHandler::GetForcePopFrame(shadow_frame_)) {
295*795d594fSAndroid Build Coastguard Worker DCHECK(Runtime::Current()->AreNonStandardExitsEnabled());
296*795d594fSAndroid Build Coastguard Worker PerformNonStandardReturn(Self(), shadow_frame_, ctx_->result, Instrumentation());
297*795d594fSAndroid Build Coastguard Worker ExitInterpreterLoop();
298*795d594fSAndroid Build Coastguard Worker return false;
299*795d594fSAndroid Build Coastguard Worker }
300*795d594fSAndroid Build Coastguard Worker return true;
301*795d594fSAndroid Build Coastguard Worker }
302*795d594fSAndroid Build Coastguard Worker
HandlePendingException()303*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool HandlePendingException() {
304*795d594fSAndroid Build Coastguard Worker DCHECK(Self()->IsExceptionPending());
305*795d594fSAndroid Build Coastguard Worker Self()->AllowThreadSuspension();
306*795d594fSAndroid Build Coastguard Worker if (!CheckTransactionAbort()) {
307*795d594fSAndroid Build Coastguard Worker return false;
308*795d594fSAndroid Build Coastguard Worker }
309*795d594fSAndroid Build Coastguard Worker if (!CheckForceReturn()) {
310*795d594fSAndroid Build Coastguard Worker return false;
311*795d594fSAndroid Build Coastguard Worker }
312*795d594fSAndroid Build Coastguard Worker bool skip_event = shadow_frame_.GetSkipNextExceptionEvent();
313*795d594fSAndroid Build Coastguard Worker shadow_frame_.SetSkipNextExceptionEvent(false);
314*795d594fSAndroid Build Coastguard Worker if (!MoveToExceptionHandler(Self(),
315*795d594fSAndroid Build Coastguard Worker shadow_frame_,
316*795d594fSAndroid Build Coastguard Worker /* skip_listeners= */ skip_event,
317*795d594fSAndroid Build Coastguard Worker /* skip_throw_listener= */ skip_event)) {
318*795d594fSAndroid Build Coastguard Worker // Structured locking is to be enforced for abnormal termination, too.
319*795d594fSAndroid Build Coastguard Worker DoMonitorCheckOnExit(Self(), &shadow_frame_);
320*795d594fSAndroid Build Coastguard Worker ctx_->result = JValue(); /* Handled in caller. */
321*795d594fSAndroid Build Coastguard Worker ExitInterpreterLoop();
322*795d594fSAndroid Build Coastguard Worker return false; // Return to caller.
323*795d594fSAndroid Build Coastguard Worker }
324*795d594fSAndroid Build Coastguard Worker if (!CheckForceReturn()) {
325*795d594fSAndroid Build Coastguard Worker return false;
326*795d594fSAndroid Build Coastguard Worker }
327*795d594fSAndroid Build Coastguard Worker int32_t displacement =
328*795d594fSAndroid Build Coastguard Worker static_cast<int32_t>(shadow_frame_.GetDexPC()) - static_cast<int32_t>(dex_pc_);
329*795d594fSAndroid Build Coastguard Worker SetNextInstruction(inst_->RelativeAt(displacement));
330*795d594fSAndroid Build Coastguard Worker return true;
331*795d594fSAndroid Build Coastguard Worker }
332*795d594fSAndroid Build Coastguard Worker
PossiblyHandlePendingExceptionOnInvoke(bool is_exception_pending)333*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool PossiblyHandlePendingExceptionOnInvoke(bool is_exception_pending) {
334*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(shadow_frame_.GetForceRetryInstruction())) {
335*795d594fSAndroid Build Coastguard Worker /* Don't need to do anything except clear the flag and exception. We leave the */
336*795d594fSAndroid Build Coastguard Worker /* instruction the same so it will be re-executed on the next go-around. */
337*795d594fSAndroid Build Coastguard Worker DCHECK(inst_->IsInvoke());
338*795d594fSAndroid Build Coastguard Worker shadow_frame_.SetForceRetryInstruction(false);
339*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(is_exception_pending)) {
340*795d594fSAndroid Build Coastguard Worker DCHECK(Self()->IsExceptionPending());
341*795d594fSAndroid Build Coastguard Worker if (kIsDebugBuild) {
342*795d594fSAndroid Build Coastguard Worker LOG(WARNING) << "Suppressing exception for instruction-retry: "
343*795d594fSAndroid Build Coastguard Worker << Self()->GetException()->Dump();
344*795d594fSAndroid Build Coastguard Worker }
345*795d594fSAndroid Build Coastguard Worker Self()->ClearException();
346*795d594fSAndroid Build Coastguard Worker }
347*795d594fSAndroid Build Coastguard Worker SetNextInstruction(inst_);
348*795d594fSAndroid Build Coastguard Worker } else if (UNLIKELY(is_exception_pending)) {
349*795d594fSAndroid Build Coastguard Worker /* Should have succeeded. */
350*795d594fSAndroid Build Coastguard Worker DCHECK(!shadow_frame_.GetForceRetryInstruction());
351*795d594fSAndroid Build Coastguard Worker return false; // Pending exception.
352*795d594fSAndroid Build Coastguard Worker }
353*795d594fSAndroid Build Coastguard Worker return true;
354*795d594fSAndroid Build Coastguard Worker }
355*795d594fSAndroid Build Coastguard Worker
356*795d594fSAndroid Build Coastguard Worker // Code to run before each dex instruction.
Preamble()357*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool Preamble() {
358*795d594fSAndroid Build Coastguard Worker /* We need to put this before & after the instrumentation to avoid having to put in a */
359*795d594fSAndroid Build Coastguard Worker /* post-script macro. */
360*795d594fSAndroid Build Coastguard Worker if (!CheckForceReturn()) {
361*795d594fSAndroid Build Coastguard Worker return false;
362*795d594fSAndroid Build Coastguard Worker }
363*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(InstrumentationHandler::NeedsDexPcEvents(shadow_frame_))) {
364*795d594fSAndroid Build Coastguard Worker uint8_t opcode = inst_->Opcode(inst_data_);
365*795d594fSAndroid Build Coastguard Worker bool is_move_result_object = (opcode == Instruction::MOVE_RESULT_OBJECT);
366*795d594fSAndroid Build Coastguard Worker JValue* save_ref = is_move_result_object ? &ctx_->result_register : nullptr;
367*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(!InstrumentationHandler::DoDexPcMoveEvent(Self(),
368*795d594fSAndroid Build Coastguard Worker Accessor(),
369*795d594fSAndroid Build Coastguard Worker shadow_frame_,
370*795d594fSAndroid Build Coastguard Worker DexPC(),
371*795d594fSAndroid Build Coastguard Worker Instrumentation(),
372*795d594fSAndroid Build Coastguard Worker save_ref))) {
373*795d594fSAndroid Build Coastguard Worker DCHECK(Self()->IsExceptionPending());
374*795d594fSAndroid Build Coastguard Worker // Do not raise exception event if it is caused by other instrumentation event.
375*795d594fSAndroid Build Coastguard Worker shadow_frame_.SetSkipNextExceptionEvent(true);
376*795d594fSAndroid Build Coastguard Worker return false; // Pending exception.
377*795d594fSAndroid Build Coastguard Worker }
378*795d594fSAndroid Build Coastguard Worker if (!CheckForceReturn()) {
379*795d594fSAndroid Build Coastguard Worker return false;
380*795d594fSAndroid Build Coastguard Worker }
381*795d594fSAndroid Build Coastguard Worker }
382*795d594fSAndroid Build Coastguard Worker
383*795d594fSAndroid Build Coastguard Worker // Call any exception handled event handlers after the dex pc move event.
384*795d594fSAndroid Build Coastguard Worker // The order is important to see a consistent behaviour in the debuggers.
385*795d594fSAndroid Build Coastguard Worker // See b/333446719 for more discussion.
386*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(shadow_frame_.GetNotifyExceptionHandledEvent())) {
387*795d594fSAndroid Build Coastguard Worker shadow_frame_.SetNotifyExceptionHandledEvent(/*enable=*/ false);
388*795d594fSAndroid Build Coastguard Worker bool is_move_exception = (inst_->Opcode(inst_data_) == Instruction::MOVE_EXCEPTION);
389*795d594fSAndroid Build Coastguard Worker
390*795d594fSAndroid Build Coastguard Worker if (!InstrumentationHandler::ExceptionHandledEvent(
391*795d594fSAndroid Build Coastguard Worker Self(), is_move_exception, Instrumentation())) {
392*795d594fSAndroid Build Coastguard Worker DCHECK(Self()->IsExceptionPending());
393*795d594fSAndroid Build Coastguard Worker // TODO(375373721): We need to set SetSkipNextExceptionEvent here since the exception was
394*795d594fSAndroid Build Coastguard Worker // thrown by an instrumentation handler.
395*795d594fSAndroid Build Coastguard Worker return false; // Pending exception.
396*795d594fSAndroid Build Coastguard Worker }
397*795d594fSAndroid Build Coastguard Worker
398*795d594fSAndroid Build Coastguard Worker if (!CheckForceReturn()) {
399*795d594fSAndroid Build Coastguard Worker return false;
400*795d594fSAndroid Build Coastguard Worker }
401*795d594fSAndroid Build Coastguard Worker }
402*795d594fSAndroid Build Coastguard Worker return true;
403*795d594fSAndroid Build Coastguard Worker }
404*795d594fSAndroid Build Coastguard Worker
HandleReturn(JValue result)405*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool HandleReturn(JValue result) {
406*795d594fSAndroid Build Coastguard Worker Self()->AllowThreadSuspension();
407*795d594fSAndroid Build Coastguard Worker if (!DoMonitorCheckOnExit(Self(), &shadow_frame_)) {
408*795d594fSAndroid Build Coastguard Worker return false;
409*795d594fSAndroid Build Coastguard Worker }
410*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(InstrumentationHandler::NeedsMethodExitEvent(Instrumentation()) &&
411*795d594fSAndroid Build Coastguard Worker !InstrumentationHandler::SendMethodExitEvents(Self(),
412*795d594fSAndroid Build Coastguard Worker Instrumentation(),
413*795d594fSAndroid Build Coastguard Worker shadow_frame_,
414*795d594fSAndroid Build Coastguard Worker shadow_frame_.GetMethod(),
415*795d594fSAndroid Build Coastguard Worker result))) {
416*795d594fSAndroid Build Coastguard Worker DCHECK(Self()->IsExceptionPending());
417*795d594fSAndroid Build Coastguard Worker // Do not raise exception event if it is caused by other instrumentation event.
418*795d594fSAndroid Build Coastguard Worker shadow_frame_.SetSkipNextExceptionEvent(true);
419*795d594fSAndroid Build Coastguard Worker return false; // Pending exception.
420*795d594fSAndroid Build Coastguard Worker }
421*795d594fSAndroid Build Coastguard Worker ctx_->result = result;
422*795d594fSAndroid Build Coastguard Worker ExitInterpreterLoop();
423*795d594fSAndroid Build Coastguard Worker return false;
424*795d594fSAndroid Build Coastguard Worker }
425*795d594fSAndroid Build Coastguard Worker
HandleBranch(int32_t offset)426*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool HandleBranch(int32_t offset) {
427*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(Self()->ObserveAsyncException())) {
428*795d594fSAndroid Build Coastguard Worker return false; // Pending exception.
429*795d594fSAndroid Build Coastguard Worker }
430*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(InstrumentationHandler::HasBranchListeners(Instrumentation()))) {
431*795d594fSAndroid Build Coastguard Worker InstrumentationHandler::Branch(
432*795d594fSAndroid Build Coastguard Worker Self(), shadow_frame_.GetMethod(), DexPC(), offset, Instrumentation());
433*795d594fSAndroid Build Coastguard Worker }
434*795d594fSAndroid Build Coastguard Worker if (!transaction_active) {
435*795d594fSAndroid Build Coastguard Worker // TODO: Do OSR only on back-edges and check if OSR code is ready here.
436*795d594fSAndroid Build Coastguard Worker JValue result;
437*795d594fSAndroid Build Coastguard Worker if (jit::Jit::MaybeDoOnStackReplacement(Self(),
438*795d594fSAndroid Build Coastguard Worker shadow_frame_.GetMethod(),
439*795d594fSAndroid Build Coastguard Worker DexPC(),
440*795d594fSAndroid Build Coastguard Worker offset,
441*795d594fSAndroid Build Coastguard Worker &result)) {
442*795d594fSAndroid Build Coastguard Worker ctx_->result = result;
443*795d594fSAndroid Build Coastguard Worker ExitInterpreterLoop();
444*795d594fSAndroid Build Coastguard Worker return false;
445*795d594fSAndroid Build Coastguard Worker }
446*795d594fSAndroid Build Coastguard Worker }
447*795d594fSAndroid Build Coastguard Worker SetNextInstruction(inst_->RelativeAt(offset));
448*795d594fSAndroid Build Coastguard Worker if (offset <= 0) { // Back-edge.
449*795d594fSAndroid Build Coastguard Worker // Hotness update.
450*795d594fSAndroid Build Coastguard Worker jit::Jit* jit = Runtime::Current()->GetJit();
451*795d594fSAndroid Build Coastguard Worker if (jit != nullptr) {
452*795d594fSAndroid Build Coastguard Worker jit->AddSamples(Self(), shadow_frame_.GetMethod());
453*795d594fSAndroid Build Coastguard Worker }
454*795d594fSAndroid Build Coastguard Worker // Record new dex pc early to have consistent suspend point at loop header.
455*795d594fSAndroid Build Coastguard Worker shadow_frame_.SetDexPC(next_->GetDexPc(Insns()));
456*795d594fSAndroid Build Coastguard Worker Self()->AllowThreadSuspension();
457*795d594fSAndroid Build Coastguard Worker }
458*795d594fSAndroid Build Coastguard Worker return true;
459*795d594fSAndroid Build Coastguard Worker }
460*795d594fSAndroid Build Coastguard Worker
HandleIf(bool cond,int32_t offset)461*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool HandleIf(bool cond, int32_t offset) {
462*795d594fSAndroid Build Coastguard Worker return HandleBranch(cond ? offset : Instruction::SizeInCodeUnits(kFormat));
463*795d594fSAndroid Build Coastguard Worker }
464*795d594fSAndroid Build Coastguard Worker
465*795d594fSAndroid Build Coastguard Worker #pragma clang diagnostic push
466*795d594fSAndroid Build Coastguard Worker #pragma clang diagnostic ignored "-Wfloat-equal"
467*795d594fSAndroid Build Coastguard Worker
468*795d594fSAndroid Build Coastguard Worker template<typename T>
HandleCmpl(T val1,T val2)469*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool HandleCmpl(T val1, T val2) {
470*795d594fSAndroid Build Coastguard Worker int32_t result;
471*795d594fSAndroid Build Coastguard Worker if (val1 > val2) {
472*795d594fSAndroid Build Coastguard Worker result = 1;
473*795d594fSAndroid Build Coastguard Worker } else if (val1 == val2) {
474*795d594fSAndroid Build Coastguard Worker result = 0;
475*795d594fSAndroid Build Coastguard Worker } else {
476*795d594fSAndroid Build Coastguard Worker result = -1;
477*795d594fSAndroid Build Coastguard Worker }
478*795d594fSAndroid Build Coastguard Worker SetVReg(A(), result);
479*795d594fSAndroid Build Coastguard Worker return true;
480*795d594fSAndroid Build Coastguard Worker }
481*795d594fSAndroid Build Coastguard Worker
482*795d594fSAndroid Build Coastguard Worker // Returns the same result as the function above. It only differs for NaN values.
483*795d594fSAndroid Build Coastguard Worker template<typename T>
HandleCmpg(T val1,T val2)484*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool HandleCmpg(T val1, T val2) {
485*795d594fSAndroid Build Coastguard Worker int32_t result;
486*795d594fSAndroid Build Coastguard Worker if (val1 < val2) {
487*795d594fSAndroid Build Coastguard Worker result = -1;
488*795d594fSAndroid Build Coastguard Worker } else if (val1 == val2) {
489*795d594fSAndroid Build Coastguard Worker result = 0;
490*795d594fSAndroid Build Coastguard Worker } else {
491*795d594fSAndroid Build Coastguard Worker result = 1;
492*795d594fSAndroid Build Coastguard Worker }
493*795d594fSAndroid Build Coastguard Worker SetVReg(A(), result);
494*795d594fSAndroid Build Coastguard Worker return true;
495*795d594fSAndroid Build Coastguard Worker }
496*795d594fSAndroid Build Coastguard Worker
497*795d594fSAndroid Build Coastguard Worker #pragma clang diagnostic pop
498*795d594fSAndroid Build Coastguard Worker
HandleConstString()499*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool HandleConstString() {
500*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::String> s = ResolveString(Self(), shadow_frame_, dex::StringIndex(B()));
501*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(s == nullptr)) {
502*795d594fSAndroid Build Coastguard Worker return false; // Pending exception.
503*795d594fSAndroid Build Coastguard Worker }
504*795d594fSAndroid Build Coastguard Worker SetVRegReference(A(), s);
505*795d594fSAndroid Build Coastguard Worker return true;
506*795d594fSAndroid Build Coastguard Worker }
507*795d594fSAndroid Build Coastguard Worker
508*795d594fSAndroid Build Coastguard Worker template<typename ArrayType, typename SetVRegFn>
HandleAGet(SetVRegFn setVReg)509*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool HandleAGet(SetVRegFn setVReg) {
510*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> a = GetVRegReference(B());
511*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(a == nullptr)) {
512*795d594fSAndroid Build Coastguard Worker ThrowNullPointerExceptionFromInterpreter();
513*795d594fSAndroid Build Coastguard Worker return false; // Pending exception.
514*795d594fSAndroid Build Coastguard Worker }
515*795d594fSAndroid Build Coastguard Worker int32_t index = GetVReg(C());
516*795d594fSAndroid Build Coastguard Worker ObjPtr<ArrayType> array = ObjPtr<ArrayType>::DownCast(a);
517*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(!array->CheckIsValidIndex(index))) {
518*795d594fSAndroid Build Coastguard Worker return false; // Pending exception.
519*795d594fSAndroid Build Coastguard Worker }
520*795d594fSAndroid Build Coastguard Worker (this->*setVReg)(A(), array->GetWithoutChecks(index));
521*795d594fSAndroid Build Coastguard Worker return true;
522*795d594fSAndroid Build Coastguard Worker }
523*795d594fSAndroid Build Coastguard Worker
524*795d594fSAndroid Build Coastguard Worker template<typename ArrayType, typename T>
HandleAPut(T value)525*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool HandleAPut(T value) {
526*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> a = GetVRegReference(B());
527*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(a == nullptr)) {
528*795d594fSAndroid Build Coastguard Worker ThrowNullPointerExceptionFromInterpreter();
529*795d594fSAndroid Build Coastguard Worker return false; // Pending exception.
530*795d594fSAndroid Build Coastguard Worker }
531*795d594fSAndroid Build Coastguard Worker int32_t index = GetVReg(C());
532*795d594fSAndroid Build Coastguard Worker ObjPtr<ArrayType> array = ObjPtr<ArrayType>::DownCast(a);
533*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(!array->CheckIsValidIndex(index))) {
534*795d594fSAndroid Build Coastguard Worker return false; // Pending exception.
535*795d594fSAndroid Build Coastguard Worker }
536*795d594fSAndroid Build Coastguard Worker if (TransactionChecker::WriteConstraint(Self(), array)) {
537*795d594fSAndroid Build Coastguard Worker return false;
538*795d594fSAndroid Build Coastguard Worker }
539*795d594fSAndroid Build Coastguard Worker array->template SetWithoutChecks<transaction_active>(index, value);
540*795d594fSAndroid Build Coastguard Worker return true;
541*795d594fSAndroid Build Coastguard Worker }
542*795d594fSAndroid Build Coastguard Worker
543*795d594fSAndroid Build Coastguard Worker template<FindFieldType find_type, Primitive::Type field_type>
HandleGet()544*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool HandleGet() {
545*795d594fSAndroid Build Coastguard Worker return DoFieldGet<find_type, field_type, transaction_active>(
546*795d594fSAndroid Build Coastguard Worker Self(), shadow_frame_, inst_, inst_data_, Instrumentation());
547*795d594fSAndroid Build Coastguard Worker }
548*795d594fSAndroid Build Coastguard Worker
549*795d594fSAndroid Build Coastguard Worker template<FindFieldType find_type, Primitive::Type field_type>
HandlePut()550*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool HandlePut() {
551*795d594fSAndroid Build Coastguard Worker return DoFieldPut<find_type, field_type, transaction_active>(
552*795d594fSAndroid Build Coastguard Worker Self(), shadow_frame_, inst_, inst_data_, Instrumentation());
553*795d594fSAndroid Build Coastguard Worker }
554*795d594fSAndroid Build Coastguard Worker
555*795d594fSAndroid Build Coastguard Worker template<InvokeType type, bool is_range>
HandleInvoke()556*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool HandleInvoke() {
557*795d594fSAndroid Build Coastguard Worker bool success = DoInvoke<type, is_range>(
558*795d594fSAndroid Build Coastguard Worker Self(), shadow_frame_, inst_, inst_data_, ResultRegister());
559*795d594fSAndroid Build Coastguard Worker return PossiblyHandlePendingExceptionOnInvoke(!success);
560*795d594fSAndroid Build Coastguard Worker }
561*795d594fSAndroid Build Coastguard Worker
HandleUnused()562*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool HandleUnused() {
563*795d594fSAndroid Build Coastguard Worker UnexpectedOpcode(inst_, shadow_frame_);
564*795d594fSAndroid Build Coastguard Worker return true;
565*795d594fSAndroid Build Coastguard Worker }
566*795d594fSAndroid Build Coastguard Worker
NOP()567*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool NOP() {
568*795d594fSAndroid Build Coastguard Worker return true;
569*795d594fSAndroid Build Coastguard Worker }
570*795d594fSAndroid Build Coastguard Worker
MOVE()571*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool MOVE() {
572*795d594fSAndroid Build Coastguard Worker SetVReg(A(), GetVReg(B()));
573*795d594fSAndroid Build Coastguard Worker return true;
574*795d594fSAndroid Build Coastguard Worker }
575*795d594fSAndroid Build Coastguard Worker
MOVE_FROM16()576*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool MOVE_FROM16() {
577*795d594fSAndroid Build Coastguard Worker SetVReg(A(), GetVReg(B()));
578*795d594fSAndroid Build Coastguard Worker return true;
579*795d594fSAndroid Build Coastguard Worker }
580*795d594fSAndroid Build Coastguard Worker
MOVE_16()581*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool MOVE_16() {
582*795d594fSAndroid Build Coastguard Worker SetVReg(A(), GetVReg(B()));
583*795d594fSAndroid Build Coastguard Worker return true;
584*795d594fSAndroid Build Coastguard Worker }
585*795d594fSAndroid Build Coastguard Worker
MOVE_WIDE()586*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool MOVE_WIDE() {
587*795d594fSAndroid Build Coastguard Worker SetVRegLong(A(), GetVRegLong(B()));
588*795d594fSAndroid Build Coastguard Worker return true;
589*795d594fSAndroid Build Coastguard Worker }
590*795d594fSAndroid Build Coastguard Worker
MOVE_WIDE_FROM16()591*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool MOVE_WIDE_FROM16() {
592*795d594fSAndroid Build Coastguard Worker SetVRegLong(A(), GetVRegLong(B()));
593*795d594fSAndroid Build Coastguard Worker return true;
594*795d594fSAndroid Build Coastguard Worker }
595*795d594fSAndroid Build Coastguard Worker
MOVE_WIDE_16()596*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool MOVE_WIDE_16() {
597*795d594fSAndroid Build Coastguard Worker SetVRegLong(A(), GetVRegLong(B()));
598*795d594fSAndroid Build Coastguard Worker return true;
599*795d594fSAndroid Build Coastguard Worker }
600*795d594fSAndroid Build Coastguard Worker
MOVE_OBJECT()601*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool MOVE_OBJECT() {
602*795d594fSAndroid Build Coastguard Worker SetVRegReference(A(), GetVRegReference(B()));
603*795d594fSAndroid Build Coastguard Worker return true;
604*795d594fSAndroid Build Coastguard Worker }
605*795d594fSAndroid Build Coastguard Worker
MOVE_OBJECT_FROM16()606*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool MOVE_OBJECT_FROM16() {
607*795d594fSAndroid Build Coastguard Worker SetVRegReference(A(), GetVRegReference(B()));
608*795d594fSAndroid Build Coastguard Worker return true;
609*795d594fSAndroid Build Coastguard Worker }
610*795d594fSAndroid Build Coastguard Worker
MOVE_OBJECT_16()611*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool MOVE_OBJECT_16() {
612*795d594fSAndroid Build Coastguard Worker SetVRegReference(A(), GetVRegReference(B()));
613*795d594fSAndroid Build Coastguard Worker return true;
614*795d594fSAndroid Build Coastguard Worker }
615*795d594fSAndroid Build Coastguard Worker
MOVE_RESULT()616*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool MOVE_RESULT() {
617*795d594fSAndroid Build Coastguard Worker SetVReg(A(), ResultRegister()->GetI());
618*795d594fSAndroid Build Coastguard Worker return true;
619*795d594fSAndroid Build Coastguard Worker }
620*795d594fSAndroid Build Coastguard Worker
MOVE_RESULT_WIDE()621*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool MOVE_RESULT_WIDE() {
622*795d594fSAndroid Build Coastguard Worker SetVRegLong(A(), ResultRegister()->GetJ());
623*795d594fSAndroid Build Coastguard Worker return true;
624*795d594fSAndroid Build Coastguard Worker }
625*795d594fSAndroid Build Coastguard Worker
MOVE_RESULT_OBJECT()626*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool MOVE_RESULT_OBJECT() {
627*795d594fSAndroid Build Coastguard Worker SetVRegReference(A(), ResultRegister()->GetL());
628*795d594fSAndroid Build Coastguard Worker return true;
629*795d594fSAndroid Build Coastguard Worker }
630*795d594fSAndroid Build Coastguard Worker
MOVE_EXCEPTION()631*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool MOVE_EXCEPTION() {
632*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Throwable> exception = Self()->GetException();
633*795d594fSAndroid Build Coastguard Worker DCHECK(exception != nullptr) << "No pending exception on MOVE_EXCEPTION instruction";
634*795d594fSAndroid Build Coastguard Worker SetVRegReference(A(), exception);
635*795d594fSAndroid Build Coastguard Worker Self()->ClearException();
636*795d594fSAndroid Build Coastguard Worker return true;
637*795d594fSAndroid Build Coastguard Worker }
638*795d594fSAndroid Build Coastguard Worker
RETURN_VOID()639*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool RETURN_VOID() {
640*795d594fSAndroid Build Coastguard Worker QuasiAtomic::ThreadFenceForConstructor();
641*795d594fSAndroid Build Coastguard Worker JValue result;
642*795d594fSAndroid Build Coastguard Worker return HandleReturn(result);
643*795d594fSAndroid Build Coastguard Worker }
644*795d594fSAndroid Build Coastguard Worker
RETURN()645*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool RETURN() {
646*795d594fSAndroid Build Coastguard Worker JValue result;
647*795d594fSAndroid Build Coastguard Worker result.SetJ(0);
648*795d594fSAndroid Build Coastguard Worker result.SetI(GetVReg(A()));
649*795d594fSAndroid Build Coastguard Worker return HandleReturn(result);
650*795d594fSAndroid Build Coastguard Worker }
651*795d594fSAndroid Build Coastguard Worker
RETURN_WIDE()652*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool RETURN_WIDE() {
653*795d594fSAndroid Build Coastguard Worker JValue result;
654*795d594fSAndroid Build Coastguard Worker result.SetJ(GetVRegLong(A()));
655*795d594fSAndroid Build Coastguard Worker return HandleReturn(result);
656*795d594fSAndroid Build Coastguard Worker }
657*795d594fSAndroid Build Coastguard Worker
RETURN_OBJECT()658*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool RETURN_OBJECT() {
659*795d594fSAndroid Build Coastguard Worker JValue result;
660*795d594fSAndroid Build Coastguard Worker Self()->AllowThreadSuspension();
661*795d594fSAndroid Build Coastguard Worker if (!DoMonitorCheckOnExit(Self(), &shadow_frame_)) {
662*795d594fSAndroid Build Coastguard Worker return false;
663*795d594fSAndroid Build Coastguard Worker }
664*795d594fSAndroid Build Coastguard Worker const size_t ref_idx = A();
665*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> obj_result = GetVRegReference(ref_idx);
666*795d594fSAndroid Build Coastguard Worker if (obj_result != nullptr && UNLIKELY(DoAssignabilityChecks())) {
667*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> return_type = shadow_frame_.GetMethod()->ResolveReturnType();
668*795d594fSAndroid Build Coastguard Worker // Re-load since it might have moved.
669*795d594fSAndroid Build Coastguard Worker obj_result = GetVRegReference(ref_idx);
670*795d594fSAndroid Build Coastguard Worker if (return_type == nullptr) {
671*795d594fSAndroid Build Coastguard Worker // Return the pending exception.
672*795d594fSAndroid Build Coastguard Worker return false; // Pending exception.
673*795d594fSAndroid Build Coastguard Worker }
674*795d594fSAndroid Build Coastguard Worker if (!obj_result->VerifierInstanceOf(return_type)) {
675*795d594fSAndroid Build Coastguard Worker CHECK_LE(Runtime::Current()->GetTargetSdkVersion(), 29u);
676*795d594fSAndroid Build Coastguard Worker // This should never happen.
677*795d594fSAndroid Build Coastguard Worker std::string temp1, temp2;
678*795d594fSAndroid Build Coastguard Worker Self()->ThrowNewExceptionF("Ljava/lang/InternalError;",
679*795d594fSAndroid Build Coastguard Worker "Returning '%s' that is not instance of return type '%s'",
680*795d594fSAndroid Build Coastguard Worker obj_result->GetClass()->GetDescriptor(&temp1),
681*795d594fSAndroid Build Coastguard Worker return_type->GetDescriptor(&temp2));
682*795d594fSAndroid Build Coastguard Worker return false; // Pending exception.
683*795d594fSAndroid Build Coastguard Worker }
684*795d594fSAndroid Build Coastguard Worker }
685*795d594fSAndroid Build Coastguard Worker result.SetL(obj_result);
686*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(InstrumentationHandler::NeedsMethodExitEvent(Instrumentation()))) {
687*795d594fSAndroid Build Coastguard Worker StackHandleScope<1> hs(Self());
688*795d594fSAndroid Build Coastguard Worker MutableHandle<mirror::Object> h_result(hs.NewHandle(obj_result));
689*795d594fSAndroid Build Coastguard Worker if (!InstrumentationHandler::SendMethodExitEvents(Self(),
690*795d594fSAndroid Build Coastguard Worker Instrumentation(),
691*795d594fSAndroid Build Coastguard Worker shadow_frame_,
692*795d594fSAndroid Build Coastguard Worker shadow_frame_.GetMethod(),
693*795d594fSAndroid Build Coastguard Worker h_result)) {
694*795d594fSAndroid Build Coastguard Worker DCHECK(Self()->IsExceptionPending());
695*795d594fSAndroid Build Coastguard Worker // Do not raise exception event if it is caused by other instrumentation event.
696*795d594fSAndroid Build Coastguard Worker shadow_frame_.SetSkipNextExceptionEvent(true);
697*795d594fSAndroid Build Coastguard Worker return false; // Pending exception.
698*795d594fSAndroid Build Coastguard Worker }
699*795d594fSAndroid Build Coastguard Worker // Re-load since it might have moved or been replaced during the MethodExitEvent.
700*795d594fSAndroid Build Coastguard Worker result.SetL(h_result.Get());
701*795d594fSAndroid Build Coastguard Worker }
702*795d594fSAndroid Build Coastguard Worker ctx_->result = result;
703*795d594fSAndroid Build Coastguard Worker ExitInterpreterLoop();
704*795d594fSAndroid Build Coastguard Worker return false;
705*795d594fSAndroid Build Coastguard Worker }
706*795d594fSAndroid Build Coastguard Worker
CONST_4()707*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool CONST_4() {
708*795d594fSAndroid Build Coastguard Worker SetVReg(A(), B());
709*795d594fSAndroid Build Coastguard Worker return true;
710*795d594fSAndroid Build Coastguard Worker }
711*795d594fSAndroid Build Coastguard Worker
CONST_16()712*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool CONST_16() {
713*795d594fSAndroid Build Coastguard Worker SetVReg(A(), B());
714*795d594fSAndroid Build Coastguard Worker return true;
715*795d594fSAndroid Build Coastguard Worker }
716*795d594fSAndroid Build Coastguard Worker
CONST()717*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool CONST() {
718*795d594fSAndroid Build Coastguard Worker SetVReg(A(), B());
719*795d594fSAndroid Build Coastguard Worker return true;
720*795d594fSAndroid Build Coastguard Worker }
721*795d594fSAndroid Build Coastguard Worker
CONST_HIGH16()722*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool CONST_HIGH16() {
723*795d594fSAndroid Build Coastguard Worker SetVReg(A(), static_cast<int32_t>(B() << 16));
724*795d594fSAndroid Build Coastguard Worker return true;
725*795d594fSAndroid Build Coastguard Worker }
726*795d594fSAndroid Build Coastguard Worker
CONST_WIDE_16()727*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool CONST_WIDE_16() {
728*795d594fSAndroid Build Coastguard Worker SetVRegLong(A(), B());
729*795d594fSAndroid Build Coastguard Worker return true;
730*795d594fSAndroid Build Coastguard Worker }
731*795d594fSAndroid Build Coastguard Worker
CONST_WIDE_32()732*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool CONST_WIDE_32() {
733*795d594fSAndroid Build Coastguard Worker SetVRegLong(A(), B());
734*795d594fSAndroid Build Coastguard Worker return true;
735*795d594fSAndroid Build Coastguard Worker }
736*795d594fSAndroid Build Coastguard Worker
CONST_WIDE()737*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool CONST_WIDE() {
738*795d594fSAndroid Build Coastguard Worker SetVRegLong(A(), inst_->WideVRegB());
739*795d594fSAndroid Build Coastguard Worker return true;
740*795d594fSAndroid Build Coastguard Worker }
741*795d594fSAndroid Build Coastguard Worker
CONST_WIDE_HIGH16()742*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool CONST_WIDE_HIGH16() {
743*795d594fSAndroid Build Coastguard Worker SetVRegLong(A(), static_cast<uint64_t>(B()) << 48);
744*795d594fSAndroid Build Coastguard Worker return true;
745*795d594fSAndroid Build Coastguard Worker }
746*795d594fSAndroid Build Coastguard Worker
CONST_STRING()747*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool CONST_STRING() {
748*795d594fSAndroid Build Coastguard Worker return HandleConstString();
749*795d594fSAndroid Build Coastguard Worker }
750*795d594fSAndroid Build Coastguard Worker
CONST_STRING_JUMBO()751*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool CONST_STRING_JUMBO() {
752*795d594fSAndroid Build Coastguard Worker return HandleConstString();
753*795d594fSAndroid Build Coastguard Worker }
754*795d594fSAndroid Build Coastguard Worker
CONST_CLASS()755*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool CONST_CLASS() {
756*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> c =
757*795d594fSAndroid Build Coastguard Worker ResolveVerifyAndClinit(dex::TypeIndex(B()),
758*795d594fSAndroid Build Coastguard Worker shadow_frame_.GetMethod(),
759*795d594fSAndroid Build Coastguard Worker Self(),
760*795d594fSAndroid Build Coastguard Worker false,
761*795d594fSAndroid Build Coastguard Worker !shadow_frame_.GetMethod()->SkipAccessChecks());
762*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(c == nullptr)) {
763*795d594fSAndroid Build Coastguard Worker return false; // Pending exception.
764*795d594fSAndroid Build Coastguard Worker }
765*795d594fSAndroid Build Coastguard Worker SetVRegReference(A(), c);
766*795d594fSAndroid Build Coastguard Worker return true;
767*795d594fSAndroid Build Coastguard Worker }
768*795d594fSAndroid Build Coastguard Worker
CONST_METHOD_HANDLE()769*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool CONST_METHOD_HANDLE() {
770*795d594fSAndroid Build Coastguard Worker ClassLinker* cl = Runtime::Current()->GetClassLinker();
771*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::MethodHandle> mh = cl->ResolveMethodHandle(Self(),
772*795d594fSAndroid Build Coastguard Worker B(),
773*795d594fSAndroid Build Coastguard Worker shadow_frame_.GetMethod());
774*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(mh == nullptr)) {
775*795d594fSAndroid Build Coastguard Worker return false; // Pending exception.
776*795d594fSAndroid Build Coastguard Worker }
777*795d594fSAndroid Build Coastguard Worker SetVRegReference(A(), mh);
778*795d594fSAndroid Build Coastguard Worker return true;
779*795d594fSAndroid Build Coastguard Worker }
780*795d594fSAndroid Build Coastguard Worker
CONST_METHOD_TYPE()781*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool CONST_METHOD_TYPE() {
782*795d594fSAndroid Build Coastguard Worker ClassLinker* cl = Runtime::Current()->GetClassLinker();
783*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::MethodType> mt = cl->ResolveMethodType(Self(),
784*795d594fSAndroid Build Coastguard Worker dex::ProtoIndex(B()),
785*795d594fSAndroid Build Coastguard Worker shadow_frame_.GetMethod());
786*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(mt == nullptr)) {
787*795d594fSAndroid Build Coastguard Worker return false; // Pending exception.
788*795d594fSAndroid Build Coastguard Worker }
789*795d594fSAndroid Build Coastguard Worker SetVRegReference(A(), mt);
790*795d594fSAndroid Build Coastguard Worker return true;
791*795d594fSAndroid Build Coastguard Worker }
792*795d594fSAndroid Build Coastguard Worker
MONITOR_ENTER()793*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool MONITOR_ENTER() {
794*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(Self()->ObserveAsyncException())) {
795*795d594fSAndroid Build Coastguard Worker return false; // Pending exception.
796*795d594fSAndroid Build Coastguard Worker }
797*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> obj = GetVRegReference(A());
798*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(obj == nullptr)) {
799*795d594fSAndroid Build Coastguard Worker ThrowNullPointerExceptionFromInterpreter();
800*795d594fSAndroid Build Coastguard Worker return false; // Pending exception.
801*795d594fSAndroid Build Coastguard Worker }
802*795d594fSAndroid Build Coastguard Worker DoMonitorEnter(Self(), &shadow_frame_, obj);
803*795d594fSAndroid Build Coastguard Worker return !Self()->IsExceptionPending();
804*795d594fSAndroid Build Coastguard Worker }
805*795d594fSAndroid Build Coastguard Worker
MONITOR_EXIT()806*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool MONITOR_EXIT() {
807*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(Self()->ObserveAsyncException())) {
808*795d594fSAndroid Build Coastguard Worker return false; // Pending exception.
809*795d594fSAndroid Build Coastguard Worker }
810*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> obj = GetVRegReference(A());
811*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(obj == nullptr)) {
812*795d594fSAndroid Build Coastguard Worker ThrowNullPointerExceptionFromInterpreter();
813*795d594fSAndroid Build Coastguard Worker return false; // Pending exception.
814*795d594fSAndroid Build Coastguard Worker }
815*795d594fSAndroid Build Coastguard Worker DoMonitorExit(Self(), &shadow_frame_, obj);
816*795d594fSAndroid Build Coastguard Worker return !Self()->IsExceptionPending();
817*795d594fSAndroid Build Coastguard Worker }
818*795d594fSAndroid Build Coastguard Worker
CHECK_CAST()819*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool CHECK_CAST() {
820*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> c =
821*795d594fSAndroid Build Coastguard Worker ResolveVerifyAndClinit(dex::TypeIndex(B()),
822*795d594fSAndroid Build Coastguard Worker shadow_frame_.GetMethod(),
823*795d594fSAndroid Build Coastguard Worker Self(),
824*795d594fSAndroid Build Coastguard Worker false,
825*795d594fSAndroid Build Coastguard Worker !shadow_frame_.GetMethod()->SkipAccessChecks());
826*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(c == nullptr)) {
827*795d594fSAndroid Build Coastguard Worker return false; // Pending exception.
828*795d594fSAndroid Build Coastguard Worker }
829*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> obj = GetVRegReference(A());
830*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(obj != nullptr && !obj->InstanceOf(c))) {
831*795d594fSAndroid Build Coastguard Worker ThrowClassCastException(c, obj->GetClass());
832*795d594fSAndroid Build Coastguard Worker return false; // Pending exception.
833*795d594fSAndroid Build Coastguard Worker }
834*795d594fSAndroid Build Coastguard Worker return true;
835*795d594fSAndroid Build Coastguard Worker }
836*795d594fSAndroid Build Coastguard Worker
INSTANCE_OF()837*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool INSTANCE_OF() {
838*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> c =
839*795d594fSAndroid Build Coastguard Worker ResolveVerifyAndClinit(dex::TypeIndex(C()),
840*795d594fSAndroid Build Coastguard Worker shadow_frame_.GetMethod(),
841*795d594fSAndroid Build Coastguard Worker Self(),
842*795d594fSAndroid Build Coastguard Worker false,
843*795d594fSAndroid Build Coastguard Worker !shadow_frame_.GetMethod()->SkipAccessChecks());
844*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(c == nullptr)) {
845*795d594fSAndroid Build Coastguard Worker return false; // Pending exception.
846*795d594fSAndroid Build Coastguard Worker }
847*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> obj = GetVRegReference(B());
848*795d594fSAndroid Build Coastguard Worker SetVReg(A(), (obj != nullptr && obj->InstanceOf(c)) ? 1 : 0);
849*795d594fSAndroid Build Coastguard Worker return true;
850*795d594fSAndroid Build Coastguard Worker }
851*795d594fSAndroid Build Coastguard Worker
ARRAY_LENGTH()852*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool ARRAY_LENGTH() {
853*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> array = GetVRegReference(B());
854*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(array == nullptr)) {
855*795d594fSAndroid Build Coastguard Worker ThrowNullPointerExceptionFromInterpreter();
856*795d594fSAndroid Build Coastguard Worker return false; // Pending exception.
857*795d594fSAndroid Build Coastguard Worker }
858*795d594fSAndroid Build Coastguard Worker SetVReg(A(), array->AsArray()->GetLength());
859*795d594fSAndroid Build Coastguard Worker return true;
860*795d594fSAndroid Build Coastguard Worker }
861*795d594fSAndroid Build Coastguard Worker
NEW_INSTANCE()862*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool NEW_INSTANCE() {
863*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> obj = nullptr;
864*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Class> c =
865*795d594fSAndroid Build Coastguard Worker ResolveVerifyAndClinit(dex::TypeIndex(B()),
866*795d594fSAndroid Build Coastguard Worker shadow_frame_.GetMethod(),
867*795d594fSAndroid Build Coastguard Worker Self(),
868*795d594fSAndroid Build Coastguard Worker false,
869*795d594fSAndroid Build Coastguard Worker !shadow_frame_.GetMethod()->SkipAccessChecks());
870*795d594fSAndroid Build Coastguard Worker if (LIKELY(c != nullptr)) {
871*795d594fSAndroid Build Coastguard Worker // Don't allow finalizable objects to be allocated during a transaction since these can't
872*795d594fSAndroid Build Coastguard Worker // be finalized without a started runtime.
873*795d594fSAndroid Build Coastguard Worker if (TransactionChecker::AllocationConstraint(Self(), c)) {
874*795d594fSAndroid Build Coastguard Worker return false; // Pending exception.
875*795d594fSAndroid Build Coastguard Worker }
876*795d594fSAndroid Build Coastguard Worker gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
877*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(c->IsStringClass())) {
878*795d594fSAndroid Build Coastguard Worker obj = mirror::String::AllocEmptyString(Self(), allocator_type);
879*795d594fSAndroid Build Coastguard Worker // Do not record the allocated string in the transaction.
880*795d594fSAndroid Build Coastguard Worker // There can be no transaction records for this immutable object.
881*795d594fSAndroid Build Coastguard Worker } else {
882*795d594fSAndroid Build Coastguard Worker obj = AllocObjectFromCode(c, Self(), allocator_type);
883*795d594fSAndroid Build Coastguard Worker if (obj != nullptr) {
884*795d594fSAndroid Build Coastguard Worker TransactionChecker::RecordNewObject(obj);
885*795d594fSAndroid Build Coastguard Worker }
886*795d594fSAndroid Build Coastguard Worker }
887*795d594fSAndroid Build Coastguard Worker }
888*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(obj == nullptr)) {
889*795d594fSAndroid Build Coastguard Worker return false; // Pending exception.
890*795d594fSAndroid Build Coastguard Worker }
891*795d594fSAndroid Build Coastguard Worker obj->GetClass()->AssertInitializedOrInitializingInThread(Self());
892*795d594fSAndroid Build Coastguard Worker SetVRegReference(A(), obj);
893*795d594fSAndroid Build Coastguard Worker return true;
894*795d594fSAndroid Build Coastguard Worker }
895*795d594fSAndroid Build Coastguard Worker
NEW_ARRAY()896*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool NEW_ARRAY() {
897*795d594fSAndroid Build Coastguard Worker int32_t length = GetVReg(B());
898*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Array> array = AllocArrayFromCode(
899*795d594fSAndroid Build Coastguard Worker dex::TypeIndex(C()),
900*795d594fSAndroid Build Coastguard Worker length,
901*795d594fSAndroid Build Coastguard Worker shadow_frame_.GetMethod(),
902*795d594fSAndroid Build Coastguard Worker Self(),
903*795d594fSAndroid Build Coastguard Worker Runtime::Current()->GetHeap()->GetCurrentAllocator());
904*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(array == nullptr)) {
905*795d594fSAndroid Build Coastguard Worker return false; // Pending exception.
906*795d594fSAndroid Build Coastguard Worker }
907*795d594fSAndroid Build Coastguard Worker TransactionChecker::RecordNewArray(array);
908*795d594fSAndroid Build Coastguard Worker SetVRegReference(A(), array);
909*795d594fSAndroid Build Coastguard Worker return true;
910*795d594fSAndroid Build Coastguard Worker }
911*795d594fSAndroid Build Coastguard Worker
FILLED_NEW_ARRAY()912*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool FILLED_NEW_ARRAY() {
913*795d594fSAndroid Build Coastguard Worker return DoFilledNewArray</*is_range=*/ false>(inst_, shadow_frame_, Self(), ResultRegister());
914*795d594fSAndroid Build Coastguard Worker }
915*795d594fSAndroid Build Coastguard Worker
FILLED_NEW_ARRAY_RANGE()916*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool FILLED_NEW_ARRAY_RANGE() {
917*795d594fSAndroid Build Coastguard Worker return DoFilledNewArray</*is_range=*/ true>(inst_, shadow_frame_, Self(), ResultRegister());
918*795d594fSAndroid Build Coastguard Worker }
919*795d594fSAndroid Build Coastguard Worker
FILL_ARRAY_DATA()920*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool FILL_ARRAY_DATA() {
921*795d594fSAndroid Build Coastguard Worker const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst_) + B();
922*795d594fSAndroid Build Coastguard Worker const Instruction::ArrayDataPayload* payload =
923*795d594fSAndroid Build Coastguard Worker reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr);
924*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> obj = GetVRegReference(A());
925*795d594fSAndroid Build Coastguard Worker // If we have an active transaction, record old values before we overwrite them.
926*795d594fSAndroid Build Coastguard Worker TransactionChecker::RecordArrayElementsInTransaction(obj, payload->element_count);
927*795d594fSAndroid Build Coastguard Worker if (!FillArrayData(obj, payload)) {
928*795d594fSAndroid Build Coastguard Worker return false; // Pending exception.
929*795d594fSAndroid Build Coastguard Worker }
930*795d594fSAndroid Build Coastguard Worker return true;
931*795d594fSAndroid Build Coastguard Worker }
932*795d594fSAndroid Build Coastguard Worker
THROW()933*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool THROW() {
934*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(Self()->ObserveAsyncException())) {
935*795d594fSAndroid Build Coastguard Worker return false; // Pending exception.
936*795d594fSAndroid Build Coastguard Worker }
937*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> exception = GetVRegReference(A());
938*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(exception == nullptr)) {
939*795d594fSAndroid Build Coastguard Worker ThrowNullPointerException();
940*795d594fSAndroid Build Coastguard Worker } else if (DoAssignabilityChecks() && !exception->GetClass()->IsThrowableClass()) {
941*795d594fSAndroid Build Coastguard Worker // This should never happen.
942*795d594fSAndroid Build Coastguard Worker std::string temp;
943*795d594fSAndroid Build Coastguard Worker Self()->ThrowNewExceptionF("Ljava/lang/InternalError;",
944*795d594fSAndroid Build Coastguard Worker "Throwing '%s' that is not instance of Throwable",
945*795d594fSAndroid Build Coastguard Worker exception->GetClass()->GetDescriptor(&temp));
946*795d594fSAndroid Build Coastguard Worker } else {
947*795d594fSAndroid Build Coastguard Worker Self()->SetException(exception->AsThrowable());
948*795d594fSAndroid Build Coastguard Worker }
949*795d594fSAndroid Build Coastguard Worker return false; // Pending exception.
950*795d594fSAndroid Build Coastguard Worker }
951*795d594fSAndroid Build Coastguard Worker
GOTO()952*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool GOTO() {
953*795d594fSAndroid Build Coastguard Worker return HandleBranch(A());
954*795d594fSAndroid Build Coastguard Worker }
955*795d594fSAndroid Build Coastguard Worker
GOTO_16()956*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool GOTO_16() {
957*795d594fSAndroid Build Coastguard Worker return HandleBranch(A());
958*795d594fSAndroid Build Coastguard Worker }
959*795d594fSAndroid Build Coastguard Worker
GOTO_32()960*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool GOTO_32() {
961*795d594fSAndroid Build Coastguard Worker return HandleBranch(A());
962*795d594fSAndroid Build Coastguard Worker }
963*795d594fSAndroid Build Coastguard Worker
PACKED_SWITCH()964*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool PACKED_SWITCH() {
965*795d594fSAndroid Build Coastguard Worker return HandleBranch(DoPackedSwitch(inst_, shadow_frame_, inst_data_));
966*795d594fSAndroid Build Coastguard Worker }
967*795d594fSAndroid Build Coastguard Worker
SPARSE_SWITCH()968*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool SPARSE_SWITCH() {
969*795d594fSAndroid Build Coastguard Worker return HandleBranch(DoSparseSwitch(inst_, shadow_frame_, inst_data_));
970*795d594fSAndroid Build Coastguard Worker }
971*795d594fSAndroid Build Coastguard Worker
CMPL_FLOAT()972*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool CMPL_FLOAT() {
973*795d594fSAndroid Build Coastguard Worker return HandleCmpl<float>(GetVRegFloat(B()), GetVRegFloat(C()));
974*795d594fSAndroid Build Coastguard Worker }
975*795d594fSAndroid Build Coastguard Worker
CMPG_FLOAT()976*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool CMPG_FLOAT() {
977*795d594fSAndroid Build Coastguard Worker return HandleCmpg<float>(GetVRegFloat(B()), GetVRegFloat(C()));
978*795d594fSAndroid Build Coastguard Worker }
979*795d594fSAndroid Build Coastguard Worker
CMPL_DOUBLE()980*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool CMPL_DOUBLE() {
981*795d594fSAndroid Build Coastguard Worker return HandleCmpl<double>(GetVRegDouble(B()), GetVRegDouble(C()));
982*795d594fSAndroid Build Coastguard Worker }
983*795d594fSAndroid Build Coastguard Worker
CMPG_DOUBLE()984*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool CMPG_DOUBLE() {
985*795d594fSAndroid Build Coastguard Worker return HandleCmpg<double>(GetVRegDouble(B()), GetVRegDouble(C()));
986*795d594fSAndroid Build Coastguard Worker }
987*795d594fSAndroid Build Coastguard Worker
CMP_LONG()988*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool CMP_LONG() {
989*795d594fSAndroid Build Coastguard Worker return HandleCmpl<int64_t>(GetVRegLong(B()), GetVRegLong(C()));
990*795d594fSAndroid Build Coastguard Worker }
991*795d594fSAndroid Build Coastguard Worker
IF_EQ()992*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool IF_EQ() {
993*795d594fSAndroid Build Coastguard Worker return HandleIf(GetVReg(A()) == GetVReg(B()), C());
994*795d594fSAndroid Build Coastguard Worker }
995*795d594fSAndroid Build Coastguard Worker
IF_NE()996*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool IF_NE() {
997*795d594fSAndroid Build Coastguard Worker return HandleIf(GetVReg(A()) != GetVReg(B()), C());
998*795d594fSAndroid Build Coastguard Worker }
999*795d594fSAndroid Build Coastguard Worker
IF_LT()1000*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool IF_LT() {
1001*795d594fSAndroid Build Coastguard Worker return HandleIf(GetVReg(A()) < GetVReg(B()), C());
1002*795d594fSAndroid Build Coastguard Worker }
1003*795d594fSAndroid Build Coastguard Worker
IF_GE()1004*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool IF_GE() {
1005*795d594fSAndroid Build Coastguard Worker return HandleIf(GetVReg(A()) >= GetVReg(B()), C());
1006*795d594fSAndroid Build Coastguard Worker }
1007*795d594fSAndroid Build Coastguard Worker
IF_GT()1008*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool IF_GT() {
1009*795d594fSAndroid Build Coastguard Worker return HandleIf(GetVReg(A()) > GetVReg(B()), C());
1010*795d594fSAndroid Build Coastguard Worker }
1011*795d594fSAndroid Build Coastguard Worker
IF_LE()1012*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool IF_LE() {
1013*795d594fSAndroid Build Coastguard Worker return HandleIf(GetVReg(A()) <= GetVReg(B()), C());
1014*795d594fSAndroid Build Coastguard Worker }
1015*795d594fSAndroid Build Coastguard Worker
IF_EQZ()1016*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool IF_EQZ() {
1017*795d594fSAndroid Build Coastguard Worker return HandleIf(GetVReg(A()) == 0, B());
1018*795d594fSAndroid Build Coastguard Worker }
1019*795d594fSAndroid Build Coastguard Worker
IF_NEZ()1020*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool IF_NEZ() {
1021*795d594fSAndroid Build Coastguard Worker return HandleIf(GetVReg(A()) != 0, B());
1022*795d594fSAndroid Build Coastguard Worker }
1023*795d594fSAndroid Build Coastguard Worker
IF_LTZ()1024*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool IF_LTZ() {
1025*795d594fSAndroid Build Coastguard Worker return HandleIf(GetVReg(A()) < 0, B());
1026*795d594fSAndroid Build Coastguard Worker }
1027*795d594fSAndroid Build Coastguard Worker
IF_GEZ()1028*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool IF_GEZ() {
1029*795d594fSAndroid Build Coastguard Worker return HandleIf(GetVReg(A()) >= 0, B());
1030*795d594fSAndroid Build Coastguard Worker }
1031*795d594fSAndroid Build Coastguard Worker
IF_GTZ()1032*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool IF_GTZ() {
1033*795d594fSAndroid Build Coastguard Worker return HandleIf(GetVReg(A()) > 0, B());
1034*795d594fSAndroid Build Coastguard Worker }
1035*795d594fSAndroid Build Coastguard Worker
IF_LEZ()1036*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool IF_LEZ() {
1037*795d594fSAndroid Build Coastguard Worker return HandleIf(GetVReg(A()) <= 0, B());
1038*795d594fSAndroid Build Coastguard Worker }
1039*795d594fSAndroid Build Coastguard Worker
AGET_BOOLEAN()1040*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool AGET_BOOLEAN() {
1041*795d594fSAndroid Build Coastguard Worker return HandleAGet<mirror::BooleanArray>(&InstructionHandler::SetVReg);
1042*795d594fSAndroid Build Coastguard Worker }
1043*795d594fSAndroid Build Coastguard Worker
AGET_BYTE()1044*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool AGET_BYTE() {
1045*795d594fSAndroid Build Coastguard Worker return HandleAGet<mirror::ByteArray>(&InstructionHandler::SetVReg);
1046*795d594fSAndroid Build Coastguard Worker }
1047*795d594fSAndroid Build Coastguard Worker
AGET_CHAR()1048*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool AGET_CHAR() {
1049*795d594fSAndroid Build Coastguard Worker return HandleAGet<mirror::CharArray>(&InstructionHandler::SetVReg);
1050*795d594fSAndroid Build Coastguard Worker }
1051*795d594fSAndroid Build Coastguard Worker
AGET_SHORT()1052*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool AGET_SHORT() {
1053*795d594fSAndroid Build Coastguard Worker return HandleAGet<mirror::ShortArray>(&InstructionHandler::SetVReg);
1054*795d594fSAndroid Build Coastguard Worker }
1055*795d594fSAndroid Build Coastguard Worker
AGET()1056*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool AGET() {
1057*795d594fSAndroid Build Coastguard Worker return HandleAGet<mirror::IntArray>(&InstructionHandler::SetVReg);
1058*795d594fSAndroid Build Coastguard Worker }
1059*795d594fSAndroid Build Coastguard Worker
AGET_WIDE()1060*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool AGET_WIDE() {
1061*795d594fSAndroid Build Coastguard Worker return HandleAGet<mirror::LongArray>(&InstructionHandler::SetVRegLong);
1062*795d594fSAndroid Build Coastguard Worker }
1063*795d594fSAndroid Build Coastguard Worker
AGET_OBJECT()1064*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool AGET_OBJECT() {
1065*795d594fSAndroid Build Coastguard Worker return HandleAGet<mirror::ObjectArray<mirror::Object>>(&InstructionHandler::SetVRegReference);
1066*795d594fSAndroid Build Coastguard Worker }
1067*795d594fSAndroid Build Coastguard Worker
APUT_BOOLEAN()1068*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool APUT_BOOLEAN() {
1069*795d594fSAndroid Build Coastguard Worker return HandleAPut<mirror::BooleanArray>(GetVReg(A()));
1070*795d594fSAndroid Build Coastguard Worker }
1071*795d594fSAndroid Build Coastguard Worker
APUT_BYTE()1072*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool APUT_BYTE() {
1073*795d594fSAndroid Build Coastguard Worker return HandleAPut<mirror::ByteArray>(GetVReg(A()));
1074*795d594fSAndroid Build Coastguard Worker }
1075*795d594fSAndroid Build Coastguard Worker
APUT_CHAR()1076*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool APUT_CHAR() {
1077*795d594fSAndroid Build Coastguard Worker return HandleAPut<mirror::CharArray>(GetVReg(A()));
1078*795d594fSAndroid Build Coastguard Worker }
1079*795d594fSAndroid Build Coastguard Worker
APUT_SHORT()1080*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool APUT_SHORT() {
1081*795d594fSAndroid Build Coastguard Worker return HandleAPut<mirror::ShortArray>(GetVReg(A()));
1082*795d594fSAndroid Build Coastguard Worker }
1083*795d594fSAndroid Build Coastguard Worker
APUT()1084*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool APUT() {
1085*795d594fSAndroid Build Coastguard Worker return HandleAPut<mirror::IntArray>(GetVReg(A()));
1086*795d594fSAndroid Build Coastguard Worker }
1087*795d594fSAndroid Build Coastguard Worker
APUT_WIDE()1088*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool APUT_WIDE() {
1089*795d594fSAndroid Build Coastguard Worker return HandleAPut<mirror::LongArray>(GetVRegLong(A()));
1090*795d594fSAndroid Build Coastguard Worker }
1091*795d594fSAndroid Build Coastguard Worker
APUT_OBJECT()1092*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool APUT_OBJECT() {
1093*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> a = GetVRegReference(B());
1094*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(a == nullptr)) {
1095*795d594fSAndroid Build Coastguard Worker ThrowNullPointerExceptionFromInterpreter();
1096*795d594fSAndroid Build Coastguard Worker return false; // Pending exception.
1097*795d594fSAndroid Build Coastguard Worker }
1098*795d594fSAndroid Build Coastguard Worker int32_t index = GetVReg(C());
1099*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> val = GetVRegReference(A());
1100*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::ObjectArray<mirror::Object>> array = a->AsObjectArray<mirror::Object>();
1101*795d594fSAndroid Build Coastguard Worker if (array->CheckIsValidIndex(index) && array->CheckAssignable(val)) {
1102*795d594fSAndroid Build Coastguard Worker if (TransactionChecker::WriteConstraint(Self(), array) ||
1103*795d594fSAndroid Build Coastguard Worker TransactionChecker::WriteValueConstraint(Self(), val)) {
1104*795d594fSAndroid Build Coastguard Worker return false;
1105*795d594fSAndroid Build Coastguard Worker }
1106*795d594fSAndroid Build Coastguard Worker array->SetWithoutChecks<transaction_active>(index, val);
1107*795d594fSAndroid Build Coastguard Worker } else {
1108*795d594fSAndroid Build Coastguard Worker return false; // Pending exception.
1109*795d594fSAndroid Build Coastguard Worker }
1110*795d594fSAndroid Build Coastguard Worker return true;
1111*795d594fSAndroid Build Coastguard Worker }
1112*795d594fSAndroid Build Coastguard Worker
IGET_BOOLEAN()1113*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool IGET_BOOLEAN() {
1114*795d594fSAndroid Build Coastguard Worker return HandleGet<InstancePrimitiveRead, Primitive::kPrimBoolean>();
1115*795d594fSAndroid Build Coastguard Worker }
1116*795d594fSAndroid Build Coastguard Worker
IGET_BYTE()1117*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool IGET_BYTE() {
1118*795d594fSAndroid Build Coastguard Worker return HandleGet<InstancePrimitiveRead, Primitive::kPrimByte>();
1119*795d594fSAndroid Build Coastguard Worker }
1120*795d594fSAndroid Build Coastguard Worker
IGET_CHAR()1121*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool IGET_CHAR() {
1122*795d594fSAndroid Build Coastguard Worker return HandleGet<InstancePrimitiveRead, Primitive::kPrimChar>();
1123*795d594fSAndroid Build Coastguard Worker }
1124*795d594fSAndroid Build Coastguard Worker
IGET_SHORT()1125*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool IGET_SHORT() {
1126*795d594fSAndroid Build Coastguard Worker return HandleGet<InstancePrimitiveRead, Primitive::kPrimShort>();
1127*795d594fSAndroid Build Coastguard Worker }
1128*795d594fSAndroid Build Coastguard Worker
IGET()1129*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool IGET() {
1130*795d594fSAndroid Build Coastguard Worker return HandleGet<InstancePrimitiveRead, Primitive::kPrimInt>();
1131*795d594fSAndroid Build Coastguard Worker }
1132*795d594fSAndroid Build Coastguard Worker
IGET_WIDE()1133*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool IGET_WIDE() {
1134*795d594fSAndroid Build Coastguard Worker return HandleGet<InstancePrimitiveRead, Primitive::kPrimLong>();
1135*795d594fSAndroid Build Coastguard Worker }
1136*795d594fSAndroid Build Coastguard Worker
IGET_OBJECT()1137*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool IGET_OBJECT() {
1138*795d594fSAndroid Build Coastguard Worker return HandleGet<InstanceObjectRead, Primitive::kPrimNot>();
1139*795d594fSAndroid Build Coastguard Worker }
1140*795d594fSAndroid Build Coastguard Worker
SGET_BOOLEAN()1141*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool SGET_BOOLEAN() {
1142*795d594fSAndroid Build Coastguard Worker return HandleGet<StaticPrimitiveRead, Primitive::kPrimBoolean>();
1143*795d594fSAndroid Build Coastguard Worker }
1144*795d594fSAndroid Build Coastguard Worker
SGET_BYTE()1145*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool SGET_BYTE() {
1146*795d594fSAndroid Build Coastguard Worker return HandleGet<StaticPrimitiveRead, Primitive::kPrimByte>();
1147*795d594fSAndroid Build Coastguard Worker }
1148*795d594fSAndroid Build Coastguard Worker
SGET_CHAR()1149*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool SGET_CHAR() {
1150*795d594fSAndroid Build Coastguard Worker return HandleGet<StaticPrimitiveRead, Primitive::kPrimChar>();
1151*795d594fSAndroid Build Coastguard Worker }
1152*795d594fSAndroid Build Coastguard Worker
SGET_SHORT()1153*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool SGET_SHORT() {
1154*795d594fSAndroid Build Coastguard Worker return HandleGet<StaticPrimitiveRead, Primitive::kPrimShort>();
1155*795d594fSAndroid Build Coastguard Worker }
1156*795d594fSAndroid Build Coastguard Worker
SGET()1157*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool SGET() {
1158*795d594fSAndroid Build Coastguard Worker return HandleGet<StaticPrimitiveRead, Primitive::kPrimInt>();
1159*795d594fSAndroid Build Coastguard Worker }
1160*795d594fSAndroid Build Coastguard Worker
SGET_WIDE()1161*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool SGET_WIDE() {
1162*795d594fSAndroid Build Coastguard Worker return HandleGet<StaticPrimitiveRead, Primitive::kPrimLong>();
1163*795d594fSAndroid Build Coastguard Worker }
1164*795d594fSAndroid Build Coastguard Worker
SGET_OBJECT()1165*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool SGET_OBJECT() {
1166*795d594fSAndroid Build Coastguard Worker return HandleGet<StaticObjectRead, Primitive::kPrimNot>();
1167*795d594fSAndroid Build Coastguard Worker }
1168*795d594fSAndroid Build Coastguard Worker
IPUT_BOOLEAN()1169*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool IPUT_BOOLEAN() {
1170*795d594fSAndroid Build Coastguard Worker return HandlePut<InstancePrimitiveWrite, Primitive::kPrimBoolean>();
1171*795d594fSAndroid Build Coastguard Worker }
1172*795d594fSAndroid Build Coastguard Worker
IPUT_BYTE()1173*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool IPUT_BYTE() {
1174*795d594fSAndroid Build Coastguard Worker return HandlePut<InstancePrimitiveWrite, Primitive::kPrimByte>();
1175*795d594fSAndroid Build Coastguard Worker }
1176*795d594fSAndroid Build Coastguard Worker
IPUT_CHAR()1177*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool IPUT_CHAR() {
1178*795d594fSAndroid Build Coastguard Worker return HandlePut<InstancePrimitiveWrite, Primitive::kPrimChar>();
1179*795d594fSAndroid Build Coastguard Worker }
1180*795d594fSAndroid Build Coastguard Worker
IPUT_SHORT()1181*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool IPUT_SHORT() {
1182*795d594fSAndroid Build Coastguard Worker return HandlePut<InstancePrimitiveWrite, Primitive::kPrimShort>();
1183*795d594fSAndroid Build Coastguard Worker }
1184*795d594fSAndroid Build Coastguard Worker
IPUT()1185*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool IPUT() {
1186*795d594fSAndroid Build Coastguard Worker return HandlePut<InstancePrimitiveWrite, Primitive::kPrimInt>();
1187*795d594fSAndroid Build Coastguard Worker }
1188*795d594fSAndroid Build Coastguard Worker
IPUT_WIDE()1189*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool IPUT_WIDE() {
1190*795d594fSAndroid Build Coastguard Worker return HandlePut<InstancePrimitiveWrite, Primitive::kPrimLong>();
1191*795d594fSAndroid Build Coastguard Worker }
1192*795d594fSAndroid Build Coastguard Worker
IPUT_OBJECT()1193*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool IPUT_OBJECT() {
1194*795d594fSAndroid Build Coastguard Worker return HandlePut<InstanceObjectWrite, Primitive::kPrimNot>();
1195*795d594fSAndroid Build Coastguard Worker }
1196*795d594fSAndroid Build Coastguard Worker
SPUT_BOOLEAN()1197*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool SPUT_BOOLEAN() {
1198*795d594fSAndroid Build Coastguard Worker return HandlePut<StaticPrimitiveWrite, Primitive::kPrimBoolean>();
1199*795d594fSAndroid Build Coastguard Worker }
1200*795d594fSAndroid Build Coastguard Worker
SPUT_BYTE()1201*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool SPUT_BYTE() {
1202*795d594fSAndroid Build Coastguard Worker return HandlePut<StaticPrimitiveWrite, Primitive::kPrimByte>();
1203*795d594fSAndroid Build Coastguard Worker }
1204*795d594fSAndroid Build Coastguard Worker
SPUT_CHAR()1205*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool SPUT_CHAR() {
1206*795d594fSAndroid Build Coastguard Worker return HandlePut<StaticPrimitiveWrite, Primitive::kPrimChar>();
1207*795d594fSAndroid Build Coastguard Worker }
1208*795d594fSAndroid Build Coastguard Worker
SPUT_SHORT()1209*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool SPUT_SHORT() {
1210*795d594fSAndroid Build Coastguard Worker return HandlePut<StaticPrimitiveWrite, Primitive::kPrimShort>();
1211*795d594fSAndroid Build Coastguard Worker }
1212*795d594fSAndroid Build Coastguard Worker
SPUT()1213*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool SPUT() {
1214*795d594fSAndroid Build Coastguard Worker return HandlePut<StaticPrimitiveWrite, Primitive::kPrimInt>();
1215*795d594fSAndroid Build Coastguard Worker }
1216*795d594fSAndroid Build Coastguard Worker
SPUT_WIDE()1217*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool SPUT_WIDE() {
1218*795d594fSAndroid Build Coastguard Worker return HandlePut<StaticPrimitiveWrite, Primitive::kPrimLong>();
1219*795d594fSAndroid Build Coastguard Worker }
1220*795d594fSAndroid Build Coastguard Worker
SPUT_OBJECT()1221*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool SPUT_OBJECT() {
1222*795d594fSAndroid Build Coastguard Worker return HandlePut<StaticObjectWrite, Primitive::kPrimNot>();
1223*795d594fSAndroid Build Coastguard Worker }
1224*795d594fSAndroid Build Coastguard Worker
INVOKE_VIRTUAL()1225*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool INVOKE_VIRTUAL() {
1226*795d594fSAndroid Build Coastguard Worker return HandleInvoke<kVirtual, /*is_range=*/ false>();
1227*795d594fSAndroid Build Coastguard Worker }
1228*795d594fSAndroid Build Coastguard Worker
INVOKE_VIRTUAL_RANGE()1229*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool INVOKE_VIRTUAL_RANGE() {
1230*795d594fSAndroid Build Coastguard Worker return HandleInvoke<kVirtual, /*is_range=*/ true>();
1231*795d594fSAndroid Build Coastguard Worker }
1232*795d594fSAndroid Build Coastguard Worker
INVOKE_SUPER()1233*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool INVOKE_SUPER() {
1234*795d594fSAndroid Build Coastguard Worker return HandleInvoke<kSuper, /*is_range=*/ false>();
1235*795d594fSAndroid Build Coastguard Worker }
1236*795d594fSAndroid Build Coastguard Worker
INVOKE_SUPER_RANGE()1237*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool INVOKE_SUPER_RANGE() {
1238*795d594fSAndroid Build Coastguard Worker return HandleInvoke<kSuper, /*is_range=*/ true>();
1239*795d594fSAndroid Build Coastguard Worker }
1240*795d594fSAndroid Build Coastguard Worker
INVOKE_DIRECT()1241*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool INVOKE_DIRECT() {
1242*795d594fSAndroid Build Coastguard Worker return HandleInvoke<kDirect, /*is_range=*/ false>();
1243*795d594fSAndroid Build Coastguard Worker }
1244*795d594fSAndroid Build Coastguard Worker
INVOKE_DIRECT_RANGE()1245*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool INVOKE_DIRECT_RANGE() {
1246*795d594fSAndroid Build Coastguard Worker return HandleInvoke<kDirect, /*is_range=*/ true>();
1247*795d594fSAndroid Build Coastguard Worker }
1248*795d594fSAndroid Build Coastguard Worker
INVOKE_INTERFACE()1249*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool INVOKE_INTERFACE() {
1250*795d594fSAndroid Build Coastguard Worker return HandleInvoke<kInterface, /*is_range=*/ false>();
1251*795d594fSAndroid Build Coastguard Worker }
1252*795d594fSAndroid Build Coastguard Worker
INVOKE_INTERFACE_RANGE()1253*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool INVOKE_INTERFACE_RANGE() {
1254*795d594fSAndroid Build Coastguard Worker return HandleInvoke<kInterface, /*is_range=*/ true>();
1255*795d594fSAndroid Build Coastguard Worker }
1256*795d594fSAndroid Build Coastguard Worker
INVOKE_STATIC()1257*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool INVOKE_STATIC() {
1258*795d594fSAndroid Build Coastguard Worker return HandleInvoke<kStatic, /*is_range=*/ false>();
1259*795d594fSAndroid Build Coastguard Worker }
1260*795d594fSAndroid Build Coastguard Worker
INVOKE_STATIC_RANGE()1261*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool INVOKE_STATIC_RANGE() {
1262*795d594fSAndroid Build Coastguard Worker return HandleInvoke<kStatic, /*is_range=*/ true>();
1263*795d594fSAndroid Build Coastguard Worker }
1264*795d594fSAndroid Build Coastguard Worker
INVOKE_POLYMORPHIC()1265*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool INVOKE_POLYMORPHIC() {
1266*795d594fSAndroid Build Coastguard Worker DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
1267*795d594fSAndroid Build Coastguard Worker bool success = DoInvokePolymorphic</* is_range= */ false>(
1268*795d594fSAndroid Build Coastguard Worker Self(), shadow_frame_, inst_, inst_data_, ResultRegister());
1269*795d594fSAndroid Build Coastguard Worker return PossiblyHandlePendingExceptionOnInvoke(!success);
1270*795d594fSAndroid Build Coastguard Worker }
1271*795d594fSAndroid Build Coastguard Worker
INVOKE_POLYMORPHIC_RANGE()1272*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool INVOKE_POLYMORPHIC_RANGE() {
1273*795d594fSAndroid Build Coastguard Worker DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
1274*795d594fSAndroid Build Coastguard Worker bool success = DoInvokePolymorphic</* is_range= */ true>(
1275*795d594fSAndroid Build Coastguard Worker Self(), shadow_frame_, inst_, inst_data_, ResultRegister());
1276*795d594fSAndroid Build Coastguard Worker return PossiblyHandlePendingExceptionOnInvoke(!success);
1277*795d594fSAndroid Build Coastguard Worker }
1278*795d594fSAndroid Build Coastguard Worker
INVOKE_CUSTOM()1279*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool INVOKE_CUSTOM() {
1280*795d594fSAndroid Build Coastguard Worker DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
1281*795d594fSAndroid Build Coastguard Worker bool success = DoInvokeCustom</* is_range= */ false>(
1282*795d594fSAndroid Build Coastguard Worker Self(), shadow_frame_, inst_, inst_data_, ResultRegister());
1283*795d594fSAndroid Build Coastguard Worker return PossiblyHandlePendingExceptionOnInvoke(!success);
1284*795d594fSAndroid Build Coastguard Worker }
1285*795d594fSAndroid Build Coastguard Worker
INVOKE_CUSTOM_RANGE()1286*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool INVOKE_CUSTOM_RANGE() {
1287*795d594fSAndroid Build Coastguard Worker DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
1288*795d594fSAndroid Build Coastguard Worker bool success = DoInvokeCustom</* is_range= */ true>(
1289*795d594fSAndroid Build Coastguard Worker Self(), shadow_frame_, inst_, inst_data_, ResultRegister());
1290*795d594fSAndroid Build Coastguard Worker return PossiblyHandlePendingExceptionOnInvoke(!success);
1291*795d594fSAndroid Build Coastguard Worker }
1292*795d594fSAndroid Build Coastguard Worker
NEG_INT()1293*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool NEG_INT() {
1294*795d594fSAndroid Build Coastguard Worker SetVReg(A(), -GetVReg(B()));
1295*795d594fSAndroid Build Coastguard Worker return true;
1296*795d594fSAndroid Build Coastguard Worker }
1297*795d594fSAndroid Build Coastguard Worker
NOT_INT()1298*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool NOT_INT() {
1299*795d594fSAndroid Build Coastguard Worker SetVReg(A(), ~GetVReg(B()));
1300*795d594fSAndroid Build Coastguard Worker return true;
1301*795d594fSAndroid Build Coastguard Worker }
1302*795d594fSAndroid Build Coastguard Worker
NEG_LONG()1303*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool NEG_LONG() {
1304*795d594fSAndroid Build Coastguard Worker SetVRegLong(A(), -GetVRegLong(B()));
1305*795d594fSAndroid Build Coastguard Worker return true;
1306*795d594fSAndroid Build Coastguard Worker }
1307*795d594fSAndroid Build Coastguard Worker
NOT_LONG()1308*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool NOT_LONG() {
1309*795d594fSAndroid Build Coastguard Worker SetVRegLong(A(), ~GetVRegLong(B()));
1310*795d594fSAndroid Build Coastguard Worker return true;
1311*795d594fSAndroid Build Coastguard Worker }
1312*795d594fSAndroid Build Coastguard Worker
NEG_FLOAT()1313*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool NEG_FLOAT() {
1314*795d594fSAndroid Build Coastguard Worker SetVRegFloat(A(), -GetVRegFloat(B()));
1315*795d594fSAndroid Build Coastguard Worker return true;
1316*795d594fSAndroid Build Coastguard Worker }
1317*795d594fSAndroid Build Coastguard Worker
NEG_DOUBLE()1318*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool NEG_DOUBLE() {
1319*795d594fSAndroid Build Coastguard Worker SetVRegDouble(A(), -GetVRegDouble(B()));
1320*795d594fSAndroid Build Coastguard Worker return true;
1321*795d594fSAndroid Build Coastguard Worker }
1322*795d594fSAndroid Build Coastguard Worker
INT_TO_LONG()1323*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool INT_TO_LONG() {
1324*795d594fSAndroid Build Coastguard Worker SetVRegLong(A(), GetVReg(B()));
1325*795d594fSAndroid Build Coastguard Worker return true;
1326*795d594fSAndroid Build Coastguard Worker }
1327*795d594fSAndroid Build Coastguard Worker
INT_TO_FLOAT()1328*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool INT_TO_FLOAT() {
1329*795d594fSAndroid Build Coastguard Worker SetVRegFloat(A(), GetVReg(B()));
1330*795d594fSAndroid Build Coastguard Worker return true;
1331*795d594fSAndroid Build Coastguard Worker }
1332*795d594fSAndroid Build Coastguard Worker
INT_TO_DOUBLE()1333*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool INT_TO_DOUBLE() {
1334*795d594fSAndroid Build Coastguard Worker SetVRegDouble(A(), GetVReg(B()));
1335*795d594fSAndroid Build Coastguard Worker return true;
1336*795d594fSAndroid Build Coastguard Worker }
1337*795d594fSAndroid Build Coastguard Worker
LONG_TO_INT()1338*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool LONG_TO_INT() {
1339*795d594fSAndroid Build Coastguard Worker SetVReg(A(), GetVRegLong(B()));
1340*795d594fSAndroid Build Coastguard Worker return true;
1341*795d594fSAndroid Build Coastguard Worker }
1342*795d594fSAndroid Build Coastguard Worker
LONG_TO_FLOAT()1343*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool LONG_TO_FLOAT() {
1344*795d594fSAndroid Build Coastguard Worker SetVRegFloat(A(), GetVRegLong(B()));
1345*795d594fSAndroid Build Coastguard Worker return true;
1346*795d594fSAndroid Build Coastguard Worker }
1347*795d594fSAndroid Build Coastguard Worker
LONG_TO_DOUBLE()1348*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool LONG_TO_DOUBLE() {
1349*795d594fSAndroid Build Coastguard Worker SetVRegDouble(A(), GetVRegLong(B()));
1350*795d594fSAndroid Build Coastguard Worker return true;
1351*795d594fSAndroid Build Coastguard Worker }
1352*795d594fSAndroid Build Coastguard Worker
FLOAT_TO_INT()1353*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool FLOAT_TO_INT() {
1354*795d594fSAndroid Build Coastguard Worker SetVReg(A(), art_float_to_integral<int32_t, float>(GetVRegFloat(B())));
1355*795d594fSAndroid Build Coastguard Worker return true;
1356*795d594fSAndroid Build Coastguard Worker }
1357*795d594fSAndroid Build Coastguard Worker
FLOAT_TO_LONG()1358*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool FLOAT_TO_LONG() {
1359*795d594fSAndroid Build Coastguard Worker SetVRegLong(A(), art_float_to_integral<int64_t, float>(GetVRegFloat(B())));
1360*795d594fSAndroid Build Coastguard Worker return true;
1361*795d594fSAndroid Build Coastguard Worker }
1362*795d594fSAndroid Build Coastguard Worker
FLOAT_TO_DOUBLE()1363*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool FLOAT_TO_DOUBLE() {
1364*795d594fSAndroid Build Coastguard Worker SetVRegDouble(A(), GetVRegFloat(B()));
1365*795d594fSAndroid Build Coastguard Worker return true;
1366*795d594fSAndroid Build Coastguard Worker }
1367*795d594fSAndroid Build Coastguard Worker
DOUBLE_TO_INT()1368*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool DOUBLE_TO_INT() {
1369*795d594fSAndroid Build Coastguard Worker SetVReg(A(), art_float_to_integral<int32_t, double>(GetVRegDouble(B())));
1370*795d594fSAndroid Build Coastguard Worker return true;
1371*795d594fSAndroid Build Coastguard Worker }
1372*795d594fSAndroid Build Coastguard Worker
DOUBLE_TO_LONG()1373*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool DOUBLE_TO_LONG() {
1374*795d594fSAndroid Build Coastguard Worker SetVRegLong(A(), art_float_to_integral<int64_t, double>(GetVRegDouble(B())));
1375*795d594fSAndroid Build Coastguard Worker return true;
1376*795d594fSAndroid Build Coastguard Worker }
1377*795d594fSAndroid Build Coastguard Worker
DOUBLE_TO_FLOAT()1378*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool DOUBLE_TO_FLOAT() {
1379*795d594fSAndroid Build Coastguard Worker SetVRegFloat(A(), GetVRegDouble(B()));
1380*795d594fSAndroid Build Coastguard Worker return true;
1381*795d594fSAndroid Build Coastguard Worker }
1382*795d594fSAndroid Build Coastguard Worker
INT_TO_BYTE()1383*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool INT_TO_BYTE() {
1384*795d594fSAndroid Build Coastguard Worker SetVReg(A(), static_cast<int8_t>(GetVReg(B())));
1385*795d594fSAndroid Build Coastguard Worker return true;
1386*795d594fSAndroid Build Coastguard Worker }
1387*795d594fSAndroid Build Coastguard Worker
INT_TO_CHAR()1388*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool INT_TO_CHAR() {
1389*795d594fSAndroid Build Coastguard Worker SetVReg(A(), static_cast<uint16_t>(GetVReg(B())));
1390*795d594fSAndroid Build Coastguard Worker return true;
1391*795d594fSAndroid Build Coastguard Worker }
1392*795d594fSAndroid Build Coastguard Worker
INT_TO_SHORT()1393*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool INT_TO_SHORT() {
1394*795d594fSAndroid Build Coastguard Worker SetVReg(A(), static_cast<int16_t>(GetVReg(B())));
1395*795d594fSAndroid Build Coastguard Worker return true;
1396*795d594fSAndroid Build Coastguard Worker }
1397*795d594fSAndroid Build Coastguard Worker
ADD_INT()1398*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool ADD_INT() {
1399*795d594fSAndroid Build Coastguard Worker SetVReg(A(), SafeAdd(GetVReg(B()), GetVReg(C())));
1400*795d594fSAndroid Build Coastguard Worker return true;
1401*795d594fSAndroid Build Coastguard Worker }
1402*795d594fSAndroid Build Coastguard Worker
SUB_INT()1403*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool SUB_INT() {
1404*795d594fSAndroid Build Coastguard Worker SetVReg(A(), SafeSub(GetVReg(B()), GetVReg(C())));
1405*795d594fSAndroid Build Coastguard Worker return true;
1406*795d594fSAndroid Build Coastguard Worker }
1407*795d594fSAndroid Build Coastguard Worker
MUL_INT()1408*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool MUL_INT() {
1409*795d594fSAndroid Build Coastguard Worker SetVReg(A(), SafeMul(GetVReg(B()), GetVReg(C())));
1410*795d594fSAndroid Build Coastguard Worker return true;
1411*795d594fSAndroid Build Coastguard Worker }
1412*795d594fSAndroid Build Coastguard Worker
DIV_INT()1413*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool DIV_INT() {
1414*795d594fSAndroid Build Coastguard Worker return DoIntDivide(shadow_frame_, A(), GetVReg(B()), GetVReg(C()));
1415*795d594fSAndroid Build Coastguard Worker }
1416*795d594fSAndroid Build Coastguard Worker
REM_INT()1417*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool REM_INT() {
1418*795d594fSAndroid Build Coastguard Worker return DoIntRemainder(shadow_frame_, A(), GetVReg(B()), GetVReg(C()));
1419*795d594fSAndroid Build Coastguard Worker }
1420*795d594fSAndroid Build Coastguard Worker
SHL_INT()1421*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool SHL_INT() {
1422*795d594fSAndroid Build Coastguard Worker SetVReg(A(), GetVReg(B()) << (GetVReg(C()) & 0x1f));
1423*795d594fSAndroid Build Coastguard Worker return true;
1424*795d594fSAndroid Build Coastguard Worker }
1425*795d594fSAndroid Build Coastguard Worker
SHR_INT()1426*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool SHR_INT() {
1427*795d594fSAndroid Build Coastguard Worker SetVReg(A(), GetVReg(B()) >> (GetVReg(C()) & 0x1f));
1428*795d594fSAndroid Build Coastguard Worker return true;
1429*795d594fSAndroid Build Coastguard Worker }
1430*795d594fSAndroid Build Coastguard Worker
USHR_INT()1431*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool USHR_INT() {
1432*795d594fSAndroid Build Coastguard Worker SetVReg(A(), static_cast<uint32_t>(GetVReg(B())) >> (GetVReg(C()) & 0x1f));
1433*795d594fSAndroid Build Coastguard Worker return true;
1434*795d594fSAndroid Build Coastguard Worker }
1435*795d594fSAndroid Build Coastguard Worker
AND_INT()1436*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool AND_INT() {
1437*795d594fSAndroid Build Coastguard Worker SetVReg(A(), GetVReg(B()) & GetVReg(C()));
1438*795d594fSAndroid Build Coastguard Worker return true;
1439*795d594fSAndroid Build Coastguard Worker }
1440*795d594fSAndroid Build Coastguard Worker
OR_INT()1441*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool OR_INT() {
1442*795d594fSAndroid Build Coastguard Worker SetVReg(A(), GetVReg(B()) | GetVReg(C()));
1443*795d594fSAndroid Build Coastguard Worker return true;
1444*795d594fSAndroid Build Coastguard Worker }
1445*795d594fSAndroid Build Coastguard Worker
XOR_INT()1446*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool XOR_INT() {
1447*795d594fSAndroid Build Coastguard Worker SetVReg(A(), GetVReg(B()) ^ GetVReg(C()));
1448*795d594fSAndroid Build Coastguard Worker return true;
1449*795d594fSAndroid Build Coastguard Worker }
1450*795d594fSAndroid Build Coastguard Worker
ADD_LONG()1451*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool ADD_LONG() {
1452*795d594fSAndroid Build Coastguard Worker SetVRegLong(A(), SafeAdd(GetVRegLong(B()), GetVRegLong(C())));
1453*795d594fSAndroid Build Coastguard Worker return true;
1454*795d594fSAndroid Build Coastguard Worker }
1455*795d594fSAndroid Build Coastguard Worker
SUB_LONG()1456*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool SUB_LONG() {
1457*795d594fSAndroid Build Coastguard Worker SetVRegLong(A(), SafeSub(GetVRegLong(B()), GetVRegLong(C())));
1458*795d594fSAndroid Build Coastguard Worker return true;
1459*795d594fSAndroid Build Coastguard Worker }
1460*795d594fSAndroid Build Coastguard Worker
MUL_LONG()1461*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool MUL_LONG() {
1462*795d594fSAndroid Build Coastguard Worker SetVRegLong(A(), SafeMul(GetVRegLong(B()), GetVRegLong(C())));
1463*795d594fSAndroid Build Coastguard Worker return true;
1464*795d594fSAndroid Build Coastguard Worker }
1465*795d594fSAndroid Build Coastguard Worker
DIV_LONG()1466*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool DIV_LONG() {
1467*795d594fSAndroid Build Coastguard Worker return DoLongDivide(shadow_frame_, A(), GetVRegLong(B()), GetVRegLong(C()));
1468*795d594fSAndroid Build Coastguard Worker }
1469*795d594fSAndroid Build Coastguard Worker
REM_LONG()1470*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool REM_LONG() {
1471*795d594fSAndroid Build Coastguard Worker return DoLongRemainder(shadow_frame_, A(), GetVRegLong(B()), GetVRegLong(C()));
1472*795d594fSAndroid Build Coastguard Worker }
1473*795d594fSAndroid Build Coastguard Worker
AND_LONG()1474*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool AND_LONG() {
1475*795d594fSAndroid Build Coastguard Worker SetVRegLong(A(), GetVRegLong(B()) & GetVRegLong(C()));
1476*795d594fSAndroid Build Coastguard Worker return true;
1477*795d594fSAndroid Build Coastguard Worker }
1478*795d594fSAndroid Build Coastguard Worker
OR_LONG()1479*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool OR_LONG() {
1480*795d594fSAndroid Build Coastguard Worker SetVRegLong(A(), GetVRegLong(B()) | GetVRegLong(C()));
1481*795d594fSAndroid Build Coastguard Worker return true;
1482*795d594fSAndroid Build Coastguard Worker }
1483*795d594fSAndroid Build Coastguard Worker
XOR_LONG()1484*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool XOR_LONG() {
1485*795d594fSAndroid Build Coastguard Worker SetVRegLong(A(), GetVRegLong(B()) ^ GetVRegLong(C()));
1486*795d594fSAndroid Build Coastguard Worker return true;
1487*795d594fSAndroid Build Coastguard Worker }
1488*795d594fSAndroid Build Coastguard Worker
SHL_LONG()1489*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool SHL_LONG() {
1490*795d594fSAndroid Build Coastguard Worker SetVRegLong(A(), GetVRegLong(B()) << (GetVReg(C()) & 0x3f));
1491*795d594fSAndroid Build Coastguard Worker return true;
1492*795d594fSAndroid Build Coastguard Worker }
1493*795d594fSAndroid Build Coastguard Worker
SHR_LONG()1494*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool SHR_LONG() {
1495*795d594fSAndroid Build Coastguard Worker SetVRegLong(A(), GetVRegLong(B()) >> (GetVReg(C()) & 0x3f));
1496*795d594fSAndroid Build Coastguard Worker return true;
1497*795d594fSAndroid Build Coastguard Worker }
1498*795d594fSAndroid Build Coastguard Worker
USHR_LONG()1499*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool USHR_LONG() {
1500*795d594fSAndroid Build Coastguard Worker SetVRegLong(A(), static_cast<uint64_t>(GetVRegLong(B())) >> (GetVReg(C()) & 0x3f));
1501*795d594fSAndroid Build Coastguard Worker return true;
1502*795d594fSAndroid Build Coastguard Worker }
1503*795d594fSAndroid Build Coastguard Worker
ADD_FLOAT()1504*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool ADD_FLOAT() {
1505*795d594fSAndroid Build Coastguard Worker SetVRegFloat(A(), GetVRegFloat(B()) + GetVRegFloat(C()));
1506*795d594fSAndroid Build Coastguard Worker return true;
1507*795d594fSAndroid Build Coastguard Worker }
1508*795d594fSAndroid Build Coastguard Worker
SUB_FLOAT()1509*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool SUB_FLOAT() {
1510*795d594fSAndroid Build Coastguard Worker SetVRegFloat(A(), GetVRegFloat(B()) - GetVRegFloat(C()));
1511*795d594fSAndroid Build Coastguard Worker return true;
1512*795d594fSAndroid Build Coastguard Worker }
1513*795d594fSAndroid Build Coastguard Worker
MUL_FLOAT()1514*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool MUL_FLOAT() {
1515*795d594fSAndroid Build Coastguard Worker SetVRegFloat(A(), GetVRegFloat(B()) * GetVRegFloat(C()));
1516*795d594fSAndroid Build Coastguard Worker return true;
1517*795d594fSAndroid Build Coastguard Worker }
1518*795d594fSAndroid Build Coastguard Worker
DIV_FLOAT()1519*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool DIV_FLOAT() {
1520*795d594fSAndroid Build Coastguard Worker SetVRegFloat(A(), GetVRegFloat(B()) / GetVRegFloat(C()));
1521*795d594fSAndroid Build Coastguard Worker return true;
1522*795d594fSAndroid Build Coastguard Worker }
1523*795d594fSAndroid Build Coastguard Worker
REM_FLOAT()1524*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool REM_FLOAT() {
1525*795d594fSAndroid Build Coastguard Worker SetVRegFloat(A(), fmodf(GetVRegFloat(B()), GetVRegFloat(C())));
1526*795d594fSAndroid Build Coastguard Worker return true;
1527*795d594fSAndroid Build Coastguard Worker }
1528*795d594fSAndroid Build Coastguard Worker
ADD_DOUBLE()1529*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool ADD_DOUBLE() {
1530*795d594fSAndroid Build Coastguard Worker SetVRegDouble(A(), GetVRegDouble(B()) + GetVRegDouble(C()));
1531*795d594fSAndroid Build Coastguard Worker return true;
1532*795d594fSAndroid Build Coastguard Worker }
1533*795d594fSAndroid Build Coastguard Worker
SUB_DOUBLE()1534*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool SUB_DOUBLE() {
1535*795d594fSAndroid Build Coastguard Worker SetVRegDouble(A(), GetVRegDouble(B()) - GetVRegDouble(C()));
1536*795d594fSAndroid Build Coastguard Worker return true;
1537*795d594fSAndroid Build Coastguard Worker }
1538*795d594fSAndroid Build Coastguard Worker
MUL_DOUBLE()1539*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool MUL_DOUBLE() {
1540*795d594fSAndroid Build Coastguard Worker SetVRegDouble(A(), GetVRegDouble(B()) * GetVRegDouble(C()));
1541*795d594fSAndroid Build Coastguard Worker return true;
1542*795d594fSAndroid Build Coastguard Worker }
1543*795d594fSAndroid Build Coastguard Worker
DIV_DOUBLE()1544*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool DIV_DOUBLE() {
1545*795d594fSAndroid Build Coastguard Worker SetVRegDouble(A(), GetVRegDouble(B()) / GetVRegDouble(C()));
1546*795d594fSAndroid Build Coastguard Worker return true;
1547*795d594fSAndroid Build Coastguard Worker }
1548*795d594fSAndroid Build Coastguard Worker
REM_DOUBLE()1549*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool REM_DOUBLE() {
1550*795d594fSAndroid Build Coastguard Worker SetVRegDouble(A(), fmod(GetVRegDouble(B()), GetVRegDouble(C())));
1551*795d594fSAndroid Build Coastguard Worker return true;
1552*795d594fSAndroid Build Coastguard Worker }
1553*795d594fSAndroid Build Coastguard Worker
ADD_INT_2ADDR()1554*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool ADD_INT_2ADDR() {
1555*795d594fSAndroid Build Coastguard Worker SetVReg(A(), SafeAdd(GetVReg(A()), GetVReg(B())));
1556*795d594fSAndroid Build Coastguard Worker return true;
1557*795d594fSAndroid Build Coastguard Worker }
1558*795d594fSAndroid Build Coastguard Worker
SUB_INT_2ADDR()1559*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool SUB_INT_2ADDR() {
1560*795d594fSAndroid Build Coastguard Worker SetVReg(A(), SafeSub(GetVReg(A()), GetVReg(B())));
1561*795d594fSAndroid Build Coastguard Worker return true;
1562*795d594fSAndroid Build Coastguard Worker }
1563*795d594fSAndroid Build Coastguard Worker
MUL_INT_2ADDR()1564*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool MUL_INT_2ADDR() {
1565*795d594fSAndroid Build Coastguard Worker SetVReg(A(), SafeMul(GetVReg(A()), GetVReg(B())));
1566*795d594fSAndroid Build Coastguard Worker return true;
1567*795d594fSAndroid Build Coastguard Worker }
1568*795d594fSAndroid Build Coastguard Worker
DIV_INT_2ADDR()1569*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool DIV_INT_2ADDR() {
1570*795d594fSAndroid Build Coastguard Worker return DoIntDivide(shadow_frame_, A(), GetVReg(A()), GetVReg(B()));
1571*795d594fSAndroid Build Coastguard Worker }
1572*795d594fSAndroid Build Coastguard Worker
REM_INT_2ADDR()1573*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool REM_INT_2ADDR() {
1574*795d594fSAndroid Build Coastguard Worker return DoIntRemainder(shadow_frame_, A(), GetVReg(A()), GetVReg(B()));
1575*795d594fSAndroid Build Coastguard Worker }
1576*795d594fSAndroid Build Coastguard Worker
SHL_INT_2ADDR()1577*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool SHL_INT_2ADDR() {
1578*795d594fSAndroid Build Coastguard Worker SetVReg(A(), GetVReg(A()) << (GetVReg(B()) & 0x1f));
1579*795d594fSAndroid Build Coastguard Worker return true;
1580*795d594fSAndroid Build Coastguard Worker }
1581*795d594fSAndroid Build Coastguard Worker
SHR_INT_2ADDR()1582*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool SHR_INT_2ADDR() {
1583*795d594fSAndroid Build Coastguard Worker SetVReg(A(), GetVReg(A()) >> (GetVReg(B()) & 0x1f));
1584*795d594fSAndroid Build Coastguard Worker return true;
1585*795d594fSAndroid Build Coastguard Worker }
1586*795d594fSAndroid Build Coastguard Worker
USHR_INT_2ADDR()1587*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool USHR_INT_2ADDR() {
1588*795d594fSAndroid Build Coastguard Worker SetVReg(A(), static_cast<uint32_t>(GetVReg(A())) >> (GetVReg(B()) & 0x1f));
1589*795d594fSAndroid Build Coastguard Worker return true;
1590*795d594fSAndroid Build Coastguard Worker }
1591*795d594fSAndroid Build Coastguard Worker
AND_INT_2ADDR()1592*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool AND_INT_2ADDR() {
1593*795d594fSAndroid Build Coastguard Worker SetVReg(A(), GetVReg(A()) & GetVReg(B()));
1594*795d594fSAndroid Build Coastguard Worker return true;
1595*795d594fSAndroid Build Coastguard Worker }
1596*795d594fSAndroid Build Coastguard Worker
OR_INT_2ADDR()1597*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool OR_INT_2ADDR() {
1598*795d594fSAndroid Build Coastguard Worker SetVReg(A(), GetVReg(A()) | GetVReg(B()));
1599*795d594fSAndroid Build Coastguard Worker return true;
1600*795d594fSAndroid Build Coastguard Worker }
1601*795d594fSAndroid Build Coastguard Worker
XOR_INT_2ADDR()1602*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool XOR_INT_2ADDR() {
1603*795d594fSAndroid Build Coastguard Worker SetVReg(A(), GetVReg(A()) ^ GetVReg(B()));
1604*795d594fSAndroid Build Coastguard Worker return true;
1605*795d594fSAndroid Build Coastguard Worker }
1606*795d594fSAndroid Build Coastguard Worker
ADD_LONG_2ADDR()1607*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool ADD_LONG_2ADDR() {
1608*795d594fSAndroid Build Coastguard Worker SetVRegLong(A(), SafeAdd(GetVRegLong(A()), GetVRegLong(B())));
1609*795d594fSAndroid Build Coastguard Worker return true;
1610*795d594fSAndroid Build Coastguard Worker }
1611*795d594fSAndroid Build Coastguard Worker
SUB_LONG_2ADDR()1612*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool SUB_LONG_2ADDR() {
1613*795d594fSAndroid Build Coastguard Worker SetVRegLong(A(), SafeSub(GetVRegLong(A()), GetVRegLong(B())));
1614*795d594fSAndroid Build Coastguard Worker return true;
1615*795d594fSAndroid Build Coastguard Worker }
1616*795d594fSAndroid Build Coastguard Worker
MUL_LONG_2ADDR()1617*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool MUL_LONG_2ADDR() {
1618*795d594fSAndroid Build Coastguard Worker SetVRegLong(A(), SafeMul(GetVRegLong(A()), GetVRegLong(B())));
1619*795d594fSAndroid Build Coastguard Worker return true;
1620*795d594fSAndroid Build Coastguard Worker }
1621*795d594fSAndroid Build Coastguard Worker
DIV_LONG_2ADDR()1622*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool DIV_LONG_2ADDR() {
1623*795d594fSAndroid Build Coastguard Worker return DoLongDivide(shadow_frame_, A(), GetVRegLong(A()), GetVRegLong(B()));
1624*795d594fSAndroid Build Coastguard Worker }
1625*795d594fSAndroid Build Coastguard Worker
REM_LONG_2ADDR()1626*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool REM_LONG_2ADDR() {
1627*795d594fSAndroid Build Coastguard Worker return DoLongRemainder(shadow_frame_, A(), GetVRegLong(A()), GetVRegLong(B()));
1628*795d594fSAndroid Build Coastguard Worker }
1629*795d594fSAndroid Build Coastguard Worker
AND_LONG_2ADDR()1630*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool AND_LONG_2ADDR() {
1631*795d594fSAndroid Build Coastguard Worker SetVRegLong(A(), GetVRegLong(A()) & GetVRegLong(B()));
1632*795d594fSAndroid Build Coastguard Worker return true;
1633*795d594fSAndroid Build Coastguard Worker }
1634*795d594fSAndroid Build Coastguard Worker
OR_LONG_2ADDR()1635*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool OR_LONG_2ADDR() {
1636*795d594fSAndroid Build Coastguard Worker SetVRegLong(A(), GetVRegLong(A()) | GetVRegLong(B()));
1637*795d594fSAndroid Build Coastguard Worker return true;
1638*795d594fSAndroid Build Coastguard Worker }
1639*795d594fSAndroid Build Coastguard Worker
XOR_LONG_2ADDR()1640*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool XOR_LONG_2ADDR() {
1641*795d594fSAndroid Build Coastguard Worker SetVRegLong(A(), GetVRegLong(A()) ^ GetVRegLong(B()));
1642*795d594fSAndroid Build Coastguard Worker return true;
1643*795d594fSAndroid Build Coastguard Worker }
1644*795d594fSAndroid Build Coastguard Worker
SHL_LONG_2ADDR()1645*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool SHL_LONG_2ADDR() {
1646*795d594fSAndroid Build Coastguard Worker SetVRegLong(A(), GetVRegLong(A()) << (GetVReg(B()) & 0x3f));
1647*795d594fSAndroid Build Coastguard Worker return true;
1648*795d594fSAndroid Build Coastguard Worker }
1649*795d594fSAndroid Build Coastguard Worker
SHR_LONG_2ADDR()1650*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool SHR_LONG_2ADDR() {
1651*795d594fSAndroid Build Coastguard Worker SetVRegLong(A(), GetVRegLong(A()) >> (GetVReg(B()) & 0x3f));
1652*795d594fSAndroid Build Coastguard Worker return true;
1653*795d594fSAndroid Build Coastguard Worker }
1654*795d594fSAndroid Build Coastguard Worker
USHR_LONG_2ADDR()1655*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool USHR_LONG_2ADDR() {
1656*795d594fSAndroid Build Coastguard Worker SetVRegLong(A(), static_cast<uint64_t>(GetVRegLong(A())) >> (GetVReg(B()) & 0x3f));
1657*795d594fSAndroid Build Coastguard Worker return true;
1658*795d594fSAndroid Build Coastguard Worker }
1659*795d594fSAndroid Build Coastguard Worker
ADD_FLOAT_2ADDR()1660*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool ADD_FLOAT_2ADDR() {
1661*795d594fSAndroid Build Coastguard Worker SetVRegFloat(A(), GetVRegFloat(A()) + GetVRegFloat(B()));
1662*795d594fSAndroid Build Coastguard Worker return true;
1663*795d594fSAndroid Build Coastguard Worker }
1664*795d594fSAndroid Build Coastguard Worker
SUB_FLOAT_2ADDR()1665*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool SUB_FLOAT_2ADDR() {
1666*795d594fSAndroid Build Coastguard Worker SetVRegFloat(A(), GetVRegFloat(A()) - GetVRegFloat(B()));
1667*795d594fSAndroid Build Coastguard Worker return true;
1668*795d594fSAndroid Build Coastguard Worker }
1669*795d594fSAndroid Build Coastguard Worker
MUL_FLOAT_2ADDR()1670*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool MUL_FLOAT_2ADDR() {
1671*795d594fSAndroid Build Coastguard Worker SetVRegFloat(A(), GetVRegFloat(A()) * GetVRegFloat(B()));
1672*795d594fSAndroid Build Coastguard Worker return true;
1673*795d594fSAndroid Build Coastguard Worker }
1674*795d594fSAndroid Build Coastguard Worker
DIV_FLOAT_2ADDR()1675*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool DIV_FLOAT_2ADDR() {
1676*795d594fSAndroid Build Coastguard Worker SetVRegFloat(A(), GetVRegFloat(A()) / GetVRegFloat(B()));
1677*795d594fSAndroid Build Coastguard Worker return true;
1678*795d594fSAndroid Build Coastguard Worker }
1679*795d594fSAndroid Build Coastguard Worker
REM_FLOAT_2ADDR()1680*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool REM_FLOAT_2ADDR() {
1681*795d594fSAndroid Build Coastguard Worker SetVRegFloat(A(), fmodf(GetVRegFloat(A()), GetVRegFloat(B())));
1682*795d594fSAndroid Build Coastguard Worker return true;
1683*795d594fSAndroid Build Coastguard Worker }
1684*795d594fSAndroid Build Coastguard Worker
ADD_DOUBLE_2ADDR()1685*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool ADD_DOUBLE_2ADDR() {
1686*795d594fSAndroid Build Coastguard Worker SetVRegDouble(A(), GetVRegDouble(A()) + GetVRegDouble(B()));
1687*795d594fSAndroid Build Coastguard Worker return true;
1688*795d594fSAndroid Build Coastguard Worker }
1689*795d594fSAndroid Build Coastguard Worker
SUB_DOUBLE_2ADDR()1690*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool SUB_DOUBLE_2ADDR() {
1691*795d594fSAndroid Build Coastguard Worker SetVRegDouble(A(), GetVRegDouble(A()) - GetVRegDouble(B()));
1692*795d594fSAndroid Build Coastguard Worker return true;
1693*795d594fSAndroid Build Coastguard Worker }
1694*795d594fSAndroid Build Coastguard Worker
MUL_DOUBLE_2ADDR()1695*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool MUL_DOUBLE_2ADDR() {
1696*795d594fSAndroid Build Coastguard Worker SetVRegDouble(A(), GetVRegDouble(A()) * GetVRegDouble(B()));
1697*795d594fSAndroid Build Coastguard Worker return true;
1698*795d594fSAndroid Build Coastguard Worker }
1699*795d594fSAndroid Build Coastguard Worker
DIV_DOUBLE_2ADDR()1700*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool DIV_DOUBLE_2ADDR() {
1701*795d594fSAndroid Build Coastguard Worker SetVRegDouble(A(), GetVRegDouble(A()) / GetVRegDouble(B()));
1702*795d594fSAndroid Build Coastguard Worker return true;
1703*795d594fSAndroid Build Coastguard Worker }
1704*795d594fSAndroid Build Coastguard Worker
REM_DOUBLE_2ADDR()1705*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool REM_DOUBLE_2ADDR() {
1706*795d594fSAndroid Build Coastguard Worker SetVRegDouble(A(), fmod(GetVRegDouble(A()), GetVRegDouble(B())));
1707*795d594fSAndroid Build Coastguard Worker return true;
1708*795d594fSAndroid Build Coastguard Worker }
1709*795d594fSAndroid Build Coastguard Worker
ADD_INT_LIT16()1710*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool ADD_INT_LIT16() {
1711*795d594fSAndroid Build Coastguard Worker SetVReg(A(), SafeAdd(GetVReg(B()), C()));
1712*795d594fSAndroid Build Coastguard Worker return true;
1713*795d594fSAndroid Build Coastguard Worker }
1714*795d594fSAndroid Build Coastguard Worker
RSUB_INT()1715*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool RSUB_INT() {
1716*795d594fSAndroid Build Coastguard Worker SetVReg(A(), SafeSub(C(), GetVReg(B())));
1717*795d594fSAndroid Build Coastguard Worker return true;
1718*795d594fSAndroid Build Coastguard Worker }
1719*795d594fSAndroid Build Coastguard Worker
MUL_INT_LIT16()1720*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool MUL_INT_LIT16() {
1721*795d594fSAndroid Build Coastguard Worker SetVReg(A(), SafeMul(GetVReg(B()), C()));
1722*795d594fSAndroid Build Coastguard Worker return true;
1723*795d594fSAndroid Build Coastguard Worker }
1724*795d594fSAndroid Build Coastguard Worker
DIV_INT_LIT16()1725*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool DIV_INT_LIT16() {
1726*795d594fSAndroid Build Coastguard Worker return DoIntDivide(shadow_frame_, A(), GetVReg(B()), C());
1727*795d594fSAndroid Build Coastguard Worker }
1728*795d594fSAndroid Build Coastguard Worker
REM_INT_LIT16()1729*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool REM_INT_LIT16() {
1730*795d594fSAndroid Build Coastguard Worker return DoIntRemainder(shadow_frame_, A(), GetVReg(B()), C());
1731*795d594fSAndroid Build Coastguard Worker }
1732*795d594fSAndroid Build Coastguard Worker
AND_INT_LIT16()1733*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool AND_INT_LIT16() {
1734*795d594fSAndroid Build Coastguard Worker SetVReg(A(), GetVReg(B()) & C());
1735*795d594fSAndroid Build Coastguard Worker return true;
1736*795d594fSAndroid Build Coastguard Worker }
1737*795d594fSAndroid Build Coastguard Worker
OR_INT_LIT16()1738*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool OR_INT_LIT16() {
1739*795d594fSAndroid Build Coastguard Worker SetVReg(A(), GetVReg(B()) | C());
1740*795d594fSAndroid Build Coastguard Worker return true;
1741*795d594fSAndroid Build Coastguard Worker }
1742*795d594fSAndroid Build Coastguard Worker
XOR_INT_LIT16()1743*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool XOR_INT_LIT16() {
1744*795d594fSAndroid Build Coastguard Worker SetVReg(A(), GetVReg(B()) ^ C());
1745*795d594fSAndroid Build Coastguard Worker return true;
1746*795d594fSAndroid Build Coastguard Worker }
1747*795d594fSAndroid Build Coastguard Worker
ADD_INT_LIT8()1748*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool ADD_INT_LIT8() {
1749*795d594fSAndroid Build Coastguard Worker SetVReg(A(), SafeAdd(GetVReg(B()), C()));
1750*795d594fSAndroid Build Coastguard Worker return true;
1751*795d594fSAndroid Build Coastguard Worker }
1752*795d594fSAndroid Build Coastguard Worker
RSUB_INT_LIT8()1753*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool RSUB_INT_LIT8() {
1754*795d594fSAndroid Build Coastguard Worker SetVReg(A(), SafeSub(C(), GetVReg(B())));
1755*795d594fSAndroid Build Coastguard Worker return true;
1756*795d594fSAndroid Build Coastguard Worker }
1757*795d594fSAndroid Build Coastguard Worker
MUL_INT_LIT8()1758*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool MUL_INT_LIT8() {
1759*795d594fSAndroid Build Coastguard Worker SetVReg(A(), SafeMul(GetVReg(B()), C()));
1760*795d594fSAndroid Build Coastguard Worker return true;
1761*795d594fSAndroid Build Coastguard Worker }
1762*795d594fSAndroid Build Coastguard Worker
DIV_INT_LIT8()1763*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool DIV_INT_LIT8() {
1764*795d594fSAndroid Build Coastguard Worker return DoIntDivide(shadow_frame_, A(), GetVReg(B()), C());
1765*795d594fSAndroid Build Coastguard Worker }
1766*795d594fSAndroid Build Coastguard Worker
REM_INT_LIT8()1767*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool REM_INT_LIT8() {
1768*795d594fSAndroid Build Coastguard Worker return DoIntRemainder(shadow_frame_, A(), GetVReg(B()), C());
1769*795d594fSAndroid Build Coastguard Worker }
1770*795d594fSAndroid Build Coastguard Worker
AND_INT_LIT8()1771*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool AND_INT_LIT8() {
1772*795d594fSAndroid Build Coastguard Worker SetVReg(A(), GetVReg(B()) & C());
1773*795d594fSAndroid Build Coastguard Worker return true;
1774*795d594fSAndroid Build Coastguard Worker }
1775*795d594fSAndroid Build Coastguard Worker
OR_INT_LIT8()1776*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool OR_INT_LIT8() {
1777*795d594fSAndroid Build Coastguard Worker SetVReg(A(), GetVReg(B()) | C());
1778*795d594fSAndroid Build Coastguard Worker return true;
1779*795d594fSAndroid Build Coastguard Worker }
1780*795d594fSAndroid Build Coastguard Worker
XOR_INT_LIT8()1781*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool XOR_INT_LIT8() {
1782*795d594fSAndroid Build Coastguard Worker SetVReg(A(), GetVReg(B()) ^ C());
1783*795d594fSAndroid Build Coastguard Worker return true;
1784*795d594fSAndroid Build Coastguard Worker }
1785*795d594fSAndroid Build Coastguard Worker
SHL_INT_LIT8()1786*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool SHL_INT_LIT8() {
1787*795d594fSAndroid Build Coastguard Worker SetVReg(A(), GetVReg(B()) << (C() & 0x1f));
1788*795d594fSAndroid Build Coastguard Worker return true;
1789*795d594fSAndroid Build Coastguard Worker }
1790*795d594fSAndroid Build Coastguard Worker
SHR_INT_LIT8()1791*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool SHR_INT_LIT8() {
1792*795d594fSAndroid Build Coastguard Worker SetVReg(A(), GetVReg(B()) >> (C() & 0x1f));
1793*795d594fSAndroid Build Coastguard Worker return true;
1794*795d594fSAndroid Build Coastguard Worker }
1795*795d594fSAndroid Build Coastguard Worker
USHR_INT_LIT8()1796*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool USHR_INT_LIT8() {
1797*795d594fSAndroid Build Coastguard Worker SetVReg(A(), static_cast<uint32_t>(GetVReg(B())) >> (C() & 0x1f));
1798*795d594fSAndroid Build Coastguard Worker return true;
1799*795d594fSAndroid Build Coastguard Worker }
1800*795d594fSAndroid Build Coastguard Worker
UNUSED_3E()1801*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool UNUSED_3E() {
1802*795d594fSAndroid Build Coastguard Worker return HandleUnused();
1803*795d594fSAndroid Build Coastguard Worker }
1804*795d594fSAndroid Build Coastguard Worker
UNUSED_3F()1805*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool UNUSED_3F() {
1806*795d594fSAndroid Build Coastguard Worker return HandleUnused();
1807*795d594fSAndroid Build Coastguard Worker }
1808*795d594fSAndroid Build Coastguard Worker
UNUSED_40()1809*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool UNUSED_40() {
1810*795d594fSAndroid Build Coastguard Worker return HandleUnused();
1811*795d594fSAndroid Build Coastguard Worker }
1812*795d594fSAndroid Build Coastguard Worker
UNUSED_41()1813*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool UNUSED_41() {
1814*795d594fSAndroid Build Coastguard Worker return HandleUnused();
1815*795d594fSAndroid Build Coastguard Worker }
1816*795d594fSAndroid Build Coastguard Worker
UNUSED_42()1817*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool UNUSED_42() {
1818*795d594fSAndroid Build Coastguard Worker return HandleUnused();
1819*795d594fSAndroid Build Coastguard Worker }
1820*795d594fSAndroid Build Coastguard Worker
UNUSED_43()1821*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool UNUSED_43() {
1822*795d594fSAndroid Build Coastguard Worker return HandleUnused();
1823*795d594fSAndroid Build Coastguard Worker }
1824*795d594fSAndroid Build Coastguard Worker
UNUSED_73()1825*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool UNUSED_73() {
1826*795d594fSAndroid Build Coastguard Worker return HandleUnused();
1827*795d594fSAndroid Build Coastguard Worker }
1828*795d594fSAndroid Build Coastguard Worker
UNUSED_79()1829*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool UNUSED_79() {
1830*795d594fSAndroid Build Coastguard Worker return HandleUnused();
1831*795d594fSAndroid Build Coastguard Worker }
1832*795d594fSAndroid Build Coastguard Worker
UNUSED_7A()1833*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool UNUSED_7A() {
1834*795d594fSAndroid Build Coastguard Worker return HandleUnused();
1835*795d594fSAndroid Build Coastguard Worker }
1836*795d594fSAndroid Build Coastguard Worker
UNUSED_E3()1837*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool UNUSED_E3() {
1838*795d594fSAndroid Build Coastguard Worker return HandleUnused();
1839*795d594fSAndroid Build Coastguard Worker }
1840*795d594fSAndroid Build Coastguard Worker
UNUSED_E4()1841*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool UNUSED_E4() {
1842*795d594fSAndroid Build Coastguard Worker return HandleUnused();
1843*795d594fSAndroid Build Coastguard Worker }
1844*795d594fSAndroid Build Coastguard Worker
UNUSED_E5()1845*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool UNUSED_E5() {
1846*795d594fSAndroid Build Coastguard Worker return HandleUnused();
1847*795d594fSAndroid Build Coastguard Worker }
1848*795d594fSAndroid Build Coastguard Worker
UNUSED_E6()1849*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool UNUSED_E6() {
1850*795d594fSAndroid Build Coastguard Worker return HandleUnused();
1851*795d594fSAndroid Build Coastguard Worker }
1852*795d594fSAndroid Build Coastguard Worker
UNUSED_E7()1853*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool UNUSED_E7() {
1854*795d594fSAndroid Build Coastguard Worker return HandleUnused();
1855*795d594fSAndroid Build Coastguard Worker }
1856*795d594fSAndroid Build Coastguard Worker
UNUSED_E8()1857*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool UNUSED_E8() {
1858*795d594fSAndroid Build Coastguard Worker return HandleUnused();
1859*795d594fSAndroid Build Coastguard Worker }
1860*795d594fSAndroid Build Coastguard Worker
UNUSED_E9()1861*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool UNUSED_E9() {
1862*795d594fSAndroid Build Coastguard Worker return HandleUnused();
1863*795d594fSAndroid Build Coastguard Worker }
1864*795d594fSAndroid Build Coastguard Worker
UNUSED_EA()1865*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool UNUSED_EA() {
1866*795d594fSAndroid Build Coastguard Worker return HandleUnused();
1867*795d594fSAndroid Build Coastguard Worker }
1868*795d594fSAndroid Build Coastguard Worker
UNUSED_EB()1869*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool UNUSED_EB() {
1870*795d594fSAndroid Build Coastguard Worker return HandleUnused();
1871*795d594fSAndroid Build Coastguard Worker }
1872*795d594fSAndroid Build Coastguard Worker
UNUSED_EC()1873*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool UNUSED_EC() {
1874*795d594fSAndroid Build Coastguard Worker return HandleUnused();
1875*795d594fSAndroid Build Coastguard Worker }
1876*795d594fSAndroid Build Coastguard Worker
UNUSED_ED()1877*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool UNUSED_ED() {
1878*795d594fSAndroid Build Coastguard Worker return HandleUnused();
1879*795d594fSAndroid Build Coastguard Worker }
1880*795d594fSAndroid Build Coastguard Worker
UNUSED_EE()1881*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool UNUSED_EE() {
1882*795d594fSAndroid Build Coastguard Worker return HandleUnused();
1883*795d594fSAndroid Build Coastguard Worker }
1884*795d594fSAndroid Build Coastguard Worker
UNUSED_EF()1885*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool UNUSED_EF() {
1886*795d594fSAndroid Build Coastguard Worker return HandleUnused();
1887*795d594fSAndroid Build Coastguard Worker }
1888*795d594fSAndroid Build Coastguard Worker
UNUSED_F0()1889*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool UNUSED_F0() {
1890*795d594fSAndroid Build Coastguard Worker return HandleUnused();
1891*795d594fSAndroid Build Coastguard Worker }
1892*795d594fSAndroid Build Coastguard Worker
UNUSED_F1()1893*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool UNUSED_F1() {
1894*795d594fSAndroid Build Coastguard Worker return HandleUnused();
1895*795d594fSAndroid Build Coastguard Worker }
1896*795d594fSAndroid Build Coastguard Worker
UNUSED_F2()1897*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool UNUSED_F2() {
1898*795d594fSAndroid Build Coastguard Worker return HandleUnused();
1899*795d594fSAndroid Build Coastguard Worker }
1900*795d594fSAndroid Build Coastguard Worker
UNUSED_F3()1901*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool UNUSED_F3() {
1902*795d594fSAndroid Build Coastguard Worker return HandleUnused();
1903*795d594fSAndroid Build Coastguard Worker }
1904*795d594fSAndroid Build Coastguard Worker
UNUSED_F4()1905*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool UNUSED_F4() {
1906*795d594fSAndroid Build Coastguard Worker return HandleUnused();
1907*795d594fSAndroid Build Coastguard Worker }
1908*795d594fSAndroid Build Coastguard Worker
UNUSED_F5()1909*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool UNUSED_F5() {
1910*795d594fSAndroid Build Coastguard Worker return HandleUnused();
1911*795d594fSAndroid Build Coastguard Worker }
1912*795d594fSAndroid Build Coastguard Worker
UNUSED_F6()1913*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool UNUSED_F6() {
1914*795d594fSAndroid Build Coastguard Worker return HandleUnused();
1915*795d594fSAndroid Build Coastguard Worker }
1916*795d594fSAndroid Build Coastguard Worker
UNUSED_F7()1917*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool UNUSED_F7() {
1918*795d594fSAndroid Build Coastguard Worker return HandleUnused();
1919*795d594fSAndroid Build Coastguard Worker }
1920*795d594fSAndroid Build Coastguard Worker
UNUSED_F8()1921*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool UNUSED_F8() {
1922*795d594fSAndroid Build Coastguard Worker return HandleUnused();
1923*795d594fSAndroid Build Coastguard Worker }
1924*795d594fSAndroid Build Coastguard Worker
UNUSED_F9()1925*795d594fSAndroid Build Coastguard Worker HANDLER_ATTRIBUTES bool UNUSED_F9() {
1926*795d594fSAndroid Build Coastguard Worker return HandleUnused();
1927*795d594fSAndroid Build Coastguard Worker }
1928*795d594fSAndroid Build Coastguard Worker
InstructionHandler(SwitchImplContext * ctx,const instrumentation::Instrumentation * instrumentation,Thread * self,ShadowFrame & shadow_frame,uint16_t dex_pc,const Instruction * inst,uint16_t inst_data,const Instruction * & next,bool & exit_interpreter_loop)1929*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE InstructionHandler(SwitchImplContext* ctx,
1930*795d594fSAndroid Build Coastguard Worker const instrumentation::Instrumentation* instrumentation,
1931*795d594fSAndroid Build Coastguard Worker Thread* self,
1932*795d594fSAndroid Build Coastguard Worker ShadowFrame& shadow_frame,
1933*795d594fSAndroid Build Coastguard Worker uint16_t dex_pc,
1934*795d594fSAndroid Build Coastguard Worker const Instruction* inst,
1935*795d594fSAndroid Build Coastguard Worker uint16_t inst_data,
1936*795d594fSAndroid Build Coastguard Worker const Instruction*& next,
1937*795d594fSAndroid Build Coastguard Worker bool& exit_interpreter_loop)
1938*795d594fSAndroid Build Coastguard Worker : ctx_(ctx),
1939*795d594fSAndroid Build Coastguard Worker instrumentation_(instrumentation),
1940*795d594fSAndroid Build Coastguard Worker self_(self),
1941*795d594fSAndroid Build Coastguard Worker shadow_frame_(shadow_frame),
1942*795d594fSAndroid Build Coastguard Worker dex_pc_(dex_pc),
1943*795d594fSAndroid Build Coastguard Worker inst_(inst),
1944*795d594fSAndroid Build Coastguard Worker inst_data_(inst_data),
1945*795d594fSAndroid Build Coastguard Worker next_(next),
1946*795d594fSAndroid Build Coastguard Worker exit_interpreter_loop_(exit_interpreter_loop) {
1947*795d594fSAndroid Build Coastguard Worker }
1948*795d594fSAndroid Build Coastguard Worker
1949*795d594fSAndroid Build Coastguard Worker private:
DoAssignabilityChecks()1950*795d594fSAndroid Build Coastguard Worker bool DoAssignabilityChecks() const REQUIRES_SHARED(Locks::mutator_lock_) {
1951*795d594fSAndroid Build Coastguard Worker return !shadow_frame_.GetMethod()->SkipAccessChecks();
1952*795d594fSAndroid Build Coastguard Worker }
1953*795d594fSAndroid Build Coastguard Worker
Accessor()1954*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE const CodeItemDataAccessor& Accessor() { return ctx_->accessor; }
Insns()1955*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE const uint16_t* Insns() { return ctx_->accessor.Insns(); }
ResultRegister()1956*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE JValue* ResultRegister() { return &ctx_->result_register; }
1957*795d594fSAndroid Build Coastguard Worker
Self()1958*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE Thread* Self() {
1959*795d594fSAndroid Build Coastguard Worker DCHECK_EQ(self_, Thread::Current());
1960*795d594fSAndroid Build Coastguard Worker return self_;
1961*795d594fSAndroid Build Coastguard Worker }
1962*795d594fSAndroid Build Coastguard Worker
DexPC()1963*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE int32_t DexPC() {
1964*795d594fSAndroid Build Coastguard Worker DCHECK_EQ(dex_pc_, shadow_frame_.GetDexPC());
1965*795d594fSAndroid Build Coastguard Worker return dex_pc_;
1966*795d594fSAndroid Build Coastguard Worker }
1967*795d594fSAndroid Build Coastguard Worker
Instrumentation()1968*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE const instrumentation::Instrumentation* Instrumentation() {
1969*795d594fSAndroid Build Coastguard Worker return instrumentation_;
1970*795d594fSAndroid Build Coastguard Worker }
1971*795d594fSAndroid Build Coastguard Worker
A()1972*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE int32_t A() { return inst_->VRegA(kFormat, inst_data_); }
B()1973*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE int32_t B() { return inst_->VRegB(kFormat, inst_data_); }
C()1974*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE int32_t C() { return inst_->VRegC(kFormat); }
1975*795d594fSAndroid Build Coastguard Worker
GetVReg(size_t i)1976*795d594fSAndroid Build Coastguard Worker int32_t GetVReg(size_t i) const { return shadow_frame_.GetVReg(i); }
GetVRegLong(size_t i)1977*795d594fSAndroid Build Coastguard Worker int64_t GetVRegLong(size_t i) const { return shadow_frame_.GetVRegLong(i); }
GetVRegFloat(size_t i)1978*795d594fSAndroid Build Coastguard Worker float GetVRegFloat(size_t i) const { return shadow_frame_.GetVRegFloat(i); }
GetVRegDouble(size_t i)1979*795d594fSAndroid Build Coastguard Worker double GetVRegDouble(size_t i) const { return shadow_frame_.GetVRegDouble(i); }
GetVRegReference(size_t i)1980*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> GetVRegReference(size_t i) const REQUIRES_SHARED(Locks::mutator_lock_) {
1981*795d594fSAndroid Build Coastguard Worker return shadow_frame_.GetVRegReference(i);
1982*795d594fSAndroid Build Coastguard Worker }
1983*795d594fSAndroid Build Coastguard Worker
SetVReg(size_t i,int32_t val)1984*795d594fSAndroid Build Coastguard Worker void SetVReg(size_t i, int32_t val) { shadow_frame_.SetVReg(i, val); }
SetVRegLong(size_t i,int64_t val)1985*795d594fSAndroid Build Coastguard Worker void SetVRegLong(size_t i, int64_t val) { shadow_frame_.SetVRegLong(i, val); }
SetVRegFloat(size_t i,float val)1986*795d594fSAndroid Build Coastguard Worker void SetVRegFloat(size_t i, float val) { shadow_frame_.SetVRegFloat(i, val); }
SetVRegDouble(size_t i,double val)1987*795d594fSAndroid Build Coastguard Worker void SetVRegDouble(size_t i, double val) { shadow_frame_.SetVRegDouble(i, val); }
SetVRegReference(size_t i,ObjPtr<mirror::Object> val)1988*795d594fSAndroid Build Coastguard Worker void SetVRegReference(size_t i, ObjPtr<mirror::Object> val)
1989*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
1990*795d594fSAndroid Build Coastguard Worker shadow_frame_.SetVRegReference(i, val);
1991*795d594fSAndroid Build Coastguard Worker }
1992*795d594fSAndroid Build Coastguard Worker
1993*795d594fSAndroid Build Coastguard Worker // Set the next instruction to be executed. It is the 'fall-through' instruction by default.
SetNextInstruction(const Instruction * next_inst)1994*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE void SetNextInstruction(const Instruction* next_inst) {
1995*795d594fSAndroid Build Coastguard Worker DCHECK_LT(next_inst->GetDexPc(Insns()), Accessor().InsnsSizeInCodeUnits());
1996*795d594fSAndroid Build Coastguard Worker next_ = next_inst;
1997*795d594fSAndroid Build Coastguard Worker }
1998*795d594fSAndroid Build Coastguard Worker
1999*795d594fSAndroid Build Coastguard Worker // Stop interpreting the current method. (return statement, debugger-forced return, OSR, ...)
ExitInterpreterLoop()2000*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE void ExitInterpreterLoop() {
2001*795d594fSAndroid Build Coastguard Worker exit_interpreter_loop_ = true;
2002*795d594fSAndroid Build Coastguard Worker }
2003*795d594fSAndroid Build Coastguard Worker
2004*795d594fSAndroid Build Coastguard Worker SwitchImplContext* const ctx_;
2005*795d594fSAndroid Build Coastguard Worker const instrumentation::Instrumentation* const instrumentation_;
2006*795d594fSAndroid Build Coastguard Worker Thread* const self_;
2007*795d594fSAndroid Build Coastguard Worker ShadowFrame& shadow_frame_;
2008*795d594fSAndroid Build Coastguard Worker uint32_t const dex_pc_;
2009*795d594fSAndroid Build Coastguard Worker const Instruction* const inst_;
2010*795d594fSAndroid Build Coastguard Worker uint16_t const inst_data_;
2011*795d594fSAndroid Build Coastguard Worker const Instruction*& next_;
2012*795d594fSAndroid Build Coastguard Worker
2013*795d594fSAndroid Build Coastguard Worker bool& exit_interpreter_loop_;
2014*795d594fSAndroid Build Coastguard Worker };
2015*795d594fSAndroid Build Coastguard Worker
2016*795d594fSAndroid Build Coastguard Worker // Don't inline in ASAN. It would create massive stack frame.
2017*795d594fSAndroid Build Coastguard Worker #if defined(ADDRESS_SANITIZER) || defined(HWADDRESS_SANITIZER)
2018*795d594fSAndroid Build Coastguard Worker #define ASAN_NO_INLINE NO_INLINE
2019*795d594fSAndroid Build Coastguard Worker #else
2020*795d594fSAndroid Build Coastguard Worker #define ASAN_NO_INLINE ALWAYS_INLINE
2021*795d594fSAndroid Build Coastguard Worker #endif
2022*795d594fSAndroid Build Coastguard Worker
2023*795d594fSAndroid Build Coastguard Worker #define OPCODE_CASE(OPCODE, OPCODE_NAME, NAME, FORMAT, i, a, e, v) \
2024*795d594fSAndroid Build Coastguard Worker template<bool transaction_active> \
2025*795d594fSAndroid Build Coastguard Worker ASAN_NO_INLINE NO_STACK_PROTECTOR static bool OP_##OPCODE_NAME( \
2026*795d594fSAndroid Build Coastguard Worker SwitchImplContext* ctx, \
2027*795d594fSAndroid Build Coastguard Worker const instrumentation::Instrumentation* instrumentation, \
2028*795d594fSAndroid Build Coastguard Worker Thread* self, \
2029*795d594fSAndroid Build Coastguard Worker ShadowFrame& shadow_frame, \
2030*795d594fSAndroid Build Coastguard Worker uint16_t dex_pc, \
2031*795d594fSAndroid Build Coastguard Worker const Instruction* inst, \
2032*795d594fSAndroid Build Coastguard Worker uint16_t inst_data, \
2033*795d594fSAndroid Build Coastguard Worker const Instruction*& next, \
2034*795d594fSAndroid Build Coastguard Worker bool& exit) REQUIRES_SHARED(Locks::mutator_lock_) { \
2035*795d594fSAndroid Build Coastguard Worker InstructionHandler<transaction_active, Instruction::FORMAT> handler( \
2036*795d594fSAndroid Build Coastguard Worker ctx, instrumentation, self, shadow_frame, dex_pc, inst, inst_data, next, exit); \
2037*795d594fSAndroid Build Coastguard Worker return LIKELY(handler.OPCODE_NAME()); \
2038*795d594fSAndroid Build Coastguard Worker }
DEX_INSTRUCTION_LIST(OPCODE_CASE)2039*795d594fSAndroid Build Coastguard Worker DEX_INSTRUCTION_LIST(OPCODE_CASE)
2040*795d594fSAndroid Build Coastguard Worker #undef OPCODE_CASE
2041*795d594fSAndroid Build Coastguard Worker
2042*795d594fSAndroid Build Coastguard Worker template<bool transaction_active>
2043*795d594fSAndroid Build Coastguard Worker NO_STACK_PROTECTOR
2044*795d594fSAndroid Build Coastguard Worker void ExecuteSwitchImplCpp(SwitchImplContext* ctx) {
2045*795d594fSAndroid Build Coastguard Worker Thread* self = ctx->self;
2046*795d594fSAndroid Build Coastguard Worker const CodeItemDataAccessor& accessor = ctx->accessor;
2047*795d594fSAndroid Build Coastguard Worker ShadowFrame& shadow_frame = ctx->shadow_frame;
2048*795d594fSAndroid Build Coastguard Worker self->VerifyStack();
2049*795d594fSAndroid Build Coastguard Worker
2050*795d594fSAndroid Build Coastguard Worker uint32_t dex_pc = shadow_frame.GetDexPC();
2051*795d594fSAndroid Build Coastguard Worker const auto* const instrumentation = Runtime::Current()->GetInstrumentation();
2052*795d594fSAndroid Build Coastguard Worker const uint16_t* const insns = accessor.Insns();
2053*795d594fSAndroid Build Coastguard Worker const Instruction* next = Instruction::At(insns + dex_pc);
2054*795d594fSAndroid Build Coastguard Worker
2055*795d594fSAndroid Build Coastguard Worker DCHECK(!shadow_frame.GetForceRetryInstruction())
2056*795d594fSAndroid Build Coastguard Worker << "Entered interpreter from invoke without retry instruction being handled!";
2057*795d594fSAndroid Build Coastguard Worker
2058*795d594fSAndroid Build Coastguard Worker while (true) {
2059*795d594fSAndroid Build Coastguard Worker const Instruction* const inst = next;
2060*795d594fSAndroid Build Coastguard Worker dex_pc = inst->GetDexPc(insns);
2061*795d594fSAndroid Build Coastguard Worker shadow_frame.SetDexPC(dex_pc);
2062*795d594fSAndroid Build Coastguard Worker TraceExecution(shadow_frame, inst, dex_pc);
2063*795d594fSAndroid Build Coastguard Worker uint16_t inst_data = inst->Fetch16(0);
2064*795d594fSAndroid Build Coastguard Worker bool exit = false;
2065*795d594fSAndroid Build Coastguard Worker bool success; // Moved outside to keep frames small under asan.
2066*795d594fSAndroid Build Coastguard Worker if (InstructionHandler<transaction_active, Instruction::kInvalidFormat>(
2067*795d594fSAndroid Build Coastguard Worker ctx, instrumentation, self, shadow_frame, dex_pc, inst, inst_data, next, exit).
2068*795d594fSAndroid Build Coastguard Worker Preamble()) {
2069*795d594fSAndroid Build Coastguard Worker DCHECK_EQ(self->IsExceptionPending(), inst->Opcode(inst_data) == Instruction::MOVE_EXCEPTION);
2070*795d594fSAndroid Build Coastguard Worker switch (inst->Opcode(inst_data)) {
2071*795d594fSAndroid Build Coastguard Worker #define OPCODE_CASE(OPCODE, OPCODE_NAME, NAME, FORMAT, i, a, e, v) \
2072*795d594fSAndroid Build Coastguard Worker case OPCODE: { \
2073*795d594fSAndroid Build Coastguard Worker next = inst->RelativeAt(Instruction::SizeInCodeUnits(Instruction::FORMAT)); \
2074*795d594fSAndroid Build Coastguard Worker success = OP_##OPCODE_NAME<transaction_active>( \
2075*795d594fSAndroid Build Coastguard Worker ctx, instrumentation, self, shadow_frame, dex_pc, inst, inst_data, next, exit); \
2076*795d594fSAndroid Build Coastguard Worker if (success) { \
2077*795d594fSAndroid Build Coastguard Worker continue; \
2078*795d594fSAndroid Build Coastguard Worker } \
2079*795d594fSAndroid Build Coastguard Worker break; \
2080*795d594fSAndroid Build Coastguard Worker }
2081*795d594fSAndroid Build Coastguard Worker DEX_INSTRUCTION_LIST(OPCODE_CASE)
2082*795d594fSAndroid Build Coastguard Worker #undef OPCODE_CASE
2083*795d594fSAndroid Build Coastguard Worker }
2084*795d594fSAndroid Build Coastguard Worker }
2085*795d594fSAndroid Build Coastguard Worker if (exit) {
2086*795d594fSAndroid Build Coastguard Worker shadow_frame.SetDexPC(dex::kDexNoIndex);
2087*795d594fSAndroid Build Coastguard Worker return; // Return statement or debugger forced exit.
2088*795d594fSAndroid Build Coastguard Worker }
2089*795d594fSAndroid Build Coastguard Worker if (self->IsExceptionPending()) {
2090*795d594fSAndroid Build Coastguard Worker if (!InstructionHandler<transaction_active, Instruction::kInvalidFormat>(
2091*795d594fSAndroid Build Coastguard Worker ctx, instrumentation, self, shadow_frame, dex_pc, inst, inst_data, next, exit).
2092*795d594fSAndroid Build Coastguard Worker HandlePendingException()) {
2093*795d594fSAndroid Build Coastguard Worker shadow_frame.SetDexPC(dex::kDexNoIndex);
2094*795d594fSAndroid Build Coastguard Worker return; // Locally unhandled exception - return to caller.
2095*795d594fSAndroid Build Coastguard Worker }
2096*795d594fSAndroid Build Coastguard Worker // Continue execution in the catch block.
2097*795d594fSAndroid Build Coastguard Worker }
2098*795d594fSAndroid Build Coastguard Worker }
2099*795d594fSAndroid Build Coastguard Worker } // NOLINT(readability/fn_size)
2100*795d594fSAndroid Build Coastguard Worker
2101*795d594fSAndroid Build Coastguard Worker } // namespace interpreter
2102*795d594fSAndroid Build Coastguard Worker } // namespace art
2103*795d594fSAndroid Build Coastguard Worker
2104*795d594fSAndroid Build Coastguard Worker #endif // ART_RUNTIME_INTERPRETER_INTERPRETER_SWITCH_IMPL_INL_H_
2105