diff options
Diffstat (limited to 'arch/mips/lib/memcpy.S')
-rw-r--r-- | arch/mips/lib/memcpy.S | 60 |
1 files changed, 47 insertions, 13 deletions
diff --git a/arch/mips/lib/memcpy.S b/arch/mips/lib/memcpy.S index a526c62cb76a..aded7b159052 100644 --- a/arch/mips/lib/memcpy.S +++ b/arch/mips/lib/memcpy.S | |||
@@ -9,6 +9,7 @@ | |||
9 | * Copyright (C) 1999, 2000, 01, 2002 Silicon Graphics, Inc. | 9 | * Copyright (C) 1999, 2000, 01, 2002 Silicon Graphics, Inc. |
10 | * Copyright (C) 2002 Broadcom, Inc. | 10 | * Copyright (C) 2002 Broadcom, Inc. |
11 | * memcpy/copy_user author: Mark Vandevoorde | 11 | * memcpy/copy_user author: Mark Vandevoorde |
12 | * Copyright (C) 2007 Maciej W. Rozycki | ||
12 | * | 13 | * |
13 | * Mnemonic names for arguments to memcpy/__copy_user | 14 | * Mnemonic names for arguments to memcpy/__copy_user |
14 | */ | 15 | */ |
@@ -175,7 +176,11 @@ | |||
175 | 176 | ||
176 | .text | 177 | .text |
177 | .set noreorder | 178 | .set noreorder |
179 | #ifndef CONFIG_CPU_DADDI_WORKAROUNDS | ||
178 | .set noat | 180 | .set noat |
181 | #else | ||
182 | .set at=v1 | ||
183 | #endif | ||
179 | 184 | ||
180 | /* | 185 | /* |
181 | * A combined memcpy/__copy_user | 186 | * A combined memcpy/__copy_user |
@@ -271,8 +276,10 @@ EXC( STORE t0, UNIT(0)(dst), s_exc_p4u) | |||
271 | EXC( STORE t1, UNIT(1)(dst), s_exc_p3u) | 276 | EXC( STORE t1, UNIT(1)(dst), s_exc_p3u) |
272 | EXC( STORE t2, UNIT(2)(dst), s_exc_p2u) | 277 | EXC( STORE t2, UNIT(2)(dst), s_exc_p2u) |
273 | EXC( STORE t3, UNIT(3)(dst), s_exc_p1u) | 278 | EXC( STORE t3, UNIT(3)(dst), s_exc_p1u) |
279 | .set reorder /* DADDI_WAR */ | ||
280 | ADD dst, dst, 4*NBYTES | ||
274 | beqz len, done | 281 | beqz len, done |
275 | ADD dst, dst, 4*NBYTES | 282 | .set noreorder |
276 | less_than_4units: | 283 | less_than_4units: |
277 | /* | 284 | /* |
278 | * rem = len % NBYTES | 285 | * rem = len % NBYTES |
@@ -284,8 +291,10 @@ EXC( LOAD t0, 0(src), l_exc) | |||
284 | ADD src, src, NBYTES | 291 | ADD src, src, NBYTES |
285 | SUB len, len, NBYTES | 292 | SUB len, len, NBYTES |
286 | EXC( STORE t0, 0(dst), s_exc_p1u) | 293 | EXC( STORE t0, 0(dst), s_exc_p1u) |
294 | .set reorder /* DADDI_WAR */ | ||
295 | ADD dst, dst, NBYTES | ||
287 | bne rem, len, 1b | 296 | bne rem, len, 1b |
288 | ADD dst, dst, NBYTES | 297 | .set noreorder |
289 | 298 | ||
290 | /* | 299 | /* |
291 | * src and dst are aligned, need to copy rem bytes (rem < NBYTES) | 300 | * src and dst are aligned, need to copy rem bytes (rem < NBYTES) |
@@ -364,8 +373,10 @@ EXC( STORE t1, UNIT(1)(dst), s_exc_p3u) | |||
364 | EXC( STORE t2, UNIT(2)(dst), s_exc_p2u) | 373 | EXC( STORE t2, UNIT(2)(dst), s_exc_p2u) |
365 | EXC( STORE t3, UNIT(3)(dst), s_exc_p1u) | 374 | EXC( STORE t3, UNIT(3)(dst), s_exc_p1u) |
366 | PREF( 1, 9*32(dst) ) # 1 is PREF_STORE (not streamed) | 375 | PREF( 1, 9*32(dst) ) # 1 is PREF_STORE (not streamed) |
376 | .set reorder /* DADDI_WAR */ | ||
377 | ADD dst, dst, 4*NBYTES | ||
367 | bne len, rem, 1b | 378 | bne len, rem, 1b |
368 | ADD dst, dst, 4*NBYTES | 379 | .set noreorder |
369 | 380 | ||
370 | cleanup_src_unaligned: | 381 | cleanup_src_unaligned: |
371 | beqz len, done | 382 | beqz len, done |
@@ -378,8 +389,10 @@ EXC( LDREST t0, REST(0)(src), l_exc_copy) | |||
378 | ADD src, src, NBYTES | 389 | ADD src, src, NBYTES |
379 | SUB len, len, NBYTES | 390 | SUB len, len, NBYTES |
380 | EXC( STORE t0, 0(dst), s_exc_p1u) | 391 | EXC( STORE t0, 0(dst), s_exc_p1u) |
392 | .set reorder /* DADDI_WAR */ | ||
393 | ADD dst, dst, NBYTES | ||
381 | bne len, rem, 1b | 394 | bne len, rem, 1b |
382 | ADD dst, dst, NBYTES | 395 | .set noreorder |
383 | 396 | ||
384 | copy_bytes_checklen: | 397 | copy_bytes_checklen: |
385 | beqz len, done | 398 | beqz len, done |
@@ -427,8 +440,10 @@ l_exc_copy: | |||
427 | EXC( lb t1, 0(src), l_exc) | 440 | EXC( lb t1, 0(src), l_exc) |
428 | ADD src, src, 1 | 441 | ADD src, src, 1 |
429 | sb t1, 0(dst) # can't fault -- we're copy_from_user | 442 | sb t1, 0(dst) # can't fault -- we're copy_from_user |
443 | .set reorder /* DADDI_WAR */ | ||
444 | ADD dst, dst, 1 | ||
430 | bne src, t0, 1b | 445 | bne src, t0, 1b |
431 | ADD dst, dst, 1 | 446 | .set noreorder |
432 | l_exc: | 447 | l_exc: |
433 | LOAD t0, TI_TASK($28) | 448 | LOAD t0, TI_TASK($28) |
434 | nop | 449 | nop |
@@ -446,20 +461,33 @@ l_exc: | |||
446 | * Clear len bytes starting at dst. Can't call __bzero because it | 461 | * Clear len bytes starting at dst. Can't call __bzero because it |
447 | * might modify len. An inefficient loop for these rare times... | 462 | * might modify len. An inefficient loop for these rare times... |
448 | */ | 463 | */ |
464 | .set reorder /* DADDI_WAR */ | ||
465 | SUB src, len, 1 | ||
449 | beqz len, done | 466 | beqz len, done |
450 | SUB src, len, 1 | 467 | .set noreorder |
451 | 1: sb zero, 0(dst) | 468 | 1: sb zero, 0(dst) |
452 | ADD dst, dst, 1 | 469 | ADD dst, dst, 1 |
470 | #ifndef CONFIG_CPU_DADDI_WORKAROUNDS | ||
453 | bnez src, 1b | 471 | bnez src, 1b |
454 | SUB src, src, 1 | 472 | SUB src, src, 1 |
473 | #else | ||
474 | .set push | ||
475 | .set noat | ||
476 | li v1, 1 | ||
477 | bnez src, 1b | ||
478 | SUB src, src, v1 | ||
479 | .set pop | ||
480 | #endif | ||
455 | jr ra | 481 | jr ra |
456 | nop | 482 | nop |
457 | 483 | ||
458 | 484 | ||
459 | #define SEXC(n) \ | 485 | #define SEXC(n) \ |
460 | s_exc_p ## n ## u: \ | 486 | .set reorder; /* DADDI_WAR */ \ |
461 | jr ra; \ | 487 | s_exc_p ## n ## u: \ |
462 | ADD len, len, n*NBYTES | 488 | ADD len, len, n*NBYTES; \ |
489 | jr ra; \ | ||
490 | .set noreorder | ||
463 | 491 | ||
464 | SEXC(8) | 492 | SEXC(8) |
465 | SEXC(7) | 493 | SEXC(7) |
@@ -471,8 +499,10 @@ SEXC(2) | |||
471 | SEXC(1) | 499 | SEXC(1) |
472 | 500 | ||
473 | s_exc_p1: | 501 | s_exc_p1: |
502 | .set reorder /* DADDI_WAR */ | ||
503 | ADD len, len, 1 | ||
474 | jr ra | 504 | jr ra |
475 | ADD len, len, 1 | 505 | .set noreorder |
476 | s_exc: | 506 | s_exc: |
477 | jr ra | 507 | jr ra |
478 | nop | 508 | nop |
@@ -502,8 +532,10 @@ r_end_bytes: | |||
502 | SUB a2, a2, 0x1 | 532 | SUB a2, a2, 0x1 |
503 | sb t0, -1(a0) | 533 | sb t0, -1(a0) |
504 | SUB a1, a1, 0x1 | 534 | SUB a1, a1, 0x1 |
535 | .set reorder /* DADDI_WAR */ | ||
536 | SUB a0, a0, 0x1 | ||
505 | bnez a2, r_end_bytes | 537 | bnez a2, r_end_bytes |
506 | SUB a0, a0, 0x1 | 538 | .set noreorder |
507 | 539 | ||
508 | r_out: | 540 | r_out: |
509 | jr ra | 541 | jr ra |
@@ -514,8 +546,10 @@ r_end_bytes_up: | |||
514 | SUB a2, a2, 0x1 | 546 | SUB a2, a2, 0x1 |
515 | sb t0, (a0) | 547 | sb t0, (a0) |
516 | ADD a1, a1, 0x1 | 548 | ADD a1, a1, 0x1 |
549 | .set reorder /* DADDI_WAR */ | ||
550 | ADD a0, a0, 0x1 | ||
517 | bnez a2, r_end_bytes_up | 551 | bnez a2, r_end_bytes_up |
518 | ADD a0, a0, 0x1 | 552 | .set noreorder |
519 | 553 | ||
520 | jr ra | 554 | jr ra |
521 | move a2, zero | 555 | move a2, zero |