Linux-libre 5.3.12-gnu
[librecmc/linux-libre.git] / arch / unicore32 / lib / clear_user.S
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * linux/arch/unicore32/lib/clear_user.S
4  *
5  * Code specific to PKUnity SoC and UniCore ISA
6  *
7  * Copyright (C) 2001-2010 GUAN Xue-tao
8  */
9 #include <linux/linkage.h>
10 #include <asm/assembler.h>
11
12                 .text
13
14 /* Prototype: int __clear_user(void *addr, size_t sz)
15  * Purpose  : clear some user memory
16  * Params   : addr - user memory address to clear
17  *          : sz   - number of bytes to clear
18  * Returns  : number of bytes NOT cleared
19  */
20 WEAK(__clear_user)
21                 stm.w   (lr), [sp-]
22                 stm.w   (r1), [sp-]
23                 mov     r2, #0
24                 csub.a  r1, #4
25                 bsl     2f
26                 and.a   ip, r0, #3
27                 beq     1f
28                 csub.a  ip, #2
29                 strusr  r2, r0, 1
30                 strusr  r2, r0, 1, el
31                 strusr  r2, r0, 1, sl
32                 rsub    ip, ip, #4
33                 sub     r1, r1, ip              @  7  6  5  4  3  2  1
34 1:              sub.a   r1, r1, #8              @ -1 -2 -3 -4 -5 -6 -7
35                 strusr  r2, r0, 4, ns, rept=2
36                 bns     1b
37                 add.a   r1, r1, #4              @  3  2  1  0 -1 -2 -3
38                 strusr  r2, r0, 4, ns
39 2:              cand.a  r1, #2                  @ 1x 1x 0x 0x 1x 1x 0x
40                 strusr  r2, r0, 1, ne, rept=2
41                 cand.a  r1, #1                  @ x1 x0 x1 x0 x1 x0 x1
42                 beq     3f
43 USER(           stb.u   r2, [r0])
44 3:              mov     r0, #0
45                 ldm.w   (r1), [sp]+
46                 ldm.w   (pc), [sp]+
47 ENDPROC(__clear_user)
48
49                 .pushsection .fixup,"ax"
50                 .align  0
51 9001:           ldm.w   (r0), [sp]+
52                 ldm.w   (pc), [sp]+
53                 .popsection
54