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