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