copy_page_64.S 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  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/cpufeature.h>
  5. #include <asm/alternative-asm.h>
  6. /*
  7. * Some CPUs run faster using the string copy instructions (sane microcode).
  8. * It is also a lot simpler. Use this when possible. But, don't use streaming
  9. * copy unless the CPU indicates X86_FEATURE_REP_GOOD. Could vary the
  10. * prefetch distance based on SMP/UP.
  11. */
  12. ALIGN
  13. ENTRY(copy_page)
  14. CFI_STARTPROC
  15. ALTERNATIVE "jmp copy_page_regs", "", X86_FEATURE_REP_GOOD
  16. movl $4096/8, %ecx
  17. rep movsq
  18. ret
  19. CFI_ENDPROC
  20. ENDPROC(copy_page)
  21. ENTRY(copy_page_regs)
  22. CFI_STARTPROC
  23. subq $2*8, %rsp
  24. CFI_ADJUST_CFA_OFFSET 2*8
  25. movq %rbx, (%rsp)
  26. CFI_REL_OFFSET rbx, 0
  27. movq %r12, 1*8(%rsp)
  28. CFI_REL_OFFSET r12, 1*8
  29. movl $(4096/64)-5, %ecx
  30. .p2align 4
  31. .Loop64:
  32. dec %rcx
  33. movq 0x8*0(%rsi), %rax
  34. movq 0x8*1(%rsi), %rbx
  35. movq 0x8*2(%rsi), %rdx
  36. movq 0x8*3(%rsi), %r8
  37. movq 0x8*4(%rsi), %r9
  38. movq 0x8*5(%rsi), %r10
  39. movq 0x8*6(%rsi), %r11
  40. movq 0x8*7(%rsi), %r12
  41. prefetcht0 5*64(%rsi)
  42. movq %rax, 0x8*0(%rdi)
  43. movq %rbx, 0x8*1(%rdi)
  44. movq %rdx, 0x8*2(%rdi)
  45. movq %r8, 0x8*3(%rdi)
  46. movq %r9, 0x8*4(%rdi)
  47. movq %r10, 0x8*5(%rdi)
  48. movq %r11, 0x8*6(%rdi)
  49. movq %r12, 0x8*7(%rdi)
  50. leaq 64 (%rsi), %rsi
  51. leaq 64 (%rdi), %rdi
  52. jnz .Loop64
  53. movl $5, %ecx
  54. .p2align 4
  55. .Loop2:
  56. decl %ecx
  57. movq 0x8*0(%rsi), %rax
  58. movq 0x8*1(%rsi), %rbx
  59. movq 0x8*2(%rsi), %rdx
  60. movq 0x8*3(%rsi), %r8
  61. movq 0x8*4(%rsi), %r9
  62. movq 0x8*5(%rsi), %r10
  63. movq 0x8*6(%rsi), %r11
  64. movq 0x8*7(%rsi), %r12
  65. movq %rax, 0x8*0(%rdi)
  66. movq %rbx, 0x8*1(%rdi)
  67. movq %rdx, 0x8*2(%rdi)
  68. movq %r8, 0x8*3(%rdi)
  69. movq %r9, 0x8*4(%rdi)
  70. movq %r10, 0x8*5(%rdi)
  71. movq %r11, 0x8*6(%rdi)
  72. movq %r12, 0x8*7(%rdi)
  73. leaq 64(%rdi), %rdi
  74. leaq 64(%rsi), %rsi
  75. jnz .Loop2
  76. movq (%rsp), %rbx
  77. CFI_RESTORE rbx
  78. movq 1*8(%rsp), %r12
  79. CFI_RESTORE r12
  80. addq $2*8, %rsp
  81. CFI_ADJUST_CFA_OFFSET -2*8
  82. ret
  83. CFI_ENDPROC
  84. ENDPROC(copy_page_regs)