xref: /freebsd/contrib/arm-optimized-routines/string/arm/strcmp-armv6m.S (revision 02e9120893770924227138ba49df1edb3896112a)
1/*
2 * strcmp for ARMv6-M (optimized for performance, not size)
3 *
4 * Copyright (c) 2014-2022, Arm Limited.
5 * SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception
6 */
7
8#include "asmdefs.h"
9
10#if __ARM_ARCH == 6 && __ARM_ARCH_6M__ >= 1
11
12	.thumb_func
13	.syntax unified
14	.arch	armv6-m
15
16	.macro DoSub n, label
17	subs	r0, r0, r1
18#ifdef __ARM_BIG_ENDIAN
19	lsrs	r1, r4, \n
20#else
21	lsls	r1, r4, \n
22#endif
23	orrs	r1, r0
24	bne	\label
25	.endm
26
27	.macro Byte_Test n, label
28	lsrs	r0, r2, \n
29	lsrs	r1, r3, \n
30	DoSub	\n, \label
31	.endm
32
33ENTRY_ALIGN (__strcmp_armv6m, 4)
34	mov	r2, r0
35	push	{r4, r5, r6, lr}
36	orrs	r2, r1
37	lsls	r2, r2, #30
38	bne	6f
39	ldr	r5, =0x01010101
40	lsls	r6, r5, #7
411:
42	ldmia	r0!, {r2}
43	ldmia	r1!, {r3}
44	subs	r4, r2, r5
45	bics	r4, r2
46	ands	r4, r6
47	beq	3f
48
49#ifdef __ARM_BIG_ENDIAN
50	Byte_Test #24, 4f
51	Byte_Test #16, 4f
52	Byte_Test #8, 4f
53
54	b       7f
553:
56	cmp     r2, r3
57	beq     1b
58	cmp     r2, r3
59#else
60	uxtb    r0, r2
61	uxtb    r1, r3
62	DoSub   #24, 2f
63
64	uxth    r0, r2
65	uxth    r1, r3
66	DoSub   #16, 2f
67
68	lsls    r0, r2, #8
69	lsls    r1, r3, #8
70	lsrs    r0, r0, #8
71	lsrs    r1, r1, #8
72	DoSub   #8, 2f
73
74	lsrs    r0, r2, #24
75	lsrs    r1, r3, #24
76	subs    r0, r0, r1
772:
78	pop     {r4, r5, r6, pc}
79
803:
81	cmp     r2, r3
82	beq     1b
83	rev     r0, r2
84	rev     r1, r3
85	cmp     r0, r1
86#endif
87
88	bls	5f
89	movs	r0, #1
904:
91	pop	{r4, r5, r6, pc}
925:
93	movs	r0, #0
94	mvns	r0, r0
95	pop	{r4, r5, r6, pc}
966:
97	ldrb	r2, [r0, #0]
98	ldrb	r3, [r1, #0]
99	adds	r0, #1
100	adds	r1, #1
101	cmp	r2, #0
102	beq	7f
103	cmp	r2, r3
104	bne	7f
105	ldrb	r2, [r0, #0]
106	ldrb	r3, [r1, #0]
107	adds	r0, #1
108	adds	r1, #1
109	cmp	r2, #0
110	beq	7f
111	cmp	r2, r3
112	beq	6b
1137:
114	subs	r0, r2, r3
115	pop	{r4, r5, r6, pc}
116
117END (__strcmp_armv6m)
118
119#endif /* __ARM_ARCH == 6 && __ARM_ARCH_6M__ >= 1  */
120