(no commit message)
[libreriscv.git] / openpower / sv / svp64_quirks.mdwn
index b8a862bab6bd65a9a40e2b40c3be55f8276c9f8b..75f3d98bdcf9290456d779c00aea526b3c2d766e 100644 (file)
@@ -101,8 +101,8 @@ makes no sense at all, such as `sc` or `mtmsr`). The categories are:
 **Arithmetic**
 
 Arithmetic (known as "normal" mode) is where Scalar and Parallel
-Reduction can be done: Saturation as well, and two new innovative
-modes for Vector ISAs: data-dependent fail-first and predicate result.
+Reduction can be done: Saturation as well, and a new innovative
+modes for Vector ISAs: data-dependent fail-first.
 Reduction and Saturation are common to see in Vector ISAs: it is just
 that they are usually added as explicit instructions,
 and NEC SX Aurora has even more iterative instructions. In SVP64 these
@@ -142,8 +142,7 @@ overrides make absolutely no sense whatsoever. Therefore the elwidth
 override field bits can be used for other purposes when Vectorising
 CR Field instructions.  Moreover, Rc=1 is completely invalid for
 CR operations such as `crand`: Rc=1 is for arithmetic operations, producing
-a "co-result" that goes into CR0 or CR1. Thus, the Arithmetic modes
-such as predicate-result make no sense, and neither does Saturation.
+a "co-result" that goes into CR0 or CR1. Thus, Saturation makes no sense.
 All of these differences, which require quite a lot of logical
 reasoning and deduction, help explain why there is an entirely different
 CR ops Vectorisation Category.
@@ -404,6 +403,28 @@ polar opposite, and in the end, the idea was thrown out, and Indexed
 REMAP added in its place.  Indexed REMAP comes with its own quirks,
 solving the Hazard problem, described in a later section.
 
