summaryrefslogtreecommitdiff
path: root/lib/ultralib/src/libc/bcopy.s
blob: 9bf1583ebe52f496726823e599a19952134829b1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
#include "PR/R4300.h"
#include "sys/asm.h"
#include "sys/regdef.h"

.text
WEAK(_bcopy, bcopy)
LEAF(bcopy)
    move a3, a1
    beqz a2, ret
    beq a0, a1, ret
    blt a1, a0, goforwards
    
    add v0, a0, a2
    bge a1, v0, goforwards
    b gobackwards

goforwards:

    blt a2, 16, forwards_bytecopy
    
    andi v0, a0, 0x3
    andi v1, a1, 0x3
    beq v0, v1,forwalignable
    

forwards_bytecopy:
    beqz a2, ret
    addu v1, a0, a2
99:
    lb v0, 0(a0)
    addiu a0, a0, 1
    sb v0, 0(a1)
    addiu a1, a1, 1
    bne a0, v1, 99b
ret:
    move v0, a3
    jr ra

forwalignable:
    beqz v0, forwards
    beq v0, 1, forw_copy3
    beq v0, 2, forw_copy2

    lb v0, 0(a0)
    addiu a0, a0, 1
    sb v0, 0(a1)
    addiu a1, a1, 1
    addiu a2, a2, -1
    b forwards

forw_copy2:
    lh v0, 0(a0)
    addiu a0, a0, 2
    sh v0, 0(a1)
    addiu a1, a1, 2
    addiu a2, a2, -2
    b forwards

forw_copy3:
    lb v0, 0(a0)
    lh v1, 1(a0)
    addiu a0, a0, 3
    sb v0, 0(a1)
    sh v1, 1(a1)
    addiu a1, a1, 3
    addiu a2, a2, -3

forwards:
forwards_32:
    blt a2, 32, forwards_16
    lw v0, 0(a0)
    lw v1, 4(a0)
    lw t0, 8(a0)
    lw t1, 12(a0)
    lw t2, 16(a0)
    lw t3, 20(a0)
    lw ta0, 24(a0)
    lw ta1, 28(a0)
    addiu a0, a0, 32
    sw v0, 0(a1)
    sw v1, 4(a1)
    sw t0, 8(a1)
    sw t1, 12(a1)
    sw t2, 16(a1)
    sw t3, 20(a1)
    sw ta0, 24(a1)
    sw ta1, 28(a1)
    addiu a1, a1, 32
    addiu a2, a2, -32
    b forwards_32

forwards_16:
    blt a2, 16, forwards_4
    lw v0, 0(a0)
    lw v1, 4(a0)
    lw t0, 8(a0)
    lw t1, 12(a0)
    addiu a0, a0, 16
    sw v0, 0(a1)
    sw v1, 4(a1)
    sw t0, 8(a1)
    sw t1, 12(a1)
    addiu a1, a1, 16
    addiu a2, a2, -16
    b forwards_16

forwards_4:
    blt a2, 4, forwards_bytecopy
    
    lw v0, 0(a0)
    addiu a0, a0, 4
    sw v0, 0(a1)
    addiu a1, a1, 4
    addiu a2, a2, -4
    b forwards_4
    
gobackwards:
    add a0, a0,a2
    add a1, a1,a2
    blt a2, 16, backwards_bytecopy

    andi v0, a0, 0x3
    andi v1, a1, 0x3
    beq v0, v1,backalignable
    
backwards_bytecopy:
    beqz a2, ret
    addiu a0, a0, -1
    addiu a1, a1, -1
    subu v1, a0,a2
99:
    lb v0, 0(a0)
    addiu a0, a0, -1
    sb v0, 0(a1)
    addiu a1, a1, -1
    bne a0, v1,99b

    move v0, a3
    jr ra
backalignable:
    beqz v0, backwards
    beq v0, 3, back_copy3
    beq v0, 2, back_copy2
    lb v0, -1(a0)
    addiu a0, a0, -1
    sb v0, -1(a1)
    addiu a1, a1, -1
    addiu a2, a2, -1
    b backwards

back_copy2:
    lh v0, -2(a0)
    addiu a0, a0, -2
    sh v0, -2(a1)
    addiu a1, a1, -2
    addiu a2, a2, -2
    b backwards

back_copy3:
    lb v0, -1(a0)
    lh v1, -3(a0)
    addiu a0, a0, -3
    sb v0, -1(a1)
    sh v1, -3(a1)
    addiu a1, a1, -3
    addiu a2, a2, -3

backwards:
backwards_32:
    blt a2, 32, backwards_16
    lw v0, -4(a0)
    lw v1, -8(a0)
    lw t0, -12(a0)
    lw t1, -16(a0)
    lw t2, -20(a0)
    lw t3, -24(a0)
    lw ta0, -28(a0)
    lw ta1, -32(a0)
    addiu a0, a0, -32
    sw v0, -4(a1)
    sw v1, -8(a1)
    sw t0, -12(a1)
    sw t1, -16(a1)
    sw t2, -20(a1)
    sw t3, -24(a1)
    sw ta0, -28(a1)
    sw ta1, -32(a1)
    addiu a1, a1, -32
    addiu a2, a2, -32
    b backwards_32

backwards_16:
    blt a2, 16, backwards_4
    lw v0, -4(a0)
    lw v1, -8(a0)
    lw t0, -12(a0)
    lw t1, -16(a0)
    addiu a0, a0, -16
    sw v0, -4(a1)
    sw v1, -8(a1)
    sw t0, -12(a1)
    sw t1, -16(a1)
    addiu a1, a1, -16
    addiu a2, a2, -16
    b backwards_16

backwards_4:
    blt a2, 4, backwards_bytecopy
    lw v0, -4(a0)
    addiu a0, a0, -4
    sw v0, -4(a1)
    addiu a1, a1, -4
    addiu a2, a2, -4
    b backwards_4
    
END(bcopy)
/*
*/