# Element-width overrides
+Element-width overrides are best illustrated with a packed structure
+union in the c programming language. The following should be taken
+literally, and assume always a little-endian layout:
+
typedef union {
- uint8_t b;
- uint16_t s;
- uint32_t i;
- uint64_t l;
+ uint8_t b[];
+ uint16_t s[];
+ uint32_t i[];
+ uint64_t l[];
+ uint8_t actual_bytes[8];
} el_reg_t;
elreg_t int_regfile[128];
elif bitwidth == 64:
int_regfile[reg].l[offset] = val
+In effect the GPR registers r0 to r127 (and corresponding FPRs fp0
+to fp127) are reinterpreted to be "starting points" in a byte-addressable
+memory. Vectors - which become just a virtual naming construct - effectively
+overlap.
+
+It is extremely important for implementors to note that the only circumstance
+where upper portions of an underlying 64-bit register are zero'd out is
+when the destination is a scalar. The ideal register file has byte-level
+write-enable lines, just like most SRAMs.
+
An example ADD operation with predication and element width overrides:
for (i = 0; i < VL; i++)
- if (predval & 1<<i) # predication uses intregs
+ if (predval & 1<<i) # predication
src1 = get_polymorphed_reg(RA, srcwid, irs1)
src2 = get_polymorphed_reg(RB, srcwid, irs2)
result = src1 + src2 # actual add here
if (RA.isvec) { irs1 += 1; }
if (RB.isvec) { irs2 += 1; }
-
# Twin (implicit) result operations
Some operations in the Power ISA already target two 64-bit scalar
Bear in mind that both RT and RT+MAXVL are starting points for Vectors,
and bear in mind that element-width overrides still have to be taken
-into consideration,
+into consideration, the starting point for the implicit destination
+is best illustrated in pseudocode:
+
+ # demo of madded
+ for (i = 0; i < VL; i++)
+ if (predval & 1<<i) # predication
+ src1 = get_polymorphed_reg(RA, srcwid, irs1)
+ src2 = get_polymorphed_reg(RB, srcwid, irs2)
+ src2 = get_polymorphed_reg(RC, srcwid, irs3)
+ result = src1*src2 + src2
+ destmask = (2<<destwid)-1
+ # store two halves of result
+ set_polymorphed_reg(RT, destwid, ird , result&destmask)
+ set_polymorphed_reg(RT, destwid, ird+MAXVL, result>>destwid)
+ if (!RT.isvec) break
+ if (RT.isvec) { id += 1; }
+ if (RA.isvec) { irs1 += 1; }
+ if (RB.isvec) { irs2 += 1; }
+ if (RC.isvec) { irs3 += 1; }
+The significant part here is that the second half is stored
+starting not from RT+MAXVL at all: it is the *element* index
+that is offset by MAXVL, both starting from RT.
* [[isa/svfixedarith]]
* [[isa/svfparith]]