def new(cls, e1, e2): if isinstance(e1, ExprConst) and isinstance(e2, ExprConst): return ExprConst(e1.val & e2.val) if (e1.bmask & e2.bmask) == 0: return ExprConst(0) if isinstance(e1, ExprConst): e1, e2 = e2, e1 if isinstance(e2, ExprConst): return ExprBigOr(super().new(e1, e2)) return super().new(e1, e2)
def emit_logop(self, dst, src1, src2, subop): if subop == 4: res = src1 & src2 elif subop == 5: res = src1 | src2 elif subop == 6: res = src1 ^ src2 self.block.set_reg(dst, res, self.name) if self.isa.version != 0: self.block.set_reg(self.isa.cf, ExprConst(0), self.name + '_cf') self.block.set_reg(self.isa.of, ExprConst(0), self.name + '_of') self.block.set_reg(self.isa.sf, res >> 31, self.name + '_sf') self.block.set_reg(self.isa.zf, ExprEq(res, 0), self.name + '_zf')
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')
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")
def encap(cls, val): if isinstance(val, Var): return ExprVar(val) elif isinstance(val, int): return ExprConst(val) else: assert 0
def _add(self, expr, mask, mul): if not mul: return if isinstance(expr, ExprSum): self._add(ExprConst(expr.const), mask, mul) for sexpr, smul in expr.parts: self._add(sexpr, mask, smul * mul) return if isinstance(expr, ExprAdd): self._add(expr.e1, mask, mul) self._add(expr.e2, mask, mul) return if isinstance(expr, ExprSub): self._add(expr.e1, mask, mul) self._add(expr.e2, mask, -mul) return if isinstance(expr, ExprMul) and isinstance(expr.e2, ExprConst): self._add(expr.e1, mask, mul * expr.e2.val) return if isinstance(expr, ExprMul) and isinstance(expr.e1, ExprConst): self._add(expr.e2, mask, mul * expr.e1.val) return if isinstance(expr, ExprConst): self.const += expr.val * mul self.const &= mask return self.parts.append(Part(expr.mask(mask), mul))
def __init__(self, func, block): self.func = func self.name = block.name self.start = block.start self.end = block.end self.inregs = block.inregs.copy() self.ops = block.ops[:] self.finalop = block.finalop or DecopJmp(block.isa, ExprConst( block.end)) self.outs = block.outs[:] self.ins = set() self.localdefs = {} self.livevars = Counter() self.outregs = [regs.copy() for regs in block.outregs] self.loop = None self.join = None self.brk = None self.used = False self.label = False for reg in self.inregs: self.localdefs[self.inregs[reg]] = reg for op in self.ops: for out in op.outs: self.localdefs[out] = op for out in self.finalop.outs: self.localdefs[out] = self.finalop
def new(cls, e1, e2): if isinstance(e1, ExprConst) and isinstance(e2, ExprConst): return ExprConst(shl(e1.val, e2.val)) if isinstance(e2, ExprConst): if e2.val == 0: return e1 return ExprBigOr(super().new(e1, e2)) return super().new(e1, e2)
def new(cls, e1, e2): if isinstance(e1, ExprConst) and isinstance(e2, ExprConst): return ExprConst(e1.val * e2.val) if isinstance(e1, ExprConst): e1, e2 = e2, e1 if isinstance(e2, ExprConst): return ExprSum(super().new(e1, e2)) return super().new(e1, e2)
def emit_extr(self, dst, src1, src2, subop): low = src2 & 0x1f size = (src2 >> 5 & 0x1f) + 1 res = src1 >> low & ((ExprConst(1) << size) - 1) if subop == 3: # XXX doesn't match hw if low+size > 0x20 res = ExprSext(res, size - 1) self.block.set_reg(dst, res, self.name) self.block.set_reg(self.isa.sf, res >> 31, self.name + '_sf') self.block.set_reg(self.isa.zf, ExprEq(res, 0), self.name + '_zf')
def get_csrc2(self): if self.csrc2 == 0: return ExprConst(0) elif self.csrc2 == 1: return self.block.get_reg(isa.cacc) elif self.csrc2 == 2: return self.block.get_reg(isa.dacc) elif self.csrc2 == 3: return self.get_csrc1() else: assert 0
def simplify(self): self.bmask = self.const for expr in self.exprs: self.bmask |= expr.bmask if not self.exprs: return ExprConst(self.const) if self.const == 1: for expr in list(self.exprs): if isinstance(expr, ExprBinBool): self.const = 0 self.exprs ^= {expr, expr.negate()} if not self.const and len(self.exprs) == 1: return list(self.exprs)[0] return self
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))
def simplify(self, mask=-1): newparts = [] for part in self.parts: newparts.append(Part(part.expr.mask(mask), part.mul)) self.parts = newparts self.const &= mask self.bmask = highmask(self.const) for part in self.parts: self.bmask |= highmask(part.expr.bmask * part.mul) if not self.parts: return ExprConst(self.const) if not self.const and len(self.parts) == 1: part = self.parts[0] if part.mul == 1: return part.expr return self
def _add(self, expr, mask): if isinstance(expr, ExprBigXor): self._add(ExprConst(expr.const), mask) for sexpr in expr.exprs: self._add(sexpr, mask) return if isinstance(expr, ExprXor): self._add(expr.e1, mask) self._add(expr.e2, mask) return if isinstance(expr, ExprConst): self.const ^= expr.val return expr = expr.mask(mask) if not expr.bmask & mask: return self.exprs ^= {expr}
def simplify(self, mask): newbitfields = [] for bf in self.bitfields: if (bf.mask | self.const) == self.const: pass elif ((mask & shl(sext(bf.expr.bmask, bf.sign), bf.shift)) | bf.mask) == bf.mask: newbitfields.append(Bitfield(bf.expr, bf.sign, bf.shift, -1)) else: newbitfields.append(bf) self.bitfields = newbitfields if not self.bitfields: return ExprConst(self.const) if not self.const and len(self.bitfields) == 1: bf = self.bitfields[0] if bf.mask == -1 and bf.sign is None and bf.shift == 0: return bf.expr return self
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')
def __new__(cls, e1, e2): if isinstance(e1, int): e1 = ExprConst(e1) if isinstance(e2, int): e2 = ExprConst(e2) return cls.new(e1, e2)
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()
def __init__(self, isa, name, block, pos): self.isa = isa self.name = name self.block = block self.pos = pos self.origpos = pos op = op0 = self.get_byte() if op < 0xc0: size = op >> 6 op = op & 0x3f if op < 0x30: subop = op & 0xf op >>= 4 if op == 0 and self.isa.version < 5: op1 = self.get_byte() reg1 = self.isa.rs[size][op1 & 0xf] reg2 = self.isa.r[op1 >> 4] imm = self.get_imm(0, 0) if subop == 0: block.emit_st(self.name, self.isa.data, 1 << size, block.get_reg(reg2) + (imm << size), block.get_reg(reg1)) else: raise DecodeError('sized low {:x}/{:x}'.format(op, subop)) elif op == 0 and self.isa.version >= 5: reg0 = isa.r[subop] imm = self.get_fimm(size + 1) block.set_reg(reg0, ExprConst(imm), self.name) elif op == 1 or (op == 2 and self.isa.version < 5): op1 = self.get_byte() reg1 = self.isa.rs[size][op1 & 0xf] reg2 = self.isa.rs[size][op1 >> 4] imm = self.get_imm(op == 2, 0) if subop in [0, 1, 2, 3]: self.emit_add(size, reg1, block.get_reg(reg2), ExprConst(imm), subop) elif subop in [4, 5, 7, 0xc, 0xd] and op == 1: self.emit_shift(size, reg1, block.get_reg(reg2), ExprConst(imm), subop) elif subop == 8 and op == 1: reg2 = self.isa.r[op1 >> 4] res = block.emit_ld(self.name, self.isa.data, 1 << size, block.get_reg(reg2) + (imm << size)) block.set_reg(reg1, res, self.name) else: raise DecodeError('sized low {:x}/{:x}'.format(op, subop)) elif op == 2 and self.isa.version >= 5: reg1 = self.isa.rs[size][op1 & 0xf] reg2 = self.isa.rs[size][op1 >> 4] # XXX st, st[sp], cmpu, cmps, cmp raise DecodeError('sized low {:x}/{:x}'.format(op, subop)) else: raise DecodeError('sized low {:x}/{:x}'.format(op, subop)) else: if op in [0x30, 0x31]: op1 = self.get_byte() subop = op1 & 0xf reg2 = self.isa.rs[size][op1 >> 4] imm = self.get_imm(op & 1, 0) if subop == 1: block.emit_st(self.name, self.isa.data, 1 << size, block.get_reg(self.isa.sp) + (imm << size), block.get_reg(reg2)) elif subop == 6 and self.isa.version >= 3: self.emit_add(size, None, block.get_reg(reg2), ExprConst(imm), 2) else: # XXX st, cmpu, cmps raise DecodeError('sized high {:x}/{:x}'.format(op, subop)) elif op == 0x34: op1 = self.get_byte() subop = op1 & 0xf reg2 = self.isa.rs[size][op1 >> 4] imm = self.get_imm(0, 0) if subop == 0: res = block.emit_ld(self.name, self.isa.data, 1 << size, block.get_reg(self.isa.sp) + (imm << size)) block.set_reg(reg2, res, self.name) else: raise DecodeError('sized high {:x}/{:x}'.format(op, subop)) elif op in [0x36, 0x37]: op1 = self.get_byte() subop = op1 & 0xf reg2 = self.isa.rs[size][op1 >> 4] imm = self.get_imm(op & 1, 0) if subop in [0, 1, 2, 3]: self.emit_add(size, reg2, self.block.get_reg(reg2), ExprConst(imm), subop) elif subop in [4, 5, 7, 0xc, 0xd] and op == 0x36: self.emit_shift(size, reg2, self.block.get_reg(reg2), ExprConst(imm), subop) else: raise DecodeError('sized high {:x}/{:x}'.format(op, subop)) elif op == 0x38 and self.isa.version < 5: op1 = self.get_byte() reg1 = self.isa.rs[size][op1 & 0xf] reg2 = self.isa.rs[size][op1 >> 4] op2 = self.get_byte() subop = op2 & 0xf if subop == 6 and self.isa.version >= 3: self.emit_add(size, None, block.get_reg(reg2), block.get_reg(reg1), 2) else: # XXX st, st[sp], cmpu, cmps raise DecodeError('sized high {:x}/{:x}'.format(op, subop)) elif op == 0x39: op1 = self.get_byte() reg1 = self.isa.rs[size][op1 & 0xf] reg2 = self.isa.rs[size][op1 >> 4] op2 = self.get_byte() subop = op2 & 0xf if subop == 0: self.emit_not(size, reg1, block.get_reg(reg2)) else: # XXX neg, mov/movf, hwswap raise DecodeError('sized high {:x}/{:x}'.format(op, subop)) elif op == 0x3b: op1 = self.get_byte() reg1 = self.isa.rs[size][op1 & 0xf] reg2 = self.isa.rs[size][op1 >> 4] op2 = self.get_byte() subop = op2 & 0xf if subop in [0, 1, 2, 3]: self.emit_add(size, reg2, block.get_reg(reg2), block.get_reg(reg1), subop) elif subop in [4, 5, 7, 0xc, 0xd]: self.emit_shift(size, reg2, block.get_reg(reg2), block.get_reg(reg1), subop) else: raise DecodeError('sized high {:x}/{:x}'.format(op, subop)) elif op == 0x3c: op1 = self.get_byte() reg1 = self.isa.rs[size][op1 & 0xf] reg2 = self.isa.rs[size][op1 >> 4] op2 = self.get_byte() subop = op2 & 0xf reg3 = self.isa.rs[size][op2 >> 4] if subop in [0, 1, 2, 3]: self.emit_add(size, reg3, block.get_reg(reg2), block.get_reg(reg1), subop) elif subop in [4, 5, 7, 0xc, 0xd]: self.emit_shift(size, reg3, block.get_reg(reg2), block.get_reg(reg1), subop) else: raise DecodeError('sized high {:x}/{:x}'.format(op, subop)) elif op == 0x3d: op1 = self.get_byte() subop = op1 & 0xf reg2 = self.isa.rs[size][op1 >> 4] if subop == 4: block.set_reg(reg2, ExprConst(0), self.name) else: # XXX not, neg, mov/movf, hswap, setf raise DecodeError('sized high {:x}/{:x}'.format(op, subop)) else: # XXX 32, 33, 35, 38[v5], 3a, 3e, 3f raise DecodeError('sized high {:x}'.format(op)) else: if op < 0xf0: subop = op & 0xf op >>= 4 if op in [0xc, 0xe]: op1 = self.get_byte() reg1 = self.isa.r[op1 & 0xf] reg2 = self.isa.r[op1 >> 4] imm = self.get_imm(op == 0xe, subop == 1) if subop in [3, 7] and self.isa.version >= 3: self.emit_extr(reg1, block.get_reg(reg2), imm, subop) elif subop in [4, 5, 6]: self.emit_logop(reg1, block.get_reg(reg2), imm, subop) elif subop == 0xf: self.emit_iord(reg1, block.get_reg(reg2) + imm * 4) else: # XXX other raise DecodeError('unsized low {:x}/{:x}'.format(op, subop)) elif op == 0xd and self.isa.version < 5: op1 = self.get_byte() reg1 = self.isa.r[op1 & 0xf] reg2 = self.isa.r[op1 >> 4] imm = self.get_imm(0, 0) block.emit_exec(self.name, self.isa.iowr, [block.get_reg(reg2) + imm * 4, block.get_reg(reg1)]) else: # XXX 0xd[old], 0xd[v5] raise DecodeError('unsized low {:x}/{:x}'.format(op, subop)) else: if op in [0xf0, 0xf1]: op1 = self.get_byte() reg2 = self.isa.r[op1 >> 4] subop = op1 & 0xf imm = self.get_imm(op & 1, subop in [1, 7]) if subop == 0: block.set_reg(reg2, isa.mulu(block.get_reg(reg2), imm), self.name) elif subop == 1: block.set_reg(reg2, isa.muls(block.get_reg(reg2), imm), self.name) #elif subop == 2 and op == 0xf0: # block.set_reg(reg2, ExprSext(block.get_reg(reg2), imm & 0x1f), self.name) elif subop == 3: block.set_reg(reg2, block.get_reg(reg2) & 0xffff | imm << 16, self.name) elif subop in [4, 5, 6]: self.emit_logop(reg2, block.get_reg(reg2), imm, subop) elif subop == 7: block.set_reg(reg2, ExprConst(imm), self.name) elif subop == 0xc and op == 0xf0: self.emit_xbit(reg2, block.get_reg(self.isa.flags), imm) else: # XXX 2, 9-11 raise DecodeError('unsized high {:x}/{:x}'.format(op, subop)) elif op in [0xf4, 0xf5]: op1 = self.get_byte() subop = op1 & 0x3f imm = self.get_imm(op & 1, subop < 0x20 or subop == 0x30) if subop < 0x20: target = ExprConst(imm + self.origpos) if subop == 0xe: block.emit_jmp(self.name, target) else: if subop in range(0x00, 0x0c): pred = block.get_reg(self.isa.flags.fields[subop][2]) elif subop in range(0x0c, 0x0e): pred = block.get_reg(self.isa.cf) | block.get_reg(self.isa.zf) if subop == 0xc: pred = pred ^ 1 elif subop in range(0x10, 0x1c): pred = block.get_reg(self.isa.flags.fields[subop - 0x10][2]) ^ 1 elif subop in range(0x1c, 0x20): pred = block.get_reg(self.isa.sf) ^ block.get_reg(self.isa.of) if subop in [0x1c, 0x1d]: pred |= block.get_reg(self.isa.zf) if subop in [0x1c, 0x1f]: pred ^= 1 else: raise DecodeError('bra pred {}'.format(subop)) block.emit_bra(self.name, pred, target) elif subop == 0x20: block.emit_jmp(self.name, ExprConst(imm)) elif subop == 0x21: block.emit_call(self.name, ExprConst(imm)) elif subop == 0x28 and op == 0xf4: block.emit_exec(self.name, self.isa.sleep, [block.get_reg(self.isa.flags) >> (imm & 0x1f)]) elif subop == 0x30: block.set_reg(isa.sp, block.get_reg(isa.sp) + imm, self.name) elif subop == 0x31 and op == 0xf4: block.set_reg(isa.flags, block.get_reg(isa.flags) | 1 << imm, self.name) elif subop == 0x32 and op == 0xf4: block.set_reg(isa.flags, block.get_reg(isa.flags) & ~(1 << imm), self.name) elif subop == 0x33 and op == 0xf4: block.set_reg(isa.flags, block.get_reg(isa.flags) ^ 1 << imm, self.name) else: # XXX 3c raise DecodeError('unsized high {:x}/{:x}'.format(op, subop)) elif op == 0xf8: op1 = self.get_byte() subop = op1 & 0xf if subop == 0: block.emit_ret() elif subop == 1: block.emit_iret() elif subop == 2: block.emit_exit() elif subop == 3: block.emit_exec(self.name, self.isa.xdwait, []) elif subop == 7: block.emit_exec(self.name, self.isa.xcwait, []) else: # XXX iret, f8/6, trap raise DecodeError('unsized high {:x}/{:x}'.format(op, subop)) elif op == 0xf9: op1 = self.get_byte() subop = op1 & 0xf reg2 = isa.r[op1 >> 4] if subop == 0: block.set_reg(isa.sp, block.get_reg(isa.sp) - 4, self.name) block.emit_st(self.name, self.isa.data, 4, block.get_reg(isa.sp), block.get_reg(reg2)) elif subop == 5: block.emit_call(self.name, block.get_reg(reg2)) else: # XXX add[sp], mpush, bra, itlb, bset, bclr, btgl raise DecodeError('unsized high {:x}/{:x}'.format(op, subop)) elif op == 0xfa: op1 = self.get_byte() op2 = self.get_byte() subop = op2 & 0xf reg1 = isa.r[op1 & 0xf] reg2 = isa.r[op1 >> 4] if subop == 0: block.emit_exec(self.name, self.isa.iowr, [block.get_reg(reg2), block.get_reg(reg1)]) elif subop == 1: block.emit_exec(self.name, self.isa.iowrs, [block.get_reg(reg2), block.get_reg(reg1)]) elif subop in [4, 5, 6]: if subop == 4: pshift = 0 spec = self.isa.xcld base = self.isa.xcbase elif subop == 5: pshift = 8 spec = self.isa.xdld base = self.isa.xdbase elif subop == 6: pshift = 12 spec = self.isa.xdst base = self.isa.xdbase port = block.get_reg(self.isa.xtargets) >> pshift base = block.get_reg(base) offs = block.get_reg(reg2) p2 = block.get_reg(reg1) addr = p2 & 0xffff size = p2 >> 16 block.emit_exec(self.name, spec, [port, base, offs, addr, size]) else: # XXX xcld, xdld. xdst, setp raise DecodeError('unsized high {:x}/{:x}'.format(op, subop)) elif op == 0xfc: op1 = self.get_byte() subop = op1 & 0xf reg2 = isa.r[op1 >> 4] if subop == 0: tmp = block.emit_ld(self.name, self.isa.data, 4, block.get_reg(isa.sp)) block.set_reg(isa.sp, block.get_reg(isa.sp) + 4, self.name + '_sp') block.set_reg(reg2, tmp, self.name) else: raise DecodeError('unsized high {:x}/{:x}'.format(op, subop)) elif op == 0xfd: op1 = self.get_byte() op2 = self.get_byte() subop = op2 & 0xf reg1 = isa.r[op1 & 0xf] reg2 = isa.r[op1 >> 4] if subop in [0, 1]: self.emit_mul(reg2, block.get_reg(reg2), block.get_reg(reg1), subop) elif subop in [4, 5, 6]: self.emit_logop(reg2, block.get_reg(reg2), block.get_reg(reg1), subop) else: # XXX sext, bit* raise DecodeError('unsized high {:x}/{:x}'.format(op, subop)) elif op == 0xfe: op1 = self.get_byte() op2 = self.get_byte() reg1 = self.isa.r[op1 & 0xf] reg2 = self.isa.r[op1 >> 4] subop = op2 & 0xf if subop == 0: sr = isa.sr[op1 & 0xf] if sr is None: raise DecodeError('mov to $sr{}'.format(op1 & 0xf)) block.set_reg(sr, block.get_reg(reg2), self.name) elif subop == 1: sr = isa.sr[op1 >> 4] if sr is None: raise DecodeError('mov from $sr{}'.format(op1 >> 4)) block.set_reg(reg1, block.get_reg(sr), self.name) else: # XXX ptlb, vtlb, xbit raise DecodeError('unsized high {:x}/{:x}'.format(op, subop)) elif op == 0xff: op1 = self.get_byte() reg1 = self.isa.r[op1 & 0xf] reg2 = self.isa.r[op1 >> 4] op2 = self.get_byte() subop = op2 & 0xf reg3 = self.isa.r[op2 >> 4] if subop in [0, 1]: self.emit_mul(reg3, block.get_reg(reg2), block.get_reg(reg1), subop) elif subop in [4, 5, 6]: self.emit_logop(reg3, block.get_reg(reg2), block.get_reg(reg1), subop) elif subop == 0xf: self.emit_iord(reg3, block.get_reg(reg2) + block.get_reg(reg1) * 4) else: # XXX sext, extr*, xbit, div/mod, 0xe raise DecodeError('unsized high {:x}/{:x}'.format(op, subop)) else: # XXX f2, f6, f7, fb raise DecodeError('unsized high {:x}'.format(op))
def new(cls, e1, e2): if isinstance(e1, ExprConst) and isinstance(e2, ExprConst): return ExprConst(e1.val >= e2.val) return super().new(e1, e2)