1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "critical_native_abi_fixup_arm.h" 18 19 #include "intrinsics.h" 20 #include "nodes.h" 21 22 namespace art HIDDEN { 23 namespace arm { 24 25 // Fix up FP arguments passed in core registers for call to @CriticalNative by inserting fake calls 26 // to Float.floatToRawIntBits() or Double.doubleToRawLongBits() to satisfy type consistency checks. FixUpArguments(HInvokeStaticOrDirect * invoke)27static void FixUpArguments(HInvokeStaticOrDirect* invoke) { 28 DCHECK_EQ(invoke->GetCodePtrLocation(), CodePtrLocation::kCallCriticalNative); 29 size_t reg = 0u; 30 for (size_t i = 0, num_args = invoke->GetNumberOfArguments(); i != num_args; ++i) { 31 HInstruction* input = invoke->InputAt(i); 32 DataType::Type input_type = input->GetType(); 33 size_t next_reg = reg + 1u; 34 if (DataType::Is64BitType(input_type)) { 35 reg = RoundUp(reg, 2u); 36 next_reg = reg + 2u; 37 } 38 if (reg == 4u) { 39 break; // Remaining arguments are passed on stack. 40 } 41 if (DataType::IsFloatingPointType(input_type)) { 42 InsertFpToIntegralIntrinsic(invoke, i); 43 } 44 reg = next_reg; 45 } 46 } 47 Run()48bool CriticalNativeAbiFixupArm::Run() { 49 if (!graph_->HasDirectCriticalNativeCall()) { 50 return false; 51 } 52 53 for (HBasicBlock* block : graph_->GetReversePostOrder()) { 54 for (HInstructionIterator it(block->GetInstructions()); !it.Done(); it.Advance()) { 55 HInstruction* instruction = it.Current(); 56 if (instruction->IsInvokeStaticOrDirect() && 57 instruction->AsInvokeStaticOrDirect()->GetCodePtrLocation() == 58 CodePtrLocation::kCallCriticalNative) { 59 FixUpArguments(instruction->AsInvokeStaticOrDirect()); 60 } 61 } 62 } 63 return true; 64 } 65 66 } // namespace arm 67 } // namespace art 68