Linux-libre 5.3.12-gnu
[librecmc/linux-libre.git] / arch / nds32 / lib / clear_user.S
1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (C) 2005-2017 Andes Technology Corporation
3
4 #include <linux/linkage.h>
5 #include <asm/assembler.h>
6 #include <asm/errno.h>
7
8 /* Prototype: int __arch_clear_user(void *addr, size_t sz)
9  * Purpose  : clear some user memory
10  * Params   : addr - user memory address to clear
11  *          : sz   - number of bytes to clear
12  * Returns  : number of bytes NOT cleared
13  */
14         .text
15         .align  5
16 ENTRY(__arch_clear_user)
17         add     $r5, $r0, $r1
18         beqz    $r1, clear_exit
19         xor     $p1, $p1, $p1           ! Use $p1=0 to clear mem
20         srli    $p0, $r1, #2            ! $p0 = number of word to clear
21         andi    $r1, $r1, #3            ! Bytes less than a word to copy
22         beqz    $p0, byte_clear         ! Only less than a word to clear
23 word_clear:
24 USER(   smw.bim,$p1, [$r0], $p1)        ! Clear the word
25         addi    $p0, $p0, #-1           ! Decrease word count
26         bnez    $p0, word_clear         ! Continue looping to clear all words
27         beqz    $r1, clear_exit         ! No left bytes to copy
28 byte_clear:
29 USER(   sbi.bi, $p1, [$r0], #1)         ! Clear the byte
30         addi    $r1, $r1, #-1           ! Decrease byte count
31         bnez    $r1, byte_clear         ! Continue looping to clear all left bytes
32 clear_exit:
33         move    $r0, $r1                ! Set return value
34         ret
35
36         .section .fixup,"ax"
37         .align  0
38 9001:
39         sub     $r0, $r5, $r0           ! Bytes left to copy
40         ret
41         .previous
42 ENDPROC(__arch_clear_user)