GNU Linux-libre 4.19.245-gnu1
[releases.git] / arch / nds32 / lib / memset.S
1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (C) 2005-2017 Andes Technology Corporation
3
4 #include <linux/linkage.h>
5
6         .text
7 ENTRY(memset)
8         move    $r5, $r0                ! Return value
9         beqz    $r2, end_memset         ! Exit when len = 0
10         srli    $p1, $r2, 2             ! $p1 is how many words to copy
11         andi    $r2, $r2, 3             ! How many bytes are less than a word
12         beqz    $p1, byte_set           ! When n is less than a word
13
14         ! set $r1 from ??????ab to abababab
15         andi    $r1, $r1, #0x00ff       ! $r1 = 000000ab
16         slli    $p0, $r1, #8            ! $p0 = 0000ab00
17         or      $r1, $r1, $p0           ! $r1 = 0000abab
18         slli    $p0, $r1, #16           ! $p0 = abab0000
19         or      $r1, $r1, $p0           ! $r1 = abababab
20 word_set:
21         addi    $p1, $p1, #-1           ! How many words left to copy
22         smw.bim $r1, [$r0], $r1         ! Copy the word to det
23         bnez    $p1, word_set           ! Still words to set, continue looping
24         beqz    $r2, end_memset         ! No left byte to set
25 byte_set:                               ! Less than 4 bytes left to set
26         addi    $r2, $r2, #-1           ! Decrease len by 1
27         sbi.bi  $r1, [$r0], #1          ! Set data of the next byte to $r1
28         bnez    $r2, byte_set           ! Still bytes left to set
29 end_memset:
30         move    $r0, $r5
31         ret
32
33 ENDPROC(memset)