PageRenderTime 58ms CodeModel.GetById 18ms app.highlight 33ms RepoModel.GetById 1ms app.codeStats 0ms

/arch/sparc/lib/memcpy.S

https://bitbucket.org/evzijst/gittest
Assembly | 1150 lines | 1008 code | 142 blank | 0 comment | 5 complexity | e763e44919bdcb602f045958f3877b47 MD5 | raw file
   1/* memcpy.S: Sparc optimized memcpy and memmove code
   2 * Hand optimized from GNU libc's memcpy and memmove
   3 * Copyright (C) 1991,1996 Free Software Foundation
   4 * Copyright (C) 1995 Linus Torvalds (Linus.Torvalds@helsinki.fi)
   5 * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
   6 * Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be)
   7 * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
   8 */
   9
  10#ifdef __KERNEL__
  11
  12#define FUNC(x) 											\
  13	.globl	x;		\
  14	.type	x,@function;	\
  15	.align	4;											\
  16x:
  17
  18#undef FASTER_REVERSE
  19#undef FASTER_NONALIGNED
  20#define FASTER_ALIGNED
  21
  22/* In kernel these functions don't return a value.
  23 * One should use macros in asm/string.h for that purpose.
  24 * We return 0, so that bugs are more apparent.
  25 */
  26#define SETUP_RETL
  27#define RETL_INSN	clr	%o0
  28
  29#else
  30
  31/* libc */
  32
  33#include "DEFS.h"
  34
  35#define FASTER_REVERSE
  36#define FASTER_NONALIGNED
  37#define FASTER_ALIGNED
  38
  39#define SETUP_RETL	mov	%o0, %g6
  40#define RETL_INSN	mov	%g6, %o0
  41
  42#endif
  43
  44/* Both these macros have to start with exactly the same insn */
  45#define MOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, t7) \
  46	ldd	[%src + (offset) + 0x00], %t0; \
  47	ldd	[%src + (offset) + 0x08], %t2; \
  48	ldd	[%src + (offset) + 0x10], %t4; \
  49	ldd	[%src + (offset) + 0x18], %t6; \
  50	st	%t0, [%dst + (offset) + 0x00]; \
  51	st	%t1, [%dst + (offset) + 0x04]; \
  52	st	%t2, [%dst + (offset) + 0x08]; \
  53	st	%t3, [%dst + (offset) + 0x0c]; \
  54	st	%t4, [%dst + (offset) + 0x10]; \
  55	st	%t5, [%dst + (offset) + 0x14]; \
  56	st	%t6, [%dst + (offset) + 0x18]; \
  57	st	%t7, [%dst + (offset) + 0x1c];
  58
  59#define MOVE_BIGALIGNCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, t7) \
  60	ldd	[%src + (offset) + 0x00], %t0; \
  61	ldd	[%src + (offset) + 0x08], %t2; \
  62	ldd	[%src + (offset) + 0x10], %t4; \
  63	ldd	[%src + (offset) + 0x18], %t6; \
  64	std	%t0, [%dst + (offset) + 0x00]; \
  65	std	%t2, [%dst + (offset) + 0x08]; \
  66	std	%t4, [%dst + (offset) + 0x10]; \
  67	std	%t6, [%dst + (offset) + 0x18];
  68
  69#define MOVE_LASTCHUNK(src, dst, offset, t0, t1, t2, t3) \
  70	ldd	[%src - (offset) - 0x10], %t0; \
  71	ldd	[%src - (offset) - 0x08], %t2; \
  72	st	%t0, [%dst - (offset) - 0x10]; \
  73	st	%t1, [%dst - (offset) - 0x0c]; \
  74	st	%t2, [%dst - (offset) - 0x08]; \
  75	st	%t3, [%dst - (offset) - 0x04];
  76
  77#define MOVE_LASTALIGNCHUNK(src, dst, offset, t0, t1, t2, t3) \
  78	ldd	[%src - (offset) - 0x10], %t0; \
  79	ldd	[%src - (offset) - 0x08], %t2; \
  80	std	%t0, [%dst - (offset) - 0x10]; \
  81	std	%t2, [%dst - (offset) - 0x08];
  82
  83#define MOVE_SHORTCHUNK(src, dst, offset, t0, t1) \
  84	ldub	[%src - (offset) - 0x02], %t0; \
  85	ldub	[%src - (offset) - 0x01], %t1; \
  86	stb	%t0, [%dst - (offset) - 0x02]; \
  87	stb	%t1, [%dst - (offset) - 0x01];
  88
  89/* Both these macros have to start with exactly the same insn */
  90#define RMOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, t7) \
  91	ldd	[%src - (offset) - 0x20], %t0; \
  92	ldd	[%src - (offset) - 0x18], %t2; \
  93	ldd	[%src - (offset) - 0x10], %t4; \
  94	ldd	[%src - (offset) - 0x08], %t6; \
  95	st	%t0, [%dst - (offset) - 0x20]; \
  96	st	%t1, [%dst - (offset) - 0x1c]; \
  97	st	%t2, [%dst - (offset) - 0x18]; \
  98	st	%t3, [%dst - (offset) - 0x14]; \
  99	st	%t4, [%dst - (offset) - 0x10]; \
 100	st	%t5, [%dst - (offset) - 0x0c]; \
 101	st	%t6, [%dst - (offset) - 0x08]; \
 102	st	%t7, [%dst - (offset) - 0x04];
 103
 104#define RMOVE_BIGALIGNCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, t7) \
 105	ldd	[%src - (offset) - 0x20], %t0; \
 106	ldd	[%src - (offset) - 0x18], %t2; \
 107	ldd	[%src - (offset) - 0x10], %t4; \
 108	ldd	[%src - (offset) - 0x08], %t6; \
 109	std	%t0, [%dst - (offset) - 0x20]; \
 110	std	%t2, [%dst - (offset) - 0x18]; \
 111	std	%t4, [%dst - (offset) - 0x10]; \
 112	std	%t6, [%dst - (offset) - 0x08];
 113
 114#define RMOVE_LASTCHUNK(src, dst, offset, t0, t1, t2, t3) \
 115	ldd	[%src + (offset) + 0x00], %t0; \
 116	ldd	[%src + (offset) + 0x08], %t2; \
 117	st	%t0, [%dst + (offset) + 0x00]; \
 118	st	%t1, [%dst + (offset) + 0x04]; \
 119	st	%t2, [%dst + (offset) + 0x08]; \
 120	st	%t3, [%dst + (offset) + 0x0c];
 121
 122#define RMOVE_SHORTCHUNK(src, dst, offset, t0, t1) \
 123	ldub	[%src + (offset) + 0x00], %t0; \
 124	ldub	[%src + (offset) + 0x01], %t1; \
 125	stb	%t0, [%dst + (offset) + 0x00]; \
 126	stb	%t1, [%dst + (offset) + 0x01];
 127
 128#define SMOVE_CHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, prev, shil, shir, offset2) \
 129	ldd	[%src + (offset) + 0x00], %t0; \
 130	ldd	[%src + (offset) + 0x08], %t2; \
 131	srl	%t0, shir, %t5; \
 132	srl	%t1, shir, %t6; \
 133	sll	%t0, shil, %t0; \
 134	or	%t5, %prev, %t5; \
 135	sll	%t1, shil, %prev; \
 136	or	%t6, %t0, %t0; \
 137	srl	%t2, shir, %t1; \
 138	srl	%t3, shir, %t6; \
 139	sll	%t2, shil, %t2; \
 140	or	%t1, %prev, %t1; \
 141	std	%t4, [%dst + (offset) + (offset2) - 0x04]; \
 142	std	%t0, [%dst + (offset) + (offset2) + 0x04]; \
 143	sll	%t3, shil, %prev; \
 144	or	%t6, %t2, %t4;
 145
 146#define SMOVE_ALIGNCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, prev, shil, shir, offset2) \
 147	ldd	[%src + (offset) + 0x00], %t0; \
 148	ldd	[%src + (offset) + 0x08], %t2; \
 149	srl	%t0, shir, %t4;	\
 150	srl	%t1, shir, %t5;	\
 151	sll	%t0, shil, %t6;	\
 152	or	%t4, %prev, %t0; \
 153	sll	%t1, shil, %prev; \
 154	or	%t5, %t6, %t1; \
 155	srl	%t2, shir, %t4;	\
 156	srl	%t3, shir, %t5;	\
 157	sll	%t2, shil, %t6; \
 158	or	%t4, %prev, %t2; \
 159	sll	%t3, shil, %prev; \
 160	or	%t5, %t6, %t3; \
 161	std	%t0, [%dst + (offset) + (offset2) + 0x00]; \
 162	std	%t2, [%dst + (offset) + (offset2) + 0x08];
 163
 164	.text
 165	.align	4
 166
 167#ifdef FASTER_REVERSE
 168
 16970:	/* rdword_align */
 170
 171	andcc		%o1, 1, %g0
 172	be		4f
 173	 andcc		%o1, 2, %g0
 174
 175	ldub		[%o1 - 1], %g2
 176	sub		%o1, 1, %o1
 177	stb		%g2, [%o0 - 1]
 178	sub		%o2, 1, %o2
 179	be		3f
 180	 sub		%o0, 1, %o0
 1814:
 182	lduh		[%o1 - 2], %g2
 183	sub		%o1, 2, %o1
 184	sth		%g2, [%o0 - 2]
 185	sub		%o2, 2, %o2
 186	b		3f
 187	 sub		%o0, 2, %o0
 188
 189#endif /* FASTER_REVERSE */
 190
 1910:
 192	retl
 193	 nop		! Only bcopy returns here and it retuns void...
 194
 195#ifdef __KERNEL__
 196FUNC(amemmove)
 197FUNC(__memmove)
 198#endif
 199FUNC(memmove)
 200	cmp		%o0, %o1
 201	SETUP_RETL
 202	bleu		9f
 203	 sub		%o0, %o1, %o4
 204
 205	add		%o1, %o2, %o3
 206	cmp		%o3, %o0
 207	bleu		0f
 208	 andcc		%o4, 3, %o5
 209
 210#ifndef FASTER_REVERSE
 211
 212	add		%o1, %o2, %o1
 213	add		%o0, %o2, %o0
 214	sub		%o1, 1, %o1
 215	sub		%o0, 1, %o0
 216	
 2171:	/* reverse_bytes */
 218
 219	ldub		[%o1], %o4
 220	subcc		%o2, 1, %o2
 221	stb		%o4, [%o0]
 222	sub		%o1, 1, %o1
 223	bne		1b
 224	 sub		%o0, 1, %o0
 225
 226	retl
 227	 RETL_INSN
 228
 229#else /* FASTER_REVERSE */
 230
 231	add		%o1, %o2, %o1
 232	add		%o0, %o2, %o0
 233	bne		77f
 234	 cmp		%o2, 15
 235	bleu		91f
 236	 andcc		%o1, 3, %g0
 237	bne		70b
 2383:
 239	 andcc		%o1, 4, %g0
 240
 241	be		2f
 242	 mov		%o2, %g1
 243
 244	ld		[%o1 - 4], %o4
 245	sub		%g1, 4, %g1
 246	st		%o4, [%o0 - 4]
 247	sub		%o1, 4, %o1
 248	sub		%o0, 4, %o0
 2492:
 250	andcc		%g1, 0xffffff80, %g7
 251	be		3f
 252	 andcc		%o0, 4, %g0
 253
 254	be		74f + 4
 2555:
 256	RMOVE_BIGCHUNK(o1, o0, 0x00, o2, o3, o4, o5, g2, g3, g4, g5)
 257	RMOVE_BIGCHUNK(o1, o0, 0x20, o2, o3, o4, o5, g2, g3, g4, g5)
 258	RMOVE_BIGCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5)
 259	RMOVE_BIGCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5)
 260	subcc		%g7, 128, %g7
 261	sub		%o1, 128, %o1
 262	bne		5b
 263	 sub		%o0, 128, %o0
 2643:
 265	andcc		%g1, 0x70, %g7
 266	be		72f
 267	 andcc		%g1, 8, %g0
 268
 269	sethi		%hi(72f), %o5
 270	srl		%g7, 1, %o4
 271	add		%g7, %o4, %o4
 272	sub		%o1, %g7, %o1
 273	sub		%o5, %o4, %o5
 274	jmpl		%o5 + %lo(72f), %g0
 275	 sub		%o0, %g7, %o0
 276
 27771:	/* rmemcpy_table */
 278	RMOVE_LASTCHUNK(o1, o0, 0x60, g2, g3, g4, g5)
 279	RMOVE_LASTCHUNK(o1, o0, 0x50, g2, g3, g4, g5)
 280	RMOVE_LASTCHUNK(o1, o0, 0x40, g2, g3, g4, g5)
 281	RMOVE_LASTCHUNK(o1, o0, 0x30, g2, g3, g4, g5)
 282	RMOVE_LASTCHUNK(o1, o0, 0x20, g2, g3, g4, g5)
 283	RMOVE_LASTCHUNK(o1, o0, 0x10, g2, g3, g4, g5)
 284	RMOVE_LASTCHUNK(o1, o0, 0x00, g2, g3, g4, g5)
 285
 28672:	/* rmemcpy_table_end */
 287
 288	be		73f
 289	 andcc		%g1, 4, %g0
 290
 291	ldd		[%o1 - 0x08], %g2
 292	sub		%o0, 8, %o0
 293	sub		%o1, 8, %o1
 294	st		%g2, [%o0]
 295	st		%g3, [%o0 + 0x04]
 296
 29773:	/* rmemcpy_last7 */
 298
 299	be		1f
 300	 andcc		%g1, 2, %g0
 301
 302	ld		[%o1 - 4], %g2
 303	sub		%o1, 4, %o1
 304	st		%g2, [%o0 - 4]
 305	sub		%o0, 4, %o0
 3061:
 307	be		1f
 308	 andcc		%g1, 1, %g0
 309
 310	lduh		[%o1 - 2], %g2
 311	sub		%o1, 2, %o1
 312	sth		%g2, [%o0 - 2]
 313	sub		%o0, 2, %o0
 3141:
 315	be		1f
 316	 nop
 317
 318	ldub		[%o1 - 1], %g2
 319	stb		%g2, [%o0 - 1]
 3201:
 321	retl
 322 	 RETL_INSN
 323
 32474:	/* rldd_std */
 325	RMOVE_BIGALIGNCHUNK(o1, o0, 0x00, o2, o3, o4, o5, g2, g3, g4, g5)
 326	RMOVE_BIGALIGNCHUNK(o1, o0, 0x20, o2, o3, o4, o5, g2, g3, g4, g5)
 327	RMOVE_BIGALIGNCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5)
 328	RMOVE_BIGALIGNCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5)
 329	subcc		%g7, 128, %g7
 330	sub		%o1, 128, %o1
 331	bne		74b
 332	 sub		%o0, 128, %o0
 333
 334	andcc		%g1, 0x70, %g7
 335	be		72b
 336	 andcc		%g1, 8, %g0
 337
 338	sethi		%hi(72b), %o5
 339	srl		%g7, 1, %o4
 340	add		%g7, %o4, %o4
 341	sub		%o1, %g7, %o1
 342	sub		%o5, %o4, %o5
 343	jmpl		%o5 + %lo(72b), %g0
 344	 sub		%o0, %g7, %o0
 345
 34675:	/* rshort_end */
 347
 348	and		%o2, 0xe, %o3
 3492:
 350	sethi		%hi(76f), %o5
 351	sll		%o3, 3, %o4
 352	sub		%o0, %o3, %o0
 353	sub		%o5, %o4, %o5
 354	sub		%o1, %o3, %o1
 355	jmpl		%o5 + %lo(76f), %g0
 356	 andcc		%o2, 1, %g0
 357
 358	RMOVE_SHORTCHUNK(o1, o0, 0x0c, g2, g3)
 359	RMOVE_SHORTCHUNK(o1, o0, 0x0a, g2, g3)
 360	RMOVE_SHORTCHUNK(o1, o0, 0x08, g2, g3)
 361	RMOVE_SHORTCHUNK(o1, o0, 0x06, g2, g3)
 362	RMOVE_SHORTCHUNK(o1, o0, 0x04, g2, g3)
 363	RMOVE_SHORTCHUNK(o1, o0, 0x02, g2, g3)
 364	RMOVE_SHORTCHUNK(o1, o0, 0x00, g2, g3)
 365
 36676:	/* rshort_table_end */
 367
 368	be		1f
 369	 nop
 370	ldub		[%o1 - 1], %g2
 371	stb		%g2, [%o0 - 1]
 3721:
 373	retl
 374 	 RETL_INSN
 375
 37691:	/* rshort_aligned_end */
 377
 378	bne		75b
 379	 andcc		%o2, 8, %g0
 380
 381	be		1f
 382	 andcc		%o2, 4, %g0
 383
 384	ld		[%o1 - 0x08], %g2
 385	ld		[%o1 - 0x04], %g3
 386	sub		%o1, 8, %o1
 387	st		%g2, [%o0 - 0x08]
 388	st		%g3, [%o0 - 0x04]
 389	sub		%o0, 8, %o0
 3901:
 391	b		73b
 392	 mov		%o2, %g1
 393
 39477:	/* rnon_aligned */
 395	cmp		%o2, 15
 396	bleu		75b
 397	 andcc		%o0, 3, %g0
 398	be		64f
 399	 andcc		%o0, 1, %g0
 400	be		63f
 401	 andcc		%o0, 2, %g0
 402	ldub		[%o1 - 1], %g5
 403	sub		%o1, 1, %o1
 404	stb		%g5, [%o0 - 1]
 405	sub		%o0, 1, %o0
 406	be		64f
 407	 sub		%o2, 1, %o2
 40863:
 409	ldub		[%o1 - 1], %g5
 410	sub		%o1, 2, %o1
 411	stb		%g5, [%o0 - 1]
 412	sub		%o0, 2, %o0
 413	ldub		[%o1], %g5
 414	sub		%o2, 2, %o2
 415	stb		%g5, [%o0]
 41664:	
 417	and		%o1, 3, %g2
 418	and		%o1, -4, %o1
 419	and		%o2, 0xc, %g3
 420	add		%o1, 4, %o1
 421	cmp		%g3, 4
 422	sll		%g2, 3, %g4
 423	mov		32, %g2
 424	be		4f
 425	 sub		%g2, %g4, %g7
 426
 427	blu		3f
 428	 cmp		%g3, 8
 429
 430	be		2f
 431	 srl		%o2, 2, %g3
 432
 433	ld		[%o1 - 4], %o3
 434	add		%o0, -8, %o0
 435	ld		[%o1 - 8], %o4
 436	add		%o1, -16, %o1
 437	b		7f
 438	 add		%g3, 1, %g3
 4392:
 440	ld		[%o1 - 4], %o4
 441	add		%o0, -4, %o0
 442	ld		[%o1 - 8], %g1
 443	add		%o1, -12, %o1
 444	b		8f
 445	 add		%g3, 2, %g3
 4463:
 447	ld		[%o1 - 4], %o5
 448	add		%o0, -12, %o0
 449	ld		[%o1 - 8], %o3
 450	add		%o1, -20, %o1
 451	b		6f
 452	 srl		%o2, 2, %g3
 4534:
 454	ld		[%o1 - 4], %g1
 455	srl		%o2, 2, %g3
 456	ld		[%o1 - 8], %o5
 457	add		%o1, -24, %o1
 458	add		%o0, -16, %o0
 459	add		%g3, -1, %g3
 460
 461	ld		[%o1 + 12], %o3
 4625:
 463	sll		%o5, %g4, %g2
 464	srl		%g1, %g7, %g5
 465	or		%g2, %g5, %g2
 466	st		%g2, [%o0 + 12]
 4676:
 468	ld		[%o1 + 8], %o4
 469	sll		%o3, %g4, %g2
 470	srl		%o5, %g7, %g5
 471	or		%g2, %g5, %g2
 472	st		%g2, [%o0 + 8]
 4737:
 474	ld		[%o1 + 4], %g1
 475	sll		%o4, %g4, %g2
 476	srl		%o3, %g7, %g5
 477	or		%g2, %g5, %g2
 478	st		%g2, [%o0 + 4]
 4798:
 480	ld		[%o1], %o5
 481	sll		%g1, %g4, %g2
 482	srl		%o4, %g7, %g5
 483	addcc		%g3, -4, %g3
 484	or		%g2, %g5, %g2
 485	add		%o1, -16, %o1
 486	st		%g2, [%o0]
 487	add		%o0, -16, %o0
 488	bne,a		5b	
 489	 ld		[%o1 + 12], %o3
 490	sll		%o5, %g4, %g2
 491	srl		%g1, %g7, %g5
 492	srl		%g4, 3, %g3
 493	or		%g2, %g5, %g2
 494	add		%o1, %g3, %o1
 495	andcc		%o2, 2, %g0
 496	st		%g2, [%o0 + 12]
 497	be		1f
 498	 andcc		%o2, 1, %g0
 499	
 500	ldub		[%o1 + 15], %g5
 501	add		%o1, -2, %o1
 502	stb		%g5, [%o0 + 11]
 503	add		%o0, -2, %o0
 504	ldub		[%o1 + 16], %g5
 505	stb		%g5, [%o0 + 12]
 5061:
 507	be		1f
 508	 nop
 509	ldub		[%o1 + 15], %g5
 510	stb		%g5, [%o0 + 11]
 5111:
 512	retl
 513	 RETL_INSN
 514
 515#endif /* FASTER_REVERSE */
 516
 517/* NOTE: This code is executed just for the cases,
 518         where %src (=%o1) & 3 is != 0.
 519	 We need to align it to 4. So, for (%src & 3)
 520	 1 we need to do ldub,lduh
 521	 2 lduh
 522	 3 just ldub
 523         so even if it looks weird, the branches
 524         are correct here. -jj
 525 */
 52678:	/* dword_align */
 527
 528	andcc		%o1, 1, %g0
 529	be		4f
 530	 andcc		%o1, 2, %g0
 531
 532	ldub		[%o1], %g2
 533	add		%o1, 1, %o1
 534	stb		%g2, [%o0]
 535	sub		%o2, 1, %o2
 536	bne		3f
 537	 add		%o0, 1, %o0
 5384:
 539	lduh		[%o1], %g2
 540	add		%o1, 2, %o1
 541	sth		%g2, [%o0]
 542	sub		%o2, 2, %o2
 543	b		3f
 544	 add		%o0, 2, %o0
 545
 546#ifdef __KERNEL__
 547FUNC(__memcpy)
 548#endif
 549FUNC(memcpy)	/* %o0=dst %o1=src %o2=len */
 550
 551	sub		%o0, %o1, %o4
 552	SETUP_RETL
 5539:
 554	andcc		%o4, 3, %o5
 5550:
 556	bne		86f
 557	 cmp		%o2, 15
 558
 559	bleu		90f
 560	 andcc		%o1, 3, %g0
 561
 562	bne		78b
 5633:
 564	 andcc		%o1, 4, %g0
 565
 566	be		2f
 567	 mov		%o2, %g1
 568
 569	ld		[%o1], %o4
 570	sub		%g1, 4, %g1
 571	st		%o4, [%o0]
 572	add		%o1, 4, %o1
 573	add		%o0, 4, %o0
 5742:
 575	andcc		%g1, 0xffffff80, %g7
 576	be		3f
 577	 andcc		%o0, 4, %g0
 578
 579	be		82f + 4
 5805:
 581	MOVE_BIGCHUNK(o1, o0, 0x00, o2, o3, o4, o5, g2, g3, g4, g5)
 582	MOVE_BIGCHUNK(o1, o0, 0x20, o2, o3, o4, o5, g2, g3, g4, g5)
 583	MOVE_BIGCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5)
 584	MOVE_BIGCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5)
 585	subcc		%g7, 128, %g7
 586	add		%o1, 128, %o1
 587	bne		5b
 588	 add		%o0, 128, %o0
 5893:
 590	andcc		%g1, 0x70, %g7
 591	be		80f
 592	 andcc		%g1, 8, %g0
 593
 594	sethi		%hi(80f), %o5
 595	srl		%g7, 1, %o4
 596	add		%g7, %o4, %o4
 597	add		%o1, %g7, %o1
 598	sub		%o5, %o4, %o5
 599	jmpl		%o5 + %lo(80f), %g0
 600	 add		%o0, %g7, %o0
 601
 60279:	/* memcpy_table */
 603
 604	MOVE_LASTCHUNK(o1, o0, 0x60, g2, g3, g4, g5)
 605	MOVE_LASTCHUNK(o1, o0, 0x50, g2, g3, g4, g5)
 606	MOVE_LASTCHUNK(o1, o0, 0x40, g2, g3, g4, g5)
 607	MOVE_LASTCHUNK(o1, o0, 0x30, g2, g3, g4, g5)
 608	MOVE_LASTCHUNK(o1, o0, 0x20, g2, g3, g4, g5)
 609	MOVE_LASTCHUNK(o1, o0, 0x10, g2, g3, g4, g5)
 610	MOVE_LASTCHUNK(o1, o0, 0x00, g2, g3, g4, g5)
 611
 61280:	/* memcpy_table_end */
 613	be		81f
 614	 andcc		%g1, 4, %g0
 615
 616	ldd		[%o1], %g2
 617	add		%o0, 8, %o0
 618	st		%g2, [%o0 - 0x08]
 619	add		%o1, 8, %o1
 620	st		%g3, [%o0 - 0x04]
 621
 62281:	/* memcpy_last7 */
 623
 624	be		1f
 625	 andcc		%g1, 2, %g0
 626
 627	ld		[%o1], %g2
 628	add		%o1, 4, %o1
 629	st		%g2, [%o0]
 630	add		%o0, 4, %o0
 6311:
 632	be		1f
 633	 andcc		%g1, 1, %g0
 634
 635	lduh		[%o1], %g2
 636	add		%o1, 2, %o1
 637	sth		%g2, [%o0]
 638	add		%o0, 2, %o0
 6391:
 640	be		1f
 641	 nop
 642
 643	ldub		[%o1], %g2
 644	stb		%g2, [%o0]
 6451:
 646	retl
 647 	 RETL_INSN
 648
 64982:	/* ldd_std */
 650	MOVE_BIGALIGNCHUNK(o1, o0, 0x00, o2, o3, o4, o5, g2, g3, g4, g5)
 651	MOVE_BIGALIGNCHUNK(o1, o0, 0x20, o2, o3, o4, o5, g2, g3, g4, g5)
 652	MOVE_BIGALIGNCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5)
 653	MOVE_BIGALIGNCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5)
 654	subcc		%g7, 128, %g7
 655	add		%o1, 128, %o1
 656	bne		82b
 657	 add		%o0, 128, %o0
 658
 659#ifndef FASTER_ALIGNED
 660
 661	andcc		%g1, 0x70, %g7
 662	be		80b
 663	 andcc		%g1, 8, %g0
 664
 665	sethi		%hi(80b), %o5
 666	srl		%g7, 1, %o4
 667	add		%g7, %o4, %o4
 668	add		%o1, %g7, %o1
 669	sub		%o5, %o4, %o5
 670	jmpl		%o5 + %lo(80b), %g0
 671	 add		%o0, %g7, %o0
 672
 673#else /* FASTER_ALIGNED */
 674
 675	andcc		%g1, 0x70, %g7
 676	be		84f
 677	 andcc		%g1, 8, %g0
 678
 679	sethi		%hi(84f), %o5
 680	add		%o1, %g7, %o1
 681	sub		%o5, %g7, %o5
 682	jmpl		%o5 + %lo(84f), %g0
 683	 add		%o0, %g7, %o0
 684
 68583:	/* amemcpy_table */
 686
 687	MOVE_LASTALIGNCHUNK(o1, o0, 0x60, g2, g3, g4, g5)
 688	MOVE_LASTALIGNCHUNK(o1, o0, 0x50, g2, g3, g4, g5)
 689	MOVE_LASTALIGNCHUNK(o1, o0, 0x40, g2, g3, g4, g5)
 690	MOVE_LASTALIGNCHUNK(o1, o0, 0x30, g2, g3, g4, g5)
 691	MOVE_LASTALIGNCHUNK(o1, o0, 0x20, g2, g3, g4, g5)
 692	MOVE_LASTALIGNCHUNK(o1, o0, 0x10, g2, g3, g4, g5)
 693	MOVE_LASTALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5)
 694
 69584:	/* amemcpy_table_end */
 696	be		85f
 697	 andcc		%g1, 4, %g0
 698
 699	ldd		[%o1], %g2
 700	add		%o0, 8, %o0
 701	std		%g2, [%o0 - 0x08]
 702	add		%o1, 8, %o1
 70385:	/* amemcpy_last7 */
 704	be		1f
 705	 andcc		%g1, 2, %g0
 706
 707	ld		[%o1], %g2
 708	add		%o1, 4, %o1
 709	st		%g2, [%o0]
 710	add		%o0, 4, %o0
 7111:
 712	be		1f
 713	 andcc		%g1, 1, %g0
 714
 715	lduh		[%o1], %g2
 716	add		%o1, 2, %o1
 717	sth		%g2, [%o0]
 718	add		%o0, 2, %o0
 7191:
 720	be		1f
 721	 nop
 722
 723	ldub		[%o1], %g2
 724	stb		%g2, [%o0]
 7251:
 726	retl
 727 	 RETL_INSN
 728
 729#endif /* FASTER_ALIGNED */
 730
 73186:	/* non_aligned */
 732	cmp		%o2, 6
 733	bleu		88f
 734
 735#ifdef FASTER_NONALIGNED
 736
 737	 cmp		%o2, 256
 738	bcc		87f
 739
 740#endif /* FASTER_NONALIGNED */
 741
 742	 andcc		%o0, 3, %g0
 743	be		61f
 744	 andcc		%o0, 1, %g0
 745	be		60f
 746	 andcc		%o0, 2, %g0
 747
 748	ldub		[%o1], %g5
 749	add		%o1, 1, %o1
 750	stb		%g5, [%o0]
 751	sub		%o2, 1, %o2
 752	bne		61f
 753	 add		%o0, 1, %o0
 75460:
 755	ldub		[%o1], %g3
 756	add		%o1, 2, %o1
 757	stb		%g3, [%o0]
 758	sub		%o2, 2, %o2
 759	ldub		[%o1 - 1], %g3
 760	add		%o0, 2, %o0
 761	stb		%g3, [%o0 - 1]
 76261:
 763	and		%o1, 3, %g2
 764	and		%o2, 0xc, %g3
 765	and		%o1, -4, %o1
 766	cmp		%g3, 4
 767	sll		%g2, 3, %g4
 768	mov		32, %g2
 769	be		4f
 770	 sub		%g2, %g4, %g7
 771	
 772	blu		3f
 773	 cmp		%g3, 0x8
 774
 775	be		2f
 776	 srl		%o2, 2, %g3
 777
 778	ld		[%o1], %o3
 779	add		%o0, -8, %o0
 780	ld		[%o1 + 4], %o4
 781	b		8f
 782	 add		%g3, 1, %g3
 7832:
 784	ld		[%o1], %o4
 785	add		%o0, -12, %o0
 786	ld		[%o1 + 4], %o5
 787	add		%g3, 2, %g3
 788	b		9f
 789	 add		%o1, -4, %o1
 7903:
 791	ld		[%o1], %g1
 792	add		%o0, -4, %o0
 793	ld		[%o1 + 4], %o3
 794	srl		%o2, 2, %g3
 795	b		7f
 796	 add		%o1, 4, %o1
 7974:
 798	ld		[%o1], %o5
 799	cmp		%o2, 7
 800	ld		[%o1 + 4], %g1
 801	srl		%o2, 2, %g3
 802	bleu		10f
 803	 add		%o1, 8, %o1
 804
 805	ld		[%o1], %o3
 806	add		%g3, -1, %g3
 8075:
 808	sll		%o5, %g4, %g2
 809	srl		%g1, %g7, %g5
 810	or		%g2, %g5, %g2
 811	st		%g2, [%o0]
 8127:
 813	ld		[%o1 + 4], %o4
 814	sll		%g1, %g4, %g2
 815	srl		%o3, %g7, %g5
 816	or		%g2, %g5, %g2
 817	st		%g2, [%o0 + 4]
 8188:
 819	ld		[%o1 + 8], %o5
 820	sll		%o3, %g4, %g2
 821	srl		%o4, %g7, %g5
 822	or		%g2, %g5, %g2
 823	st		%g2, [%o0 + 8]
 8249:
 825	ld		[%o1 + 12], %g1
 826	sll		%o4, %g4, %g2
 827	srl		%o5, %g7, %g5
 828	addcc		%g3, -4, %g3
 829	or		%g2, %g5, %g2
 830	add		%o1, 16, %o1
 831	st		%g2, [%o0 + 12]
 832	add		%o0, 16, %o0
 833	bne,a		5b
 834	 ld		[%o1], %o3
 83510:
 836	sll		%o5, %g4, %g2
 837	srl		%g1, %g7, %g5
 838	srl		%g7, 3, %g3
 839	or		%g2, %g5, %g2
 840	sub		%o1, %g3, %o1
 841	andcc		%o2, 2, %g0
 842	st		%g2, [%o0]
 843	be		1f
 844	 andcc		%o2, 1, %g0
 845
 846	ldub		[%o1], %g2
 847	add		%o1, 2, %o1
 848	stb		%g2, [%o0 + 4]
 849	add		%o0, 2, %o0
 850	ldub		[%o1 - 1], %g2
 851	stb		%g2, [%o0 + 3]
 8521:
 853	be		1f
 854	 nop
 855	ldub		[%o1], %g2
 856	stb		%g2, [%o0 + 4]
 8571:
 858	retl
 859	 RETL_INSN
 860
 861#ifdef FASTER_NONALIGNED
 862
 86387:	/* faster_nonaligned */
 864
 865	andcc		%o1, 3, %g0
 866	be		3f
 867	 andcc		%o1, 1, %g0
 868
 869	be		4f
 870	 andcc		%o1, 2, %g0
 871
 872	ldub		[%o1], %g2
 873	add		%o1, 1, %o1
 874	stb		%g2, [%o0]
 875	sub		%o2, 1, %o2
 876	bne		3f
 877	 add		%o0, 1, %o0
 8784:
 879	lduh		[%o1], %g2
 880	add		%o1, 2, %o1
 881	srl		%g2, 8, %g3
 882	sub		%o2, 2, %o2
 883	stb		%g3, [%o0]
 884	add		%o0, 2, %o0
 885	stb		%g2, [%o0 - 1]
 8863:
 887	 andcc		%o1, 4, %g0
 888
 889	bne		2f
 890	 cmp		%o5, 1
 891
 892	ld		[%o1], %o4
 893	srl		%o4, 24, %g2
 894	stb		%g2, [%o0]
 895	srl		%o4, 16, %g3
 896	stb		%g3, [%o0 + 1]
 897	srl		%o4, 8, %g2
 898	stb		%g2, [%o0 + 2]
 899	sub		%o2, 4, %o2
 900	stb		%o4, [%o0 + 3]
 901	add		%o1, 4, %o1
 902	add		%o0, 4, %o0
 9032:
 904	be		33f
 905	 cmp		%o5, 2
 906	be		32f
 907	 sub		%o2, 4, %o2
 90831:
 909	ld		[%o1], %g2
 910	add		%o1, 4, %o1
 911	srl		%g2, 24, %g3
 912	and		%o0, 7, %g5
 913	stb		%g3, [%o0]
 914	cmp		%g5, 7
 915	sll		%g2, 8, %g1
 916	add		%o0, 4, %o0
 917	be		41f
 918	 and		%o2, 0xffffffc0, %o3
 919	ld		[%o0 - 7], %o4
 9204:
 921	SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3)
 922	SMOVE_CHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3)
 923	SMOVE_CHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3)
 924	SMOVE_CHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3)
 925	subcc		%o3, 64, %o3
 926	add		%o1, 64, %o1
 927	bne		4b
 928	 add		%o0, 64, %o0
 929
 930	andcc		%o2, 0x30, %o3
 931	be,a		1f
 932	 srl		%g1, 16, %g2
 9334:
 934	SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3)
 935	subcc		%o3, 16, %o3
 936	add		%o1, 16, %o1
 937	bne		4b
 938	 add		%o0, 16, %o0
 939
 940	srl		%g1, 16, %g2
 9411:
 942	st		%o4, [%o0 - 7]
 943	sth		%g2, [%o0 - 3]
 944	srl		%g1, 8, %g4
 945	b		88f
 946	 stb		%g4, [%o0 - 1]
 94732:
 948	ld		[%o1], %g2
 949	add		%o1, 4, %o1
 950	srl		%g2, 16, %g3
 951	and		%o0, 7, %g5
 952	sth		%g3, [%o0]
 953	cmp		%g5, 6
 954	sll		%g2, 16, %g1
 955	add		%o0, 4, %o0
 956	be		42f
 957	 and		%o2, 0xffffffc0, %o3
 958	ld		[%o0 - 6], %o4
 9594:
 960	SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2)
 961	SMOVE_CHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2)
 962	SMOVE_CHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2)
 963	SMOVE_CHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2)
 964	subcc		%o3, 64, %o3
 965	add		%o1, 64, %o1
 966	bne		4b
 967	 add		%o0, 64, %o0
 968
 969	andcc		%o2, 0x30, %o3
 970	be,a		1f
 971	 srl		%g1, 16, %g2
 9724:
 973	SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2)
 974	subcc		%o3, 16, %o3
 975	add		%o1, 16, %o1
 976	bne		4b
 977	 add		%o0, 16, %o0
 978
 979	srl		%g1, 16, %g2
 9801:
 981	st		%o4, [%o0 - 6]
 982	b		88f
 983	 sth		%g2, [%o0 - 2]
 98433:
 985	ld		[%o1], %g2
 986	sub		%o2, 4, %o2
 987	srl		%g2, 24, %g3
 988	and		%o0, 7, %g5
 989	stb		%g3, [%o0]
 990	cmp		%g5, 5
 991	srl		%g2, 8, %g4
 992	sll		%g2, 24, %g1
 993	sth		%g4, [%o0 + 1]
 994	add		%o1, 4, %o1
 995	be		43f
 996	 and		%o2, 0xffffffc0, %o3
 997
 998	ld		[%o0 - 1], %o4
 999	add		%o0, 4, %o0
