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_div( s, inst ): x = signed( s.rf[ inst.rs ] ) y = signed( s.rf[ inst.rt ] ) sign = -1 if (x < 0)^(y < 0) else 1 s.rf[ inst.rd ] = trim_32( abs(x) / abs(y) * sign ) s.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_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_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_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_bne( s, inst ): if s.rf[inst.rs] != s.rf[inst.rt]: s.pc = trim_32( signed(s.pc) + 4 + signed(sext_16(inst.imm) << 2) ) else: s.pc += 4
def execute_srav( s, inst ): # TODO: should it really be masked like this? s.rf[inst.rd] = trim_32( signed( s.rf[inst.rt] ) >> trim_5( s.rf[inst.rs] ) ) s.pc += 4
def execute_sra( s, inst ): s.rf[inst.rd] = trim_32( signed( s.rf[inst.rt] ) >> inst.shamt ) s.pc += 4
def execute_slti( s, inst ): s.rf[inst.rt] = signed( s.rf[inst.rs] ) < signed( sext_16(inst.imm) ) s.pc += 4
def execute_rem( s, inst ): x = signed( s.rf[ inst.rs ] ) y = signed( s.rf[ inst.rt ] ) s.rf[ inst.rd ] = trim_32( abs(x) % abs(y) * (1 if x > 0 else -1) ) s.pc += 4
def execute_bgez( s, inst ): if signed( s.rf[inst.rs] ) >= 0: s.pc = s.pc + 4 + (signed(sext_16(inst.imm)) << 2) else: s.pc += 4
def execute_bne( s, inst ): if s.rf[inst.rs] != s.rf[inst.rt]: s.pc = s.pc + 4 + (signed(sext_16(inst.imm)) << 2) else: s.pc += 4
def execute_amo_min( s, inst ): temp = s.mem.read( s.rf[ inst.rs ], 4 ) s.mem.write( s.rf[inst.rs], 4, trim_32( min( signed( temp ), signed( s.rf[inst.rt] ) ) ) ) s.rf[ inst.rd ] = temp s.pc += 4
def execute_bgez( s, inst ): if signed( s.rf[inst.rs] ) >= 0: s.pc = trim_32( signed(s.pc) + 4 + signed(sext_16(inst.imm) << 2) ) else: s.pc += 4
def execute_cvt_s_w( s, inst ): x = signed( s.rf[ inst.fs ] ) s.rf[ inst.fd ] = float2bits( float( x ) ) s.pc += 4
def execute_slt( s, inst ): s.rf[inst.rd] = signed( s.rf[inst.rs] ) < signed( s.rf[inst.rt] ) s.pc += 4