1*412f47f9SXin Li /* 2*412f47f9SXin Li * Macros for asm code. Arm version. 3*412f47f9SXin Li * 4*412f47f9SXin Li * Copyright (c) 2019-2022, Arm Limited. 5*412f47f9SXin Li * SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception 6*412f47f9SXin Li */ 7*412f47f9SXin Li 8*412f47f9SXin Li #ifndef _ASMDEFS_H 9*412f47f9SXin Li #define _ASMDEFS_H 10*412f47f9SXin Li 11*412f47f9SXin Li /* Check whether leaf function PAC signing has been requested in the 12*412f47f9SXin Li -mbranch-protect compile-time option. */ 13*412f47f9SXin Li #define LEAF_PROTECT_BIT 2 14*412f47f9SXin Li 15*412f47f9SXin Li #ifdef __ARM_FEATURE_PAC_DEFAULT 16*412f47f9SXin Li # define HAVE_PAC_LEAF \ 17*412f47f9SXin Li ((__ARM_FEATURE_PAC_DEFAULT & (1 << LEAF_PROTECT_BIT)) && 1) 18*412f47f9SXin Li #else 19*412f47f9SXin Li # define HAVE_PAC_LEAF 0 20*412f47f9SXin Li #endif 21*412f47f9SXin Li 22*412f47f9SXin Li /* Provide default parameters for PAC-code handling in leaf-functions. */ 23*412f47f9SXin Li #if HAVE_PAC_LEAF 24*412f47f9SXin Li # ifndef PAC_LEAF_PUSH_IP 25*412f47f9SXin Li # define PAC_LEAF_PUSH_IP 1 26*412f47f9SXin Li # endif 27*412f47f9SXin Li #else /* !HAVE_PAC_LEAF */ 28*412f47f9SXin Li # undef PAC_LEAF_PUSH_IP 29*412f47f9SXin Li # define PAC_LEAF_PUSH_IP 0 30*412f47f9SXin Li #endif /* HAVE_PAC_LEAF */ 31*412f47f9SXin Li 32*412f47f9SXin Li #define STACK_ALIGN_ENFORCE 0 33*412f47f9SXin Li 34*412f47f9SXin Li /****************************************************************************** 35*412f47f9SXin Li * Implementation of the prologue and epilogue assembler macros and their 36*412f47f9SXin Li * associated helper functions. 37*412f47f9SXin Li * 38*412f47f9SXin Li * These functions add support for the following: 39*412f47f9SXin Li * 40*412f47f9SXin Li * - M-profile branch target identification (BTI) landing-pads when compiled 41*412f47f9SXin Li * with `-mbranch-protection=bti'. 42*412f47f9SXin Li * - PAC-signing and verification instructions, depending on hardware support 43*412f47f9SXin Li * and whether the PAC-signing of leaf functions has been requested via the 44*412f47f9SXin Li * `-mbranch-protection=pac-ret+leaf' compiler argument. 45*412f47f9SXin Li * - 8-byte stack alignment preservation at function entry, defaulting to the 46*412f47f9SXin Li * value of STACK_ALIGN_ENFORCE. 47*412f47f9SXin Li * 48*412f47f9SXin Li * Notes: 49*412f47f9SXin Li * - Prologue stack alignment is implemented by detecting a push with an odd 50*412f47f9SXin Li * number of registers and prepending a dummy register to the list. 51*412f47f9SXin Li * - If alignment is attempted on a list containing r0, compilation will result 52*412f47f9SXin Li * in an error. 53*412f47f9SXin Li * - If alignment is attempted in a list containing r1, r0 will be prepended to 54*412f47f9SXin Li * the register list and r0 will be restored prior to function return. for 55*412f47f9SXin Li * functions with non-void return types, this will result in the corruption of 56*412f47f9SXin Li * the result register. 57*412f47f9SXin Li * - Stack alignment is enforced via the following helper macro call-chain: 58*412f47f9SXin Li * 59*412f47f9SXin Li * {prologue|epilogue} ->_align8 -> _preprocess_reglist -> 60*412f47f9SXin Li * _preprocess_reglist1 -> {_prologue|_epilogue} 61*412f47f9SXin Li * 62*412f47f9SXin Li * - Debug CFI directives are automatically added to prologues and epilogues, 63*412f47f9SXin Li * assisted by `cfisavelist' and `cfirestorelist', respectively. 64*412f47f9SXin Li * 65*412f47f9SXin Li * Arguments: 66*412f47f9SXin Li * prologue 67*412f47f9SXin Li * -------- 68*412f47f9SXin Li * - first - If `last' specified, this serves as start of general-purpose 69*412f47f9SXin Li * register (GPR) range to push onto stack, otherwise represents 70*412f47f9SXin Li * single GPR to push onto stack. If omitted, no GPRs pushed 71*412f47f9SXin Li * onto stack at prologue. 72*412f47f9SXin Li * - last - If given, specifies inclusive upper-bound of GPR range. 73*412f47f9SXin Li * - push_ip - Determines whether IP register is to be pushed to stack at 74*412f47f9SXin Li * prologue. When pac-signing is requested, this holds the 75*412f47f9SXin Li * the pac-key. Either 1 or 0 to push or not push, respectively. 76*412f47f9SXin Li * Default behavior: Set to value of PAC_LEAF_PUSH_IP macro. 77*412f47f9SXin Li * - push_lr - Determines whether to push lr to the stack on function entry. 78*412f47f9SXin Li * Either 1 or 0 to push or not push, respectively. 79*412f47f9SXin Li * - align8 - Whether to enforce alignment. Either 1 or 0, with 1 requesting 80*412f47f9SXin Li * alignment. 81*412f47f9SXin Li * 82*412f47f9SXin Li * epilogue 83*412f47f9SXin Li * -------- 84*412f47f9SXin Li * The epilogue should be called passing the same arguments as those passed to 85*412f47f9SXin Li * the prologue to ensure the stack is not corrupted on function return. 86*412f47f9SXin Li * 87*412f47f9SXin Li * Usage examples: 88*412f47f9SXin Li * 89*412f47f9SXin Li * prologue push_ip=1 -> push {ip} 90*412f47f9SXin Li * epilogue push_ip=1, align8=1 -> pop {r2, ip} 91*412f47f9SXin Li * prologue push_ip=1, push_lr=1 -> push {ip, lr} 92*412f47f9SXin Li * epilogue 1 -> pop {r1} 93*412f47f9SXin Li * prologue 1, align8=1 -> push {r0, r1} 94*412f47f9SXin Li * epilogue 1, push_ip=1 -> pop {r1, ip} 95*412f47f9SXin Li * prologue 1, 4 -> push {r1-r4} 96*412f47f9SXin Li * epilogue 1, 4 push_ip=1 -> pop {r1-r4, ip} 97*412f47f9SXin Li * 98*412f47f9SXin Li ******************************************************************************/ 99*412f47f9SXin Li 100*412f47f9SXin Li /* Emit .cfi_restore directives for a consecutive sequence of registers. */ 101*412f47f9SXin Li .macro cfirestorelist first, last 102*412f47f9SXin Li .cfi_restore \last 103*412f47f9SXin Li .if \last-\first 104*412f47f9SXin Li cfirestorelist \first, \last-1 105*412f47f9SXin Li .endif 106*412f47f9SXin Li .endm 107*412f47f9SXin Li 108*412f47f9SXin Li /* Emit .cfi_offset directives for a consecutive sequence of registers. */ 109*412f47f9SXin Li .macro cfisavelist first, last, index=1 110*412f47f9SXin Li .cfi_offset \last, -4*(\index) 111*412f47f9SXin Li .if \last-\first 112*412f47f9SXin Li cfisavelist \first, \last-1, \index+1 113*412f47f9SXin Li .endif 114*412f47f9SXin Li .endm 115*412f47f9SXin Li 116*412f47f9SXin Li .macro _prologue first=-1, last=-1, push_ip=PAC_LEAF_PUSH_IP, push_lr=0 117*412f47f9SXin Li .if \push_ip & 1 != \push_ip 118*412f47f9SXin Li .error "push_ip may be either 0 or 1" 119*412f47f9SXin Li .endif 120*412f47f9SXin Li .if \push_lr & 1 != \push_lr 121*412f47f9SXin Li .error "push_lr may be either 0 or 1" 122*412f47f9SXin Li .endif 123*412f47f9SXin Li .if \first != -1 124*412f47f9SXin Li .if \last == -1 125*412f47f9SXin Li /* Upper-bound not provided: Set upper = lower. */ 126*412f47f9SXin Li _prologue \first, \first, \push_ip, \push_lr 127*412f47f9SXin Li .exitm 128*412f47f9SXin Li .endif 129*412f47f9SXin Li .endif 130*412f47f9SXin Li #if HAVE_PAC_LEAF 131*412f47f9SXin Li # if __ARM_FEATURE_BTI_DEFAULT 132*412f47f9SXin Li pacbti ip, lr, sp 133*412f47f9SXin Li # else 134*412f47f9SXin Li pac ip, lr, sp 135*412f47f9SXin Li # endif /* __ARM_FEATURE_BTI_DEFAULT */ 136*412f47f9SXin Li .cfi_register 143, 12 137*412f47f9SXin Li #else 138*412f47f9SXin Li # if __ARM_FEATURE_BTI_DEFAULT 139*412f47f9SXin Li bti 140*412f47f9SXin Li # endif /* __ARM_FEATURE_BTI_DEFAULT */ 141*412f47f9SXin Li #endif /* HAVE_PAC_LEAF */ 142*412f47f9SXin Li .if \first != -1 143*412f47f9SXin Li .if \last != \first 144*412f47f9SXin Li .if \last >= 13 145*412f47f9SXin Li .error "SP cannot be in the save list" 146*412f47f9SXin Li .endif 147*412f47f9SXin Li .if \push_ip 148*412f47f9SXin Li .if \push_lr 149*412f47f9SXin Li /* Case 1: push register range, ip and lr registers. */ 150*412f47f9SXin Li push {r\first-r\last, ip, lr} 151*412f47f9SXin Li .cfi_adjust_cfa_offset ((\last-\first)+3)*4 152*412f47f9SXin Li .cfi_offset 14, -4 153*412f47f9SXin Li .cfi_offset 143, -8 154*412f47f9SXin Li cfisavelist \first, \last, 3 155*412f47f9SXin Li .else // !\push_lr 156*412f47f9SXin Li /* Case 2: push register range and ip register. */ 157*412f47f9SXin Li push {r\first-r\last, ip} 158*412f47f9SXin Li .cfi_adjust_cfa_offset ((\last-\first)+2)*4 159*412f47f9SXin Li .cfi_offset 143, -4 160*412f47f9SXin Li cfisavelist \first, \last, 2 161*412f47f9SXin Li .endif 162*412f47f9SXin Li .else // !\push_ip 163*412f47f9SXin Li .if \push_lr 164*412f47f9SXin Li /* Case 3: push register range and lr register. */ 165*412f47f9SXin Li push {r\first-r\last, lr} 166*412f47f9SXin Li .cfi_adjust_cfa_offset ((\last-\first)+2)*4 167*412f47f9SXin Li .cfi_offset 14, -4 168*412f47f9SXin Li cfisavelist \first, \last, 2 169*412f47f9SXin Li .else // !\push_lr 170*412f47f9SXin Li /* Case 4: push register range. */ 171*412f47f9SXin Li push {r\first-r\last} 172*412f47f9SXin Li .cfi_adjust_cfa_offset ((\last-\first)+1)*4 173*412f47f9SXin Li cfisavelist \first, \last, 1 174*412f47f9SXin Li .endif 175*412f47f9SXin Li .endif 176*412f47f9SXin Li .else // \last == \first 177*412f47f9SXin Li .if \push_ip 178*412f47f9SXin Li .if \push_lr 179*412f47f9SXin Li /* Case 5: push single GP register plus ip and lr registers. */ 180*412f47f9SXin Li push {r\first, ip, lr} 181*412f47f9SXin Li .cfi_adjust_cfa_offset 12 182*412f47f9SXin Li .cfi_offset 14, -4 183*412f47f9SXin Li .cfi_offset 143, -8 184*412f47f9SXin Li cfisavelist \first, \first, 3 185*412f47f9SXin Li .else // !\push_lr 186*412f47f9SXin Li /* Case 6: push single GP register plus ip register. */ 187*412f47f9SXin Li push {r\first, ip} 188*412f47f9SXin Li .cfi_adjust_cfa_offset 8 189*412f47f9SXin Li .cfi_offset 143, -4 190*412f47f9SXin Li cfisavelist \first, \first, 2 191*412f47f9SXin Li .endif 192*412f47f9SXin Li .else // !\push_ip 193*412f47f9SXin Li .if \push_lr 194*412f47f9SXin Li /* Case 7: push single GP register plus lr register. */ 195*412f47f9SXin Li push {r\first, lr} 196*412f47f9SXin Li .cfi_adjust_cfa_offset 8 197*412f47f9SXin Li .cfi_offset 14, -4 198*412f47f9SXin Li cfisavelist \first, \first, 2 199*412f47f9SXin Li .else // !\push_lr 200*412f47f9SXin Li /* Case 8: push single GP register. */ 201*412f47f9SXin Li push {r\first} 202*412f47f9SXin Li .cfi_adjust_cfa_offset 4 203*412f47f9SXin Li cfisavelist \first, \first, 1 204*412f47f9SXin Li .endif 205*412f47f9SXin Li .endif 206*412f47f9SXin Li .endif 207*412f47f9SXin Li .else // \first == -1 208*412f47f9SXin Li .if \push_ip 209*412f47f9SXin Li .if \push_lr 210*412f47f9SXin Li /* Case 9: push ip and lr registers. */ 211*412f47f9SXin Li push {ip, lr} 212*412f47f9SXin Li .cfi_adjust_cfa_offset 8 213*412f47f9SXin Li .cfi_offset 14, -4 214*412f47f9SXin Li .cfi_offset 143, -8 215*412f47f9SXin Li .else // !\push_lr 216*412f47f9SXin Li /* Case 10: push ip register. */ 217*412f47f9SXin Li push {ip} 218*412f47f9SXin Li .cfi_adjust_cfa_offset 4 219*412f47f9SXin Li .cfi_offset 143, -4 220*412f47f9SXin Li .endif 221*412f47f9SXin Li .else // !\push_ip 222*412f47f9SXin Li .if \push_lr 223*412f47f9SXin Li /* Case 11: push lr register. */ 224*412f47f9SXin Li push {lr} 225*412f47f9SXin Li .cfi_adjust_cfa_offset 4 226*412f47f9SXin Li .cfi_offset 14, -4 227*412f47f9SXin Li .endif 228*412f47f9SXin Li .endif 229*412f47f9SXin Li .endif 230*412f47f9SXin Li .endm 231*412f47f9SXin Li 232*412f47f9SXin Li .macro _epilogue first=-1, last=-1, push_ip=PAC_LEAF_PUSH_IP, push_lr=0 233*412f47f9SXin Li .if \push_ip & 1 != \push_ip 234*412f47f9SXin Li .error "push_ip may be either 0 or 1" 235*412f47f9SXin Li .endif 236*412f47f9SXin Li .if \push_lr & 1 != \push_lr 237*412f47f9SXin Li .error "push_lr may be either 0 or 1" 238*412f47f9SXin Li .endif 239*412f47f9SXin Li .if \first != -1 240*412f47f9SXin Li .if \last == -1 241*412f47f9SXin Li /* Upper-bound not provided: Set upper = lower. */ 242*412f47f9SXin Li _epilogue \first, \first, \push_ip, \push_lr 243*412f47f9SXin Li .exitm 244*412f47f9SXin Li .endif 245*412f47f9SXin Li .if \last != \first 246*412f47f9SXin Li .if \last >= 13 247*412f47f9SXin Li .error "SP cannot be in the save list" 248*412f47f9SXin Li .endif 249*412f47f9SXin Li .if \push_ip 250*412f47f9SXin Li .if \push_lr 251*412f47f9SXin Li /* Case 1: pop register range, ip and lr registers. */ 252*412f47f9SXin Li pop {r\first-r\last, ip, lr} 253*412f47f9SXin Li .cfi_restore 14 254*412f47f9SXin Li .cfi_register 143, 12 255*412f47f9SXin Li cfirestorelist \first, \last 256*412f47f9SXin Li .else // !\push_lr 257*412f47f9SXin Li /* Case 2: pop register range and ip register. */ 258*412f47f9SXin Li pop {r\first-r\last, ip} 259*412f47f9SXin Li .cfi_register 143, 12 260*412f47f9SXin Li cfirestorelist \first, \last 261*412f47f9SXin Li .endif 262*412f47f9SXin Li .else // !\push_ip 263*412f47f9SXin Li .if \push_lr 264*412f47f9SXin Li /* Case 3: pop register range and lr register. */ 265*412f47f9SXin Li pop {r\first-r\last, lr} 266*412f47f9SXin Li .cfi_restore 14 267*412f47f9SXin Li cfirestorelist \first, \last 268*412f47f9SXin Li .else // !\push_lr 269*412f47f9SXin Li /* Case 4: pop register range. */ 270*412f47f9SXin Li pop {r\first-r\last} 271*412f47f9SXin Li cfirestorelist \first, \last 272*412f47f9SXin Li .endif 273*412f47f9SXin Li .endif 274*412f47f9SXin Li .else // \last == \first 275*412f47f9SXin Li .if \push_ip 276*412f47f9SXin Li .if \push_lr 277*412f47f9SXin Li /* Case 5: pop single GP register plus ip and lr registers. */ 278*412f47f9SXin Li pop {r\first, ip, lr} 279*412f47f9SXin Li .cfi_restore 14 280*412f47f9SXin Li .cfi_register 143, 12 281*412f47f9SXin Li cfirestorelist \first, \first 282*412f47f9SXin Li .else // !\push_lr 283*412f47f9SXin Li /* Case 6: pop single GP register plus ip register. */ 284*412f47f9SXin Li pop {r\first, ip} 285*412f47f9SXin Li .cfi_register 143, 12 286*412f47f9SXin Li cfirestorelist \first, \first 287*412f47f9SXin Li .endif 288*412f47f9SXin Li .else // !\push_ip 289*412f47f9SXin Li .if \push_lr 290*412f47f9SXin Li /* Case 7: pop single GP register plus lr register. */ 291*412f47f9SXin Li pop {r\first, lr} 292*412f47f9SXin Li .cfi_restore 14 293*412f47f9SXin Li cfirestorelist \first, \first 294*412f47f9SXin Li .else // !\push_lr 295*412f47f9SXin Li /* Case 8: pop single GP register. */ 296*412f47f9SXin Li pop {r\first} 297*412f47f9SXin Li cfirestorelist \first, \first 298*412f47f9SXin Li .endif 299*412f47f9SXin Li .endif 300*412f47f9SXin Li .endif 301*412f47f9SXin Li .else // \first == -1 302*412f47f9SXin Li .if \push_ip 303*412f47f9SXin Li .if \push_lr 304*412f47f9SXin Li /* Case 9: pop ip and lr registers. */ 305*412f47f9SXin Li pop {ip, lr} 306*412f47f9SXin Li .cfi_restore 14 307*412f47f9SXin Li .cfi_register 143, 12 308*412f47f9SXin Li .else // !\push_lr 309*412f47f9SXin Li /* Case 10: pop ip register. */ 310*412f47f9SXin Li pop {ip} 311*412f47f9SXin Li .cfi_register 143, 12 312*412f47f9SXin Li .endif 313*412f47f9SXin Li .else // !\push_ip 314*412f47f9SXin Li .if \push_lr 315*412f47f9SXin Li /* Case 11: pop lr register. */ 316*412f47f9SXin Li pop {lr} 317*412f47f9SXin Li .cfi_restore 14 318*412f47f9SXin Li .endif 319*412f47f9SXin Li .endif 320*412f47f9SXin Li .endif 321*412f47f9SXin Li #if HAVE_PAC_LEAF 322*412f47f9SXin Li aut ip, lr, sp 323*412f47f9SXin Li #endif /* HAVE_PAC_LEAF */ 324*412f47f9SXin Li bx lr 325*412f47f9SXin Li .endm 326*412f47f9SXin Li 327*412f47f9SXin Li /* Clean up expressions in 'last'. */ 328*412f47f9SXin Li .macro _preprocess_reglist1 first:req, last:req, push_ip:req, push_lr:req, reglist_op:req 329*412f47f9SXin Li .if \last == 0 330*412f47f9SXin Li \reglist_op \first, 0, \push_ip, \push_lr 331*412f47f9SXin Li .elseif \last == 1 332*412f47f9SXin Li \reglist_op \first, 1, \push_ip, \push_lr 333*412f47f9SXin Li .elseif \last == 2 334*412f47f9SXin Li \reglist_op \first, 2, \push_ip, \push_lr 335*412f47f9SXin Li .elseif \last == 3 336*412f47f9SXin Li \reglist_op \first, 3, \push_ip, \push_lr 337*412f47f9SXin Li .elseif \last == 4 338*412f47f9SXin Li \reglist_op \first, 4, \push_ip, \push_lr 339*412f47f9SXin Li .elseif \last == 5 340*412f47f9SXin Li \reglist_op \first, 5, \push_ip, \push_lr 341*412f47f9SXin Li .elseif \last == 6 342*412f47f9SXin Li \reglist_op \first, 6, \push_ip, \push_lr 343*412f47f9SXin Li .elseif \last == 7 344*412f47f9SXin Li \reglist_op \first, 7, \push_ip, \push_lr 345*412f47f9SXin Li .elseif \last == 8 346*412f47f9SXin Li \reglist_op \first, 8, \push_ip, \push_lr 347*412f47f9SXin Li .elseif \last == 9 348*412f47f9SXin Li \reglist_op \first, 9, \push_ip, \push_lr 349*412f47f9SXin Li .elseif \last == 10 350*412f47f9SXin Li \reglist_op \first, 10, \push_ip, \push_lr 351*412f47f9SXin Li .elseif \last == 11 352*412f47f9SXin Li \reglist_op \first, 11, \push_ip, \push_lr 353*412f47f9SXin Li .else 354*412f47f9SXin Li .error "last (\last) out of range" 355*412f47f9SXin Li .endif 356*412f47f9SXin Li .endm 357*412f47f9SXin Li 358*412f47f9SXin Li /* Clean up expressions in 'first'. */ 359*412f47f9SXin Li .macro _preprocess_reglist first:req, last, push_ip=0, push_lr=0, reglist_op:req 360*412f47f9SXin Li .ifb \last 361*412f47f9SXin Li _preprocess_reglist \first \first \push_ip \push_lr 362*412f47f9SXin Li .else 363*412f47f9SXin Li .if \first > \last 364*412f47f9SXin Li .error "last (\last) must be at least as great as first (\first)" 365*412f47f9SXin Li .endif 366*412f47f9SXin Li .if \first == 0 367*412f47f9SXin Li _preprocess_reglist1 0, \last, \push_ip, \push_lr, \reglist_op 368*412f47f9SXin Li .elseif \first == 1 369*412f47f9SXin Li _preprocess_reglist1 1, \last, \push_ip, \push_lr, \reglist_op 370*412f47f9SXin Li .elseif \first == 2 371*412f47f9SXin Li _preprocess_reglist1 2, \last, \push_ip, \push_lr, \reglist_op 372*412f47f9SXin Li .elseif \first == 3 373*412f47f9SXin Li _preprocess_reglist1 3, \last, \push_ip, \push_lr, \reglist_op 374*412f47f9SXin Li .elseif \first == 4 375*412f47f9SXin Li _preprocess_reglist1 4, \last, \push_ip, \push_lr, \reglist_op 376*412f47f9SXin Li .elseif \first == 5 377*412f47f9SXin Li _preprocess_reglist1 5, \last, \push_ip, \push_lr, \reglist_op 378*412f47f9SXin Li .elseif \first == 6 379*412f47f9SXin Li _preprocess_reglist1 6, \last, \push_ip, \push_lr, \reglist_op 380*412f47f9SXin Li .elseif \first == 7 381*412f47f9SXin Li _preprocess_reglist1 7, \last, \push_ip, \push_lr, \reglist_op 382*412f47f9SXin Li .elseif \first == 8 383*412f47f9SXin Li _preprocess_reglist1 8, \last, \push_ip, \push_lr, \reglist_op 384*412f47f9SXin Li .elseif \first == 9 385*412f47f9SXin Li _preprocess_reglist1 9, \last, \push_ip, \push_lr, \reglist_op 386*412f47f9SXin Li .elseif \first == 10 387*412f47f9SXin Li _preprocess_reglist1 10, \last, \push_ip, \push_lr, \reglist_op 388*412f47f9SXin Li .elseif \first == 11 389*412f47f9SXin Li _preprocess_reglist1 11, \last, \push_ip, \push_lr, \reglist_op 390*412f47f9SXin Li .else 391*412f47f9SXin Li .error "first (\first) out of range" 392*412f47f9SXin Li .endif 393*412f47f9SXin Li .endif 394*412f47f9SXin Li .endm 395*412f47f9SXin Li 396*412f47f9SXin Li .macro _align8 first, last, push_ip=0, push_lr=0, reglist_op=_prologue 397*412f47f9SXin Li .ifb \first 398*412f47f9SXin Li .ifnb \last 399*412f47f9SXin Li .error "can't have last (\last) without specifying first" 400*412f47f9SXin Li .else // \last not blank 401*412f47f9SXin Li .if ((\push_ip + \push_lr) % 2) == 0 402*412f47f9SXin Li \reglist_op first=-1, last=-1, push_ip=\push_ip, push_lr=\push_lr 403*412f47f9SXin Li .exitm 404*412f47f9SXin Li .else // ((\push_ip + \push_lr) % 2) odd 405*412f47f9SXin Li _align8 2, 2, \push_ip, \push_lr, \reglist_op 406*412f47f9SXin Li .exitm 407*412f47f9SXin Li .endif // ((\push_ip + \push_lr) % 2) == 0 408*412f47f9SXin Li .endif // .ifnb \last 409*412f47f9SXin Li .endif // .ifb \first 410*412f47f9SXin Li 411*412f47f9SXin Li .ifb \last 412*412f47f9SXin Li _align8 \first, \first, \push_ip, \push_lr, \reglist_op 413*412f47f9SXin Li .else 414*412f47f9SXin Li .if \push_ip & 1 <> \push_ip 415*412f47f9SXin Li .error "push_ip may be 0 or 1" 416*412f47f9SXin Li .endif 417*412f47f9SXin Li .if \push_lr & 1 <> \push_lr 418*412f47f9SXin Li .error "push_lr may be 0 or 1" 419*412f47f9SXin Li .endif 420*412f47f9SXin Li .ifeq (\last - \first + \push_ip + \push_lr) % 2 421*412f47f9SXin Li .if \first == 0 422*412f47f9SXin Li .error "Alignment required and first register is r0" 423*412f47f9SXin Li .exitm 424*412f47f9SXin Li .endif 425*412f47f9SXin Li _preprocess_reglist \first-1, \last, \push_ip, \push_lr, \reglist_op 426*412f47f9SXin Li .else 427*412f47f9SXin Li _preprocess_reglist \first \last, \push_ip, \push_lr, \reglist_op 428*412f47f9SXin Li .endif 429*412f47f9SXin Li .endif 430*412f47f9SXin Li .endm 431*412f47f9SXin Li 432*412f47f9SXin Li .macro prologue first, last, push_ip=PAC_LEAF_PUSH_IP, push_lr=0, align8=STACK_ALIGN_ENFORCE 433*412f47f9SXin Li .if \align8 434*412f47f9SXin Li _align8 \first, \last, \push_ip, \push_lr, _prologue 435*412f47f9SXin Li .else 436*412f47f9SXin Li _prologue first=\first, last=\last, push_ip=\push_ip, push_lr=\push_lr 437*412f47f9SXin Li .endif 438*412f47f9SXin Li .endm 439*412f47f9SXin Li 440*412f47f9SXin Li .macro epilogue first, last, push_ip=PAC_LEAF_PUSH_IP, push_lr=0, align8=STACK_ALIGN_ENFORCE 441*412f47f9SXin Li .if \align8 442*412f47f9SXin Li _align8 \first, \last, \push_ip, \push_lr, reglist_op=_epilogue 443*412f47f9SXin Li .else 444*412f47f9SXin Li _epilogue first=\first, last=\last, push_ip=\push_ip, push_lr=\push_lr 445*412f47f9SXin Li .endif 446*412f47f9SXin Li .endm 447*412f47f9SXin Li 448*412f47f9SXin Li #define ENTRY_ALIGN(name, alignment) \ 449*412f47f9SXin Li .global name; \ 450*412f47f9SXin Li .type name,%function; \ 451*412f47f9SXin Li .align alignment; \ 452*412f47f9SXin Li name: \ 453*412f47f9SXin Li .fnstart; \ 454*412f47f9SXin Li .cfi_startproc; 455*412f47f9SXin Li 456*412f47f9SXin Li #define ENTRY(name) ENTRY_ALIGN(name, 6) 457*412f47f9SXin Li 458*412f47f9SXin Li #define ENTRY_ALIAS(name) \ 459*412f47f9SXin Li .global name; \ 460*412f47f9SXin Li .type name,%function; \ 461*412f47f9SXin Li name: 462*412f47f9SXin Li 463*412f47f9SXin Li #if defined (IS_LEAF) 464*412f47f9SXin Li # define END_UNWIND .cantunwind; 465*412f47f9SXin Li #else 466*412f47f9SXin Li # define END_UNWIND 467*412f47f9SXin Li #endif 468*412f47f9SXin Li 469*412f47f9SXin Li #define END(name) \ 470*412f47f9SXin Li .cfi_endproc; \ 471*412f47f9SXin Li END_UNWIND \ 472*412f47f9SXin Li .fnend; \ 473*412f47f9SXin Li .size name, .-name; 474*412f47f9SXin Li 475*412f47f9SXin Li #define L(l) .L ## l 476*412f47f9SXin Li 477*412f47f9SXin Li #endif 478