From 3191ca25e16c50d0f37a6b072b21b7471514097f Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Thu, 6 Oct 2022 12:43:00 +0100 Subject: [PATCH] add sv.cmp (ffirst-5) decode/encode asm support * sv/trans/svp64.py needed a totally different ffirst handling * CROpFF5RM needs to derive from FFPRRc0BaseRM and PredicateWidthBaseRM --- src/openpower/decoder/power_insn.py | 6 ++++-- src/openpower/sv/trans/svp64.py | 23 ++++++++++++++++------- src/openpower/sv/trans/test_pysvp64dis.py | 4 ++++ 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/src/openpower/decoder/power_insn.py b/src/openpower/decoder/power_insn.py index b46d49cc..6099c817 100644 --- a/src/openpower/decoder/power_insn.py +++ b/src/openpower/decoder/power_insn.py @@ -1747,15 +1747,17 @@ class CROpFF3RM(VLiBaseRM, ZZBaseRM, CROpBaseRM): yield from super().specifiers(record=record, mode="ff") -class CROpFF5RM(VLiBaseRM, DZBaseRM, SZBaseRM, CROpBaseRM): +class CROpFF5RM(FFPRRc0BaseRM, PredicateWidthBaseRM, + VLiBaseRM, DZBaseRM, SZBaseRM, CROpBaseRM): """cr_op: ffirst 5-bit mode""" VLi: BaseRM[20] inv: BaseRM[21] + RC1: BaseRM[19] # cheat: set RC=1 based on ffirst mode being set dz: BaseRM[22] sz: BaseRM[23] def specifiers(self, record): - yield from super().specifiers(record=record) + yield from super().specifiers(record=record, mode="ff") class CROpRM(CROpBaseRM): diff --git a/src/openpower/sv/trans/svp64.py b/src/openpower/sv/trans/svp64.py index ab09917f..1665087d 100644 --- a/src/openpower/sv/trans/svp64.py +++ b/src/openpower/sv/trans/svp64.py @@ -1359,25 +1359,34 @@ class SVP64Asm: ###################################### # "failfirst" modes - elif failfirst is not False: # sv_mode == 0b01: + elif failfirst is not False and not is_cr: # sv_mode == 0b01: assert src_zero == 0, "dest-zero not allowed in failfirst mode" if failfirst == 'RC1': mode |= (0b1 << SVP64MODE.RC1) # sets RC1 mode mode |= (dst_zero << SVP64MODE.DZ) # predicate dst-zeroing - if not is_cr: - assert rc_mode == False, "ffirst RC1 only ok when Rc=0" + assert rc_mode == False, "ffirst RC1 only ok when Rc=0" elif failfirst == '~RC1': mode |= (0b1 << SVP64MODE.RC1) # sets RC1 mode mode |= (dst_zero << SVP64MODE.DZ) # predicate dst-zeroing mode |= (0b1 << SVP64MODE.INV) # ... with inversion - if not is_cr: - assert rc_mode == False, "ffirst RC1 only ok when Rc=0" + assert rc_mode == False, "ffirst RC1 only ok when Rc=0" else: assert dst_zero == 0, "dst-zero not allowed in ffirst BO" - if not is_cr: - assert rc_mode, "ffirst BO only possible when Rc=1" + assert rc_mode, "ffirst BO only possible when Rc=1" mode |= (failfirst << SVP64MODE.BO_LSB) # set BO + # (crops is really different) + elif failfirst is not False and is_cr: + if failfirst in ['RC1', '~RC1']: + mode |= (src_zero << SVP64MODE.SZ) # predicate src-zeroing + mode |= (dst_zero << SVP64MODE.DZ) # predicate dst-zeroing + if failfirst == '~RC1': + mode |= (0b1 << SVP64MODE.INV) # ... with inversion + else: + assert dst_zero == src_zero, "dz must equal sz in ffirst BO" + mode |= (failfirst << SVP64MODE.BO_LSB) # set BO + svp64_rm.crops.zz = dst_zero + ###################################### # "saturation" modes elif sv_mode == 0b10: diff --git a/src/openpower/sv/trans/test_pysvp64dis.py b/src/openpower/sv/trans/test_pysvp64dis.py index 95817cc0..794f3ee0 100644 --- a/src/openpower/sv/trans/test_pysvp64dis.py +++ b/src/openpower/sv/trans/test_pysvp64dis.py @@ -308,6 +308,10 @@ class SVSTATETestCase(unittest.TestCase): expected = [ "sv.cmp *4,1,*0,1", "sv.cmp/ff=RC1 *4,1,*0,1", + "sv.cmp/ff=~RC1 *4,1,*0,1", + "sv.cmp/ff=RC1/m=r3/sz *4,1,*0,1", + "sv.cmp/dz/ff=RC1/m=r3 *4,1,*0,1", + "sv.cmp/dz/ff=RC1/m=r3/sz *4,1,*0,1", ] self._do_tst(expected) -- 2.30.2