add more tests and fix missing corner case
authorJacob Lifshay <programmerjake@gmail.com>
Mon, 26 Sep 2022 23:01:03 +0000 (16:01 -0700)
committerJacob Lifshay <programmerjake@gmail.com>
Mon, 26 Sep 2022 23:01:03 +0000 (16:01 -0700)
openpower/isa/prefix_codes.mdwn
src/openpower/test/prefix_codes/prefix_codes_cases.py

index fc6d7be9547813679499f957710590efa2f3a565..11f5e62e944085eaeab8de323af256452315b6aa 100644 (file)
@@ -25,6 +25,8 @@ Pseudo-code:
         if in_bits = 1 then
             if ra_used | (_RA = 0) then
                 early_stop <- 0b1
+                if decoded != 1 then  # error: stopped in the middle of a code
+                    so_bit <- 0b1
                 leave
             ra_used <- 0b1
             in_bit <- (RA)[63]
index 114963b80a5971d66c9cfa9721b532c2312a7590..1e2212b6a76530d93dffcf531e8c285f389a51cd 100644 (file)
@@ -1,3 +1,5 @@
+import functools
+import itertools
 from openpower.test.common import TestAccumulatorBase
 from openpower.sv.trans.svp64 import SVP64Asm
 from openpower.test.state import ExpectedState
@@ -30,18 +32,16 @@ def reference_pcdec(supported_codes, input_bits, max_count):
     assert input_bits.lstrip("01") == "", "input_bits must be binary bits"
     retval = []
     current_code = ""
-    overflow = False
     for bit in input_bits:
         current_code += bit
-        if len(current_code) > 6:
-            overflow = True
+        if len(current_code) > 5:
             break
         if current_code in supported_codes:
             retval.append(current_code)
             current_code = ""
             if len(retval) >= max_count:
                 break
-    return retval, overflow
+    return retval, current_code != ""
 
 
 CODE_2 = "0"
@@ -52,6 +52,11 @@ CODE_37 = "10111"
 CODES = {CODE_2, CODE_7, CODE_19, CODE_35, CODE_37}
 
 
+@functools.lru_cache()
+def _cached_program(*instrs):
+    return Program(list(SVP64Asm(list(instrs))), bigendian=False)
+
+
 class PrefixCodesCases(TestAccumulatorBase):
     def check_pcdec(self, supported_codes, input_bits, once, src_loc_at=0):
         # type: (set[str], str, bool, int) -> None
@@ -79,11 +84,12 @@ class PrefixCodesCases(TestAccumulatorBase):
             rev_input_bits = rev_input_bits[64:]
             expected_ra_used = decoded_bits_len > len(rev_input_bits)
             if expected_ra_used:
-                expected_RS = (RA_val + 2 ** 64) >> decoded_bits_len
+                expected_RS = (RA_val + 2 ** 64) >> (decoded_bits_len
+                                                     - len(rev_input_bits))
         RC_val = int("1" + rev_input_bits, 2)
         if expected_RS is None:
             expected_RS = RC_val >> decoded_bits_len
-        lst = list(SVP64Asm([f"pcdec. 4,{RA},6,5,{int(once)}"]))
+        lst = [f"pcdec. 4,{RA},6,5,{int(once)}"]
         gprs = [0] * 32
         gprs[6] = RB_val
         if RA:
@@ -95,8 +101,8 @@ class PrefixCodesCases(TestAccumulatorBase):
         e.crregs[0] = (expected_ra_used * 8 + expected_GT * 4
                        + expected_EQ * 2 + expected_SO)
         with self.subTest(supported_codes=supported_codes,
-                          input_bits=original_input_bits):
-            self.add_case(Program(lst, False), gprs, expected=e,
+                          input_bits=original_input_bits, once=once):
+            self.add_case(_cached_program(*lst), gprs, expected=e,
                           src_loc_at=src_loc_at + 1)
 
     def case_pcdec_empty(self):
@@ -170,3 +176,18 @@ class PrefixCodesCases(TestAccumulatorBase):
 
     def case_pcdec_overlong_code_once(self):
         self.check_pcdec(CODES, "_".join([CODE_2, CODE_19, "10000000"]), True)
+
+    def case_pcdec_incomplete_code(self):
+        self.check_pcdec(CODES, "_".join([CODE_19[:-1]]), False)
+
+    def case_pcdec_incomplete_code_once(self):
+        self.check_pcdec(CODES, "_".join([CODE_19[:-1]]), True)
+
+    def case_rest(self):
+        for repeat in range(8):
+            for bits in itertools.product("01", repeat=repeat):
+                self.check_pcdec(CODES, "".join(bits), False)
+                self.check_pcdec(CODES, "".join(bits), True)
+                # 60 so we cover both less and more than 64 bits
+                self.check_pcdec(CODES, "".join(bits) + "0" * 60, False)
+                self.check_pcdec(CODES, "".join(bits) + "0" * 60, True)