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 546FUNC(memcpy) /* %o0=dst %o1=src %o2=len */ 547 548 sub %o0, %o1, %o4 549 SETUP_RETL 5509: 551 andcc %o4, 3, %o5 5520: 553 bne 86f 554 cmp %o2, 15 555 556 bleu 90f 557 andcc %o1, 3, %g0 558 559 bne 78b 5603: 561 andcc %o1, 4, %g0 562 563 be 2f 564 mov %o2, %g1 565 566 ld [%o1], %o4 567 sub %g1, 4, %g1 568 st %o4, [%o0] 569 add %o1, 4, %o1 570 add %o0, 4, %o0 5712: 572 andcc %g1, 0xffffff80, %g7 573 be 3f 574 andcc %o0, 4, %g0 575 576 be 82f + 4 5775: 578 MOVE_BIGCHUNK(o1, o0, 0x00, o2, o3, o4, o5, g2, g3, g4, g5) 579 MOVE_BIGCHUNK(o1, o0, 0x20, o2, o3, o4, o5, g2, g3, g4, g5) 580 MOVE_BIGCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5) 581 MOVE_BIGCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5) 582 subcc %g7, 128, %g7 583 add %o1, 128, %o1 584 bne 5b 585 add %o0, 128, %o0 5863: 587 andcc %g1, 0x70, %g7 588 be 80f 589 andcc %g1, 8, %g0 590 591 sethi %hi(80f), %o5 592 srl %g7, 1, %o4 593 add %g7, %o4, %o4 594 add %o1, %g7, %o1 595 sub %o5, %o4, %o5 596 jmpl %o5 + %lo(80f), %g0 597 add %o0, %g7, %o0 598 59979: /* memcpy_table */ 600 601 MOVE_LASTCHUNK(o1, o0, 0x60, g2, g3, g4, g5) 602 MOVE_LASTCHUNK(o1, o0, 0x50, g2, g3, g4, g5) 603 MOVE_LASTCHUNK(o1, o0, 0x40, g2, g3, g4, g5) 604 MOVE_LASTCHUNK(o1, o0, 0x30, g2, g3, g4, g5) 605 MOVE_LASTCHUNK(o1, o0, 0x20, g2, g3, g4, g5) 606 MOVE_LASTCHUNK(o1, o0, 0x10, g2, g3, g4, g5) 607 MOVE_LASTCHUNK(o1, o0, 0x00, g2, g3, g4, g5) 608 60980: /* memcpy_table_end */ 610 be 81f 611 andcc %g1, 4, %g0 612 613 ldd [%o1], %g2 614 add %o0, 8, %o0 615 st %g2, [%o0 - 0x08] 616 add %o1, 8, %o1 617 st %g3, [%o0 - 0x04] 618 61981: /* memcpy_last7 */ 620 621 be 1f 622 andcc %g1, 2, %g0 623 624 ld [%o1], %g2 625 add %o1, 4, %o1 626 st %g2, [%o0] 627 add %o0, 4, %o0 6281: 629 be 1f 630 andcc %g1, 1, %g0 631 632 lduh [%o1], %g2 633 add %o1, 2, %o1 634 sth %g2, [%o0] 635 add %o0, 2, %o0 6361: 637 be 1f 638 nop 639 640 ldub [%o1], %g2 641 stb %g2, [%o0] 6421: 643 retl 644 RETL_INSN 645 64682: /* ldd_std */ 647 MOVE_BIGALIGNCHUNK(o1, o0, 0x00, o2, o3, o4, o5, g2, g3, g4, g5) 648 MOVE_BIGALIGNCHUNK(o1, o0, 0x20, o2, o3, o4, o5, g2, g3, g4, g5) 649 MOVE_BIGALIGNCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5) 650 MOVE_BIGALIGNCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5) 651 subcc %g7, 128, %g7 652 add %o1, 128, %o1 653 bne 82b 654 add %o0, 128, %o0 655 656#ifndef FASTER_ALIGNED 657 658 andcc %g1, 0x70, %g7 659 be 80b 660 andcc %g1, 8, %g0 661 662 sethi %hi(80b), %o5 663 srl %g7, 1, %o4 664 add %g7, %o4, %o4 665 add %o1, %g7, %o1 666 sub %o5, %o4, %o5 667 jmpl %o5 + %lo(80b), %g0 668 add %o0, %g7, %o0 669 670#else /* FASTER_ALIGNED */ 671 672 andcc %g1, 0x70, %g7 673 be 84f 674 andcc %g1, 8, %g0 675 676 sethi %hi(84f), %o5 677 add %o1, %g7, %o1 678 sub %o5, %g7, %o5 679 jmpl %o5 + %lo(84f), %g0 680 add %o0, %g7, %o0 681 68283: /* amemcpy_table */ 683 684 MOVE_LASTALIGNCHUNK(o1, o0, 0x60, g2, g3, g4, g5) 685 MOVE_LASTALIGNCHUNK(o1, o0, 0x50, g2, g3, g4, g5) 686 MOVE_LASTALIGNCHUNK(o1, o0, 0x40, g2, g3, g4, g5) 687 MOVE_LASTALIGNCHUNK(o1, o0, 0x30, g2, g3, g4, g5) 688 MOVE_LASTALIGNCHUNK(o1, o0, 0x20, g2, g3, g4, g5) 689 MOVE_LASTALIGNCHUNK(o1, o0, 0x10, g2, g3, g4, g5) 690 MOVE_LASTALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5) 691 69284: /* amemcpy_table_end */ 693 be 85f 694 andcc %g1, 4, %g0 695 696 ldd [%o1], %g2 697 add %o0, 8, %o0 698 std %g2, [%o0 - 0x08] 699 add %o1, 8, %o1 70085: /* amemcpy_last7 */ 701 be 1f 702 andcc %g1, 2, %g0 703 704 ld [%o1], %g2 705 add %o1, 4, %o1 706 st %g2, [%o0] 707 add %o0, 4, %o0 7081: 709 be 1f 710 andcc %g1, 1, %g0 711 712 lduh [%o1], %g2 713 add %o1, 2, %o1 714 sth %g2, [%o0] 715 add %o0, 2, %o0 7161: 717 be 1f 718 nop 719 720 ldub [%o1], %g2 721 stb %g2, [%o0] 7221: 723 retl 724 RETL_INSN 725 726#endif /* FASTER_ALIGNED */ 727 72886: /* non_aligned */ 729 cmp %o2, 6 730 bleu 88f 731 732#ifdef FASTER_NONALIGNED 733 734 cmp %o2, 256 735 bcc 87f 736 737#endif /* FASTER_NONALIGNED */ 738 739 andcc %o0, 3, %g0 740 be 61f 741 andcc %o0, 1, %g0 742 be 60f 743 andcc %o0, 2, %g0 744 745 ldub [%o1], %g5 746 add %o1, 1, %o1 747 stb %g5, [%o0] 748 sub %o2, 1, %o2 749 bne 61f 750 add %o0, 1, %o0 75160: 752 ldub [%o1], %g3 753 add %o1, 2, %o1 754 stb %g3, [%o0] 755 sub %o2, 2, %o2 756 ldub [%o1 - 1], %g3 757 add %o0, 2, %o0 758 stb %g3, [%o0 - 1] 75961: 760 and %o1, 3, %g2 761 and %o2, 0xc, %g3 762 and %o1, -4, %o1 763 cmp %g3, 4 764 sll %g2, 3, %g4 765 mov 32, %g2 766 be 4f 767 sub %g2, %g4, %g7 768 769 blu 3f 770 cmp %g3, 0x8 771 772 be 2f 773 srl %o2, 2, %g3 774 775 ld [%o1], %o3 776 add %o0, -8, %o0 777 ld [%o1 + 4], %o4 778 b 8f 779 add %g3, 1, %g3 7802: 781 ld [%o1], %o4 782 add %o0, -12, %o0 783 ld [%o1 + 4], %o5 784 add %g3, 2, %g3 785 b 9f 786 add %o1, -4, %o1 7873: 788 ld [%o1], %g1 789 add %o0, -4, %o0 790 ld [%o1 + 4], %o3 791 srl %o2, 2, %g3 792 b 7f 793 add %o1, 4, %o1 7944: 795 ld [%o1], %o5 796 cmp %o2, 7 797 ld [%o1 + 4], %g1 798 srl %o2, 2, %g3 799 bleu 10f 800 add %o1, 8, %o1 801 802 ld [%o1], %o3 803 add %g3, -1, %g3 8045: 805 sll %o5, %g4, %g2 806 srl %g1, %g7, %g5 807 or %g2, %g5, %g2 808 st %g2, [%o0] 8097: 810 ld [%o1 + 4], %o4 811 sll %g1, %g4, %g2 812 srl %o3, %g7, %g5 813 or %g2, %g5, %g2 814 st %g2, [%o0 + 4] 8158: 816 ld [%o1 + 8], %o5 817 sll %o3, %g4, %g2 818 srl %o4, %g7, %g5 819 or %g2, %g5, %g2 820 st %g2, [%o0 + 8] 8219: 822 ld [%o1 + 12], %g1 823 sll %o4, %g4, %g2 824 srl %o5, %g7, %g5 825 addcc %g3, -4, %g3 826 or %g2, %g5, %g2 827 add %o1, 16, %o1 828 st %g2, [%o0 + 12] 829 add %o0, 16, %o0 830 bne,a 5b 831 ld [%o1], %o3 83210: 833 sll %o5, %g4, %g2 834 srl %g1, %g7, %g5 835 srl %g7, 3, %g3 836 or %g2, %g5, %g2 837 sub %o1, %g3, %o1 838 andcc %o2, 2, %g0 839 st %g2, [%o0] 840 be 1f 841 andcc %o2, 1, %g0 842 843 ldub [%o1], %g2 844 add %o1, 2, %o1 845 stb %g2, [%o0 + 4] 846 add %o0, 2, %o0 847 ldub [%o1 - 1], %g2 848 stb %g2, [%o0 + 3] 8491: 850 be 1f 851 nop 852 ldub [%o1], %g2 853 stb %g2, [%o0 + 4] 8541: 855 retl 856 RETL_INSN 857 858#ifdef FASTER_NONALIGNED 859 86087: /* faster_nonaligned */ 861 862 andcc %o1, 3, %g0 863 be 3f 864 andcc %o1, 1, %g0 865 866 be 4f 867 andcc %o1, 2, %g0 868 869 ldub [%o1], %g2 870 add %o1, 1, %o1 871 stb %g2, [%o0] 872 sub %o2, 1, %o2 873 bne 3f 874 add %o0, 1, %o0 8754: 876 lduh [%o1], %g2 877 add %o1, 2, %o1 878 srl %g2, 8, %g3 879 sub %o2, 2, %o2 880 stb %g3, [%o0] 881 add %o0, 2, %o0 882 stb %g2, [%o0 - 1] 8833: 884 andcc %o1, 4, %g0 885 886 bne 2f 887 cmp %o5, 1 888 889 ld [%o1], %o4 890 srl %o4, 24, %g2 891 stb %g2, [%o0] 892 srl %o4, 16, %g3 893 stb %g3, [%o0 + 1] 894 srl %o4, 8, %g2 895 stb %g2, [%o0 + 2] 896 sub %o2, 4, %o2 897 stb %o4, [%o0 + 3] 898 add %o1, 4, %o1 899 add %o0, 4, %o0 9002: 901 be 33f 902 cmp %o5, 2 903 be 32f 904 sub %o2, 4, %o2 90531: 906 ld [%o1], %g2 907 add %o1, 4, %o1 908 srl %g2, 24, %g3 909 and %o0, 7, %g5 910 stb %g3, [%o0] 911 cmp %g5, 7 912 sll %g2, 8, %g1 913 add %o0, 4, %o0 914 be 41f 915 and %o2, 0xffffffc0, %o3 916 ld [%o0 - 7], %o4 9174: 918 SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3) 919 SMOVE_CHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3) 920 SMOVE_CHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3) 921 SMOVE_CHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3) 922 subcc %o3, 64, %o3 923 add %o1, 64, %o1 924 bne 4b 925 add %o0, 64, %o0 926 927 andcc %o2, 0x30, %o3 928 be,a 1f 929 srl %g1, 16, %g2 9304: 931 SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3) 932 subcc %o3, 16, %o3 933 add %o1, 16, %o1 934 bne 4b 935 add %o0, 16, %o0 936 937 srl %g1, 16, %g2 9381: 939 st %o4, [%o0 - 7] 940 sth %g2, [%o0 - 3] 941 srl %g1, 8, %g4 942 b 88f 943 stb %g4, [%o0 - 1] 94432: 945 ld [%o1], %g2 946 add %o1, 4, %o1 947 srl %g2, 16, %g3 948 and %o0, 7, %g5 949 sth %g3, [%o0] 950 cmp %g5, 6 951 sll %g2, 16, %g1 952 add %o0, 4, %o0 953 be 42f 954 and %o2, 0xffffffc0, %o3 955 ld [%o0 - 6], %o4 9564: 957 SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2) 958 SMOVE_CHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2) 959 SMOVE_CHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2) 960 SMOVE_CHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2) 961 subcc %o3, 64, %o3 962 add %o1, 64, %o1 963 bne 4b 964 add %o0, 64, %o0 965 966 andcc %o2, 0x30, %o3 967 be,a 1f 968 srl %g1, 16, %g2 9694: 970 SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2) 971 subcc %o3, 16, %o3 972 add %o1, 16, %o1 973 bne 4b 974 add %o0, 16, %o0 975 976 srl %g1, 16, %g2 9771: 978 st %o4, [%o0 - 6] 979 b 88f 980 sth %g2, [%o0 - 2] 98133: 982 ld [%o1], %g2 983 sub %o2, 4, %o2 984 srl %g2, 24, %g3 985 and %o0, 7, %g5 986 stb %g3, [%o0] 987 cmp %g5, 5 988 srl %g2, 8, %g4 989 sll %g2, 24, %g1 990 sth %g4, [%o0 + 1] 991 add %o1, 4, %o1 992 be 43f 993 and %o2, 0xffffffc0, %o3 994 995 ld [%o0 - 1], %o4 996 add %o0, 4, %o0 9974: 998 SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, -1) 999 SMOVE_CHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, -1) 1000 SMOVE_CHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, -1) 1001 SMOVE_CHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, -1) 1002 subcc %o3, 64, %o3 1003 add %o1, 64, %o1 1004 bne 4b 1005 add %o0, 64, %o0 1006 1007 andcc %o2, 0x30, %o3 1008 be,a 1f 1009 srl %g1, 24, %g2 10104: 1011 SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, -1) 1012 subcc %o3, 16, %o3 1013 add %o1, 16, %o1 1014 bne 4b 1015 add %o0, 16, %o0 1016 1017 srl %g1, 24, %g2 10181: 1019 st %o4, [%o0 - 5] 1020 b 88f 1021 stb %g2, [%o0 - 1] 102241: 1023 SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3) 1024 SMOVE_ALIGNCHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3) 1025 SMOVE_ALIGNCHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3) 1026 SMOVE_ALIGNCHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3) 1027 subcc %o3, 64, %o3 1028 add %o1, 64, %o1 1029 bne 41b 1030 add %o0, 64, %o0 1031 1032 andcc %o2, 0x30, %o3 1033 be,a 1f 1034 srl %g1, 16, %g2 10354: 1036 SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3) 1037 subcc %o3, 16, %o3 1038 add %o1, 16, %o1 1039 bne 4b 1040 add %o0, 16, %o0 1041 1042 srl %g1, 16, %g2 10431: 1044 sth %g2, [%o0 - 3] 1045 srl %g1, 8, %g4 1046 b 88f 1047 stb %g4, [%o0 - 1] 104843: 1049 SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, 3) 1050 SMOVE_ALIGNCHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, 3) 1051 SMOVE_ALIGNCHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, 3) 1052 SMOVE_ALIGNCHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, 3) 1053 subcc %o3, 64, %o3 1054 add %o1, 64, %o1 1055 bne 43b 1056 add %o0, 64, %o0 1057 1058 andcc %o2, 0x30, %o3 1059 be,a 1f 1060 srl %g1, 24, %g2 10614: 1062 SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, 3) 1063 subcc %o3, 16, %o3 1064 add %o1, 16, %o1 1065 bne 4b 1066 add %o0, 16, %o0 1067 1068 srl %g1, 24, %g2 10691: 1070 stb %g2, [%o0 + 3] 1071 b 88f 1072 add %o0, 4, %o0 107342: 1074 SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2) 1075 SMOVE_ALIGNCHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2) 1076 SMOVE_ALIGNCHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2) 1077 SMOVE_ALIGNCHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2) 1078 subcc %o3, 64, %o3 1079 add %o1, 64, %o1 1080 bne 42b 1081 add %o0, 64, %o0 1082 1083 andcc %o2, 0x30, %o3 1084 be,a 1f 1085 srl %g1, 16, %g2 10864: 1087 SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2) 1088 subcc %o3, 16, %o3 1089 add %o1, 16, %o1 1090 bne 4b 1091 add %o0, 16, %o0 1092 1093 srl %g1, 16, %g2 10941: 1095 sth %g2, [%o0 - 2] 1096 1097 /* Fall through */ 1098 1099#endif /* FASTER_NONALIGNED */ 1100 110188: /* short_end */ 1102 1103 and %o2, 0xe, %o3 110420: 1105 sethi %hi(89f), %o5 1106 sll %o3, 3, %o4 1107 add %o0, %o3, %o0 1108 sub %o5, %o4, %o5 1109 add %o1, %o3, %o1 1110 jmpl %o5 + %lo(89f), %g0 1111 andcc %o2, 1, %g0 1112 1113 MOVE_SHORTCHUNK(o1, o0, 0x0c, g2, g3) 1114 MOVE_SHORTCHUNK(o1, o0, 0x0a, g2, g3) 1115 MOVE_SHORTCHUNK(o1, o0, 0x08, g2, g3) 1116 MOVE_SHORTCHUNK(o1, o0, 0x06, g2, g3) 1117 MOVE_SHORTCHUNK(o1, o0, 0x04, g2, g3) 1118 MOVE_SHORTCHUNK(o1, o0, 0x02, g2, g3) 1119 MOVE_SHORTCHUNK(o1, o0, 0x00, g2, g3) 1120 112189: /* short_table_end */ 1122 1123 be 1f 1124 nop 1125 1126 ldub [%o1], %g2 1127 stb %g2, [%o0] 11281: 1129 retl 1130 RETL_INSN 1131 113290: /* short_aligned_end */ 1133 bne 88b 1134 andcc %o2, 8, %g0 1135 1136 be 1f 1137 andcc %o2, 4, %g0 1138 1139 ld [%o1 + 0x00], %g2 1140 ld [%o1 + 0x04], %g3 1141 add %o1, 8, %o1 1142 st %g2, [%o0 + 0x00] 1143 st %g3, [%o0 + 0x04] 1144 add %o0, 8, %o0 11451: 1146 b 81b 1147 mov %o2, %g1 1148