1/* memcpy.S: Sparc optimized memcpy, bcopy and memmove code 2 * Hand optimized from GNU libc's memcpy, bcopy 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#include <asm/cprefix.h> 13 14#define FUNC(x) \ 15 .globl C_LABEL(x); \ 16 .type C_LABEL(x),@function; \ 17 .align 4; \ 18C_LABEL(x): 19 20#undef FASTER_REVERSE 21#undef FASTER_NONALIGNED 22#define FASTER_ALIGNED 23 24/* In kernel these functions don't return a value. 25 * One should use macros in asm/string.h for that purpose. 26 * We return 0, so that bugs are more apparent. 27 */ 28#define SETUP_RETL 29#define RETL_INSN clr %o0 30 31#else 32 33/* libc */ 34 35#include "DEFS.h" 36 37#define FASTER_REVERSE 38#define FASTER_NONALIGNED 39#define FASTER_ALIGNED 40 41#define SETUP_RETL mov %o0, %g6 42#define RETL_INSN mov %g6, %o0 43 44#endif 45 46/* Both these macros have to start with exactly the same insn */ 47#define MOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, t7) \ 48 ldd [%src + offset + 0x00], %t0; \ 49 ldd [%src + offset + 0x08], %t2; \ 50 ldd [%src + offset + 0x10], %t4; \ 51 ldd [%src + offset + 0x18], %t6; \ 52 st %t0, [%dst + offset + 0x00]; \ 53 st %t1, [%dst + offset + 0x04]; \ 54 st %t2, [%dst + offset + 0x08]; \ 55 st %t3, [%dst + offset + 0x0c]; \ 56 st %t4, [%dst + offset + 0x10]; \ 57 st %t5, [%dst + offset + 0x14]; \ 58 st %t6, [%dst + offset + 0x18]; \ 59 st %t7, [%dst + offset + 0x1c]; 60 61#define MOVE_BIGALIGNCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, t7) \ 62 ldd [%src + offset + 0x00], %t0; \ 63 ldd [%src + offset + 0x08], %t2; \ 64 ldd [%src + offset + 0x10], %t4; \ 65 ldd [%src + offset + 0x18], %t6; \ 66 std %t0, [%dst + offset + 0x00]; \ 67 std %t2, [%dst + offset + 0x08]; \ 68 std %t4, [%dst + offset + 0x10]; \ 69 std %t6, [%dst + offset + 0x18]; 70 71#define MOVE_LASTCHUNK(src, dst, offset, t0, t1, t2, t3) \ 72 ldd [%src - offset - 0x10], %t0; \ 73 ldd [%src - offset - 0x08], %t2; \ 74 st %t0, [%dst - offset - 0x10]; \ 75 st %t1, [%dst - offset - 0x0c]; \ 76 st %t2, [%dst - offset - 0x08]; \ 77 st %t3, [%dst - offset - 0x04]; 78 79#define MOVE_LASTALIGNCHUNK(src, dst, offset, t0, t1, t2, t3) \ 80 ldd [%src - offset - 0x10], %t0; \ 81 ldd [%src - offset - 0x08], %t2; \ 82 std %t0, [%dst - offset - 0x10]; \ 83 std %t2, [%dst - offset - 0x08]; 84 85#define MOVE_SHORTCHUNK(src, dst, offset, t0, t1) \ 86 ldub [%src - offset - 0x02], %t0; \ 87 ldub [%src - offset - 0x01], %t1; \ 88 stb %t0, [%dst - offset - 0x02]; \ 89 stb %t1, [%dst - offset - 0x01]; 90 91/* Both these macros have to start with exactly the same insn */ 92#define RMOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, t7) \ 93 ldd [%src - offset - 0x20], %t0; \ 94 ldd [%src - offset - 0x18], %t2; \ 95 ldd [%src - offset - 0x10], %t4; \ 96 ldd [%src - offset - 0x08], %t6; \ 97 st %t0, [%dst - offset - 0x20]; \ 98 st %t1, [%dst - offset - 0x1c]; \ 99 st %t2, [%dst - offset - 0x18]; \ 100 st %t3, [%dst - offset - 0x14]; \ 101 st %t4, [%dst - offset - 0x10]; \ 102 st %t5, [%dst - offset - 0x0c]; \ 103 st %t6, [%dst - offset - 0x08]; \ 104 st %t7, [%dst - offset - 0x04]; 105 106#define RMOVE_BIGALIGNCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, t7) \ 107 ldd [%src - offset - 0x20], %t0; \ 108 ldd [%src - offset - 0x18], %t2; \ 109 ldd [%src - offset - 0x10], %t4; \ 110 ldd [%src - offset - 0x08], %t6; \ 111 std %t0, [%dst - offset - 0x20]; \ 112 std %t2, [%dst - offset - 0x18]; \ 113 std %t4, [%dst - offset - 0x10]; \ 114 std %t6, [%dst - offset - 0x08]; 115 116#define RMOVE_LASTCHUNK(src, dst, offset, t0, t1, t2, t3) \ 117 ldd [%src + offset + 0x00], %t0; \ 118 ldd [%src + offset + 0x08], %t2; \ 119 st %t0, [%dst + offset + 0x00]; \ 120 st %t1, [%dst + offset + 0x04]; \ 121 st %t2, [%dst + offset + 0x08]; \ 122 st %t3, [%dst + offset + 0x0c]; 123 124#define RMOVE_SHORTCHUNK(src, dst, offset, t0, t1) \ 125 ldub [%src + offset + 0x00], %t0; \ 126 ldub [%src + offset + 0x01], %t1; \ 127 stb %t0, [%dst + offset + 0x00]; \ 128 stb %t1, [%dst + offset + 0x01]; 129 130#define SMOVE_CHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, prev, shil, shir, offset2) \ 131 ldd [%src + offset + 0x00], %t0; \ 132 ldd [%src + offset + 0x08], %t2; \ 133 srl %t0, shir, %t5; \ 134 srl %t1, shir, %t6; \ 135 sll %t0, shil, %t0; \ 136 or %t5, %prev, %t5; \ 137 sll %t1, shil, %prev; \ 138 or %t6, %t0, %t0; \ 139 srl %t2, shir, %t1; \ 140 srl %t3, shir, %t6; \ 141 sll %t2, shil, %t2; \ 142 or %t1, %prev, %t1; \ 143 std %t4, [%dst + offset + offset2 - 0x04]; \ 144 std %t0, [%dst + offset + offset2 + 0x04]; \ 145 sll %t3, shil, %prev; \ 146 or %t6, %t2, %t4; 147 148#define SMOVE_ALIGNCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, prev, shil, shir, offset2) \ 149 ldd [%src + offset + 0x00], %t0; \ 150 ldd [%src + offset + 0x08], %t2; \ 151 srl %t0, shir, %t4; \ 152 srl %t1, shir, %t5; \ 153 sll %t0, shil, %t6; \ 154 or %t4, %prev, %t0; \ 155 sll %t1, shil, %prev; \ 156 or %t5, %t6, %t1; \ 157 srl %t2, shir, %t4; \ 158 srl %t3, shir, %t5; \ 159 sll %t2, shil, %t6; \ 160 or %t4, %prev, %t2; \ 161 sll %t3, shil, %prev; \ 162 or %t5, %t6, %t3; \ 163 std %t0, [%dst + offset + offset2 + 0x00]; \ 164 std %t2, [%dst + offset + offset2 + 0x08]; 165 166 .text 167 .align 4 168 169#ifdef FASTER_REVERSE 170 17170: /* rdword_align */ 172 173 andcc %o1, 1, %g0 174 be 4f 175 andcc %o1, 2, %g0 176 177 ldub [%o1 - 1], %g2 178 sub %o1, 1, %o1 179 stb %g2, [%o0 - 1] 180 sub %o2, 1, %o2 181 be 3f 182 sub %o0, 1, %o0 1834: 184 lduh [%o1 - 2], %g2 185 sub %o1, 2, %o1 186 sth %g2, [%o0 - 2] 187 sub %o2, 2, %o2 188 b 3f 189 sub %o0, 2, %o0 190 191#endif /* FASTER_REVERSE */ 192 1930: 194 retl 195 nop ! Only bcopy returns here and it retuns void... 196 197FUNC(bcopy) 198 mov %o0, %o3 199 mov %o1, %o0 200 mov %o3, %o1 201 tst %o2 202 bcs 0b 203 /* Do the cmp in the delay slot */ 204#ifdef __KERNEL__ 205FUNC(amemmove) 206FUNC(__memmove) 207#endif 208FUNC(memmove) 209 cmp %o0, %o1 210 SETUP_RETL 211 bleu 9f 212 sub %o0, %o1, %o4 213 214 add %o1, %o2, %o3 215 cmp %o3, %o0 216 bleu 0f 217 andcc %o4, 3, %o5 218 219#ifndef FASTER_REVERSE 220 221 add %o1, %o2, %o1 222 add %o0, %o2, %o0 223 sub %o1, 1, %o1 224 sub %o0, 1, %o0 225 2261: /* reverse_bytes */ 227 228 ldub [%o1], %o4 229 subcc %o2, 1, %o2 230 stb %o4, [%o0] 231 sub %o1, 1, %o1 232 bne 1b 233 sub %o0, 1, %o0 234 235 retl 236 RETL_INSN 237 238#else /* FASTER_REVERSE */ 239 240 add %o1, %o2, %o1 241 add %o0, %o2, %o0 242 bne 77f 243 cmp %o2, 15 244 bleu 91f 245 andcc %o1, 3, %g0 246 bne 70b 2473: 248 andcc %o1, 4, %g0 249 250 be 2f 251 mov %o2, %g1 252 253 ld [%o1 - 4], %o4 254 sub %g1, 4, %g1 255 st %o4, [%o0 - 4] 256 sub %o1, 4, %o1 257 sub %o0, 4, %o0 2582: 259 andcc %g1, 0xffffff80, %g7 260 be 3f 261 andcc %o0, 4, %g0 262 263 be 74f + 4 2645: 265 RMOVE_BIGCHUNK(o1, o0, 0x00, o2, o3, o4, o5, g2, g3, g4, g5) 266 RMOVE_BIGCHUNK(o1, o0, 0x20, o2, o3, o4, o5, g2, g3, g4, g5) 267 RMOVE_BIGCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5) 268 RMOVE_BIGCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5) 269 subcc %g7, 128, %g7 270 sub %o1, 128, %o1 271 bne 5b 272 sub %o0, 128, %o0 2733: 274 andcc %g1, 0x70, %g7 275 be 72f 276 andcc %g1, 8, %g0 277 278 sethi %hi(72f), %o5 279 srl %g7, 1, %o4 280 add %g7, %o4, %o4 281 sub %o1, %g7, %o1 282 sub %o5, %o4, %o5 283 jmpl %o5 + %lo(72f), %g0 284 sub %o0, %g7, %o0 285 28671: /* rmemcpy_table */ 287 RMOVE_LASTCHUNK(o1, o0, 0x60, g2, g3, g4, g5) 288 RMOVE_LASTCHUNK(o1, o0, 0x50, g2, g3, g4, g5) 289 RMOVE_LASTCHUNK(o1, o0, 0x40, g2, g3, g4, g5) 290 RMOVE_LASTCHUNK(o1, o0, 0x30, g2, g3, g4, g5) 291 RMOVE_LASTCHUNK(o1, o0, 0x20, g2, g3, g4, g5) 292 RMOVE_LASTCHUNK(o1, o0, 0x10, g2, g3, g4, g5) 293 RMOVE_LASTCHUNK(o1, o0, 0x00, g2, g3, g4, g5) 294 29572: /* rmemcpy_table_end */ 296 297 be 73f 298 andcc %g1, 4, %g0 299 300 ldd [%o1 - 0x08], %g2 301 sub %o0, 8, %o0 302 sub %o1, 8, %o1 303 st %g2, [%o0] 304 st %g3, [%o0 + 0x04] 305 30673: /* rmemcpy_last7 */ 307 308 be 1f 309 andcc %g1, 2, %g0 310 311 ld [%o1 - 4], %g2 312 sub %o1, 4, %o1 313 st %g2, [%o0 - 4] 314 sub %o0, 4, %o0 3151: 316 be 1f 317 andcc %g1, 1, %g0 318 319 lduh [%o1 - 2], %g2 320 sub %o1, 2, %o1 321 sth %g2, [%o0 - 2] 322 sub %o0, 2, %o0 3231: 324 be 1f 325 nop 326 327 ldub [%o1 - 1], %g2 328 stb %g2, [%o0 - 1] 3291: 330 retl 331 RETL_INSN 332 33374: /* rldd_std */ 334 RMOVE_BIGALIGNCHUNK(o1, o0, 0x00, o2, o3, o4, o5, g2, g3, g4, g5) 335 RMOVE_BIGALIGNCHUNK(o1, o0, 0x20, o2, o3, o4, o5, g2, g3, g4, g5) 336 RMOVE_BIGALIGNCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5) 337 RMOVE_BIGALIGNCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5) 338 subcc %g7, 128, %g7 339 sub %o1, 128, %o1 340 bne 74b 341 sub %o0, 128, %o0 342 343 andcc %g1, 0x70, %g7 344 be 72b 345 andcc %g1, 8, %g0 346 347 sethi %hi(72b), %o5 348 srl %g7, 1, %o4 349 add %g7, %o4, %o4 350 sub %o1, %g7, %o1 351 sub %o5, %o4, %o5 352 jmpl %o5 + %lo(72b), %g0 353 sub %o0, %g7, %o0 354 35575: /* rshort_end */ 356 357 and %o2, 0xe, %o3 3582: 359 sethi %hi(76f), %o5 360 sll %o3, 3, %o4 361 sub %o0, %o3, %o0 362 sub %o5, %o4, %o5 363 sub %o1, %o3, %o1 364 jmpl %o5 + %lo(76f), %g0 365 andcc %o2, 1, %g0 366 367 RMOVE_SHORTCHUNK(o1, o0, 0x0c, g2, g3) 368 RMOVE_SHORTCHUNK(o1, o0, 0x0a, g2, g3) 369 RMOVE_SHORTCHUNK(o1, o0, 0x08, g2, g3) 370 RMOVE_SHORTCHUNK(o1, o0, 0x06, g2, g3) 371 RMOVE_SHORTCHUNK(o1, o0, 0x04, g2, g3) 372 RMOVE_SHORTCHUNK(o1, o0, 0x02, g2, g3) 373 RMOVE_SHORTCHUNK(o1, o0, 0x00, g2, g3) 374 37576: /* rshort_table_end */ 376 377 be 1f 378 nop 379 ldub [%o1 - 1], %g2 380 stb %g2, [%o0 - 1] 3811: 382 retl 383 RETL_INSN 384 38591: /* rshort_aligned_end */ 386 387 bne 75b 388 andcc %o2, 8, %g0 389 390 be 1f 391 andcc %o2, 4, %g0 392 393 ld [%o1 - 0x08], %g2 394 ld [%o1 - 0x04], %g3 395 sub %o1, 8, %o1 396 st %g2, [%o0 - 0x08] 397 st %g3, [%o0 - 0x04] 398 sub %o0, 8, %o0 3991: 400 b 73b 401 mov %o2, %g1 402 40377: /* rnon_aligned */ 404 cmp %o2, 15 405 bleu 75b 406 andcc %o0, 3, %g0 407 be 64f 408 andcc %o0, 1, %g0 409 be 63f 410 andcc %o0, 2, %g0 411 ldub [%o1 - 1], %g5 412 sub %o1, 1, %o1 413 stb %g5, [%o0 - 1] 414 sub %o0, 1, %o0 415 be 64f 416 sub %o2, 1, %o2 41763: 418 ldub [%o1 - 1], %g5 419 sub %o1, 2, %o1 420 stb %g5, [%o0 - 1] 421 sub %o0, 2, %o0 422 ldub [%o1], %g5 423 sub %o2, 2, %o2 424 stb %g5, [%o0] 42564: 426 and %o1, 3, %g2 427 and %o1, -4, %o1 428 and %o2, 0xc, %g3 429 add %o1, 4, %o1 430 cmp %g3, 4 431 sll %g2, 3, %g4 432 mov 32, %g2 433 be 4f 434 sub %g2, %g4, %g7 435 436 blu 3f 437 cmp %g3, 8 438 439 be 2f 440 srl %o2, 2, %g3 441 442 ld [%o1 - 4], %o3 443 add %o0, -8, %o0 444 ld [%o1 - 8], %o4 445 add %o1, -16, %o1 446 b 7f 447 add %g3, 1, %g3 4482: 449 ld [%o1 - 4], %o4 450 add %o0, -4, %o0 451 ld [%o1 - 8], %g1 452 add %o1, -12, %o1 453 b 8f 454 add %g3, 2, %g3 4553: 456 ld [%o1 - 4], %o5 457 add %o0, -12, %o0 458 ld [%o1 - 8], %o3 459 add %o1, -20, %o1 460 b 6f 461 srl %o2, 2, %g3 4624: 463 ld [%o1 - 4], %g1 464 srl %o2, 2, %g3 465 ld [%o1 - 8], %o5 466 add %o1, -24, %o1 467 add %o0, -16, %o0 468 add %g3, -1, %g3 469 470 ld [%o1 + 12], %o3 4715: 472 sll %o5, %g4, %g2 473 srl %g1, %g7, %g5 474 or %g2, %g5, %g2 475 st %g2, [%o0 + 12] 4766: 477 ld [%o1 + 8], %o4 478 sll %o3, %g4, %g2 479 srl %o5, %g7, %g5 480 or %g2, %g5, %g2 481 st %g2, [%o0 + 8] 4827: 483 ld [%o1 + 4], %g1 484 sll %o4, %g4, %g2 485 srl %o3, %g7, %g5 486 or %g2, %g5, %g2 487 st %g2, [%o0 + 4] 4888: 489 ld [%o1], %o5 490 sll %g1, %g4, %g2 491 srl %o4, %g7, %g5 492 addcc %g3, -4, %g3 493 or %g2, %g5, %g2 494 add %o1, -16, %o1 495 st %g2, [%o0] 496 add %o0, -16, %o0 497 bne,a 5b 498 ld [%o1 + 12], %o3 499 sll %o5, %g4, %g2 500 srl %g1, %g7, %g5 501 srl %g4, 3, %g3 502 or %g2, %g5, %g2 503 add %o1, %g3, %o1 504 andcc %o2, 2, %g0 505 st %g2, [%o0 + 12] 506 be 1f 507 andcc %o2, 1, %g0 508 509 ldub [%o1 + 15], %g5 510 add %o1, -2, %o1 511 stb %g5, [%o0 + 11] 512 add %o0, -2, %o0 513 ldub [%o1 + 16], %g5 514 stb %g5, [%o0 + 12] 5151: 516 be 1f 517 nop 518 ldub [%o1 + 15], %g5 519 stb %g5, [%o0 + 11] 5201: 521 retl 522 RETL_INSN 523 524#endif /* FASTER_REVERSE */ 525 526/* NOTE: This code is executed just for the cases, 527 where %src (=%o1) & 3 is != 0. 528 We need to align it to 4. So, for (%src & 3) 529 1 we need to do ldub,lduh 530 2 lduh 531 3 just ldub 532 so even if it looks weird, the branches 533 are correct here. -jj 534 */ 53578: /* dword_align */ 536 537 andcc %o1, 1, %g0 538 be 4f 539 andcc %o1, 2, %g0 540 541 ldub [%o1], %g2 542 add %o1, 1, %o1 543 stb %g2, [%o0] 544 sub %o2, 1, %o2 545 bne 3f 546 add %o0, 1, %o0 5474: 548 lduh [%o1], %g2 549 add %o1, 2, %o1 550 sth %g2, [%o0] 551 sub %o2, 2, %o2 552 b 3f 553 add %o0, 2, %o0 554 555#ifdef __KERNEL__ 556FUNC(__memcpy) 557#endif 558FUNC(memcpy) /* %o0=dst %o1=src %o2=len */ 559 560 sub %o0, %o1, %o4 561 SETUP_RETL 5629: 563 andcc %o4, 3, %o5 5640: 565 bne 86f 566 cmp %o2, 15 567 568 bleu 90f 569 andcc %o1, 3, %g0 570 571 bne 78b 5723: 573 andcc %o1, 4, %g0 574 575 be 2f 576 mov %o2, %g1 577 578 ld [%o1], %o4 579 sub %g1, 4, %g1 580 st %o4, [%o0] 581 add %o1, 4, %o1 582 add %o0, 4, %o0 5832: 584 andcc %g1, 0xffffff80, %g7 585 be 3f 586 andcc %o0, 4, %g0 587 588 be 82f + 4 5895: 590 MOVE_BIGCHUNK(o1, o0, 0x00, o2, o3, o4, o5, g2, g3, g4, g5) 591 MOVE_BIGCHUNK(o1, o0, 0x20, o2, o3, o4, o5, g2, g3, g4, g5) 592 MOVE_BIGCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5) 593 MOVE_BIGCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5) 594 subcc %g7, 128, %g7 595 add %o1, 128, %o1 596 bne 5b 597 add %o0, 128, %o0 5983: 599 andcc %g1, 0x70, %g7 600 be 80f 601 andcc %g1, 8, %g0 602 603 sethi %hi(80f), %o5 604 srl %g7, 1, %o4 605 add %g7, %o4, %o4 606 add %o1, %g7, %o1 607 sub %o5, %o4, %o5 608 jmpl %o5 + %lo(80f), %g0 609 add %o0, %g7, %o0 610 61179: /* memcpy_table */ 612 613 MOVE_LASTCHUNK(o1, o0, 0x60, g2, g3, g4, g5) 614 MOVE_LASTCHUNK(o1, o0, 0x50, g2, g3, g4, g5) 615 MOVE_LASTCHUNK(o1, o0, 0x40, g2, g3, g4, g5) 616 MOVE_LASTCHUNK(o1, o0, 0x30, g2, g3, g4, g5) 617 MOVE_LASTCHUNK(o1, o0, 0x20, g2, g3, g4, g5) 618 MOVE_LASTCHUNK(o1, o0, 0x10, g2, g3, g4, g5) 619 MOVE_LASTCHUNK(o1, o0, 0x00, g2, g3, g4, g5) 620 62180: /* memcpy_table_end */ 622 be 81f 623 andcc %g1, 4, %g0 624 625 ldd [%o1], %g2 626 add %o0, 8, %o0 627 st %g2, [%o0 - 0x08] 628 add %o1, 8, %o1 629 st %g3, [%o0 - 0x04] 630 63181: /* memcpy_last7 */ 632 633 be 1f 634 andcc %g1, 2, %g0 635 636 ld [%o1], %g2 637 add %o1, 4, %o1 638 st %g2, [%o0] 639 add %o0, 4, %o0 6401: 641 be 1f 642 andcc %g1, 1, %g0 643 644 lduh [%o1], %g2 645 add %o1, 2, %o1 646 sth %g2, [%o0] 647 add %o0, 2, %o0 6481: 649 be 1f 650 nop 651 652 ldub [%o1], %g2 653 stb %g2, [%o0] 6541: 655 retl 656 RETL_INSN 657 65882: /* ldd_std */ 659 MOVE_BIGALIGNCHUNK(o1, o0, 0x00, o2, o3, o4, o5, g2, g3, g4, g5) 660 MOVE_BIGALIGNCHUNK(o1, o0, 0x20, o2, o3, o4, o5, g2, g3, g4, g5) 661 MOVE_BIGALIGNCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5) 662 MOVE_BIGALIGNCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5) 663 subcc %g7, 128, %g7 664 add %o1, 128, %o1 665 bne 82b 666 add %o0, 128, %o0 667 668#ifndef FASTER_ALIGNED 669 670 andcc %g1, 0x70, %g7 671 be 80b 672 andcc %g1, 8, %g0 673 674 sethi %hi(80b), %o5 675 srl %g7, 1, %o4 676 add %g7, %o4, %o4 677 add %o1, %g7, %o1 678 sub %o5, %o4, %o5 679 jmpl %o5 + %lo(80b), %g0 680 add %o0, %g7, %o0 681 682#else /* FASTER_ALIGNED */ 683 684 andcc %g1, 0x70, %g7 685 be 84f 686 andcc %g1, 8, %g0 687 688 sethi %hi(84f), %o5 689 add %o1, %g7, %o1 690 sub %o5, %g7, %o5 691 jmpl %o5 + %lo(84f), %g0 692 add %o0, %g7, %o0 693 69483: /* amemcpy_table */ 695 696 MOVE_LASTALIGNCHUNK(o1, o0, 0x60, g2, g3, g4, g5) 697 MOVE_LASTALIGNCHUNK(o1, o0, 0x50, g2, g3, g4, g5) 698 MOVE_LASTALIGNCHUNK(o1, o0, 0x40, g2, g3, g4, g5) 699 MOVE_LASTALIGNCHUNK(o1, o0, 0x30, g2, g3, g4, g5) 700 MOVE_LASTALIGNCHUNK(o1, o0, 0x20, g2, g3, g4, g5) 701 MOVE_LASTALIGNCHUNK(o1, o0, 0x10, g2, g3, g4, g5) 702 MOVE_LASTALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5) 703 70484: /* amemcpy_table_end */ 705 be 85f 706 andcc %g1, 4, %g0 707 708 ldd [%o1], %g2 709 add %o0, 8, %o0 710 std %g2, [%o0 - 0x08] 711 add %o1, 8, %o1 71285: /* amemcpy_last7 */ 713 be 1f 714 andcc %g1, 2, %g0 715 716 ld [%o1], %g2 717 add %o1, 4, %o1 718 st %g2, [%o0] 719 add %o0, 4, %o0 7201: 721 be 1f 722 andcc %g1, 1, %g0 723 724 lduh [%o1], %g2 725 add %o1, 2, %o1 726 sth %g2, [%o0] 727 add %o0, 2, %o0 7281: 729 be 1f 730 nop 731 732 ldub [%o1], %g2 733 stb %g2, [%o0] 7341: 735 retl 736 RETL_INSN 737 738#endif /* FASTER_ALIGNED */ 739 74086: /* non_aligned */ 741 cmp %o2, 6 742 bleu 88f 743 744#ifdef FASTER_NONALIGNED 745 746 cmp %o2, 256 747 bcc 87f 748 749#endif /* FASTER_NONALIGNED */ 750 751 andcc %o0, 3, %g0 752 be 61f 753 andcc %o0, 1, %g0 754 be 60f 755 andcc %o0, 2, %g0 756 757 ldub [%o1], %g5 758 add %o1, 1, %o1 759 stb %g5, [%o0] 760 sub %o2, 1, %o2 761 bne 61f 762 add %o0, 1, %o0 76360: 764 ldub [%o1], %g3 765 add %o1, 2, %o1 766 stb %g3, [%o0] 767 sub %o2, 2, %o2 768 ldub [%o1 - 1], %g3 769 add %o0, 2, %o0 770 stb %g3, [%o0 - 1] 77161: 772 and %o1, 3, %g2 773 and %o2, 0xc, %g3 774 and %o1, -4, %o1 775 cmp %g3, 4 776 sll %g2, 3, %g4 777 mov 32, %g2 778 be 4f 779 sub %g2, %g4, %g7 780 781 blu 3f 782 cmp %g3, 0x8 783 784 be 2f 785 srl %o2, 2, %g3 786 787 ld [%o1], %o3 788 add %o0, -8, %o0 789 ld [%o1 + 4], %o4 790 b 8f 791 add %g3, 1, %g3 7922: 793 ld [%o1], %o4 794 add %o0, -12, %o0 795 ld [%o1 + 4], %o5 796 add %g3, 2, %g3 797 b 9f 798 add %o1, -4, %o1 7993: 800 ld [%o1], %g1 801 add %o0, -4, %o0 802 ld [%o1 + 4], %o3 803 srl %o2, 2, %g3 804 b 7f 805 add %o1, 4, %o1 8064: 807 ld [%o1], %o5 808 cmp %o2, 7 809 ld [%o1 + 4], %g1 810 srl %o2, 2, %g3 811 bleu 10f 812 add %o1, 8, %o1 813 814 ld [%o1], %o3 815 add %g3, -1, %g3 8165: 817 sll %o5, %g4, %g2 818 srl %g1, %g7, %g5 819 or %g2, %g5, %g2 820 st %g2, [%o0] 8217: 822 ld [%o1 + 4], %o4 823 sll %g1, %g4, %g2 824 srl %o3, %g7, %g5 825 or %g2, %g5, %g2 826 st %g2, [%o0 + 4] 8278: 828 ld [%o1 + 8], %o5 829 sll %o3, %g4, %g2 830 srl %o4, %g7, %g5 831 or %g2, %g5, %g2 832 st %g2, [%o0 + 8] 8339: 834 ld [%o1 + 12], %g1 835 sll %o4, %g4, %g2 836 srl %o5, %g7, %g5 837 addcc %g3, -4, %g3 838 or %g2, %g5, %g2 839 add %o1, 16, %o1 840 st %g2, [%o0 + 12] 841 add %o0, 16, %o0 842 bne,a 5b 843 ld [%o1], %o3 84410: 845 sll %o5, %g4, %g2 846 srl %g1, %g7, %g5 847 srl %g7, 3, %g3 848 or %g2, %g5, %g2 849 sub %o1, %g3, %o1 850 andcc %o2, 2, %g0 851 st %g2, [%o0] 852 be 1f 853 andcc %o2, 1, %g0 854 855 ldub [%o1], %g2 856 add %o1, 2, %o1 857 stb %g2, [%o0 + 4] 858 add %o0, 2, %o0 859 ldub [%o1 - 1], %g2 860 stb %g2, [%o0 + 3] 8611: 862 be 1f 863 nop 864 ldub [%o1], %g2 865 stb %g2, [%o0 + 4] 8661: 867 retl 868 RETL_INSN 869 870#ifdef FASTER_NONALIGNED 871 87287: /* faster_nonaligned */ 873 874 andcc %o1, 3, %g0 875 be 3f 876 andcc %o1, 1, %g0 877 878 be 4f 879 andcc %o1, 2, %g0 880 881 ldub [%o1], %g2 882 add %o1, 1, %o1 883 stb %g2, [%o0] 884 sub %o2, 1, %o2 885 bne 3f 886 add %o0, 1, %o0 8874: 888 lduh [%o1], %g2 889 add %o1, 2, %o1 890 srl %g2, 8, %g3 891 sub %o2, 2, %o2 892 stb %g3, [%o0] 893 add %o0, 2, %o0 894 stb %g2, [%o0 - 1] 8953: 896 andcc %o1, 4, %g0 897 898 bne 2f 899 cmp %o5, 1 900 901 ld [%o1], %o4 902 srl %o4, 24, %g2 903 stb %g2, [%o0] 904 srl %o4, 16, %g3 905 stb %g3, [%o0 + 1] 906 srl %o4, 8, %g2 907 stb %g2, [%o0 + 2] 908 sub %o2, 4, %o2 909 stb %o4, [%o0 + 3] 910 add %o1, 4, %o1 911 add %o0, 4, %o0 9122: 913 be 33f 914 cmp %o5, 2 915 be 32f 916 sub %o2, 4, %o2 91731: 918 ld [%o1], %g2 919 add %o1, 4, %o1 920 srl %g2, 24, %g3 921 and %o0, 7, %g5 922 stb %g3, [%o0] 923 cmp %g5, 7 924 sll %g2, 8, %g1 925 add %o0, 4, %o0 926 be 41f 927 and %o2, 0xffffffc0, %o3 928 ld [%o0 - 7], %o4 9294: 930 SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3) 931 SMOVE_CHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3) 932 SMOVE_CHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3) 933 SMOVE_CHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3) 934 subcc %o3, 64, %o3 935 add %o1, 64, %o1 936 bne 4b 937 add %o0, 64, %o0 938 939 andcc %o2, 0x30, %o3 940 be,a 1f 941 srl %g1, 16, %g2 9424: 943 SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3) 944 subcc %o3, 16, %o3 945 add %o1, 16, %o1 946 bne 4b 947 add %o0, 16, %o0 948 949 srl %g1, 16, %g2 9501: 951 st %o4, [%o0 - 7] 952 sth %g2, [%o0 - 3] 953 srl %g1, 8, %g4 954 b 88f 955 stb %g4, [%o0 - 1] 95632: 957 ld [%o1], %g2 958 add %o1, 4, %o1 959 srl %g2, 16, %g3 960 and %o0, 7, %g5 961 sth %g3, [%o0] 962 cmp %g5, 6 963 sll %g2, 16, %g1 964 add %o0, 4, %o0 965 be 42f 966 and %o2, 0xffffffc0, %o3 967 ld [%o0 - 6], %o4 9684: 969 SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2) 970 SMOVE_CHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2) 971 SMOVE_CHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2) 972 SMOVE_CHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2) 973 subcc %o3, 64, %o3 974 add %o1, 64, %o1 975 bne 4b 976 add %o0, 64, %o0 977 978 andcc %o2, 0x30, %o3 979 be,a 1f 980 srl %g1, 16, %g2 9814: 982 SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2) 983 subcc %o3, 16, %o3 984 add %o1, 16, %o1 985 bne 4b 986 add %o0, 16, %o0 987 988 srl %g1, 16, %g2 9891: 990 st %o4, [%o0 - 6] 991 b 88f 992 sth %g2, [%o0 - 2] 99333: 994 ld [%o1], %g2 995 sub %o2, 4, %o2 996 srl %g2, 24, %g3 997 and %o0, 7, %g5 998 stb %g3, [%o0] 999 cmp %g5, 5 1000 srl %g2, 8, %g4 1001 sll %g2, 24, %g1 1002 sth %g4, [%o0 + 1] 1003 add %o1, 4, %o1 1004 be 43f 1005 and %o2, 0xffffffc0, %o3 1006 1007 ld [%o0 - 1], %o4 1008 add %o0, 4, %o0 10094: 1010 SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, -1) 1011 SMOVE_CHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, -1) 1012 SMOVE_CHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, -1) 1013 SMOVE_CHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, -1) 1014 subcc %o3, 64, %o3 1015 add %o1, 64, %o1 1016 bne 4b 1017 add %o0, 64, %o0 1018 1019 andcc %o2, 0x30, %o3 1020 be,a 1f 1021 srl %g1, 24, %g2 10224: 1023 SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, -1) 1024 subcc %o3, 16, %o3 1025 add %o1, 16, %o1 1026 bne 4b 1027 add %o0, 16, %o0 1028 1029 srl %g1, 24, %g2 10301: 1031 st %o4, [%o0 - 5] 1032 b 88f 1033 stb %g2, [%o0 - 1] 103441: 1035 SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3) 1036 SMOVE_ALIGNCHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3) 1037 SMOVE_ALIGNCHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3) 1038 SMOVE_ALIGNCHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3) 1039 subcc %o3, 64, %o3 1040 add %o1, 64, %o1 1041 bne 41b 1042 add %o0, 64, %o0 1043 1044 andcc %o2, 0x30, %o3 1045 be,a 1f 1046 srl %g1, 16, %g2 10474: 1048 SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3) 1049 subcc %o3, 16, %o3 1050 add %o1, 16, %o1 1051 bne 4b 1052 add %o0, 16, %o0 1053 1054 srl %g1, 16, %g2 10551: 1056 sth %g2, [%o0 - 3] 1057 srl %g1, 8, %g4 1058 b 88f 1059 stb %g4, [%o0 - 1] 106043: 1061 SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, 3) 1062 SMOVE_ALIGNCHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, 3) 1063 SMOVE_ALIGNCHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, 3) 1064 SMOVE_ALIGNCHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, 3) 1065 subcc %o3, 64, %o3 1066 add %o1, 64, %o1 1067 bne 43b 1068 add %o0, 64, %o0 1069 1070 andcc %o2, 0x30, %o3 1071 be,a 1f 1072 srl %g1, 24, %g2 10734: 1074 SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, 3) 1075 subcc %o3, 16, %o3 1076 add %o1, 16, %o1 1077 bne 4b 1078 add %o0, 16, %o0 1079 1080 srl %g1, 24, %g2 10811: 1082 stb %g2, [%o0 + 3] 1083 b 88f 1084 add %o0, 4, %o0 108542: 1086 SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2) 1087 SMOVE_ALIGNCHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2) 1088 SMOVE_ALIGNCHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2) 1089 SMOVE_ALIGNCHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2) 1090 subcc %o3, 64, %o3 1091 add %o1, 64, %o1 1092 bne 42b 1093 add %o0, 64, %o0 1094 1095 andcc %o2, 0x30, %o3 1096 be,a 1f 1097 srl %g1, 16, %g2 10984: 1099 SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2) 1100 subcc %o3, 16, %o3 1101 add %o1, 16, %o1 1102 bne 4b 1103 add %o0, 16, %o0 1104 1105 srl %g1, 16, %g2 11061: 1107 sth %g2, [%o0 - 2] 1108 1109 /* Fall through */ 1110 1111#endif /* FASTER_NONALIGNED */ 1112 111388: /* short_end */ 1114 1115 and %o2, 0xe, %o3 111620: 1117 sethi %hi(89f), %o5 1118 sll %o3, 3, %o4 1119 add %o0, %o3, %o0 1120 sub %o5, %o4, %o5 1121 add %o1, %o3, %o1 1122 jmpl %o5 + %lo(89f), %g0 1123 andcc %o2, 1, %g0 1124 1125 MOVE_SHORTCHUNK(o1, o0, 0x0c, g2, g3) 1126 MOVE_SHORTCHUNK(o1, o0, 0x0a, g2, g3) 1127 MOVE_SHORTCHUNK(o1, o0, 0x08, g2, g3) 1128 MOVE_SHORTCHUNK(o1, o0, 0x06, g2, g3) 1129 MOVE_SHORTCHUNK(o1, o0, 0x04, g2, g3) 1130 MOVE_SHORTCHUNK(o1, o0, 0x02, g2, g3) 1131 MOVE_SHORTCHUNK(o1, o0, 0x00, g2, g3) 1132 113389: /* short_table_end */ 1134 1135 be 1f 1136 nop 1137 1138 ldub [%o1], %g2 1139 stb %g2, [%o0] 11401: 1141 retl 1142 RETL_INSN 1143 114490: /* short_aligned_end */ 1145 bne 88b 1146 andcc %o2, 8, %g0 1147 1148 be 1f 1149 andcc %o2, 4, %g0 1150 1151 ld [%o1 + 0x00], %g2 1152 ld [%o1 + 0x04], %g3 1153 add %o1, 8, %o1 1154 st %g2, [%o0 + 0x00] 1155 st %g3, [%o0 + 0x04] 1156 add %o0, 8, %o0 11571: 1158 b 81b 1159 mov %o2, %g1 1160