aboutsummaryrefslogtreecommitdiff
path: root/string/arm/strcmp-armv6m.S
blob: 4d55306810ad3a2697ede7d45ec2ab420eba8002 (plain)
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
119
/*
 * strcmp for ARMv6-M (optimized for performance, not size)
 *
 * Copyright (c) 2014-2022, Arm Limited.
 * SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception
 */

#include "asmdefs.h"

#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  */