def doDataInst(self, code, execute): global Rd global Rn global condCode logging.debug("doDataInst: code:" + str("%08X"%code) + " Rn:" + str(Rn) + " Rd:" + str(Rd)) """ opCode is the data instructions """ if not conditionMet(self, condCode): logging.debug("doDataInst: turn off exec because condition is " + hex(condCode) + " met") execute = 0 op2_val = getImmOP2DataProcessing(self, code) logging.debug("d_op_code:"+hex(d_op_code)+" op2_val:"+hex(op2_val)+" d:"+str(Rd)) # output instruction s_bit = code >> 20 & 1 # S bit # split functionality by opcode; AND, MLA, MUL, STR, LDR, udf, LDR retStr = getStrOP2DataProcessing(self, code) if (self.d_op_code == 0): oc2 = (code >> 4) & 15 if oc2 == 0b0001: # # or Rs # AND if (not execute): retStr =+ getStrOP2DataProcessing(self, code) else: globals.regs[Rd] = op2_val & globals.regs[Rn] if oc2 == 0b1001: if (code >> 21) & 1 == 1: # A retStr = " MLA" else: retStr = " MUL" getRm(self, code) getRs(self, code) if (execute): logging.debug("mul " + hex(globals.regs[Rd]) + " " + hex(globals.regs[Rm]) + " " + hex(globals.regs[Rs])) logging.debug("mul " + str(Rd) + " " + str(Rm) + " " + str(Rs)) if (code >> 21) & 1 == 1: # A # MLA Rd = Rm * Rs + Rn globals.regs[Rd] = globals.regs[Rm] * globals.regs[Rs] + globals.regs[Rn] else: # MUL Rd = Rm * Rs globals.regs[Rd] = globals.regs[Rm] * globals.regs[Rs] if oc2 == 0b1011 and mod == 0: retStr = " STR" if oc2 == 0b1011 and mod == 1: retStr = " LDR" if oc2 == 0b1101 and mod == 0: retStr = " udf" if oc2 == 0b1101 and mod == 1: retStr = " LDR" if oc2 == 0b1111 and mod == 0: retStr = " udf" if oc2 == 0b1111 and mod == 1: retStr = " LDR" carry = ARMCPU.isCarry(self) if (self.d_op_code == 1): # EOR rd = rn EOR op2 globals.regs[Rd] = op2_val ^ globals.regs[Rn] if (self.d_op_code == 2): # SUB rd = rn - op2 globals.regs[Rd] = globals.regs[Rn] - op2_val if (self.d_op_code == 3): # RSB rd = op2 - rn globals.regs[Rd] = op2_val - globals.regs[Rn] if (self.d_op_code == 4): # ADD rd = rn + op2 globals.regs[Rd] = globals.regs[Rn] + op2_val if (self.d_op_code == 5): # ADC rd = rn + op2 + carry globals.regs[Rd] = globals.regs[Rn] + op2_val + carry logging.debug("Rd:" + str(Rd) + " Rn:" + str(Rn) + " OP2:" + str(op2_val) + " C:" + str(carry)) if (self.d_op_code == 6): # SBC rd = rn - op2 - not(carry) globals.regs[Rd] = globals.regs[Rn] - op2_val - ~carry if (self.d_op_code == 7): # RSC rd = op2 - rn - not carry globals.regs[Rd] = op2_val - globals.regs[Rn] - ~carry if (self.d_op_code == 8): # TST flags -> rn & op2 flags = globals.regs[Rn] & op2_val if (self.d_op_code == 9): # TEQ flags -> rn ^ op2 flags = globals.regs[Rn] ^ op2_val if (self.d_op_code == 10): # CMP flags -> rn - op2 flags = globals.regs[Rn] - op2_val if (self.d_op_code == 11): # CMN flags -> rn + op2 flags = globals.regs[Rn] + op2_val if (self.d_op_code == 12): # ORR rd = rn or op2 globals.regs[Rd] = op2_val | globals.regs[Rn] if (self.d_op_code == 13): # MOV rd = op2 (rn ignored) globals.regs[Rd] = op2_val if (self.d_op_code == 14): # BIC rd = rn & !op2 (bit clear) globals.regs[Rd] = globals.regs[Rn] & ~op2_val if (self.d_op_code == 15): # MVN !rd (rn igrnored) globals.regs[Rd] = ~op2_val if (sCode != 0 and Rd != 15): # set the flags if globals.regs[Rd] == 0: # Zero globals.regs[globals.CPSR] = globals.regs[globals.CPSR] | ARMCPU.ZEROBIT else: globals.regs[globals.CPSR] = globals.regs[globals.CPSR] & ~ARMCPU.ZEROBIT if carryOut == 1: globals.regs[globals.CPSR] = globals.regs[globals.CPSR] | ARMCPU.CARRYBIT else: globals.regs[globals.CPSR] = globals.regs[globals.CPSR] & ~ARMCPU.CARRYBIT return retStr
def doDataInst(self, code, execute): global Rd global Rn global condCode logging.debug("doDataInst: code:" + str("%08X"%code) + " Rn:" + str(Rn) + " Rd:" + str(Rd)) """ opCode is the data instructions """ mod = code >> 20 & 1 # S bit & other instructions if self.d_op_code == 9 and mod == 0: # BKPT address = ((code & 0xFFF00) >> 4) | (code & 0xF) retStr = " BKPT #" + str(address) if execute == 1: ARMCPU.breakpoint(self, address) return retStr if not conditionMet(self, condCode): logging.debug("doDataInst: turn off exec because condition is " + hex(condCode) + " met") execute = 0 op2_val = getOP2DataProcessing(self, code, 0) logging.debug("d_op_code:"+hex(d_op_code)+" op2_val:"+hex(op2_val)+" d:"+str(Rd)) # output instruction # split functionality by opcode; AND, MLA, MUL, STR, LDR, udf, LDR retStr = getOP2DataProcessing(self, code, 1) overflow = 0 copySPSRtoCPSR = 0 carryOut = 0 if (self.d_op_code == 0): oc2 = (code >> 4) & 15 if oc2 == 0b0001: # # or Rs # AND if (not execute): retStr =+ getOP2DataProcessing(self, code, 1) else: globals.regs[Rd] = op2_val & globals.regs[Rn] if oc2 == 0b1001: if (code >> 21) & 1 == 1: # A retStr = " MLA" else: retStr = " MUL" getRm(self, code) getRs(self, code) if (execute): logging.debug("mul " + hex(globals.regs[Rd]) + " " + hex(globals.regs[Rm]) + " " + hex(globals.regs[Rs])) logging.debug("mul " + str(Rd) + " " + str(Rm) + " " + str(Rs)) if (code >> 21) & 1 == 1: # A # MLA Rd = Rm * Rs + Rn globals.regs[Rd] = globals.regs[Rm] * globals.regs[Rs] + globals.regs[Rn] else: # MUL Rd = Rm * Rs globals.regs[Rd] = globals.regs[Rm] * globals.regs[Rs] if oc2 == 0b1011 and mod == 0: retStr = " STR" if oc2 == 0b1011 and mod == 1: retStr = " LDR" if oc2 == 0b1101 and mod == 0: retStr = " udf" if oc2 == 0b1101 and mod == 1: retStr = " LDR" if oc2 == 0b1111 and mod == 0: retStr = " udf" if oc2 == 0b1111 and mod == 1: retStr = " LDR" carry = ARMCPU.isCarry(self) if (self.d_op_code == 1): # EOR rd = rn EOR op2 globals.regs[Rd] = op2_val ^ globals.regs[Rn] if (self.d_op_code == 2): # SUB rd = rn - op2 globals.regs[Rd] = globals.regs[Rn] - op2_val if (self.d_op_code == 3): # RSB rd = op2 - rn globals.regs[Rd] = op2_val - globals.regs[Rn] if (self.d_op_code == 4): # ADD rd = rn + op2 globals.regs[Rd] = globals.regs[Rn] + op2_val if (globals.regs[Rn] & 0x80000000) == 0 and (op2_val & 0x80000000) == 0 and (globals.regs[Rd] & 0x80000000) > 0: overflow = 1 if (globals.regs[Rn] & 0x80000000) > 0 and (op2_val & 0x80000000) > 0 and (globals.regs[Rd] & 0x80000000) == 0: overflow = 1 if (self.d_op_code == 5): # ADC rd = rn + op2 + carry globals.regs[Rd] = globals.regs[Rn] + op2_val + carry if (globals.regs[Rn] & 0x80000000) == 0 and (op2_val & 0x80000000) == 0 and (globals.regs[Rd] & 0x80000000) > 0: overflow = 1 if (globals.regs[Rn] & 0x80000000) > 0 and (op2_val & 0x80000000) > 0 and (globals.regs[Rd] & 0x80000000) == 0: overflow = 1 if Rd == 15: copySPSRtoCPSR = 1 logging.debug("Rd:" + str(Rd) + " Rn:" + str(Rn) + " OP2:" + hex(op2_val) + " C:" + str(carry)) if (self.d_op_code == 6): # SBC rd = rn - op2 - not(carry) globals.regs[Rd] = globals.regs[Rn] - op2_val - ~carry if (globals.regs[Rn] & 0x80000000) == 0 and (op2_val & 0x80000000) == 0 and (globals.regs[Rd] & 0x80000000) > 0: overflow = 1 if (globals.regs[Rn] & 0x80000000) > 0 and (op2_val & 0x80000000) > 0 and (globals.regs[Rd] & 0x80000000) == 0: overflow = 1 if (self.d_op_code == 7): # RSC rd = op2 - rn - not carry globals.regs[Rd] = op2_val - globals.regs[Rn] - ~carry if (self.d_op_code == 8): # TST flags -> rn & op2 flags = globals.regs[Rn] & op2_val if (self.d_op_code == 9): if mod == 1: # TEQ flags -> rn ^ op2 flags = globals.regs[Rn] ^ op2_val if (self.d_op_code == 10): # CMP flags -> rn - op2 flags = globals.regs[Rn] - op2_val if (self.d_op_code == 11): # CMN flags -> rn + op2 flags = globals.regs[Rn] + op2_val if (self.d_op_code == 12): # ORR rd = rn or op2 globals.regs[Rd] = op2_val | globals.regs[Rn] if (self.d_op_code == 13): # MOV rd = op2 (rn ignored) globals.regs[Rd] = op2_val if (self.d_op_code == 14): # BIC rd = rn & !op2 (bit clear) globals.regs[Rd] = globals.regs[Rn] & ~op2_val if (self.d_op_code == 15): # MVN !rd (rn igrnored) globals.regs[Rd] = ~op2_val if globals.regs[Rd] > 0xFFFFFFFF: # limit value to register size globals.regs[Rd] = 0 carryOut = 1 if (sCode != 0 and Rd != 15): # set the flags if globals.regs[Rd] == 0: # Zero globals.regs[globals.CPSR] = globals.regs[globals.CPSR] | ARMCPU.ZEROBIT else: globals.regs[globals.CPSR] = globals.regs[globals.CPSR] & ~ARMCPU.ZEROBIT if globals.regs[Rd] & 0x80000000 > 0: # negative globals.regs[globals.CPSR] = globals.regs[globals.CPSR] | ARMCPU.NEGATIVEBIT else: globals.regs[globals.CPSR] = globals.regs[globals.CPSR] & ~ARMCPU.NEGATIVEBIT if carryOut == 1: globals.regs[globals.CPSR] = globals.regs[globals.CPSR] | ARMCPU.CARRYBIT else: globals.regs[globals.CPSR] = globals.regs[globals.CPSR] & ~ARMCPU.CARRYBIT if overflow == 1: globals.regs[globals.CPSR] = globals.regs[globals.CPSR] | ARMCPU.OVERBIT else: globals.regs[globals.CPSR] = globals.regs[globals.CPSR] & ~ARMCPU.OVERBIT if copySPSRtoCPSR == 1: globals.regs[globals.CPSR] = globals.regs[globals.SPSR] return retStr