• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 get_vlenb, export=1
87  csrr a0, vlenb
88  ret
89endfunc
90
91function checked_call, export=1, ext=v
92  /* Save the function ptr, RA, SP, unallocatable and callee-saved registers */
93  la.tls.ie t0, saved_regs
94  add t0, tp, t0
95  sd a0, (t0)
96  sd ra, 8(t0)
97  sd sp, 16(t0)
98  sd gp, 24(t0)
99  sd tp, 32(t0)
100.irp n, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
101  sd s\n, 40 + 16*\n(t0)
102#ifdef __riscv_float_abi_double
103  fsd fs\n, 48 + 16*\n(t0)
104#endif
105.endr
106
107  /* Check for vector extension */
108  call dav1d_get_cpu_flags_riscv
109  and a0, a0, 1 # DAV1D_RISCV_CPU_FLAG_RVV
110  beqz a0, 0f
111
112  /* Clobber vector configuration */
113  vsetvli t0, zero, e32, m8, ta, ma
114  lla t0, register_init
115  ld t0, (t0)
116.irp n, 0, 8, 16, 24
117  vmv.v.x v0, t0
118.endr
119  li t0, -1 << 31
120  vsetvl zero, zero, t0
121  csrwi vxrm, 3
122  csrwi vxsat, 1
123
1240:
125  /* Load the register arguments */
126.irp n, 0, 1, 2, 3, 4, 5, 6, 7
127  ld a\n, 8*\n(sp)
128.endr
129
130  /* Load the stack arguments */
131.irp n, 8, 9, 10, 11, 12, 13, 14, 15
132   ld t0, 8*\n(sp)
133   sd t0, 8*(\n - 8) - ARG_STACK(sp)
134.endr
135
136  /* Setup the stack canary */
137  ld t0, MAX_ARGS*8(sp)
138  addi sp, sp, -ARG_STACK
139  slli t0, t0, 3
140  add t0, t0, sp
141  ld t0, (t0)
142  not t0, t0
143  sd t0, ARG_STACK - 8(sp)
144
145  /* Clobber the stack space right below SP */
146  lla t0, register_init
147  ld t1, (t0)
148.rept 16
149  addi sp, sp, -16
150  sd t1, (sp)
151  sd t1, 8(sp)
152.endr
153  addi sp, sp, 16*16
154
155  /* Clobber the callee-saved and temporary registers */
156.irp n, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
157.if (\n > 0 && \n < 7)
158  ld t\n, 16*\n(t0)
159.endif
160  ld s\n, 8 + 8*\n(t0)
161#ifdef __riscv_float_abi_double
162  fld ft\n, 16 + 16*\n(t0)
163  fld fs\n, 24 + 8*\n(t0)
164#endif
165.endr
166
167  /* Call the checked function */
168  la.tls.ie t0, saved_regs
169  add t0, tp, t0
170  ld t0, (t0)
171  jalr t0
172
173  /* Check the value of callee-saved registers */
174  lla t0, register_init
175.irp n, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
176  ld t1, 8 + 8*\n(t0)
177  li a1, \n
178  bne t1, s\n, 2f
179#ifdef __riscv_float_abi_double
180  ld t1, 24 + 8*\n(t0)
181  fmv.x.d t2, fs\n
182  bne t1, t2, 3f
183#endif
184.endr
185
186  /* Check unallocatable register values */
187  la.tls.ie t0, saved_regs
188  add t0, tp, t0
189  ld t1, 16(t0)
190  addi t1, t1, -ARG_STACK
191  bne t1, sp, 4f
192  ld t1, 24(t0)
193  bne t1, gp, 4f
194  ld t1, 32(t0)
195  bne t1, tp, 4f
196
197  /* Check the stack canary */
198  ld t0, ARG_STACK + MAX_ARGS*8(sp)
199  slli t0, t0, 3
200  add t0, t0, sp
201  ld t0, (t0)
202  not t0, t0
203  ld t1, ARG_STACK - 8(sp)
204  bne t0, t1, 5f
205
2061:
207  /* Restore RA, SP and callee-saved registers from thread local storage */
208  la.tls.ie t0, saved_regs
209  add t0, tp, t0
210  ld ra, 8(t0)
211  ld sp, 16(t0)
212.irp n, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
213  ld s\n, 40 + 16*\n(t0)
214#ifdef __riscv_float_abi_double
215  fld fs\n, 48 + 16*\n(t0)
216#endif
217.endr
218  ret
219
2202:
221  lla a0, error_message_sreg
222#ifdef PREFIX
223  call _checkasm_fail_func
224#else
225  call checkasm_fail_func
226#endif
227  j 1b
228
229#ifdef __riscv_float_abi_double
2303:
231  lla a0, error_message_fsreg
232#ifdef PREFIX
233  call _checkasm_fail_func
234#else
235  call checkasm_fail_func
236#endif
237  j 1b
238#endif
239
2404:
241  lla a0, error_message_rsvd
242#ifdef PREFIX
243  call _checkasm_fail_func
244#else
245  call checkasm_fail_func
246#endif
247  j 1b
248
2495:
250  lla a0, error_message_stack
251#ifdef PREFIX
252  call _checkasm_fail_func
253#else
254  call checkasm_fail_func
255#endif
256  j 1b
257endfunc
258