···11+// SPDX-License-Identifier: GPL-2.022+// Copyright (C) 2005-2017 Andes Technology Corporation33+44+#include <linux/linkage.h>55+#include <asm/assembler.h>66+#include <asm/errno.h>77+88+/* Prototype: int __arch_clear_user(void *addr, size_t sz)99+ * Purpose : clear some user memory1010+ * Params : addr - user memory address to clear1111+ * : sz - number of bytes to clear1212+ * Returns : number of bytes NOT cleared1313+ */1414+ .text1515+ .align 51616+ENTRY(__arch_clear_user)1717+ add $r5, $r0, $r11818+ beqz $r1, clear_exit1919+ xor $p1, $p1, $p1 ! Use $p1=0 to clear mem2020+ srli $p0, $r1, #2 ! $p0 = number of word to clear2121+ andi $r1, $r1, #3 ! Bytes less than a word to copy2222+ beqz $p0, byte_clear ! Only less than a word to clear2323+word_clear:2424+USER( smw.bim,$p1, [$r0], $p1) ! Clear the word2525+ addi $p0, $p0, #-1 ! Decrease word count2626+ bnez $p0, word_clear ! Continue looping to clear all words2727+ beqz $r1, clear_exit ! No left bytes to copy2828+byte_clear:2929+USER( sbi.bi, $p1, [$r0], #1) ! Clear the byte3030+ addi $r1, $r1, #-1 ! Decrease byte count3131+ bnez $r1, byte_clear ! Continue looping to clear all left bytes3232+clear_exit:3333+ move $r0, $r1 ! Set return value3434+ ret3535+3636+ .section .fixup,"ax"3737+ .align 03838+9001:3939+ sub $r0, $r5, $r0 ! Bytes left to copy4040+ ret4141+ .previous4242+ENDPROC(__arch_clear_user)
+45
arch/nds32/lib/copy_from_user.S
···11+// SPDX-License-Identifier: GPL-2.022+// Copyright (C) 2005-2017 Andes Technology Corporation33+44+#include <linux/linkage.h>55+#include <asm/assembler.h>66+#include <asm/errno.h>77+88+.macro lbi1 dst, addr, adj99+USER( lbi.bi, \dst, [\addr], \adj)1010+.endm1111+1212+.macro sbi1 src, addr, adj1313+sbi.bi \src, [\addr], \adj1414+.endm1515+1616+.macro lmw1 start_reg, addr, end_reg1717+USER( lmw.bim, \start_reg, [\addr], \end_reg)1818+.endm1919+2020+.macro smw1 start_reg, addr, end_reg2121+smw.bim \start_reg, [\addr], \end_reg2222+.endm2323+2424+2525+/* Prototype: int __arch_copy_from_user(void *to, const char *from, size_t n)2626+ * Purpose : copy a block from user memory to kernel memory2727+ * Params : to - kernel memory2828+ * : from - user memory2929+ * : n - number of bytes to copy3030+ * Returns : Number of bytes NOT copied.3131+ */3232+3333+.text3434+ENTRY(__arch_copy_from_user)3535+ add $r5, $r0, $r23636+#include "copy_template.S"3737+ move $r0, $r23838+ ret3939+.section .fixup,"ax"4040+.align 24141+9001:4242+ sub $r0, $r5, $r04343+ ret4444+.previous4545+ENDPROC(__arch_copy_from_user)
···11+// SPDX-License-Identifier: GPL-2.022+// Copyright (C) 2005-2017 Andes Technology Corporation33+44+#include <linux/linkage.h>55+66+/*77+ void *memmove(void *dst, const void *src, int n);88+99+ dst: $r01010+ src: $r11111+ n : $r21212+ ret: $r0 - pointer to the memory area dst.1313+*/1414+ .text1515+1616+ENTRY(memmove)1717+ move $r5, $r0 ! Set return value = det1818+ beq $r0, $r1, exit_memcpy ! Exit when det = src1919+ beqz $r2, exit_memcpy ! Exit when n = 02020+ pushm $t0, $t1 ! Save reg2121+ srli $p1, $r2, #2 ! $p1 is how many words to copy2222+2323+ ! Avoid data lost when memory overlap2424+ ! Copy data reversely when src < dst2525+ slt $p0, $r0, $r1 ! check if $r0 < $r12626+ beqz $p0, do_reverse ! branch if dst > src2727+2828+ ! No reverse, dst < src2929+ andi $r2, $r2, #3 ! How many bytes are less than a word3030+ li $t0, #1 ! Determining copy direction in byte_cpy3131+ beqz $p1, byte_cpy ! When n is less than a word3232+3333+word_cpy:3434+ lmw.bim $p0, [$r1], $p0 ! Read a word from src3535+ addi $p1, $p1, #-1 ! How many words left to copy3636+ smw.bim $p0, [$r0], $p0 ! Copy the word to det3737+ bnez $p1, word_cpy ! If remained words > 03838+ beqz $r2, end_memcpy ! No left bytes to copy3939+ b byte_cpy4040+4141+do_reverse:4242+ add $r0, $r0, $r2 ! Start with the end of $r04343+ add $r1, $r1, $r2 ! Start with the end of $r14444+ andi $r2, $r2, #3 ! How many bytes are less than a word4545+ li $t0, #-1 ! Determining copy direction in byte_cpy4646+ beqz $p1, reverse_byte_cpy ! When n is less than a word4747+4848+reverse_word_cpy:4949+ lmw.adm $p0, [$r1], $p0 ! Read a word from src5050+ addi $p1, $p1, #-1 ! How many words left to copy5151+ smw.adm $p0, [$r0], $p0 ! Copy the word to det5252+ bnez $p1, reverse_word_cpy ! If remained words > 05353+ beqz $r2, end_memcpy ! No left bytes to copy5454+5555+reverse_byte_cpy:5656+ addi $r0, $r0, #-15757+ addi $r1, $r1, #-15858+byte_cpy: ! Less than 4 bytes to copy now5959+ lb.bi $p0, [$r1], $t0 ! Read a byte from src6060+ addi $r2, $r2, #-1 ! How many bytes left to copy6161+ sb.bi $p0, [$r0], $t0 ! copy the byte to det6262+ bnez $r2, byte_cpy ! If remained bytes > 06363+6464+end_memcpy:6565+ popm $t0, $t16666+exit_memcpy:6767+ move $r0, $r56868+ ret6969+7070+ENDPROC(memmove)
+33
arch/nds32/lib/memset.S
···11+// SPDX-License-Identifier: GPL-2.022+// Copyright (C) 2005-2017 Andes Technology Corporation33+44+#include <linux/linkage.h>55+66+ .text77+ENTRY(memset)88+ move $r5, $r0 ! Return value99+ beqz $r2, end_memset ! Exit when len = 01010+ srli $p1, $r2, 2 ! $p1 is how many words to copy1111+ andi $r2, $r2, 3 ! How many bytes are less than a word1212+ beqz $p1, byte_set ! When n is less than a word1313+1414+ ! set $r1 from ??????ab to abababab1515+ andi $r1, $r1, #0x00ff ! $r1 = 000000ab1616+ slli $p0, $r1, #8 ! $p0 = 0000ab001717+ or $r1, $r1, $p0 ! $r1 = 0000abab1818+ slli $p0, $r1, #16 ! $p0 = abab00001919+ or $r1, $r1, $p0 ! $r1 = abababab2020+word_set:2121+ addi $p1, $p1, #-1 ! How many words left to copy2222+ smw.bim $r1, [$r0], $r1 ! Copy the word to det2323+ bnez $p1, word_set ! Still words to set, continue looping2424+ beqz $r2, end_memset ! No left byte to set2525+byte_set: ! Less than 4 bytes left to set2626+ addi $r2, $r2, #-1 ! Decrease len by 12727+ sbi.bi $r1, [$r0], #1 ! Set data of the next byte to $r12828+ bnez $r2, byte_set ! Still bytes left to set2929+end_memset:3030+ move $r0, $r53131+ ret3232+3333+ENDPROC(memset)
+18
arch/nds32/lib/memzero.S
···11+// SPDX-License-Identifier: GPL-2.022+// Copyright (C) 2005-2017 Andes Technology Corporation33+44+#include <linux/linkage.h>55+66+ .text77+ENTRY(memzero)88+ beqz $r1, 1f99+ push $lp1010+ move $r2, $r11111+ move $r1, #01212+ push $r01313+ bal memset1414+ pop $r01515+ pop $lp1616+1:1717+ ret1818+ENDPROC(memzero)