Пример #1
0
 def set_reg(self, reg, expr, name):
     assert self.finalop is None
     if isinstance(reg, (IsaReg, IsaVisibleReg)):
         val = self.make_temp(expr, name, reg.dmask)
         if reg in self.inregs and reg not in self.regs and self.inregs[
                 reg] == val:
             pass
         elif reg in self.regs and self.regs[reg] == val:
             pass
         else:
             if isinstance(reg, IsaVisibleReg):
                 self.ops.append(DecopWrite(reg, self.encap(val)))
             self.regs[reg] = val
     elif isinstance(reg, IsaSplitReg):
         for start, len_, field in reg.fields:
             if isinstance(field, int):
                 pass
             else:
                 self.set_reg(field, expr >> start & bflmask(len_),
                              name + '_' + field.name)
     elif isinstance(reg, IsaSubReg):
         mask = bflmask(reg.len_) << reg.start
         res = (self.get_reg(reg.reg) & ~mask) | (expr << reg.start & mask)
         self.set_reg(reg.reg, res, name)
     else:
         raise DecodeError("unk reg")
Пример #2
0
 def emit_not(self, size, dst, src):
     size = 8 << size
     res = src ^ bflmask(size)
     self.block.set_reg(dst, res, self.name)
     self.block.set_reg(self.isa.of, ExprConst(0), self.name + '_of')
     self.block.set_reg(self.isa.sf, res >> (size - 1), self.name + '_sf')
     self.block.set_reg(self.isa.zf, ExprEq(res, 0), self.name + '_zf')
Пример #3
0
 def emit_ld(self, name, space, sz, addr):
     #addr = self.make_temp(addr, name + '_addr', space.amask)
     res = TempVar(name + '_data', bflmask(space.bsz * sz))
     self.locals.add(res)
     #self.ops.append(DecopLd(space, sz, res, self.encap(addr)))
     self.ops.append(DecopLd(space, sz, res, addr))
     return self.encap(res)
Пример #4
0
 def get_reg(self, reg):
     assert self.finalop is None
     if isinstance(reg, (IsaReg, IsaVisibleReg)):
         if reg in self.regs:
             return self.encap(self.regs[reg])
         elif reg not in self.inregs:
             val = InVar(self.name + '_in_' + reg.name, reg.mask)
             self.locals.add(val)
             self.inregs[reg] = val
             return self.encap(val)
         else:
             return self.encap(self.inregs[reg])
     elif isinstance(reg, IsaSplitReg):
         res = ExprConst(0)
         for start, len_, field in reg.fields:
             if isinstance(field, int):
                 res |= field << start
             else:
                 res |= self.get_reg(field) << start
         return res
     elif isinstance(reg, IsaSubReg):
         res = self.get_reg(reg.reg)
         res >>= reg.start
         res &= bflmask(reg.len_)
         return res
     else:
         raise DecodeError("unk reg")
Пример #5
0
 def findlivemasks(self, vars_, mask):
     for bf in self.bitfields:
         imask = shl(mask & bf.mask, -bf.shift)
         if bf.sign is not None:
             if imask & -1 << bf.sign:
                 imask |= 1 << bf.sign
             imask &= bflmask(bf.sign + 1)
         bf.expr.findlivemasks(vars_, imask)
Пример #6
0
 def __init__(self, name, fields):
     self.name = name
     self.mask = 0
     self.dmask = 0
     self.fields = fields
     for start, len_, field in fields:
         mask = bflmask(len_) << start
         if isinstance(field, (IsaReg, IsaVisibleReg)):
             self.dmask |= mask
             self.mask |= mask
         elif isinstance(field, int):
             self.mask |= field << start
         else:
             raise TypeError("Unknown field type")
