clear_user.S 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. /*
  2. * arch/alpha/lib/clear_user.S
  3. * Contributed by Richard Henderson <rth@tamu.edu>
  4. *
  5. * Zero user space, handling exceptions as we go.
  6. *
  7. * We have to make sure that $0 is always up-to-date and contains the
  8. * right "bytes left to zero" value (and that it is updated only _after_
  9. * a successful copy). There is also some rather minor exception setup
  10. * stuff.
  11. *
  12. * NOTE! This is not directly C-callable, because the calling semantics
  13. * are different:
  14. *
  15. * Inputs:
  16. * length in $0
  17. * destination address in $6
  18. * exception pointer in $7
  19. * return address in $28 (exceptions expect it there)
  20. *
  21. * Outputs:
  22. * bytes left to copy in $0
  23. *
  24. * Clobbers:
  25. * $1,$2,$3,$4,$5,$6
  26. */
  27. #include <asm/export.h>
  28. /* Allow an exception for an insn; exit if we get one. */
  29. #define EX(x,y...) \
  30. 99: x,##y; \
  31. .section __ex_table,"a"; \
  32. .long 99b - .; \
  33. lda $31, $exception-99b($31); \
  34. .previous
  35. .set noat
  36. .set noreorder
  37. .align 4
  38. .globl __do_clear_user
  39. .ent __do_clear_user
  40. .frame $30, 0, $28
  41. .prologue 0
  42. $loop:
  43. and $1, 3, $4 # e0 :
  44. beq $4, 1f # .. e1 :
  45. 0: EX( stq_u $31, 0($6) ) # e0 : zero one word
  46. subq $0, 8, $0 # .. e1 :
  47. subq $4, 1, $4 # e0 :
  48. addq $6, 8, $6 # .. e1 :
  49. bne $4, 0b # e1 :
  50. unop # :
  51. 1: bic $1, 3, $1 # e0 :
  52. beq $1, $tail # .. e1 :
  53. 2: EX( stq_u $31, 0($6) ) # e0 : zero four words
  54. subq $0, 8, $0 # .. e1 :
  55. EX( stq_u $31, 8($6) ) # e0 :
  56. subq $0, 8, $0 # .. e1 :
  57. EX( stq_u $31, 16($6) ) # e0 :
  58. subq $0, 8, $0 # .. e1 :
  59. EX( stq_u $31, 24($6) ) # e0 :
  60. subq $0, 8, $0 # .. e1 :
  61. subq $1, 4, $1 # e0 :
  62. addq $6, 32, $6 # .. e1 :
  63. bne $1, 2b # e1 :
  64. $tail:
  65. bne $2, 1f # e1 : is there a tail to do?
  66. ret $31, ($28), 1 # .. e1 :
  67. 1: EX( ldq_u $5, 0($6) ) # e0 :
  68. clr $0 # .. e1 :
  69. nop # e1 :
  70. mskqh $5, $0, $5 # e0 :
  71. EX( stq_u $5, 0($6) ) # e0 :
  72. ret $31, ($28), 1 # .. e1 :
  73. __do_clear_user:
  74. and $6, 7, $4 # e0 : find dest misalignment
  75. beq $0, $zerolength # .. e1 :
  76. addq $0, $4, $1 # e0 : bias counter
  77. and $1, 7, $2 # e1 : number of bytes in tail
  78. srl $1, 3, $1 # e0 :
  79. beq $4, $loop # .. e1 :
  80. EX( ldq_u $5, 0($6) ) # e0 : load dst word to mask back in
  81. beq $1, $oneword # .. e1 : sub-word store?
  82. mskql $5, $6, $5 # e0 : take care of misaligned head
  83. addq $6, 8, $6 # .. e1 :
  84. EX( stq_u $5, -8($6) ) # e0 :
  85. addq $0, $4, $0 # .. e1 : bytes left -= 8 - misalignment
  86. subq $1, 1, $1 # e0 :
  87. subq $0, 8, $0 # .. e1 :
  88. br $loop # e1 :
  89. unop # :
  90. $oneword:
  91. mskql $5, $6, $4 # e0 :
  92. mskqh $5, $2, $5 # e0 :
  93. or $5, $4, $5 # e1 :
  94. EX( stq_u $5, 0($6) ) # e0 :
  95. clr $0 # .. e1 :
  96. $zerolength:
  97. $exception:
  98. ret $31, ($28), 1 # .. e1 :
  99. .end __do_clear_user
  100. EXPORT_SYMBOL(__do_clear_user)