add fgrevi and friends
authorJacob Lifshay <programmerjake@gmail.com>
Wed, 8 Mar 2023 03:56:56 +0000 (19:56 -0800)
committerJacob Lifshay <programmerjake@gmail.com>
Wed, 8 Mar 2023 03:56:56 +0000 (19:56 -0800)
openpower/sv/int_fp_mv_replace_fmv_with_fgrev.mdwn

index 0851eb0ac7865ec66fdc28764c2626b7b87f6086..4b3a6900deafad6493b7b4a3cf1e4da91b05a994 100644 (file)
@@ -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`,