diff --git a/README.md b/README.md index bbd07c23..799de94a 100644 --- a/README.md +++ b/README.md @@ -162,10 +162,6 @@ Vector Multiplication High ### vssrarn.bu.h/hu.w/wu.d -### vbitset.b/h/w/d - -### vbitrev.b/h/w/d - ### vpackev.b/h/w/d ### vpackod.b/h/w/d @@ -364,10 +360,6 @@ Vector Multiplication High ### vextl.qu.du -### vbitseti.b/h/w/d - -### vbitrevi.b/h/w/d - ### vsat.b/h/w/d/bu/hu/wu/du ### vslli.b/h/w/d diff --git a/code/gen_impl.py b/code/gen_impl.py index b36afde4..cb268bb5 100644 --- a/code/gen_impl.py +++ b/code/gen_impl.py @@ -126,5 +126,19 @@ file=f, ) print(f"}}", file=f) + with open(f"vbitrev_{width}.h", "w") as f: + print(f"for (int i = 0;i < {128 // w};i++) {{", file=f) + print( + f" dst.{m}[i] = a.{m}[i] ^ ((u{w})1 << (b.{m}[i] % {w}));", + file=f, + ) + print(f"}}", file=f) + with open(f"vbitrevi_{width}.h", "w") as f: + print(f"for (int i = 0;i < {128 // w};i++) {{", file=f) + print( + f" dst.{m}[i] = a.{m}[i] ^ ((u{w})1 << imm);", + file=f, + ) + print(f"}}", file=f) os.system("clang-format -i *.cpp *.h") diff --git a/code/gen_tb.py b/code/gen_tb.py index 4da31815..38079fd2 100644 --- a/code/gen_tb.py +++ b/code/gen_tb.py @@ -27,6 +27,8 @@ "vbitclri": (widths_signed, "v128 a, int imm", [0, 3, 7]), "vbitset": (widths_signed, "v128 a, v128 b"), "vbitseti": (widths_signed, "v128 a, int imm", [0, 3, 7]), + "vbitrev": (widths_signed, "v128 a, v128 b"), + "vbitrevi": (widths_signed, "v128 a, int imm", [0, 3, 7]), } for name in tb: diff --git a/code/vbitrev_b.cpp b/code/vbitrev_b.cpp new file mode 100644 index 00000000..2ce52e91 --- /dev/null +++ b/code/vbitrev_b.cpp @@ -0,0 +1,9 @@ +#include "common.h" + +v128 vbitrev_b(v128 a, v128 b) { + v128 dst; +#include "vbitrev_b.h" + return dst; +} + +void test() { FUZZ2(vbitrev_b); } diff --git a/code/vbitrev_b.h b/code/vbitrev_b.h new file mode 100644 index 00000000..fe28cc51 --- /dev/null +++ b/code/vbitrev_b.h @@ -0,0 +1,3 @@ +for (int i = 0; i < 16; i++) { + dst.byte[i] = a.byte[i] ^ ((u8)1 << (b.byte[i] % 8)); +} diff --git a/code/vbitrev_d.cpp b/code/vbitrev_d.cpp new file mode 100644 index 00000000..c1fb8003 --- /dev/null +++ b/code/vbitrev_d.cpp @@ -0,0 +1,9 @@ +#include "common.h" + +v128 vbitrev_d(v128 a, v128 b) { + v128 dst; +#include "vbitrev_d.h" + return dst; +} + +void test() { FUZZ2(vbitrev_d); } diff --git a/code/vbitrev_d.h b/code/vbitrev_d.h new file mode 100644 index 00000000..f24ef848 --- /dev/null +++ b/code/vbitrev_d.h @@ -0,0 +1,3 @@ +for (int i = 0; i < 2; i++) { + dst.dword[i] = a.dword[i] ^ ((u64)1 << (b.dword[i] % 64)); +} diff --git a/code/vbitrev_h.cpp b/code/vbitrev_h.cpp new file mode 100644 index 00000000..29bce34d --- /dev/null +++ b/code/vbitrev_h.cpp @@ -0,0 +1,9 @@ +#include "common.h" + +v128 vbitrev_h(v128 a, v128 b) { + v128 dst; +#include "vbitrev_h.h" + return dst; +} + +void test() { FUZZ2(vbitrev_h); } diff --git a/code/vbitrev_h.h b/code/vbitrev_h.h new file mode 100644 index 00000000..cc4422fe --- /dev/null +++ b/code/vbitrev_h.h @@ -0,0 +1,3 @@ +for (int i = 0; i < 8; i++) { + dst.half[i] = a.half[i] ^ ((u16)1 << (b.half[i] % 16)); +} diff --git a/code/vbitrev_w.cpp b/code/vbitrev_w.cpp new file mode 100644 index 00000000..8fbfd91d --- /dev/null +++ b/code/vbitrev_w.cpp @@ -0,0 +1,9 @@ +#include "common.h" + +v128 vbitrev_w(v128 a, v128 b) { + v128 dst; +#include "vbitrev_w.h" + return dst; +} + +void test() { FUZZ2(vbitrev_w); } diff --git a/code/vbitrev_w.h b/code/vbitrev_w.h new file mode 100644 index 00000000..0cc29773 --- /dev/null +++ b/code/vbitrev_w.h @@ -0,0 +1,3 @@ +for (int i = 0; i < 4; i++) { + dst.word[i] = a.word[i] ^ ((u32)1 << (b.word[i] % 32)); +} diff --git a/code/vbitrevi_b.cpp b/code/vbitrevi_b.cpp new file mode 100644 index 00000000..dd424599 --- /dev/null +++ b/code/vbitrevi_b.cpp @@ -0,0 +1,13 @@ +#include "common.h" + +v128 vbitrevi_b(v128 a, int imm) { + v128 dst; +#include "vbitrevi_b.h" + return dst; +} + +void test() { + FUZZ1(vbitrevi_b, 0); + FUZZ1(vbitrevi_b, 3); + FUZZ1(vbitrevi_b, 7); +} diff --git a/code/vbitrevi_b.h b/code/vbitrevi_b.h new file mode 100644 index 00000000..03cd2f90 --- /dev/null +++ b/code/vbitrevi_b.h @@ -0,0 +1,3 @@ +for (int i = 0; i < 16; i++) { + dst.byte[i] = a.byte[i] ^ ((u8)1 << imm); +} diff --git a/code/vbitrevi_d.cpp b/code/vbitrevi_d.cpp new file mode 100644 index 00000000..92662562 --- /dev/null +++ b/code/vbitrevi_d.cpp @@ -0,0 +1,13 @@ +#include "common.h" + +v128 vbitrevi_d(v128 a, int imm) { + v128 dst; +#include "vbitrevi_d.h" + return dst; +} + +void test() { + FUZZ1(vbitrevi_d, 0); + FUZZ1(vbitrevi_d, 3); + FUZZ1(vbitrevi_d, 7); +} diff --git a/code/vbitrevi_d.h b/code/vbitrevi_d.h new file mode 100644 index 00000000..93f5622d --- /dev/null +++ b/code/vbitrevi_d.h @@ -0,0 +1,3 @@ +for (int i = 0; i < 2; i++) { + dst.dword[i] = a.dword[i] ^ ((u64)1 << imm); +} diff --git a/code/vbitrevi_h.cpp b/code/vbitrevi_h.cpp new file mode 100644 index 00000000..ed5e38a5 --- /dev/null +++ b/code/vbitrevi_h.cpp @@ -0,0 +1,13 @@ +#include "common.h" + +v128 vbitrevi_h(v128 a, int imm) { + v128 dst; +#include "vbitrevi_h.h" + return dst; +} + +void test() { + FUZZ1(vbitrevi_h, 0); + FUZZ1(vbitrevi_h, 3); + FUZZ1(vbitrevi_h, 7); +} diff --git a/code/vbitrevi_h.h b/code/vbitrevi_h.h new file mode 100644 index 00000000..326b618f --- /dev/null +++ b/code/vbitrevi_h.h @@ -0,0 +1,3 @@ +for (int i = 0; i < 8; i++) { + dst.half[i] = a.half[i] ^ ((u16)1 << imm); +} diff --git a/code/vbitrevi_w.cpp b/code/vbitrevi_w.cpp new file mode 100644 index 00000000..fe316d0e --- /dev/null +++ b/code/vbitrevi_w.cpp @@ -0,0 +1,13 @@ +#include "common.h" + +v128 vbitrevi_w(v128 a, int imm) { + v128 dst; +#include "vbitrevi_w.h" + return dst; +} + +void test() { + FUZZ1(vbitrevi_w, 0); + FUZZ1(vbitrevi_w, 3); + FUZZ1(vbitrevi_w, 7); +} diff --git a/code/vbitrevi_w.h b/code/vbitrevi_w.h new file mode 100644 index 00000000..63bf8873 --- /dev/null +++ b/code/vbitrevi_w.h @@ -0,0 +1,3 @@ +for (int i = 0; i < 4; i++) { + dst.word[i] = a.word[i] ^ ((u32)1 << imm); +} diff --git a/docs/lsx_bitops/vbitwise.md b/docs/lsx_bitops/vbitwise.md index caa38062..ad1a5dc1 100644 --- a/docs/lsx_bitops/vbitwise.md +++ b/docs/lsx_bitops/vbitwise.md @@ -39,4 +39,14 @@ Compute bitwise selection: for each bit position, if the bit in `c` equals to on {{ vbitseti('b') }} {{ vbitseti('h') }} {{ vbitseti('w') }} -{{ vbitseti('d') }} \ No newline at end of file +{{ vbitseti('d') }} + +{{ vbitrev('b') }} +{{ vbitrev('h') }} +{{ vbitrev('w') }} +{{ vbitrev('d') }} + +{{ vbitrevi('b') }} +{{ vbitrevi('h') }} +{{ vbitrevi('w') }} +{{ vbitrevi('d') }} \ No newline at end of file diff --git a/main.py b/main.py index f0cfec45..014686cd 100644 --- a/main.py +++ b/main.py @@ -194,6 +194,25 @@ def vbitseti(name): desc=f"Set the bit specified by `imm` from {width}-bit elements in `a`, save the result in `dst`.", ) + @env.macro + def vbitrev(name): + width = widths[name] + return instruction( + intrinsic=f"__m128i __lsx_vbitrev_{name} (__m128i a, __m128i b)", + instr=f"vbitrev.{name} vr, vr, vr", + desc=f"Toggle the bit specified by elements in `b` from {width}-bit elements in `a`, save the result in `dst`.", + ) + + @env.macro + def vbitrevi(name): + width = widths[name] + imm_upper = width - 1 + return instruction( + intrinsic=f"__m128i __lsx_vbitrevi_{name} (__m128i a, imm0_{imm_upper} imm)", + instr=f"vbitrevi.{name} vr, vr, imm", + desc=f"Toggle the bit specified by `imm` from {width}-bit elements in `a`, save the result in `dst`.", + ) + @env.macro def vshuf_hwd(name): width = widths[name]