From 53f89737fbbc00ede56f2638db43090818a16e0b Mon Sep 17 00:00:00 2001 From: Jacob Lifshay Date: Tue, 7 Mar 2023 19:56:56 -0800 Subject: [PATCH] add fgrevi and friends --- .../sv/int_fp_mv_replace_fmv_with_fgrev.mdwn | 149 ++++++++++++++++-- 1 file changed, 137 insertions(+), 12 deletions(-) diff --git a/openpower/sv/int_fp_mv_replace_fmv_with_fgrev.mdwn b/openpower/sv/int_fp_mv_replace_fmv_with_fgrev.mdwn index 0851eb0ac..4b3a6900d 100644 --- a/openpower/sv/int_fp_mv_replace_fmv_with_fgrev.mdwn +++ b/openpower/sv/int_fp_mv_replace_fmv_with_fgrev.mdwn @@ -241,15 +241,111 @@ fmvis f4, 0x3F80 # writes +1.0 to f4 fishmv f4, 0x8000 # writes +1.00390625 to f4 ``` -# Moves +# Moves & Generalized Bit Reverses + +These instructions perform a generalized bit reverse on the underlying bits in +FPRs, optionally moving between FPR/GPR register files. These instructions are +designed to replace using a store/load pair to `memcpy`/transmute the bitwise +representation of floating-point values, with optional endian swaps. + +# FPR to FPR Generalized Bit Reverse +* `fgrevi FRT, FRA, SH` XS-form +* `fgrevi. FRT, FRA, SH` XS-form +* `fgrevisd FRT, FRA, SH` XS-form +* `fgrevisd. FRT, FRA, SH` XS-form +* `fgrevids FRT, FRA, SH` XS-form +* `fgrevids. FRT, FRA, SH` XS-form +* `fgrevis FRT, FRA, SH` XS-form +* `fgrevis. FRT, FRA, SH` XS-form + +Jacob: maybe leave out sd/ds forms? + +read a 32/64-bit float from `FRA`, do a generalized bit reverse on the +zero-extended bitwise representation, then write the result as a 32/64-bit +float to `FRT`. +This can be used to do any combination of endian swaps, which are useful +for emulating a big-endian `memcpy`/transmute e.g. from `f32x2` to `f64` or +from the MSB half of `f64` to `f32` or similar. + +Pseudo-code: -These instructions perform a straight unaltered bit-level copy from one Register -File to another. +``` +v <- (FRA) +if insn in ["fgrevisd", "fgrevisd.", "fgrevis", "fgrevis."] then + v <- [0] * 32 || SINGLE(v) +v <- GREV64(v, SH) +if insn in ["fgrevids", "fgrevids.", "fgrevis", "fgrevis."] then + FRT <- DOUBLE(v[32:63]) +else + FRT <- v +``` + +All instructions, including `*s` forms, are explicitly XS-form and have 6-bit +SH immediates, this allows having `f32` values in the MSB 32-bits of the +input/result. + +Rc=1 tests FRT and sets CR1, following usual fp Rc=1 semantics. + +# GPR to FPR moves & Generalized Bit Reverses + +* `fgrevfgi FRT, RA, SH` XS-form +* `fgrevfgi. FRT, RA, SH` XS-form +* `fgrevfgis FRT, RA, SH` XS-form +* `fgrevfgis. FRT, RA, SH` XS-form + +read from a GPR and do a generalized bit reverse (grev) on +the bits, writing the resulting bits as a 32/64-bit float to a FPR. +This can be used to do a bitwise copy from a GPR to a FPR. +This can also be used to do any combination of endian swaps, which are useful +for emulating a big-endian `memcpy`/transmute e.g. from `u32x2` to `f64` or +from `i8x4` to `f32` or similar. + +Pseudo-code: -# FPR to GPR moves +``` +v <- GREV64((RA), SH) +if insn = "fgrevfgis" or insn = "fgrevfgis." then + FRT <- DOUBLE(v[32:63]) +else + FRT <- v +``` + +Rc=1 tests FRT and sets CR1, following usual fp Rc=1 semantics. + +Note `fgrevfgis` is explicitly XS-form and has a 6-bit SH immediate, this +allows taking the `f32` value from the MSB 32-bits of the input GPR. -* `fmvtg RT, FRA` -* `fmvtg. RT, FRA` +# FPR to GPR Moves & Generalized Bit Reverses + +* `fgrevtgi RT, FRA, SH` XS-form +* `fgrevtgi. RT, FRA, SH` XS-form +* `fgrevtgis RT, FRA, SH` XS-form +* `fgrevtgis. RT, FRA, SH` XS-form + +read a 32/64-bit float from a FPR and do a generalized bit reverse (grev) on +the zero-extended bitwise bits, writing the result to a GPR. This can be used +to do a bitwise copy from a FPR to a GPR. This can also be used to do any +combination of endian swaps, which are useful for emulating a big-endian +`memcpy`/transmute, e.g. from `f64` to `u32x2` or from `f32` to `i8x4` or +similar. + +Pseudo-code: + +``` +v <- (FRA) +if insn = "fgrevtgis" or insn = "fgrevtgis." then + v <- [0] * 32 || SINGLE(v) +RT <- GREV64(v, SH) +``` + +Rc=1 tests RT and sets CR0, exactly like all other Scalar Fixed-Point +operations. + +Note `fgrevtgis` is explicitly XS-form and has a 6-bit SH immediate, this +allows putting the `f32` value into the MSB 32-bits of the result. + +* `fmvtg RT, FRA` (alias of `fgrevtgi RT, FRA, 0`) +* `fmvtg. RT, FRA` (alias of `fgrevtgi. RT, FRA, 0`) move a 64-bit float from a FPR to a GPR, just copying bits directly. As a direct bitcopy, no exceptions occur and no status flags are set. @@ -257,8 +353,8 @@ As a direct bitcopy, no exceptions occur and no status flags are set. Rc=1 tests RT and sets CR0, exactly like all other Scalar Fixed-Point operations. -* `fmvtgs RT, FRA` -* `fmvtgs. RT, FRA` +* `fmvtgs RT, FRA` (alias of `fgrevtgis RT, FRA, 0`) +* `fmvtgs. RT, FRA` (alias of `fgrevtgis. RT, FRA, 0`) move a 32-bit float from a FPR to a GPR, just copying bits. Converts the 64-bit float in `FRA` to a 32-bit float, using the same method as `stfs`, @@ -269,16 +365,45 @@ does not behave like `frsp` and does not set any fp exception flags. Since RT is a GPR, Rc=1 follows standard *integer* behaviour, i.e. tests RT and sets CR0. -# GPR to FPR moves +# GPR to FPR moves & Generalized Bit Reverses + +* `fgrevfgi FRT, RA, SH` XS-form +* `fgrevfgi. FRT, RA, SH` XS-form +* `fgrevfgis FRT, RA, SH` XS-form +* `fgrevfgis. FRT, RA, SH` XS-form + +read from a GPR and do a generalized bit reverse (grev) on +the bits, writing the resulting bits as a 32/64-bit float to a FPR. +This can be used to do a bitwise copy from a GPR to a FPR. +This can also be used to do any combination of endian swaps, which are useful +for emulating a big-endian `memcpy`/transmute e.g. from `u32x2` to `f64` or +from `i8x4` to `f32` or similar. -`fmvfg FRT, RA` +Pseudo-code: + +``` +v <- GREV64((RA), SH) +if insn = "fgrevfgis" or insn = "fgrevfgis." then + FRT <- DOUBLE(v[32:63]) +else + FRT <- v +``` + +Rc=1 tests FRT and sets CR1, following usual fp Rc=1 semantics. + +Note `fgrevfgis` is explicitly XS-form and has a 6-bit SH immediate, this +allows taking the `f32` value from the MSB 32-bits of the input GPR. + +* `fmvfg FRT, RA` (alias of `fgrevfgi FRT, RA, 0`) +* `fmvfg. FRT, RA` (alias of `fgrevfgi. FRT, RA, 0`) move a 64-bit float from a GPR to a FPR, just copying bits. No exceptions are raised, no flags are altered of any kind. -Rc=1 tests FRT and sets CR1 +Rc=1 tests FRT and sets CR1, following usual fp Rc=1 semantics. -`fmvfgs FRT, RA` +* `fmvfgs FRT, RA` (alias of `fgrevfgis FRT, RA, 0`) +* `fmvfgs. FRT, RA` (alias of `fgrevfgis. FRT, RA, 0`) move a 32-bit float from a GPR to a FPR, just copying bits. Converts the 32-bit float in `RA` to a 64-bit float, using the same method as `lfs`, -- 2.30.2