diff options
Diffstat (limited to 'arch/alpha/lib/strlen_user.S')
-rw-r--r-- | arch/alpha/lib/strlen_user.S | 91 |
1 files changed, 0 insertions, 91 deletions
diff --git a/arch/alpha/lib/strlen_user.S b/arch/alpha/lib/strlen_user.S deleted file mode 100644 index 508a18e96479..000000000000 --- a/arch/alpha/lib/strlen_user.S +++ /dev/null | |||
@@ -1,91 +0,0 @@ | |||
1 | /* | ||
2 | * arch/alpha/lib/strlen_user.S | ||
3 | * | ||
4 | * Return the length of the string including the NUL terminator | ||
5 | * (strlen+1) or zero if an error occurred. | ||
6 | * | ||
7 | * In places where it is critical to limit the processing time, | ||
8 | * and the data is not trusted, strnlen_user() should be used. | ||
9 | * It will return a value greater than its second argument if | ||
10 | * that limit would be exceeded. This implementation is allowed | ||
11 | * to access memory beyond the limit, but will not cross a page | ||
12 | * boundary when doing so. | ||
13 | */ | ||
14 | |||
15 | #include <asm/regdef.h> | ||
16 | |||
17 | |||
18 | /* Allow an exception for an insn; exit if we get one. */ | ||
19 | #define EX(x,y...) \ | ||
20 | 99: x,##y; \ | ||
21 | .section __ex_table,"a"; \ | ||
22 | .long 99b - .; \ | ||
23 | lda v0, $exception-99b(zero); \ | ||
24 | .previous | ||
25 | |||
26 | |||
27 | .set noreorder | ||
28 | .set noat | ||
29 | .text | ||
30 | |||
31 | .globl __strlen_user | ||
32 | .ent __strlen_user | ||
33 | .frame sp, 0, ra | ||
34 | |||
35 | .align 3 | ||
36 | __strlen_user: | ||
37 | ldah a1, 32767(zero) # do not use plain strlen_user() for strings | ||
38 | # that might be almost 2 GB long; you should | ||
39 | # be using strnlen_user() instead | ||
40 | |||
41 | .globl __strnlen_user | ||
42 | |||
43 | .align 3 | ||
44 | __strnlen_user: | ||
45 | .prologue 0 | ||
46 | |||
47 | EX( ldq_u t0, 0(a0) ) # load first quadword (a0 may be misaligned) | ||
48 | lda t1, -1(zero) | ||
49 | insqh t1, a0, t1 | ||
50 | andnot a0, 7, v0 | ||
51 | or t1, t0, t0 | ||
52 | subq a0, 1, a0 # get our +1 for the return | ||
53 | cmpbge zero, t0, t1 # t1 <- bitmask: bit i == 1 <==> i-th byte == 0 | ||
54 | subq a1, 7, t2 | ||
55 | subq a0, v0, t0 | ||
56 | bne t1, $found | ||
57 | |||
58 | addq t2, t0, t2 | ||
59 | addq a1, 1, a1 | ||
60 | |||
61 | .align 3 | ||
62 | $loop: ble t2, $limit | ||
63 | EX( ldq t0, 8(v0) ) | ||
64 | subq t2, 8, t2 | ||
65 | addq v0, 8, v0 # addr += 8 | ||
66 | cmpbge zero, t0, t1 | ||
67 | beq t1, $loop | ||
68 | |||
69 | $found: negq t1, t2 # clear all but least set bit | ||
70 | and t1, t2, t1 | ||
71 | |||
72 | and t1, 0xf0, t2 # binary search for that set bit | ||
73 | and t1, 0xcc, t3 | ||
74 | and t1, 0xaa, t4 | ||
75 | cmovne t2, 4, t2 | ||
76 | cmovne t3, 2, t3 | ||
77 | cmovne t4, 1, t4 | ||
78 | addq t2, t3, t2 | ||
79 | addq v0, t4, v0 | ||
80 | addq v0, t2, v0 | ||
81 | nop # dual issue next two on ev4 and ev5 | ||
82 | subq v0, a0, v0 | ||
83 | $exception: | ||
84 | ret | ||
85 | |||
86 | .align 3 # currently redundant | ||
87 | $limit: | ||
88 | subq a1, t2, v0 | ||
89 | ret | ||
90 | |||
91 | .end __strlen_user | ||