clear_user.S 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  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. /* Allow an exception for an insn; exit if we get one. */
  28. #define EX(x,y...) \
  29. 99: x,##y; \
  30. .section __ex_table,"a"; \
  31. .long 99b - .; \
  32. lda $31, $exception-99b($31); \
  33. .previous
  34. .set noat
  35. .set noreorder
  36. .align 4
  37. .globl __do_clear_user
  38. .ent __do_clear_user
  39. .frame $30, 0, $28
  40. .prologue 0
  41. $loop:
  42. and $1, 3, $4 # e0 :
  43. beq $4, 1f # .. e1 :
  44. 0: EX( stq_u $31, 0($6) ) # e0 : zero one word
  45. subq $0, 8, $0 # .. e1 :
  46. subq $4, 1, $4 # e0 :
  47. addq $6, 8, $6 # .. e1 :
  48. bne $4, 0b # e1 :
  49. unop # :
  50. 1: bic $1, 3, $1 # e0 :
  51. beq $1, $tail # .. e1 :
  52. 2: EX( stq_u $31, 0($6) ) # e0 : zero four words
  53. subq $0, 8, $0 # .. e1 :
  54. EX( stq_u $31, 8($6) ) # e0 :
  55. subq $0, 8, $0 # .. e1 :
  56. EX( stq_u $31, 16($6) ) # e0 :
  57. subq $0, 8, $0 # .. e1 :
  58. EX( stq_u $31, 24($6) ) # e0 :
  59. subq $0, 8, $0 # .. e1 :
  60. subq $1, 4, $1 # e0 :
  61. addq $6, 32, $6 # .. e1 :
  62. bne $1, 2b # e1 :
  63. $tail:
  64. bne $2, 1f # e1 : is there a tail to do?
  65. ret $31, ($28), 1 # .. e1 :
  66. 1: EX( ldq_u $5, 0($6) ) # e0 :
  67. clr $0 # .. e1 :
  68. nop # e1 :
  69. mskqh $5, $0, $5 # e0 :
  70. EX( stq_u $5, 0($6) ) # e0 :
  71. ret $31, ($28), 1 # .. e1 :
  72. __do_clear_user:
  73. and $6, 7, $4 # e0 : find dest misalignment
  74. beq $0, $zerolength # .. e1 :
  75. addq $0, $4, $1 # e0 : bias counter
  76. and $1, 7, $2 # e1 : number of bytes in tail
  77. srl $1, 3, $1 # e0 :
  78. beq $4, $loop # .. e1 :
  79. EX( ldq_u $5, 0($6) ) # e0 : load dst word to mask back in
  80. beq $1, $oneword # .. e1 : sub-word store?
  81. mskql $5, $6, $5 # e0 : take care of misaligned head
  82. addq $6, 8, $6 # .. e1 :
  83. EX( stq_u $5, -8($6) ) # e0 :
  84. addq $0, $4, $0 # .. e1 : bytes left -= 8 - misalignment
  85. subq $1, 1, $1 # e0 :
  86. subq $0, 8, $0 # .. e1 :
  87. br $loop # e1 :
  88. unop # :
  89. $oneword:
  90. mskql $5, $6, $4 # e0 :
  91. mskqh $5, $2, $5 # e0 :
  92. or $5, $4, $5 # e1 :
  93. EX( stq_u $5, 0($6) ) # e0 :
  94. clr $0 # .. e1 :
  95. $zerolength:
  96. $exception:
  97. ret $31, ($28), 1 # .. e1 :
  98. .end __do_clear_user