checkasm: Check register clobbering on arm
[ffmpeg.git] / tests / checkasm / arm / checkasm.S
1 /****************************************************************************
2  * Assembly testing and benchmarking tool
3  * Copyright (c) 2015 Martin Storsjo
4  * Copyright (c) 2015 Janne Grunau
5  *
6  * This file is part of Libav.
7  *
8  * Libav is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * Libav is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
21  *****************************************************************************/
22
23 #include "libavutil/arm/asm.S"
24
25 const register_init
26     .quad 0x21f86d66c8ca00ce
27     .quad 0x75b6ba21077c48ad
28     .quad 0xed56bb2dcb3c7736
29     .quad 0x8bda43d3fd1a7e06
30     .quad 0xb64a9c9e5d318408
31     .quad 0xdf9a54b303f1d3a3
32     .quad 0x4a75479abd64e097
33     .quad 0x249214109d5d1c88
34 endconst
35
36 const error_message
37     .asciz "failed to preserve register"
38 endconst
39
40 @ max number of args used by any asm function.
41 #define MAX_ARGS 15
42
43 #define ARG_STACK 4*(MAX_ARGS - 2)
44
45 .macro clobbercheck variant
46 .equ pushed, 4*9
47 function checkasm_checked_call_\variant, export=1
48     push        {r4-r11, lr}
49 .ifc \variant, vfp
50     vpush       {d8-d15}
51     fmrx        r4,  FPSCR
52     push        {r4}
53 .equ pushed, pushed + 16*4 + 4
54 .endif
55
56     movrel      r12, register_init
57 .ifc \variant, vfp
58     vldm        r12, {d8-d15}
59 .endif
60     ldm         r12, {r4-r11}
61
62     sub         sp,  sp,  #ARG_STACK
63 .equ pos, 0
64 .rept MAX_ARGS-2
65     ldr         r12, [sp, #ARG_STACK + pushed + 8 + pos]
66     str         r12, [sp, #pos]
67 .equ pos, pos + 4
68 .endr
69
70     mov         r12, r0
71     mov         r0,  r2
72     mov         r1,  r3
73     ldrd        r2,  r3,  [sp, #ARG_STACK + pushed]
74     blx         r12
75     add         sp,  sp,  #ARG_STACK
76
77     push        {r0, r1}
78     movrel      r12, register_init
79     mov         r3,  #0
80 .ifc \variant, vfp
81 .macro check_reg_vfp, dreg, inc=8
82     ldrd        r0,  r1,  [r12], #\inc
83     vmov        r2,  lr,  \dreg
84     eor         r0,  r0,  r2
85     eor         r1,  r1,  lr
86     orr         r3,  r3,  r0
87     orr         r3,  r3,  r1
88 .endm
89
90 .irp n, 8, 9, 10, 11, 12, 13, 14
91     check_reg_vfp d\n
92 .endr
93     check_reg_vfp d15, -56
94 .purgem check_reg_vfp
95
96     fmrx        r0,  FPSCR
97     ldr         r1,  [sp, #8]
98     eor         r0,  r0,  r1
99     @ Ignore changes in the topmost 5 bits
100     lsl         r0,  r0,  #5
101     orr         r3,  r3,  r0
102 .endif
103
104 .macro check_reg reg1, reg2=
105     ldrd        r0,  r1,  [r12], #8
106     eor         r0,  r0,  \reg1
107     orrs        r3,  r3,  r0
108 .ifnb \reg2
109     eor         r1,  r1,  \reg2
110     orrs        r3,  r3,  r1
111 .endif
112 .endm
113     check_reg   r4,  r5
114     check_reg   r6,  r7
115 @ r9 is a volatile register in the ios ABI
116 #ifdef __APPLE__
117     check_reg   r8
118 #else
119     check_reg   r8,  r9
120 #endif
121     check_reg   r10, r11
122 .purgem check_reg
123
124     beq         0f
125
126     movrel      r0, error_message
127     blx         X(checkasm_fail_func)
128 0:
129     pop         {r0, r1}
130 .ifc \variant, vfp
131     pop         {r2}
132     fmxr        FPSCR, r2
133     vpop        {d8-d15}
134 .endif
135     pop         {r4-r11, pc}
136 endfunc
137 .endm
138
139 #if HAVE_VFP || HAVE_NEON
140 clobbercheck vfp
141 #endif
142 clobbercheck novfp