CR0 (if Rc=1)
+# Condition Register Ternary Bitwise Logic Immediate
+
+CRB-Form
+
+* crternlogi BF,BFA,BFB,TLI,msk
+
+Pseudo-code:
+
+ bf <- CR[4*BF+32:4*BF+35]
+ bfa <- CR[4*BFA+32:4*BFA+35]
+ bfb <- CR[4*BFB+32:4*BFB+35]
+
+ result <- [0] * 4
+ do i = 0 to 3
+ idx <- bf[i] || bfa[i] || bfb[i]
+ result[i] <- TLI[7-idx]
+ do i = 0 to 3
+ if msk[i] = 1 then
+ CR[4*BF+32+i] <- result[i]
+
+Special Registers Altered:
+
+ CR field BF
+
# Add With Shift By Immediate
Z23-Form
BF (6:8)
Field used to specify one of the CR fields or one of
the FPSCR fields to be used as a target.
- Formats: D, X, XL, XX2, XX3, Z22
+ Formats: D, X, XL, XX2, XX3, Z22, CRB
BFA (22:24)
Field used to specify one of the CR fields
to be used as a source.
BFA (11:13)
Field used to specify one of the CR fields or one of
the FPSCR fields to be used as a source.
- Formats: X, XL
+ Formats: X, XL, CRB
+ BFB (16:18)
+ Field used to specify one of the CR fields
+ to be used as a source.
+ Formats: CRB
BH (19:20)
Field used to specify a hint in the Branch Condi-
tional to Link Register and Branch Conditional to
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,CONDITIONS,unofficial,comment2
--------00-,SHIFT_ROT,OP_TERNLOG,RA,RB,RT,RT,NONE,CR0,0,0,ZERO,0,NONE,0,0,0,0,0,0,RC_ONLY,0,0,ternlogi,TLI,,1,unofficial until submitted and approved/renumbered by the opf isa wg
+--------01-,CR,OP_CRTERNLOG,NONE,NONE,NONE,NONE,BFA_BFB_BF,BF,0,0,ZERO,0,NONE,0,0,0,0,0,0,NONE,0,0,crternlogi,CRB,,1,unofficial until submitted and approved/renumbered by the opf isa wg
# these are all opcode fields involved in index-selection of CR,
# and need to do "standard" arithmetic. CR[BA+32] for example
# would, if using SelectableInt, only be 5-bit.
- if name in ['BF', 'BFA', 'BC', 'BA', 'BB', 'BT', 'BI']:
+ if name in ['BF', 'BFA', 'BFB', 'BC', 'BA', 'BB', 'BT', 'BI']:
self.namespace[name] = val
else:
self.namespace[name] = SelectableInt(val, sig.width)
"brh", "brw", "brd",
'setvl', 'svindex', 'svremap', 'svstep',
'svshape', 'svshape2',
- 'ternlogi', 'bmask', 'cprop', 'gbbd',
+ 'crternlogi', 'ternlogi', 'bmask', 'cprop', 'gbbd',
'absdu', 'absds', 'absdacs', 'absdacu', 'avgadd',
'fmvis', 'fishmv', 'pcdec', "maddedu", "divmod2du",
"dsld", "dsrd", "maddedus",
comb += self.cr_bitfield_b.ok.eq(1)
comb += self.cr_bitfield_o.data.eq(self.dec.BT[2:5])
comb += self.cr_bitfield_o.ok.eq(1)
+ with m.Case(CRInSel.BFA_BFB_BF):
+ comb += self.cr_bitfield.data.eq(self.dec.FormCRB.BFA)
+ comb += self.cr_bitfield.ok.eq(1)
+ comb += self.cr_bitfield_b.data.eq(self.dec.FormCRB.BFB)
+ comb += self.cr_bitfield_b.ok.eq(1)
+ comb += self.cr_bitfield_o.data.eq(self.dec.FormCRB.BF)
+ comb += self.cr_bitfield_o.ok.eq(1)
with m.Case(CRInSel.BC):
comb += self.cr_bitfield.data.eq(self.dec.BC[2:5])
comb += self.cr_bitfield.ok.eq(1)
(e.read_cr1, self.dec_cr_in, "cr_bitfield", ),
(e.read_cr2, self.dec_cr_in, "cr_bitfield_b", ),
(e.read_cr3, self.dec_cr_in, "cr_bitfield_o", ),
- (e.write_cr, self.dec_cr_out, "cr_bitfield", )):
+ (e.write_cr, self.dec_cr_out, "cr_bitfield", )):
fromreg = getattr(cr, name)
comb += to_reg.data.eq(fromreg.data)
comb += to_reg.ok.eq(fromreg.ok)
CR1 = auto()
BF = auto()
BFA = auto()
+ BFB = auto()
BA = auto()
BB = auto()
BC = auto()
CR_3BIT = 2 # CR field; the CR register is 32-bit
BF = CR_3BIT
BFA = CR_3BIT
+ BFB = CR_3BIT
CR_5BIT = 3 # bit of the 32-bit CR register
BA = CR_5BIT
"cprop", # AV bitmanip
"crand", "crandc", "creqv",
"crnand", "crnor", "cror", "crorc", "crxor",
+ "crternlogi", # ternary bitmanip
"darn",
"dcbf", "dcbst", "dcbt", "dcbtst", "dcbz",
"divd", "divde", "divdeo", "divdeu",
OP_PEXT = 110
OP_SETBC = 111
OP_BMAT = 112 # bmatflip/xor/and - known by many names (vgbbd in Power)
+ OP_CRTERNLOG = 113
class SelType(Enum):
WHOLE_REG = 6
CR1 = 7
BA = 8
+ BFA_BFB_BF = 9
def __str__(self):
return self.name
# identifies register by type
def is_CR_3bit(regname):
- return regname in ['BF', 'BFA']
+ return regname in ['BF', 'BFA', 'BFB']
def is_CR_5bit(regname):
return regname in ['BA', 'BB', 'BC', 'BI', 'BT']
index1 = svp64_src.get('BA', None)
index2 = svp64_src.get('BB', None)
entry['sv_cr_in'] = "Idx_%d_%d" % (index1, index2)
+ elif cr_in == 'BFA_BFB_BF':
+ index1 = svp64_src.get('BFA', None)
+ index2 = svp64_src.get('BFB', None)
+ index3 = svp64_src.get('BF', None)
+ entry['sv_cr_in'] = "Idx_%d_%d_%d" % (index1, index2, index3)
# CRout a lot easier. ignore WHOLE_REG for now
cr_out = entry['CR out']
record["cr_in"] = "BA"
record["cr_in2"] = "BB"
del record["CR in"]
+ elif record["CR in"] == "BFA_BFB_BF":
+ record["cr_in"] = "BFA"
+ record["cr_in2"] = "BFB"
+ #record["cr_out"] = "BF" # only use BFA_BFB_BF when BF is a dest
+ del record["CR in"]
extra = []
for idx in range(0, 4):
regs[key] = _Reg(sels[key])
seltype[key] = _SelType.SRC
+ # should only be used when BF is also a destination
+ if sels["cr_in"] is _CRInSel.BFA_BFB_BF:
+ sels["cr_in"] = _CRIn2Sel.BFA
+ sels["cr_in2"] = _CRIn2Sel.BFB
+ idxs["cr_in2"] = idxs["cr_in"]
+ for key in ("cr_in", "cr_in2"):
+ regs[key] = _Reg(sels[key])
+ seltype[key] = _SelType.SRC
+
records = {}
for key in keys:
records[key] = {
from openpower.simulator.program import Program
from openpower.test.state import ExpectedState
from nmutil.sim_util import hash_256
-from openpower.decoder.isa.caller import SVP64State
+from openpower.decoder.isa.caller import SVP64State, CRFields
from openpower.util import log
import struct
import itertools
self.add_case(Program(lst, bigendian), initial_regs, expected=e)
+ def do_case_crternlogi(self, bf, bfa, bfb, imm, mask):
+ lst = [f"crternlogi 3,4,5,%d,%d" % (imm, mask)]
+ # set up CR
+ bf %= 2 ** 4
+ bfa %= 2 ** 4
+ bfb %= 2 ** 4
+ cr = CRFields()
+ cr.crl[3][0:4] = bf
+ cr.crl[4][0:4] = bfa
+ cr.crl[5][0:4] = bfb
+ initial_cr = cr.cr.asint()
+ print("initial cr", bin(initial_cr), bf, bfa, bfb)
+ print("mask tli", bin(mask), bin(imm))
+
+ lst = list(SVP64Asm(lst, bigendian))
+ e = ExpectedState(pc=4)
+ expected = bf&~mask # start at BF, mask overwrites masked bits only
+ checks = (bfb, bfa, bf) # LUT positions 1<<0=bfb 1<<1=bfa 1<<2=bf
+ for i in range(4):
+ lut_index = 0
+ for j, check in enumerate(checks):
+ if check & (1<<i):
+ lut_index |= 1<<j
+ maskbit = (mask >> i) & 0b1
+ if (imm & (1<<lut_index)) and maskbit:
+ expected |= 1<<i
+ e.crregs[3] = expected
+ e.crregs[4] = bfa
+ e.crregs[5] = bfb
+ self.add_case(Program(lst, bigendian), initial_regs=None, expected=e,
+ initial_cr=initial_cr)
+
+ def case_crternlogi_0(self):
+ self.do_case_crternlogi(0b1111,
+ 0b1100,
+ 0b1010,
+ 0x80, 0b1111)
+
+ def case_crternlogi_random(self):
+ for i in range(100):
+ rc = bool(hash_256(f"crternlogi rc {i}") & 1)
+ imm = hash_256(f"crternlogi imm {i}") & 0xFF
+ bf = hash_256(f"crternlogi bf {i}") % 2 ** 4
+ bfa = hash_256(f"crternlogi bfa {i}") % 2 ** 4
+ bfb = hash_256(f"crternlogi bfb {i}") % 2 ** 4
+ msk = hash_256(f"crternlogi msk {i}") % 2 ** 4
+ self.do_case_crternlogi(bf, bfa, bfb, imm, msk)
+
def do_case_ternlogi(self, rc, rt, ra, rb, imm):
rc_dot = "." if rc else ""
lst = [f"ternlogi{rc_dot} 3, 4, 5, {imm}"]