def __new__(cls, expr, mask=-1): mask = lowmask(mask) self = super().__new__(cls) self.const = 0 self.bmask = 0 self.parts = [] self._add(expr, mask, 1) return self.simplify(mask)
def findlivemasks(self, vars_, mask): for part in self.parts: part.expr.findlivemasks(vars_, lowmask(mask))
def mask(self, mask): e1 = self.e1.mask(lowmask(mask)) e2 = self.e2.mask(lowmask(mask)) return e1 * e2
def findlivemasks(self, vars_, mask): self.e1.findlivemasks(vars_, lowmask(mask)) self.e2.findlivemasks(vars_, lowmask(mask))
def find_sp(self): self.spoffsets = {} if self.isa.stackptr is None: return if self.isa.stackptr not in self.eblock.outregs[0]: return osp = self.eblock.get_out(0, self.isa.stackptr) offsets = {} queue = [] offsets[osp] = 0 queue.append((self.eblock.outs[0], self.isa.stackptr, 0)) spmask = self.isa.stackptr.mask while queue: block, reg, off = queue.pop() ivar = block.get_in(reg) if ivar not in offsets: offsets[ivar] = off elif offsets[ivar] != off and offsets[ivar] is not None: offsets[ivar] = None else: continue newoff = {ivar: offsets[ivar]} for op in block.ops: if not isinstance(op, DecopAssign): continue aconv = op.src.as_offset() if aconv is None: continue avar, aoff, amask = aconv if avar not in newoff: continue # XXX not correct if amask | spmask != amask: continue if newoff[avar] is None: newoff[op.dst] = None else: newoff[op.dst] = (newoff[avar] + aoff) & lowmask(spmask) offsets[op.dst] = newoff[op.dst] for out, regs in zip(block.outs, block.outregs): if out is not None: for reg in regs: if regs[reg] in newoff: queue.append((out, reg, newoff[regs[reg]])) for block in self.cblocks.values(): newops = [] subst = {} for op in block.ops: if isinstance(op, DecopAssign) and op.dst in offsets and offsets[ op.dst] is not None: if offsets[op.dst] == 0: subst[op.dst] = osp else: newops.append( DecopAssign( op.dst, Block.encap(osp) + offsets[op.dst] & spmask)) else: newops.append(op) block.ops = newops block.localdefs[osp] = None block.substvars(subst) self.spoffsets = offsets