From: Luke Kenneth Casson Leighton Date: Sun, 19 Jun 2022 16:10:21 +0000 (+0100) Subject: add maxs DRAFT instruction X-Git-Tag: sv_maxu_works-initial~382 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=e8f2840243978b2eaec77ae53aabb4765b83e1ec;p=openpower-isa.git add maxs DRAFT instruction https://libre-soc.org/openpower/sv/av_opcodes/ --- diff --git a/openpower/isa/av.mdwn b/openpower/isa/av.mdwn new file mode 100644 index 00000000..b4958b0d --- /dev/null +++ b/openpower/isa/av.mdwn @@ -0,0 +1,18 @@ + + +# Fixed Point Signed Max + +X-Form + +* maxs RT,RA,RB (Rc=0) +* maxs. RT,RA,RB (Rc=1) + +Pseudo-code: + + if (RA) >= (RB) then RT <- (RA) + else RT <- (RB) + +Special Registers Altered: + + CR0 (if Rc=1) + diff --git a/openpower/isatables/minor_22.csv b/openpower/isatables/minor_22.csv index 6e2b0c64..224eb1ae 100644 --- a/openpower/isatables/minor_22.csv +++ b/openpower/isatables/minor_22.csv @@ -3,3 +3,4 @@ opcode,unit,internal op,in1,in2,in3,out,CR in,CR out,inv A,inv out,cry in,cry ou -----011001,VL,OP_SVSHAPE,NONE,NONE,NONE,NONE,NONE,NONE,0,0,ZERO,0,NONE,0,0,0,0,0,0,NONE,0,0,svshape,SVM,,1,unofficial until submitted and approved/renumbered by the opf isa wg -----111001,VL,OP_SVREMAP,NONE,NONE,NONE,NONE,NONE,NONE,0,0,ZERO,0,NONE,0,0,0,0,0,0,NONE,0,0,svremap,SVRM,,1,unofficial until submitted and approved/renumbered by the opf isa wg -----10011-,VL,OP_SVSTEP,NONE,NONE,NONE,RT,NONE,CR0,0,0,ZERO,0,NONE,0,0,0,0,0,0,RC,0,0,svstep,SVL,,1,unofficial until submitted and approved/renumbered by the opf isa wg +0111001110-,ALU,OP_MINMAX,RA,RB,NONE,RT,NONE,CR0,0,0,ZERO,0,NONE,0,0,0,0,0,0,RC,0,0,maxs,X,,1,unofficial until submitted and approved/renumbered by the opf isa wg diff --git a/src/openpower/decoder/isa/caller.py b/src/openpower/decoder/isa/caller.py index afa3f76e..c8a60c4e 100644 --- a/src/openpower/decoder/isa/caller.py +++ b/src/openpower/decoder/isa/caller.py @@ -1268,7 +1268,19 @@ class ISACaller(ISACallerHelper, ISAFPHelpers): illegal = False ins_name = 'ffadds' - if re.fullmatch(r'ternlogi\.?|grevw?i?\.?', asmop or ''): + # and min/max/su + if asmop in ['mins', 'maxs', 'minu', 'maxu', + 'mins.', 'maxs.', 'minu.', 'maxu.']: + illegal = False + ins_name = asmop + + # and anything ternlog + if asmop.startswith('ternlog'): + illegal = False + ins_name = asmop + + # and anything grev + if asmop.startswith('grev'): illegal = False ins_name = asmop diff --git a/src/openpower/decoder/isa/test_caller_bitmanip_av.py b/src/openpower/decoder/isa/test_caller_bitmanip_av.py new file mode 100644 index 00000000..9c4788fc --- /dev/null +++ b/src/openpower/decoder/isa/test_caller_bitmanip_av.py @@ -0,0 +1,38 @@ +""" Decoder tests + +related bugs: + + * +""" + +import unittest +import sys + +# These tests utilize the run_hdl=False parameter to compare +# simulator with expected states +from soc.simple.test.test_runner import TestRunner +from openpower.test.bitmanip.av_cases import AVTestCase + + +if __name__ == "__main__": + + # allow list of testing to be selected by command-line + testing = sys.argv[1:] + sys.argv = sys.argv[:1] + + if not testing: + testing = ['bitmanipav'] + + unittest.main(exit=False) + suite = unittest.TestSuite() + + # dictionary of data for tests + tests = {'bitmanipav': AVTestCase().test_data} + + # walk through all tests, those requested get added + for tname, data in tests.items(): + if tname in testing: + suite.addTest(TestRunner(data, run_hdl=False)) + + runner = unittest.TextTestRunner() + runner.run(suite) diff --git a/src/openpower/decoder/power_enums.py b/src/openpower/decoder/power_enums.py index d5a97ccc..a54cc270 100644 --- a/src/openpower/decoder/power_enums.py +++ b/src/openpower/decoder/power_enums.py @@ -304,6 +304,7 @@ _insns = [ "maddhd", "maddhdu", "maddld", # INT multiply-and-add "mcrf", "mcrxr", "mcrxrx", "mfcr/mfocrf", # CR mvs "mfmsr", "mfspr", + "mins", "maxs", "minu", "maxu", # AV bitmanip "modsd", "modsw", "modud", "moduw", "mtcrf/mtocrf", "mtmsr", "mtmsrd", "mtspr", "mulhd", "mulhdu", "mulhw", "mulhwu", "mulld", "mulldo", @@ -442,6 +443,7 @@ class MicrOp(Enum): OP_TERNLOG = 86 OP_FETCH_FAILED = 87 OP_GREV = 88 + OP_MINMAX = 89 @unique diff --git a/src/openpower/sv/trans/svp64.py b/src/openpower/sv/trans/svp64.py index ef618b79..af13e7a7 100644 --- a/src/openpower/sv/trans/svp64.py +++ b/src/openpower/sv/trans/svp64.py @@ -417,6 +417,21 @@ class SVP64Asm: yield f".4byte {hex(instr)} # {asm}" return + # and maxs + # XXX WARNING THESE ARE NOT APPROVED BY OPF ISA WG + if opcode.startswith('maxs'): + fields = list(map(int, fields)) + insn = 22 << (31-5) # opcode 22, bits 0-5 + insn |= fields[0] << (31-10) # RT , bits 6-10 + insn |= fields[1] << (31-15) # RA , bits 11-15 + insn |= fields[2] << (31-20) # RB , bits 16-20 + insn |= 0b0111001110 << (31-30) # XO , bits 21..30 + if opcode == 'maxs.': + insn |= 1 << (31-31) # Rc=1 , bit 31 + log("maxs", bin(insn)) + yield ".long 0x%x" % insn + return + # identify if is a svp64 mnemonic if not opcode.startswith('sv.'): yield insn # unaltered @@ -1287,6 +1302,10 @@ if __name__ == '__main__': 'sv.ld 5.v, 4(1.v)', 'sv.svstep. 2.v, 4, 0', ] + lst = [ + 'maxs 3,12,5', + 'maxs. 3,12,5', + ] isa = SVP64Asm(lst, macros=macros) log("list", list(isa)) asm_process() diff --git a/src/openpower/test/bitmanip/av_cases.py b/src/openpower/test/bitmanip/av_cases.py new file mode 100644 index 00000000..66161d77 --- /dev/null +++ b/src/openpower/test/bitmanip/av_cases.py @@ -0,0 +1,99 @@ +from openpower.sv.trans.svp64 import SVP64Asm +import random +from openpower.test.common import TestAccumulatorBase +from openpower.endian import bigendian +from openpower.simulator.program import Program +from openpower.decoder.selectable_int import SelectableInt +from openpower.decoder.power_enums import XER_bits +from openpower.decoder.isa.caller import special_sprs +from openpower.decoder.helpers import exts +from openpower.test.state import ExpectedState +import unittest + + +class AVTestCase(TestAccumulatorBase): + + def cse_0_maxs(self): + lst = ["maxs 3, 1, 2"] + lst = list(SVP64Asm(lst, bigendian)) + + initial_regs = [0] * 32 + initial_regs[1] = 0xc523e996a8ff6215 + initial_regs[2] = 0xe1e5b9cc9864c4a8 + e = ExpectedState(pc=4) + e.intregs[1] = 0xc523e996a8ff6215 + e.intregs[2] = 0xe1e5b9cc9864c4a8 + e.intregs[3] = 0xe1e5b9cc9864c4a8 + self.add_case(Program(lst, bigendian), initial_regs, expected=e) + + def cse_1_maxs(self): + lst = ["maxs 3, 1, 2"] + lst = list(SVP64Asm(lst, bigendian)) + + initial_regs = [0] * 32 + initial_regs[1] = 0xe1e5b9cc9864c4a8 + initial_regs[2] = 0xc523e996a8ff6215 + e = ExpectedState(pc=4) + e.intregs[1] = 0xe1e5b9cc9864c4a8 + e.intregs[2] = 0xc523e996a8ff6215 + e.intregs[3] = 0xe1e5b9cc9864c4a8 + self.add_case(Program(lst, bigendian), initial_regs, expected=e) + + def cse_2_maxs_(self): + lst = [f"maxs. 3, 1, 2"] + lst = list(SVP64Asm(lst, bigendian)) + + initial_regs = [0] * 32 + initial_regs[1] = 0xc523e996a8ff6215 + initial_regs[2] = 0xe1e5b9cc9864c4a8 + e = ExpectedState(pc=4) + e.intregs[1] = 0xc523e996a8ff6215 + e.intregs[2] = 0xe1e5b9cc9864c4a8 + e.intregs[3] = 0xe1e5b9cc9864c4a8 + e.crregs[0] = 0x8 + self.add_case(Program(lst, bigendian), initial_regs, expected=e) + + def cse_3_maxs_(self): + lst = [f"maxs. 3, 1, 2"] + lst = list(SVP64Asm(lst, bigendian)) + + initial_regs = [0] * 32 + initial_regs[1] = 0xc523e996a8ff6215 + initial_regs[2] = 0 + e = ExpectedState(pc=4) + e.intregs[1] = 0xc523e996a8ff6215 + e.intregs[2] = 0 + e.intregs[3] = 0 + e.crregs[0] = 0x2 # RT is zero + self.add_case(Program(lst, bigendian), initial_regs, expected=e) + + def cse_4_maxs_(self): + lst = [f"maxs. 3, 1, 2"] + lst = list(SVP64Asm(lst, bigendian)) + + initial_regs = [0] * 32 + initial_regs[1] = 1 + initial_regs[2] = 0 + e = ExpectedState(pc=4) + e.intregs[1] = 1 + e.intregs[2] = 0 + e.intregs[3] = 1 + e.crregs[0] = 0x4 # RT is +ve + self.add_case(Program(lst, bigendian), initial_regs, expected=e) + + def case_5_maxs_(self): + """max negative number compared against +ve number + """ + lst = [f"maxs. 3, 1, 2"] + lst = list(SVP64Asm(lst, bigendian)) + + initial_regs = [0] * 32 + initial_regs[1] = 1 + initial_regs[2] = 0x8000_0000_0000_0000 + e = ExpectedState(pc=4) + e.intregs[1] = 1 + e.intregs[2] = 0x8000_0000_0000_0000 + e.intregs[3] = 1 + e.crregs[0] = 0x4 # RT is +ve + self.add_case(Program(lst, bigendian), initial_regs, expected=e) +