10004:
1001	SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, -1)
1002	SMOVE_CHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, -1)
1003	SMOVE_CHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, -1)
1004	SMOVE_CHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, -1)
1005	subcc		%o3, 64, %o3
1006	add		%o1, 64, %o1
1007	bne		4b
1008	 add		%o0, 64, %o0
1009
1010	andcc		%o2, 0x30, %o3
1011	be,a		1f
1012	 srl		%g1, 24, %g2
10134:
1014	SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, -1)
1015	subcc		%o3, 16, %o3
1016	add		%o1, 16, %o1
1017	bne		4b
1018	 add		%o0, 16, %o0
1019
1020	srl		%g1, 24, %g2
10211:
1022	st		%o4, [%o0 - 5]
1023	b		88f
1024	 stb		%g2, [%o0 - 1]
102541:
1026	SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3)
1027	SMOVE_ALIGNCHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3)
1028	SMOVE_ALIGNCHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3)
1029	SMOVE_ALIGNCHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3)
1030	subcc		%o3, 64, %o3
1031	add		%o1, 64, %o1
1032	bne		41b
1033	 add		%o0, 64, %o0
1034	 
1035	andcc		%o2, 0x30, %o3
1036	be,a		1f
1037	 srl		%g1, 16, %g2
10384:
1039	SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3)
1040	subcc		%o3, 16, %o3
1041	add		%o1, 16, %o1
1042	bne		4b
1043	 add		%o0, 16, %o0
1044
1045	srl		%g1, 16, %g2
10461:
1047	sth		%g2, [%o0 - 3]
1048	srl		%g1, 8, %g4
1049	b		88f
1050	 stb		%g4, [%o0 - 1]
105143:
1052	SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, 3)
1053	SMOVE_ALIGNCHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, 3)
1054	SMOVE_ALIGNCHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, 3)
1055	SMOVE_ALIGNCHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, 3)
1056	subcc		%o3, 64, %o3
1057	add		%o1, 64, %o1
1058	bne		43b
1059	 add		%o0, 64, %o0
1060
1061	andcc		%o2, 0x30, %o3
1062	be,a		1f
1063	 srl		%g1, 24, %g2
10644:
1065	SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, 3)
1066	subcc		%o3, 16, %o3
1067	add		%o1, 16, %o1
1068	bne		4b
1069	 add		%o0, 16, %o0
1070
1071	srl		%g1, 24, %g2
10721:
1073	stb		%g2, [%o0 + 3]
1074	b		88f
1075	 add		%o0, 4, %o0
107642:
1077	SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2)
1078	SMOVE_ALIGNCHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2)
1079	SMOVE_ALIGNCHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2)
1080	SMOVE_ALIGNCHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2)
1081	subcc		%o3, 64, %o3
1082	add		%o1, 64, %o1
1083	bne		42b
1084	 add		%o0, 64, %o0
1085	 
1086	andcc		%o2, 0x30, %o3
1087	be,a		1f
1088	 srl		%g1, 16, %g2
10894:
1090	SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2)
1091	subcc		%o3, 16, %o3
1092	add		%o1, 16, %o1
1093	bne		4b
1094	 add		%o0, 16, %o0
1095
1096	srl		%g1, 16, %g2
10971:
1098	sth		%g2, [%o0 - 2]
1099
1100	/* Fall through */
1101	 
1102#endif /* FASTER_NONALIGNED */
1103
110488:	/* short_end */
1105
1106	and		%o2, 0xe, %o3
110720:
1108	sethi		%hi(89f), %o5
1109	sll		%o3, 3, %o4
1110	add		%o0, %o3, %o0
1111	sub		%o5, %o4, %o5
1112	add		%o1, %o3, %o1
1113	jmpl		%o5 + %lo(89f), %g0
1114	 andcc		%o2, 1, %g0
1115
1116	MOVE_SHORTCHUNK(o1, o0, 0x0c, g2, g3)
1117	MOVE_SHORTCHUNK(o1, o0, 0x0a, g2, g3)
1118	MOVE_SHORTCHUNK(o1, o0, 0x08, g2, g3)
1119	MOVE_SHORTCHUNK(o1, o0, 0x06, g2, g3)
1120	MOVE_SHORTCHUNK(o1, o0, 0x04, g2, g3)
1121	MOVE_SHORTCHUNK(o1, o0, 0x02, g2, g3)
1122	MOVE_SHORTCHUNK(o1, o0, 0x00, g2, g3)
1123
112489:	/* short_table_end */
1125
1126	be		1f
1127	 nop
1128
1129	ldub		[%o1], %g2
1130	stb		%g2, [%o0]
11311:
1132	retl
1133 	 RETL_INSN
1134
113590:	/* short_aligned_end */
1136	bne		88b
1137	 andcc		%o2, 8, %g0
1138
1139	be		1f
1140	 andcc		%o2, 4, %g0
1141
1142	ld		[%o1 + 0x00], %g2
1143	ld		[%o1 + 0x04], %g3
1144	add		%o1, 8, %o1
1145	st		%g2, [%o0 + 0x00]
1146	st		%g3, [%o0 + 0x04]
1147	add		%o0, 8, %o0
11481:
1149	b		81b
1150	 mov		%o2, %g1