--- /dev/null
+<!-- https://libre-soc.org/openpower/prefix_codes/ -->
+
+# [DRAFT] Prefix-code decode
+
+VA2-Form
+
+* pcdec RT,RA,RB,RC,once
+
+Pseudo-code:
+
+ tree[0:63] <- (RA)
+ rb_used <- 0b0
+ in_bits[0:63] <- (RC|0)
+ if in_bits = 0 then
+ in_bits[0:63] <- 1
+ final_in_bits <- in_bits
+ final_rb_used <- rb_used
+ output <- [0] * 64
+ out_byte <- 0
+ decoded[0:7] <- 1
+ so_bit <- 0b0
+ do while out_byte < 8
+ in_bit <- in_bits[63]
+ if in_bits = 1 then
+ if rb_used | (_RB = 0) then
+ leave
+ rb_used <- 0b1
+ in_bit <- (RB)[63]
+ in_bits <- 0b1 || (RB)[0:62]
+ else
+ in_bits <- 0b0 || in_bits[0:62]
+ # walk the binary tree in `tree` from parent to the selected child
+ decoded <- decoded[1:7] || in_bit
+ if decoded <u 64 then
+ if tree[63 - decoded] then
+ final_in_bits <- in_bits
+ final_rb_used <- rb_used
+ output[56 - 8 * out_byte:63 - 8 * out_byte] <- decoded
+ decoded[0:7] <- 1
+ out_byte <- out_byte + 1
+ if once then
+ leave
+ else
+ so_bit <- 0b1
+ leave
+ RT <- output
+ RS <- final_in_bits
+ CR0 <- final_rb_used || 0b0 || (output = 0) || so_bit
+
+Special Registers Altered:
+
+ CR0
maddld,NORMAL,,1P,EXTRA2,NO,d:RT,s:RA,s:RB,s:RC,RA,RB,RC,RT,0,0,0
absdacs,NORMAL,,1P,EXTRA2,NO,d:RT;d:CR0,s:RA,s:RB,s:RT,RA,RB,RT,RT,0,CR0,0
absdacu,NORMAL,,1P,EXTRA2,NO,d:RT;d:CR0,s:RA,s:RB,s:RT,RA,RB,RT,RT,0,CR0,0
+pcdec,NORMAL,,1P,EXTRA2,NO,d:RT;d:CR0,s:RA,s:RB,s:RC,RA,RB,RC,RT,0,CR0,0
+pcdec,NORMAL,,1P,EXTRA2,NO,d:RT;d:CR0,s:RA,s:RB,s:RC,RA,RB,RC,RT,0,CR0,0
ternlogi,NORMAL,,1P,EXTRA2,NO,d:RT;d:CR0,s:RA,s:RB,s:RT,RA,RB,RT,RT,0,CR0,0
ffmsubs,NORMAL,,1P,EXTRA2,NO,d:FRT;d:CR1,s:FRA,s:FRB,s:FRC,FRA,FRB,FRC,FRT,0,CR1,0
ffmadds,NORMAL,,1P,EXTRA2,NO,d:FRT;d:CR1,s:FRA,s:FRB,s:FRC,FRA,FRB,FRC,FRT,0,CR1,0
| PO | VRT | VRA | VRB | /|BFA|/ | XO |
# 1.6.21.1 VA2-FORM
- |0 |6 |11 |16 |21 |24|26 |31|
- | PO | RT | RA | RB | RC | XO |Rc|
+ |0 |6 |11 |16 |21 |24|26 |31 |
+ | PO | RT | RA | RB | RC | XO | Rc |
+ | PO | RT | RA | RB | RC | XO |once|
# 1.6.22 VC-FORM
|0 |6 |11 |16 |21|22 |31|
Field used by XO-form instructions to enable set-
ting OV and SO in the XER.
Formats: XO
+ once (31)
+ Once bit. Used by Prefix-code encode/decode instructions.
+ 0 Decode/Encode multiple times per instruction.
+ 1 Only Decode once per instruction
+ Formats: VA2
PO (0:5)
Primary opcode field.
Formats: all
48,ALU,OP_MADDHD,RA,RB,RC,RT,NONE,NONE,0,0,ZERO,0,NONE,0,0,0,0,1,0,NONE,0,0,maddhd,VA,,,
49,ALU,OP_MADDHDU,RA,RB,RC,RT,NONE,NONE,0,0,ZERO,0,NONE,0,0,0,0,1,0,NONE,0,0,maddhdu,VA,,,
51,ALU,OP_MADDLD,RA,RB,RC,RT,NONE,NONE,0,0,ZERO,0,NONE,0,0,0,0,1,0,NONE,0,0,maddld,VA,,,
+56,ALU,OP_PCDEC,RA,RB,RC,RT,NONE,CR0,0,0,ZERO,0,NONE,0,0,0,0,1,0,NONE,0,0,pcdec,VA2,,1,unofficial until submitted and approved/renumbered by the opf isa wg
+57,ALU,OP_PCDEC,RA,RB,RC,RT,NONE,CR0,0,0,ZERO,0,NONE,0,0,0,0,1,0,NONE,0,0,pcdec,VA2,,1,unofficial until submitted and approved/renumbered by the opf isa wg
/svfixedload.py
/svfparith.py
/svfpload.py
+/prefix_codes.py
*.orig
*.rej
'svshape', 'svshape2',
'grev', 'ternlogi', 'bmask', 'cprop',
'absdu', 'absds', 'absdacs', 'absdacu', 'avgadd',
- 'fmvis', 'fishmv',
+ 'fmvis', 'fishmv', 'pcdec'
]:
illegal = False
ins_name = dotstrp
--- /dev/null
+""" prefix-codes tests
+"""
+
+import unittest
+from openpower.test.runner import TestRunnerBase
+from openpower.test.prefix_codes.prefix_codes_cases import PrefixCodesCases
+
+# writing the test_caller invocation this way makes it work with pytest
+
+
+# FIXME: fails because ISACaller can't currently handle writing to
+# both RT and RS
+@unittest.expectedFailure
+class TestPrefixCodes(TestRunnerBase):
+ def __init__(self, test):
+ assert test == 'test'
+ super().__init__(PrefixCodesCases().test_data)
+
+ def test(self):
+ # dummy function to make unittest try to test this class
+ pass
+
+
+if __name__ == "__main__":
+ unittest.main()
"nand", "neg", "nego",
"nop",
"nor", "or", "orc", "ori", "oris",
+ "pcdec",
"popcntb", "popcntd", "popcntw",
"prtyd", "prtyw",
"rfid",
OP_SVINDEX = 95
OP_FMVIS = 96
OP_FISHMV = 97
+ OP_PCDEC = 98
@unique
res['1'] = 's:RA' # RA: Rsrc1_EXTRA2
res['2'] = 's:RB' # RT: Rsrc2_EXTRA2
res['3'] = 's:RC' # RT: Rsrc3_EXTRA2
+ elif regs == ['RA', 'RB', 'RC', 'RT', '', 'CR0']: # pcdec
+ res['0'] = 'd:RT;d:CR0' # RT,CR0: Rdest1_EXTRA2
+ res['1'] = 's:RA' # RA: Rsrc1_EXTRA2
+ res['2'] = 's:RB' # RT: Rsrc2_EXTRA2
+ res['3'] = 's:RC' # RT: Rsrc3_EXTRA2
elif regs == ['RA', 'RB', 'RT', 'RT', '', 'CR0']: # overwrite 3-in
res['0'] = 'd:RT;d:CR0' # RT,CR0: Rdest1_EXTRA2
res['1'] = 's:RA' # RA: Rsrc1_EXTRA2
)
+@_custom_insns()
+def pcdec(fields):
+ # 1.6.21.1 VA2-FORM
+ # |0 |6 |11 |16 |21 |24|26 |31 |
+ # | PO | RT | RA | RB | RC | XO |once|
+ PO = 4
+ XO = 0b11100
+ (RT, RA, RB, RC, once) = fields
+ return instruction(
+ (PO, 0, 5),
+ (RT, 6, 10),
+ (RA, 11, 15),
+ (RB, 16, 20),
+ (RC, 21, 25),
+ (XO, 26, 30),
+ (once, 31, 31),
+ )
+
+
# decode GPR into sv extra
def get_extra_gpr(etype, regmode, field):
if regmode == 'scalar':
--- /dev/null
+from openpower.test.common import TestAccumulatorBase
+from openpower.sv.trans.svp64 import SVP64Asm
+from openpower.test.state import ExpectedState
+from openpower.simulator.program import Program
+
+
+def tree_code(code):
+ # type: (str) -> int
+ retval = 1
+ for bit in reversed(code):
+ assert bit in "01"
+ retval = retval * 2 + int(bit)
+ return retval
+
+
+def make_tree(*codes):
+ # type: (*str) -> int
+ retval = 0
+ for code in codes:
+ retval |= 1 << tree_code(code)
+ return retval
+
+
+def code_seq(*codes, prefix1=False):
+ # type: (*str, bool) -> int
+ prefix = "0b1" if prefix1 else "0b"
+ return int(prefix + "".join(reversed(codes)), base=0)
+
+
+class PrefixCodesCases(TestAccumulatorBase):
+ def case_pcdec_simple(self):
+ lst = list(SVP64Asm(["pcdec 4,6,7,5,0"]))
+ gprs = [0] * 32
+ gpr5_codes = ["0", "11", "1001", "101010"]
+ gpr7_codes = ["1001"] * 8 + ["101010", "11"] * 4
+ gprs[5] = code_seq(*gpr5_codes, prefix1=True)
+ gprs[6] = make_tree("0", "11", "1001", "101010")
+ gprs[7] = code_seq(*gpr7_codes)
+ e = ExpectedState(pc=4, int_regs=gprs)
+ e.intregs[4] = int.from_bytes(
+ map(tree_code, (gpr5_codes + gpr7_codes)[:8]), 'little')
+ e.intregs[5] = code_seq(*(gpr5_codes + gpr7_codes)[8:], prefix1=True)
+ e.crregs[0] = 0b1000
+ self.add_case(Program(lst, False), gprs, expected=e)