Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/alpha/lib/ev67-strlen_user.S
10817 views
1
/*
2
* arch/alpha/lib/ev67-strlen_user.S
3
* 21264 version contributed by Rick Gorton <[email protected]>
4
*
5
* Return the length of the string including the NULL terminator
6
* (strlen+1) or zero if an error occurred.
7
*
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.
14
*
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:
20
* E - either cluster
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.
24
*/
25
26
#include <asm/regdef.h>
27
28
29
/* Allow an exception for an insn; exit if we get one. */
30
#define EX(x,y...) \
31
99: x,##y; \
32
.section __ex_table,"a"; \
33
.long 99b - .; \
34
lda v0, $exception-99b(zero); \
35
.previous
36
37
38
.set noreorder
39
.set noat
40
.text
41
42
.globl __strlen_user
43
.ent __strlen_user
44
.frame sp, 0, ra
45
46
.align 4
47
__strlen_user:
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
51
nop
52
nop
53
nop
54
55
.globl __strnlen_user
56
57
.align 4
58
__strnlen_user:
59
.prologue 0
60
EX( ldq_u t0, 0(a0) ) # L : load first quadword (a0 may be misaligned)
61
lda t1, -1(zero) # E :
62
63
insqh t1, a0, t1 # U :
64
andnot a0, 7, v0 # E :
65
or t1, t0, t0 # E :
66
subq a0, 1, a0 # E : get our +1 for the return
67
68
cmpbge zero, t0, t1 # E : t1 <- bitmask: bit i == 1 <==> i-th byte == 0
69
subq a1, 7, t2 # E :
70
subq a0, v0, t0 # E :
71
bne t1, $found # U :
72
73
addq t2, t0, t2 # E :
74
addq a1, 1, a1 # E :
75
nop # E :
76
nop # E :
77
78
.align 4
79
$loop: ble t2, $limit # U :
80
EX( ldq t0, 8(v0) ) # L :
81
nop # E :
82
nop # E :
83
84
cmpbge zero, t0, t1 # E :
85
subq t2, 8, t2 # E :
86
addq v0, 8, v0 # E : addr += 8
87
beq t1, $loop # U :
88
89
$found: cttz t1, t2 # U0 :
90
addq v0, t2, v0 # E :
91
subq v0, a0, v0 # E :
92
ret # L0 :
93
94
$exception:
95
nop
96
nop
97
nop
98
ret
99
100
.align 4 # currently redundant
101
$limit:
102
nop
103
nop
104
subq a1, t2, v0
105
ret
106
107
.end __strlen_user
108
109