Imported Upstream version 6.1
[platform/upstream/ffmpeg.git] / tests / checkasm / riscv / checkasm.S
1 /****************************************************************************
2  * Copyright © 2022 Rémi Denis-Courmont.
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (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
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
19  *****************************************************************************/
20
21 #include "libavutil/riscv/asm.S"
22
23 #if (__riscv_xlen == 64)
24
25 const fail_s_reg
26         .asciz  "callee-saved integer register clobbered"
27 endconst
28
29 const fail_fs_reg
30         .asciz  "callee-saved floating-point register clobbered"
31 endconst
32
33 const fail_rsvd_reg
34         .asciz  "unallocatable register clobbered"
35 endconst
36
37         .section .tbss, "waT"
38         .align  3
39         .hidden checked_func
40         .hidden saved_regs
41
42 checked_func:
43         .quad   0
44
45 saved_regs:
46         /* Space to spill RA, SP, GP, TP, S0-S11 and FS0-FS11 */
47         .rept   4 + 12 + 12
48         .quad   0
49         .endr
50
51 func checkasm_set_function
52         la.tls.ie t0, checked_func
53         add     t0, tp, t0
54         sd      a0, (t0)
55         ret
56 endfunc
57
58 func checkasm_get_wrapper, v
59         addi    sp, sp, -16
60         sd      fp,  (sp)
61         sd      ra, 8(sp)
62         addi    fp, sp, 16
63
64         call    av_get_cpu_flags
65         andi    t0, a0, 8 /* AV_CPU_FLAG_RVV_I32 */
66
67         lla     a0, 3f
68         beqz    t0, 1f
69         lla     a0, 2f
70 1:
71         ld      ra, 8(sp)
72         ld      fp,  (sp)
73         addi    sp, sp, 16
74         ret
75
76 2:      /* <-- Entry point with the Vector extension --> */
77         /* Clobber the vectors */
78         vsetvli t0, zero, e32, m8, ta, ma
79         li      t0, 0xdeadbeef
80         vmv.v.x v0, t0
81         vmv.v.x v8, t0
82         vmv.v.x v16, t0
83         vmv.v.x v24, t0
84
85         /* Clobber the vector configuration */
86         li      t0, 0        /* Vector length: zero */
87         li      t1, -1 << 31 /* Vector type:   illegal */
88         vsetvl  zero, t0, t1
89         csrwi   vxrm, 3      /* Rounding mode: round-to-odd */
90         csrwi   vxsat, 1     /* Saturation:    encountered */
91
92 3:      /* <-- Entry point without the Vector extension --> */
93         /* Save RA, unallocatable and callee-saved registers */
94         la.tls.ie t0, saved_regs
95         add     t0, tp, t0
96         sd      ra,   (t0)
97         sd      sp,  8(t0)
98         sd      gp, 16(t0)
99         sd      tp, 24(t0)
100         .irp    n, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
101         sd      s\n, (32 + (16 * \n))(t0)
102         fsd     fs\n, (40 + (16 * \n))(t0)
103         .endr
104
105         /* Clobber the stack space right below SP */
106         li      t0, 0xdeadbeef1badf00d
107         .rept   16
108         addi    sp, sp, -16
109         sd      t0,  (sp)
110         sd      t0, 8(sp)
111         .endr
112         addi    sp, sp, 256
113
114         /* Clobber the saved and temporary registers */
115         .irp    n, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
116         .if (\n > 0 && \n < 7)
117         mv      t\n, t0
118         .endif
119         fmv.d.x ft\n, t0
120         mv      s\n, t0
121         fmv.d.x fs\n, t0
122         .endr
123
124         /* Call the tested function */
125         la.tls.ie t0, checked_func
126         add     t0, tp, t0
127         ld      t1, (t0)
128         sd      zero, (t0)
129         jalr    t1
130
131         /* Check special register values */
132         la.tls.ie t0, saved_regs
133         add     t0, tp, t0
134         ld      t1,  8(t0)
135         bne     t1, sp, 5f
136         ld      t1, 16(t0)
137         bne     t1, gp, 5f
138         ld      t1, 24(t0) // If TP was corrupted, we probably will have...
139         bne     t1, tp, 5f // ...already crashed before we even get here.
140
141         /* Check value of saved registers */
142         li      t0, 0xdeadbeef1badf00d
143         .irp    n, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
144         bne     t0, s\n, 6f
145 #ifdef __riscv_float_abi_double
146         /* TODO: check float ABI single too */
147         fmv.x.d t1, fs\n
148         bne     t0, t1, 7f
149 #endif
150         .endr
151
152 4:
153         /* Restore RA and saved registers */
154         la.tls.ie t0, saved_regs
155         add     t0, tp, t0
156         ld      ra,   (t0)
157         .irp    n, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
158         ld      s\n, (32 + (16 * \n))(t0)
159         fld     fs\n, (40 + (16 * \n))(t0)
160         .endr
161         ret
162
163 5:
164         lla     a0, fail_rsvd_reg
165         call    checkasm_fail_func
166         tail    abort /* The test harness would probably crash anyway */
167
168 6:
169         lla     a0, fail_s_reg
170         call    checkasm_fail_func
171         j       4b
172
173 7:
174         lla     a0, fail_fs_reg
175         call    checkasm_fail_func
176         j       4b
177 endfunc
178 #endif