From ca57c0af2e6851c58e30b2e67fce4416996f69ae Mon Sep 17 00:00:00 2001 From: Jacob Lifshay Date: Thu, 19 Oct 2023 18:18:51 -0700 Subject: [PATCH] Revert "Revert "fix bug where pseudo-code assignments modify more than just the variable being assigned to"" 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 | 29 ++++++++++++++++++++++ src/openpower/decoder/pseudo/parser.py | 8 +++++- src/openpower/decoder/pseudo/pyfnwriter.py | 2 +- src/openpower/decoder/pseudo/pywriter.py | 2 +- 4 files changed, 38 insertions(+), 3 deletions(-) diff --git a/src/openpower/decoder/helpers.py b/src/openpower/decoder/helpers.py index 99131c7f..2c937134 100644 --- a/src/openpower/decoder/helpers.py +++ b/src/openpower/decoder/helpers.py @@ -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): diff --git a/src/openpower/decoder/pseudo/parser.py b/src/openpower/decoder/pseudo/parser.py index 8610c284..8e913244 100644 --- a/src/openpower/decoder/pseudo/parser.py +++ b/src/openpower/decoder/pseudo/parser.py @@ -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) diff --git a/src/openpower/decoder/pseudo/pyfnwriter.py b/src/openpower/decoder/pseudo/pyfnwriter.py index 448b3e34..417706a4 100644 --- a/src/openpower/decoder/pseudo/pyfnwriter.py +++ b/src/openpower/decoder/pseudo/pyfnwriter.py @@ -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 diff --git a/src/openpower/decoder/pseudo/pywriter.py b/src/openpower/decoder/pseudo/pywriter.py index b0772935..6d436eef 100644 --- a/src/openpower/decoder/pseudo/pywriter.py +++ b/src/openpower/decoder/pseudo/pywriter.py @@ -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 -- 2.30.2