• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6/arch/alpha/lib/
1/*
2 * arch/alpha/lib/ev67-strlen_user.S
3 * 21264 version contributed by Rick Gorton <rick.gorton@api-networks.com>
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