copy_page_64.S 2.1 KB

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