strcmp-armv6m.S
1.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/*
* strcmp for ARMv6-M (optimized for performance, not size)
*
* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
* See https://llvm.org/LICENSE.txt for license information.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#if __ARM_ARCH == 6 && __ARM_ARCH_6M__ >= 1
.thumb_func
.syntax unified
.arch armv6-m
.macro DoSub n, label
subs r0, r0, r1
#ifdef __ARM_BIG_ENDIAN
lsrs r1, r4, \n
#else
lsls r1, r4, \n
#endif
orrs r1, r0
bne \label
.endm
.macro Byte_Test n, label
lsrs r0, r2, \n
lsrs r1, r3, \n
DoSub \n, \label
.endm
ENTRY_ALIGN (__strcmp_armv6m, 4)
mov r2, r0
push {r4, r5, r6, lr}
orrs r2, r1
lsls r2, r2, #30
bne 6f
ldr r5, =0x01010101
lsls r6, r5, #7
1:
ldmia r0!, {r2}
ldmia r1!, {r3}
subs r4, r2, r5
bics r4, r2
ands r4, r6
beq 3f
#ifdef __ARM_BIG_ENDIAN
Byte_Test #24, 4f
Byte_Test #16, 4f
Byte_Test #8, 4f
b 7f
3:
cmp r2, r3
beq 1b
cmp r2, r3
#else
uxtb r0, r2
uxtb r1, r3
DoSub #24, 2f
uxth r0, r2
uxth r1, r3
DoSub #16, 2f
lsls r0, r2, #8
lsls r1, r3, #8
lsrs r0, r0, #8
lsrs r1, r1, #8
DoSub #8, 2f
lsrs r0, r2, #24
lsrs r1, r3, #24
subs r0, r0, r1
2:
pop {r4, r5, r6, pc}
3:
cmp r2, r3
beq 1b
rev r0, r2
rev r1, r3
cmp r0, r1
#endif
bls 5f
movs r0, #1
4:
pop {r4, r5, r6, pc}
5:
movs r0, #0
mvns r0, r0
pop {r4, r5, r6, pc}
6:
ldrb r2, [r0, #0]
ldrb r3, [r1, #0]
adds r0, #1
adds r1, #1
cmp r2, #0
beq 7f
cmp r2, r3
bne 7f
ldrb r2, [r0, #0]
ldrb r3, [r1, #0]
adds r0, #1
adds r1, #1
cmp r2, #0
beq 7f
cmp r2, r3
beq 6b
7:
subs r0, r2, r3
pop {r4, r5, r6, pc}
END (__strcmp_armv6m)
#endif /* __ARM_ARCH == 6 && __ARM_ARCH_6M__ >= 1 */