summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2021-03-04 16:20:49 -0500
committerKent Overstreet <kent.overstreet@gmail.com>2021-03-24 19:24:31 -0400
commit37dba2762bd5fe36d2df0815fd8ad931d4af5649 (patch)
treea229ba818240a0a7797361a3eb543a1fa51529df
parent0ad657ef52bd28504effae5bff58cde887ed0e66 (diff)
bcachefs: asm bch2_bpos_sub()
Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
-rw-r--r--fs/bcachefs/bkey.c37
-rw-r--r--fs/bcachefs/bkey.h28
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 *);