Skip to content

Instantly share code, notes, and snippets.

@Validark
Created March 6, 2024 19:36
Show Gist options
  • Save Validark/4479191b28e4dd2af1099fda0c3d609e to your computer and use it in GitHub Desktop.
Save Validark/4479191b28e4dd2af1099fda0c3d609e to your computer and use it in GitHub Desktop.
Some SWAR functions for byte-level operations
fn swarGe(x: anytype, y: @TypeOf(x)) @TypeOf(x) {
const msb: @TypeOf(x) = @bitCast(@as(@Vector(@sizeOf(@TypeOf(x)), u8), @splat(0x80)));
return (((x ^ y) & x) | (~(x ^ y) & ((x | msb) -% (y & ~msb))));
}
fn swarLe(x: anytype, y: @TypeOf(x)) @TypeOf(x) {
return swarGe(y, x);
}
fn swarEq(x: anytype, y: @TypeOf(x)) @TypeOf(x) {
const msb: @TypeOf(x) = @bitCast(@as(@Vector(@sizeOf(@TypeOf(x)), u8), @splat(0x80)));
const z = (x ^ y);
return ~(((z & ~msb) +% ~msb) | z);
}
fn swarGt(x: anytype, y: @TypeOf(x)) @TypeOf(x) {
return swarGe(x, y) & ~swarEq(x, y);
}
fn swarLt(x: anytype, y: @TypeOf(x)) @TypeOf(x) {
return swarLe(x, y) & ~swarEq(x, y);
}
fn swarAdd(x: anytype, y: @TypeOf(x)) @TypeOf(x) {
const msb: @TypeOf(x) = @bitCast(@as(@Vector(@sizeOf(@TypeOf(x)), u8), @splat(0x80)));
return ((x & ~msb) +% (y & ~msb)) ^ ((x ^ y) & msb);
}
fn swarSub(x: anytype, y: @TypeOf(x)) @TypeOf(x) {
const msb: @TypeOf(x) = @bitCast(@as(@Vector(@sizeOf(@TypeOf(x)), u8), @splat(0x80)));
return ((x | msb) -% (y & ~msb)) ^ ((x ^ ~y) & msb);
}
fn swarMinMax(x: anytype, y: @TypeOf(x), comptime min_or_max: enum { min, max }) @TypeOf(x) {
const msb: @TypeOf(x) = @bitCast(@as(@Vector(@sizeOf(@TypeOf(x)), u8), @splat(0x80)));
const b = swarGe(x, y) & msb;
return (((b << 1) -% (b >> 7)) & (x ^ y)) ^ switch (min_or_max) {
.min => x,
.max => y,
};
}
fn swarMin(x: anytype, y: @TypeOf(x)) @TypeOf(x) {
return swarMinMax(x, y, .min);
}
fn swarMax(x: anytype, y: @TypeOf(x)) @TypeOf(x) {
return swarMinMax(x, y, .max);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment