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_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 integerAddition(self, op): """ Do the core of integer addition but only *return* the resulting value rather than assigning it. Architectures shouldn't have to override this as operand order doesn't matter """ src = self.getOperValue(op, 0) dst = self.getOperValue(op, 1) #FIXME PDE and flags if src == None: self.undefFlags() self.setOperValue(op, 1, None) return ssize = op.opers[0].tsize dsize = op.opers[1].tsize udst = e_bits.unsigned(dst, dsize) sdst = e_bits.signed(dst, dsize) usrc = e_bits.unsigned(src, dsize) ssrc = e_bits.signed(src, dsize) ures = usrc + udst sres = ssrc + sdst return (ssize, dsize, sres, ures, sdst, udst)
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 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_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_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_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 integerAddition(self, op): """ Do the core of integer addition but only *return* the resulting value rather than assigning it. Architectures shouldn't have to override this as operand order doesn't matter """ src = self.getOperValue(op, 0) dst = self.getOperValue(op, 1) #FIXME PDE and flags if src is None: self.undefFlags() self.setOperValue(op, 1, None) return ssize = op.opers[0].tsize dsize = op.opers[1].tsize udst = e_bits.unsigned(dst, dsize) sdst = e_bits.signed(dst, dsize) usrc = e_bits.unsigned(src, dsize) ssrc = e_bits.signed(src, dsize) ures = usrc + udst sres = ssrc + sdst return (ssize, dsize, sres, ures, sdst, udst)
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 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 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 twoRegCompound(self, topreg, botreg, size): """ Build a compound value where the value of the top reg is shifted and or'd with the value of the bot reg ( assuming they are size bytes in length). The return is size * 2 wide (and unsigned). """ top = e_bits.unsigned(self.getRegister(topreg), size) bot = e_bits.unsigned(self.getRegister(botreg), size) return ((top << (size * 8)) | bot)
def twoRegCompound(self, topreg, botreg, size): """ Build a compound value where the value of the top reg is shifted and or'd with the value of the bot reg ( assuming they are size bytes in length). The return is size * 2 wide (and unsigned). """ top = e_bits.unsigned(self.getRegister(topreg), size) bot = e_bits.unsigned(self.getRegister(botreg), size) return ((top << (size *8)) | bot)
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 doAnd(self, a, b, size): ua = e_bits.unsigned(a, size) ub = e_bits.unsigned(b, size) res = ua & ub self.setFlag(SR_N, e_bits.msb(res, size)) self.setFlag(SR_Z, res == 0) self.setFlag(SR_C, res != 0) self.setFlag(SR_V, 0) return res
def i_bis(self, op): src = self.getOperValue(op, 0) dst = self.getOperValue(op, 1) size = self.getOperSize(op) usrc = e_bits.unsigned(src, size) udst = e_bits.unsigned(dst, size) res = usrc | udst self.setOperValue(op, 1, res)
def getOperAddress(self, op, idx): """ Return the address that an operand which deref's memory would read from on getOperValue(). """ oper = op.opers[idx] if oper.mode == OM_IMMMEM: base, size = self.getSegmentInfo(op) return e_bits.unsigned(base + oper.imm, oper.tsize) if oper.mode == OM_REGMEM: val = self.getRegister(oper.reg) if val == None: return None base, size = self.getSegmentInfo(op) val += base if oper.disp != None: val += oper.disp return e_bits.unsigned(val, oper.tsize) if oper.mode == OM_SIBMEM: addr = 0 if oper.reg != None: basereg = self.getRegister(oper.reg) if basereg == None: return None addr += basereg if oper.imm != None: addr += oper.imm if oper.indexreg != None: index = self.getRegister(oper.indexreg) if index == None: return None if oper.scale != None: index *= oper.scale addr += index if oper.disp != None: addr += oper.disp base, size = self.getSegmentInfo(op) return e_bits.unsigned(addr + base, oper.tsize) raise Exception("getOperAddress() on wrong type!")
def i_inv(self, op): dst = self.getOperValue(op, 0) size = self.getOperSize(op) udst = e_bits.unsigned(dst, size) res = e_bits.unsigned(~dst, size) self.setFlag(SR_N, e_bits.msb(res, size)) self.setFlag(SR_Z, res == 0) self.setFlag(SR_C, res != 0) self.setFlag(SR_V, e_bits.msb(udst, size)) self.setOperValue(op, 0, res)
def i_swpb(self, op): dst = self.getOperValue(op, 0) udst = e_bits.unsigned(dst, WORD) res = ((udst&0xff) << 8) | ((udst&0xff00) >> 8) self.setOperValue(op, 0, res)
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_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_rcl(self, op): dsize = op.opers[0].tsize dst = self.getOperValue(op, 0) src = self.getOperValue(op, 1) src = src & 0x1f # Put that carry bit up there. if self.getFlag(EFLAGS_CF): dst = dst | (1 << (8 * dsize)) # Add one to account for carry x = ((8*dsize) - src) + 1 #FIXME is this the one that can end up negative? res = (dst << src) | (dst >> x) cf = (res >> (8*dsize)) & 1 res = e_bits.unsigned(res, dsize) self.setFlag(EFLAGS_CF, cf) if src == 1: m1 = e_bits.msb(res, dsize) m2 = e_bits.msb(res << 1, dsize) self.setFlag(EFLAGS_OF, m1 ^ m2) self.setOperValue(op, 0, res)
def i_rcl(self, op): dsize = op.opers[0].tsize dst = self.getOperValue(op, 0) src = self.getOperValue(op, 1) src = src & 0x1f # Put that carry bit up there. if self.getFlag(EFLAGS_CF): dst = dst | (1 << (8 * dsize)) # Add one to account for carry x = ((8 * dsize) - src) + 1 #FIXME is this the one that can end up negative? res = (dst << src) | (dst >> x) cf = (res >> (8 * dsize)) & 1 res = e_bits.unsigned(res, dsize) self.setFlag(EFLAGS_CF, cf) if src == 1: m1 = e_bits.msb(res, dsize) m2 = e_bits.msb(res << 1, dsize) self.setFlag(EFLAGS_OF, m1 ^ m2) 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 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 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_rra(self, op): dst = self.getOperValue(op, 0) size = self.getOperSize(op) udst = e_bits.unsigned(dst, size) shift = (size * 8) - 1 res = (e_bits.msb(udst, size) << shift) | (udst>>1) ures = e_bits.unsigned(res, size) self.setFlag(SR_N, e_bits.msb(ures, size)) self.setFlag(SR_Z, ures == 0) self.setFlag(SR_C, e_bits.lsb(udst)) self.setFlag(SR_V, 0) self.setOperValue(op, 0, ures)
def i_xor(self, op): src = self.getOperValue(op, 0) dst = self.getOperValue(op, 1) size = self.getOperSize(op) usrc = e_bits.unsigned(src, size) udst = e_bits.unsigned(dst, size) ures = usrc ^ udst self.setFlag(SR_N, e_bits.msb(ures, size)) self.setFlag(SR_Z, ures == 0) self.setFlag(SR_C, ures != 0) self.setFlag(SR_V, e_bits.msb(usrc, size) and e_bits.msb(udst, size)) self.setOperValue(op, 1, ures)
def i_tst(self, op): dst = self.getOperValue(op, 0) size = self.getOperSize(op) udst = e_bits.unsigned(dst, size) self.setFlag(SR_N, e_bits.msb(udst, size)) self.setFlag(SR_Z, udst == 0) self.setFlag(SR_C, 1) self.setFlag(SR_V, 0)
def setRegister(self, regindex, value): """ Set the value of the architecuture specific register by index. """ # We assume a default "pointer length" width. If you are # dealing with registers other than that, you will need # to over-ride this method to use them (see IntelModule for example) width = self.arch.getPointerSize() value = e_bits.unsigned(value, width) self.regs[regindex] = value
def i_xor(self, op): 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, 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(CCR_C, e_bits.is_unsigned_carry(ures, 4)) self.setFlag(CCR_Z, not ures) self.setFlag(CCR_N, e_bits.is_signed(ures, 4)) self.setFlag(CCR_V, e_bits.is_signed_overflow(ures, 4))
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 doDecAddC(self, a, b, carry, size): ua = e_bits.unsigned(a, size) ub = e_bits.unsigned(b, size) int_a = e_enc.bcd_to_int(ua) int_b = e_enc.bcd_to_int(ub) int_res = int_a + int_b + carry bcd_res = e_enc.int_to_bcd(int_res) res = e_bits.unsigned(bcd_res, size) if size == BYTE: bcd_max = 99 else: bcd_max = 9999 self.setFlag(SR_N, e_bits.msb(res, size)) self.setFlag(SR_Z, res == 0) self.setFlag(SR_C, 1 if int_res > bcd_max else 0) return res
def setOperValue(self, op, idx, value): """ Set the value of the target operand at index idx from opcode op. (obviously OM_IMMEDIATE *cannot* be set) """ oper = op.opers[idx] value = e_bits.unsigned(value, oper.tsize) if oper.mode == OM_IMMEDIATE: raise InvalidInstruction() if oper.mode == OM_REGISTER: return self.setRegister(oper.reg, value) if oper.mode == OM_IMMMEM: base, size = self.getSegmentInfo(op) return self.writeMemValue(base + oper.imm, value, oper.tsize) if oper.mode == OM_REGMEM: reg = self.getRegister(oper.reg) base, size = self.getSegmentInfo(op) reg += base if oper.disp != None: reg += oper.disp return self.writeMemValue(reg, value, oper.tsize) if oper.mode == OM_SIBMEM: base, size = self.getSegmentInfo(op) addr = base if oper.reg != None: addr += self.getRegister(oper.reg) if oper.imm != None: addr += oper.imm if oper.indexreg != None: index = self.getRegister(oper.indexreg) if oper.scale != None: index *= oper.scale addr += index if oper.disp != None: addr += oper.disp return self.writeMemValue(addr, value, oper.tsize)
def i_rla(self, op): dst = self.getOperValue(op, 0) size = self.getOperSize(op) udst = e_bits.unsigned(dst, size) self.setFlag(SR_C, e_bits.msb(udst, size)) res = udst << 1 ures = e_bits.unsigned(res, size) if size == BYTE: val_min = 0x40 val_max = 0xc0 else: val_min = 0x4000 val_max = 0xc000 self.setFlag(SR_N, e_bits.msb(ures, size)) self.setFlag(SR_Z, ures == 0) self.setFlag(SR_V, udst >= val_min and udst < val_max) self.setOperValue(op, 0, 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_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, subtrahend, minuend, ssize, msize): ''' Base for integer subtraction. Segmented such that order of operands can easily be overridden by subclasses. Does not set flags (arch-specific), and doesn't set the dest operand. That's up to the instruction implementation. 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. Math vocab refresher: Subtrahend - Minuend = Difference ''' usubtra = e_bits.unsigned(subtrahend, ssize) uminuend = e_bits.unsigned(minuend, msize) ssubtra = e_bits.signed(subtrahend, ssize) sminuend = e_bits.signed(minuend, msize) ures = usubtra - uminuend sres = ssubtra - sminuend return (ssize, msize, sres, ures, ssubtra, usubtra)
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_dec(self, op): val = self.getOperValue(op, 0) uval = e_bits.unsigned(val, op.opers[0].tsize) 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, e_bits.is_aux_carry_sub(1, uval)) self.setFlag(EFLAGS_PF, e_bits.is_parity_byte(val))