+# REMAP and other reordering
+
+There are several places in Simple-V which apply some sort of reordering
+schedule to elements.  srcstep and dststep do not themselves reorder:
+they continue to march in sequence (VL-1 downto 0 in the case of reverse-gear)
+
+It is perfectly legal to apply Parallel-Reduction on top of any type
+of REMAP, for example, and it is possible to apply Pack/Unpack on a
+REMAP as well.
+
+The order of application of REMAP combined with Parallel-Reduction
+should be logically obvious: REMAP has to come first because otherwise
+how can the Parallel-Reduction perform a tree-walk?
+
+Pack/Unpack on the other hand is best implemented as applying first,
+because it is applied
+as the inversion of the for-loops which generate the steps and substeps.
+REMAP then applies to the src/dst-step indices (never to the subvl
+step indices: that is SWIZZLE's job).
+
+It's all perfectly logical, just a lot going on.
+
 # Branch-Conditional
 
 [[sv/branches]] are a very special exception to the rule that there
@@ -553,6 +574,18 @@ Where this breaks down is when attempting to do half-width on
 BF16 or FP16 operations: there does not exist a BF8 or an IEEE754 FP8
 format, so these (`sv.fadds/ew=8`) should be avoided.
 
+# Word frequently becomes "half"
+
+Again, related to "Single" becoming "half of element width", unless there
+are compelling reasons the same trick applies to Scalar GPR operations.
+With the pseudocode being "XLEN//2" then of course if XLEN=8 the operation
+becomes a 4-bit one.
+
+Similarly byte operations which use "XLEN//8" when XLEN=8 actually become
+single-bit operations, which is very useful with `sv.extsb/w=8`
+for example.  This instruction copies the LSB of each byte in a sequence of bytes,
+and expands it to all 8 bits in each result byte.
+
 # Vertical-First and Subvectors
 
 Documented in the [[sv/setvl]] page, Vertical-First goes through
@@ -578,41 +611,21 @@ comes when Pack/Unpack are enabled, and it is really important
 to be aware how the Arrays of vec2/3/4 become re-ordered
 *and swizzled at the same time*.
 
-Pack/Unpack applies to 
-[[sv/mv.vec]] as well however the uniform relationship and
-the fact that the source and destination subvector length
-must be the same (vec2/3/4) makes things slightly easier to
-understand.  The main thing to keep in mind about Pack/Unpack
+Pack/Unpack started out as 
+[[sv/mv.vec]] but became its own distinct Mode over time.
+The main thing to keep in mind about Pack/Unpack
 is that it engages a swap of the ordering of the VL-SUBVL
 nested for-loops, in exactly the same way that Matrix REMAP
-can do.  When Pack or Unpack is enabled it is the SUBVL for-loop
-that becomes outermost.
-
-# No Scalar GPR Move
-
-Perhaps unsurprisingly the Scalar Power ISA does not have
-a Scalar GPR Move instruction: instead, there are a series
-of pseudo-op opportunities such as `addi RT,RA,0` or `ori RT,RA,0`
-and many more.
-
-Strictly speaking these may orthogonally be Vectorised and achieve
-the same effect as a Vector Move.  However these instructions
-are marked as `RM-2P-1S1D` and have EXTRA3 Augmentation. In other
-words it is not possible to use them in Pack/Unpack Mode.
-There is however a trick: [[sv/mv.swizzle]] with a straight linear
-mapping (X to X, Y to Y...)
-By applying a straight linear swizzle map, the `RM-2P-1S1D-PU` mode
-of `sv.mv.swizzle`
-is available.
-
-It has however been decided to make one of the many pseudo-op aliases
-a Pack/Unpack variant: `sv.xori RT,RA,0`.  This loses half the range
-of access of the Scalar regs (r0..r63) due to using an EXTRA2. It was
-felt to be better to do this to xori rather than ori or addi.
-
-Pack/Unpack has to be deployed across SVP64 sparingly (not so uniformly
-general) due to the fact that it takes up two RM.EXTRA bits, putting
-pressure on developers by restricting the register range as above.
+can do.
+When Pack or Unpack is enabled it is the SUBVL for-loop
+that becomes outermost.  A bit of thought shows that this is
+a 2D "Transpose" where Dimension X is VL and Dimension Y is SUBVL.
+However *both* source *and* destination may be independently
+"Transposed", which makes no sense at all until the fact that
+Swizzle can have a *different SUBVL* is taken into account.
+
+Basically Pack/Unpack covers everything that VSX `vpkpx` and
+other ops can do, and then some: Saturation included, for arithmetic ops.
 
 # LD/ST with zero-immediate vs mapreduce mode
 
@@ -622,7 +635,8 @@ multiplied by zero.  Thus, a sequence of LD operations will load from
 the exact same address, and likewise STs to the exact same address.
 
 Ordinarily this would make absolutely no sense whatsoever, except
-that Power ISA has cache-inhibited LD/STs, for accessing memory-mapped
+that Power ISA has cache-inhibited LD/STs (Power ISA v.1, Book III,
+1.6.1, p1033), for accessing memory-mapped
 peripherals and other crucial uses.  Thus, *despite not being a mapreduce mode*,
 zero-immediates cause multiple hits on the same element.
 
@@ -638,4 +652,65 @@ more of an artefact.
 LD/ST zero-immediate has similar quirky overwriting as the "mapreduce"
 mode, but actually requires the registers to be Vectors.  It is simply
 a mathematical artefact of multiplying by zero, which happens to be
-useful for cache=inhibited operations.
+useful for cache-inhibited operations.
+
+# Limited space in LD/ST Mode
+
+As pointed out in the [[sv/ldst]] page there is limited space in only
+5 mode bits to fully express all potential modes of operation.
+
+* LD/ST Immediate has no individual control over src/dest zeroing,
+  whereas LD/ST Indexed does.
+* Post-Increment is not possible with Saturation or Data-Dependent Fail-First
+* Element-Strided LD/ST Indexed is not possible with Data-Dependent Fail-First.
+
+Also, the LD/ST Indexed Mode can be element-strided (RB as
+a Scalar, times
+the element index), or, if that is not enough,
+although potentially costly it is possible to
+use `svstep` to compute a Vector RB sequence of
+Indices, then activate either `sz` or `dz` as required, as a workaround
+for LDST Immediate only having `zz`.
+
+Simple-V is powerful but it cannot do everything! There is just not
+enough space and so some compromises had to be made.
+
+# sv.mtcr on entire 64-bit Condition Register
+
+Normally, CR operations are either bit-based (where the element numbering actually
+applies to the CR Field) or field-based in which case the elements are still
+fields.  The `sv.mtcr` and other instructions are actually full 64-bit Condition
+*Register* operations and are therefore qualified as Normal/Arithmetic not
+CRops.
+
+This is to save on both Vector Length (VL of 16 is sufficient) as well as
+complexity in the Hazard Management when context-switching CR fields, as the
+entire batch of 128 CR Fields may be transferred to 8 GPRs with a VL of 16
+and elwidth overriding of 32. Truncation is sufficent, dropping the top 32 bits
+of the Condition Register(s) which are always zero anyway.
+
+# Separate Scalar and Vector Condition Register files
+
+As explained in the introduction [[sv/svp64]] and [[sv/cr_ops]]
+Scalar Power ISA lacks "Conditional Execution" present in ARM
+Scalar ISA of several decades.  When Vectorised the fact that
+Rc=1 Vector results can immediately be used as a Predicate Mask
+back into the following instruction can result in large latency
+unless "Vector Chaining" is used in the Micro-Architecture.
+
+But that aside is not the main problem faced by the introduction
+of Simple-V to the Power ISA: it's that the existing implementations
+(IBM) don't have "Conditional Execution" and to add it to their
+existing designs would be too disruptive a first step.
+
+A compromise is to wipe blank certain entries in the Register Dependency
+Matrices by prohibiting some operations involving the two groups
+of CR Fields: those that fall into the existing Scalar 32-bit CR
+(fields CR0-CR7) and those that fall into the newly-introduced
+CR Fields, CR8-CR127.
+
+This will drive compiler writers nuts, and give assembler writers headaches,
+but it gives IBM the opportunity to implement SVP64 without massive
+disruption. They can add an entirely new Vector CR register file,
+new pipelines etc safe in the knowledge that existing Scalar HDL
+needs no modification.