Revert "Revert "fix bug where pseudo-code assignments modify more than just the varia...
authorJacob Lifshay <programmerjake@gmail.com>
Fri, 20 Oct 2023 01:18:51 +0000 (18:18 -0700)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 22 Dec 2023 19:26:21 +0000 (19:26 +0000)
we need copy_assign_rhs

See https://bugs.libre-soc.org/show_bug.cgi?id=1066

This reverts commit bd3b54e83101217dc32da09083c6a3858fd7c600.

src/openpower/decoder/helpers.py
src/openpower/decoder/pseudo/parser.py
src/openpower/decoder/pseudo/pyfnwriter.py
src/openpower/decoder/pseudo/pywriter.py

index 99131c7fdb5457e8bc7bf5232e686e7e035d950b..2c93713484dbde0da0c774db94ef518df70888a3 100644 (file)
@@ -72,6 +72,35 @@ def EXTS128(value):
     return SelectableInt(exts(value.value, value.bits) & ((1 << 128)-1), 128)
 
 
+def copy_assign_rhs(inp):
+    """ implicitly added function call to all assignment RHSes.
+        This copies the passed-in value so later assignments to parts of the
+        LHS don't modify the RHS if it's a SelectableInt.
+
+        Example:
+        ```
+        # this needs to copy the SelectableInt instance in RA
+        # not just assign a reference to it to A
+        A <- RA
+        A[0] <- 1  # if the copy wasn't performed, we just modified RA too!
+        ```
+    """
+    if isinstance(inp, (str, int)):
+        return inp
+    if isinstance(inp, (SelectableInt, FieldSelectableInt)):
+        return SelectableInt(inp)
+    if isinstance(inp, BFPState):
+        return BFPState(inp)
+    if isinstance(inp, SelectableMSB0Fraction):
+        return SelectableMSB0Fraction(inp)
+    if isinstance(inp, tuple):
+        return tuple(map(copy_assign_rhs, inp))
+    if isinstance(inp, dict):
+        return {copy_assign_rhs(k): copy_assign_rhs(v) for k, v in inp.items()}
+    raise TypeError("tried to assign an unsupported type in pseudo-code",
+                    repr(type(inp)))
+
+
 # signed version of MUL
 def MULS(a, b):
     if isinstance(b, int):
index 8610c28469c9229383f7ed239c6beb0ae3836c8d..8e9132447ed8207875dc4058d4919ea14d207634 100644 (file)
@@ -405,7 +405,13 @@ class PowerParser:
                     self.read_regs.add(toname)
             if name and name in self.gprs:
                 self.write_regs.add(name)  # add to list of regs to write
-            p[0] = Assign(autoassign, name, p[1], p[3], iea_mode)
+
+            # copy rhs -- see openpower.decoder.helpers.copy_assign_rhs()'s
+            # documentation for why we need this
+            copy_fn = ast.Name("copy_assign_rhs", ast.Load())
+            rhs = ast.Call(copy_fn, (p[3],), [])
+            p[0] = self.Assign(autoassign, name, p[1], rhs, iea_mode,
+                               p.slice[2])
             if name:
                 self.declared_vars.add(name)
 
index 448b3e345b89fae8bb33fb06df5d451ec5c748f6..417706a4df0af58f1be1af6c285998a3862a607e 100644 (file)
@@ -21,7 +21,7 @@ header = """\
 from openpower.decoder.isa.caller import inject
 from openpower.decoder.helpers import (ISACallerHelper,
                                  ne, eq, gt, ge, lt, le, ltu, gtu, length,
-                                 trunc_divs, trunc_rems,
+                                 trunc_divs, trunc_rems, copy_assign_rhs,
                                 )
 from openpower.decoder.selectable_int import SelectableInt
 from openpower.decoder.selectable_int import selectconcat as concat
index b0772935a86ca6af4e1c1dd3d43d11f2783f28d0..6d436eef2f8f9877322bd6e91d2022f6c36a09b9 100644 (file)
@@ -23,7 +23,7 @@ header = """\
 from openpower.decoder.isa.caller import inject, instruction_info
 from openpower.decoder.helpers import (
                                  ne, eq, gt, ge, lt, le, ltu, gtu, length,
-                                 RANGE,
+                                 RANGE, copy_assign_rhs,
                                  ISACallerHelper,
                                 )
 from openpower.decoder.selectable_int import SelectableInt