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_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_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 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_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_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_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 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_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_and(self, op): src = self.getOperValue(op, 0) dst = self.getOperValue(op, 1) uval = dst&src self.setOperValue(op, 1, uval) osize = op.opers[1].tsize self.setFlag(REG_SR_V, e_bits.is_signed_overflow(uval, osize)) self.setFlag(REG_SR_Z, not uval) self.setFlag(REG_SR_N, uval > e_bits.s_maxes[osize]) self.setFlag(REG_SR_C, e_bits.is_aux_carry(uval, 1))
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_rra(self, op): oper = self.getOperValue(op, 0) osize = op.opers[0].tsize # tsize needs to be correct! print "op: %s tsize: %s" % (op, osize) shift = (osize*8)-1 uval = ((oper&1)<<shift | oper>>1) self.setOperValue(op, 0, uval) self.setFlag(REG_SR_V, e_bits.is_signed_overflow(uval, osize)) self.setFlag(REG_SR_Z, not uval) self.setFlag(REG_SR_N, uval > e_bits.s_maxes[osize]) self.setFlag(REG_SR_C, e_bits.is_aux_carry(uval, 1))
def i_bit(self, op): bit = self.getOperValue(op, 0) dst = self.getOperValue(op, 1) val = dst & bit size = 2 if op.iflags & IF_BYTE: size = 1 self.setFlag(REG_SR_V, e_bits.is_signed_overflow(val, size)) self.setFlag(REG_SR_Z, not val) self.setFlag(REG_SR_N, val < 0) self.setFlag(REG_SR_C, e_bits.is_aux_carry(val, 1))
def i_inc(self, op): size = op.opers[0].tsize val = self.getOperValue(op, 0) sval = e_bits.signed(val, size) sval += 1 self.setOperValue(op, 0, sval) # Another arithmetic op where doing signed and unsigned is easier ;) self.setFlag(EFLAGS_OF, e_bits.is_signed_overflow(sval, size)) self.setFlag(EFLAGS_SF, e_bits.is_signed(sval, size)) self.setFlag(EFLAGS_ZF, not sval) self.setFlag(EFLAGS_AF, (sval & 0xf == 0)) self.setFlag(EFLAGS_PF, e_bits.is_parity_byte(sval))
def i_sxt(self, op): oper = self.getOperValue(op, 0) osize = 1 # must be for msp430 to sign extend smax = e_bits.s_maxes[osize] umax = e_bits.u_maxes[2] if oper > smax: ubits = smax ^ (umax-1) oper |= ubits self.setOperValue(op, 0, oper) self.setFlag(REG_SR_V, e_bits.is_signed_overflow(oper, osize)) self.setFlag(REG_SR_Z, not oper) self.setFlag(REG_SR_N, oper > e_bits.s_maxes[osize]) self.setFlag(REG_SR_C, e_bits.is_aux_carry(oper, 1))
def doSubC(self, a, b, carry, size): ua = e_bits.unsigned(a, size) ub = e_bits.unsigned(b, size) sa = e_bits.signed(a, size) sb = e_bits.signed(b, size) ures = ua - ub - 1 + carry sres = sa - sb - 1 + carry res = e_bits.unsigned(ures, size) self.setFlag(SR_N, e_bits.msb(res, size)) self.setFlag(SR_Z, res == 0) self.setFlag(SR_C, not e_bits.is_unsigned_carry(ures, size)) self.setFlag(SR_V, e_bits.is_signed_overflow(sres, size)) return res
def i_inc(self, op): if op.iflags & IF_BYTE: size = BYTE size = WORD #size = op.opers[0].tsize val = self.getOperValue(op, 0) sval = e_bits.signed(val, size) sval += 1 self.setOperValue(op, 0, sval) # Another arithmetic op where doing signed and unsigned is easier ;) self.setFlag(REG_SR_V, e_bits.is_signed_overflow(sval, size)) self.setFlag(REG_SR_Z, not sval) self.setFlag(REG_SR_N, sval < 0) self.setFlag(REG_SR_C, e_bits.is_aux_carry(val, 1))
def i_xor(self, op): src1 = self.getOperValue(op, 0) src2 = self.getOperValue(op, 1) # FIXME PDE and flags if src1 is None or src2 is None: self.undefFlags() self.setOperValue(op, 1, None) return usrc1 = e_bits.unsigned(src1, 4) usrc2 = e_bits.unsigned(src2, 4) ures = usrc1 ^ usrc2 self.setOperValue(op, 1, ures) self.setFlag(h8_regs.CCR_C, e_bits.is_unsigned_carry(ures, 4)) self.setFlag(h8_regs.CCR_Z, not ures) self.setFlag(h8_regs.CCR_N, e_bits.is_signed(ures, 4)) self.setFlag(h8_regs.CCR_V, e_bits.is_signed_overflow(ures, 4))
def i_add(self, op): if len(op.opers) == 3: src1 = self.getOperValue(op, 1) src2 = self.getOperValue(op, 2) else: src1 = self.getOperValue(op, 0) src2 = self.getOperValue(op, 1) #FIXME PDE and flags if src1 == None or src2 == None: self.undefFlags() self.setOperValue(op, 0, None) return dsize = op.opers[0].tsize ssize = op.opers[1].tsize usrc1 = e_bits.unsigned(src1, 4) usrc2 = e_bits.unsigned(src2, 4) ssrc1 = e_bits.signed(src1, 4) ssrc2 = e_bits.signed(src2, 4) ures = usrc1 + usrc2 sres = ssrc1 + ssrc2 self.setOperValue(op, 0, ures) curmode = self.getProcMode() if op.iflags & IF_S: if op.opers[0].reg == 15 and (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, dsize)) self.setFlag(PSR_Z_bit, not ures) self.setFlag(PSR_C_bit, e_bits.is_unsigned_carry(ures, dsize)) self.setFlag(PSR_V_bit, e_bits.is_signed_overflow(sres, dsize))
def intSubBase(self, src, dst, ssize, dsize): usrc = e_bits.unsigned(src, ssize) udst = e_bits.unsigned(dst, dsize) ssrc = e_bits.signed(src, ssize) sdst = e_bits.signed(dst, dsize) ures = udst - usrc sres = sdst - ssrc #print "dsize/ssize: %d %d" % (dsize, ssize) #print "unsigned: %d %d %d" % (usrc, udst, ures) #print "signed: %d %d %d" % (ssrc, sdst, sres) self.setFlag(EFLAGS_OF, e_bits.is_signed_overflow(sres, dsize)) self.setFlag(EFLAGS_AF, e_bits.is_aux_carry_sub(usrc, udst)) self.setFlag(EFLAGS_CF, e_bits.is_unsigned_carry(ures, dsize)) self.setFlag(EFLAGS_SF, e_bits.is_signed(ures, dsize)) self.setFlag(EFLAGS_ZF, not sres) self.setFlag(EFLAGS_PF, e_bits.is_parity_byte(ures)) return ures
def intSubBase(self, src, dst, ssize, dsize): usrc = e_bits.unsigned(src, ssize) udst = e_bits.unsigned(dst, dsize) ssrc = e_bits.signed(src, ssize) sdst = e_bits.signed(dst, dsize) ures = udst - usrc sres = sdst - ssrc #print "dsize/ssize: %d %d" % (dsize, ssize) #print "unsigned: %d %d %d" % (usrc, udst, ures) #print "signed: %d %d %d" % (ssrc, sdst, sres) self.setFlag(EFLAGS_OF, e_bits.is_signed_overflow(sres, dsize)) self.setFlag(EFLAGS_AF, e_bits.is_aux_carry(usrc, udst)) self.setFlag(EFLAGS_CF, e_bits.is_unsigned_carry(ures, dsize)) self.setFlag(EFLAGS_SF, e_bits.is_signed(ures, dsize)) self.setFlag(EFLAGS_ZF, not sres) self.setFlag(EFLAGS_PF, e_bits.is_parity_byte(ures)) return ures
def intSubBase(self, src, dst, ssize, dsize): usrc = e_bits.unsigned(src, ssize) udst = e_bits.unsigned(dst, dsize) ssrc = e_bits.signed(src, ssize) sdst = e_bits.signed(dst, dsize) ures = udst - usrc sres = sdst - ssrc #print "dsize/ssize: %d %d" % (dsize, ssize) #print "unsigned: %d %d %d" % (usrc, udst, ures) #print "signed: %d %d %d" % (ssrc, sdst, sres) """ http://cnx.org/content/m23497/latest/ Bit Description 8 V Overflow bit.V = 1 -> Result of an arithmetic operation overflows the signed-variable range. 2 N Negative flag.N = 1 -> result of a byte or word operation is negative. 1 Z Zero flag.Z = 1 -> result of a byte or word operation is 0. 0 C Carry flag.C = 1 -> result of a byte or word operation produced a carry. REG_SR_C = 1 << 0 # Carry bit REG_SR_Z = 1 << 1 REG_SR_N = 1 << 2 REG_SR_V = 1 << 8 """ #print "ures: %x udst: %x usrc: %x"% (ures, udst, usrc) self.setFlag(REG_SR_V, e_bits.is_signed_overflow(sres, dsize)) self.setFlag(REG_SR_Z, not sres) self.setFlag(REG_SR_N, sres < 0) #self.setFlag(REG_SR_C, e_bits.is_aux_carry(usrc, udst)) self.setFlag(REG_SR_C, e_bits.is_unsigned_carry(ures, dsize)) return ures
def i_shal(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 = (val >> (bits - shbits)) & 1 val <<= shbits rawval = val 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, e_bits.is_signed_overflow(rawval, dsize)) self.setFlag(CCR_C, C)
def i_shal(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 = (val >> (bits - shbits)) & 1 val <<= shbits rawval = val 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, e_bits.is_signed_overflow(rawval, dsize)) self.setFlag(h8_regs.CCR_C, C)