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