]> git.sesse.net Git - bcachefs-tools-debian/blob - libbcachefs/bkey_cmp.h
Move c_src dirs back to toplevel
[bcachefs-tools-debian] / libbcachefs / bkey_cmp.h
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef _BCACHEFS_BKEY_CMP_H
3 #define _BCACHEFS_BKEY_CMP_H
4
5 #include "bkey.h"
6
7 #ifdef CONFIG_X86_64
8 static inline int __bkey_cmp_bits(const u64 *l, const u64 *r,
9                                   unsigned nr_key_bits)
10 {
11         long d0, d1, d2, d3;
12         int cmp;
13
14         /* we shouldn't need asm for this, but gcc is being retarded: */
15
16         asm(".intel_syntax noprefix;"
17             "xor eax, eax;"
18             "xor edx, edx;"
19             "1:;"
20             "mov r8, [rdi];"
21             "mov r9, [rsi];"
22             "sub ecx, 64;"
23             "jl 2f;"
24
25             "cmp r8, r9;"
26             "jnz 3f;"
27
28             "lea rdi, [rdi - 8];"
29             "lea rsi, [rsi - 8];"
30             "jmp 1b;"
31
32             "2:;"
33             "not ecx;"
34             "shr r8, 1;"
35             "shr r9, 1;"
36             "shr r8, cl;"
37             "shr r9, cl;"
38             "cmp r8, r9;"
39
40             "3:\n"
41             "seta al;"
42             "setb dl;"
43             "sub eax, edx;"
44             ".att_syntax prefix;"
45             : "=&D" (d0), "=&S" (d1), "=&d" (d2), "=&c" (d3), "=&a" (cmp)
46             : "0" (l), "1" (r), "3" (nr_key_bits)
47             : "r8", "r9", "cc", "memory");
48
49         return cmp;
50 }
51 #else
52 static inline int __bkey_cmp_bits(const u64 *l, const u64 *r,
53                                   unsigned nr_key_bits)
54 {
55         u64 l_v, r_v;
56
57         if (!nr_key_bits)
58                 return 0;
59
60         /* for big endian, skip past header */
61         nr_key_bits += high_bit_offset;
62         l_v = *l & (~0ULL >> high_bit_offset);
63         r_v = *r & (~0ULL >> high_bit_offset);
64
65         while (1) {
66                 if (nr_key_bits < 64) {
67                         l_v >>= 64 - nr_key_bits;
68                         r_v >>= 64 - nr_key_bits;
69                         nr_key_bits = 0;
70                 } else {
71                         nr_key_bits -= 64;
72                 }
73
74                 if (!nr_key_bits || l_v != r_v)
75                         break;
76
77                 l = next_word(l);
78                 r = next_word(r);
79
80                 l_v = *l;
81                 r_v = *r;
82         }
83
84         return cmp_int(l_v, r_v);
85 }
86 #endif
87
88 static inline __pure __flatten
89 int __bch2_bkey_cmp_packed_format_checked_inlined(const struct bkey_packed *l,
90                                           const struct bkey_packed *r,
91                                           const struct btree *b)
92 {
93         const struct bkey_format *f = &b->format;
94         int ret;
95
96         EBUG_ON(!bkey_packed(l) || !bkey_packed(r));
97         EBUG_ON(b->nr_key_bits != bkey_format_key_bits(f));
98
99         ret = __bkey_cmp_bits(high_word(f, l),
100                               high_word(f, r),
101                               b->nr_key_bits);
102
103         EBUG_ON(ret != bpos_cmp(bkey_unpack_pos(b, l),
104                                 bkey_unpack_pos(b, r)));
105         return ret;
106 }
107
108 static inline __pure __flatten
109 int bch2_bkey_cmp_packed_inlined(const struct btree *b,
110                          const struct bkey_packed *l,
111                          const struct bkey_packed *r)
112 {
113         struct bkey unpacked;
114
115         if (likely(bkey_packed(l) && bkey_packed(r)))
116                 return __bch2_bkey_cmp_packed_format_checked_inlined(l, r, b);
117
118         if (bkey_packed(l)) {
119                 __bkey_unpack_key_format_checked(b, &unpacked, l);
120                 l = (void *) &unpacked;
121         } else if (bkey_packed(r)) {
122                 __bkey_unpack_key_format_checked(b, &unpacked, r);
123                 r = (void *) &unpacked;
124         }
125
126         return bpos_cmp(((struct bkey *) l)->p, ((struct bkey *) r)->p);
127 }
128
129 #endif /* _BCACHEFS_BKEY_CMP_H */