Пример #7
0
 def _add(self, expr, sign, shift, mask):
     if sign is not None and not (mask & shl(-1, shift + sign + 1)):
         sign = None
     if not mask:
         return
     imask = shl(mask, -shift)
     if sign is not None:
         if imask & -1 << sign:
             imask |= 1 << sign
         imask &= bflmask(sign + 1)
     if isinstance(expr, ExprBigOr):
         self._add(ExprConst(expr.const), sign, shift, mask)
         for sexpr, ssign, sshift, smask in expr.bitfields:
             self._add(
                 sexpr,
                 *self._reduce(ssign, sshift, smask, sign, shift, mask))
         return
     if isinstance(expr, ExprAnd):
         e1 = expr.e1.mask(imask)
         e2 = expr.e2.mask(imask)
         if isinstance(e1, ExprConst):
             e2, e1 = e1, e2
         if isinstance(e2, ExprConst):
             self._add(e1, *self._reduce(None, 0, e2.val, sign, shift,
                                         mask))
             return
     if isinstance(expr, ExprOr):
         self._add(expr.e1, sign, shift, mask)
         self._add(expr.e2, sign, shift, mask)
         return
     if isinstance(expr, ExprConst):
         val = shl(sext(expr.val, sign), shift) & mask
         self.const |= val
         self.bmask |= val
         return
     if isinstance(expr, ExprShl) and isinstance(expr.e2, ExprConst):
         self._add(expr.e1,
                   *self._reduce(None, expr.e2.val, -1, sign, shift, mask))
         return
     if isinstance(expr, ExprSext) and isinstance(expr.e2, ExprConst):
         self._add(expr.e1,
                   *self._reduce(expr.e2.val, 0, -1, sign, shift, mask))
         return
     expr = expr.mask(imask)
     if not expr.bmask & imask:
         return
     self.bmask |= shl(sext(expr.bmask, sign), shift) & mask
     self.bitfields.append(Bitfield(expr, sign, shift, mask))
Пример #8
0
 def emit_add(self, size, dst, src1, src2, subop):
     size = 8 << size
     s2 = src2
     if subop in [1, 3]:
         s2 += self.isa.cf
     if subop in [2, 3]:
         s2 = -src2
     res = src1 + s2
     if dst is not None:
         self.block.set_reg(dst, res, self.name)
     self.block.set_reg(self.isa.cf, res >> size, self.name + '_cf')
     sign = self.block.encap(self.block.make_temp(res >> (size - 1), self.name + '_sign', 1))
     self.block.set_reg(self.isa.of, sign ^ ExprLt(ExprSext(src1, size - 1), ExprSext(-s2, size - 1)), self.name + '_of')
     self.block.set_reg(self.isa.sf, sign, self.name + '_sf')
     if subop == 2:
         self.block.set_reg(self.isa.zf, ExprEq(src1, src2), self.name + '_zf')
     else:
         self.block.set_reg(self.isa.zf, ExprEq(res & bflmask(size), 0), self.name + '_zf')
Пример #9
0
 def emit_shift(self, size, dst, src1, src2, subop):
     shcnt = src2 & bflmask(size + 3)
     size = 8 << size
     if subop in [4, 0xc]:
         res = src1 << shcnt
         if subop == 0xc:
             res |= self.block.get_reg(self.isa.cf) << (shcnt - 1)
         cf = res >> size
     else:
         cf = src1 >> (shcnt - 1)
         if subop == 7:
             src1 = ExprSext(src1, size - 1)
         elif subop == 0xd:
             src1 |= self.block.get_reg(self.isa.cf) << size
         res = src1 >> shcnt
     self.block.set_reg(dst, res, self.name)
     self.block.set_reg(self.isa.cf, cf, self.name + '_cf')
     if self.isa.version != 0:
         self.block.set_reg(self.isa.of, ExprConst(0), self.name + '_of')
         self.block.set_reg(self.isa.sf, res >> (size - 1), self.name + '_sf')
         self.block.set_reg(self.isa.zf, ExprEq(res, 0), self.name + '_zf')
