1
2
3
4
5
6
7
8
9 #include <asm/asm.h>
10 #include <asm/asm-offsets.h>
11 #include <asm/export.h>
12 #include <asm/regdef.h>
13
14 #define EX(insn,reg,addr,handler) \
15 9: insn reg, addr; \
16 .section __ex_table,"a"; \
17 PTR 9b, handler; \
18 .previous
19
20
21
22
23
24
25
26
27
28
29 .macro __BUILD_STRNLEN_ASM func
30 LEAF(__strnlen_\func\()_asm)
31 LONG_L v0, TI_ADDR_LIMIT($28) # pointer ok?
32 and v0, a0
33 bnez v0, .Lfault\@
34
35 move v0, a0
36 PTR_ADDU a1, a0 # stop pointer
37 1:
38 #ifdef CONFIG_CPU_DADDI_WORKAROUNDS
39 .set noat
40 li AT, 1
41 #endif
42 beq v0, a1, 1f # limit reached?
43 .ifeqs "\func", "kernel"
44 EX(lb, t0, (v0), .Lfault\@)
45 .else
46 EX(lbe, t0, (v0), .Lfault\@)
47 .endif
48 .set noreorder
49 bnez t0, 1b
50 1:
51 #ifndef CONFIG_CPU_DADDI_WORKAROUNDS
52 PTR_ADDIU v0, 1
53 #else
54 PTR_ADDU v0, AT
55 .set at
56 #endif
57 .set reorder
58 PTR_SUBU v0, a0
59 jr ra
60 END(__strnlen_\func\()_asm)
61
62 .Lfault\@:
63 move v0, zero
64 jr ra
65 .endm
66
67 #ifndef CONFIG_EVA
68
69 .global __strnlen_user_asm
70 .set __strnlen_user_asm, __strnlen_kernel_asm
71 EXPORT_SYMBOL(__strnlen_user_asm)
72 #endif
73
74 __BUILD_STRNLEN_ASM kernel
75 EXPORT_SYMBOL(__strnlen_kernel_asm)
76
77 #ifdef CONFIG_EVA
78
79 .set push
80 .set eva
81 __BUILD_STRNLEN_ASM user
82 .set pop
83 EXPORT_SYMBOL(__strnlen_user_asm)
84 #endif