2 * arch/alpha/lib/ev67-strlen_user.S
3 * 21264 version contributed by Rick Gorton <rick.gorton@api-networks.com>
5 * Return the length of the string including the NULL terminator
6 * (strlen+1) or zero if an error occurred.
8 * In places where it is critical to limit the processing time,
9 * and the data is not trusted, strnlen_user() should be used.
10 * It will return a value greater than its second argument if
11 * that limit would be exceeded. This implementation is allowed
12 * to access memory beyond the limit, but will not cross a page
13 * boundary when doing so.
15 * Much of the information about 21264 scheduling/coding comes from:
16 * Compiler Writer's Guide for the Alpha 21264
17 * abbreviated as 'CWG' in other comments here
18 * ftp.digital.com/pub/Digital/info/semiconductor/literature/dsc-library.html
19 * Scheduling notation:
21 * U - upper subcluster; U0 - subcluster U0; U1 - subcluster U1
22 * L - lower subcluster; L0 - subcluster L0; L1 - subcluster L1
23 * Try not to change the actual algorithm if possible for consistency.
26 #include <asm/regdef.h>
29 /* Allow an exception for an insn; exit if we get one. */
32 .section __ex_table,"a"; \
34 lda v0, $exception-99b(zero); \
48 ldah a1, 32767(zero) # do not use plain strlen_user() for strings
49 # that might be almost 2 GB long; you should
50 # be using strnlen_user() instead
60 EX( ldq_u t0, 0(a0) ) # L : load first quadword (a0 may be misaligned)
61 lda t1, -1(zero) # E :
63 insqh t1, a0, t1 # U :
64 andnot a0, 7, v0 # E :
66 subq a0, 1, a0 # E : get our +1 for the return
68 cmpbge zero, t0, t1 # E : t1 <- bitmask: bit i == 1 <==> i-th byte == 0
79 $loop: ble t2, $limit # U :
80 EX( ldq t0, 8(v0) ) # L :
84 cmpbge zero, t0, t1 # E :
86 addq v0, 8, v0 # E : addr += 8
89 $found: cttz t1, t2 # U0 :
100 .align 4 # currently redundant