Пример #10
0
 def __init__(self, version):
     self.r = [IsaReg('r{}'.format(idx), bflmask(32)) for idx in range(16)]
     self.rh = [IsaSubReg(self.r[idx], 0, 16) for idx in range(16)]
     self.rb = [IsaSubReg(self.r[idx], 0, 8) for idx in range(16)]
     self.rs = [self.rb, self.rh, self.r]
     self.sp = IsaReg('sp', bflmask(32) & ~3)
     self.iv0 = IsaVisibleReg('iv0', bflmask(32))
     self.iv1 = IsaVisibleReg('iv1', bflmask(32))
     self.tv = IsaVisibleReg('tv', bflmask(32))
     flags = []
     self.cf = IsaReg('cf', 1)
     self.of = IsaReg('of', 1)
     self.sf = IsaReg('sf', 1)
     self.zf = IsaReg('zf', 1)
     for idx in range(8):
         flags.append((idx, 1, IsaReg('p{}'.format(idx), 1)))
     flags.append((8, 1, self.cf))
     flags.append((9, 1, self.of))
     flags.append((10, 1, self.sf))
     flags.append((11, 1, self.zf))
     flags.append((16, 1, IsaVisibleReg('ie0', 1)))
     flags.append((17, 1, IsaVisibleReg('ie1', 1)))
     flags.append((20, 1, IsaReg('is0', 1)))
     flags.append((21, 1, IsaReg('is1', 1)))
     flags.append((24, 1, IsaVisibleReg('ta', 1)))
     self.flags = IsaSplitReg('flags', flags)
     self.xtargets = IsaReg('xtargets', 0x7707)
     self.xdbase = IsaReg('xdbase', bflmask(32))
     self.xcbase = IsaReg('xdbase', bflmask(32))
     self.version = version
     self.sr = [
         self.iv0, self.iv1, None, self.tv,
         self.sp, None, self.xcbase, self.xdbase,  # XXX PC
         self.flags, None, None, self.xtargets,  # XXX crypto crap
         None, None, None, None,  # XXX tstatus
     ]
     self.data = IsaMem('D', 8, bflmask(32), ISA_MEM_RW)
     self.iowr = IsaExec('iowr', [], [bflmask(32), bflmask(32)])
     self.iowrs = IsaExec('iowrs', [], [bflmask(32), bflmask(32)])
     self.iord = IsaExec('iord', [bflmask(32)], [bflmask(32)])
     self.sleep = IsaExec('sleep', [], [1])
     self.xcwait = IsaExec('xcwait', [], [])
     self.xdwait = IsaExec('xdwait', [], [])
     self.xcld = IsaExec('xcld', [], [bflmask(3), bflmask(32), bflmask(32), bflmask(16), bflmask(3)])
     self.xdld = IsaExec('xdld', [], [bflmask(3), bflmask(32), bflmask(32), bflmask(16), bflmask(3)])
     self.xdst = IsaExec('xdst', [], [bflmask(3), bflmask(32), bflmask(32), bflmask(16), bflmask(3)])
     if version < 4:
         self.codemem = IsaMem('C', 8, bflmask(16), ISA_MEM_RO)
     else:
         self.codemem = IsaMem('C', 8, bflmask(24), ISA_MEM_RO)
     self.stackptr = self.sp
     self.stackmem = self.data
Пример #11
0
Файл: op.py Проект: mwkmwkmwk/ax
 def fold(self, vars_, reason):
     return DecopSt(
         self.space, self.sz,
         self.addr.fold(vars_, reason).mask(self.space.amask),
         self.src.fold(vars_,
                       reason).mask(bflmask(self.space.bsz * self.sz)))
Пример #12
0
Файл: op.py Проект: mwkmwkmwk/ax
 def findlivemasks(self, vars_):
     self.addr.findlivemasks(vars_, self.space.amask)
     self.src.findlivemasks(vars_, bflmask(self.space.bsz * self.sz))
Пример #13
0
 def __init__(self):
     self.cacc = IsaReg('cacc', bflmask(32))
     self.cmd = IsaReg('cmd', 0x1fffc)
     self.lutidx = IsaReg('lutidx', bflmask(5))
     self.datahi = IsaReg('datahi', bflmask(8))
     self.dacc = IsaReg('dacc', bflmask(32))
     self.data = IsaReg('data', bflmask(32))
     self.csr = [self.cacc, self.cmd, self.lutidx, self.datahi]
     self.dsr = [self.dacc, self.data]
     self.r = [IsaReg('r{}'.format(idx), bflmask(32)) for idx in range(8)]
     self.g = [IsaReg('g{}'.format(idx), bflmask(32)) for idx in range(6)]
     self.p = [1] + [
         IsaReg('p{}'.format(idx), bflmask(1)) for idx in range(1, 4)
     ]
     self.pred = IsaSplitReg('pred',
                             [(idx, 1, self.p[idx]) for idx in range(4)])
     self.gpr = self.r + self.g + [None, self.pred]
     self.lut = IsaMem('lut', 32, bflmask(5), ISA_MEM_RO)
     self.submit = IsaExec('submit', (), (0x1fffc, bflmask(32), bflmask(8)))
     self.codemem = IsaMem('C', 64, 0x1ff, ISA_MEM_RO)
