Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/m32r/lib/strlen.S
10817 views
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
*/
9
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
118
119