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