--- /dev/null
+# ISA Pseudo-code
+
+<!-- this is a test comment -->
+
+ISA is the [[!wikipedia Instruction_set_architecture]] of a machine, the: CPU instructions, register set, memory model, etc, that describe the way a machine works.
+
+These pages contain (in a strict machine-readable subset of mdwn)
+the pseudo-code for all opcodes in the POWER v3.0B Public Spec
+
+* [[isa/bcd]]
+* [[isa/branch]]
+* [[isa/comparefixed]]
+* [[isa/condition]]
+* [[isa/fixedarith]]
+* [[isa/fixedload]]
+* [[isa/fixedlogical]]
+* [[isa/fixedshift]]
+* [[isa/fixedstore]]
+* [[isa/fixedtrap]]
+* [[isa/sprset]]
+* [[isa/stringldst]]
+* [[isa/system]]
+* [[isa/simplev]]
+
+# Pseudocode syntax
+
+The syntax is shown in the v3.0B OpenPOWER Reference Manual. The implementation of a parser, using python-ply, is here: <https://git.libre-soc.org/?p=soc.git;a=blob;f=src/soc/decoder/pseudo/parser.py;hb=HEAD>
+
+The parser is based on the python-ply GardenSnake.py example (except bugs were fixed in it, first). Extra tokens, in the lexer phase, are inserted dynamically into the stream to make the parser think that it is seeing python-like syntax where in fact it is not. Example: when a pseudocode keyword "THEN" is seen, this is substituted for ":". The keyword "ELSE" will also automatically have a second ":" token inserted in order to comply with python syntax. Thus the following pseudocode:
+
+ if x = 1 then
+ RT <- 1
+ else
+ RT <- 0
+
+results in the parser seeing the following python code:
+
+ if x == 1:
+ RT = 1
+ else
+ RT = 0
+
+To support this python-like syntax some of the pseudocode after extraction from the PDF had to be cleaned up and proper indentation added.
+
+Also worth noting as used in the above example: the following operators are used (see section 1.3 "Notation" of v3.0B PDF):
+
+* `<-` assignment, instead of "=" as in python
+* `=` equals comparator, instead of "==" as in python
+* `||` concatenate, done bitwise, in MSB0 order.
+* `>u` for unsigned greater (">" is signed)
+* `<u` for unsigned lessthan ("<" is signed)
+* X superscript n subscript is instead expressed `[X]*n`
+* X subscript n or n:m is expressed as `X[n:m]`
+
+The reason for the addition of the unsigned comparator operators is because numbers in the pseudocode are bitpatterns, not assigned a type or a sign as would normally be done in a standard programming language
+
--- /dev/null
+<!-- Instructions here described in PowerISA Version 3.0 B Book 1 -->
+
+<!-- Section 3.3.15 Binary Coded Decimal (BCD) Assist Instructions. Page 111 -->
+
+<!-- The Binary Coded Decimal Assist instructions operate on Binary Coded Decimal -->
+<!-- operands (cbcdtd and addg6s) and Decimal Floating-Point operands (cdtbcd) -->
+<!-- See Chapter 5. for additional information. -->
+
+
+# Convert Declets To Binary Coded Decimal
+
+X-Form
+
+* cdtbcd RA, RS
+
+Pseudo-code:
+
+ do i = 0 to 1
+ n <- i * 32
+ RA[n+0:n+7] <- 0
+ RA[n+8:n+19 ] <- DPD_TO_BCD ( (RS)[n+12:n+21] )
+ RA[n+20:n+31] <- DPD_TO_BCD ( (RS)[n+22:n+31] )
+
+Special Registers Altered:
+
+ None
+
+# Add and Generate Sixes
+
+XO-Form
+
+* addg6s RT,RA,RB
+
+Pseudo-code:
+
+ do i = 0 to 15
+ dci <- carry_out(RA[4*i:63] + RB[4*i:63])
+ c <- ([dc[0]]*4 || [dc[1]]*4 || [dc[2]]*4 || [dc[3]]*4 ||
+ [dc[4]]*4 || [dc[5]]*4 || [dc[6]]*4 || [dc[7]]*4 ||
+ [dc[8]]*4 || [dc[9]]*4 || [dc[10]]*4 || [dc[11]]*4 ||
+ [dc[12]]*4 || [dc[13]]*4 || [dc[14]]*4 || [dc[15]]*4)
+ RT <- (¬c) & 0x6666_6666_6666_6666
+
+Special Registers Altered:
+
+ None
+
+# Convert Binary Coded Decimal To Declets
+
+X-Form
+
+* cbcdtd RA, RS
+
+Pseudo-code:
+
+ do i = 0 to 1
+ n <- i * 32
+ RA[n+0:n+11] <- 0
+ RA[n+12:n+21] <- BCD_TO_DPD ( (RS)[n+8:n+19] )
+ RA[n+22:n+31] <- BCD_TO_DPD ( (RS)[n+20:n+31] )
+
+Special Registers Altered:
+
+ None
+
+<!-- Checked March 2021 -->
--- /dev/null
+<!-- Instructions here described in PowerISA Version 3.0 B Book 1 -->
+
+<!-- Section 2.4 Branch Instructions. Pages 33 - 39 -->
+
+<!-- The sequence of instruction execution can be changed by the Branch -->
+<!-- instructions. Because all instructions are on word boundaries, bits 62 and 63 -->
+<!-- of the generated branch target address are ignored by the processor in -->
+<!-- performing the branch. -->
+
+<!-- target_addr specifies the branch target address. -->
+
+<!-- If AA=0 then the branch target address is the sum of LI || 0b00 sign-extended -->
+<!-- and the address of this instruction, with the high-order 32 bits of the branch -->
+<!-- target address set to 0 in 32-bit mode. -->
+
+<!-- If AA=1 then the branch target address is the value LI || 0b00 sign-extended, -->
+<!-- with the high-order 32 bits of the branch target address set to 0 in 32-bit -->
+<!-- mode. -->
+
+<!-- If LK=1 then the effective address of the instruction following the Branch -->
+<!-- instruction is placed into the Link Register. -->
+
+# Branch
+
+I-Form
+
+* b target_addr (AA=0 LK=0)
+* ba target_addr (AA=1 LK=0)
+* bl target_addr (AA=0 LK=1)
+* bla target_addr (AA=1 LK=1)
+
+Pseudo-code:
+
+ if AA then NIA <-iea EXTS(LI || 0b00)
+ else NIA <-iea CIA + EXTS(LI || 0b00)
+ if LK then LR <-iea CIA + 4
+
+Special Registers Altered:
+
+ LR (if LK=1)
+
+# Branch Conditional
+
+B-Form
+
+* bc BO,BI,target_addr (AA=0 LK=0)
+* bca BO,BI,target_addr (AA=1 LK=0)
+* bcl BO,BI,target_addr (AA=0 LK=1)
+* bcla BO,BI,target_addr (AA=1 LK=1)
+
+Pseudo-code:
+
+ if (mode_is_64bit) then M <- 0
+ else M <- 32
+ if ¬BO[2] then CTR <- CTR - 1
+ ctr_ok <- BO[2] | ((CTR[M:63] != 0) ^ BO[3])
+ cond_ok <- BO[0] | ¬(CR[BI+32] ^ BO[1])
+ if ctr_ok & cond_ok then
+ if AA then NIA <-iea EXTS(BD || 0b00)
+ else NIA <-iea CIA + EXTS(BD || 0b00)
+ if LK then LR <-iea CIA + 4
+
+Special Registers Altered:
+
+ CTR (if BO2=0)
+ LR (if LK=1)
+
+# Branch Conditional to Link Register
+
+XL-Form
+
+* bclr BO,BI,BH (LK=0)
+* bclrl BO,BI,BH (LK=1)
+
+Pseudo-code:
+
+ if (mode_is_64bit) then M <- 0
+ else M <- 32
+ if ¬BO[2] then CTR <- CTR - 1
+ ctr_ok <- BO[2] | ((CTR[M:63] != 0) ^ BO[3])
+ cond_ok <- BO[0] | ¬(CR[BI+32] ^ BO[1])
+ if ctr_ok & cond_ok then NIA <-iea LR[0:61] || 0b00
+ if LK then LR <-iea CIA + 4
+
+Special Registers Altered:
+
+ CTR (if BO2=0)
+ LR (if LK=1)
+
+# Branch Conditional to Count Register
+
+XL-Form
+
+* bcctr BO,BI,BH (LK=0)
+* bcctrl BO,BI,BH (LK=1)
+
+Pseudo-code:
+
+ cond_ok <- BO[0] | ¬(CR[BI+32] ^ BO[1])
+ if cond_ok then NIA <-iea CTR[0:61] || 0b00
+ if LK then LR <-iea CIA + 4
+
+Special Registers Altered:
+
+ LR (if LK=1)
+
+# Branch Conditional to Branch Target Address Register
+
+XL-Form
+
+* bctar BO,BI,BH (LK=0)
+* bctarl BO,BI,BH (LK=1)
+
+Pseudo-code:
+
+ if (mode_is_64bit) then M <- 0
+ else M <- 32
+ if ¬BO[2] then CTR <- CTR - 1
+ ctr_ok <- BO[2] | ((CTR[M:63] != 0) ^ BO[3])
+ cond_ok <- BO[0] | ¬(CR[BI+32] ^ BO[1])
+ if ctr_ok & cond_ok then NIA <-iea TAR[0:61] || 0b00
+ if LK then LR <-iea CIA + 4
+
+Special Registers Altered:
+
+ CTR (if BO2=0)
+ LR (if LK=1)
+
+
+<!-- Checked March 2021 -->
--- /dev/null
+<!-- Instructions here described in PowerISA Version 3.0 B Book 1 -->
+
+<!-- Section 3.3.10 Fixed-Point Compare Instructions Pages 84 - 88 -->
+
+<!-- The fixed-point Compare instructions compare the contents of register RA with -->
+<!-- (1) the sign-extended value of the SI field, (2) the zero-extended value of the -->
+<!-- UI field, or (3) the contents of register RB. The comparison is signed for cmpi -->
+<!-- and cmp, and unsigned for cmpli and cmpl. -->
+
+# Compare Immediate
+
+D-Form
+
+* cmpi BF,L,RA,SI
+
+Pseudo-code:
+
+ if L = 0 then a <- EXTS((RA)[32:63])
+ else a <- (RA)
+ if a < EXTS(SI) then c <- 0b100
+ else if a > EXTS(SI) then c <- 0b010
+ else c <- 0b001
+ CR[4*BF+32:4*BF+35] <- c || XER[SO]
+
+Special Registers Altered:
+
+ CR field BF
+
+# Compare
+
+X-Form
+
+* cmp BF,L,RA,RB
+
+Pseudo-code:
+
+ if L = 0 then
+ a <- EXTS((RA)[32:63])
+ b <- EXTS((RB)[32:63])
+ else
+ a <- (RA)
+ b <- (RB)
+ if a < b then c <- 0b100
+ else if a > b then c <- 0b010
+ else c <- 0b001
+ CR[4*BF+32:4*BF+35] <- c || XER[SO]
+
+Special Registers Altered:
+
+ CR field BF
+
+# Compare Logical Immediate
+
+D-Form
+
+* cmpli BF,L,RA,UI
+
+Pseudo-code:
+
+ if L = 0 then a <- [0]*32 || (RA)[32:63]
+ else a <- (RA)
+ if a <u ([0]*48 || UI) then c <- 0b100
+ else if a >u ([0]*48 || UI) then c <- 0b010
+ else c <- 0b001
+ CR[4*BF+32:4*BF+35] <- c || XER[SO]
+
+Special Registers Altered:
+
+ CR field BF
+
+# Compare Logical
+
+X-Form
+
+* cmpl BF,L,RA,RB
+
+Pseudo-code:
+
+ if L = 0 then
+ a <- [0]*32 || (RA)[32:63]
+ b <- [0]*32 || (RB)[32:63]
+ else
+ a <- (RA)
+ b <- (RB)
+ if a <u b then c <- 0b100
+ else if a >u b then c <- 0b010
+ else c <- 0b001
+ CR[4*BF+32:4*BF+35] <- c || XER[SO]
+
+Special Registers Altered:
+
+ CR field BF
+
+# Compare Ranged Byte
+
+X-Form
+
+* cmprb BF,L,RA,RB
+
+Pseudo-code:
+
+ src1 <- EXTZ((RA)[56:63])
+ src21hi <- EXTZ((RB)[32:39])
+ src21lo <- EXTZ((RB)[40:47])
+ src22hi <- EXTZ((RB)[48:55])
+ src22lo <- EXTZ((RB)[56:63])
+ if L=0 then
+ in_range <- (src22lo <= src1) & (src1 <= src22hi)
+ else
+ in_range <- (((src21lo <= src1) & (src1 <= src21hi)) |
+ ((src22lo <= src1) & (src1 <= src22hi)))
+ CR[4*BF+32] <- 0b0
+ CR[4*BF+33] <- in_range
+ CR[4*BF+34] <- 0b0
+ CR[4*BF+35] <- 0b0
+
+Special Registers Altered:
+
+ CR field BF
+
+# Compare Equal Byte
+
+X-Form
+
+* cmpeqb BF,RA,RB
+
+Pseudo-code:
+
+ src1 <- GPR[RA]
+ src1 <- src1[56:63]
+ match <- ((src1 = (RB)[00:07]) |
+ (src1 = (RB)[08:15]) |
+ (src1 = (RB)[16:23]) |
+ (src1 = (RB)[24:31]) |
+ (src1 = (RB)[32:39]) |
+ (src1 = (RB)[40:47]) |
+ (src1 = (RB)[48:55]) |
+ (src1 = (RB)[56:63]))
+ CR[4*BF+32] <- 0b0
+ CR[4*BF+33] <- match
+ CR[4*BF+34] <- 0b0
+ CR[4*BF+35] <- 0b0
+
+Special Registers Altered:
+
+ CR field BF
+
+<!-- Checked March 2021 -->
--- /dev/null
+<!-- Instructions here described in PowerISA Version 3.0 B Book 1 -->
+
+<!-- Section 2.5.1 Condition Register Logical Instructions Pages 40 - 41 -->
+
+<!-- The Condition Register Logical instructions have preferred forms; see Section -->
+<!-- 1.9.1. -->
+
+<!-- In the preferred forms, the BT and BB fields satisfy the following rule: -->
+
+<!-- * The bit specified by BT is in the same Condition Register field as the bit -->
+<!-- specified by BB. -->
+
+# Condition Register AND
+
+XL-Form
+
+* crand BT,BA,BB
+
+Pseudo-code:
+
+ CR[BT+32] <- CR[BA+32] & CR[BB+32]
+
+Special Registers Altered:
+
+ CR[BT+32]
+
+# Condition Register NAND
+
+XL-Form
+
+* crnand BT,BA,BB
+
+Pseudo-code:
+
+ CR[BT+32] <- ¬(CR[BA+32] & CR[BB+32])
+
+Special Registers Altered:
+
+ CR[BT+32]
+
+# Condition Register OR
+
+XL-Form
+
+* cror BT,BA,BB
+
+Pseudo-code:
+
+ CR[BT+32] <- CR[BA+32] | CR[BB+32]
+
+Special Registers Altered:
+
+ CR[BT+32]
+
+# Condition Register XOR
+
+XL-Form
+
+* crxor BT,BA,BB
+
+Pseudo-code:
+
+ CR[BT+32] <- CR[BA+32] ^ CR[BB+32]
+
+Special Registers Altered:
+
+ CR[BT+32]
+
+# Condition Register NOR
+
+XL-Form
+
+* crnor BT,BA,BB
+
+Pseudo-code:
+
+ CR[BT+32] <- ¬(CR[BA+32] | CR[BB+32])
+
+Special Registers Altered:
+
+ CR[BT+32]
+
+# Condition Register Equivalent
+
+XL-Form
+
+* creqv BT,BA,BB
+
+Pseudo-code:
+
+ CR[BT+32] <- ¬(CR[BA+32] ^ CR[BB+32])
+
+Special Registers Altered:
+
+ CR[BT+32]
+
+# Condition Register AND with Complement
+
+XL-Form
+
+* crandc BT,BA,BB
+
+Pseudo-code:
+
+ CR[BT+32] <- CR[BA+32] & ¬CR[BB+32]
+
+Special Registers Altered:
+
+ CR[BT+32]
+
+# Condition Register OR with Complement
+
+XL-Form
+
+* crorc BT,BA,BB
+
+Pseudo-code:
+
+ CR[BT+32] <- CR[BA+32] | ¬CR[BB+32]
+
+Special Registers Altered:
+
+ CR[BT+32]
+
+# Move Condition Register Field
+
+XL-Form
+
+* mcrf BF,BFA
+
+Pseudo-code:
+
+ CR[4*BF+32:4*BF+35] <- CR[4*BFA+32:4*BFA+35]
+
+Special Registers Altered:
+
+ CR field BF
+
+<!-- Checked March 2021 -->
--- /dev/null
+<!-- X Instructions here described in PowerISA Version 3.0 B Book 1 -->
+
+<!-- Section 3.3.9 Fixed-point arithmetic instructions. Pages 67 - 83 -->
+
+# Add Immediate
+
+D-Form
+
+* addi RT,RA,SI
+
+Pseudo-code:
+
+ RT <- (RA|0) + EXTS(SI)
+
+Special Registers Altered:
+
+ None
+
+# Add Immediate Shifted
+
+D-Form
+
+* addis RT,RA,SI
+
+Pseudo-code:
+
+ RT <- (RA|0) + EXTS(SI || [0]*16)
+
+Special Registers Altered:
+
+ None
+
+# Add PC Immediate Shifted
+
+DX-Form
+
+* addpcis RT,D
+
+Pseudo-code:
+
+ D <- d0||d1||d2
+ RT <- NIA + EXTS(D || [0]*16)
+
+Special Registers Altered:
+
+ None
+
+# Add
+
+XO-Form
+
+* add RT,RA,RB (OE=0 Rc=0)
+* add. RT,RA,RB (OE=0 Rc=1)
+* addo RT,RA,RB (OE=1 Rc=0)
+* addo. RT,RA,RB (OE=1 Rc=1)
+
+Pseudo-code:
+
+ RT <- (RA) + (RB)
+
+Special Registers Altered:
+
+ CR0 (if Rc=1)
+ SO OV OV32 (if OE=1)
+
+# Subtract From
+
+XO-Form
+
+* subf RT,RA,RB (OE=0 Rc=0)
+* subf. RT,RA,RB (OE=0 Rc=1)
+* subfo RT,RA,RB (OE=1 Rc=0)
+* subfo. RT,RA,RB (OE=1 Rc=1)
+
+Pseudo-code:
+
+ RT <- ¬(RA) + (RB) + 1
+
+Special Registers Altered:
+
+ CR0 (if Rc=1)
+ SO OV OV32 (if OE=1)
+
+# Add Immediate Carrying
+
+D-Form
+
+* addic RT,RA,SI
+
+Pseudo-code:
+
+ RT <- (RA) + EXTS(SI)
+
+Special Registers Altered:
+
+ CA CA32
+
+# Add Immediate Carrying and Record
+
+D-Form
+
+* addic. RT,RA,SI
+
+Pseudo-code:
+
+ RT <- (RA) + EXTS(SI)
+
+Special Registers Altered:
+
+ CR0 CA CA32
+
+# Subtract From Immediate Carrying
+
+D-Form
+
+* subfic RT,RA,SI
+
+Pseudo-code:
+
+ RT <- ¬(RA) + EXTS(SI) + 1
+
+Special Registers Altered:
+
+ CA CA32
+
+# Add Carrying
+
+XO-Form
+
+* addc RT,RA,RB (OE=0 Rc=0)
+* addc. RT,RA,RB (OE=0 Rc=1)
+* addco RT,RA,RB (OE=1 Rc=0)
+* addco. RT,RA,RB (OE=1 Rc=1)
+
+Pseudo-code:
+
+ RT <- (RA) + (RB)
+
+Special Registers Altered:
+
+ CA CA32
+ CR0 (if Rc=1)
+ SO OV OV32 (if OE=1)
+
+# Subtract From Carrying
+
+XO-Form
+
+* subfc RT,RA,RB (OE=0 Rc=0)
+* subfc. RT,RA,RB (OE=0 Rc=1)
+* subfco RT,RA,RB (OE=1 Rc=0)
+* subfco. RT,RA,RB (OE=1 Rc=1)
+
+Pseudo-code:
+
+ RT <- ¬(RA) + (RB) + 1
+
+Special Registers Altered:
+
+ CA CA32
+ CR0 (if Rc=1)
+ SO OV OV32 (if OE=1)
+
+# Add Extended
+
+XO-Form
+
+* adde RT,RA,RB (OE=0 Rc=0)
+* adde. RT,RA,RB (OE=0 Rc=1)
+* addeo RT,RA,RB (OE=1 Rc=0)
+* addeo. RT,RA,RB (OE=1 Rc=1)
+
+Pseudo-code:
+
+ RT <- (RA) + (RB) + CA
+
+Special Registers Altered:
+
+ CA CA32
+ CR0 (if Rc=1)
+ SO OV OV32 (if OE=1)
+
+# Subtract From Extended
+
+XO-Form
+
+* subfe RT,RA,RB (OE=0 Rc=0)
+* subfe. RT,RA,RB (OE=0 Rc=1)
+* subfeo RT,RA,RB (OE=1 Rc=0)
+* subfeo. RT,RA,RB (OE=1 Rc=1)
+
+Pseudo-code:
+
+ RT <- ¬(RA) + (RB) + CA
+
+Special Registers Altered:
+
+ CA CA32
+ CR0 (if Rc=1)
+ SO OV OV32 (if OE=1)
+
+# Add to Minus One Extended
+
+XO-Form
+
+* addme RT,RA (OE=0 Rc=0)
+* addme. RT,RA (OE=0 Rc=1)
+* addmeo RT,RA (OE=1 Rc=0)
+* addmeo. RT,RA (OE=1 Rc=1)
+
+Pseudo-code:
+
+ RT <- (RA) + CA - 1
+
+Special Registers Altered:
+
+ CA CA32
+ CR0 (if Rc=1)
+ SO OV OV32 (if OE=1)
+
+# Subtract From Minus One Extended
+
+XO-Form
+
+* subfme RT,RA (OE=0 Rc=0)
+* subfme. RT,RA (OE=0 Rc=1)
+* subfmeo RT,RA (OE=1 Rc=0)
+* subfmeo. RT,RA (OE=1 Rc=1)
+
+Pseudo-code:
+
+ RT <- ¬(RA) + CA - 1
+
+Special Registers Altered:
+
+ CA CA32
+ CR0 (if Rc=1)
+ SO OV OV32 (if OE=1)
+
+# Add Extended using alternate carry bit
+
+Z23-Form
+
+* addex RT,RA,RB,CY
+
+Pseudo-code:
+
+ if CY=0 then RT <- (RA) + (RB) + OV
+
+Special Registers Altered:
+
+ OV OV32 (if CY=0 )
+
+# Subtract From Zero Extended
+
+XO-Form
+
+* subfze RT,RA (OE=0 Rc=0)
+* subfze. RT,RA (OE=0 Rc=1)
+* subfzeo RT,RA (OE=1 Rc=0)
+* subfzeo. RT,RA (OE=1 Rc=1)
+
+Pseudo-code:
+
+ RT <- ¬(RA) + CA
+
+Special Registers Altered:
+
+ CA CA32
+ CR0 (if Rc=1)
+ SO OV OV32 (if OE=1)
+
+# Add to Zero Extended
+
+XO-Form
+
+* addze RT,RA (OE=0 Rc=0)
+* addze. RT,RA (OE=0 Rc=1)
+* addzeo RT,RA (OE=1 Rc=0)
+* addzeo. RT,RA (OE=1 Rc=1)
+
+Pseudo-code:
+
+ RT <- (RA) + CA
+
+Special Registers Altered:
+
+ CA CA32
+ CR0 (if Rc=1)
+ SO OV OV32 (if OE=1)
+
+# Negate
+
+XO-Form
+
+* neg RT,RA (OE=0 Rc=0)
+* neg. RT,RA (OE=0 Rc=1)
+* nego RT,RA (OE=1 Rc=0)
+* nego. RT,RA (OE=1 Rc=1)
+
+Pseudo-code:
+
+ RT <- ¬(RA) + 1
+
+Special Registers Altered:
+
+ CR0 (if Rc=1)
+ SO OV OV32 (if OE=1)
+
+# Multiply Low Immediate
+
+D-Form
+
+* mulli RT,RA,SI
+
+Pseudo-code:
+
+ prod[0:127] <- MULS((RA), EXTS(SI))
+ RT <- prod[64:127]
+
+Special Registers Altered:
+
+ None
+
+# Multiply High Word
+
+XO-Form
+
+* mulhw RT,RA,RB (Rc=0)
+* mulhw. RT,RA,RB (Rc=1)
+
+Pseudo-code:
+
+ prod[0:63] <- MULS((RA)[32:63], (RB)[32:63])
+ RT[32:63] <- prod[0:31]
+ RT[0:31] <- undefined(prod[0:31])
+
+Special Registers Altered:
+
+ CR0 (bits 0:2 undefined in 64-bit mode) (if Rc=1)
+
+# Multiply Low Word
+
+XO-Form
+
+* mullw RT,RA,RB (OE=0 Rc=0)
+* mullw. RT,RA,RB (OE=0 Rc=1)
+* mullwo RT,RA,RB (OE=1 Rc=0)
+* mullwo. RT,RA,RB (OE=1 Rc=1)
+
+Pseudo-code:
+
+ prod[0:63] <- MULS((RA)[32:63], (RB)[32:63])
+ RT <- prod
+ overflow <- ((prod[0:32] != [0]*33) &
+ (prod[0:32] != [1]*33))
+
+Special Registers Altered:
+
+ CR0 (if Rc=1)
+ SO OV OV32 (if OE=1)
+
+# Multiply High Word Unsigned
+
+XO-Form
+
+* mulhwu RT,RA,RB (Rc=0)
+* mulhwu. RT,RA,RB (Rc=1)
+
+Pseudo-code:
+
+ prod[0:63] <- (RA)[32:63] * (RB)[32:63]
+ RT[32:63] <- prod[0:31]
+ RT[0:31] <- undefined(prod[0:31])
+
+Special Registers Altered:
+
+ CR0 (bits 0:2 undefined in 64-bit mode) (if Rc=1)
+
+# Divide Word
+
+XO-Form
+
+* divw RT,RA,RB (OE=0 Rc=0)
+* divw. RT,RA,RB (OE=0 Rc=1)
+* divwo RT,RA,RB (OE=1 Rc=0)
+* divwo. RT,RA,RB (OE=1 Rc=1)
+
+Pseudo-code:
+
+ dividend[0:31] <- (RA)[32:63]
+ divisor[0:31] <- (RB) [32:63]
+ if (((dividend = 0x8000_0000) &
+ (divisor = [1]*32)) |
+ (divisor = [0]*32)) then
+ RT[0:63] <- undefined([0]*64)
+ overflow <- 1
+ else
+ RT[32:63] <- DIVS(dividend, divisor)
+ RT[0:31] <- undefined([0]*32)
+ overflow <- 0
+
+Special Registers Altered:
+
+ CR0 (bits 0:2 undefined in 64-bit mode) (if Rc=1)
+ SO OV OV32 (if OE=1)
+
+# Divide Word Unsigned
+
+XO-Form
+
+* divwu RT,RA,RB (OE=0 Rc=0)
+* divwu. RT,RA,RB (OE=0 Rc=1)
+* divwuo RT,RA,RB (OE=1 Rc=0)
+* divwuo. RT,RA,RB (OE=1 Rc=1)
+
+Pseudo-code:
+
+ dividend[0:31] <- (RA)[32:63]
+ divisor[0:31] <- (RB)[32:63]
+ if divisor != 0 then
+ RT[32:63] <- dividend / divisor
+ RT[0:31] <- undefined([0]*32)
+ overflow <- 0
+ else
+ RT[0:63] <- undefined([0]*64)
+ overflow <- 1
+
+Special Registers Altered:
+
+ CR0 (bits 0:2 undefined in 64-bit mode) (if Rc=1)
+ SO OV OV32 (if OE=1)
+
+# Divide Word Extended
+
+XO-Form
+
+* divwe RT,RA,RB (OE=0 Rc=0)
+* divwe. RT,RA,RB (OE=0 Rc=1)
+* divweo RT,RA,RB (OE=1 Rc=0)
+* divweo. RT,RA,RB (OE=1 Rc=1)
+
+Pseudo-code:
+
+ dividend[0:63] <- (RA)[32:63] || [0]*32
+ divisor[0:63] <- EXTS64((RB)[32:63])
+ if (((dividend = 0x8000_0000_0000_0000) &
+ (divisor = [1]*64)) |
+ (divisor = [0]*64)) then
+ overflow <- 1
+ else
+ result <- DIVS(dividend, divisor)
+ result32[0:63] <- EXTS64(result[32:63])
+ if (result32 = result) then
+ RT[32:63] <- result[32:63]
+ RT[0:31] <- undefined([0]*32)
+ overflow <- 0
+ else
+ overflow <- 1
+ if overflow = 1 then
+ RT[0:63] <- undefined([0]*64)
+
+Special Registers Altered:
+
+ CR0 (bits 0:2 undefined in 64-bit mode) (if Rc=1)
+ SO OV OV32 (if OE=1)
+
+# Divide Word Extended Unsigned
+
+XO-Form
+
+* divweu RT,RA,RB (OE=0 Rc=0)
+* divweu. RT,RA,RB (OE=0 Rc=1)
+* divweuo RT,RA,RB (OE=1 Rc=0)
+* divweuo. RT,RA,RB (OE=1 Rc=1)
+
+Pseudo-code:
+
+ dividend[0:63] <- (RA)[32:63] || [0]*32
+ divisor[0:63] <- [0]*32 || (RB)[32:63]
+ if (divisor = [0]*64) then
+ overflow <- 1
+ else
+ result <- dividend / divisor
+ if RA[32:63] <u RB[32:63] then
+ RT[32:63] <- result[32:63]
+ RT[0:31] <- undefined([0]*32)
+ overflow <- 0
+ else
+ overflow <- 1
+ if overflow = 1 then
+ RT[0:63] <- undefined([0]*64)
+
+Special Registers Altered:
+
+ CR0 (bits 0:2 undefined in 64-bit mode) (if Rc=1)
+ SO OV OV32 (if OE=1)
+
+# Modulo Signed Word
+
+X-Form
+
+* modsw RT,RA,RB
+
+Pseudo-code:
+
+ dividend[0:31] <- (RA)[32:63]
+ divisor[0:31] <- (RB)[32:63]
+ if (((dividend = 0x8000_0000) &
+ (divisor = [1]*32)) |
+ (divisor = [0]*32)) then
+ RT[0:63] <- undefined([0]*64)
+ overflow <- 1
+ else
+ RT[0:63] <- EXTS64(MODS(dividend, divisor))
+ RT[0:31] <- undefined(RT[0:31])
+ overflow <- 0
+
+Special Registers Altered:
+
+ None
+
+# Modulo Unsigned Word
+
+X-Form
+
+* moduw RT,RA,RB
+
+Pseudo-code:
+
+ dividend[0:31] <- (RA) [32:63]
+ divisor [0:31] <- (RB) [32:63]
+ if divisor = [0]*32 then
+ RT[0:63] <- undefined([0]*64)
+ overflow <- 1
+ else
+ RT[32:63] <- dividend % divisor
+ RT[0:31] <- undefined([0]*32)
+ overflow <- 0
+
+Special Registers Altered:
+
+ None
+
+# Deliver A Random Number
+
+X-Form
+
+* darn RT,L3
+
+Pseudo-code:
+
+ RT <- random(L3)
+
+Special Registers Altered:
+
+ none
+
+# Multiply Low Doubleword
+
+XO-Form
+
+* mulld RT,RA,RB (OE=0 Rc=0)
+* mulld. RT,RA,RB (OE=0 Rc=1)
+* mulldo RT,RA,RB (OE=1 Rc=0)
+* mulldo. RT,RA,RB (OE=1 Rc=1)
+
+Pseudo-code:
+
+ prod[0:127] <- MULS((RA), (RB))
+ RT <- prod[64:127]
+ overflow <- ((prod[0:64] != [0]*65) &
+ (prod[0:64] != [1]*65))
+
+Special Registers Altered:
+
+ CR0 (if Rc=1)
+ SO OV OV32 (if OE=1)
+
+# Multiply High Doubleword
+
+XO-Form
+
+* mulhd RT,RA,RB (Rc=0)
+* mulhd. RT,RA,RB (Rc=1)
+
+Pseudo-code:
+
+ prod[0:127] <- MULS((RA), (RB))
+ RT <- prod[0:63]
+
+Special Registers Altered:
+
+ CR0 (if Rc=1)
+
+# Multiply High Doubleword Unsigned
+
+XO-Form
+
+* mulhdu RT,RA,RB (Rc=0)
+* mulhdu. RT,RA,RB (Rc=1)
+
+Pseudo-code:
+
+ prod[0:127] <- (RA) * (RB)
+ RT <- prod[0:63]
+
+Special Registers Altered:
+
+ CR0 (if Rc=1)
+
+# Multiply-Add High Doubleword VA-Form
+
+VA-Form
+
+* maddhd RT,RA.RB,RC
+
+Pseudo-code:
+
+ prod[0:127] <- MULS((RA), (RB))
+ sum[0:127] <- prod + EXTS(RC)
+ RT <- sum[0:63]
+
+Special Registers Altered:
+
+ None
+
+# Multiply-Add High Doubleword Unsigned
+
+VA-Form
+
+* maddhdu RT,RA.RB,RC
+
+Pseudo-code:
+
+ prod[0:127] <- (RA) * (RB)
+ sum[0:127] <- prod + EXTZ(RC)
+ RT <- sum[0:63]
+
+Special Registers Altered:
+
+ None
+
+# Multiply-Add Low Doubleword
+
+VA-Form
+
+* maddld RT,RA.RB,RC
+
+Pseudo-code:
+
+ prod[0:127] <- MULS((RA), (RB))
+ sum[0:127] <- prod + EXTS(RC)
+ RT <- sum[64:127]
+
+Special Registers Altered:
+
+ None
+
+# Divide Doubleword
+
+XO-Form
+
+* divd RT,RA,RB (OE=0 Rc=0)
+* divd. RT,RA,RB (OE=0 Rc=1)
+* divdo RT,RA,RB (OE=1 Rc=0)
+* divdo. RT,RA,RB (OE=1 Rc=1)
+
+Pseudo-code:
+
+ dividend[0:63] <- (RA)
+ divisor[0:63] <- (RB)
+ if (((dividend = 0x8000_0000_0000_0000) &
+ (divisor = [1]*64)) |
+ (divisor = [0]*64)) then
+ RT[0:63] <- undefined([0]*64)
+ overflow <- 1
+ else
+ RT <- DIVS(dividend, divisor)
+ overflow <- 0
+
+Special Registers Altered:
+
+ CR0 (if Rc=1)
+ SO OV OV32 (if OE=1)
+
+# Divide Doubleword Unsigned
+
+XO-Form
+
+* divdu RT,RA,RB (OE=0 Rc=0)
+* divdu. RT,RA,RB (OE=0 Rc=1)
+* divduo RT,RA,RB (OE=1 Rc=0)
+* divduo. RT,RA,RB (OE=1 Rc=1)
+
+Pseudo-code:
+
+ dividend[0:63] <- (RA)
+ divisor[0:63] <- (RB)
+ if (divisor = [0]*64) then
+ RT[0:63] <- undefined([0]*64)
+ overflow <- 1
+ else
+ RT <- dividend / divisor
+ overflow <- 0
+
+Special Registers Altered:
+
+ CR0 (if Rc=1)
+ SO OV OV32 (if OE=1)
+
+# Divide Doubleword Extended
+
+XO-Form
+
+* divde RT,RA,RB (OE=0 Rc=0)
+* divde. RT,RA,RB (OE=0 Rc=1)
+* divdeo RT,RA,RB (OE=1 Rc=0)
+* divdeo. RT,RA,RB (OE=1 Rc=1)
+
+Pseudo-code:
+
+ dividend[0:127] <- (RA) || [0]*64
+ divisor[0:127] <- EXTS128((RB))
+ if (((dividend = 0x8000_0000_0000_0000_0000_0000_0000_0000) &
+ (divisor = [1]*128)) |
+ (divisor = [0]*128)) then
+ overflow <- 1
+ else
+ result <- DIVS(dividend, divisor)
+ result64[0:127] <- EXTS128(result[64:127])
+ if (result64 = result) then
+ RT <- result[64:127]
+ overflow <- 0
+ else
+ overflow <- 1
+ if overflow = 1 then
+ RT[0:63] <- undefined([0]*64)
+
+Special Registers Altered:
+
+ CR0 (if Rc=1)
+ SO OV OV32 (if OE=1)
+
+# Divide Doubleword Extended Unsigned
+
+XO-Form
+
+* divdeu RT,RA,RB (OE=0 Rc=0)
+* divdeu. RT,RA,RB (OE=0 Rc=1)
+* divdeuo RT,RA,RB (OE=1 Rc=0)
+* divdeuo. RT,RA,RB (OE=1 Rc=1)
+
+Pseudo-code:
+
+ dividend[0:127] <- (RA) || [0]*64
+ divisor[0:127] <- [0]*64 || (RB)
+ if divisor = [0]*128 then
+ overflow <- 1
+ else
+ result <- dividend / divisor
+ if (RA) <u (RB) then
+ RT <- result[64:127]
+ overflow <- 0
+ else
+ overflow <- 1
+ if overflow = 1 then
+ RT[0:63] <- undefined([0]*64)
+
+Special Registers Altered:
+
+ CR0 (if Rc=1)
+ SO OV OV32 (if OE=1)
+
+# Modulo Signed Doubleword
+
+X-Form
+
+* modsd RT,RA,RB
+
+Pseudo-code:
+
+ dividend <- (RA)
+ divisor <- (RB)
+ if (((dividend = 0x8000_0000_0000_0000) &
+ (divisor = [1]*64)) |
+ (divisor = [0]*64)) then
+ RT[0:63] <- undefined([0]*64)
+ overflow <- 1
+ else
+ RT <- MODS(dividend, divisor)
+ overflow <- 0
+
+Special Registers Altered:
+
+ None
+
+# Modulo Unsigned Doubleword
+
+X-Form
+
+* modud RT,RA,RB
+
+Pseudo-code:
+
+ dividend <- (RA)
+ divisor <- (RB)
+ if (divisor = [0]*64) then
+ RT[0:63] <- undefined([0]*64)
+ overflow <- 1
+ else
+ RT <- dividend % divisor
+ overflow <- 0
+
+Special Registers Altered:
+
+ None
+
+<!-- Checked March 2021 -->
--- /dev/null
+<!-- Instructions here described in PowerISA Version 3.0 B Book 1 -->
+
+<!-- Section 4.4.1 Fixed-Point Load and Store Caching Inhibited Instructions. Pages 965 - 967 -->
+
+<!-- The storage accesses caused by the instructions described in this section are -->
+<!-- performed as though the specified storage location is Caching Inhibited and -->
+<!-- Guarded. The instructions can be executed only in hypervisor state. Software -->
+<!-- must ensure that the specified storage location is not in the caches. If the -->
+<!-- specified storage location is in a cache, the results are undefined. -->
+
+
+# Load Byte and Zero Caching Inhibited Indexed
+
+X-Form
+
+* lbzcix RT,RA,RB
+
+Pseudo-code:
+
+ b <- (RA|0)
+ EA <- b + (RB)
+ RT <- [0] * 56 || MEM(EA, 1)
+
+Special Registers Altered:
+
+ None
+
+# Load Halfword and Zero Caching Inhibited Indexed
+
+X-Form
+
+* lhzcix RT,RA,RB
+
+Pseudo-code:
+
+ b <- (RA|0)
+ EA <- b + (RB)
+ RT <- [0] * 48 || MEM(EA, 2)
+
+Special Registers Altered:
+
+ None
+
+# Load Word and Zero Caching Inhibited Indexed
+
+X-Form
+
+* lwzcix RT,RA,RB
+
+Pseudo-code:
+
+ b <- (RA|0)
+ EA <- b + (RB)
+ RT <- [0] * 32 || MEM(EA, 4)
+
+Special Registers Altered:
+
+ None
+
+# Load Doubleword Caching Inhibited Indexed
+
+X-Form
+
+* ldcix RT,RA,RB
+
+Pseudo-code:
+
+ b <- (RA|0)
+ EA <- b + (RB)
+ RT <- MEM(EA, 8)
+
+Special Registers Altered:
+
+ None
+
+# Store Byte Caching Inhibited Indexed
+
+X-Form
+
+* stbcix RS,RA,RB
+
+Pseudo-code:
+
+ b <- (RA|0)
+ EA <- b + (RB)
+ MEM(EA, 1) <- (RS)[56:63]
+
+Special Registers Altered:
+
+ None
+
+# Store Halfword Caching Inhibited Indexed
+
+X-Form
+
+* sthcix RS,RA,RB
+
+Pseudo-code:
+
+ b <- (RA|0)
+ EA <- b + (RB)
+ MEM(EA, 2) <- (RS)[48:63]
+
+Special Registers Altered:
+
+ None
+
+# Store Word Caching Inhibited Indexed
+
+X-Form
+
+* stwcix RS,RA,RB
+
+Pseudo-code:
+
+ b <- (RA|0)
+ EA <- b + (RB)
+ MEM(EA, 4) <- (RS)[32:63]
+
+Special Registers Altered:
+
+ None
+
+# Store Doubleword Caching Inhibited Indexed
+
+X-Form
+
+* stdcix RS,RA,RB
+
+Pseudo-code:
+
+ b <- (RA|0)
+ EA <- b + (RB)
+ MEM(EA, 8) <- (RS)
+
+Special Registers Altered:
+
+ None
+
+<!-- Checked March 2021 -->
--- /dev/null
+<!-- This defines instructions described in PowerISA Version 3.0 B Book 1 -->
+
+<!-- This defines instructions that load from RAM to a register -->
+
+<!-- Note that these pages also define equivalent store instructions, -->
+<!-- these are described in fixedstore.mdwn -->
+
+<!-- Section 3.3.2 This defines the Fixed-Point Load Instructions pages 47 - 53 -->
+<!-- Section 3.3.3 Fixed-Point Store Instructions pages 54 - 56 -->
+<!-- Section 3.3.3.1 64-bit Fixed-Point Store Instructions pages 57 -->
+<!-- Section 3.3.4 Fixed Point Load and Store Quadword Instructions pages 58 - 59 -->
+<!-- Section 3.3.5 Fixed-Point Load and Store with Byte Reversal Instructions page 60 -->
+<!-- Section 3.3.5.1 64-Bit Load and Store with Byte Reversal Instructions page 61 -->
+<!-- Section 3.3.6 Fixed-Point Load and Store Multiple Instructions page 62 -->
+
+
+
+<!-- Section 3.3.2 This defines the Fixed-Point Load Instructions pages 47 - 53 -->
+
+<!-- The byte, halfword, word, or doubleword in storage addressed by EA is loaded -->
+<!-- into register RT. -->
+
+<!-- Many of the Load instructions have an “update” form, in which register RA is -->
+<!-- updated with the effective address. For these forms, if RA!=0 and RA!=RT, the -->
+<!-- effective address is placed into register RA and the storage element (byte, -->
+<!-- halfword, word, or doubleword) addressed by EA is loaded into RT. -->
+
+
+# Load Byte and Zero
+
+D-Form
+
+* lbz RT,D(RA)
+
+Pseudo-code:
+
+ b <- (RA|0)
+ EA <- b + EXTS(D)
+ RT <- [0]*56 || MEM(EA, 1)
+
+Special Registers Altered:
+
+ None
+
+# Load Byte and Zero Indexed
+
+X-Form
+
+* lbzx RT,RA,RB
+
+Pseudo-code:
+
+ b <- (RA|0)
+ EA <- b + (RB)
+ RT <- [0] * 56 || MEM(EA, 1)
+
+Special Registers Altered:
+
+ None
+
+# Load Byte and Zero with Update
+
+D-Form
+
+* lbzu RT,D(RA)
+
+Pseudo-code:
+
+ EA <- (RA) + EXTS(D)
+ RT <- [0] * 56 || MEM(EA, 1)
+ RA <- EA
+
+Special Registers Altered:
+
+ None
+
+# Load Byte and Zero with Update Indexed
+
+X-Form
+
+* lbzux RT,RA,RB
+
+Pseudo-code:
+
+ EA <- (RA) + (RB)
+ RT <- [0] * 56 || MEM(EA, 1)
+ RA <- EA
+
+Special Registers Altered:
+
+ None
+
+# Load Halfword and Zero
+
+D-Form
+
+* lhz RT,D(RA)
+
+Pseudo-code:
+
+ b <- (RA|0)
+ EA <- b + EXTS(D)
+ RT <- [0] * 48 || MEM(EA, 2)
+
+Special Registers Altered:
+
+ None
+
+# Load Halfword and Zero Indexed
+
+X-Form
+
+* lhzx RT,RA,RB
+
+Pseudo-code:
+
+ b <- (RA|0)
+ EA <- b + (RB)
+ RT <- [0] * 48 || MEM(EA, 2)
+
+Special Registers Altered:
+
+ None
+
+# Load Halfword and Zero with Update
+
+D-Form
+
+* lhzu RT,D(RA)
+
+Pseudo-code:
+
+ EA <- (RA) + EXTS(D)
+ RT <- [0] * 48 || MEM(EA, 2)
+ RA <- EA
+
+Special Registers Altered:
+
+ None
+
+# Load Halfword and Zero with Update Indexed
+
+X-Form
+
+* lhzux RT,RA,RB
+
+Pseudo-code:
+
+ EA <- (RA) + (RB)
+ RT <- [0] * 48 || MEM(EA, 2)
+ RA <- EA
+
+Special Registers Altered:
+
+ None
+
+# Load Halfword Algebraic
+
+D-Form
+
+* lha RT,D(RA)
+
+Pseudo-code:
+
+ b <- (RA|0)
+ EA <- b + EXTS(D)
+ RT <- EXTS(MEM(EA, 2))
+
+Special Registers Altered:
+
+ None
+
+# Load Halfword Algebraic Indexed
+
+X-Form
+
+* lhax RT,RA,RB
+
+Pseudo-code:
+
+ b <- (RA|0)
+ EA <- b + (RB)
+ RT <- EXTS(MEM(EA, 2))
+
+Special Registers Altered:
+
+ None
+
+# Load Halfword Algebraic with Update
+
+D-Form
+
+* lhau RT,D(RA)
+
+Pseudo-code:
+
+ EA <- (RA) + EXTS(D)
+ RT <- EXTS(MEM(EA, 2))
+ RA <- EA
+
+Special Registers Altered:
+
+ None
+
+# Load Halfword Algebraic with Update Indexed
+
+X-Form
+
+* lhaux RT,RA,RB
+
+Pseudo-code:
+
+ EA <- (RA) + (RB)
+ RT <- EXTS(MEM(EA, 2))
+ RA <- EA
+
+Special Registers Altered:
+
+ None
+
+# Load Word and Zero
+
+D-Form
+
+* lwz RT,D(RA)
+
+Pseudo-code:
+
+ b <- (RA|0)
+ EA <- b + EXTS(D)
+ RT <- [0] * 32 || MEM(EA, 4)
+
+Special Registers Altered:
+
+ None
+
+# Load Word and Zero Indexed
+
+X-Form
+
+* lwzx RT,RA,RB
+
+Pseudo-code:
+
+ b <- (RA|0)
+ EA <- b + (RB)
+ RT <- [0] * 32 || MEM(EA, 4)
+
+Special Registers Altered:
+
+ None
+
+# Load Word and Zero with Update
+
+D-Form
+
+* lwzu RT,D(RA)
+
+Pseudo-code:
+
+ EA <- (RA) + EXTS(D)
+ RT <- [0]*32 || MEM(EA, 4)
+ RA <- EA
+
+Special Registers Altered:
+
+ None
+
+# Load Word and Zero with Update Indexed
+
+X-Form
+
+* lwzux RT,RA,RB
+
+Pseudo-code:
+
+ EA <- (RA) + (RB)
+ RT <- [0] * 32 || MEM(EA, 4)
+ RA <- EA
+
+Special Registers Altered:
+
+ None
+
+# Load Word Algebraic
+
+DS-Form
+
+* lwa RT,DS(RA)
+
+Pseudo-code:
+
+ b <- (RA|0)
+ EA <- b + EXTS(DS || 0b00)
+ RT <- EXTS(MEM(EA, 4))
+
+Special Registers Altered:
+
+ None
+
+# Load Word Algebraic Indexed
+
+X-Form
+
+* lwax RT,RA,RB
+
+Pseudo-code:
+
+ b <- (RA|0)
+ EA <- b + (RB)
+ RT <- EXTS(MEM(EA, 4))
+
+Special Registers Altered:
+
+ None
+
+# Load Word Algebraic with Update Indexed
+
+X-Form
+
+* lwaux RT,RA,RB
+
+Pseudo-code:
+
+ EA <- (RA) + (RB)
+ RT <- EXTS(MEM(EA, 4))
+ RA <- EA
+
+Special Registers Altered:
+
+ None
+
+# Load Doubleword
+
+DS-Form
+
+* ld RT,DS(RA)
+
+Pseudo-code:
+
+ b <- (RA|0)
+ EA <- b + EXTS(DS || 0b00)
+ RT <- MEM(EA, 8)
+
+Special Registers Altered:
+
+ None
+
+# Load Doubleword Indexed
+
+X-Form
+
+* ldx RT,RA,RB
+
+Pseudo-code:
+
+ b <- (RA|0)
+ EA <- b + (RB)
+ RT <- MEM(EA, 8)
+
+Special Registers Altered:
+
+ None
+
+# Load Doubleword with Update Indexed
+
+DS-Form
+
+* ldu RT,DS(RA)
+
+Pseudo-code:
+
+ EA <- (RA) + EXTS(DS || 0b00)
+ RT <- MEM(EA, 8)
+ RA <- EA
+
+Special Registers Altered:
+
+ None
+
+# Load Doubleword with Update Indexed
+
+X-Form
+
+* ldux RT,RA,RB
+
+Pseudo-code:
+
+ EA <- (RA) + (RB)
+ RT <- MEM(EA, 8)
+ RA <- EA
+
+Special Registers Altered:
+
+ None
+
+<!-- Section 3.3.3 Fixed-Point Store Instructions pages 54 - 56 -->
+
+<!-- The contents of register RS are stored into the byte, halfword, word, or -->
+<!-- doubleword in storage addressed by EA. -->
+
+<!-- Many of the Store instructions have an “update” form, in which register RA is -->
+<!-- updated with the effective address. For these forms, the following rules apply. -->
+
+<!-- If RA!=0, the effective address is placed into register RA. -->
+
+<!-- If RS=RA, the contents of register RS are copied to the target storage element -->
+<!-- and then EA is placed into RA (RS). -->
+
+<!-- Section 3.3.3.1 64-bit Fixed-Point Store Instructions pages 57 -->
+
+<!-- Section 3.3.4 Fixed Point Load and Store Quadword Instructions pages 58 - 59 -->
+
+<!-- For lq, the quadword in storage addressed by EA is loaded into an even-odd pair -->
+<!-- of GPRs as follows. In Big-Endian mode, the even-numbered GPR is loaded with -->
+<!-- the doubleword from storage addressed by EA and the odd-numbered GPR is loaded -->
+<!-- with the doubleword addressed by EA+8. In Little-Endian mode, the even-numbered -->
+<!-- GPR is loaded with the byte-reversed doubleword from storage addressed by EA+8 -->
+<!-- and the odd-numbered GPR is loaded with the byte-reversed doubleword addressed -->
+<!-- by EA. -->
+
+# Load Quadword
+
+DQ-Form
+
+* lq RTp,DQ(RA)
+
+Pseudo-code:
+
+ b <- (RA|0)
+ EA <- b + EXTS(DQ || 0b0000)
+ RTp <- MEM(EA, 16)
+
+Special Registers Altered:
+
+ None
+
+<!-- MISSING stq -->
+
+<!-- Section 3.3.5 Fixed-Point Load and Store with Byte Reversal Instructions page 60 -->
+
+# Load Halfword Byte-Reverse Indexed
+
+X-Form
+
+* lhbrx RT,RA,RB
+
+Pseudo-code:
+
+ b <- (RA|0)
+ EA <- b + (RB)
+ load_data <- MEM(EA, 2)
+ RT <- [0]*48 || load_data[8:15] || load_data[0:7]
+
+Special Registers Altered:
+
+ None
+
+<!-- MISSING sthbrx -->
+
+# Load Word Byte-Reverse Indexed
+
+X-Form
+
+* lwbrx RT,RA,RB
+
+Pseudo-code:
+
+ b <- (RA|0)
+ EA <- b + (RB)
+ load_data <- MEM(EA, 4)
+ RT <- ([0] * 32 || load_data[24:31] || load_data[16:23]
+ || load_data[8:15] || load_data[0:7])
+
+Special Registers Altered:
+
+ None
+
+<!-- MISSING stwbrx -->
+
+
+<!-- Section 3.3.5.1 64-Bit Load and Store with Byte Reversal Instructions page 61 -->
+
+# Load Doubleword Byte-Reverse Indexed
+
+X-Form
+
+* ldbrx RT,RA,RB
+
+Pseudo-code:
+
+ b <- (RA|0)
+ EA <- b + (RB)
+ load_data <- MEM(EA, 8)
+ RT <- (load_data[56:63] || load_data[48:55]
+ || load_data[40:47] || load_data[32:39]
+ || load_data[24:31] || load_data[16:23]
+ || load_data[8:15] || load_data[0:7])
+
+Special Registers Altered:
+
+ None
+
+<!-- MISSING stdbrx -->
+
+<!-- Section 3.3.6 Fixed-Point Load and Store Multiple Instructions page 62 -->
+
+# Load Multiple Word
+
+DQ-Form
+
+* lmw RT,D(RA)
+
+Pseudo-code:
+
+ b <- (RA|0)
+ EA <- b + EXTS(D)
+ r <- RT
+ do while r <= 31
+ GPR(r) <- [0]*32 || MEM(EA, 4)
+ r <- r + 1
+ EA <- EA + 4
+
+Special Registers Altered:
+
+ None
+
+<!-- MISSING stmw -->
+
+
--- /dev/null
+<!-- This defines instructions described in PowerISA Version 3.0 B Book 1 -->
+
+<!-- Section 3.3.13 Fixed-Point Logical Instructions page 92 - 100 -->
+
+<!-- The Logical instructions perform bit-parallel operations on 64-bit operands. -->
+
+<!-- The X-form Logical instructions with Rc=1, and the D-form Logical instructions -->
+<!-- andi. and andis., set the first three bits of CR Field 0 as described in -->
+<!-- Section 3.3.8, “Other Fixed-Point Instructions” on page 66. The Logical -->
+<!-- instructions do not change the SO, OV, OV32, CA, and CA32 bits in the XER. -->
+
+
+# AND Immediate
+
+D-Form
+
+* andi. RA,RS,UI
+
+Pseudo-code:
+
+ RA <- (RS) & ([0]*48 || UI)
+
+Special Registers Altered:
+
+ CR0
+
+# OR Immediate
+
+D-Form
+
+* ori RA,RS,UI
+
+Pseudo-code:
+
+ RA <- (RS) | ([0]*48 || UI)
+
+Special Registers Altered:
+
+ None
+
+# AND Immediate Shifted
+
+D-Form
+
+* andis. RA,RS,UI
+
+Pseudo-code:
+
+ RA <- (RS) & ([0]*32 || UI || [0]*16)
+
+Special Registers Altered:
+
+ CR0
+
+# OR Immediate Shifted
+
+D-Form
+
+* oris RA,RS,UI
+
+Pseudo-code:
+
+ RA <- (RS) | ([0]*32 || UI || [0]*16)
+
+Special Registers Altered:
+
+ None
+
+# XOR Immediate Shifted
+
+D-Form
+
+* xoris RA,RS,UI
+
+Pseudo-code:
+
+ RA <- (RS) ^ ([0]*32 || UI || [0]*16)
+
+Special Registers Altered:
+
+ None
+
+# XOR Immediate
+
+D-Form
+
+* xori RA,RS,UI
+
+Pseudo-code:
+
+ RA <- (RS) ^ ([0]*48 || UI)
+
+Special Registers Altered:
+
+ None
+
+# AND
+
+X-Form
+
+* and RA,RS,RB (Rc=0)
+* and. RA,RS,RB (Rc=1)
+
+Pseudo-code:
+
+ RA <- (RS) & (RB)
+
+Special Registers Altered:
+
+ CR0 (if Rc=1)
+
+# OR
+
+X-Form
+
+* or RA,RS,RB (Rc=0)
+* or. RA,RS,RB (Rc=1)
+
+Pseudo-code:
+
+ RA <- (RS) | (RB)
+
+Special Registers Altered:
+
+ CR0 (if Rc=1)
+
+# XOR
+
+X-Form
+
+* xor RA,RS,RB (Rc=0)
+* xor. RA,RS,RB (Rc=1)
+
+Pseudo-code:
+
+ RA <- (RS) ^ (RB)
+
+Special Registers Altered:
+
+ CR0 (if Rc=1)
+
+# NAND
+
+X-Form
+
+* nand RA,RS,RB (Rc=0)
+* nand. RA,RS,RB (Rc=1)
+
+Pseudo-code:
+
+ RA <- ¬((RS) & (RB))
+
+Special Registers Altered:
+
+ CR0 (if Rc=1)
+
+# NOR
+
+X-Form
+
+* nor RA,RS,RB (Rc=0)
+* nor. RA,RS,RB (Rc=1)
+
+Pseudo-code:
+
+ RA <- ¬((RS) | (RB))
+
+Special Registers Altered:
+
+ CR0 (if Rc=1)
+
+# Equivalent
+
+X-Form
+
+* eqv RA,RS,RB (Rc=0)
+* eqv. RA,RS,RB (Rc=1)
+
+Pseudo-code:
+
+ RA <- ¬((RS) ^ (RB))
+
+Special Registers Altered:
+
+ CR0 (if Rc=1)
+
+# AND with Complement
+
+X-Form
+
+* andc RA,RS,RB (Rc=0)
+* andc. RA,RS,RB (Rc=1)
+
+Pseudo-code:
+
+ RA <- (RS) & ¬(RB)
+
+Special Registers Altered:
+
+ CR0 (if Rc=1)
+
+# OR with Complement
+
+X-Form
+
+* orc RA,RS,RB (Rc=0)
+* orc. RA,RS,RB (Rc=1)
+
+Pseudo-code:
+
+ RA <- (RS) | ¬(RB)
+
+Special Registers Altered:
+
+ CR0 (if Rc=1)
+
+# Extend Sign Byte
+
+X-Form
+
+* extsb RA,RS (Rc=0)
+* extsb. RA,RS (Rc=1)
+
+Pseudo-code:
+
+ s <- (RS)[56]
+ RA[56:63] <- (RS)[56:63]
+ RA[0:55] <- [s]*56
+
+Special Registers Altered:
+
+ CR0 (if Rc=1)
+
+# Extend Sign Halfword
+
+X-Form
+
+* extsh RA,RS (Rc=0)
+* extsh. RA,RS (Rc=1)
+
+Pseudo-code:
+
+ s <- (RS)[48]
+ RA[48:63] <- (RS)[48:63]
+ RA[0:47] <- [s]*48
+
+Special Registers Altered:
+
+ CR0 (if Rc=1)
+
+# Count Leading Zeros Word
+
+X-Form
+
+* cntlzw RA,RS (Rc=0)
+* cntlzw. RA,RS (Rc=1)
+
+Pseudo-code:
+
+ n <- 32
+ do while n < 64
+ if (RS)[n] = 1 then
+ leave
+ n <- n + 1
+ RA <- n - 32
+
+Special Registers Altered:
+
+ CR0 (if Rc=1)
+
+# Count Trailing Zeros Word
+
+X-Form
+
+* cnttzw RA,RS (Rc=0)
+* cnttzw. RA,RS (Rc=1)
+
+Pseudo-code:
+
+ n <- 0
+ do while n < 32
+ if (RS)[63-n] = 0b1 then
+ leave
+ n <- n + 1
+ RA <- EXTZ64(n)
+
+Special Registers Altered:
+
+ CR0 (if Rc=1)
+
+# Compare Bytes
+
+X-Form
+
+* cmpb RA,RS,RB
+
+Pseudo-code:
+
+ do n = 0 to 7
+ if RS[8*n:8* n+7] = (RB)[8*n:8*n+7] then
+ RA[8*n:8* n+7] <- [1]*8
+ else
+ RA[8*n:8* n+7] <- [0]*8
+
+Special Registers Altered:
+
+ None
+
+# Population Count Bytes
+
+X-Form
+
+* popcntb RA, RS
+
+Pseudo-code:
+
+ do i = 0 to 7
+ n <- 0
+ do j = 0 to 7
+ if (RS)[(i*8)+j] = 1 then
+ n <- n+1
+ RA[(i*8):(i*8)+7] <- n
+
+Special Registers Altered:
+
+ None
+
+# Population Count Words
+
+X-Form
+
+* popcntw RA, RS
+
+Pseudo-code:
+
+ do i = 0 to 1
+ n <- 0
+ do j = 0 to 31
+ if (RS)[(i*32)+j] = 1 then
+ n <- n+1
+ RA[(i*32):(i*32)+31] <- n
+
+Special Registers Altered:
+
+ None
+
+# Parity Doubleword
+
+X-Form
+
+* prtyd RA,RS
+
+Pseudo-code:
+
+ s <- 0
+ do i = 0 to 7
+ s <- s ^ (RS)[i*8+7]
+ RA <- [0] * 63 || s
+
+Special Registers Altered:
+
+ None
+
+# Parity Word
+
+X-Form
+
+* prtyw RA,RS
+
+Pseudo-code:
+
+ s <- 0
+ t <- 0
+ do i = 0 to 3
+ s <- s ^ (RS)[i*8+7]
+ do i = 4 to 7
+ t <- t ^ (RS)[i*8+7]
+ RA[0:31] <- [0]*31 || s
+ RA[32:63] <- [0]*31 || t
+
+Special Registers Altered:
+
+ None
+
+# Extend Sign Word
+
+X-Form
+
+* extsw RA,RS (Rc=0)
+* extsw. RA,RS (Rc=1)
+
+Pseudo-code:
+
+ s <- (RS)[32]
+ RA[32:63] <- (RS)[32:63]
+ RA[0:31] <- [s]*32
+
+Special Registers Altered:
+
+ CR0 (if Rc=1)
+
+# Population Count Doubleword
+
+X-Form
+
+* popcntd RA, RS
+
+Pseudo-code:
+
+ n <- 0
+ do i = 0 to 63
+ if (RS)[i] = 1 then
+ n <- n+1
+ RA <- n
+
+Special Registers Altered:
+
+ None
+
+# Count Leading Zeros Doubleword
+
+X-Form
+
+* cntlzd RA,RS (Rc=0)
+* cntlzd. RA,RS (Rc=1)
+
+Pseudo-code:
+
+ n <- 0
+ do while n < 64
+ if (RS)[n] = 1 then
+ leave
+ n <- n + 1
+ RA <- n
+
+Special Registers Altered:
+
+ CR0 (if Rc=1)
+
+# Count Trailing Zeros Doubleword
+
+X-Form
+
+* cnttzd RA,RS (Rc=0)
+* cnttzd. RA,RS (Rc=1)
+
+Pseudo-code:
+
+ n <- 0
+ do while n < 64
+ if (RS)[63-n] = 0b1 then
+ leave
+ n <- n + 1
+ RA <- EXTZ64(n)
+
+Special Registers Altered:
+
+ CR0 (if Rc=1)
+
+# Bit Permute Doubleword
+
+X-Form
+
+* bpermd RA,RS,RB]
+
+Pseudo-code:
+
+ perm <- [0] * 8
+ for i = 0 to 7
+ index <- (RS)[8*i:8*i+7]
+ if index < 64 then
+ perm[i] <- (RB)[index]
+ else
+ perm[i] <- 0
+ RA <- [0]*56 || perm[0:7]
+
+Special Registers Altered:
+
+ None
+
+<!-- Checked March 2021 -->
--- /dev/null
+<!-- This defines instructions described in PowerISA Version 3.0 B Book 1 -->
+
+<!-- Section 3.3.14 Fixed-Point Rotate and Shift Instructions pages 101 - 110 -->
+<!-- Section 3.3.14.1 Fixed-Point Rotate Instructions pages 101 - 106 -->
+<!-- Section 3.3.14.2 Fixed-Point Shift Instructions pages 107 - 110 -->
+
+<!-- The Fixed-Point Facility performs rotation operations on data from a GPR and -->
+<!-- returns the result, or a portion of the result, to a GPR. -->
+
+
+<!-- Section 3.3.14.1 Fixed-Point Rotate Instructions pages 101 - 106 -->
+
+# Rotate Left Word Immediate then AND with Mask
+
+M-Form
+
+* rlwinm RA,RS,SH,MB,ME (Rc=0)
+* rlwinm. RA,RS,SH,MB,ME (Rc=1)
+
+Pseudo-code:
+
+ n <- SH
+ r <- ROTL32((RS)[32:63], n)
+ m <- MASK(MB+32, ME+32)
+ RA <- r & m
+
+Special Registers Altered:
+
+ CR0 (if Rc=1)
+
+# Rotate Left Word then AND with Mask
+
+M-Form
+
+* rlwnm RA,RS,RB,MB,ME (Rc=0)
+* rlwnm. RA,RS,RB,MB,ME (Rc=1)
+
+Pseudo-code:
+
+ n <- (RB)[59:63]
+ r <- ROTL32((RS)[32:63], n)
+ m <- MASK(MB+32, ME+32)
+ RA <- r & m
+
+Special Registers Altered:
+
+ CR0 (if Rc=1)
+
+# Rotate Left Word Immediate then Mask Insert
+
+M-Form
+
+* rlwimi RA,RS,SH,MB,ME (Rc=0)
+* rlwimi. RA,RS,SH,MB,ME (Rc=1)
+
+Pseudo-code:
+
+ n <- SH
+ r <- ROTL32((RS)[32:63], n)
+ m <- MASK(MB+32, ME+32)
+ RA <- r&m | (RA) & ¬m
+
+Special Registers Altered:
+
+ CR0 (if Rc=1)
+
+# Rotate Left Doubleword Immediate then Clear Left
+
+MD-Form
+
+* rldicl RA,RS,SH,MB (Rc=0)
+* rldicl. RA,RS,SH,MB (Rc=1)
+
+Pseudo-code:
+
+ n <- sh
+ r <- ROTL64((RS), n)
+ b <- mb[5] || mb[0:4]
+ m <- MASK(b, 63)
+ RA <- r & m
+
+Special Registers Altered:
+
+ CR0 (if Rc=1)
+
+# Rotate Left Doubleword Immediate then Clear Right
+
+MD-Form
+
+* rldicr RA,RS,SH,ME (Rc=0)
+* rldicr. RA,RS,SH,ME (Rc=1)
+
+Pseudo-code:
+
+ n <- sh
+ r <- ROTL64((RS), n)
+ e <- me[5] || me[0:4]
+ m <- MASK(0, e)
+ RA <- r & m
+
+Special Registers Altered:
+
+ CR0 (if Rc=1)
+
+# Rotate Left Doubleword Immediate then Clear
+
+MD-Form
+
+* rldic RA,RS,SH,MB (Rc=0)
+* rldic. RA,RS,SH,MB (Rc=1)
+
+Pseudo-code:
+
+ n <- sh
+ r <- ROTL64((RS), n)
+ b <- mb[5] || mb[0:4]
+ m <- MASK(b, ¬n)
+ RA <- r & m
+
+Special Registers Altered:
+
+ CR0 (if Rc=1)
+
+# Rotate Left Doubleword then Clear Left
+
+MDS-Form
+
+* rldcl RA,RS,RB,MB (Rc=0)
+* rldcl. RA,RS,RB,MB (Rc=1)
+
+Pseudo-code:
+
+ n <- (RB)[58:63]
+ r <- ROTL64((RS), n)
+ b <- mb[5] || mb[0:4]
+ m <- MASK(b, 63)
+ RA <- r & m
+
+Special Registers Altered:
+
+ CR0 (if Rc=1)
+
+# Rotate Left Doubleword then Clear Right
+
+MDS-Form
+
+* rldcr RA,RS,RB,ME (Rc=0)
+* rldcr. RA,RS,RB,ME (Rc=1)
+
+Pseudo-code:
+
+ n <- (RB)[58:63]
+ r <- ROTL64((RS), n)
+ e <- me[5] || me[0:4]
+ m <- MASK(0, e)
+ RA <- r & m
+
+Special Registers Altered:
+
+ CR0 (if Rc=1)
+
+# Rotate Left Doubleword Immediate then Mask Insert
+
+MD-Form
+
+* rldimi RA,RS,SH,MB (Rc=0)
+* rldimi. RA,RS,SH,MB (Rc=1)
+
+Pseudo-code:
+
+ n <- sh
+ r <- ROTL64((RS), n)
+ b <- mb[5] || mb[0:4]
+ m <- MASK(b, ¬n)
+ RA <- r&m | (RA)& ¬m
+
+Special Registers Altered:
+
+ CR0 (if Rc=1)
+
+
+<!-- Section 3.3.14.2 Fixed-Point Shift Instructions pages 107 - 110 -->
+
+# Shift Left Word
+
+X-Form
+
+* slw RA,RS,RB (Rc=0)
+* slw. RA,RS,RB (Rc=1)
+
+Pseudo-code:
+
+ n <- (RB)[59:63]
+ r <- ROTL32((RS)[32:63], n)
+ if (RB)[58] = 0 then
+ m <- MASK(32, 63-n)
+ else m <- [0]*64
+ RA <- r & m
+
+Special Registers Altered:
+
+ CR0 (if Rc=1)
+
+# Shift Right Word
+
+X-Form
+
+* srw RA,RS,RB (Rc=0)
+* srw. RA,RS,RB (Rc=1)
+
+Pseudo-code:
+
+ n <- (RB)[59:63]
+ r <- ROTL32((RS)[32:63], 64-n)
+ if (RB)[58] = 0 then
+ m <- MASK(n+32, 63)
+ else m <- [0]*64
+ RA <- r & m
+
+Special Registers Altered:
+
+ CR0 (if Rc=1)
+
+# Shift Right Algebraic Word Immediate
+
+X-Form
+
+* srawi RA,RS,SH (Rc=0)
+* srawi. RA,RS,SH (Rc=1)
+
+Pseudo-code:
+
+ n <- SH
+ r <- ROTL32((RS)[32:63], 64-n)
+ m <- MASK(n+32, 63)
+ s <- (RS)[32]
+ RA <- r&m | ([s]*64)& ¬m
+ carry <- s & ((r&¬m)[32:63] != 0)
+ CA <- carry
+ CA32 <- carry
+
+Special Registers Altered:
+
+ CA CA32
+ CR0 (if Rc=1)
+
+# Shift Right Algebraic Word
+
+X-Form
+
+* sraw RA,RS,RB (Rc=0)
+* sraw. RA,RS,RB (Rc=1)
+
+Pseudo-code:
+
+ n <- (RB)[59:63]
+ r <- ROTL32((RS)[32:63], 64-n)
+ if (RB)[58] = 0 then
+ m <- MASK(n+32, 63)
+ else m <- [0]*64
+ s <- (RS)[32]
+ RA <- r&m | ([s]*64)& ¬m
+ carry <- s & ((r&¬m)[32:63] != 0)
+ CA <- carry
+ CA32 <- carry
+
+Special Registers Altered:
+
+ CA CA32
+ CR0 (if Rc=1)
+
+# Shift Left Doubleword
+
+X-Form
+
+* sld RA,RS,RB (Rc=0)
+* sld. RA,RS,RB (Rc=1)
+
+Pseudo-code:
+
+ n <- (RB)[58:63]
+ r <- ROTL64((RS), n)
+ if (RB)[57] = 0 then
+ m <- MASK(0, 63-n)
+ else m <- [0]*64
+ RA <- r & m
+
+Special Registers Altered:
+
+ CR0 (if Rc=1)
+
+# Shift Right Doubleword
+
+X-Form
+
+* srd RA,RS,RB (Rc=0)
+* srd. RA,RS,RB (Rc=1)
+
+Pseudo-code:
+
+ n <- (RB)[58:63]
+ r <- ROTL64((RS), 64-n)
+ if (RB)[57] = 0 then
+ m <- MASK(n, 63)
+ else m <- [0]*64
+ RA <- r & m
+
+Special Registers Altered:
+
+ CR0 (if Rc=1)
+
+# Shift Right Algebraic Doubleword Immediate
+
+XS-Form
+
+* sradi RA,RS,SH (Rc=0)
+* sradi. RA,RS,SH (Rc=1)
+
+Pseudo-code:
+
+ n <- sh
+ r <- ROTL64((RS), 64-n)
+ m <- MASK(n, 63)
+ s <- (RS)[0]
+ RA <- r&m | ([s]*64)& ¬m
+ carry <- s & ((r& ¬m) != 0)
+ CA <- carry
+ CA32 <- carry
+
+Special Registers Altered:
+
+ CA CA32
+ CR0 (if Rc=1)
+
+# Shift Right Algebraic Doubleword
+
+X-Form
+
+* srad RA,RS,RB (Rc=0)
+* srad. RA,RS,RB (Rc=1)
+
+Pseudo-code:
+
+ n <- (RB)[58:63]
+ r <- ROTL64((RS), 64-n)
+ if (RB)[57] = 0 then
+ m <- MASK(n, 63)
+ else m <- [0]*64
+ s <- (RS)[0]
+ RA <- r&m | ([s]*64)& ¬m
+ carry <- s & ((r&¬m) != 0)
+ CA <- carry
+ CA32 <- carry
+
+Special Registers Altered:
+
+ CA CA32
+ CR0 (if Rc=1)
+
+# Extend-Sign Word and Shift Left Immediate
+
+XS-Form
+
+* extswsli RA,RS,SH (Rc=0)
+* extswsli. RA,RS,SH (Rc=1)
+
+Pseudo-code:
+
+ n <- sh
+ r <- ROTL64(EXTS64(RS[32:63]), n)
+ m <- MASK(0, 63-n)
+ RA <- r & m
+
+Special Registers Altered:
+
+ CR0 (if Rc=1)
+
+<!-- Checked March 2021 -->
--- /dev/null
+<!-- This defines instructions described in PowerISA Version 3.0 B Book 1 -->
+
+<!-- This defines instructions that store from a register to RAM -->
+
+<!-- Note that these pages also define equivalent load instructions, -->
+<!-- these are described in fixedload.mdwn -->
+
+<!-- Section 3.3.3 Fixed-Point Store Instructions pages 54 - 57 -->
+<!-- Section 3.3.3.1 64-bit Fixed-Point Store Instructions page 57 -->
+<!-- Section 3.3.4 Fixed Point Load and Store Quadword Instructions pages 58 - 59 -->
+<!-- Section 3.3.5 Fixed-Point Load and Store with Byte Reversal Instructions page 60 -->
+<!-- Section 3.3.5.1 64-Bit Load and Store with Byte Reversal Instructions page 61 -->
+<!-- Section 3.3.6 Fixed-Point Load and Store Multiple Instructions page 62 -->
+
+<!-- MISSING stbh -->
+<!-- MISSING stbhx -->
+<!-- MISSING stbhu -->
+<!-- MISSING stbhux -->
+<!-- MISSING stbw -->
+<!-- MISSING stbwx -->
+<!-- MISSING stbwu -->
+<!-- MISSING stbwux -->
+
+<!-- Section 3.3.3 Fixed-Point Store Instructions pages 54 - 57 -->
+
+# Store Byte
+
+D-Form
+
+* stb RS,D(RA)
+
+Pseudo-code:
+
+ b <- (RA|0)
+ EA <- b + EXTS(D)
+ MEM(EA, 1) <- (RS)[56:63]
+
+Special Registers Altered:
+
+ None
+
+# Store Byte Indexed
+
+X-Form
+
+* stbx RS,RA,RB
+
+Pseudo-code:
+
+ b <- (RA|0)
+ EA <- b + (RB)
+ MEM(EA, 1) <- (RS)[56:63]
+
+Special Registers Altered:
+
+ None
+
+# Store Byte with Update
+
+D-Form
+
+* stbu RS,D(RA)
+
+Pseudo-code:
+
+ EA <- (RA) + EXTS(D)
+ MEM(EA, 1) <- (RS)[56:63]
+ RA <- EA
+
+Special Registers Altered:
+
+ None
+
+# Store Byte with Update Indexed
+
+X-Form
+
+* stbux RS,RA,RB
+
+Pseudo-code:
+
+ EA <- (RA) + (RB)
+ MEM(EA, 1) <- (RS)[56:63]
+ RA <- EA
+
+Special Registers Altered:
+
+ None
+
+# Store Halfword
+
+D-Form
+
+* sth RS,D(RA)
+
+Pseudo-code:
+
+ b <- (RA|0)
+ EA <- b + EXTS(D)
+ MEM(EA, 2) <- (RS)[48:63]
+
+Special Registers Altered:
+
+ None
+
+# Store Halfword Indexed
+
+X-Form
+
+* sthx RS,RA,RB
+
+Pseudo-code:
+
+ b <- (RA|0)
+ EA <- b + (RB)
+ MEM(EA, 2) <- (RS)[48:63]
+
+Special Registers Altered:
+
+ None
+
+# Store Halfword with Update
+
+D-Form
+
+* sthu RS,D(RA)
+
+Pseudo-code:
+
+ EA <- (RA) + EXTS(D)
+ MEM(EA, 2) <- (RS)[48:63]
+ RA <- EA
+
+Special Registers Altered:
+
+ None
+
+# Store Halfword with Update Indexed
+
+X-Form
+
+* sthux RS,RA,RB
+
+Pseudo-code:
+
+ EA <- (RA) + (RB)
+ MEM(EA, 2) <- (RS)[48:63]
+ RA <- EA
+
+Special Registers Altered:
+
+ None
+
+# Store Word
+
+D-Form
+
+* stw RS,D(RA)
+
+Pseudo-code:
+
+ b <- (RA|0)
+ EA <- b + EXTS(D)
+ MEM(EA, 4) <- (RS)[32:63]
+
+Special Registers Altered:
+
+ None
+
+# Store Word Indexed
+
+X-Form
+
+* stwx RS,RA,RB
+
+Pseudo-code:
+
+ b <- (RA|0)
+ EA <- b + (RB)
+ MEM(EA, 4) <- (RS)[32:63]
+
+Special Registers Altered:
+
+ None
+
+# Store Word with Update
+
+D-Form
+
+* stwu RS,D(RA)
+
+Pseudo-code:
+
+ EA <- (RA) + EXTS(D)
+ MEM(EA, 4) <- (RS)[32:63]
+ RA <- EA
+
+Special Registers Altered:
+
+ None
+
+# Store Word with Update Indexed
+
+X-Form
+
+* stwux RS,RA,RB
+
+Pseudo-code:
+
+ EA <- (RA) + (RB)
+ MEM(EA, 4) <- (RS)[32:63]
+ RA <- EA
+
+Special Registers Altered:
+
+ None
+
+
+
+<!-- Section 3.3.3.1 64-bit Fixed-Point Store Instructions page 57 -->
+
+# Store Doubleword
+
+DS-Form
+
+* std RS,DS(RA)
+
+Pseudo-code:
+
+ b <- (RA|0)
+ EA <- b + EXTS(DS || 0b00)
+ MEM(EA, 8) <- (RS)
+
+Special Registers Altered:
+
+ None
+
+# Store Doubleword Indexed
+
+X-Form
+
+* stdx RS,RA,RB
+
+Pseudo-code:
+
+ b <- (RA|0)
+ EA <- b + (RB)
+ MEM(EA, 8) <- (RS)
+
+Special Registers Altered:
+
+ None
+
+# Store Doubleword with Update
+
+DS-Form
+
+* stdu RS,DS(RA)
+
+Pseudo-code:
+
+ EA <- (RA) + EXTS(DS || 0b00)
+ MEM(EA, 8) <- (RS)
+ RA <- EA
+
+Special Registers Altered:
+
+ None
+
+# Store Doubleword with Update Indexed
+
+X-Form
+
+* stdux RS,RA,RB
+
+Pseudo-code:
+
+ EA <- (RA) + (RB)
+ MEM(EA, 8) <- (RS)
+ RA <- EA
+
+Special Registers Altered:
+
+ None
+
+
+<!-- Section 3.3.4 Fixed Point Load and Store Quadword Instructions pages 58 - 59 -->
+
+<!-- For stq, the contents of an even-odd pair of GPRs is stored into the quadword -->
+<!-- in storage addressed by EA as follows. In Big-Endian mode, the even-numbered -->
+<!-- GPR is stored into the doubleword in storage addressed by EA and the -->
+<!-- odd-numbered GPR is stored into the doubleword addressed by EA+8. In -->
+<!-- Little-Endian mode, the even-numbered GPR is stored byte-reversed into the -->
+<!-- doubleword in storage addressed by EA+8 and the odd-numbered GPR is stored -->
+<!-- byte-reversed into the doubleword addressed by EA. -->
+
+
+# Store Quadword
+
+DS-Form
+
+* stq RSp,DS(RA)
+
+Pseudo-code:
+
+ b <- (RA|0)
+ EA <- b + EXTS(DS || 0b00)
+ MEM(EA, 16) <- RSp
+
+Special Registers Altered:
+
+ None
+
+<!-- Section 3.3.5 Fixed-Point Load and Store with Byte Reversal Instructions page 60 -->
+
+# Store Halfword Byte-Reverse Indexed
+
+X-Form
+
+* sthbrx RS,RA,RB
+
+Pseudo-code:
+
+ b <- (RA|0)
+ EA <- b + (RB)
+ MEM(EA, 2) <- (RS) [56:63] || (RS)[48:55]
+
+Special Registers Altered:
+
+ None
+
+# Store Word Byte-Reverse Indexed
+
+X-Form
+
+* stwbrx RS,RA,RB
+
+Pseudo-code:
+
+ b <- (RA|0)
+ EA <- b + (RB)
+ MEM(EA, 4) <- ((RS)[56:63] || (RS)[48:55] || (RS)[40:47]
+ ||(RS)[32:39])
+
+Special Registers Altered:
+
+ None
+
+<!-- Section 3.3.5.1 64-Bit Load and Store with Byte Reversal Instructions page 61 -->
+
+# Store Doubleword Byte-Reverse Indexed
+
+X-Form
+
+* stdbrx RS,RA,RB
+
+Pseudo-code:
+
+ b <- (RA|0)
+ EA <- b + (RB)
+ MEM(EA, 8) <- ((RS) [56:63] || (RS)[48:55]
+ || (RS)[40:47] || (RS)[32:39]
+ || (RS)[24:31] || (RS)[16:23]
+ || (RS)[8:15] || (RS)[0:7])
+
+Special Registers Altered:
+
+ None
+
+
+<!-- Section 3.3.6 Fixed-Point Load and Store Multiple Instructions page 62 -->
+
+# Store Multiple Word
+
+D-Form
+
+* stmw RS,D(RA)
+
+Pseudo-code:
+
+ b <- (RA|0)
+ EA <- b + EXTS(D)
+ r <- RS
+ do while r <= 31
+ MEM(EA, 4) <- GPR(r)[32:63]
+ r <- r + 1
+ EA <- EA + 4
+
+Special Registers Altered:
+
+ None
+
+<!-- Checked March 2021 -->
--- /dev/null
+<!-- This defines instructions described in PowerISA Version 3.0 B Book 1 -->
+
+<!-- Section 3.3.11 Fixed-Point Trap Instructions pages 89 - 91 -->
+
+<!-- The Trap instructions are provided to test for a specified set of conditions. -->
+<!-- If any of the conditions tested by a Trap instruction are met, the system trap -->
+<!-- handler is invoked. If none of the tested conditions are met, instruction -->
+<!-- execution continues normally. -->
+
+# Trap Word Immediate
+
+D-Form
+
+* twi TO,RA,SI
+
+Pseudo-code:
+
+ a <- EXTS((RA)[32:63])
+ if (a < EXTS(SI)) & TO[0] then TRAP
+ if (a > EXTS(SI)) & TO[1] then TRAP
+ if (a = EXTS(SI)) & TO[2] then TRAP
+ if (a <u EXTS(SI)) & TO[3] then TRAP
+ if (a >u EXTS(SI)) & TO[4] then TRAP
+
+Special Registers Altered:
+
+ None
+
+# Trap Word
+
+X-Form
+
+* tw TO,RA,RB
+
+Pseudo-code:
+
+ a <- EXTS((RA)[32:63])
+ b <- EXTS((RB)[32:63])
+ if (a < b) & TO[0] then TRAP
+ if (a > b) & TO[1] then TRAP
+ if (a = b) & TO[2] then TRAP
+ if (a <u b) & TO[3] then TRAP
+ if (a >u b) & TO[4] then TRAP
+
+Special Registers Altered:
+
+ None
+
+# Trap Doubleword Immediate
+
+D-Form
+
+* tdi TO,RA,SI
+
+Pseudo-code:
+
+ a <- (RA)
+ b <- EXTS(SI)
+ if (a < b) & TO[0] then TRAP
+ if (a > b) & TO[1] then TRAP
+ if (a = b) & TO[2] then TRAP
+ if (a <u b) & TO[3] then TRAP
+ if (a >u b) & TO[4] then TRAP
+
+Special Registers Altered:
+
+ None
+
+# Trap Doubleword
+
+X-Form
+
+* td TO,RA,RB
+
+Pseudo-code:
+
+ a <- (RA)
+ b <- (RB)
+ if (a < b) & TO[0] then TRAP
+ if (a > b) & TO[1] then TRAP
+ if (a = b) & TO[2] then TRAP
+ if (a <u b) & TO[3] then TRAP
+ if (a >u b) & TO[4] then TRAP
+
+Special Registers Altered:
+
+ None
+
+# Integer Select
+
+A-Form
+
+* isel RT,RA,RB,BC
+
+Pseudo-code:
+
+ if CR[BC+32]=1 then RT <- (RA|0)
+ else RT <- (RB)
+
+Special Registers Altered:
+
+ None
+
+<!-- Checked March 2021 -->
--- /dev/null
+The SOC is designed to be compliant with POWER 3.0B with somewhere near
+300 instructions excluding Vector instructions.
+
+# Decoder
+
+The Decoder uses a class called PowerOp which get instantiated
+for every instruction. PowerOp class instantiation has member signals
+whose values get set respectively for each instruction.
+
+We use Python Enums to help with common decoder values.
+Below is the POWER add insruction.
+
+| opcode | unit | internal op | in1 | in2 | in3 | out | CR in | CR out | inv A | inv out | cry in | cry out | ldst len | BR | sgn ext | upd | rsrv | 32b | sgn | rc | lk | sgl pipe | comment | form |
+|--------------|------|-------------|-----|-----|------|-----|-------|--------|-------|---------|--------|---------|----------|----|---------|-----|------|-----|-----|----|----|----------|---------|------|
+| 0b0100001010 | ALU | OP_ADD | RA | RB | NONE | RT | 0 | 0 | 0 | 0 | ZERO | 0 | NONE | 0 | 0 | 0 | 0 | 0 | 0 | RC | 0 | 0 | add | XO |
+
+Here is an example of a toy multiplexer that sets various fields in the
+PowerOP signal class to the correct values for the add instruction when
+select is set equal to 1. This should give you a feel for how we work with
+enums and PowerOP.
+
+ from nmigen import Module, Elaboratable, Signal, Cat, Mux
+ from soc.decoder.power_enums import (Function, Form, InternalOp,
+ In1Sel, In2Sel, In3Sel, OutSel, RC, LdstLen,
+ CryIn, get_csv, single_bit_flags,
+ get_signal_name, default_values)
+ from soc.decoder.power_fields import DecodeFields
+ from soc.decoder.power_fieldsn import SigDecode, SignalBitRange
+ from soc.decoder.power_decoder import PowerOp
+
+ class Op_Add_Example(Elaboratable):
+ def __init__(self):
+ self.select = Signal(reset_less=True)
+ self.op_add = PowerOp()
+
+ def elaborate(self, platform):
+ m = Module()
+ op_add = self.op_add
+
+ with m.If(self.select == 1):
+ m.d.comb += op_add.function_unit.eq(Function.ALU)
+ m.d.comb += op_add.form.eq(Form.XO)
+ m.d.comb += op_add.internal_op.eq(InternalOp.OP_ADD)
+ m.d.comb += op_add.in1_sel.eq(In1Sel.RA)
+ m.d.comb += op_add.in2_sel.eq(In2Sel.RB)
+ m.d.comb += op_add.in3_sel.eq(In3Sel.NONE)
+ m.d.comb += op_add.out_sel.eq(OutSel.RT)
+ m.d.comb += op_add.rc_sel.eq(RC.RC)
+ m.d.comb += op_add.ldst_len.eq(LdstLen.NONE)
+ m.d.comb += op_add.cry_in.eq(CryIn.ZERO)
+
+ return m
+
+ from nmigen.back import verilog
+ verilog_file = "op_add_example.v"
+ top = Op_Add_Example()
+ f = open(verilog_file, "w")
+ verilog = verilog.convert(top, name='top', strip_internal_attrs=True,
+ ports=top.op_add.ports())
+ f.write(verilog)
+ print(f"Verilog Written to: {verilog_file}")
+
+The [actual POWER9 Decoder](https://git.libre-soc.org/?p=soc.git;a=blob;f=src/soc/decoder/power_decoder2.py;hb=HEAD)
+uses this principle, in conjunction with reading the information shown
+in the table above from CSV files (as opposed to hardcoding them in
+python source). These [[CSV files|openpower/isatables]],
+being machine-readable in a wide variety
+of programming languages, are conveniently available for use by
+other projects well beyond just this SOC.
+
+This also demonstrates one of the design aspects taken in this project: to
+*combine* the power of python's full capabilities in order to create
+advanced dynamically generated HDL, rather than (as done with MyHDL)
+limit python code to a subset of its full capabilities.
+
+The CSV Files are loaded by
+[power_decoder.py](https://git.libre-soc.org/?p=soc.git;a=blob;f=src/soc/decoder/power_decoder.py;hb=HEAD)
+and are used to construct a hierarchical cascade of switch statements. The original code came from
+[microwatt](https://github.com/antonblanchard/microwatt/blob/master/decode1.vhdl)
+where the original hardcoded cascade can be seen.
+
+The docstring for power_decoder.py gives more details: each level in the hierarchy, just as in the original decode1.vhdl, will take slices of the instruction bitpattern, match against it, and if successful will continue with further subdecoders until a line is met that contains the required Operand Information (a PowerOp) exactly as shown at the top of this page.
+
+In this way, different sections of the instruction are successively decoded (major opcode, then minor opcode, then sub-patterns under those) until the required instruction is fully recognised, and the hierarchical cascade of switch patterns results in a flat interpretation being produced that is useful internally.
+
+
--- /dev/null
+<!-- This defines instructions described in PowerISA Version 3.0 B Book 1 -->
+
+<!-- These are not described in book 1 -->
+
+# setvl
+
+SVL-Form
+
+* setvl RT, RA, SVi, vs, ms
+* setvl. RT, RA, SVi, vs, ms
+
+Pseudo-code:
+
+ VLimm <- SVi + 1
+ if vs = 1 then
+ if _RA != 0 then
+ VL <- (RA|0)[57:63]
+ else
+ VL <- VLimm[1:7]
+ else
+ VL <- SVSTATE[7:13]
+ if ms = 1 then
+ MVL <- VLimm[1:7]
+ else
+ MVL <- SVSTATE[0:6]
+ if VL > MVL then
+ VL = MVL
+ SVSTATE[0:6] <- MVL
+ SVSTATE[7:13] <- VL
+ RT <- [0]*57 || VL
+
+Special Registers Altered:
+
+ CR0 (if Rc=1)
+
--- /dev/null
+<!-- This defines instructions described in PowerISA Version 3.0 B Book 1 -->
+
+<!-- Section 4.4.4 Move To/From System Register Instructions pages 970 - 1038 -->
+
+<!-- Section 4.4.4 Move To/From System Register Instructions pages 970 - 1038 -->
+<!-- Section 3.3.17 Move To/From System Register Instructions Page 120 -->
+<!-- Section 4.3.2 Data Cache Instructions Page 850 -->
+
+<!-- This needs checking again -->
+
+<!-- The Move To Special Purpose Register and Move From Special Purpose Register -->
+<!-- instructions are described in Book I, but only at the level available to an -->
+<!-- application programmer. For example, no mention is made there of registers that -->
+<!-- can be accessed only in privileged state. The descriptions of these instructions -->
+<!-- given below extend the descriptions given in Book I, but do not list Special -->
+<!-- Purpose Registers that are implementation-dependent. In the descriptions of -->
+<!-- these instructions given in below, the “defined” SPR numbers are the SPR -->
+<!-- numbers shown in the Figure 18 for the instruction and the -->
+<!-- implementation-specific SPR numbers that are implemented, and similarly for -->
+<!-- “defined” registers. All other SPR numbers are undefined for the instruction. -->
+<!-- (Implementation-specific SPR numbers that are not implemented are considered to -->
+<!-- be undefined.) When an SPR is defined for mtspr and undefined for mfspr, or -->
+<!-- vice versa, a hyphen appears in the column for the instruction for which the -->
+<!-- SPR number is undefined. -->
+
+
+
+<!-- Page 974 -->
+
+# Move To Special Purpose Register
+
+XFX-Form
+
+* mtspr SPR,RS
+
+Pseudo-code:
+
+ n <- spr[5:9] || spr[0:4]
+ switch (n)
+ case(13): see(Book_III_p974)
+ case(808, 809, 810, 811):
+ default:
+ if length(SPR(n)) = 64 then
+ SPR(n) <- (RS)
+ else
+ SPR(n) <- (RS) [32:63]
+
+Special Registers Altered:
+
+ See spec 3.3.17
+
+<!-- Page 975 -->
+
+# Move From Special Purpose Register
+
+XFX-Form
+
+* mfspr RT,SPR
+
+Pseudo-code:
+
+ n <- spr[5:9] || spr[0:4]
+ switch (n)
+ case(129): see(Book_III_p975)
+ case(808, 809, 810, 811):
+ default:
+ if length(SPR(n)) = 64 then
+ RT <- SPR(n)
+ else
+ RT <- [0]*32 || SPR(n)
+
+Special Registers Altered:
+
+ None
+
+<!-- Section 3.3.17 Move To/From System Register Instructions Page 120 -->
+
+# Move to CR from XER Extended
+
+X-Form
+
+* mcrxrx BF
+
+Pseudo-code:
+
+ CR[4*BF+32:4*BF+35] <- XER[OV] || XER[OV32] || XER[CA] || XER[CA32]
+
+Special Registers Altered:
+
+ CR field BF
+
+# Move To One Condition Register Field
+
+XFX-Form
+
+* mtocrf FXM,RS
+
+Pseudo-code:
+
+ n <- 7
+ do i = 7 to 0
+ if FXM[i] = 1 then
+ n <- i
+ CR[4*n+32:4*n+35] <- (RS)[4*n+32:4*n+35]
+
+Special Registers Altered:
+
+ CR field selected by FXM
+
+# Move To Condition Register Fields
+
+XFX-Form
+
+* mtcrf FXM,RS
+
+Pseudo-code:
+
+ do n = 0 to 7
+ if FXM[n] = 1 then
+ CR[4*n+32:4*n+35] <- (RS)[4*n+32:4*n+35]
+
+Special Registers Altered:
+
+ CR fields selected by mask
+
+# Move From One Condition Register Field
+
+XFX-Form
+
+* mfocrf RT,FXM
+
+Pseudo-code:
+
+ done <- 0
+ RT <- [0]*64
+ do n = 0 to 7
+ if (done = 0) & (FXM[n] = 1) then
+ RT[4*n+32:4*n+35] <- CR[4*n+32:4*n+35]
+ done <- 1
+
+Special Registers Altered:
+
+ None
+
+# Move From Condition Register
+
+XFX-Form
+
+* mfcr RT
+
+Pseudo-code:
+
+ RT <- [0]*32 || CR
+
+Special Registers Altered:
+
+ None
+
+# Set Boolean
+
+X-Form
+
+* setb RT,BFA
+
+Pseudo-code:
+
+ if CR[4*BFA+32] = 1 then
+ RT <- 0xFFFF_FFFF_FFFF_FFFF
+ else if CR[4*BFA+33]=1 then
+ RT <- 0x0000_0000_0000_0001
+ else
+ RT <- 0x0000_0000_0000_0000
+
+Special Registers Altered:
+
+ None
+
+<!-- Out of order from the PDF. Page 977 -->
+
+# Move To Machine State Register
+
+X-Form
+
+* mtmsr RS,L1
+
+Pseudo-code:
+
+ if L1 = 0 then
+ MSR[48] <- (RS)[48] | (RS)[49]
+ MSR[58] <- (RS)[58] | (RS)[49]
+ MSR[59] <- (RS)[59] | (RS)[49]
+ MSR[32:40] <- (RS)[32:40]
+ MSR[42:47] <- (RS)[42:47]
+ MSR[49:50] <- (RS)[49:50]
+ MSR[52:57] <- (RS)[52:57]
+ MSR[60:62] <- (RS)[60:62]
+ else
+ MSR[48] <- (RS)[48]
+ MSR[62] <- (RS)[62]
+
+Special Registers Altered:
+
+ MSR
+
+# Move To Machine State Register
+
+X-Form
+
+* mtmsrd RS,L1
+
+Pseudo-code:
+
+ if L1 = 0 then
+ if (MSR[29:31] != 0b010) | ((RS)[29:31] != 0b000) then
+ MSR[29:31] <- (RS)[29:31]
+ MSR[48] <- (RS)[48] | (RS)[49]
+ MSR[58] <- (RS)[58] | (RS)[49]
+ MSR[59] <- (RS)[59] | (RS)[49]
+ MSR[0:2] <- (RS)[0:2]
+ MSR[4:28] <- (RS)[4:28]
+ MSR[32:40] <- (RS)[32:40]
+ MSR[42:47] <- (RS)[42:47]
+ MSR[49:50] <- (RS)[49:50]
+ MSR[52:57] <- (RS)[52:57]
+ MSR[60:62] <- (RS)[60:62]
+ else
+ MSR[48] <- (RS)[48]
+ MSR[62] <- (RS)[62]
+
+Special Registers Altered:
+
+ MSR
+
+# Move From Machine State Register
+
+X-Form
+
+* mfmsr RT
+
+Pseudo-code:
+
+ RT <- MSR
+
+Special Registers Altered:
+
+ None
+
+<!-- Section 4.3.2 Data Cache Instructions Page 850 -->
+
+# Data Cache Block set to Zero
+
+X-Form
+
+* dcbz RA,RB
+
+Pseudo-code:
+
+ if RA = 0 then b <- 0
+ else b <-(RA)
+ EA <- b + (RB)
+
+Special Registers Altered:
+
+ None
+
+<!-- Section 5.9.3.3 TLB Management Instructions Page 1033 -->
+
+# TLB Invalidate Entry
+
+X-Form
+
+* tlbie RB,RS,RIC,PRS,R
+
+Pseudo-code:
+
+ IS <- (RB) [52:53]
+
+Special Registers Altered:
+
+ None
+
+<!-- MISSING tlbiel page 1038 -->
+<!-- MISSING tlbsync page 1042 -->
--- /dev/null
+<!-- Instructions here described in PowerISA Version 3.0 B Book 1 -->
+
+<!-- Section 3.3.7 Fixed-Point Move Assist Instructions [Phased Out] pages 63 - 65 -->
+
+<!-- The Move Assist instructions allow movement of an arbitrary sequence of bytes -->
+<!-- from storage to registers or from registers to storage without concern for -->
+<!-- alignment. These instructions can be used for a short move between arbitrary -->
+<!-- storage locations or to initiate a long move between unaligned storage fields. -->
+
+
+# Load String Word Immediate
+
+X-Form
+
+* lswi RT,RA,NB
+
+Pseudo-code:
+
+ EA <- (RA|0)
+ if NB = 0 then n <- 32
+ else n <- NB
+ r <- RT - 1
+ i <- 32
+ do while n > 0
+ if i = 32 then
+ r <- (r + 1) % 32
+ GPR(r) <- 0
+ GPR(r)[i:i+7] <- MEM(EA, 1)
+ i <- i + 8
+ if i = 64 then i <- 32
+ EA <- EA + 1
+ n <- n - 1
+
+Special Registers Altered:
+
+ None
+
+# Load String Word Indexed
+
+X-Form
+
+* lswx RT,RA,RB
+
+Pseudo-code:
+
+ b <- (RA|0)
+ EA <- b + (RB)
+ n <- XER[57:63]
+ r <- RT - 1
+ i <- 32
+ RT <- undefined([0]*64)
+ do while n > 0
+ if i = 32 then
+ r <- (r + 1) % 32
+ GPR(r) <- 0
+ GPR(r)[i:i+7] <- MEM(EA, 1)
+ i <- i + 8
+ if i = 64 then i <- 32
+ EA <- EA + 1
+ n <- n - 1
+
+Special Registers Altered:
+
+ None
+
+# Store String Word Immediate
+
+X-Form
+
+* stswi RS,RA,NB
+
+Pseudo-code:
+
+ EA <- (RA|0)
+ if NB = 0 then n <- 32
+ else n <- NB
+ r <- RS - 1
+ i <- 32
+ do while n > 0
+ if i = 32 then r <- (r + 1) % 32
+ MEM(EA, 1) <- GPR(r)[i:i+7]
+ i <- i + 8
+ if i = 64 then i <- 32
+ EA <- EA + 1
+ n <- n - 1
+
+Special Registers Altered:
+
+ None
+
+# Store String Word Indexed
+
+X-Form
+
+* stswx RS,RA,RB
+
+Pseudo-code:
+
+ b <- (RA|0)
+ EA <- b + (RB)
+ n <- XER[57:63]
+ r <- RS - 1
+ i <- 32
+ do while n > 0
+ if i = 32 then r <- (r + 1) % 32
+ MEM(EA, 1) <- GPR(r)[i:i+7]
+ i <- i + 8
+ if i = 64 then i <- 32
+ EA <- EA + 1
+ n <- n - 1
+
+Special Registers Altered:
+
+ None
+
+<!-- Checked March 2021 -->
--- /dev/null
+<!-- Instructions here described in PowerISA Version 3.0 B Book 1 -->
+
+<!-- 3.3.1 System Linkage Instructions Page 952 - 956 -->
+
+<!-- These instructions provide the means by which a program can call upon the system to perform a service. -->
+
+# System Call
+
+SC-Form
+
+* sc LEV
+
+Pseudo-code:
+
+ SRR0 <-iea CIA + 4
+ SRR1[33:36] <- 0
+ SRR1[42:47] <- 0
+ SRR1[0:32] <- MSR[0:32]
+ SRR1[37:41] <- MSR[37:41]
+ SRR1[48:63] <- MSR[48:63]
+ MSR <- new_value
+ NIA <- 0x0000_0000_0000_0C00
+
+Special Registers Altered:
+
+ SRR0 SRR1 MSR
+
+# System Call Vectored
+
+SC-Form
+
+* scv LEV
+
+Pseudo-code:
+
+ LR <- CIA + 4
+ SRR1[33:36] <- undefined([0]*4)
+ SRR1[42:47] <- undefined([0]*6)
+ SRR1[0:32] <- MSR[0:32]
+ SRR1[37:41] <- MSR[37:41]
+ SRR1[48:63] <- MSR[48:63]
+ MSR <- new_value
+ NIA <- vectored
+
+Special Registers Altered:
+
+ LR CTR MSR
+
+# Return From System Call Vectored
+
+XL-Form
+
+* rfscv
+
+Pseudo-code:
+
+ if (MSR[29:31] != 0b010) | (CTR[29:31] != 0b000) then
+ MSR[29:31] <- CTR[29:31]
+ MSR[48] <- CTR[49]
+ MSR[58] <- CTR[49]
+ MSR[59] <- CTR[49]
+ MSR[0:2] <- CTR[0:2]
+ MSR[4:28] <- CTR[4:28]
+ MSR[32] <- CTR[32]
+ MSR[37:41] <- CTR[37:41]
+ MSR[49:50] <- CTR[49:50]
+ MSR[52:57] <- CTR[52:57]
+ MSR[60:63] <- CTR[60:63]
+ NIA <-iea LR[0:61] || 0b00
+
+Special Registers Altered:
+
+ MSR
+
+# Return From Interrupt Doubleword
+
+XL-Form
+
+* rfid
+
+Pseudo-code:
+
+ MSR[51] <- (MSR[3] & SRR1[51]) | ((¬MSR[3] & MSR[51]))
+ MSR[3] <- (MSR[3] & SRR1[3])
+ if (MSR[29:31] != 0b010) | (SRR1[29:31] != 0b000) then
+ MSR[29:31] <- SRR1[29:31]
+ MSR[48] <- SRR1[48] | SRR1[49]
+ MSR[58] <- SRR1[58] | SRR1[49]
+ MSR[59] <- SRR1[59] | SRR1[49]
+ MSR[0:2] <- SRR1[0:2]
+ MSR[4:28] <- SRR1[4:28]
+ MSR[32] <- SRR1[32]
+ MSR[37:41] <- SRR1[37:41]
+ MSR[49:50] <- SRR1[49:50]
+ MSR[52:57] <- SRR1[52:57]
+ MSR[60:63] <- SRR1[60:63]
+ NIA <-iea SRR0[0:61] || 0b00
+
+Special Registers Altered:
+
+ MSR
+
+# Hypervisor Return From Interrupt Doubleword
+
+XL-Form
+
+* hrfid
+
+Pseudo-code:
+
+ if (MSR[29:31] != 0b010) | (HSRR1[29:31] != 0b000) then
+ MSR[29:31] <- HSRR1[29:31]
+ MSR[48] <- HSRR1[48] | HSRR1[49]
+ MSR[58] <- HSRR1[58] | HSRR1[49]
+ MSR[59] <- HSRR1[59] | HSRR1[49]
+ MSR[0:28] <- HSRR1[0:28]
+ MSR[32] <- HSRR1[32]
+ MSR[37:41] <- HSRR1[37:41]
+ MSR[49:57] <- HSRR1[49:57]
+ MSR[60:63] <- HSRR1[60:63]
+ NIA <-iea HSRR0[0:61] || 0b00
+
+Special Registers Altered:
+
+ MSR
+
+<!-- Checked March 2021 -->