Merge commit '5584abf69d83169a010aca404cd1cf95c23ad9ef'
[ffmpeg.git] / libavutil / arm / asm.S
1 /*
2  * Copyright (c) 2008 Mans Rullgard <mans@mansr.com>
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20
21 #include "config.h"
22
23 #ifdef __ELF__
24 #   define ELF
25 #else
26 #   define ELF @
27 #endif
28
29 #if CONFIG_THUMB
30 #   define A @
31 #   define T
32 #else
33 #   define A
34 #   define T @
35 #endif
36
37 #if HAVE_AS_FUNC
38 #   define FUNC
39 #else
40 #   define FUNC @
41 #endif
42
43 #if HAVE_AS_FPU_DIRECTIVE
44 #   define FPU
45 #else
46 #   define FPU @
47 #endif
48
49 #if CONFIG_THUMB && defined(__APPLE__)
50 #   define TFUNC
51 #else
52 #   define TFUNC @
53 #endif
54
55 #if HAVE_AS_ARCH_DIRECTIVE
56 #if   HAVE_NEON
57         .arch           armv7-a
58 #elif HAVE_ARMV6T2
59         .arch           armv6t2
60 #elif HAVE_ARMV6
61         .arch           armv6
62 #elif HAVE_ARMV5TE
63         .arch           armv5te
64 #endif
65 #endif
66 #if   HAVE_AS_OBJECT_ARCH
67 ELF     .object_arch    armv4
68 #endif
69
70 #if   HAVE_NEON
71 FPU     .fpu            neon
72 ELF     .eabi_attribute 10, 0           @ suppress Tag_FP_arch
73 ELF     .eabi_attribute 12, 0           @ suppress Tag_Advanced_SIMD_arch
74 #elif HAVE_VFP
75 FPU     .fpu            vfp
76 ELF     .eabi_attribute 10, 0           @ suppress Tag_FP_arch
77 #endif
78
79         .syntax unified
80 T       .thumb
81 ELF     .eabi_attribute 25, 1           @ Tag_ABI_align_preserved
82 ELF     .section .note.GNU-stack,"",%progbits @ Mark stack as non-executable
83
84 .macro  function name, export=0, align=2
85         .set            .Lpic_idx, 0
86         .set            .Lpic_gp, 0
87     .macro endfunc
88       .if .Lpic_idx
89         .align          2
90         .altmacro
91         put_pic         %(.Lpic_idx - 1)
92         .noaltmacro
93       .endif
94       .if .Lpic_gp
95         .unreq          gp
96       .endif
97 ELF     .size   \name, . - \name
98 FUNC    .endfunc
99         .purgem endfunc
100     .endm
101         .text
102         .align          \align
103     .if \export
104         .global EXTERN_ASM\name
105 ELF     .type   EXTERN_ASM\name, %function
106 FUNC    .func   EXTERN_ASM\name
107 TFUNC   .thumb_func EXTERN_ASM\name
108 EXTERN_ASM\name:
109     .else
110 ELF     .type   \name, %function
111 FUNC    .func   \name
112 TFUNC   .thumb_func \name
113 \name:
114     .endif
115 .endm
116
117 .macro  const   name, align=2, relocate=0
118     .macro endconst
119 ELF     .size   \name, . - \name
120         .purgem endconst
121     .endm
122 #if HAVE_SECTION_DATA_REL_RO
123 .if \relocate
124         .section        .data.rel.ro
125 .else
126         .section        .rodata
127 .endif
128 #elif !defined(__MACH__)
129         .section        .rodata
130 #else
131         .const_data
132 #endif
133         .align          \align
134 \name:
135 .endm
136
137 #if !HAVE_ARMV6T2_EXTERNAL
138 .macro  movw    rd, val
139         mov     \rd, \val &  255
140         orr     \rd, \val & ~255
141 .endm
142 #endif
143
144 .macro  mov32   rd, val
145 #if HAVE_ARMV6T2_EXTERNAL
146         movw            \rd, #(\val) & 0xffff
147     .if (\val) >> 16
148         movt            \rd, #(\val) >> 16
149     .endif
150 #else
151         ldr             \rd, =\val
152 #endif
153 .endm
154
155 .macro  put_pic         num
156         put_pic_\num
157 .endm
158
159 .macro  do_def_pic      num, val, label
160     .macro put_pic_\num
161       .if \num
162         .altmacro
163         put_pic         %(\num - 1)
164         .noaltmacro
165       .endif
166 \label: .word           \val
167         .purgem         put_pic_\num
168     .endm
169 .endm
170
171 .macro  def_pic         val, label
172         .altmacro
173         do_def_pic      %.Lpic_idx, \val, \label
174         .noaltmacro
175         .set            .Lpic_idx, .Lpic_idx + 1
176 .endm
177
178 .macro  ldpic           rd,  val, indir=0
179         ldr             \rd, .Lpicoff\@
180 .Lpic\@:
181     .if \indir
182 A       ldr             \rd, [pc, \rd]
183 T       add             \rd, pc
184 T       ldr             \rd, [\rd]
185     .else
186         add             \rd, pc
187     .endif
188         def_pic         \val - (.Lpic\@ + (8 >> CONFIG_THUMB)), .Lpicoff\@
189 .endm
190
191 .macro  movrel rd, val
192 #if CONFIG_PIC
193         ldpic           \rd, \val
194 #elif HAVE_ARMV6T2_EXTERNAL && !defined(__APPLE__)
195         movw            \rd, #:lower16:\val
196         movt            \rd, #:upper16:\val
197 #else
198         ldr             \rd, =\val
199 #endif
200 .endm
201
202 .macro  movrelx         rd,  val, gp
203     .ifc \rd,\gp
204         .error      "movrelx needs two distinct registers"
205     .endif
206     .ifc \rd\()_\gp,r12_
207         .warning    "movrelx rd=\rd without explicit set gp"
208     .endif
209     .ifc \rd\()_\gp,ip_
210         .warning    "movrelx rd=\rd without explicit set gp"
211     .endif
212 #if CONFIG_PIC && defined(__ELF__)
213     .ifnb \gp
214       .if .Lpic_gp
215         .unreq          gp
216       .endif
217         gp      .req    \gp
218         ldpic           gp,  _GLOBAL_OFFSET_TABLE_
219     .elseif !.Lpic_gp
220         gp      .req    r12
221         ldpic           gp,  _GLOBAL_OFFSET_TABLE_
222     .endif
223         .set            .Lpic_gp, 1
224         ldr             \rd, .Lpicoff\@
225         ldr             \rd, [gp, \rd]
226         def_pic         \val(GOT), .Lpicoff\@
227 #elif CONFIG_PIC && defined(__APPLE__)
228         ldpic           \rd, .Lpic\@, indir=1
229         .non_lazy_symbol_pointer
230 .Lpic\@:
231         .indirect_symbol \val
232         .word           0
233         .text
234 #else
235         movrel          \rd, \val
236 #endif
237 .endm
238
239 .macro  add_sh          rd,  rn,  rm,  sh:vararg
240 A       add             \rd, \rn, \rm, \sh
241 T       mov             \rm, \rm, \sh
242 T       add             \rd, \rn, \rm
243 .endm
244
245 .macro  ldr_pre         rt,  rn,  rm:vararg
246 A       ldr             \rt, [\rn, \rm]!
247 T       add             \rn, \rn, \rm
248 T       ldr             \rt, [\rn]
249 .endm
250
251 .macro  ldr_dpre        rt,  rn,  rm:vararg
252 A       ldr             \rt, [\rn, -\rm]!
253 T       sub             \rn, \rn, \rm
254 T       ldr             \rt, [\rn]
255 .endm
256
257 .macro  ldr_nreg        rt,  rn,  rm:vararg
258 A       ldr             \rt, [\rn, -\rm]
259 T       sub             \rt, \rn, \rm
260 T       ldr             \rt, [\rt]
261 .endm
262
263 .macro  ldr_post        rt,  rn,  rm:vararg
264 A       ldr             \rt, [\rn], \rm
265 T       ldr             \rt, [\rn]
266 T       add             \rn, \rn, \rm
267 .endm
268
269 .macro  ldrc_pre        cc,  rt,  rn,  rm:vararg
270 A       ldr\cc          \rt, [\rn, \rm]!
271 T       itt             \cc
272 T       add\cc          \rn, \rn, \rm
273 T       ldr\cc          \rt, [\rn]
274 .endm
275
276 .macro  ldrd_reg        rt,  rt2, rn,  rm
277 A       ldrd            \rt, \rt2, [\rn, \rm]
278 T       add             \rt, \rn, \rm
279 T       ldrd            \rt, \rt2, [\rt]
280 .endm
281
282 .macro  ldrd_post       rt,  rt2, rn,  rm
283 A       ldrd            \rt, \rt2, [\rn], \rm
284 T       ldrd            \rt, \rt2, [\rn]
285 T       add             \rn, \rn, \rm
286 .endm
287
288 .macro  ldrh_pre        rt,  rn,  rm
289 A       ldrh            \rt, [\rn, \rm]!
290 T       add             \rn, \rn, \rm
291 T       ldrh            \rt, [\rn]
292 .endm
293
294 .macro  ldrh_dpre       rt,  rn,  rm
295 A       ldrh            \rt, [\rn, -\rm]!
296 T       sub             \rn, \rn, \rm
297 T       ldrh            \rt, [\rn]
298 .endm
299
300 .macro  ldrh_post       rt,  rn,  rm
301 A       ldrh            \rt, [\rn], \rm
302 T       ldrh            \rt, [\rn]
303 T       add             \rn, \rn, \rm
304 .endm
305
306 .macro  ldrb_post       rt,  rn,  rm
307 A       ldrb            \rt, [\rn], \rm
308 T       ldrb            \rt, [\rn]
309 T       add             \rn, \rn, \rm
310 .endm
311
312 .macro  str_post       rt,  rn,  rm:vararg
313 A       str             \rt, [\rn], \rm
314 T       str             \rt, [\rn]
315 T       add             \rn, \rn, \rm
316 .endm
317
318 .macro  strb_post       rt,  rn,  rm:vararg
319 A       strb            \rt, [\rn], \rm
320 T       strb            \rt, [\rn]
321 T       add             \rn, \rn, \rm
322 .endm
323
324 .macro  strd_post       rt,  rt2, rn,  rm
325 A       strd            \rt, \rt2, [\rn], \rm
326 T       strd            \rt, \rt2, [\rn]
327 T       add             \rn, \rn, \rm
328 .endm
329
330 .macro  strh_pre        rt,  rn,  rm
331 A       strh            \rt, [\rn, \rm]!
332 T       add             \rn, \rn, \rm
333 T       strh            \rt, [\rn]
334 .endm
335
336 .macro  strh_dpre       rt,  rn,  rm
337 A       strh            \rt, [\rn, -\rm]!
338 T       sub             \rn, \rn, \rm
339 T       strh            \rt, [\rn]
340 .endm
341
342 .macro  strh_post       rt,  rn,  rm
343 A       strh            \rt, [\rn], \rm
344 T       strh            \rt, [\rn]
345 T       add             \rn, \rn, \rm
346 .endm
347
348 .macro  strh_dpost       rt,  rn,  rm
349 A       strh            \rt, [\rn], -\rm
350 T       strh            \rt, [\rn]
351 T       sub             \rn, \rn, \rm
352 .endm
353
354 #if HAVE_VFP_ARGS
355 ELF     .eabi_attribute 28, 1
356 #   define VFP
357 #   define NOVFP @
358 #else
359 #   define VFP   @
360 #   define NOVFP
361 #endif
362
363 #define GLUE(a, b) a ## b
364 #define JOIN(a, b) GLUE(a, b)
365 #define X(s) JOIN(EXTERN_ASM, s)