copy_page_64.S 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. /* Written 2003 by Andi Kleen, based on a kernel by Evandro Menezes */
  2. #include <linux/linkage.h>
  3. #include <asm/dwarf2.h>
  4. #include <asm/alternative-asm.h>
  5. ALIGN
  6. copy_page_c:
  7. CFI_STARTPROC
  8. movl $4096/8,%ecx
  9. rep movsq
  10. ret
  11. CFI_ENDPROC
  12. ENDPROC(copy_page_c)
  13. /* Don't use streaming store because it's better when the target
  14. ends up in cache. */
  15. /* Could vary the prefetch distance based on SMP/UP */
  16. ENTRY(copy_page)
  17. CFI_STARTPROC
  18. subq $3*8,%rsp
  19. CFI_ADJUST_CFA_OFFSET 3*8
  20. movq %rbx,(%rsp)
  21. CFI_REL_OFFSET rbx, 0
  22. movq %r12,1*8(%rsp)
  23. CFI_REL_OFFSET r12, 1*8
  24. movq %r13,2*8(%rsp)
  25. CFI_REL_OFFSET r13, 2*8
  26. movl $(4096/64)-5,%ecx
  27. .p2align 4
  28. .Loop64:
  29. dec %rcx
  30. movq (%rsi), %rax
  31. movq 8 (%rsi), %rbx
  32. movq 16 (%rsi), %rdx
  33. movq 24 (%rsi), %r8
  34. movq 32 (%rsi), %r9
  35. movq 40 (%rsi), %r10
  36. movq 48 (%rsi), %r11
  37. movq 56 (%rsi), %r12
  38. prefetcht0 5*64(%rsi)
  39. movq %rax, (%rdi)
  40. movq %rbx, 8 (%rdi)
  41. movq %rdx, 16 (%rdi)
  42. movq %r8, 24 (%rdi)
  43. movq %r9, 32 (%rdi)
  44. movq %r10, 40 (%rdi)
  45. movq %r11, 48 (%rdi)
  46. movq %r12, 56 (%rdi)
  47. leaq 64 (%rsi), %rsi
  48. leaq 64 (%rdi), %rdi
  49. jnz .Loop64
  50. movl $5,%ecx
  51. .p2align 4
  52. .Loop2:
  53. decl %ecx
  54. movq (%rsi), %rax
  55. movq 8 (%rsi), %rbx
  56. movq 16 (%rsi), %rdx
  57. movq 24 (%rsi), %r8
  58. movq 32 (%rsi), %r9
  59. movq 40 (%rsi), %r10
  60. movq 48 (%rsi), %r11
  61. movq 56 (%rsi), %r12
  62. movq %rax, (%rdi)
  63. movq %rbx, 8 (%rdi)
  64. movq %rdx, 16 (%rdi)
  65. movq %r8, 24 (%rdi)
  66. movq %r9, 32 (%rdi)
  67. movq %r10, 40 (%rdi)
  68. movq %r11, 48 (%rdi)
  69. movq %r12, 56 (%rdi)
  70. leaq 64(%rdi),%rdi
  71. leaq 64(%rsi),%rsi
  72. jnz .Loop2
  73. movq (%rsp),%rbx
  74. CFI_RESTORE rbx
  75. movq 1*8(%rsp),%r12
  76. CFI_RESTORE r12
  77. movq 2*8(%rsp),%r13
  78. CFI_RESTORE r13
  79. addq $3*8,%rsp
  80. CFI_ADJUST_CFA_OFFSET -3*8
  81. ret
  82. .Lcopy_page_end:
  83. CFI_ENDPROC
  84. ENDPROC(copy_page)
  85. /* Some CPUs run faster using the string copy instructions.
  86. It is also a lot simpler. Use this when possible */
  87. #include <asm/cpufeature.h>
  88. .section .altinstr_replacement,"ax"
  89. 1: .byte 0xeb /* jmp <disp8> */
  90. .byte (copy_page_c - copy_page) - (2f - 1b) /* offset */
  91. 2:
  92. .previous
  93. .section .altinstructions,"a"
  94. altinstruction_entry copy_page, 1b, X86_FEATURE_REP_GOOD, \
  95. .Lcopy_page_end-copy_page, 2b-1b
  96. .previous