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