Linux-2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
This commit is contained in:
91
arch/alpha/lib/strlen_user.S
Normal file
91
arch/alpha/lib/strlen_user.S
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* arch/alpha/lib/strlen_user.S
|
||||
*
|
||||
* Return the length of the string including the NUL terminator
|
||||
* (strlen+1) or zero if an error occurred.
|
||||
*
|
||||
* In places where it is critical to limit the processing time,
|
||||
* and the data is not trusted, strnlen_user() should be used.
|
||||
* It will return a value greater than its second argument if
|
||||
* that limit would be exceeded. This implementation is allowed
|
||||
* to access memory beyond the limit, but will not cross a page
|
||||
* boundary when doing so.
|
||||
*/
|
||||
|
||||
#include <asm/regdef.h>
|
||||
|
||||
|
||||
/* Allow an exception for an insn; exit if we get one. */
|
||||
#define EX(x,y...) \
|
||||
99: x,##y; \
|
||||
.section __ex_table,"a"; \
|
||||
.long 99b - .; \
|
||||
lda v0, $exception-99b(zero); \
|
||||
.previous
|
||||
|
||||
|
||||
.set noreorder
|
||||
.set noat
|
||||
.text
|
||||
|
||||
.globl __strlen_user
|
||||
.ent __strlen_user
|
||||
.frame sp, 0, ra
|
||||
|
||||
.align 3
|
||||
__strlen_user:
|
||||
ldah a1, 32767(zero) # do not use plain strlen_user() for strings
|
||||
# that might be almost 2 GB long; you should
|
||||
# be using strnlen_user() instead
|
||||
|
||||
.globl __strnlen_user
|
||||
|
||||
.align 3
|
||||
__strnlen_user:
|
||||
.prologue 0
|
||||
|
||||
EX( ldq_u t0, 0(a0) ) # load first quadword (a0 may be misaligned)
|
||||
lda t1, -1(zero)
|
||||
insqh t1, a0, t1
|
||||
andnot a0, 7, v0
|
||||
or t1, t0, t0
|
||||
subq a0, 1, a0 # get our +1 for the return
|
||||
cmpbge zero, t0, t1 # t1 <- bitmask: bit i == 1 <==> i-th byte == 0
|
||||
subq a1, 7, t2
|
||||
subq a0, v0, t0
|
||||
bne t1, $found
|
||||
|
||||
addq t2, t0, t2
|
||||
addq a1, 1, a1
|
||||
|
||||
.align 3
|
||||
$loop: ble t2, $limit
|
||||
EX( ldq t0, 8(v0) )
|
||||
subq t2, 8, t2
|
||||
addq v0, 8, v0 # addr += 8
|
||||
cmpbge zero, t0, t1
|
||||
beq t1, $loop
|
||||
|
||||
$found: negq t1, t2 # clear all but least set bit
|
||||
and t1, t2, t1
|
||||
|
||||
and t1, 0xf0, t2 # binary search for that set bit
|
||||
and t1, 0xcc, t3
|
||||
and t1, 0xaa, t4
|
||||
cmovne t2, 4, t2
|
||||
cmovne t3, 2, t3
|
||||
cmovne t4, 1, t4
|
||||
addq t2, t3, t2
|
||||
addq v0, t4, v0
|
||||
addq v0, t2, v0
|
||||
nop # dual issue next two on ev4 and ev5
|
||||
subq v0, a0, v0
|
||||
$exception:
|
||||
ret
|
||||
|
||||
.align 3 # currently redundant
|
||||
$limit:
|
||||
subq a1, t2, v0
|
||||
ret
|
||||
|
||||
.end __strlen_user
|
Reference in New Issue
Block a user