From 1c66a3c9c2f51f33ff3bb0af01b609a70a46d1ca Mon Sep 17 00:00:00 2001 From: Jiajie Chen Date: Wed, 13 Dec 2023 17:26:16 +0800 Subject: [PATCH] Add vffint --- README.md | 10 +-------- code/gen_impl.py | 14 +++++++++++++ code/vffint_d_l.h | 3 +++ code/vffint_d_lu.h | 3 +++ code/vffint_s_l.h | 5 +++++ code/vffint_s_w.h | 3 +++ code/vffint_s_wu.h | 3 +++ code/vffinth_d_w.h | 3 +++ code/vffintl_d_w.h | 3 +++ docs/lsx/float_conversion.md | 10 +++++++++ main.py | 40 ++++++++++++++++++++++++++++++++++++ 11 files changed, 88 insertions(+), 9 deletions(-) create mode 100644 code/vffint_d_l.h create mode 100644 code/vffint_d_lu.h create mode 100644 code/vffint_s_l.h create mode 100644 code/vffint_s_w.h create mode 100644 code/vffint_s_wu.h create mode 100644 code/vffinth_d_w.h create mode 100644 code/vffintl_d_w.h diff --git a/README.md b/README.md index f62d0b95..5aa0aa53 100644 --- a/README.md +++ b/README.md @@ -8,12 +8,4 @@ TODO List: ### vfrstp.b/h -### vffint.s.l - -### vfrstpi.b/h - -### vffint.s.w/s.wu/d.l/d.lu - -### vffintl.d.w - -### vffinth.d.w \ No newline at end of file +### vfrstpi.b/h \ No newline at end of file diff --git a/code/gen_impl.py b/code/gen_impl.py index c7af46e9..33d1104f 100644 --- a/code/gen_impl.py +++ b/code/gen_impl.py @@ -828,6 +828,20 @@ file=f, ) print(f"}}", file=f) + with open(f"vffint_{width}_{int_width}.h", "w") as f: + print(f"for (int i = 0;i < {128 // w};i++) {{", file=f) + print( + f" dst.{m}[i] = (f{int_w})(s{int_w})a.{int_m}[i]; // rounding mode is not expressed in C", + file=f, + ) + print(f"}}", file=f) + with open(f"vffint_{width}_{int_width}u.h", "w") as f: + print(f"for (int i = 0;i < {128 // w};i++) {{", file=f) + print( + f" dst.{m}[i] = (f{int_w})(u{int_w})a.{int_m}[i]; // rounding mode is not expressed in C", + file=f, + ) + print(f"}}", file=f) for name in ["max", "min"]: with open(f"vf{name}_{width}.h", "w") as f: diff --git a/code/vffint_d_l.h b/code/vffint_d_l.h new file mode 100644 index 00000000..fa1abd2b --- /dev/null +++ b/code/vffint_d_l.h @@ -0,0 +1,3 @@ +for (int i = 0; i < 2; i++) { + dst.fp64[i] = (f64)(s64)a.dword[i]; // rounding mode is not expressed in C +} diff --git a/code/vffint_d_lu.h b/code/vffint_d_lu.h new file mode 100644 index 00000000..ff3302c4 --- /dev/null +++ b/code/vffint_d_lu.h @@ -0,0 +1,3 @@ +for (int i = 0; i < 2; i++) { + dst.fp64[i] = (f64)(u64)a.dword[i]; // rounding mode is not expressed in C +} diff --git a/code/vffint_s_l.h b/code/vffint_s_l.h new file mode 100644 index 00000000..cc2378e9 --- /dev/null +++ b/code/vffint_s_l.h @@ -0,0 +1,5 @@ +for (int i = 0; i < 4; i++) { + dst.fp32[i] = + (i < 2) ? (f32)(s32)a.dword[i] + : (f32)(s32)b.dword[i]; // rounding mode is not expressed in C +} diff --git a/code/vffint_s_w.h b/code/vffint_s_w.h new file mode 100644 index 00000000..f8eed628 --- /dev/null +++ b/code/vffint_s_w.h @@ -0,0 +1,3 @@ +for (int i = 0; i < 4; i++) { + dst.fp32[i] = (f32)(s32)a.word[i]; // rounding mode is not expressed in C +} diff --git a/code/vffint_s_wu.h b/code/vffint_s_wu.h new file mode 100644 index 00000000..84c84140 --- /dev/null +++ b/code/vffint_s_wu.h @@ -0,0 +1,3 @@ +for (int i = 0; i < 4; i++) { + dst.fp32[i] = (f32)(u32)a.word[i]; // rounding mode is not expressed in C +} diff --git a/code/vffinth_d_w.h b/code/vffinth_d_w.h new file mode 100644 index 00000000..d876c0e6 --- /dev/null +++ b/code/vffinth_d_w.h @@ -0,0 +1,3 @@ +for (int i = 0; i < 2; i++) { + dst.fp64[i] = (f64)(s32)a.word[i + 2]; // rounding mode is not expressed in C +} diff --git a/code/vffintl_d_w.h b/code/vffintl_d_w.h new file mode 100644 index 00000000..23ab9509 --- /dev/null +++ b/code/vffintl_d_w.h @@ -0,0 +1,3 @@ +for (int i = 0; i < 2; i++) { + dst.fp64[i] = (f64)(s32)a.word[i]; // rounding mode is not expressed in C +} diff --git a/docs/lsx/float_conversion.md b/docs/lsx/float_conversion.md index 3a0ecf1a..f7603694 100644 --- a/docs/lsx/float_conversion.md +++ b/docs/lsx/float_conversion.md @@ -128,6 +128,16 @@ Convert single precision floating point elements in `a` and `b` to half precisio {% include('vfcvt_h_s.h') %} ``` +{{ vffint_d_w('h') }} +{{ vffint_d_w('l') }} + +{{ vffint('d', 'l') }} +{{ vffint('d', 'lu') }} +{{ vffint('s', 'w') }} +{{ vffint('s', 'wu') }} + +{{ vffint_s_l() }} + {{ vftint_l_s('', 'l') }} {{ vftint_l_s('', 'h') }} {{ vftint_l_s('rm', 'l') }} diff --git a/main.py b/main.py index df794383..c4cd9194 100644 --- a/main.py +++ b/main.py @@ -1342,4 +1342,44 @@ def vfrint(rounding, name): intrinsic=f"{arg_type} __lsx_vfrint{rounding}_{name} ({arg_type} a)", instr=f"vfrint{rounding}.{name} vr, vr", desc=f"Round single-precision floating point elements in `a` to integers, {rounding_mode}, and store as floating point numbers.", + ) + + @env.macro + def vffint_d_w(low_high): + if low_high == "l": + half = "lower" + else: + half = "higher" + return instruction( + intrinsic=f"__m128d __lsx_vffint{low_high}_d_w (__m128i a)", + instr=f"vffint{low_high}.d.w vr, vr", + desc=f"Convert 32-bit integer elements in {half} part of `a` to double precision floating point numbers.", + ) + + @env.macro + def vffint(name, name2): + if name == "d": + arg_type = "__m128d" + precision = "double" + int_width = 64 + else: + arg_type = "__m128" + precision = "single" + int_width = 32 + if len(name2) == 1: + signedness = "signed" + else: + signedness = "unsigned" + return instruction( + intrinsic=f"{arg_type} __lsx_vffint_{name}_{name2} (__m128i a)", + instr=f"vffint.{name}.{name2} vr, vr", + desc=f"Convert {signedness} {int_width}-bit integer elements in `a` to {precision}-precision floating point numbers.", + ) + + @env.macro + def vffint_s_l(): + return instruction( + intrinsic=f"__m128 __lsx_vffint_s_l (__m128i a, __m128i b)", + instr=f"vffint.s.l vr, vr, vr", + desc=f"Convert 64-bit integer elements in `a` and `b` to double-precision floating point numbers.", ) \ No newline at end of file