# LOAD/STORE Elwidths <a name="ldst"></a>
+Loads and Stores are almost unique in that the OpenPOWER Scalar ISA provides a width for the operation (lb, lh, lw, ld). There are therefore three widths involved:
+
+* operation width (lb=8, lh=16, lw=32, ld=64)
+* source width override
+* destination element override
+
+The reason for all three is because Saturation (and other transformations) may occur in between, which rely on the source and destination width, and have nothing to do (per se) with the operation width.
+
+Below is the pseudocode for Unit-Strided LD. Note the following:
+
+* `scalar identity behaviour` SV Context parameter conditions turn this
+ into a straight absolute fully-compliant Scalar v3.0B LD operation
+* brev selects whether the operation is the byte-reversed variant (ldbrx
+ rather than ld)
+* op_width specifies the operation width (lb, lh, lw, ld)
+* imm_offs specifies the immediate offset `ld r3, imm_offs(r5)`
+* svctx specifies the SV Context and includes VL as well as source and
+ destination elwidth overrides.
+
# LD not VLD! (ldbrx if brev=True)
# this covers unit stride mode
function op_ld(rd, rs, brev, op_width, imm_offs, svctx)
- for (int i = 0, int j = 0; i < VL && j < VL;):
+ for (int i = 0, int j = 0; i < svctx.VL && j < svctx.VL;):
# unit stride mode, compute the address
srcbase = ireg[rs] + i * op_width;
if (bytereverse):
memread = byteswap(memread, op_width)
- # now truncate to source over-ridden width
+ # now truncate to source over-ridden width.
if (svctx.src_elwidth != default)
memread = adjust_wid(memread, op_width, svctx.src_elwidth)
+ # note that here we would now do saturation if it was enabled.
+ ... saturation adjustment...
+
# takes care of inserting memory-read (now correctly byteswapped)
# into regfile underlying LE-defined order, into the right place
# within the NEON-like register, respecting destination element