Linux-libre 4.19.20-gnu
[librecmc/linux-libre.git] / arch / h8300 / lib / memcpy.S
1 ;;; SPDX-License-Identifier: GPL-2.0
2 ;;; memcpy.S
3
4 #include <asm/linkage.h>
5
6 #if defined(CONFIG_CPU_H8300H)
7         .h8300h
8 #endif
9 #if defined(CONFIG_CPU_H8S)
10         .h8300s
11 #endif
12         .text
13 .global memcpy
14
15 ;;; void *memcpy(void *to, void *from, size_t n)
16 memcpy:
17         mov.l   er2,er2
18         bne     1f
19         rts
20 1:
21         ;; address check
22         bld     #0,r0l
23         bxor    #0,r1l
24         bcs     4f
25         mov.l   er4,@-sp
26         mov.l   er0,@-sp
27         btst    #0,r0l
28         beq     1f
29         ;; (aligned even) odd address
30         mov.b   @er1,r3l
31         mov.b   r3l,@er0
32         adds    #1,er1
33         adds    #1,er0
34         dec.l   #1,er2
35         beq     3f
36 1:
37         ;; n < sizeof(unsigned long) check
38         sub.l   er4,er4
39         adds    #4,er4          ; loop count check value
40         cmp.l   er4,er2
41         blo     2f
42         ;; unsigned long copy
43 1:
44         mov.l   @er1,er3
45         mov.l   er3,@er0
46         adds    #4,er0
47         adds    #4,er1
48         subs    #4,er2
49         cmp.l   er4,er2
50         bcc     1b
51         ;; rest
52 2:
53         mov.l   er2,er2
54         beq     3f
55 1:
56         mov.b   @er1,r3l
57         mov.b   r3l,@er0
58         adds    #1,er1
59         adds    #1,er0
60         dec.l   #1,er2
61         bne     1b
62 3:
63         mov.l   @sp+,er0
64         mov.l   @sp+,er4
65         rts
66
67         ;; odd <- even / even <- odd
68 4:
69         mov.l   er4,er3
70         mov.l   er2,er4
71         mov.l   er5,er2
72         mov.l   er1,er5
73         mov.l   er6,er1
74         mov.l   er0,er6
75 1:
76         eepmov.w
77         mov.w   r4,r4
78         bne     1b
79         dec.w   #1,e4
80         bpl     1b
81         mov.l   er1,er6
82         mov.l   er2,er5
83         mov.l   er3,er4
84         rts
85
86         .end