Пример #14
0
    def decode(self):
        if self.pred or self.pnot:
            # XXX
            raise DecodeError('predicate')
        if self.submit:
            cmd = self.block.get_reg(isa.cmd)
            data = self.block.get_reg(isa.data)
            datahi = self.block.get_reg(isa.datahi)
            self.block.emit_exec(self.name, isa.submit, [cmd, data, datahi])
            # XXX auto-increment

        if self.cbfend >= self.cbfstart:
            cbfmask = (2 << self.cbfend) - (1 << self.cbfstart)
        else:
            cbfmask = 0

        pres = ExprConst(0)
        if self.cop == CINSRT_R:
            if self.cshdir == 0:
                ssrc = self.get_csrc1() << self.cshift
            else:
                ssrc = self.get_csrc1() >> self.cshift
            tmp = ssrc & cbfmask
            c2d = cres = tmp | (self.get_csrc2() & ~cbfmask)
            pres = ExprEq(tmp, 0)
        elif self.cop == CINSRT_I:
            c2d = cres = (self.get_csrc2()
                          & ~cbfmask) | (self.cimm6 << self.cbfstart & cbfmask)
        elif self.cop == CMOV_I:
            c2d = cres = ExprConst(self.cimm18)
        elif self.cop == CEXTRADD8:
            c2d = (self.get_csrc1() & cbfmask) >> self.cbfstart
            cres = ((c2d + self.cimm8) & 0xff) | (c2d & ~0xff)
        else:
            assert 0

        if self.dbfend >= self.dbfstart:
            dbfmask = (2 << self.dbfend) - (1 << self.dbfstart)
        else:
            dbfmask = 0

        ddst_skip = False
        if self.dop == DINSRT_R:
            if self.dshdir == 0:
                ssrc = self.get_dsrc1() << self.dshift
            else:
                ssrc = ExprSext(self.get_dsrc1(), 31) >> self.dshift
            tmp = ssrc & dbfmask
            dres = tmp | (self.get_dsrc2() & ~dbfmask)
            if self.c2den:
                dres = (c2d & cbfmask) | (dres & ~cbfmask)
            pres = ExprEq(tmp, 0)
        elif self.dop == DINSRT_I:
            dres = (self.get_dsrc2() & ~dbfmask) | (self.dimm6 << self.dbfstart
                                                    & dbfmask)
            if self.c2den:
                dres = (c2d & cbfmask) | (dres & ~cbfmask)
        elif self.dop == DMOV_I:
            dres = ExprConst(self.dimm23)
        elif self.dop == DADD16_I:
            src1 = (self.get_dsrc1() >> (self.dhi * 16)) & 0xffff
            sum_ = (src1 + self.dimm16) & 0xffff
            dres = (self.get_dsrc1()
                    & ~(0xffff << 16 * self.dhi)) | (sum_ << (16 * self.dhi))
            pres = sum_ >> 15 & 1
            ddst_skip = self.ddstskip
        elif self.dop == DLOGOP16_I:
            src = self.get_dsrc1()
            if self.dhi:
                src = src >> 16
            src = src & 0xffff
            if self.dlogop == 0:
                res = ExprConst(self.dimm16)
            elif self.dlogop == 1:
                res = src & self.dimm16
            elif self.dlogop == 2:
                res = src | self.dimm16
            elif self.dlogop == 3:
                res = src ^ self.dimm16
            if self.dhi:
                dres = (self.get_dsrc1() & ~0xffff0000) | (res << 16)
            else:
                dres = (self.get_dsrc1() & ~0xffff) | res
            pres = ExprEq(res, 0)
        elif self.dop == DSHIFT_R:
            shift = self.get_csrc1() & 0x1f
            if self.dshdir == 0:
                dres = self.get_dsrc1() << shift
            else:
                dres = ExprSext(self.get_dsrc1(), 31) >> shift
        elif self.dop == DSEXT:
            bfstart = max(self.dbfstart, self.dshift)
            if self.dbfend >= bfstart:
                dbfmask = (2 << self.dbfend) - (1 << bfstart)
            else:
                dbfmask = 0
            pres = self.get_dsrc2() >> self.dshift & 1
            dres = (self.get_dsrc2() & ~dbfmask) | (
                ExprSext(self.get_dsrc2(), self.dshift) & dbfmask)
        elif self.dop == DADD16_R:
            src1 = (self.get_dsrc1() >> (self.dhi * 16)) & 0xffff
            src2 = (self.get_csrc1() >> (self.dhi2 * 16)) & 0xffff
            if self.dsub == 0:
                sum_ = (src1 + src2) & 0xffff
            else:
                sum_ = (src2 - src2) & 0xffff
            dres = (self.get_dsrc1()
                    & ~(0xffff << 16 * self.dhi)) | (sum_ << (16 * self.dhi))
            pres = sum_ >> 15 & 1
        else:
            assert 0

        self.block.set_reg(isa.csr[self.cdst], cres, self.name + '_cres')
        dres = self.block.encap(
            self.block.make_temp(dres, self.name + '_dres', bflmask(32)))
        if not ddst_skip:
            self.block.set_reg(isa.dsr[self.ddst], dres,
                               self.name + '_dres_dsr')
        if self.drdst != 14:
            self.block.set_reg(isa.gpr[self.drdst], dres,
                               self.name + '_dres_gpr')
        if self.pdst:
            self.block.set_reg(isa.p[self.pdst], pres, self.name + '_pres')

        if self.exit:
            self.block.emit_exit()