def i_shld(self, op): dsize = op.opers[0].tsize bsize = dsize * 8 dst = self.getOperValue(op, 0) src = self.getOperValue(op, 1) cnt = self.getOperValue(op, 2) cnt &= 0x1f # Reg gets masked down if cnt == 0: return if cnt > bsize: return res = dst << cnt res |= src >> (bsize - cnt) ret = e_bits.unsigned(res, dsize) if cnt == 1: # Set OF on sign change dsign = e_bits.is_signed(dst, dsize) rsign = e_bits.is_signed(ret, dsize) self.setFlag(EFLAGS_OF, dsign != rsign) # set carry to last shifted bit self.setFlag(EFLAGS_CF, (dst << (cnt-1)) & 1) self.setFlag(EFLAGS_SF, e_bits.is_signed(ret, dsize)) self.setFlag(EFLAGS_ZF, not ret) self.setFlag(EFLAGS_PF, e_bits.is_parity_byte(ret)) self.setOperValue(op, 0, ret)
def i_shld(self, op): dsize = op.opers[0].tsize bsize = dsize * 8 dst = self.getOperValue(op, 0) src = self.getOperValue(op, 1) cnt = self.getOperValue(op, 2) cnt &= 0x1f # Reg gets masked down if cnt == 0: return if cnt > bsize: return res = dst << cnt res |= src >> (bsize - cnt) ret = e_bits.unsigned(res, dsize) if cnt == 1: # Set OF on sign change dsign = e_bits.is_signed(dst, dsize) rsign = e_bits.is_signed(ret, dsize) self.setFlag(EFLAGS_OF, dsign != rsign) # set carry to last shifted bit self.setFlag(EFLAGS_CF, (dst << (cnt - 1)) & 1) self.setFlag(EFLAGS_SF, e_bits.is_signed(ret, dsize)) self.setFlag(EFLAGS_ZF, not ret) self.setFlag(EFLAGS_PF, e_bits.is_parity_byte(ret)) self.setOperValue(op, 0, ret)
def i_shlr(self, op): ''' not the same as shar ''' dstidx = len(op.opers) - 1 if dstidx: shbits = self.getOperValue(op, 0) val = self.getOperValue(op, 1) dsize = op.opers[1].tsize else: shbits = 1 val = self.getOperValue(op, 0) dsize = op.opers[0].tsize # bits = (dsize * 8) - 1 C = (val >> (shbits-1)) & 1 val >>= shbits self.setOperValue(op, dstidx, val) self.setFlag(h8_regs.CCR_N, e_bits.is_signed(val, dsize)) self.setFlag(h8_regs.CCR_Z, not val) self.setFlag(h8_regs.CCR_V, 0) self.setFlag(h8_regs.CCR_C, C)
def i_shll(self, op): ''' same as shal, except for handling of V ''' dstidx = len(op.opers) - 1 if dstidx: shbits = self.getOperValue(op, 0) val = self.getOperValue(op, 1) dsize = op.opers[1].tsize else: shbits = 1 val = self.getOperValue(op, 0) dsize = op.opers[0].tsize bits = (dsize * 8) C = (val >> (bits - shbits)) & 1 val <<= shbits val &= e_bits.u_maxes[dsize] self.setOperValue(op, dstidx, val) self.setFlag(h8_regs.CCR_N, e_bits.is_signed(val, dsize)) self.setFlag(h8_regs.CCR_Z, not val) self.setFlag(h8_regs.CCR_V, 0) self.setFlag(h8_regs.CCR_C, C)
def i_shar(self, op): dstidx = len(op.opers) - 1 if dstidx: shbits = self.getOperValue(op, 0) val = self.getOperValue(op, 1) dsize = op.opers[1].tsize else: shbits = 1 val = self.getOperValue(op, 0) dsize = op.opers[0].tsize logger.debug(repr((shbits, val, dsize))) max_mask = e_bits.u_maxes[dsize] signbits = ((-1 & max_mask) << ((8 * dsize) - shbits) & max_mask) S = val > e_bits.s_maxes[dsize] C = (val >> (shbits-1)) & 1 val >>= shbits if S: val |= signbits self.setOperValue(op, dstidx, val) self.setFlag(h8_regs.CCR_N, e_bits.is_signed(val, dsize)) self.setFlag(h8_regs.CCR_Z, not val) self.setFlag(h8_regs.CCR_V, 0) self.setFlag(h8_regs.CCR_C, C)
def i_rotxr(self, op): dstidx = len(op.opers) - 1 if dstidx: shbits = self.getOperValue(op, 0) val = self.getOperValue(op, 1) dsize = op.opers[1].tsize else: shbits = 1 val = self.getOperValue(op, 0) dsize = op.opers[0].tsize bits = (dsize * 8) C = self.getFlag(h8_regs.CCR_C) newC = (val >> (shbits-1)) & 1 val |= (val << (bits + 1)) val |= (C << bits) val >>= shbits val &= e_bits.u_maxes[dsize] self.setOperValue(op, dstidx, val) self.setFlag(h8_regs.CCR_N, e_bits.is_signed(val, dsize)) self.setFlag(h8_regs.CCR_Z, not val) self.setFlag(h8_regs.CCR_V, 0) self.setFlag(h8_regs.CCR_C, newC)
def i_rotxl(self, op): ''' rotate left, with extend Carry ''' dstidx = len(op.opers) - 1 if dstidx: shbits = self.getOperValue(op, 0) val = self.getOperValue(op, 1) dsize = op.opers[1].tsize else: shbits = 1 val = self.getOperValue(op, 0) dsize = op.opers[0].tsize bits = (dsize * 8) - 1 C = self.getFlag(CCR_C) newC = (val >> (bits + 1 - shbits)) & 1 val <<= shbits val |= (val >> (bits + 2)) val |= (C << (shbits - 1)) val &= e_bits.u_maxes[dsize] self.setOperValue(op, dstidx, val) self.setFlag(CCR_N, e_bits.is_signed(val, dsize)) self.setFlag(CCR_Z, not val) self.setFlag(CCR_V, 0) self.setFlag(CCR_C, newC)
def i_eor(self, op): src1 = self.getOperValue(op, 1) src2 = self.getOperValue(op, 2) # FIXME PDE and flags if src1 == None or src2 == None: self.undefFlags() self.setOperValue(op, 0, None) return usrc1 = e_bits.unsigned(src1, 4) usrc2 = e_bits.unsigned(src2, 4) ures = usrc1 ^ usrc2 self.setOperValue(op, 0, ures) curmode = self.getProcMode() if op.iflags & IF_S: if op.opers[0].reg == 15: if (curmode != PM_sys and curmode != PM_usr): self.setCPSR(self.getSPSR(curmode)) else: raise Exception( "Messed up opcode... adding to r15 from PM_usr or PM_sys" ) self.setFlag(PSR_C_bit, e_bits.is_unsigned_carry(ures, 4)) self.setFlag(PSR_Z_bit, not ures) self.setFlag(PSR_N_bit, e_bits.is_signed(ures, 4)) self.setFlag(PSR_V_bit, e_bits.is_signed_overflow(sres, 4))
def i_dec(self, op): dstidx = len(op.opers) - 1 if dstidx == 1: ssize = op.opers[0].tsize dsize = op.opers[1].tsize src = self.getOperValue(op, 0) dst = self.getOperValue(op, 1) udst = e_bits.unsigned(dst, dsize) sdst = e_bits.signed(dst, dsize) usrc = e_bits.unsigned(src, ssize) ssrc = e_bits.signed(src, ssize) else: dsize = op.opers[0].tsize dst = self.getOperValue(op, 0) udst = e_bits.unsigned(dst, dsize) sdst = e_bits.signed(dst, dsize) ssrc = usrc = 1 ures = udst - usrc sres = sdst - ssrc self.setFlag(h8_regs.CCR_Z, not ures) self.setFlag(h8_regs.CCR_N, e_bits.is_signed(ures, dsize)) self.setFlag(h8_regs.CCR_V, e_bits.is_signed_overflow(sres, dsize)) # V must be set if previous value was 0x80 (per docs, page 73 of H8/300) self.setOperValue(op, dstidx, ures)
def i_shr(self, op): dsize = op.opers[0].tsize dst = self.getOperValue(op, 0) src = self.getOperValue(op, 1) src = src & 0x1f # According to intel manual, if src == 0 eflags are not changed if src == 0: return res = dst >> src cf = (dst >> (src - 1)) & 1 res = e_bits.unsigned(res, dsize) self.setFlag(EFLAGS_CF, cf) self.setFlag(EFLAGS_SF, e_bits.is_signed(res, dsize)) self.setFlag(EFLAGS_ZF, not res) self.setFlag(EFLAGS_PF, e_bits.is_parity_byte(res)) if src == 1: self.setFlag(EFLAGS_OF, False) else: self.setFlag(EFLAGS_OF, 0) # Undefined, but zero'd on core2 duo self.setOperValue(op, 0, res)
def intSubBase(self, src1, src2, Sflag=0, rd=0): # So we can either do a BUNCH of crazyness with xor and shifting to # get the necessary flags here, *or* we can just do both a signed and # unsigned sub and use the results. udst = e_bits.unsigned(src1, 4) usrc = e_bits.unsigned(src2, 4) sdst = e_bits.signed(src1, 4) ssrc = e_bits.signed(src2, 4) ures = udst - usrc sres = sdst - ssrc if Sflag: curmode = self.getProcMode() if rd == 15: if(curmode != PM_sys and curmode != PM_usr): self.setCPSR(self.getSPSR(curmode)) else: raise Exception("Messed up opcode... adding to r15 from PM_usr or PM_sys") self.setFlag(PSR_N_bit, e_bits.is_signed(ures, 4)) self.setFlag(PSR_Z_bit, not ures) self.setFlag(PSR_C_bit, not e_bits.is_unsigned_carry(ures, 4)) self.setFlag(PSR_V_bit, e_bits.is_signed_overflow(sres, 4)) return ures
def i_adc(self, op): dst = self.getOperValue(op, 0) src = self.getOperValue(op, 1) cf = 0 if self.getFlag(EFLAGS_CF): cf = 1 dsize = op.opers[0].tsize ssize = op.opers[1].tsize sdst = e_bits.signed(dst, dsize) ssrc = e_bits.signed(src, ssize) if (isinstance(op.opers[1], i386ImmOper) and ssize < dsize): src = e_bits.sign_extend(src, ssize, dsize) ssize = dsize #FIXME perhaps unify the add/adc flags/arith code res = dst + src + cf sres = sdst + ssrc + cf tsize = op.opers[0].tsize self.setFlag(EFLAGS_CF, e_bits.is_unsigned_carry(res, tsize)) self.setFlag(EFLAGS_PF, e_bits.is_parity_byte(res)) self.setFlag(EFLAGS_AF, e_bits.is_aux_carry(src, dst)) self.setFlag(EFLAGS_ZF, not res) self.setFlag(EFLAGS_SF, e_bits.is_signed(res, tsize)) self.setFlag(EFLAGS_OF, e_bits.is_signed_overflow(sres, dsize)) self.setOperValue(op, 0, res)
def i_add(self, op): dst = self.getOperValue(op, 0) src = self.getOperValue(op, 1) dsize = op.opers[0].tsize ssize = op.opers[1].tsize if dsize > ssize: src = e_bits.sign_extend(src, ssize, dsize) ssize = dsize udst = e_bits.unsigned(dst, dsize) usrc = e_bits.unsigned(src, ssize) sdst = e_bits.signed(dst, dsize) ssrc = e_bits.signed(src, ssize) ures = udst + usrc sres = sdst + ssrc self.setFlag(EFLAGS_CF, e_bits.is_unsigned_carry(ures, dsize)) self.setFlag(EFLAGS_PF, e_bits.is_parity_byte(ures)) self.setFlag(EFLAGS_AF, e_bits.is_aux_carry(src, dst)) self.setFlag(EFLAGS_ZF, not ures) self.setFlag(EFLAGS_SF, e_bits.is_signed(ures, dsize)) self.setFlag(EFLAGS_OF, e_bits.is_signed_overflow(sres, dsize)) self.setOperValue(op, 0, ures)
def logicalAnd(self, op): dst = self.getOperValue(op, 0) src = self.getOperValue(op, 1) # PDE if dst == None or src == None: self.undefFlags() self.setOperValue(op, 0, None) return dsize = op.opers[0].tsize ssize = op.opers[1].tsize # sign-extend an immediate if needed if dsize != ssize: src = e_bits.sign_extend(src, ssize, dsize) ssize = dsize # Make sure everybody's on the same bit page. dst = e_bits.unsigned(dst, dsize) src = e_bits.unsigned(src, ssize) res = src & dst self.setFlag(EFLAGS_AF, 0) # AF is undefined, but it seems like it is zeroed self.setFlag(EFLAGS_OF, 0) self.setFlag(EFLAGS_CF, 0) self.setFlag(EFLAGS_SF, e_bits.is_signed(res, dsize)) self.setFlag(EFLAGS_ZF, not res) self.setFlag(EFLAGS_PF, e_bits.is_parity_byte(res)) return res
def i_shlr(self, op): ''' not the same as shar ''' dstidx = len(op.opers) - 1 if dstidx: shbits = self.getOperValue(op, 0) val = self.getOperValue(op, 1) dsize = op.opers[1].tsize else: shbits = 1 val = self.getOperValue(op, 0) dsize = op.opers[0].tsize bits = (dsize * 8) - 1 C = (val >> (shbits - 1)) & 1 val >>= shbits self.setOperValue(op, dstidx, val) self.setFlag(CCR_N, e_bits.is_signed(val, dsize)) self.setFlag(CCR_Z, not val) self.setFlag(CCR_V, 0) self.setFlag(CCR_C, C)
def i_adc(self, op): dst = self.getOperValue(op, 0) src = self.getOperValue(op, 1) # PDE if dst == None or src == None: self.undefFlags() self.setOperValue(op, 0, None) return cf = 0 if self.getFlag(EFLAGS_CF): cf = 1 dstsize = op.opers[0].tsize srcsize = op.opers[1].tsize if (isinstance(op.opers[1], i386ImmOper) and srcsize < dstsize): src = e_bits.sign_extend(src, srcsize, dstsize) srcsize = dstsize #FIXME perhaps unify the add/adc flags/arith code res = dst + src + cf tsize = op.opers[0].tsize self.setFlag(EFLAGS_CF, e_bits.is_unsigned_carry(res, tsize)) self.setFlag(EFLAGS_PF, e_bits.is_parity_byte(res)) self.setFlag(EFLAGS_AF, e_bits.is_aux_carry(src, dst)) self.setFlag(EFLAGS_ZF, not res) self.setFlag(EFLAGS_SF, e_bits.is_signed(res, tsize)) self.setFlag(EFLAGS_OF, e_bits.is_signed_overflow(res, tsize)) self.setOperValue(op, 0, res)
def i_inc(self, op): dstidx = len(op.opers) - 1 if dstidx == 1: ssize = op.opers[0].tsize dsize = op.opers[1].tsize src = self.getOperValue(op, 0) dst = self.getOperValue(op, 1) udst = e_bits.unsigned(dst, dsize) # TODO: What is sdst and why does it exist? # sdst = e_bits.signed(dst, dsize) usrc = e_bits.unsigned(src, ssize) ssrc = e_bits.signed(src, ssize) else: dsize = op.opers[0].tsize dst = self.getOperValue(op, 0) udst = e_bits.unsigned(dst, dsize) # sdst = e_bits.signed(dst, dsize) ssrc = usrc = 1 ures = usrc + udst sres = ssrc + udst self.setFlag(h8_regs.CCR_Z, not ures) self.setFlag(h8_regs.CCR_N, e_bits.is_signed(ures, dsize)) self.setFlag(h8_regs.CCR_V, e_bits.is_signed_overflow(sres, dsize)) # V must be set if previous value was 0x7f (per docs, page 78 of H8/300) self.setOperValue(op, dstidx, ures)
def i_dec(self, op): dstidx = len(op.opers) - 1 if dstidx == 1: ssize = op.opers[0].tsize dsize = op.opers[1].tsize src = self.getOperValue(op, 0) dst = self.getOperValue(op, 1) udst = e_bits.unsigned(dst, dsize) sdst = e_bits.signed(dst, dsize) usrc = e_bits.unsigned(src, ssize) ssrc = e_bits.signed(src, ssize) else: dsize = op.opers[0].tsize dst = self.getOperValue(op, 0) udst = e_bits.unsigned(dst, dsize) sdst = e_bits.signed(dst, dsize) ssrc = usrc = 1 ures = udst - usrc sres = sdst - ssrc self.setFlag(CCR_Z, not ures) self.setFlag(CCR_N, e_bits.is_signed(ures, dsize)) self.setFlag(CCR_V, e_bits.is_signed_overflow(sres, dsize)) # V must be set if previous value was 0x80 (per docs, page 73 of H8/300) self.setOperValue(op, dstidx, ures)
def i_sar(self, op): dsize = op.opers[0].tsize dst = self.getOperValue(op, 0) src = self.getOperValue(op, 1) src = src & 0x1f # According to intel manual, if src == 0 eflags are not changed if src == 0: return signed = e_bits.msb(dst, dsize) res = dst >> src cf = (dst >> (src - 1)) & 1 # If it was signed, we need to fill in all those bits we # shifted off with ones. if signed: x = (8 * dsize) - src umax = e_bits.u_maxes[dsize] res |= (umax >> x) << x res = e_bits.unsigned(res, dsize) self.setFlag(EFLAGS_CF, cf) self.setFlag(EFLAGS_SF, e_bits.is_signed(res, dsize)) self.setFlag(EFLAGS_ZF, not res) self.setFlag(EFLAGS_PF, e_bits.is_parity_byte(res)) if src == 1: self.setFlag(EFLAGS_OF, False) else: self.setFlag(EFLAGS_OF, 0) # Undefined, but zero'd on core2 duo self.setOperValue(op, 0, res)
def i_shr(self, op): dsize = op.opers[0].tsize dst = self.getOperValue(op, 0) src = self.getOperValue(op, 1) src = src & 0x1f # According to intel manual, if src == 0 eflags are not changed if src == 0: return res = dst >> src cf = (dst >> (src-1)) & 1 res = e_bits.unsigned(res, dsize) self.setFlag(EFLAGS_CF, cf) self.setFlag(EFLAGS_SF, e_bits.is_signed(res, dsize)) self.setFlag(EFLAGS_ZF, not res) self.setFlag(EFLAGS_PF, e_bits.is_parity_byte(res)) if src == 1: self.setFlag(EFLAGS_OF, False) else: self.setFlag(EFLAGS_OF, 0) # Undefined, but zero'd on core2 duo self.setOperValue(op, 0, res)
def i_sar(self, op): dsize = op.opers[0].tsize dst = self.getOperValue(op, 0) src = self.getOperValue(op, 1) src = src & 0x1f # According to intel manual, if src == 0 eflags are not changed if src == 0: return signed = e_bits.msb(dst, dsize) res = dst >> src cf = (dst >> (src-1)) & 1 # If it was signed, we need to fill in all those bits we # shifted off with ones. if signed: x = (8*dsize) - src umax = e_bits.u_maxes[dsize] res |= (umax >> x) << x res = e_bits.unsigned(res, dsize) self.setFlag(EFLAGS_CF, cf) self.setFlag(EFLAGS_SF, e_bits.is_signed(res, dsize)) self.setFlag(EFLAGS_ZF, not res) self.setFlag(EFLAGS_PF, e_bits.is_parity_byte(res)) if src == 1: self.setFlag(EFLAGS_OF, False) else: self.setFlag(EFLAGS_OF, 0) # Undefined, but zero'd on core2 duo self.setOperValue(op, 0, res)
def logicalAnd(self, op): dst = self.getOperValue(op, 0) src = self.getOperValue(op, 1) dsize = op.opers[0].tsize ssize = op.opers[1].tsize # sign-extend an immediate if needed if dsize != ssize: src = e_bits.sign_extend(src, ssize, dsize) ssize = dsize # Make sure everybody's on the same bit page. dst = e_bits.unsigned(dst, dsize) src = e_bits.unsigned(src, ssize) res = src & dst self.setFlag(EFLAGS_AF, 0) # AF is undefined, but it seems like it is zeroed self.setFlag(EFLAGS_OF, 0) self.setFlag(EFLAGS_CF, 0) self.setFlag(EFLAGS_SF, e_bits.is_signed(res, dsize)) self.setFlag(EFLAGS_ZF, not res) self.setFlag(EFLAGS_PF, e_bits.is_parity_byte(res)) return res
def intSubBase(self, src1, src2, Sflag=0, rd=0): # So we can either do a BUNCH of crazyness with xor and shifting to # get the necessary flags here, *or* we can just do both a signed and # unsigned sub and use the results. udst = e_bits.unsigned(src1, 4) usrc = e_bits.unsigned(src2, 4) sdst = e_bits.signed(src1, 4) ssrc = e_bits.signed(src2, 4) ures = udst - usrc sres = sdst - ssrc if Sflag: curmode = self.getProcMode() if rd == 15: if curmode != PM_sys and curmode != PM_usr: self.setCPSR(self.getSPSR(curmode)) else: raise Exception( "Messed up opcode... adding to r15 from PM_usr or PM_sys" ) self.setFlag(PSR_N_bit, e_bits.is_signed(ures, 4)) self.setFlag(PSR_Z_bit, not ures) self.setFlag(PSR_C_bit, e_bits.is_unsigned_carry(ures, 4)) self.setFlag(PSR_V_bit, e_bits.is_signed_overflow(sres, 4)) return ures
def i_add(self, op): dst = self.getOperValue(op, 0) src = self.getOperValue(op, 1) dsize = op.opers[0].tsize ssize = op.opers[1].tsize #FIXME PDE and flags if dst == None or src == None: self.undefFlags() self.setOperValue(op, 0, None) return if dsize > ssize: src = e_bits.sign_extend(src, ssize, dsize) ssize = dsize udst = e_bits.unsigned(dst, dsize) usrc = e_bits.unsigned(src, ssize) sdst = e_bits.signed(dst, dsize) ssrc = e_bits.signed(src, ssize) ures = udst + usrc sres = sdst + ssrc self.setFlag(EFLAGS_CF, e_bits.is_unsigned_carry(ures, dsize)) self.setFlag(EFLAGS_PF, e_bits.is_parity_byte(ures)) self.setFlag(EFLAGS_AF, e_bits.is_aux_carry(src, dst)) self.setFlag(EFLAGS_ZF, not ures) self.setFlag(EFLAGS_SF, e_bits.is_signed(ures, dsize)) self.setFlag(EFLAGS_OF, e_bits.is_signed_overflow(sres, dsize)) self.setOperValue(op, 0, ures)
def i_shar(self, op): dstidx = len(op.opers) - 1 if dstidx: shbits = self.getOperValue(op, 0) val = self.getOperValue(op, 1) dsize = op.opers[1].tsize else: shbits = 1 val = self.getOperValue(op, 0) dsize = op.opers[0].tsize logger.debug(repr((shbits, val, dsize))) max_mask = e_bits.u_maxes[dsize] signbits = ((-1 & max_mask) << ((8 * dsize) - shbits) & max_mask) S = val > e_bits.s_maxes[dsize] C = (val >> (shbits - 1)) & 1 val >>= shbits if S: val |= signbits self.setOperValue(op, dstidx, val) self.setFlag(CCR_N, e_bits.is_signed(val, dsize)) self.setFlag(CCR_Z, not val) self.setFlag(CCR_V, 0) self.setFlag(CCR_C, C)
def i_shll(self, op): ''' same as shal, except for handling of V ''' dstidx = len(op.opers) - 1 if dstidx: shbits = self.getOperValue(op, 0) val = self.getOperValue(op, 1) dsize = op.opers[1].tsize else: shbits = 1 val = self.getOperValue(op, 0) dsize = op.opers[0].tsize bits = (dsize * 8) C = (val >> (bits - shbits)) & 1 val <<= shbits val &= e_bits.u_maxes[dsize] self.setOperValue(op, dstidx, val) self.setFlag(CCR_N, e_bits.is_signed(val, dsize)) self.setFlag(CCR_Z, not val) self.setFlag(CCR_V, 0) self.setFlag(CCR_C, C)
def i_rotxl(self, op): ''' rotate left, with extend Carry ''' dstidx = len(op.opers) - 1 if dstidx: shbits = self.getOperValue(op, 0) val = self.getOperValue(op, 1) dsize = op.opers[1].tsize else: shbits = 1 val = self.getOperValue(op, 0) dsize = op.opers[0].tsize bits = (dsize * 8) - 1 C = self.getFlag(h8_regs.CCR_C) newC = (val >> (bits+1-shbits)) & 1 val <<= shbits val |= (val >> (bits + 2)) val |= (C << (shbits - 1)) val &= e_bits.u_maxes[dsize] self.setOperValue(op, dstidx, val) self.setFlag(h8_regs.CCR_N, e_bits.is_signed(val, dsize)) self.setFlag(h8_regs.CCR_Z, not val) self.setFlag(h8_regs.CCR_V, 0) self.setFlag(h8_regs.CCR_C, newC)
def i_rotxr(self, op): dstidx = len(op.opers) - 1 if dstidx: shbits = self.getOperValue(op, 0) val = self.getOperValue(op, 1) dsize = op.opers[1].tsize else: shbits = 1 val = self.getOperValue(op, 0) dsize = op.opers[0].tsize bits = (dsize * 8) C = self.getFlag(CCR_C) newC = (val >> (shbits - 1)) & 1 val |= (val << (bits + 1)) val |= (C << bits) val >>= shbits val &= e_bits.u_maxes[dsize] self.setOperValue(op, dstidx, val) self.setFlag(CCR_N, e_bits.is_signed(val, dsize)) self.setFlag(CCR_Z, not val) self.setFlag(CCR_V, 0) self.setFlag(CCR_C, newC)
def i_eor(self, op): src1 = self.getOperValue(op, 1) src2 = self.getOperValue(op, 2) #FIXME PDE and flags if src1 == None or src2 == None: self.undefFlags() self.setOperValue(op, 0, None) return usrc1 = e_bits.unsigned(src1, 4) usrc2 = e_bits.unsigned(src2, 4) ures = usrc1 ^ usrc2 self.setOperValue(op, 0, ures) curmode = self.getProcMode() if op.iflags & IF_S: if op.opers[0].reg == 15: if (curmode != PM_sys and curmode != PM_usr): self.setCPSR(self.getSPSR(curmode)) else: raise Exception("Messed up opcode... adding to r15 from PM_usr or PM_sys") self.setFlag(PSR_C_bit, e_bits.is_unsigned_carry(ures, 4)) self.setFlag(PSR_Z_bit, not ures) self.setFlag(PSR_N_bit, e_bits.is_signed(ures, 4)) self.setFlag(PSR_V_bit, e_bits.is_signed_overflow(sres, 4))
def i_cwd(self, op): #FIXME handle 16 bit variant eax = self.getRegister(REG_EAX) if e_bits.is_signed(eax, 4): self.setRegister(REG_EDX, 0xffffffff) else: self.setRegister(REG_EDX, 0)
def i_pop(self, op): dsize = op.opers[0].tsize val = self.doPop() self.setOperValue(op, 0, val) self.setFlag(h8_regs.CCR_N, e_bits.is_signed(val, dsize)) self.setFlag(h8_regs.CCR_Z, not val) self.setFlag(h8_regs.CCR_V, 0)
def i_and(self, op): dsize = op.opers[1].tsize res = self.logicalAnd(op) self.setOperValue(op, 1, res) self.setFlag(CCR_Z, not res) self.setFlag(CCR_N, e_bits.is_signed(res, dsize)) self.setFlag(CCR_V, 0)
def doFlags(self, flagtup): (ssize, dsize, sres, ures, sdst, udst) = flagtup self.setFlag(h8_regs.CCR_H, e_bits.is_signed_half_carry(ures, dsize, udst)) self.setFlag(h8_regs.CCR_C, e_bits.is_unsigned_carry(ures, dsize)) self.setFlag(h8_regs.CCR_Z, not ures) self.setFlag(h8_regs.CCR_N, e_bits.is_signed(ures, dsize)) self.setFlag(h8_regs.CCR_V, e_bits.is_signed_overflow(sres, dsize))
def i_push(self, op): dsize = op.opers[0].tsize val = self.getOperValue(op, 0) self.doPush(val) self.setFlag(h8_regs.CCR_N, e_bits.is_signed(val, dsize)) self.setFlag(h8_regs.CCR_Z, not val) self.setFlag(h8_regs.CCR_V, 0)
def i_pop(self, op): dsize = op.opers[0].tsize val = self.doPop() self.setOperValue(op, 0, val) self.setFlag(CCR_N, e_bits.is_signed(val, dsize)) self.setFlag(CCR_Z, not val) self.setFlag(CCR_V, 0)
def doFlags(self, flagtup): (ssize, dsize, sres, ures, sdst, udst) = flagtup self.setFlag(CCR_H, e_bits.is_signed_half_carry(ures, dsize, udst)) self.setFlag(CCR_C, e_bits.is_unsigned_carry(ures, dsize)) self.setFlag(CCR_Z, not ures) self.setFlag(CCR_N, e_bits.is_signed(ures, dsize)) self.setFlag(CCR_V, e_bits.is_signed_overflow(sres, dsize))
def i_and(self, op): dsize = op.opers[1].tsize res = self.logicalAnd(op) self.setOperValue(op, 1, res) self.setFlag(h8_regs.CCR_Z, not res) self.setFlag(h8_regs.CCR_N, e_bits.is_signed(res, dsize)) self.setFlag(h8_regs.CCR_V, 0)
def i_push(self, op): dsize = op.opers[0].tsize val = self.getOperValue(op, 0) self.doPush(val) self.setFlag(CCR_N, e_bits.is_signed(val, dsize)) self.setFlag(CCR_Z, not val) self.setFlag(CCR_V, 0)
def i_tst(self, op): src1 = self.getOperValue(op, 0) src2 = self.getOperValue(op, 1) dsize = op.opers[0].tsize ures = src1 & src2 self.setFlag(PSR_N_bit, e_bits.is_signed(ures, dsize)) self.setFlag(PSR_Z_bit, (0,1)[ures==0]) self.setFlag(PSR_C_bit, e_bits.is_unsigned_carry(ures, dsize))
def i_not(self, op): dsize = op.opers[0].tsize oper = self.getOperValue(op, 0) #oper = e_bits.signed(oper, dsize) oper = e_bits.u_maxes[dsize] - oper self.setOperValue(op, 0, oper) self.setFlag(CCR_N, e_bits.is_signed(oper, dsize)) self.setFlag(CCR_Z, not oper) self.setFlag(CCR_V, 0)
def i_teq(self, op): src1 = self.getOperValue(op, 0) src2 = self.getOperValue(op, 1) dsize = op.opers[0].tsize ures = src1 ^ src2 self.setFlag(PSR_N_bit, e_bits.is_signed(ures, dsize)) self.setFlag(PSR_Z_bit, (0, 1)[ures == 0]) self.setFlag(PSR_C_bit, e_bits.is_unsigned_carry(ures, dsize))
def i_not(self, op): dsize = op.opers[0].tsize oper = self.getOperValue(op, 0) # oper = e_bits.signed(oper, dsize) oper = e_bits.u_maxes[dsize] - oper self.setOperValue(op, 0, oper) self.setFlag(h8_regs.CCR_N, e_bits.is_signed(oper, dsize)) self.setFlag(h8_regs.CCR_Z, not oper) self.setFlag(h8_regs.CCR_V, 0)
def AddWithCarry(self, src1, src2, carry=0, Sflag=0, rd=0): '''////AddWithCarry() ============== (bits(N), bit, bit) AddWithCarry(bits(N) x, bits(N) y, bit carry_in) unsigned_sum = UInt(x) + UInt(y) + UInt(carry_in); signed_sum = SInt(x) + SInt(y) + UInt(carry_in); result = unsigned_sum<N-1:0>; // same value as signed_sum<N-1:0> carry_out = if UInt(result) == unsigned_sum then '0' else '1'; overflow = if SInt(result) == signed_sum then '0' else '1'; return (result, carry_out, overflow); An important property of the AddWithCarry() function is that if: (result, carry_out, overflow) = AddWithCarry(x, NOT(y), carry_in) then: * if carry_in == '1', then result == x-y with: overflow == '1' if signed overflow occurred during the subtraction carry_out == '1' if unsigned borrow did not occur during the subtraction, that is, if x >= y * if carry_in == '0', then result == x-y-1 with: overflow == '1' if signed overflow occurred during the subtraction carry_out == '1' if unsigned borrow did not occur during the subtraction, that is, if x > y. Together, these mean that the carry_in and carry_out bits in AddWithCarry() calls can act as NOT borrow flags for subtractions as well as carry flags for additions. (@ we don't retrn carry-out and overflow, but set the flags here) ''' udst = e_bits.unsigned(src1, 4) usrc = e_bits.unsigned(src2, 4) sdst = e_bits.signed(src1, 4) ssrc = e_bits.signed(src2, 4) ures = (udst + usrc + carry) & 0xffffffff sres = (sdst + ssrc + carry) result = ures & 0x7fffffff #newcarry = (ures != result) newcarry = (udst >= usrc) overflow = (sres != result) if Sflag: curmode = self.getProcMode() if rd == 15: if (curmode != PM_sys and curmode != PM_usr): self.setCPSR(self.getSPSR(curmode)) else: raise Exception( "Messed up opcode... adding to r15 from PM_usr or PM_sys" ) else: self.setFlag(PSR_N_bit, e_bits.is_signed(ures, 4)) self.setFlag(PSR_Z_bit, not ures) self.setFlag(PSR_C_bit, newcarry) self.setFlag(PSR_V_bit, overflow) return ures
def i_neg(self, op): tsize = op.opers[0].tsize val = self.getOperValue(op, 0) res = 0 - val self.setOperValue(op, 0, res) self.setFlag(EFLAGS_CF, val != 0) self.setFlag(EFLAGS_ZF, not res) self.setFlag(EFLAGS_SF, e_bits.is_signed(res, tsize)) #FIXME how does neg cause/not cause a carry? self.setFlag(EFLAGS_AF, 0) # FIXME EFLAGS_AF
def i_mov(self, op): ssize = op.opers[0].tsize val = self.getOperValue(op, 0) self.setOperValue(op, 1, val) self.setFlag(h8_regs.CCR_N, e_bits.is_signed(val, ssize)) self.setFlag(h8_regs.CCR_Z, not val) self.setFlag(h8_regs.CCR_V, 0) if isinstance(op.opers[1], H8RegDirOper) and op.opers[1].reg == h8_const.REG_PC: return val
def i_mov(self, op): ssize = op.opers[0].tsize val = self.getOperValue(op, 0) self.setOperValue(op, 1, val) self.setFlag(CCR_N, e_bits.is_signed(val, ssize)) self.setFlag(CCR_Z, not val) self.setFlag(CCR_V, 0) if isinstance(op.opers[1], H8RegDirOper) and op.opers[1].reg == REG_PC: return val
def i_add(self, op): (ssize, dsize, sres, ures, sdst, udst) = self.integerAddition(op) self.setOperValue(op, 1, ures) # FIXME: test and validate self.setFlag(h8_regs.CCR_H, e_bits.is_signed_half_carry(sres, dsize, sdst)) self.setFlag(h8_regs.CCR_C, e_bits.is_unsigned_carry(ures, dsize)) self.setFlag(h8_regs.CCR_Z, not ures) self.setFlag(h8_regs.CCR_N, e_bits.is_signed(ures, dsize)) self.setFlag(h8_regs.CCR_V, e_bits.is_signed_overflow(sres, dsize))
def i_add(self, op): (ssize, dsize, sres, ures, sdst, udst) = self.integerAddition(op) self.setOperValue(op, 1, ures) # FIXME: test and validate self.setFlag(CCR_H, e_bits.is_signed_half_carry(sres, dsize, sdst)) self.setFlag(CCR_C, e_bits.is_unsigned_carry(ures, dsize)) self.setFlag(CCR_Z, not ures) self.setFlag(CCR_N, e_bits.is_signed(ures, dsize)) self.setFlag(CCR_V, e_bits.is_signed_overflow(sres, dsize))
def i_orr(self, op): val1 = self.getOperValue(op, 1) val2 = self.getOperValue(op, 2) val = val1 | val2 self.setOperValue(op, 0, val) Sflag = op.iflags & IF_S # FIXME: IF_PSR_S??? if Sflag: self.setFlag(PSR_N_bit, e_bits.is_signed(val, 4)) self.setFlag(PSR_Z_bit, not val) self.setFlag(PSR_C_bit, e_bits.is_unsigned_carry(val, 4)) self.setFlag(PSR_V_bit, e_bits.is_signed_overflow(val, 4))
def i_neg(self, op): dsize = op.opers[0].tsize oper = self.getOperValue(op, 0) oper = e_bits.signed(oper, dsize) oper = -oper self.setOperValue(op, 0, oper) self.setFlag(CCR_H, e_bits.is_signed_half_carry(oper, dsize, oper)) self.setFlag(CCR_N, e_bits.is_signed(oper, dsize)) self.setFlag(CCR_Z, not oper) self.setFlag(CCR_V, e_bits.is_signed_overflow(oper, dsize)) self.setFlag(CCR_C, e_bits.is_unsigned_carry(oper, dsize))
def i_neg(self, op): dsize = op.opers[0].tsize oper = self.getOperValue(op, 0) oper = e_bits.signed(oper, dsize) oper = -oper self.setOperValue(op, 0, oper) self.setFlag(h8_regs.CCR_H, e_bits.is_signed_half_carry(oper, dsize, oper)) self.setFlag(h8_regs.CCR_N, e_bits.is_signed(oper, dsize)) self.setFlag(h8_regs.CCR_Z, not oper) self.setFlag(h8_regs.CCR_V, e_bits.is_signed_overflow(oper, dsize)) self.setFlag(h8_regs.CCR_C, e_bits.is_unsigned_carry(oper, dsize))
def i_divxu(self, op): divisor = self.getOperValue(op, 0) dividend = self.getOperValue(op, 1) quotient = dividend / divisor remainder = dividend % divisor rdval = (remainder << 8) | quotient self.setOperValue(op, 1, rdval) self.setFlag(CCR_Z, not quotient) self.setFlag(CCR_N, e_bits.is_signed(quotient, 4))
def i_divxu(self, op): divisor = self.getOperValue(op, 0) dividend = self.getOperValue(op, 1) quotient = dividend / divisor remainder = dividend % divisor rdval = (remainder << 8) | quotient self.setOperValue(op, 1, rdval) self.setFlag(h8_regs.CCR_Z, not quotient) self.setFlag(h8_regs.CCR_N, e_bits.is_signed(quotient, 4))
def i_dec(self, op): val = self.getOperValue(op, 0) if val == None: self.undefFlags() return val -= 1 self.setOperValue(op, 0, val) #FIXME change over to integer subtraction self.setFlag(EFLAGS_OF, 0) #FIXME OF self.setFlag(EFLAGS_SF, e_bits.is_signed(val, op.opers[0].tsize)) self.setFlag(EFLAGS_ZF, not val) self.setFlag(EFLAGS_AF, 0) #FIXME AF... self.setFlag(EFLAGS_PF, e_bits.is_parity_byte(val))
def i_shrd(self, op): dsize = op.opers[0].tsize bsize = dsize * 8 dst = self.getOperValue(op, 0) src = self.getOperValue(op, 1) cnt = self.getOperValue(op, 2) cnt &= 0x1f # Reg gets masked down if cnt == 0: return if cnt > bsize: # result is "undfined" return res = dst >> cnt res |= src << (bsize - cnt) # We now have the bits masked into res, but it has become # wider than the original operand. # Ret is masked down to size ret = e_bits.unsigned(res, dsize) if cnt == 1: # Set OF on sign change dsign = e_bits.is_signed(dst, dsize) rsign = e_bits.is_signed(ret, dsize) self.setFlag(EFLAGS_OF, dsign != rsign) # set carry to last shifted bit self.setFlag(EFLAGS_CF, (res << bsize) & 1) self.setFlag(EFLAGS_SF, e_bits.is_signed(ret, dsize)) self.setFlag(EFLAGS_ZF, not ret) self.setFlag(EFLAGS_PF, e_bits.is_parity_byte(ret)) self.setOperValue(op, 0, ret)