From 5eb7cfb5cd7b7932fe42e3cc4dd21291dff0c0ad Mon Sep 17 00:00:00 2001 From: Jacob Lifshay Date: Fri, 21 Jul 2023 17:31:04 -0700 Subject: [PATCH] add cntlzdm/cnttzdm --- openpower/isa/fixedlogical.mdwn | 38 +++++++++++++++++ openpower/isatables/RM-1P-2S1D.csv | 2 + openpower/isatables/minor_31.csv | 2 + src/openpower/decoder/isa/caller.py | 3 +- src/openpower/decoder/power_enums.py | 2 +- src/openpower/test/logical/logical_cases.py | 46 ++++++++++++++++++++- 6 files changed, 89 insertions(+), 4 deletions(-) diff --git a/openpower/isa/fixedlogical.mdwn b/openpower/isa/fixedlogical.mdwn index c38dd04d..43aafe51 100644 --- a/openpower/isa/fixedlogical.mdwn +++ b/openpower/isa/fixedlogical.mdwn @@ -453,6 +453,44 @@ Special Registers Altered: CR0 (if Rc=1) +# Count Leading Zeros Doubleword under bit Mask + +X-Form + +* cntlzdm RA,RS,RB + +Pseudo-code: + + count <- 0 + do i = 0 to 63 + if (RB)[i] = 1 then + if (RS)[i] = 1 then leave + count <- count + 1 + RA <- EXTZ64(count) + +Special Registers Altered: + + None + +# Count Trailing Zeros Doubleword under bit Mask + +X-Form + +* cnttzdm RA,RS,RB + +Pseudo-code: + + count <- 0 + do i = 0 to 63 + if (RB)[63-i] = 1 then + if (RS)[63-i] = 1 then leave + count <- count + 1 + RA <- EXTZ64(count) + +Special Registers Altered: + + None + # Bit Permute Doubleword X-Form diff --git a/openpower/isatables/RM-1P-2S1D.csv b/openpower/isatables/RM-1P-2S1D.csv index 3a51f606..c96a038a 100644 --- a/openpower/isatables/RM-1P-2S1D.csv +++ b/openpower/isatables/RM-1P-2S1D.csv @@ -15,11 +15,13 @@ cmpeqb,CROP,,1P,EXTRA3,NO,d:BF,s:RA,s:RB,0,RA,RB,0,0,0,BF,0 1/0=fcmpo,NORMAL,,1P,EXTRA3,NO,d:BF,s:FRA,s:FRB,0,FRA,FRB,0,0,0,BF,0 4/0=ftdiv,NORMAL,,1P,EXTRA3,NO,d:BF,s:FRA,s:FRB,0,FRA,FRB,0,0,0,BF,0 bmask,NORMAL,,1P,EXTRA3,NO,d:RT,s:RA,s:RB,0,RA,RB,0,RT,0,0,0 +cntlzdm,NORMAL,,1P,EXTRA3,NO,d:RT,s:RA,s:RB,0,RS,RB,0,RA,0,0,0 addex,NORMAL,,1P,EXTRA3,NO,d:RT,s:RA,s:RB,0,RA,RB,0,RT,0,0,0 bpermd,NORMAL,,1P,EXTRA3,NO,d:RA,s:RS,s:RB,0,RS,RB,0,RA,0,0,0 modud,NORMAL,,1P,EXTRA3,NO,d:RT,s:RA,s:RB,0,RA,RB,0,RT,0,0,0 moduw,NORMAL,,1P,EXTRA3,NO,d:RT,s:RA,s:RB,0,RA,RB,0,RT,0,0,0 cmpb,CROP,,1P,EXTRA3,NO,d:RA,s:RS,s:RB,0,RS,RB,0,RA,0,0,0 +cnttzdm,NORMAL,,1P,EXTRA3,NO,d:RT,s:RA,s:RB,0,RS,RB,0,RA,0,0,0 modsd,NORMAL,,1P,EXTRA3,NO,d:RT,s:RA,s:RB,0,RA,RB,0,RT,0,0,0 modsw,NORMAL,,1P,EXTRA3,NO,d:RT,s:RA,s:RB,0,RA,RB,0,RT,0,0,0 26/6=fmrgow,NORMAL,,1P,EXTRA3,NO,d:FRT,s:FRA,s:FRB,0,FRA,FRB,0,FRT,0,0,0 diff --git a/openpower/isatables/minor_31.csv b/openpower/isatables/minor_31.csv index 9579c7d4..b10dbf76 100644 --- a/openpower/isatables/minor_31.csv +++ b/openpower/isatables/minor_31.csv @@ -27,8 +27,10 @@ opcode,unit,internal op,in1,in2,in3,out,CR in,CR out,inv A,inv out,cry in,cry ou 0b0000100000,ALU,OP_CMP,RA,RB,NONE,NONE,NONE,BF,1,0,ONE,0,NONE,0,0,0,0,0,0,NONE,0,0,cmpl,X,,, 0b0011000000,,,RA,RB,NONE,NONE,NONE,BF,,,,,,,,,,,,,,,cmprb,X,,, 0b0000111010,LOGICAL,OP_CNTZ,RS,NONE,NONE,RA,NONE,CR0,0,0,ZERO,0,NONE,0,0,0,0,0,0,RC,0,0,cntlzd,X,,, +0b0000111011,LOGICAL,OP_CNTZ,RS,RB,NONE,RA,NONE,NONE,0,0,ZERO,0,NONE,0,0,0,0,0,0,NONE,0,0,cntlzdm,X,,0, 0b0000011010,LOGICAL,OP_CNTZ,RS,NONE,NONE,RA,NONE,CR0,0,0,ZERO,0,NONE,0,0,0,0,1,0,RC,0,0,cntlzw,X,,, 0b1000111010,LOGICAL,OP_CNTZ,RS,NONE,NONE,RA,NONE,CR0,0,0,ZERO,0,NONE,0,0,0,0,0,0,RC,0,0,cnttzd,X,,, +0b1000111011,LOGICAL,OP_CNTZ,RS,RB,NONE,RA,NONE,NONE,0,0,ZERO,0,NONE,0,0,0,0,0,0,NONE,0,0,cnttzdm,X,,0, 0b1000011010,LOGICAL,OP_CNTZ,RS,NONE,NONE,RA,NONE,CR0,0,0,ZERO,0,NONE,0,0,0,0,1,0,RC,0,0,cnttzw,X,,, 0b1011110011,,,,,RT,,,,,,,,,,,,,,,,,,darn,X,,, 0b0001010110,ALU,OP_NOP,NONE,NONE,NONE,NONE,NONE,NONE,0,0,ZERO,0,NONE,0,0,0,0,0,0,NONE,0,1,dcbf,X,,, diff --git a/src/openpower/decoder/isa/caller.py b/src/openpower/decoder/isa/caller.py index 3b8d8694..b79295cc 100644 --- a/src/openpower/decoder/isa/caller.py +++ b/src/openpower/decoder/isa/caller.py @@ -1968,7 +1968,8 @@ class ISACaller(ISACallerHelper, ISAFPHelpers, StepLoop): "mffpr", "mffprs", "ctfpr", "ctfprs", "mtfpr", "mtfprs", - "maddsubrs", "maddrs", "msubrs" + "maddsubrs", "maddrs", "msubrs", + "cntlzdm", "cnttzdm", ]: illegal = False ins_name = dotstrp diff --git a/src/openpower/decoder/power_enums.py b/src/openpower/decoder/power_enums.py index 44ad2f54..1b37bf3e 100644 --- a/src/openpower/decoder/power_enums.py +++ b/src/openpower/decoder/power_enums.py @@ -742,7 +742,7 @@ _insns = [ "cbcdtd", "cdtbcd", "cmp", "cmpb", "cmpeqb", "cmpi", "cmpl", "cmpli", "cmprb", - "cntlzd", "cntlzw", "cnttzd", "cnttzw", + "cntlzd", "cntlzdm", "cntlzw", "cnttzd", "cnttzdm", "cnttzw", "cprop", # AV bitmanip "crand", "crandc", "creqv", "crnand", "crnor", "cror", "crorc", "crxor", diff --git a/src/openpower/test/logical/logical_cases.py b/src/openpower/test/logical/logical_cases.py index 8e9c4e0e..6e5709d0 100644 --- a/src/openpower/test/logical/logical_cases.py +++ b/src/openpower/test/logical/logical_cases.py @@ -1,7 +1,9 @@ -import unittest +from nmutil.sim_util import hash_256 +from openpower.test.state import ExpectedState from openpower.simulator.program import Program from openpower.endian import bigendian -from openpower.test.common import TestAccumulatorBase +from openpower.insndb.asm import SVP64Asm +from openpower.test.common import TestAccumulatorBase, skip_case import random @@ -124,3 +126,43 @@ class LogicalTestCase(TestAccumulatorBase): initial_regs[1] = random.randint(0, (1 << 64)-1) initial_regs[2] = random.randint(0, (1 << 64)-1) self.add_case(Program(lst, bigendian), initial_regs) + + def case_cntlzdm(self): + prog = Program(list(SVP64Asm(["cntlzdm 3,4,5"])), bigendian) + for case_idx in range(200): + gprs = [0] * 32 + gprs[4] = hash_256(f"cntlzdm {case_idx} r4") % 2**64 + gprs[5] = hash_256(f"cntlzdm {case_idx} r5") % 2**64 + e = ExpectedState(pc=4, int_regs=gprs) + count = 0 + for i in reversed(range(64)): + bit = 1 << i + if gprs[5] & bit: + if gprs[4] & bit: + break + count += 1 + e.intregs[3] = count + with self.subTest( + case_idx=case_idx, RS_in=hex(gprs[4]), + RB_in=hex(gprs[5]), expected_RA=hex(e.intregs[3])): + self.add_case(prog, gprs, expected=e) + + def case_cnttzdm(self): + prog = Program(list(SVP64Asm(["cnttzdm 3,4,5"])), bigendian) + for case_idx in range(200): + gprs = [0] * 32 + gprs[4] = hash_256(f"cnttzdm {case_idx} r4") % 2**64 + gprs[5] = hash_256(f"cnttzdm {case_idx} r5") % 2**64 + e = ExpectedState(pc=4, int_regs=gprs) + count = 0 + for i in range(64): + bit = 1 << i + if gprs[5] & bit: + if gprs[4] & bit: + break + count += 1 + e.intregs[3] = count + with self.subTest( + case_idx=case_idx, RS_in=hex(gprs[4]), + RB_in=hex(gprs[5]), expected_RA=hex(e.intregs[3])): + self.add_case(prog, gprs, expected=e) -- 2.30.2