Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/lib/libc/aarch64/string/timingsafe_memcmp.S
48266 views
1
/*
2
* SPDX-License-Identifier: BSD-2-Clause
3
*
4
* Copyright (c) 2024 Robert Clausecker
5
*/
6
7
#include <machine/asm.h>
8
9
ENTRY(timingsafe_memcmp)
10
cmp x2, #16 // at least 17 bytes to process?
11
bhi .Lgt16
12
13
cmp x2, #8 // at least 9 bytes to process?
14
bhi .L0916
15
16
cmp x2, #4 // at least 5 bytes to process?
17
bhi .L0508
18
19
cmp x2, #2 // at least 3 bytes to process?
20
bhi .L0304
21
22
cbnz x2, .L0102 // buffer empty?
23
24
mov w0, #0 // empty buffer always matches
25
ret
26
27
.L0102: ldrb w3, [x0] // load first bytes
28
ldrb w4, [x1]
29
sub x2, x2, #1
30
ldrb w5, [x0, x2] // load last bytes
31
ldrb w6, [x1, x2]
32
bfi w5, w3, #8, #8 // join bytes in big endian
33
bfi w6, w4, #8, #8
34
sub w0, w5, w6
35
ret
36
37
38
.L0304: ldrh w3, [x0] // load first halfwords
39
ldrh w4, [x1]
40
sub x2, x2, #2
41
ldrh w5, [x0, x2] // load last halfwords
42
ldrh w6, [x1, x2]
43
bfi w3, w5, #16, #16 // join halfwords in little endian
44
bfi w4, w6, #16, #16
45
rev w3, w3 // swap word order
46
rev w4, w4
47
cmp w3, w4
48
csetm w0, lo // w0 = w3 >= w4 ? 0 : -1
49
csinc w0, w0, wzr, ls // w0 = w3 <=> w4 ? 1 : 0 : -1
50
ret
51
52
.L0508: ldr w3, [x0] // load first words
53
ldr w4, [x1]
54
sub x2, x2, #4
55
ldr w5, [x0, x2] // load last words
56
ldr w6, [x1, x2]
57
bfi x3, x5, #32, #32 // join words in little endian
58
bfi x4, x6, #32, #32
59
rev x3, x3 // swap word order
60
rev x4, x4
61
cmp x3, x4
62
csetm w0, lo // x0 = x3 >= w4 ? 0 : -1
63
csinc w0, w0, wzr, ls // x0 = x3 <=> w4 ? 1 : 0 : -1
64
ret
65
66
.L0916: ldr x3, [x0]
67
ldr x4, [x1]
68
sub x2, x2, #8
69
ldr x5, [x0, x2]
70
ldr x6, [x1, x2]
71
cmp x3, x4 // mismatch in first pair?
72
csel x3, x3, x5, ne // use second pair if first pair equal
73
csel x4, x4, x6, ne
74
rev x3, x3
75
rev x4, x4
76
cmp x3, x4
77
csetm w0, lo
78
csinc w0, w0, wzr, ls
79
ret
80
81
/* more than 16 bytes: process buffer in a loop */
82
.Lgt16: ldp x3, x4, [x0], #16
83
ldp x5, x6, [x1], #16
84
cmp x3, x5 // mismatch in first pair?
85
csel x3, x3, x4, ne // use second pair if first pair equal
86
csel x5, x5, x6, ne
87
subs x2, x2, #32
88
bls .Ltail
89
90
0: ldp x4, x7, [x0], #16
91
ldp x6, x8, [x1], #16
92
cmp x4, x6 // mismatch in first pair?
93
csel x4, x4, x7, ne // if not, try second pair
94
csel x6, x6, x8, ne
95
cmp x3, x5 // was there a mismatch previously?
96
csel x3, x3, x4, ne // apply new pair if there was not
97
csel x5, x5, x6, ne
98
subs x2, x2, #16
99
bhi 0b
100
101
.Ltail: add x0, x0, x2
102
add x1, x1, x2
103
ldp x4, x7, [x0]
104
ldp x6, x8, [x1]
105
cmp x4, x6 // mismatch in first pair?
106
csel x4, x4, x7, ne // if not, try second pair
107
csel x6, x6, x8, ne
108
cmp x3, x5 // was there a mismatch previously?
109
csel x3, x3, x4, ne // apply new pair if there was not
110
csel x5, x5, x6, ne
111
rev x3, x3
112
rev x5, x5
113
cmp x3, x5
114
csetm w0, lo
115
csinc w0, w0, wzr, ls
116
ret
117
END(timingsafe_memcmp)
118
119