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,NONE,0,0,ternlogi,TLI,,1,unofficial until submitted and approved/renumbered by the opf isa wg
-0010010110-,SHIFT_ROT,OP_GREV,RA,RB,NONE,RT,NONE,CR0,0,0,ZERO,0,NONE,0,0,0,0,0,0,NONE,0,0,grev,X,,1,unofficial until submitted and approved/renumbered by the opf isa wg
--011010110-,SHIFT_ROT,OP_GREV,RA,CONST_XBI,NONE,RT,NONE,CR0,0,0,ZERO,0,NONE,0,0,0,0,0,0,NONE,0,0,grevi,XB,,1,unofficial until submitted and approved/renumbered by the opf isa wg
-0010110110-,SHIFT_ROT,OP_GREV,RA,RB,NONE,RT,NONE,CR0,0,0,ZERO,0,NONE,0,0,0,0,1,0,NONE,0,0,grevw,X,,1,unofficial until submitted and approved/renumbered by the opf isa wg
-0011110110-,SHIFT_ROT,OP_GREV,RA,CONST_SH32,NONE,RT,NONE,CR0,0,0,ZERO,0,NONE,0,0,0,0,1,0,NONE,0,0,grevwi,X,,1,unofficial until submitted and approved/renumbered by the opf isa wg
+0010010110-,SHIFT_ROT,OP_GREV,RA,RB,NONE,RT,NONE,CR0,0,0,ZERO,0,NONE,0,0,0,0,0,0,RC,0,0,grev,X,,1,unofficial until submitted and approved/renumbered by the opf isa wg
+-011010110-,SHIFT_ROT,OP_GREV,RA,CONST_XBI,NONE,RT,NONE,CR0,0,0,ZERO,0,NONE,0,0,0,0,0,0,RC,0,0,grevi,XB,,1,unofficial until submitted and approved/renumbered by the opf isa wg
+0010110110-,SHIFT_ROT,OP_GREV,RA,RB,NONE,RT,NONE,CR0,0,0,ZERO,0,NONE,0,0,0,0,1,0,RC,0,0,grevw,X,,1,unofficial until submitted and approved/renumbered by the opf isa wg
+0011110110-,SHIFT_ROT,OP_GREV,RA,CONST_SH32,NONE,RT,NONE,CR0,0,0,ZERO,0,NONE,0,0,0,0,1,0,RC,0,0,grevwi,X,,1,unofficial until submitted and approved/renumbered by the opf isa wg
yield f".4byte {hex(instr)} # {asm}"
return
+ # XXX WARNING THESE ARE NOT APPROVED BY OPF ISA WG
+ # however we are out of space with opcode 22
+ if opcode in ('grev', 'grevi', 'grevw', 'grevwi',
+ 'grev.', 'grevi.', 'grevw.', 'grevwi.'):
+ po = 5
+ # _ matches fields in table at:
+ # https://libre-soc.org/openpower/sv/bitmanip/
+ xo = 0b1_0010_110
+ if 'w' in opcode:
+ xo |= 0b100_000
+ if 'i' in opcode:
+ xo |= 0b1000_000
+ Rc = 1 if '.' in opcode else 0
+ rt = int(fields[0])
+ ra = int(fields[1])
+ rb_imm = int(fields[2])
+ instr = po
+ instr = (instr << 5) | rt
+ instr = (instr << 5) | ra
+ if opcode == 'grevi' or opcode == 'grevi.':
+ assert 0 <= rb_imm < 64
+ instr = (instr << 6) | rb_imm
+ instr = (instr << 9) | xo
+ else:
+ assert 0 <= rb_imm < 32
+ instr = (instr << 5) | rb_imm
+ instr = (instr << 10) | xo
+ instr = (instr << 1) | Rc
+ asm = f"{opcode} {rt}, {ra}, {rb_imm}"
+ yield f".4byte {hex(instr)} # {asm}"
+ return
+
# identify if is a svp64 mnemonic
if not opcode.startswith('sv.'):
yield insn # unaltered
e.intregs[5] = rb
self.add_case(Program(lst, bigendian), initial_regs, expected=e)
+ def do_case_grev(self, w, is_imm, ra, rb):
+ bits = 32 if w else 64
+ masked_rb = rb % bits
+ if is_imm:
+ lst = [f"grev{'w' if w else ''}i. 3, 4, {masked_rb}"]
+ else:
+ lst = [f"grev{'w' if w else ''}. 3, 4, 5"]
+ initial_regs = [0] * 32
+ ra %= 2 ** 64
+ rb %= 2 ** 64
+ initial_regs[4] = ra
+ initial_regs[5] = rb
+ lst = list(SVP64Asm(lst, bigendian))
+ e = ExpectedState(pc=4)
+ expected = 0
+ for i in range(bits):
+ dest_bit = i ^ masked_rb
+ if ra & 2 ** i:
+ expected |= 2 ** dest_bit
+ e.intregs[3] = expected
+ e.intregs[4] = ra
+ e.intregs[5] = rb
+ if expected & 2 ** 63: # sign extend
+ expected -= 2 ** 64
+ eq = expected == 0
+ gt = expected > 0
+ lt = expected < 0
+ e.crregs[0] = (eq << 1) | (gt << 2) | (lt << 3)
+ self.add_case(Program(lst, bigendian), initial_regs, expected=e)
+
def case_ternlogi_0(self):
self.do_case_ternlogi(0x8000_0000_FFFF_0000,
0x8000_0000_FF00_FF00,
ra = hash_256(f"ternlogi ra {i}") % 2 ** 64
rb = hash_256(f"ternlogi rb {i}") % 2 ** 64
self.do_case_ternlogi(rt, ra, rb, imm)
+
+ def case_grev_random(self):
+ for i in range(100):
+ w = hash_256(f"grev w {i}") & 1
+ is_imm = hash_256(f"grev is_imm {i}") & 1
+ ra = hash_256(f"grev ra {i}") % 2 ** 64
+ rb = hash_256(f"grev rb {i}") % 2 ** 64
+ self.do_case_grev(w, is_imm, ra, rb)
+
+ def case_grevi_1(self):
+ self.do_case_grev(False, True, 14361919363078703450,
+ 8396479064514513069)
+
+ def case_grevi_2(self):
+ self.do_case_grev(True, True, 397097147229333315, 8326716970539357702)
+
+ def case_grevi_3(self):
+ self.do_case_grev(True, True, 0xFFFF_FFFF_0000_0000, 6)