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