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