def execute_stm1(s, inst): if condition_passed(s, inst.cond): orig_Rn = s.rf[inst.rn] addr, end_addr = addressing_mode_4(s, inst) register_mask = inst.register_list # TODO: support multiple memory accessing modes? # MemoryAccess( s.B, s.E ) for i in range(16): if register_mask & 0b1: # Note from ISA document page A4-190: # If <Rn> is specified in <registers> and base register write-back # is specified: # - If <Rn> is the lowest-numbered register specified in # <registers>, the original value of <Rn> is stored. # - Otherwise, the stored value of <Rn> is UNPREDICTABLE. # # We check if i is Rn, and if so, we use the original value if i == inst.rn: s.mem.write(addr, 4, orig_Rn) else: s.mem.write(addr, 4, s.rf[i]) addr += 4 register_mask >>= 1 assert end_addr == addr - 4 s.rf[PC] = s.fetch_pc() + 4
def execute_stm1( s, inst ): if condition_passed( s, inst.cond ): orig_Rn = s.rf[ inst.rn ] addr, end_addr = addressing_mode_4( s, inst ) register_mask = inst.register_list # TODO: support multiple memory accessing modes? # MemoryAccess( s.B, s.E ) for i in range(16): if register_mask & 0b1: # Note from ISA document page A4-190: # If <Rn> is specified in <registers> and base register write-back # is specified: # - If <Rn> is the lowest-numbered register specified in # <registers>, the original value of <Rn> is stored. # - Otherwise, the stored value of <Rn> is UNPREDICTABLE. # # We check if i is Rn, and if so, we use the original value if i == inst.rn: s.mem.write( addr, 4, orig_Rn ) else: s.mem.write( addr, 4, s.rf[i] ) addr += 4 register_mask >>= 1 assert end_addr == addr - 4 s.rf[PC] = s.fetch_pc() + 4
def execute_mrs( s, inst ): if condition_passed( s, inst.cond ): if inst.R: raise FatalError('Cannot read SPSR in "mrs"') else: s.rf[ inst.rd ] = s.cpsr() s.rf[PC] = s.fetch_pc() + 4
def execute_mrs(s, inst): if condition_passed(s, inst.cond): if inst.R: raise FatalError('Cannot read SPSR in "mrs"') else: s.rf[inst.rd] = s.cpsr() s.rf[PC] = s.fetch_pc() + 4
def execute_bl( s, inst ): if condition_passed( s, inst.cond ): s.rf[LR] = trim_32( s.fetch_pc() + 4 ) offset = signed( sext_30( inst.imm_24 ) << 2 ) s.rf[PC] = trim_32( signed( s.rf[PC] ) + offset ) return s.rf[PC] = s.fetch_pc() + 4
def execute_bl(s, inst): if condition_passed(s, inst.cond()): s.rf[LR] = trim_32(s.fetch_pc() + 4) offset = signed(sign_extend_30(inst.imm_24()) << 2) s.rf[PC] = trim_32(s.rf[PC] + offset) return s.rf[PC] = s.fetch_pc() + 4
def execute_ldr(s, inst): if condition_passed(s, inst.cond()): addr = addressing_mode_2(s, inst) # TODO: support multiple memory accessing modes? # MemoryAccess( s.B, s.E ) # TODO: handle memory alignment? # CP15_reg1_Ubit checks if the MMU is enabled # if (CP15_reg1_Ubit == 0): # data = Memory[address,4] Rotate_Right (8 * address[1:0]) # else # data = Memory[address,4] data = s.mem.read(addr, 4) if inst.rd() == 15: s.rf[PC] = data & 0xFFFFFFFE s.T = data & 0b1 return else: s.rf[inst.rd()] = data s.rf[PC] = s.fetch_pc() + 4
def execute_ldr( s, inst ): if condition_passed( s, inst.cond ): addr = addressing_mode_2( s, inst ) # TODO: support multiple memory accessing modes? # MemoryAccess( s.B, s.E ) # TODO: handle memory alignment? # CP15_reg1_Ubit checks if the MMU is enabled # if (CP15_reg1_Ubit == 0): # data = Memory[address,4] Rotate_Right (8 * address[1:0]) # else # data = Memory[address,4] data = s.mem.read( addr, 4 ) if inst.rd == 15: s.rf[PC] = data & 0xFFFFFFFE s.T = data & 0b1 return else: s.rf[ inst.rd ] = data s.rf[PC] = s.fetch_pc() + 4
def execute_swp( s, inst ): if condition_passed( s, inst.cond ): addr = s.rf[ inst.rn ] temp = s.mem.read( addr, 4 ) s.mem.write( addr, 4, s.rf[ inst.rm ] ) s.rf[ inst.rd ] = temp s.rf[PC] = s.fetch_pc() + 4
def execute_swp(s, inst): if condition_passed(s, inst.cond): addr = s.rf[inst.rn] temp = s.mem.read(addr, 4) s.mem.write(addr, 4, s.rf[inst.rm]) s.rf[inst.rd] = temp s.rf[PC] = s.fetch_pc() + 4
def execute_strb( s, inst ): if condition_passed( s, inst.cond ): addr = addressing_mode_2( s, inst ) s.mem.write( addr, 1, trim_8( s.rf[ inst.rd ] ) ) s.rf[PC] = s.fetch_pc() + 4
def execute_strb(s, inst): if condition_passed(s, inst.cond()): addr = addressing_mode_2(s, inst) s.mem.write(addr, 1, trim_8(s.rf[inst.rd()])) s.rf[PC] = s.fetch_pc() + 4
def execute_bx(s, inst): if condition_passed(s, inst.cond()): s.T = s.rf[inst.rm()] & 0x00000001 s.rf[PC] = s.rf[inst.rm()] & 0xFFFFFFFE if s.T: raise FatalError("Entering THUMB mode! Unsupported!") # no pc + 4 on success else: s.rf[PC] = s.fetch_pc() + 4
def execute_bx( s, inst ): if condition_passed( s, inst.cond ): s.T = s.rf[ inst.rm ] & 0x00000001 s.rf[PC] = s.rf[ inst.rm ] & 0xFFFFFFFE if s.T: raise FatalError( "Entering THUMB mode! Unsupported!") # no pc + 4 on success else: s.rf[PC] = s.fetch_pc() + 4
def execute_str( s, inst ): if condition_passed( s, inst.cond ): addr = addressing_mode_2( s, inst ) # TODO: support multiple memory accessing modes? # MemoryAccess( s.B, s.E ) s.mem.write( addr, 4, s.rf[ inst.rd ] ) s.rf[PC] = s.fetch_pc() + 4
def execute_str(s, inst): if condition_passed(s, inst.cond()): addr = addressing_mode_2(s, inst) # TODO: support multiple memory accessing modes? # MemoryAccess( s.B, s.E ) s.mem.write(addr, 4, s.rf[inst.rd()]) s.rf[PC] = s.fetch_pc() + 4
def execute_ldrb( s, inst ): if condition_passed( s, inst.cond ): if inst.rd == 15: raise FatalError('UNPREDICTABLE') addr = addressing_mode_2( s, inst ) # TODO: support multiple memory accessing modes? # MemoryAccess( s.B, s.E ) s.rf[ inst.rd ] = s.mem.read( addr, 1 ) s.rf[PC] = s.fetch_pc() + 4
def execute_ldrb(s, inst): if condition_passed(s, inst.cond()): if inst.rd() == 15: raise FatalError('UNPREDICTABLE') addr = addressing_mode_2(s, inst) # TODO: support multiple memory accessing modes? # MemoryAccess( s.B, s.E ) s.rf[inst.rd()] = s.mem.read(addr, 1) s.rf[PC] = s.fetch_pc() + 4
def execute_tst( s, inst ): if condition_passed( s, inst.cond ): a, (b, cout) = s.rf[ inst.rn ], shifter_operand( s, inst ) result = trim_32( a & b ) if inst.S: s.N = (result >> 31)&1 s.Z = result == 0 s.C = cout if inst.rd == 15: return s.rf[PC] = s.fetch_pc() + 4
def execute_cmp( s, inst ): if condition_passed( s, inst.cond ): a, (b, _) = s.rf[ inst.rn ], shifter_operand( s, inst ) result = intmask( a - b ) s.N = (result >> 31)&1 s.Z = trim_32( result ) == 0 s.C = not_borrow_from( result ) s.V = overflow_from_sub( a, b, result ) if inst.rd == 15: return s.rf[PC] = s.fetch_pc() + 4
def execute_cmp(s, inst): if condition_passed(s, inst.cond()): a, (b, _) = s.rf[inst.rn()], shifter_operand(s, inst) result = a - b s.N = (result >> 31) & 1 s.Z = trim_32(result) == 0 s.C = not borrow_from(result) s.V = overflow_from_sub(a, b, result) if inst.rd() == 15: return s.rf[PC] = s.fetch_pc() + 4
def execute_cmn(s, inst): if condition_passed(s, inst.cond): a, (b, _) = s.rf[inst.rn], shifter_operand(s, inst) result = a + b s.N = (result >> 31) & 1 s.Z = trim_32(result) == 0 s.C = carry_from(result) s.V = overflow_from_add(a, b, result) if inst.rd == 15: return s.rf[PC] = s.fetch_pc() + 4
def execute_cmn( s, inst ): if condition_passed( s, inst.cond ): a, (b, _) = s.rf[ inst.rn ], shifter_operand( s, inst ) result = a + b s.N = (result >> 31)&1 s.Z = trim_32( result ) == 0 s.C = carry_from( result ) s.V = overflow_from_add( a, b, result ) if inst.rd == 15: return s.rf[PC] = s.fetch_pc() + 4
def execute_tst(s, inst): if condition_passed(s, inst.cond()): a, (b, cout) = s.rf[inst.rn()], shifter_operand(s, inst) result = trim_32(a & b) if inst.S(): s.N = (result >> 31) & 1 s.Z = result == 0 s.C = cout if inst.rd() == 15: return s.rf[PC] = s.fetch_pc() + 4
def execute_strh(s, inst): if condition_passed(s, inst.cond()): addr = addressing_mode_3(s, inst) # TODO: support multiple memory accessing modes? # MemoryAccess( s.B, s.E ) # TODO: alignment fault checking? # if (CP15_reg1_Ubit == 0) and address[0] == 0b1: # UNPREDICTABLE s.mem.write(addr, 2, s.rf[inst.rd()] & 0xFFFF) s.rf[PC] = s.fetch_pc() + 4
def execute_strh( s, inst ): if condition_passed( s, inst.cond ): addr = addressing_mode_3( s, inst ) # TODO: support multiple memory accessing modes? # MemoryAccess( s.B, s.E ) # TODO: alignment fault checking? # if (CP15_reg1_Ubit == 0) and address[0] == 0b1: # UNPREDICTABLE s.mem.write( addr, 2, s.rf[ inst.rd ] & 0xFFFF ) s.rf[PC] = s.fetch_pc() + 4
def execute_ldrsh(s, inst): if condition_passed(s, inst.cond()): if inst.rd() == 15: raise FatalError('UNPREDICTABLE') addr = addressing_mode_3(s, inst) # TODO: support multiple memory accessing modes? # MemoryAccess( s.B, s.E ) # TODO: alignment fault checking? # if (CP15_reg1_Ubit == 0) and address[0] == 0b1: # UNPREDICTABLE s.rf[inst.rd()] = sign_extend_half(s.mem.read(addr, 2)) s.rf[PC] = s.fetch_pc() + 4
def execute_bic( s, inst ): if condition_passed( s, inst.cond ): a, (b, cout) = s.rf[ inst.rn ], shifter_operand( s, inst ) result = a & trim_32(~b) s.rf[ inst.rd ] = trim_32( result ) if inst.S: if inst.rd == 15: raise FatalError('Writing SPSR not implemented!') s.N = (result >> 31)&1 s.Z = trim_32( result ) == 0 s.C = cout if inst.rd == 15: return s.rf[PC] = s.fetch_pc() + 4
def execute_ldrsh( s, inst ): if condition_passed( s, inst.cond ): if inst.rd == 15: raise FatalError('UNPREDICTABLE') addr = addressing_mode_3( s, inst ) # TODO: support multiple memory accessing modes? # MemoryAccess( s.B, s.E ) # TODO: alignment fault checking? # if (CP15_reg1_Ubit == 0) and address[0] == 0b1: # UNPREDICTABLE s.rf[ inst.rd ] = sext_16( s.mem.read( addr, 2 ) ) s.rf[PC] = s.fetch_pc() + 4
def execute_bic(s, inst): if condition_passed(s, inst.cond): a, (b, cout) = s.rf[inst.rn], shifter_operand(s, inst) result = a & trim_32(~b) s.rf[inst.rd] = trim_32(result) if inst.S: if inst.rd == 15: raise FatalError('Writing SPSR not implemented!') s.N = (result >> 31) & 1 s.Z = trim_32(result) == 0 s.C = cout if inst.rd == 15: return s.rf[PC] = s.fetch_pc() + 4
def execute_mla(s, inst): if condition_passed(s, inst.cond): if inst.rd == 15: raise FatalError('UNPREDICTABLE') if inst.rm == 15: raise FatalError('UNPREDICTABLE') if inst.rs == 15: raise FatalError('UNPREDICTABLE') if inst.rn == 15: raise FatalError('UNPREDICTABLE') Rm, Rs, Rd = s.rf[inst.rm], s.rf[inst.rs], s.rf[inst.rd] result = trim_32(Rm * Rs + Rd) s.rf[inst.rn] = result if inst.S: s.N = (result >> 31) & 1 s.Z = result == 0 s.rf[PC] = s.fetch_pc() + 4
def execute_stm1(s, inst): if condition_passed(s, inst.cond()): addr, end_addr = addressing_mode_4(s, inst) register_mask = inst.register_list() # TODO: support multiple memory accessing modes? # MemoryAccess( s.B, s.E ) for i in range(16): if register_mask & 0b1: s.mem.write(addr, 4, s.rf[i]) addr += 4 register_mask >>= 1 assert end_addr == addr - 4 s.rf[PC] = s.fetch_pc() + 4
def execute_sbc(s, inst): if condition_passed(s, inst.cond): a, (b, _) = s.rf[inst.rn], shifter_operand(s, inst) result = intmask(a - b - (not s.C)) s.rf[inst.rd] = trim_32(result) if inst.S: if inst.rd == 15: raise FatalError('Writing SPSR not implemented!') s.N = (result >> 31) & 1 s.Z = trim_32(result) == 0 s.C = not_borrow_from(result) s.V = overflow_from_sub(a, b, result) if inst.rd == 15: return s.rf[PC] = s.fetch_pc() + 4
def execute_mvn(s, inst): if condition_passed(s, inst.cond): a, cout = shifter_operand(s, inst) result = trim_32(~a) s.rf[inst.rd] = result if inst.S: if inst.rd == 15: raise FatalError('Writing SPSR not implemented!') s.N = (result >> 31) & 1 s.Z = trim_32(result) == 0 s.C = cout s.V = s.V if inst.rd == 15: return s.rf[PC] = s.fetch_pc() + 4
def execute_adc( s, inst ): if condition_passed( s, inst.cond ): a, (b, _) = s.rf[ inst.rn ], shifter_operand( s, inst ) result = a + b + s.C s.rf[ inst.rd ] = trim_32( result ) if inst.S: if inst.rd == 15: raise FatalError('Writing SPSR not implemented!') s.N = (result >> 31)&1 s.Z = trim_32( result ) == 0 s.C = carry_from( result ) s.V = overflow_from_add( a, b, result ) if inst.rd == 15: return s.rf[PC] = s.fetch_pc() + 4
def execute_mvn( s, inst ): if condition_passed( s, inst.cond ): a, cout = shifter_operand( s, inst ) result = trim_32( ~a ) s.rf[ inst.rd ] = result if inst.S: if inst.rd == 15: raise FatalError('Writing SPSR not implemented!') s.N = (result >> 31)&1 s.Z = trim_32( result ) == 0 s.C = cout s.V = s.V if inst.rd == 15: return s.rf[PC] = s.fetch_pc() + 4
def execute_sbc( s, inst ): if condition_passed( s, inst.cond ): a, (b, _) = s.rf[ inst.rn ], shifter_operand( s, inst ) result = intmask( a - b - (not s.C) ) s.rf[ inst.rd ] = trim_32( result ) if inst.S: if inst.rd == 15: raise FatalError('Writing SPSR not implemented!') s.N = (result >> 31)&1 s.Z = trim_32( result ) == 0 s.C = not_borrow_from( result ) s.V = overflow_from_sub( a, b, result ) if inst.rd == 15: return s.rf[PC] = s.fetch_pc() + 4
def execute_adc(s, inst): if condition_passed(s, inst.cond): a, (b, _) = s.rf[inst.rn], shifter_operand(s, inst) result = a + b + s.C s.rf[inst.rd] = trim_32(result) if inst.S: if inst.rd == 15: raise FatalError('Writing SPSR not implemented!') s.N = (result >> 31) & 1 s.Z = trim_32(result) == 0 s.C = carry_from(result) s.V = overflow_from_add(a, b, result) if inst.rd == 15: return s.rf[PC] = s.fetch_pc() + 4
def execute_mul( s, inst ): if condition_passed( s, inst.cond ): Rm, Rs = s.rf[ inst.rm ], s.rf[ inst.rs ] result = trim_32(Rm * Rs) s.rf[ inst.rn ] = result if inst.S: if inst.rn == 15: raise FatalError('UNPREDICTABLE') if inst.rm == 15: raise FatalError('UNPREDICTABLE') if inst.rs == 15: raise FatalError('UNPREDICTABLE') s.N = (result >> 31)&1 s.Z = result == 0 if inst.rd == 15: return s.rf[PC] = s.fetch_pc() + 4
def execute_mul(s, inst): if condition_passed(s, inst.cond()): Rm, Rs = s.rf[inst.rm()], s.rf[inst.rs()] result = trim_32(Rm * Rs) s.rf[inst.rn()] = result if inst.S(): if inst.rn() == 15: raise FatalError('UNPREDICTABLE') if inst.rm() == 15: raise FatalError('UNPREDICTABLE') if inst.rs() == 15: raise FatalError('UNPREDICTABLE') s.N = (result >> 31) & 1 s.Z = result == 0 if inst.rd() == 15: return s.rf[PC] = s.fetch_pc() + 4
def execute_mla( s, inst ): if condition_passed( s, inst.cond ): if inst.rd == 15: raise FatalError('UNPREDICTABLE') if inst.rm == 15: raise FatalError('UNPREDICTABLE') if inst.rs == 15: raise FatalError('UNPREDICTABLE') if inst.rn == 15: raise FatalError('UNPREDICTABLE') Rm, Rs, Rd = s.rf[ inst.rm ], s.rf[ inst.rs ], s.rf[ inst.rd ] result = trim_32(Rm * Rs + Rd) s.rf[ inst.rn ] = result if inst.S: s.N = (result >> 31)&1 s.Z = result == 0 s.rf[PC] = s.fetch_pc() + 4
def execute_rsc(s, inst): if condition_passed(s, inst.cond()): a, (b, _) = s.rf[inst.rn()], shifter_operand(s, inst) result = b - a - (not s.C) s.rf[inst.rd()] = trim_32(result) if inst.S(): if inst.rd() == 15: raise FatalError('Writing SPSR not implemented!') s.N = (result >> 31) & 1 s.Z = trim_32(result) == 0 s.C = not borrow_from(result) s.V = overflow_from_sub(b, a, result) if inst.rd() == 15: return s.rf[PC] = s.fetch_pc() + 4
def execute_orr(s, inst): if condition_passed(s, inst.cond()): a, (b, cout) = s.rf[inst.rn()], shifter_operand(s, inst) result = a | b s.rf[inst.rd()] = trim_32(result) if inst.S(): if inst.rd() == 15: raise FatalError('Writing SPSR not implemented!') s.N = (result >> 31) & 1 s.Z = trim_32(result) == 0 s.C = cout s.V = s.V if inst.rd() == 15: return s.rf[PC] = s.fetch_pc() + 4
def execute_mov( s, inst ): if condition_passed( s, inst.cond ): if inst.rd == 15 and inst.S: # if not CurrentModeHasSPSR(): CPSR = SPSR # else: UNPREDICTABLE raise FatalError('UNPREDICTABLE in user and system mode!') result, cout = shifter_operand( s, inst ) s.rf[ inst.rd ] = trim_32( result ) if inst.S: s.N = (result >> 31)&1 s.Z = trim_32( result ) == 0 s.C = cout s.V = s.V if inst.rd == 15: return s.rf[PC] = s.fetch_pc() + 4
def execute_mov(s, inst): if condition_passed(s, inst.cond()): if inst.rd() == 15 and inst.S(): # if not CurrentModeHasSPSR(): CPSR = SPSR # else: UNPREDICTABLE raise FatalError('UNPREDICTABLE in user and system mode!') result, cout = shifter_operand(s, inst) s.rf[inst.rd()] = trim_32(result) if inst.S(): s.N = (result >> 31) & 1 s.Z = trim_32(result) == 0 s.C = cout s.V = s.V if inst.rd() == 15: return s.rf[PC] = s.fetch_pc() + 4
def execute_smull( s, inst ): if condition_passed( s, inst.cond ): if inst.rd == 15: raise FatalError('UNPREDICTABLE') if inst.rm == 15: raise FatalError('UNPREDICTABLE') if inst.rs == 15: raise FatalError('UNPREDICTABLE') if inst.rn == 15: raise FatalError('UNPREDICTABLE') RdHi, RdLo = inst.rn, inst.rd Rm, Rs = signed(s.rf[ inst.rm ]), signed(s.rf[ inst.rs ]) result = Rm * Rs if RdHi == RdLo: raise FatalError('UNPREDICTABLE') s.rf[ RdHi ] = trim_32( result >> 32 ) s.rf[ RdLo ] = trim_32( result ) if inst.S: s.N = (result >> 63)&1 s.Z = result == 0 s.rf[PC] = s.fetch_pc() + 4
def execute_smull(s, inst): if condition_passed(s, inst.cond): if inst.rd == 15: raise FatalError('UNPREDICTABLE') if inst.rm == 15: raise FatalError('UNPREDICTABLE') if inst.rs == 15: raise FatalError('UNPREDICTABLE') if inst.rn == 15: raise FatalError('UNPREDICTABLE') RdHi, RdLo = inst.rn, inst.rd Rm, Rs = signed(s.rf[inst.rm]), signed(s.rf[inst.rs]) result = Rm * Rs if RdHi == RdLo: raise FatalError('UNPREDICTABLE') s.rf[RdHi] = trim_32(result >> 32) s.rf[RdLo] = trim_32(result) if inst.S: s.N = (result >> 63) & 1 s.Z = result == 0 s.rf[PC] = s.fetch_pc() + 4
def execute_umull(s, inst): if condition_passed(s, inst.cond()): if inst.rd() == 15: raise FatalError('UNPREDICTABLE') if inst.rm() == 15: raise FatalError('UNPREDICTABLE') if inst.rs() == 15: raise FatalError('UNPREDICTABLE') if inst.rn() == 15: raise FatalError('UNPREDICTABLE') RdHi, RdLo = inst.rn(), inst.rd() Rm, Rs = s.rf[inst.rm()], s.rf[inst.rs()] result = Rm * Rs if RdHi == RdLo: raise FatalError('UNPREDICTABLE') s.rf[RdHi] = trim_32(result >> 32) s.rf[RdLo] = trim_32(result) if inst.S(): s.N = (result >> 63) & 1 s.Z = (s.rf[RdHi] == s.rf[RdLo] == 0) s.rf[PC] = s.fetch_pc() + 4
def execute_clz( s, inst ): if condition_passed( s, inst.cond ): Rm = s.rf[ inst.rm ] if Rm == 0: s.rf[ inst.rd ] = 32 else: mask = 0x80000000 leading_zeros = 32 for x in range(32): if mask & Rm: leading_zeros = x break mask >>= 1 assert leading_zeros != 32 s.rf[ inst.rd ] = leading_zeros if inst.rd == 15: return s.rf[PC] = s.fetch_pc() + 4
def execute_smlal( s, inst ): if condition_passed( s, inst.cond ): if inst.rd == 15: raise FatalError('UNPREDICTABLE') if inst.rm == 15: raise FatalError('UNPREDICTABLE') if inst.rs == 15: raise FatalError('UNPREDICTABLE') if inst.rn == 15: raise FatalError('UNPREDICTABLE') RdHi, RdLo = inst.rn, inst.rd Rm, Rs = signed(s.rf[ inst.rm ]), signed(s.rf[ inst.rs ]) accumulate = (s.rf[ RdHi ] << 32) | s.rf[ RdLo ] result = (Rm * Rs) + signed( accumulate ) if RdHi == RdLo: raise FatalError('UNPREDICTABLE') s.rf[ RdHi ] = trim_32( result >> 32 ) s.rf[ RdLo ] = trim_32( result ) if inst.S: s.N = (result >> 63)&1 s.Z = (s.rf[RdHi] == s.rf[RdLo] == 0) s.rf[PC] = s.fetch_pc() + 4
def execute_clz(s, inst): if condition_passed(s, inst.cond()): Rm = s.rf[inst.rm()] if Rm == 0: s.rf[inst.rd()] = 32 else: mask = 0x80000000 leading_zeros = 32 for x in range(31): if mask & Rm: leading_zeros = x break mask >>= 1 assert leading_zeros != 32 s.rf[inst.rd()] = leading_zeros if inst.rd() == 15: return s.rf[PC] = s.fetch_pc() + 4
def execute_umlal(s, inst): if condition_passed(s, inst.cond): if inst.rd == 15: raise FatalError('UNPREDICTABLE') if inst.rm == 15: raise FatalError('UNPREDICTABLE') if inst.rs == 15: raise FatalError('UNPREDICTABLE') if inst.rn == 15: raise FatalError('UNPREDICTABLE') RdHi, RdLo = inst.rn, inst.rd Rm, Rs = s.rf[inst.rm], s.rf[inst.rs] accumulate = (s.rf[RdHi] << 32) | s.rf[RdLo] result = (Rm * Rs) + accumulate if RdHi == RdLo: raise FatalError('UNPREDICTABLE') s.rf[RdHi] = trim_32(result >> 32) s.rf[RdLo] = trim_32(result) if inst.S: s.N = (result >> 63) & 1 s.Z = (s.rf[RdHi] == s.rf[RdLo] == 0) s.rf[PC] = s.fetch_pc() + 4
def execute_ldm1( s, inst ): if condition_passed( s, inst.cond ): addr, end_addr = addressing_mode_4( s, inst ) register_mask = inst.register_list # TODO: support multiple memory accessing modes? # MemoryAccess( s.B, s.E ) for i in range(15): if register_mask & 0b1: s.rf[ i ] = s.mem.read( addr, 4 ) addr += 4 register_mask >>= 1 if register_mask & 0b1: # reg 15 s.rf[PC] = s.mem.read( addr, 4 ) & 0xFFFFFFFE s.T = s.rf[PC] & 0b1 if s.T: raise FatalError( "Entering THUMB mode! Unsupported!") assert end_addr == addr return assert end_addr == addr - 4 s.rf[PC] = s.fetch_pc() + 4
def execute_ldm1(s, inst): if condition_passed(s, inst.cond()): addr, end_addr = addressing_mode_4(s, inst) register_mask = inst.register_list() # TODO: support multiple memory accessing modes? # MemoryAccess( s.B, s.E ) for i in range(15): if register_mask & 0b1: s.rf[i] = s.mem.read(addr, 4) addr += 4 register_mask >>= 1 if register_mask & 0b1: # reg 15 s.rf[PC] = s.mem.read(addr, 4) & 0xFFFFFFFE s.T = s.rf[PC] & 0b1 if s.T: raise FatalError("Entering THUMB mode! Unsupported!") assert end_addr == addr return assert end_addr == addr - 4 s.rf[PC] = s.fetch_pc() + 4
def execute_msr(s, inst): raise FatalError('"msr" instruction unimplemented!') if condition_passed(s, inst.cond()): pass s.rf[PC] = s.fetch_pc() + 4
def execute_swi( s, inst ): if condition_passed( s, inst.cond ): do_syscall( s ) s.rf[PC] = s.fetch_pc() + 4
def execute_stc( s, inst ): raise FatalError('"stc" instruction unimplemented!') if condition_passed( s, inst.cond ): pass s.rf[PC] = s.fetch_pc() + 4