^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/ev6-copy_user.S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * 21264 version contributed by Rick Gorton <rick.gorton@alpha-processor.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copy to/from user space, handling exceptions as we go.. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * isn't exactly pretty.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * This is essentially the same as "memcpy()", but with a few twists.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Notably, we have to make sure that $0 is always up-to-date and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * contains the right "bytes left to copy" value (and that it is updated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * only _after_ a successful copy). There is also some rather minor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * exception setup stuff..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * Much of the information about 21264 scheduling/coding comes from:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * Compiler Writer's Guide for the Alpha 21264
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * abbreviated as 'CWG' in other comments here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * ftp.digital.com/pub/Digital/info/semiconductor/literature/dsc-library.html
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * Scheduling notation:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * E - either cluster
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * U - upper subcluster; U0 - subcluster U0; U1 - subcluster U1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * L - lower subcluster; L0 - subcluster L0; L1 - subcluster L1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <asm/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) /* Allow an exception for an insn; exit if we get one. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define EXI(x,y...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) 99: x,##y; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) .section __ex_table,"a"; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) .long 99b - .; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) lda $31, $exitin-99b($31); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) .previous
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define EXO(x,y...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) 99: x,##y; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) .section __ex_table,"a"; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) .long 99b - .; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) lda $31, $exitout-99b($31); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) .previous
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) .set noat
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) .align 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) .globl __copy_user
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) .ent __copy_user
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) # Pipeline info: Slotting & Comments
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) __copy_user:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) .prologue 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) mov $18, $0 # .. .. .. E
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) subq $18, 32, $1 # .. .. E. .. : Is this going to be a small copy?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) nop # .. E .. ..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) beq $18, $zerolength # U .. .. .. : U L U L
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) and $16,7,$3 # .. .. .. E : is leading dest misalignment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) ble $1, $onebyteloop # .. .. U .. : 1st branch : small amount of data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) beq $3, $destaligned # .. U .. .. : 2nd (one cycle fetcher stall)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) subq $3, 8, $3 # E .. .. .. : L U U L : trip counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * The fetcher stall also hides the 1 cycle cross-cluster stall for $3 (L --> U)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * This loop aligns the destination a byte at a time
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * We know we have at least one trip through this loop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) $aligndest:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) EXI( ldbu $1,0($17) ) # .. .. .. L : Keep loads separate from stores
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) addq $16,1,$16 # .. .. E .. : Section 3.8 in the CWG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) addq $3,1,$3 # .. E .. .. :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) nop # E .. .. .. : U L U L
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) * the -1 is to compensate for the inc($16) done in a previous quadpack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) * which allows us zero dependencies within either quadpack in the loop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) EXO( stb $1,-1($16) ) # .. .. .. L :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) addq $17,1,$17 # .. .. E .. : Section 3.8 in the CWG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) subq $0,1,$0 # .. E .. .. :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) bne $3, $aligndest # U .. .. .. : U L U L
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * If we fell through into here, we have a minimum of 33 - 7 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * If we arrived via branch, we have a minimum of 32 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) $destaligned:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) and $17,7,$1 # .. .. .. E : Check _current_ source alignment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) bic $0,7,$4 # .. .. E .. : number bytes as a quadword loop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) EXI( ldq_u $3,0($17) ) # .. L .. .. : Forward fetch for fallthrough code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) beq $1,$quadaligned # U .. .. .. : U L U L
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * In the worst case, we've just executed an ldq_u here from 0($17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * and we'll repeat it once if we take the branch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) /* Misaligned quadword loop - not unrolled. Leave it that way. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) $misquad:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) EXI( ldq_u $2,8($17) ) # .. .. .. L :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) subq $4,8,$4 # .. .. E .. :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) extql $3,$17,$3 # .. U .. .. :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) extqh $2,$17,$1 # U .. .. .. : U U L L
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) bis $3,$1,$1 # .. .. .. E :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) EXO( stq $1,0($16) ) # .. .. L .. :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) addq $17,8,$17 # .. E .. .. :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) subq $0,8,$0 # E .. .. .. : U L L U
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) addq $16,8,$16 # .. .. .. E :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) bis $2,$2,$3 # .. .. E .. :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) nop # .. E .. .. :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) bne $4,$misquad # U .. .. .. : U L U L
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) nop # .. .. .. E
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) nop # .. .. E ..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) nop # .. E .. ..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) beq $0,$zerolength # U .. .. .. : U L U L
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) /* We know we have at least one trip through the byte loop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) EXI ( ldbu $2,0($17) ) # .. .. .. L : No loads in the same quad
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) addq $16,1,$16 # .. .. E .. : as the store (Section 3.8 in CWG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) nop # .. E .. .. :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) br $31, $dirtyentry # L0 .. .. .. : L U U L
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) /* Do the trailing byte loop load, then hop into the store part of the loop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) * A minimum of (33 - 7) bytes to do a quad at a time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) * Based upon the usage context, it's worth the effort to unroll this loop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) * $0 - number of bytes to be moved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * $4 - number of bytes to move as quadwords
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * $16 is current destination address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * $17 is current source address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) $quadaligned:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) subq $4, 32, $2 # .. .. .. E : do not unroll for small stuff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) nop # .. .. E ..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) nop # .. E .. ..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) blt $2, $onequad # U .. .. .. : U L U L
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * There is a significant assumption here that the source and destination
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * addresses differ by more than 32 bytes. In this particular case, a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) * sparsity of registers further bounds this to be a minimum of 8 bytes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) * But if this isn't met, then the output result will be incorrect.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * Furthermore, due to a lack of available registers, we really can't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * unroll this to be an 8x loop (which would enable us to use the wh64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * instruction memory hint instruction).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) $unroll4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) EXI( ldq $1,0($17) ) # .. .. .. L
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) EXI( ldq $2,8($17) ) # .. .. L ..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) subq $4,32,$4 # .. E .. ..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) nop # E .. .. .. : U U L L
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) addq $17,16,$17 # .. .. .. E
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) EXO( stq $1,0($16) ) # .. .. L ..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) EXO( stq $2,8($16) ) # .. L .. ..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) subq $0,16,$0 # E .. .. .. : U L L U
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) addq $16,16,$16 # .. .. .. E
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) EXI( ldq $1,0($17) ) # .. .. L ..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) EXI( ldq $2,8($17) ) # .. L .. ..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) subq $4, 32, $3 # E .. .. .. : U U L L : is there enough for another trip?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) EXO( stq $1,0($16) ) # .. .. .. L
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) EXO( stq $2,8($16) ) # .. .. L ..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) subq $0,16,$0 # .. E .. ..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) addq $17,16,$17 # E .. .. .. : U L L U
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) nop # .. .. .. E
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) nop # .. .. E ..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) addq $16,16,$16 # .. E .. ..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) bgt $3,$unroll4 # U .. .. .. : U L U L
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) beq $4, $noquads
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) $onequad:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) EXI( ldq $1,0($17) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) subq $4,8,$4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) addq $17,8,$17
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) EXO( stq $1,0($16) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) subq $0,8,$0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) addq $16,8,$16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) bne $4,$onequad
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) $noquads:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) beq $0,$zerolength
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) * For small copies (or the tail of a larger copy), do a very simple byte loop.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * There's no point in doing a lot of complex alignment calculations to try to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) * to quadword stuff for a small amount of data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) * $0 - remaining number of bytes left to copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) * $16 - current dest addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) * $17 - current source addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) $onebyteloop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) EXI ( ldbu $2,0($17) ) # .. .. .. L : No loads in the same quad
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) addq $16,1,$16 # .. .. E .. : as the store (Section 3.8 in CWG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) nop # .. E .. .. :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) nop # E .. .. .. : U L U L
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) $dirtyentry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) * the -1 is to compensate for the inc($16) done in a previous quadpack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) * which allows us zero dependencies within either quadpack in the loop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) EXO ( stb $2,-1($16) ) # .. .. .. L :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) addq $17,1,$17 # .. .. E .. : quadpack as the load
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) subq $0,1,$0 # .. E .. .. : change count _after_ copy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) bgt $0,$onebyteloop # U .. .. .. : U L U L
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) $zerolength:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) $exitin:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) $exitout: # Destination for exception recovery(?)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) nop # .. .. .. E
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) nop # .. .. E ..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) nop # .. E .. ..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) ret $31,($26),1 # L0 .. .. .. : L U L U
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) .end __copy_user
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) EXPORT_SYMBOL(__copy_user)