xref: /aosp_15_r20/external/libdav1d/tests/checkasm/riscv/checkasm_64.S (revision c09093415860a1c2373dacd84c4fde00c507cdfd)
1/******************************************************************************
2 * Copyright © 2018, VideoLAN and dav1d authors
3 * Copyright © 2023, Nathan Egge
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright notice, this
10 *    list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright notice,
13 *    this list of conditions and the following disclaimer in the documentation
14 *    and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *****************************************************************************/
27
28#define PRIVATE_PREFIX checkasm_
29
30#include "src/riscv/asm.S"
31
32// max number of args used by any asm function.
33#define MAX_ARGS 15
34
35// + 16 for stack canary reference
36#define ARG_STACK ((8*(MAX_ARGS - 8) + 15) & ~15 + 16)
37
38const register_init, align=4
39        .quad 0x68909d060f4a7fdd
40        .quad 0x924f739e310218a1
41        .quad 0xb988385a8254174c
42        .quad 0x4c1110430bf09fd7
43        .quad 0x2b310edf6a5d7ecf
44        .quad 0xda8112e98ddbb559
45        .quad 0x6da5854aa2f84b62
46        .quad 0x72b761199e9b1f38
47        .quad 0x13f27aa74ae5dcdf
48        .quad 0x36a6c12a7380e827
49        .quad 0x5c452889aefc8548
50        .quad 0x6a9ea1ddb236235f
51        .quad 0x0449854bdfc94b1e
52        .quad 0x4f849b7076a156f5
53        .quad 0x1baa4275e734930e
54        .quad 0x77df3503ba3e073d
55        .quad 0x6060e073705a4bf2
56        .quad 0xa7b482508471e44b
57        .quad 0xd296a3158d6da2b9
58        .quad 0x1c0ed711a93d970b
59        .quad 0x9359537fdd79569d
60        .quad 0x2b1dc95c1e232d62
61        .quad 0xab06cd578e2bb5a0
62        .quad 0x4100b4987a0af30f
63        .quad 0x2523e36f9bb1e36f
64        .quad 0xfb0b815930c6d25c
65        .quad 0x89acc810c2902fcf
66        .quad 0xa65854b4c2b381f1
67        .quad 0x78150d69a1accedf
68        .quad 0x057e24868e022de1
69        .quad 0x88f6e79ed4b8d362
70        .quad 0x1f4a420e262c9035
71endconst
72
73const error_message_register
74error_message_rsvd:
75        .asciz "unallocatable register clobbered"
76error_message_sreg:
77        .asciz "callee-saved integer register s%i modified"
78error_message_fsreg:
79        .asciz "callee-saved floating-point register fs%i modified"
80error_message_stack:
81        .asciz "stack clobbered"
82endconst
83
84thread_local saved_regs, quads=29 # 5 + 12 + 12
85
86function checked_call, export=1, ext=v
87  /* Save the function ptr, RA, SP, unallocatable and callee-saved registers */
88  la.tls.ie t0, saved_regs
89  add t0, tp, t0
90  sd a0, (t0)
91  sd ra, 8(t0)
92  sd sp, 16(t0)
93  sd gp, 24(t0)
94  sd tp, 32(t0)
95.irp n, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
96  sd s\n, 40 + 16*\n(t0)
97#ifdef __riscv_float_abi_double
98  fsd fs\n, 48 + 16*\n(t0)
99#endif
100.endr
101
102  /* Check for vector extension */
103  call dav1d_get_cpu_flags_riscv
104  and a0, a0, 1 # DAV1D_RISCV_CPU_FLAG_RVV
105  beqz a0, 0f
106
107  /* Clobber vector configuration */
108  vsetvli t0, zero, e32, m8, ta, ma
109  lla t0, register_init
110  ld t0, (t0)
111.irp n, 0, 8, 16, 24
112  vmv.v.x v0, t0
113.endr
114  li t0, -1 << 31
115  vsetvl zero, zero, t0
116  csrwi vxrm, 3
117  csrwi vxsat, 1
118
1190:
120  /* Load the register arguments */
121.irp n, 0, 1, 2, 3, 4, 5, 6, 7
122  ld a\n, 8*\n(sp)
123.endr
124
125  /* Load the stack arguments */
126.irp n, 8, 9, 10, 11, 12, 13, 14, 15
127   ld t0, 8*\n(sp)
128   sd t0, 8*(\n - 8) - ARG_STACK(sp)
129.endr
130
131  /* Setup the stack canary */
132  ld t0, MAX_ARGS*8(sp)
133  addi sp, sp, -ARG_STACK
134  slli t0, t0, 3
135  add t0, t0, sp
136  ld t0, (t0)
137  not t0, t0
138  sd t0, ARG_STACK - 8(sp)
139
140  /* Clobber the stack space right below SP */
141  lla t0, register_init
142  ld t1, (t0)
143.rept 16
144  addi sp, sp, -16
145  sd t1, (sp)
146  sd t1, 8(sp)
147.endr
148  addi sp, sp, 16*16
149
150  /* Clobber the callee-saved and temporary registers */
151.irp n, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
152.if (\n > 0 && \n < 7)
153  ld t\n, 16*\n(t0)
154.endif
155  ld s\n, 8 + 8*\n(t0)
156#ifdef __riscv_float_abi_double
157  fld ft\n, 16 + 16*\n(t0)
158  fld fs\n, 24 + 8*\n(t0)
159#endif
160.endr
161
162  /* Call the checked function */
163  la.tls.ie t0, saved_regs
164  add t0, tp, t0
165  ld t0, (t0)
166  jalr t0
167
168  /* Check the value of callee-saved registers */
169  lla t0, register_init
170.irp n, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
171  ld t1, 8 + 8*\n(t0)
172  li a1, \n
173  bne t1, s\n, 2f
174#ifdef __riscv_float_abi_double
175  ld t1, 24 + 8*\n(t0)
176  fmv.x.d t2, fs\n
177  bne t1, t2, 3f
178#endif
179.endr
180
181  /* Check unallocatable register values */
182  la.tls.ie t0, saved_regs
183  add t0, tp, t0
184  ld t1, 16(t0)
185  addi t1, t1, -ARG_STACK
186  bne t1, sp, 4f
187  ld t1, 24(t0)
188  bne t1, gp, 4f
189  ld t1, 32(t0)
190  bne t1, tp, 4f
191
192  /* Check the stack canary */
193  ld t0, ARG_STACK + MAX_ARGS*8(sp)
194  slli t0, t0, 3
195  add t0, t0, sp
196  ld t0, (t0)
197  not t0, t0
198  ld t1, ARG_STACK - 8(sp)
199  bne t0, t1, 5f
200
2011:
202  /* Restore RA, SP and callee-saved registers from thread local storage */
203  la.tls.ie t0, saved_regs
204  add t0, tp, t0
205  ld ra, 8(t0)
206  ld sp, 16(t0)
207.irp n, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
208  ld s\n, 40 + 16*\n(t0)
209#ifdef __riscv_float_abi_double
210  fld fs\n, 48 + 16*\n(t0)
211#endif
212.endr
213  ret
214
2152:
216  lla a0, error_message_sreg
217#ifdef PREFIX
218  call _checkasm_fail_func
219#else
220  call checkasm_fail_func
221#endif
222  j 1b
223
224#ifdef __riscv_float_abi_double
2253:
226  lla a0, error_message_fsreg
227#ifdef PREFIX
228  call _checkasm_fail_func
229#else
230  call checkasm_fail_func
231#endif
232  j 1b
233#endif
234
2354:
236  lla a0, error_message_rsvd
237#ifdef PREFIX
238  call _checkasm_fail_func
239#else
240  call checkasm_fail_func
241#endif
242  j 1b
243
2445:
245  lla a0, error_message_stack
246#ifdef PREFIX
247  call _checkasm_fail_func
248#else
249  call checkasm_fail_func
250#endif
251  j 1b
252endfunc
253