Home | History | Annotate | Download | only in arm
      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