]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - string/arm/strcmp-armv6m.S
Import Arm Optimized Routines v21.02
[FreeBSD/FreeBSD.git] / string / arm / strcmp-armv6m.S
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
31 ENTRY_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
39 1:
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
53 3:
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
75 2:
76         pop     {r4, r5, r6, pc}
77
78 3:
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
88 4:
89         pop     {r4, r5, r6, pc}
90 5:
91         movs    r0, #0
92         mvns    r0, r0
93         pop     {r4, r5, r6, pc}
94 6:
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
111 7:
112         subs    r0, r2, r3
113         pop     {r4, r5, r6, pc}
114
115 END (__strcmp_armv6m)
116
117 #endif /* __ARM_ARCH == 6 && __ARM_ARCH_6M__ >= 1  */