add sv.cmp (ffirst-5) decode/encode asm support
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Thu, 6 Oct 2022 11:43:00 +0000 (12:43 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Thu, 6 Oct 2022 11:43:00 +0000 (12:43 +0100)
* sv/trans/svp64.py needed a totally different ffirst handling
* CROpFF5RM needs to derive from FFPRRc0BaseRM and PredicateWidthBaseRM

src/openpower/decoder/power_insn.py
src/openpower/sv/trans/svp64.py
src/openpower/sv/trans/test_pysvp64dis.py

index b46d49cc33e97b34bc470e877ed08df0ec43f8bb..6099c817f3e08090e12932cfcbfa9c3a950a075a 100644 (file)
@@ -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):
index ab09917fe86b3c6135380b95b472daea9b71678b..1665087d52dafc4b60f7472e5f5762e3ac86d624 100644 (file)
@@ -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:
index 95817cc03324c5ac28a25ca2a7d5b3c4b468c70e..794f3ee0ee76a8197b46b2e4236338a4d6f46d19 100644 (file)
@@ -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)