]>
Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
2 | * linux/arch/m32r/strlen.S -- strlen code. | |
3 | * | |
4 | * Copyright (C) 2001 Hirokazu Takata | |
5 | * | |
6 | * size_t strlen(const char *s); | |
7 | * | |
8 | */ | |
1da177e4 | 9 | |
1da177e4 LT |
10 | #include <linux/linkage.h> |
11 | #include <asm/assembler.h> | |
12 | ||
13 | #ifdef CONFIG_ISA_DUAL_ISSUE | |
14 | ||
15 | .text | |
16 | ENTRY(strlen) | |
17 | mv r6, r0 || ldi r2, #0 | |
18 | and3 r0, r0, #3 | |
19 | bnez r0, strlen_byte | |
20 | ; | |
21 | strlen_word: | |
22 | ld r0, @r6+ | |
23 | ; | |
24 | seth r5, #high(0x01010101) | |
25 | or3 r5, r5, #low(0x01010101) | |
26 | sll3 r7, r5, #7 | |
27 | strlen_word_loop: | |
28 | ld r1, @r6+ || not r4, r0 | |
29 | sub r0, r5 || and r4, r7 | |
30 | and r4, r0 | |
31 | bnez r4, strlen_last_bytes | |
32 | ld r0, @r6+ || not r4, r1 | |
33 | sub r1, r5 || and r4, r7 | |
34 | and r4, r1 || addi r2, #4 | |
35 | bnez r4, strlen_last_bytes | |
36 | addi r2, #4 || bra.s strlen_word_loop | |
37 | ||
38 | ; NOTE: If a null char. exists, return 0. | |
39 | ; if ((x - 0x01010101) & ~x & 0x80808080) | |
40 | ; return 0; | |
41 | ; | |
42 | strlen_byte: | |
43 | ldb r1, @r6 || addi r6, #1 | |
44 | beqz r1, strlen_exit | |
45 | addi r2, #1 || bra.s strlen_byte | |
46 | ; | |
47 | strlen_last_bytes: | |
48 | ldi r0, #4 || addi r6, #-8 | |
49 | ; | |
50 | strlen_byte_loop: | |
51 | ldb r1, @r6 || addi r6, #1 | |
52 | addi r0, #-1 || cmpz r1 | |
53 | bc.s strlen_exit || cmpz r0 | |
54 | addi r2, #1 || bnc.s strlen_byte_loop | |
55 | ; | |
56 | strlen_exit: | |
57 | mv r0, r2 || jmp r14 | |
58 | ||
59 | #else /* not CONFIG_ISA_DUAL_ISSUE */ | |
60 | ||
61 | .text | |
62 | ENTRY(strlen) | |
63 | mv r6, r0 | |
64 | ldi r2, #0 | |
65 | and3 r0, r0, #3 | |
66 | bnez r0, strlen_byte | |
67 | ; | |
68 | strlen_word: | |
69 | ld r0, @r6+ | |
70 | ; | |
71 | seth r5, #high(0x01010101) | |
72 | or3 r5, r5, #low(0x01010101) | |
73 | sll3 r7, r5, #7 | |
74 | strlen_word_loop: | |
75 | ld r1, @r6+ | |
76 | not r4, r0 ; NOTE: If a null char. exists, return 0. | |
77 | sub r0, r5 ; if ((x - 0x01010101) & ~x & 0x80808080) | |
78 | and r4, r7 ; return 0; | |
79 | and r4, r0 | |
80 | bnez r4, strlen_last_bytes | |
81 | addi r2, #4 | |
82 | ; | |
83 | ld r0, @r6+ | |
84 | not r4, r1 ; NOTE: If a null char. exists, return 0. | |
85 | sub r1, r5 ; if ((x - 0x01010101) & ~x & 0x80808080) | |
86 | and r4, r7 ; return 0; | |
87 | and r4, r1 | |
88 | bnez r4, strlen_last_bytes | |
89 | addi r2, #4 | |
90 | bra strlen_word_loop | |
91 | ; | |
92 | strlen_byte: | |
93 | ldb r1, @r6 | |
94 | addi r6, #1 | |
95 | beqz r1, strlen_exit | |
96 | addi r2, #1 | |
97 | bra strlen_byte | |
98 | ; | |
99 | strlen_last_bytes: | |
100 | ldi r0, #4 | |
101 | addi r6, #-8 | |
102 | ; | |
103 | strlen_byte_loop: | |
104 | ldb r1, @r6 | |
105 | addi r6, #1 | |
106 | addi r0, #-1 | |
107 | beqz r1, strlen_exit | |
108 | addi r2, #1 | |
109 | bnez r0, strlen_byte_loop | |
110 | ; | |
111 | strlen_exit: | |
112 | mv r0, r2 | |
113 | jmp r14 | |
114 | ||
115 | #endif /* not CONFIG_ISA_DUAL_ISSUE */ | |
116 | ||
117 | .end |