Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/frv/lib/memcpy.S
10817 views
1
/* memcpy.S: optimised assembly memcpy
2
*
3
* Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
4
* Written by David Howells ([email protected])
5
*
6
* This program is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public License
8
* as published by the Free Software Foundation; either version
9
* 2 of the License, or (at your option) any later version.
10
*/
11
12
13
.text
14
.p2align 4
15
16
###############################################################################
17
#
18
# void *memcpy(void *to, const char *from, size_t count)
19
#
20
# - NOTE: must not use any stack. exception detection performs function return
21
# to caller's fixup routine, aborting the remainder of the copy
22
#
23
###############################################################################
24
.globl memcpy,__memcpy_end
25
.type memcpy,@function
26
memcpy:
27
or.p gr8,gr9,gr4
28
orcc gr10,gr0,gr0,icc3
29
or.p gr10,gr4,gr4
30
beqlr icc3,#0
31
32
# optimise based on best common alignment for to, from & count
33
andicc.p gr4,#0x0f,gr0,icc0
34
setlos #8,gr11
35
andicc.p gr4,#0x07,gr0,icc1
36
beq icc0,#0,memcpy_16
37
andicc.p gr4,#0x03,gr0,icc0
38
beq icc1,#0,memcpy_8
39
andicc.p gr4,#0x01,gr0,icc1
40
beq icc0,#0,memcpy_4
41
setlos.p #1,gr11
42
beq icc1,#0,memcpy_2
43
44
# do byte by byte copy
45
sub.p gr8,gr11,gr3
46
sub gr9,gr11,gr9
47
0: ldubu.p @(gr9,gr11),gr4
48
subicc gr10,#1,gr10,icc0
49
stbu.p gr4,@(gr3,gr11)
50
bne icc0,#2,0b
51
bralr
52
53
# do halfword by halfword copy
54
memcpy_2:
55
setlos #2,gr11
56
sub.p gr8,gr11,gr3
57
sub gr9,gr11,gr9
58
0: lduhu.p @(gr9,gr11),gr4
59
subicc gr10,#2,gr10,icc0
60
sthu.p gr4,@(gr3,gr11)
61
bne icc0,#2,0b
62
bralr
63
64
# do word by word copy
65
memcpy_4:
66
setlos #4,gr11
67
sub.p gr8,gr11,gr3
68
sub gr9,gr11,gr9
69
0: ldu.p @(gr9,gr11),gr4
70
subicc gr10,#4,gr10,icc0
71
stu.p gr4,@(gr3,gr11)
72
bne icc0,#2,0b
73
bralr
74
75
# do double-word by double-word copy
76
memcpy_8:
77
sub.p gr8,gr11,gr3
78
sub gr9,gr11,gr9
79
0: lddu.p @(gr9,gr11),gr4
80
subicc gr10,#8,gr10,icc0
81
stdu.p gr4,@(gr3,gr11)
82
bne icc0,#2,0b
83
bralr
84
85
# do quad-word by quad-word copy
86
memcpy_16:
87
sub.p gr8,gr11,gr3
88
sub gr9,gr11,gr9
89
0: lddu @(gr9,gr11),gr4
90
lddu.p @(gr9,gr11),gr6
91
subicc gr10,#16,gr10,icc0
92
stdu gr4,@(gr3,gr11)
93
stdu.p gr6,@(gr3,gr11)
94
bne icc0,#2,0b
95
bralr
96
__memcpy_end:
97
98
.size memcpy, __memcpy_end-memcpy
99
100
###############################################################################
101
#
102
# copy to/from userspace
103
# - return the number of bytes that could not be copied (0 on complete success)
104
#
105
# long __memcpy_user(void *dst, const void *src, size_t count)
106
#
107
###############################################################################
108
.globl __memcpy_user, __memcpy_user_error_lr, __memcpy_user_error_handler
109
.type __memcpy_user,@function
110
__memcpy_user:
111
movsg lr,gr7
112
subi.p sp,#8,sp
113
add gr8,gr10,gr6 ; calculate expected end address
114
stdi gr6,@(sp,#0)
115
116
# abuse memcpy to do the dirty work
117
call memcpy
118
__memcpy_user_error_lr:
119
ldi.p @(sp,#4),gr7
120
setlos #0,gr8
121
jmpl.p @(gr7,gr0)
122
addi sp,#8,sp
123
124
# deal any exception generated by memcpy
125
# GR8 - memcpy's current dest address
126
# GR11 - memset's step value (index register for store insns)
127
__memcpy_user_error_handler:
128
lddi.p @(sp,#0),gr4 ; load GR4 with dst+count, GR5 with ret addr
129
add gr11,gr3,gr7
130
sub.p gr4,gr7,gr8
131
132
addi sp,#8,sp
133
jmpl @(gr5,gr0)
134
135
.size __memcpy_user, .-__memcpy_user
136
137