Merge commit '3a7b4ae62c798edbd82bcd8fef863c74ed2acd4a'
[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 HAVE_AS_ARCH_DIRECTIVE
50 #if   HAVE_NEON
51         .arch           armv7-a
52 #elif HAVE_ARMV6T2
53         .arch           armv6t2
54 #elif HAVE_ARMV6
55         .arch           armv6
56 #elif HAVE_ARMV5TE
57         .arch           armv5te
58 #endif
59 #endif
60 #if   HAVE_AS_OBJECT_ARCH
61 ELF     .object_arch    armv4
62 #endif
63
64 #if   HAVE_NEON
65 FPU     .fpu            neon
66 ELF     .eabi_attribute 10, 0           @ suppress Tag_FP_arch
67 ELF     .eabi_attribute 12, 0           @ suppress Tag_Advanced_SIMD_arch
68 #elif HAVE_VFP
69 FPU     .fpu            vfp
70 ELF     .eabi_attribute 10, 0           @ suppress Tag_FP_arch
71 #endif
72
73         .syntax unified
74 T       .thumb
75 ELF     .eabi_attribute 25, 1           @ Tag_ABI_align_preserved
76 ELF     .section .note.GNU-stack,"",%progbits @ Mark stack as non-executable
77
78 .macro  function name, export=0, align=2
79         .set            .Lpic_idx, 0
80         .set            .Lpic_gp, 0
81     .macro endfunc
82       .if .Lpic_idx
83         .align          2
84         .altmacro
85         put_pic         %(.Lpic_idx - 1)
86         .noaltmacro
87       .endif
88       .if .Lpic_gp
89         .unreq          gp
90       .endif
91 ELF     .size   \name, . - \name
92 FUNC    .endfunc
93         .purgem endfunc
94     .endm
95         .text
96         .align          \align
97     .if \export
98         .global EXTERN_ASM\name
99 ELF     .type   EXTERN_ASM\name, %function
100 FUNC    .func   EXTERN_ASM\name
101 EXTERN_ASM\name:
102     .else
103 ELF     .type   \name, %function
104 FUNC    .func   \name
105 \name:
106     .endif
107 .endm
108
109 .macro  const   name, align=2, relocate=0
110     .macro endconst
111 ELF     .size   \name, . - \name
112         .purgem endconst
113     .endm
114 #if HAVE_SECTION_DATA_REL_RO
115 .if \relocate
116         .section        .data.rel.ro
117 .else
118         .section        .rodata
119 .endif
120 #elif !defined(__MACH__)
121         .section        .rodata
122 #else
123         .const_data
124 #endif
125         .align          \align
126 \name:
127 .endm
128
129 #if !HAVE_ARMV6T2_EXTERNAL
130 .macro  movw    rd, val
131         mov     \rd, \val &  255
132         orr     \rd, \val & ~255
133 .endm
134 #endif
135
136 .macro  mov32   rd, val
137 #if HAVE_ARMV6T2_EXTERNAL
138         movw            \rd, #(\val) & 0xffff
139     .if (\val) >> 16
140         movt            \rd, #(\val) >> 16
141     .endif
142 #else
143         ldr             \rd, =\val
144 #endif
145 .endm
146
147 .macro  put_pic         num
148         put_pic_\num
149 .endm
150
151 .macro  do_def_pic      num, val, label
152     .macro put_pic_\num
153       .if \num
154         .altmacro
155         put_pic         %(\num - 1)
156         .noaltmacro
157       .endif
158 \label: .word           \val
159         .purgem         put_pic_\num
160     .endm
161 .endm
162
163 .macro  def_pic         val, label
164         .altmacro
165         do_def_pic      %.Lpic_idx, \val, \label
166         .noaltmacro
167         .set            .Lpic_idx, .Lpic_idx + 1
168 .endm
169
170 .macro  ldpic           rd,  val, indir=0
171         ldr             \rd, .Lpicoff\@
172 .Lpic\@:
173     .if \indir
174 A       ldr             \rd, [pc, \rd]
175 T       add             \rd, pc
176 T       ldr             \rd, [\rd]
177     .else
178         add             \rd, pc
179     .endif
180         def_pic         \val - (.Lpic\@ + (8 >> CONFIG_THUMB)), .Lpicoff\@
181 .endm
182
183 .macro  movrel rd, val
184 #if CONFIG_PIC
185         ldpic           \rd, \val
186 #elif HAVE_ARMV6T2_EXTERNAL && !defined(__APPLE__)
187         movw            \rd, #:lower16:\val
188         movt            \rd, #:upper16:\val
189 #else
190         ldr             \rd, =\val
191 #endif
192 .endm
193
194 .macro  movrelx         rd,  val, gp
195     .ifc \rd,\gp
196         .error      "movrelx needs two distinct registers"
197     .endif
198     .ifc \rd\()_\gp,r12_
199         .warning    "movrelx rd=\rd without explicit set gp"
200     .endif
201     .ifc \rd\()_\gp,ip_
202         .warning    "movrelx rd=\rd without explicit set gp"
203     .endif
204 #if CONFIG_PIC && defined(__ELF__)
205     .ifnb \gp
206       .if .Lpic_gp
207         .unreq          gp
208       .endif
209         gp      .req    \gp
210         ldpic           gp,  _GLOBAL_OFFSET_TABLE_
211     .elseif !.Lpic_gp
212         gp      .req    r12
213         ldpic           gp,  _GLOBAL_OFFSET_TABLE_
214     .endif
215         .set            .Lpic_gp, 1
216         ldr             \rd, .Lpicoff\@
217         ldr             \rd, [gp, \rd]
218         def_pic         \val(GOT), .Lpicoff\@
219 #elif CONFIG_PIC && defined(__APPLE__)
220         ldpic           \rd, .Lpic\@, indir=1
221         .non_lazy_symbol_pointer
222 .Lpic\@:
223         .indirect_symbol \val
224         .word           0
225         .text
226 #else
227         movrel          \rd, \val
228 #endif
229 .endm
230
231 .macro  add_sh          rd,  rn,  rm,  sh:vararg
232 A       add             \rd, \rn, \rm, \sh
233 T       mov             \rm, \rm, \sh
234 T       add             \rd, \rn, \rm
235 .endm
236
237 .macro  ldr_pre         rt,  rn,  rm:vararg
238 A       ldr             \rt, [\rn, \rm]!
239 T       add             \rn, \rn, \rm
240 T       ldr             \rt, [\rn]
241 .endm
242
243 .macro  ldr_dpre        rt,  rn,  rm:vararg
244 A       ldr             \rt, [\rn, -\rm]!
245 T       sub             \rn, \rn, \rm
246 T       ldr             \rt, [\rn]
247 .endm
248
249 .macro  ldr_nreg        rt,  rn,  rm:vararg
250 A       ldr             \rt, [\rn, -\rm]
251 T       sub             \rt, \rn, \rm
252 T       ldr             \rt, [\rt]
253 .endm
254
255 .macro  ldr_post        rt,  rn,  rm:vararg
256 A       ldr             \rt, [\rn], \rm
257 T       ldr             \rt, [\rn]
258 T       add             \rn, \rn, \rm
259 .endm
260
261 .macro  ldrc_pre        cc,  rt,  rn,  rm:vararg
262 A       ldr\cc          \rt, [\rn, \rm]!
263 T       itt             \cc
264 T       add\cc          \rn, \rn, \rm
265 T       ldr\cc          \rt, [\rn]
266 .endm
267
268 .macro  ldrd_reg        rt,  rt2, rn,  rm
269 A       ldrd            \rt, \rt2, [\rn, \rm]
270 T       add             \rt, \rn, \rm
271 T       ldrd            \rt, \rt2, [\rt]
272 .endm
273
274 .macro  ldrd_post       rt,  rt2, rn,  rm
275 A       ldrd            \rt, \rt2, [\rn], \rm
276 T       ldrd            \rt, \rt2, [\rn]
277 T       add             \rn, \rn, \rm
278 .endm
279
280 .macro  ldrh_pre        rt,  rn,  rm
281 A       ldrh            \rt, [\rn, \rm]!
282 T       add             \rn, \rn, \rm
283 T       ldrh            \rt, [\rn]
284 .endm
285
286 .macro  ldrh_dpre       rt,  rn,  rm
287 A       ldrh            \rt, [\rn, -\rm]!
288 T       sub             \rn, \rn, \rm
289 T       ldrh            \rt, [\rn]
290 .endm
291
292 .macro  ldrh_post       rt,  rn,  rm
293 A       ldrh            \rt, [\rn], \rm
294 T       ldrh            \rt, [\rn]
295 T       add             \rn, \rn, \rm
296 .endm
297
298 .macro  ldrb_post       rt,  rn,  rm
299 A       ldrb            \rt, [\rn], \rm
300 T       ldrb            \rt, [\rn]
301 T       add             \rn, \rn, \rm
302 .endm
303
304 .macro  str_post       rt,  rn,  rm:vararg
305 A       str             \rt, [\rn], \rm
306 T       str             \rt, [\rn]
307 T       add             \rn, \rn, \rm
308 .endm
309
310 .macro  strb_post       rt,  rn,  rm:vararg
311 A       strb            \rt, [\rn], \rm
312 T       strb            \rt, [\rn]
313 T       add             \rn, \rn, \rm
314 .endm
315
316 .macro  strd_post       rt,  rt2, rn,  rm
317 A       strd            \rt, \rt2, [\rn], \rm
318 T       strd            \rt, \rt2, [\rn]
319 T       add             \rn, \rn, \rm
320 .endm
321
322 .macro  strh_pre        rt,  rn,  rm
323 A       strh            \rt, [\rn, \rm]!
324 T       add             \rn, \rn, \rm
325 T       strh            \rt, [\rn]
326 .endm
327
328 .macro  strh_dpre       rt,  rn,  rm
329 A       strh            \rt, [\rn, -\rm]!
330 T       sub             \rn, \rn, \rm
331 T       strh            \rt, [\rn]
332 .endm
333
334 .macro  strh_post       rt,  rn,  rm
335 A       strh            \rt, [\rn], \rm
336 T       strh            \rt, [\rn]
337 T       add             \rn, \rn, \rm
338 .endm
339
340 .macro  strh_dpost       rt,  rn,  rm
341 A       strh            \rt, [\rn], -\rm
342 T       strh            \rt, [\rn]
343 T       sub             \rn, \rn, \rm
344 .endm
345
346 #if HAVE_VFP_ARGS
347 ELF     .eabi_attribute 28, 1
348 #   define VFP
349 #   define NOVFP @
350 #else
351 #   define VFP   @
352 #   define NOVFP
353 #endif
354
355 #define GLUE(a, b) a ## b
356 #define JOIN(a, b) GLUE(a, b)
357 #define X(s) JOIN(EXTERN_ASM, s)