xref: /plan9/sys/src/libc/386/memmove.s (revision 80ee5cbfe36716af62da8896207e9763b8e3d760)
1TEXT memmove(SB), $0
2	MOVL	p1+0(FP), DI
3	MOVL	DI, AX			/* return value */
4	MOVL	p2+4(FP), SI
5	MOVL	n+8(FP), BX
6	CMPL	BX, $0
7	JGT	_ok
8	JEQ	_return			/* nothing to do if n == 0 */
9	MOVL	$0, SI			/* fault if n < 0 */
10
11/*
12 * check and set for backwards:
13 *	(p2 < p1) && ((p2+n) > p1)
14 */
15_ok:
16	CMPL	SI, DI
17	JGT	_forward
18	JEQ	_return			/* nothing to do if p2 == p1 */
19	MOVL	SI, DX
20	ADDL	BX, DX
21	CMPL	DX, DI
22	JGT	_back
23
24/*
25 * copy whole longs
26 */
27_forward:
28	MOVL	BX, CX
29	CLD
30	SHRL	$2, CX
31	ANDL	$3, BX
32	REP;	MOVSL
33
34/*
35 * copy the rest, by bytes
36 */
37	JEQ	_return			/* flags set by above ANDL */
38	MOVL	BX, CX
39	REP;	MOVSB
40
41	RET
42
43/*
44 * whole thing backwards has
45 * adjusted addresses
46 */
47_back:
48	ADDL	BX, DI
49	ADDL	BX, SI
50	STD
51	SUBL	$4, DI
52	SUBL	$4, SI
53/*
54 * copy whole longs
55 */
56	MOVL	BX, CX
57	SHRL	$2, CX
58	ANDL	$3, BX
59	REP;	MOVSL
60/*
61 * copy the rest, by bytes
62 */
63	JEQ	_return			/* flags set by above ANDL */
64
65	ADDL	$3, DI
66	ADDL	$3, SI
67	MOVL	BX, CX
68	REP;	MOVSB
69
70_return:
71	RET
72