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):
+ return SelectableInt(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):
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] = Assign(autoassign, name, p[1], rhs, iea_mode)
if name:
self.declared_vars.add(name)
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
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