1 /* 2 * Copyright (c) 2022, Arm Limited. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 * 6 */ 7 #ifndef __TFM_AAPCS_LOCAL_H__ 8 #define __TFM_AAPCS_LOCAL_H__ 9 10 #include <stdint.h> 11 12 /* 13 * AAPCS: Procedure Call Standard for the Arm Architecture(IHI0042). 14 * 15 * This file complies with AAPCS rules for the local project(TF-M) 16 * convenience. Append a 'local' postfix here in case the toolchain 17 * makes 'AAPCS' as one built-in word. 18 */ 19 20 /* 21 * Returning values in multiple argument registers: 22 * 23 * If a caller in assembly code requires multiple return values from a 24 * callee, returning in argument registers is more convenient. This needs 25 * the callee to assemble multiple return values into one fundamental data 26 * type whose size exceeds the default data width, such as returning a 64-bit 27 * integer on a 32-bit system separates the 64-bit into two 32-bit values 28 * and gets returned in argument register 0 and 1. 29 * 30 * The following is the implementation for a generic 32-bit system. To 31 * be expanded when new systems get involved. 32 * 33 * Method (MACRO) uses 'a(x)', which stands for AAPCS 'argument register'. 34 * Implementation uses 'r(x)', which is the implementation name for 35 * 'a(x)' in the 32-bit system. 36 */ 37 union u64_in_u32_regs_t { 38 struct { 39 uint32_t r0; 40 uint32_t r1; 41 } u32_regs; 42 43 uint64_t u64_val; 44 }; 45 46 #define AAPCS_DUAL_U32_T union u64_in_u32_regs_t 47 48 #define AAPCS_DUAL_U32_SET(v, a0, a1) \ 49 do { \ 50 (v).u32_regs.r0 = (uint32_t)(a0); \ 51 (v).u32_regs.r1 = (uint32_t)(a1); \ 52 } while (0) 53 54 #define AAPCS_DUAL_U32_SET_A0(v, a0) \ 55 (v).u32_regs.r0 = (uint32_t)(a0) 56 57 #define AAPCS_DUAL_U32_SET_A1(v, a1) \ 58 (v).u32_regs.r1 = (uint32_t)(a1) 59 60 #define AAPCS_DUAL_U32_AS_U64(v) (v).u64_val 61 62 #endif /* __TFM_AAPCS_LOCAL_H__ */ 63