1// -*- Mode: asm; -*- 2// 3// Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. 4// 5// Use of this source code is governed by a BSD-style license 6// that can be found in the LICENSE file in the root of the source 7// tree. An additional intellectual property rights grant can be found 8// in the file PATENTS. All contributing project authors may 9// be found in the AUTHORS file in the root of the source tree. 10// 11// This file was originally licensed as follows. It has been 12// relicensed with permission from the copyright holders. 13// 14 15// 16// File Name: armCOMM_s.h 17// OpenMAX DL: v1.0.2 18// Last Modified Revision: 13871 19// Last Modified Date: Fri, 09 May 2008 20// 21// (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. 22// 23// 24// 25// ARM optimized OpenMAX common header file 26// 27 28 .set _SBytes, 0 // Number of scratch bytes on stack 29 .set _Workspace, 0 // Stack offset of scratch workspace 30 31 .set _RRegList, 0 // R saved register list (last register number) 32 .set _DRegList, 0 // D saved register list (last register number) 33 34 // Work out list of D saved registers, like for R registers. 35 .macro _M_GETDREGLIST dreg 36 .ifeqs "\dreg", "" 37 .set _DRegList, 0 38 .exitm 39 .endif 40 41 .ifeqs "\dreg", "d8" 42 .set _DRegList, 8 43 .exitm 44 .endif 45 46 .ifeqs "\dreg", "d9" 47 .set _DRegList, 9 48 .exitm 49 .endif 50 51 .ifeqs "\dreg", "d10" 52 .set _DRegList, 10 53 .exitm 54 .endif 55 56 .ifeqs "\dreg", "d11" 57 .set _DRegList, 11 58 .exitm 59 .endif 60 61 .ifeqs "\dreg", "d12" 62 .set _DRegList, 12 63 .exitm 64 .endif 65 66 .ifeqs "\dreg", "d13" 67 .set _DRegList, 13 68 .exitm 69 .endif 70 71 .ifeqs "\dreg", "d14" 72 .set _DRegList, 14 73 .exitm 74 .endif 75 76 .ifeqs "\dreg", "d15" 77 .set _DRegList, 15 78 .exitm 79 .endif 80 81 .warning "Unrecognized saved d register limit: \rreg" 82 .endm 83 84////////////////////////////////////////////////////////// 85// Function header and footer macros 86////////////////////////////////////////////////////////// 87 88 // Function Header Macro 89 // Generates the function prologue 90 // Note that functions should all be "stack-moves-once" 91 // The FNSTART and FNEND macros should be the only places 92 // where the stack moves. 93 // 94 // name = function name 95 // rreg = "" don't stack any registers 96 // "lr" stack "lr" only 97 // "rN" stack registers "r4-rN,lr" 98 // dreg = "" don't stack any D registers 99 // "dN" stack registers "d8-dN" 100 // 101 // Note: ARM Archicture procedure call standard AAPCS 102 // states that r4-r11, sp, d8-d15 must be preserved by 103 // a compliant function. 104 .macro M_START name, rreg, dreg 105 .set _Workspace, 0 106 107 // Define the function and make it external. 108 .global \name 109 .section .text.\name,"ax",%progbits 110 .align 4 111\name : 112//.fnstart 113 // Save specified R registers 114 _M_PUSH_RREG 115 116 // Save specified D registers 117 _M_GETDREGLIST \dreg 118 _M_PUSH_DREG 119 120 // Ensure size claimed on stack is 16-byte aligned for ARM64 121 .if (_SBytes & 15) != 0 122 .set _SBytes, _SBytes + (16 - (_SBytes & 15)) 123 .endif 124 .if _SBytes != 0 125 sub sp, sp, #_SBytes 126 .endif 127 .endm 128 129 // Function Footer Macro 130 // Generates the function epilogue 131 .macro M_END 132 // Restore the stack pointer to its original value on function entry 133 .if _SBytes != 0 134 add sp, sp, #_SBytes 135 .endif 136 // Restore any saved R or D registers. 137 _M_RET 138 //.fnend 139 // Reset the global stack tracking variables back to their 140 // initial values. 141 .set _SBytes, 0 142 .endm 143 144 // Based on the value of _DRegList, push the specified set of registers 145 // to the stack. 146 // The ARM64 ABI says only v8-v15 needs to be saved across calls and only 147 // the lower 64 bits need to be saved. 148 .macro _M_PUSH_DREG 149 .if _DRegList >= 8 150 sub sp, sp, (_DRegList - 7) * 16 // 16-byte alignment 151 str q8, [sp] 152 .endif 153 154 .if _DRegList >= 9 155 str q9, [sp, #16] 156 .endif 157 158 .if _DRegList >= 10 159 str q10, [sp, #32] 160 .endif 161 162 .if _DRegList >= 11 163 str q11, [sp, #48] 164 .endif 165 166 .if _DRegList >= 12 167 str q12, [sp, #64] 168 .endif 169 170 .if _DRegList >= 13 171 str q13, [sp, #80] 172 .endif 173 174 .if _DRegList >= 14 175 str q14, [sp, #96] 176 .endif 177 178 .if _DRegList >= 15 179 str q15, [sp, #112] 180 .endif 181 182 .exitm 183 .endm 184 185 // Based on the value of _RRegList, push the specified set of registers 186 // to the stack. 187 // The ARM64 ABI says registers r19-r29 needs to be saved across calls. 188 // But for the FFT routines, we don't need to save anything, so just 189 // preserve the SP and LR. 190 .macro _M_PUSH_RREG 191 sub sp, sp, #16 192 str x30, [sp] 193 str x29, [sp, #8] 194 .exitm 195 .endm 196 197 // The opposite of _M_PUSH_DREG 198 .macro _M_POP_DREG 199 .if _DRegList >= 8 200 ldr q8, [sp] 201 .endif 202 203 .if _DRegList >= 9 204 ldr q9, [sp, #16] 205 .endif 206 207 .if _DRegList >= 10 208 ldr q10, [sp, #32] 209 .endif 210 211 .if _DRegList >= 11 212 ldr q11, [sp, #48] 213 .endif 214 215 .if _DRegList >= 12 216 ldr q12, [sp, #64] 217 .endif 218 219 .if _DRegList >= 13 220 ldr q13, [sp, #80] 221 .endif 222 223 .if _DRegList >= 14 224 ldr q14, [sp, #96] 225 .endif 226 227 .if _DRegList >= 15 228 ldr q15, [sp, #112] 229 .endif 230 231 .if _DRegList >= 8 232 add sp, sp, (_DRegList - 7) * 16 // 16-byte alignment 233 .endif 234 .exitm 235 .endm 236 237 // The opposite of _M_PUSH_RREG 238 .macro _M_POP_RREG cc 239 ldr x29, [sp, #8] 240 ldr x30, [sp] 241 add sp, sp, #16 242 .exitm 243 .endm 244 245 // Produce function return instructions 246 .macro _M_RET cc 247 _M_POP_DREG \cc 248 _M_POP_RREG \cc 249 ret 250 .endm 251 // rsb - reverse subtract 252 // compute dst = src2 - src1, useful when src2 is an immediate value 253 .macro rsb dst, src1, src2 254 sub \dst, \src1, \src2 255 neg \dst, \dst 256 .endm 257