From 8e33fbbd17c75efe47cdec52e41a35303cddda12 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Sun, 19 Jun 2022 19:14:58 +0100 Subject: [PATCH] add the rest of min/max DRAFT av opcodes https://bugs.libre-soc.org/show_bug.cgi?id=863 --- openpower/isa/av.mdwn | 50 ++++++++++++++- openpower/isatables/minor_22.csv | 3 + src/openpower/sv/trans/svp64.py | 17 +++-- src/openpower/test/bitmanip/av_cases.py | 82 +++++++++++++++++++++++-- 4 files changed, 142 insertions(+), 10 deletions(-) diff --git a/openpower/isa/av.mdwn b/openpower/isa/av.mdwn index b4958b0d..7f10262a 100644 --- a/openpower/isa/av.mdwn +++ b/openpower/isa/av.mdwn @@ -9,10 +9,58 @@ X-Form Pseudo-code: - if (RA) >= (RB) then RT <- (RA) + if (RA) > (RB) then RT <- (RA) + else RT <- (RB) + +Special Registers Altered: + + CR0 (if Rc=1) + +# Fixed Point Unsighed Max + +X-Form + +* maxu RT,RA,RB (Rc=0) +* maxu. RT,RA,RB (Rc=1) + +Pseudo-code: + + if (RA) >u (RB) then RT <- (RA) else RT <- (RB) Special Registers Altered: CR0 (if Rc=1) +# Fixed Point Signed Min + +X-Form + +* mins RT,RA,RB (Rc=0) +* mins. RT,RA,RB (Rc=1) + +Pseudo-code: + + if (RA) < (RB) then RT <- (RA) + else RT <- (RB) + +Special Registers Altered: + + CR0 (if Rc=1) + +# Fixed Point Unsighed Min + +X-Form + +* minu RT,RA,RB (Rc=0) +* minu. 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 224eb1ae..4c4834f8 100644 --- a/openpower/isatables/minor_22.csv +++ b/openpower/isatables/minor_22.csv @@ -4,3 +4,6 @@ opcode,unit,internal op,in1,in2,in3,out,CR in,CR out,inv A,inv out,cry in,cry ou -----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 +0011001110-,ALU,OP_MINMAX,RA,RB,NONE,RT,NONE,CR0,0,0,ZERO,0,NONE,0,0,0,0,0,0,RC,0,0,maxu,X,,1,unofficial until submitted and approved/renumbered by the opf isa wg +0101001110-,ALU,OP_MINMAX,RA,RB,NONE,RT,NONE,CR0,0,0,ZERO,0,NONE,0,0,0,0,0,0,RC,0,0,mins,X,,1,unofficial until submitted and approved/renumbered by the opf isa wg +0001001110-,ALU,OP_MINMAX,RA,RB,NONE,RT,NONE,CR0,0,0,ZERO,0,NONE,0,0,0,0,0,0,RC,0,0,minu,X,,1,unofficial until submitted and approved/renumbered by the opf isa wg diff --git a/src/openpower/sv/trans/svp64.py b/src/openpower/sv/trans/svp64.py index af13e7a7..2c10a23f 100644 --- a/src/openpower/sv/trans/svp64.py +++ b/src/openpower/sv/trans/svp64.py @@ -417,16 +417,25 @@ class SVP64Asm: yield f".4byte {hex(instr)} # {asm}" return - # and maxs + # and min/max # XXX WARNING THESE ARE NOT APPROVED BY OPF ISA WG - if opcode.startswith('maxs'): + if opcode in ['mins', 'maxs', 'minu', 'maxu', + 'mins.', 'maxs.', 'minu.', 'maxu.']: + if opcode[:4] == 'maxs': + XO = 0b0111001110 + if opcode[:4] == 'maxu': + XO = 0b0011001110 + if opcode[:4] == 'mins': + XO = 0b0101001110 + if opcode[:4] == 'minu': + XO = 0b0001001110 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 |= XO << (31-30) # XO , bits 21..30 + if opcode.endswith('.'): insn |= 1 << (31-31) # Rc=1 , bit 31 log("maxs", bin(insn)) yield ".long 0x%x" % insn diff --git a/src/openpower/test/bitmanip/av_cases.py b/src/openpower/test/bitmanip/av_cases.py index 66161d77..913c5c43 100644 --- a/src/openpower/test/bitmanip/av_cases.py +++ b/src/openpower/test/bitmanip/av_cases.py @@ -13,7 +13,7 @@ import unittest class AVTestCase(TestAccumulatorBase): - def cse_0_maxs(self): + def case_0_maxs(self): lst = ["maxs 3, 1, 2"] lst = list(SVP64Asm(lst, bigendian)) @@ -26,7 +26,7 @@ class AVTestCase(TestAccumulatorBase): e.intregs[3] = 0xe1e5b9cc9864c4a8 self.add_case(Program(lst, bigendian), initial_regs, expected=e) - def cse_1_maxs(self): + def case_1_maxs(self): lst = ["maxs 3, 1, 2"] lst = list(SVP64Asm(lst, bigendian)) @@ -39,7 +39,7 @@ class AVTestCase(TestAccumulatorBase): e.intregs[3] = 0xe1e5b9cc9864c4a8 self.add_case(Program(lst, bigendian), initial_regs, expected=e) - def cse_2_maxs_(self): + def case_2_maxs_(self): lst = [f"maxs. 3, 1, 2"] lst = list(SVP64Asm(lst, bigendian)) @@ -53,7 +53,7 @@ class AVTestCase(TestAccumulatorBase): e.crregs[0] = 0x8 self.add_case(Program(lst, bigendian), initial_regs, expected=e) - def cse_3_maxs_(self): + def case_3_maxs_(self): lst = [f"maxs. 3, 1, 2"] lst = list(SVP64Asm(lst, bigendian)) @@ -67,7 +67,7 @@ class AVTestCase(TestAccumulatorBase): e.crregs[0] = 0x2 # RT is zero self.add_case(Program(lst, bigendian), initial_regs, expected=e) - def cse_4_maxs_(self): + def case_4_maxs_(self): lst = [f"maxs. 3, 1, 2"] lst = list(SVP64Asm(lst, bigendian)) @@ -97,3 +97,75 @@ class AVTestCase(TestAccumulatorBase): e.crregs[0] = 0x4 # RT is +ve self.add_case(Program(lst, bigendian), initial_regs, expected=e) + def case_0_mins(self): + lst = ["mins 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] = 0xc523e996a8ff6215 + self.add_case(Program(lst, bigendian), initial_regs, expected=e) + + def case_2_mins_(self): + lst = [f"mins. 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] = 0xc523e996a8ff6215 + e.crregs[0] = 0x8 + self.add_case(Program(lst, bigendian), initial_regs, expected=e) + + def case_5_mins_(self): + """min negative number compared against +ve number + """ + lst = [f"mins. 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] = 0x8000_0000_0000_0000 + e.crregs[0] = 0x8 # RT is -ve + self.add_case(Program(lst, bigendian), initial_regs, expected=e) + + def case_0_maxu(self): + lst = ["maxu 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 case_5_minu_(self): + """min +ve numbers + """ + lst = [f"minu. 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] = 0x8000_0000_0000_0000 + e.crregs[0] = 0x8 # RT is -ve + self.add_case(Program(lst, bigendian), initial_regs, expected=e) + -- 2.30.2