diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2021-03-04 16:20:49 -0500 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2021-03-24 19:24:31 -0400 |
commit | 37dba2762bd5fe36d2df0815fd8ad931d4af5649 (patch) | |
tree | a229ba818240a0a7797361a3eb543a1fa51529df | |
parent | 0ad657ef52bd28504effae5bff58cde887ed0e66 (diff) |
bcachefs: asm bch2_bpos_sub()
Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
-rw-r--r-- | fs/bcachefs/bkey.c | 37 | ||||
-rw-r--r-- | fs/bcachefs/bkey.h | 28 |
2 files changed, 41 insertions, 24 deletions
diff --git a/fs/bcachefs/bkey.c b/fs/bcachefs/bkey.c index 3af56062601f..9f293ac95d3f 100644 --- a/fs/bcachefs/bkey.c +++ b/fs/bcachefs/bkey.c @@ -1095,6 +1095,43 @@ int __bch2_bkey_cmp_left_packed(const struct btree *b, : __bch2_bkey_cmp_left_packed_format_checked(b, l, r); } +#define sbb(a, b, borrow) \ +do { \ + typeof(a) d1, d2; \ + \ + d1 = a - borrow; \ + borrow = d1 > a; \ + \ + d2 = d1 - b; \ + borrow += d2 > d1; \ + a = d2; \ +} while (0) + +/* a -= b: */ +void bch2_bpos_sub(struct bpos *a, const struct bpos *b) +{ +#ifdef CONFIG_X86_64 + asm(".intel_syntax noprefix;" + "test al, al;" /* clear flags */ + "mov eax, [rsi];" + "sbb [rdi], eax;" + "mov rax, [rsi + 4];" + "sbb [rdi + 4], rax;" + "mov rax, [rsi + 12];" + "sbb [rdi + 12], rax;" + ".att_syntax prefix;" + : + : "rdi" (a), "rsi" (b) + : "rax", "cc", "memory"); +#else + int borrow = 0; + + sbb(a->snapshot, b->snapshot, borrow); + sbb(a->offset, b->offset, borrow); + sbb(a->inode, b->inode, borrow); +#endif +} + void bch2_bpos_swab(struct bpos *p) { u8 *l = (u8 *) p; diff --git a/fs/bcachefs/bkey.h b/fs/bcachefs/bkey.h index 6fd894186194..215500c08195 100644 --- a/fs/bcachefs/bkey.h +++ b/fs/bcachefs/bkey.h @@ -173,35 +173,15 @@ static inline struct bpos bpos_max(struct bpos l, struct bpos r) return bpos_cmp(l, r) > 0 ? l : r; } -#define sbb(a, b, borrow) \ -do { \ - typeof(a) d1, d2; \ - \ - d1 = a - borrow; \ - borrow = d1 > a; \ - \ - d2 = d1 - b; \ - borrow += d2 > d1; \ - a = d2; \ -} while (0) - -/* returns a - b: */ -static inline struct bpos bpos_sub(struct bpos a, struct bpos b) -{ - int borrow = 0; - - sbb(a.snapshot, b.snapshot, borrow); - sbb(a.offset, b.offset, borrow); - sbb(a.inode, b.inode, borrow); - return a; -} +void bch2_bpos_sub(struct bpos *, const struct bpos *); static inline struct bpos bpos_diff(struct bpos l, struct bpos r) { - if (bpos_cmp(l, r) > 0) + if (bpos_cmp(l, r) < 0) swap(l, r); - return bpos_sub(r, l); + bch2_bpos_sub(&l, &r); + return l; } void bch2_bpos_swab(struct bpos *); |