summaryrefslogtreecommitdiff
path: root/sys/src/libc/68020/memmove.s
blob: 482b3d690233c9a087f59e6ee4b73ef1ec037fda (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
	TEXT	memmove(SB), $0
move:

	MOVL	n+8(FP),R0
	BEQ	return
	BGT	ok
	MOVL	0, R0
ok:
	MOVL	s1+0(FP),A2
	MOVL	s2+4(FP),A1

	CMPL	A2,A1
	BHI	back

/*
 * speed depends on source allignment
 * destination allignment is secondary
 * byte-at-a-time foreward copy to
 * get source (A1) alligned.
 */
f1:
	MOVL	A1, R1
	ANDL	$3, R1
	BEQ	f2
	SUBL	$1, R0
	BLT	return
	MOVB	(A1)+, (A2)+
	BRA	f1
/*
 * quad-long-at-a-time forward copy
 */
f2:
	SUBL	$16, R0
	BLT	f3
	MOVL	(A1)+, (A2)+
	MOVL	(A1)+, (A2)+
	MOVL	(A1)+, (A2)+
	MOVL	(A1)+, (A2)+
	BRA	f2

/*
 * cleanup byte-at-a-time
 */
f3:
	ADDL	$15, R0
	BLT	return
f4:
	MOVB	(A1)+, (A2)+
	SUBL	$1, R0
	BGE	f4
	BRA	return

return:
	MOVL	s1+0(FP),R0
	RTS

/*
 * everything the same, but
 * copy backwards
 */
back:
	ADDL	R0, A1
	ADDL	R0, A2

/*
 * byte-at-a-time backward copy to
 * get source (A1) alligned.
 */
b1:
	MOVL	A1, R1
	ANDL	$3, R1
	BEQ	b2
	SUBL	$1, R0
	BLT	return
	MOVB	-(A1), -(A2)
	BRA	b1
/*
 * quad-long-at-a-time backward copy
 */
b2:
	SUBL	$16, R0
	BLT	b3
	MOVL	-(A1), -(A2)
	MOVL	-(A1), -(A2)
	MOVL	-(A1), -(A2)
	MOVL	-(A1), -(A2)
	BRA	b2

/*
 * cleanup byte-at-a-time backward
 */
b3:
	ADDL	$15, R0
	BLT	return
b4:
	MOVB	-(A1), -(A2)
	SUBL	$1, R0
	BGE	b4
	BRA	return