copy_in_user.S 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /* copy_in_user.S: Copy from userspace to userspace.
  2. *
  3. * Copyright (C) 1999, 2000, 2004 David S. Miller (davem@redhat.com)
  4. */
  5. #include <linux/linkage.h>
  6. #include <asm/asi.h>
  7. #include <asm/export.h>
  8. #define XCC xcc
  9. #define EX(x,y,z) \
  10. 98: x,y; \
  11. .section __ex_table,"a";\
  12. .align 4; \
  13. .word 98b, z; \
  14. .text; \
  15. .align 4;
  16. #define EX_O4(x,y) EX(x,y,__retl_o4_plus_8)
  17. #define EX_O2_4(x,y) EX(x,y,__retl_o2_plus_4)
  18. #define EX_O2_1(x,y) EX(x,y,__retl_o2_plus_1)
  19. .register %g2,#scratch
  20. .register %g3,#scratch
  21. .text
  22. __retl_o4_plus_8:
  23. add %o4, %o2, %o4
  24. retl
  25. add %o4, 8, %o0
  26. __retl_o2_plus_4:
  27. retl
  28. add %o2, 4, %o0
  29. __retl_o2_plus_1:
  30. retl
  31. add %o2, 1, %o0
  32. .align 32
  33. /* Don't try to get too fancy here, just nice and
  34. * simple. This is predominantly used for well aligned
  35. * small copies in the compat layer. It is also used
  36. * to copy register windows around during thread cloning.
  37. */
  38. ENTRY(___copy_in_user) /* %o0=dst, %o1=src, %o2=len */
  39. cmp %o2, 0
  40. be,pn %XCC, 85f
  41. or %o0, %o1, %o3
  42. cmp %o2, 16
  43. bleu,a,pn %XCC, 80f
  44. or %o3, %o2, %o3
  45. /* 16 < len <= 64 */
  46. andcc %o3, 0x7, %g0
  47. bne,pn %XCC, 90f
  48. nop
  49. andn %o2, 0x7, %o4
  50. and %o2, 0x7, %o2
  51. 1: subcc %o4, 0x8, %o4
  52. EX_O4(ldxa [%o1] %asi, %o5)
  53. EX_O4(stxa %o5, [%o0] %asi)
  54. add %o1, 0x8, %o1
  55. bgu,pt %XCC, 1b
  56. add %o0, 0x8, %o0
  57. andcc %o2, 0x4, %g0
  58. be,pt %XCC, 1f
  59. nop
  60. sub %o2, 0x4, %o2
  61. EX_O2_4(lduwa [%o1] %asi, %o5)
  62. EX_O2_4(stwa %o5, [%o0] %asi)
  63. add %o1, 0x4, %o1
  64. add %o0, 0x4, %o0
  65. 1: cmp %o2, 0
  66. be,pt %XCC, 85f
  67. nop
  68. ba,pt %xcc, 90f
  69. nop
  70. 80: /* 0 < len <= 16 */
  71. andcc %o3, 0x3, %g0
  72. bne,pn %XCC, 90f
  73. nop
  74. 82:
  75. subcc %o2, 4, %o2
  76. EX_O2_4(lduwa [%o1] %asi, %g1)
  77. EX_O2_4(stwa %g1, [%o0] %asi)
  78. add %o1, 4, %o1
  79. bgu,pt %XCC, 82b
  80. add %o0, 4, %o0
  81. 85: retl
  82. clr %o0
  83. .align 32
  84. 90:
  85. subcc %o2, 1, %o2
  86. EX_O2_1(lduba [%o1] %asi, %g1)
  87. EX_O2_1(stba %g1, [%o0] %asi)
  88. add %o1, 1, %o1
  89. bgu,pt %XCC, 90b
  90. add %o0, 1, %o0
  91. retl
  92. clr %o0
  93. ENDPROC(___copy_in_user)
  94. EXPORT_SYMBOL(___copy_in_user)