1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 #ifndef _BRIDGES_CPP_UNO_AARCH64_ABI_HXX_ 25 #define _BRIDGES_CPP_UNO_AARCH64_ABI_HXX_ 26 27 // This is an implementation of the AArch64 procedure call standard, as 28 // described in "Procedure Call Standard for the Arm 64-bit Architecture" 29 // (ARM IHI 0055), with the deviations documented in Apple's "Writing ARM64 30 // Code for Apple Platforms". It is a clean-room implementation written from 31 // those public specifications; see ../../../../AAPCS64_BRIDGE_SPEC.md. 32 33 #include <typelib/typedescription.hxx> 34 35 namespace aarch64 36 { 37 38 /* 8 general purpose registers (x0..x7) are used for parameter passing. 39 Note: the indirect-result-location register x8 is *separate* and is NOT 40 part of this count. */ 41 const sal_uInt32 MAX_GPR_REGS = 8; 42 43 /* 8 SIMD/FP registers (v0..v7) are used for parameter passing. */ 44 const sal_uInt32 MAX_FPR_REGS = 8; 45 46 /* The largest number of registers a single aggregate can occupy: an HFA/HVA 47 may use up to 4 FP registers; a non-HFA aggregate passed in GPRs uses at 48 most 2 (16 bytes / 8). */ 49 const sal_uInt32 MAX_AGGREGATE_REGS = 4; 50 51 /* Count the number of registers required to pass the given type. 52 53 Examines the argument and sets the number of GPR (x) and FPR (v) registers 54 it would consume. For a Homogeneous Floating-point Aggregate the FPR count 55 is the number of members (<= 4); for a non-HFA aggregate <= 16 bytes the GPR 56 count is 1 or 2; scalars use exactly one register of the appropriate bank. 57 58 Returns false iff the parameter must be passed indirectly (in memory): a 59 non-HFA aggregate larger than 16 bytes. When bInReturn is true the same 60 classification answers "can this be returned in registers?" (false => the 61 caller must allocate a buffer and pass it in x8). 62 */ 63 bool examine_argument( typelib_TypeDescriptionReference *pTypeRef, bool bInReturn, int &nUsedGPR, int &nUsedFPR ); 64 65 /** Does a function returning this type use the hidden indirect-result pointer 66 (passed by the caller in x8), or can it return in registers? 67 68 A scalar returns in x0 or v0; an HFA returns in v0..v3; a non-HFA aggregate 69 of <= 16 bytes returns in x0,x1. Anything larger (non-HFA aggregate 70 > 16 bytes) is returned via the caller-allocated buffer addressed by x8 - 71 that is the "hidden param" case, for which this returns true. 72 */ 73 bool return_in_hidden_param( typelib_TypeDescriptionReference *pTypeRef ); 74 75 /** Scatter a register-resident return value (an HFA returned in v0..v3, or a 76 non-HFA aggregate <= 16 bytes returned in x0,x1) into the caller's struct. 77 78 pGPR points at the saved x0,x1,... ; pFPR at the saved v0,v1,... (each 79 element the low 8 bytes of a v register, i.e. a double slot). Only valid 80 when return_in_hidden_param() is false. 81 */ 82 void fill_struct( typelib_TypeDescriptionReference *pTypeRef, const sal_uInt64* pGPR, const double* pFPR, void *pStruct ); 83 84 } // namespace aarch64 85 86 #endif // _BRIDGES_CPP_UNO_AARCH64_ABI_HXX_ 87