1369 lines
43 KiB
Python
1369 lines
43 KiB
Python
from emulator.operations import *
|
|
|
|
class ILLSLOT(Exception):
|
|
pass
|
|
|
|
class TRAP(Exception):
|
|
pass
|
|
|
|
def clrt__no_operand(cpu, mem):
|
|
# CLRT
|
|
t = 0
|
|
cpu.sr.t = bit(t)
|
|
|
|
def clrmac__no_operand(cpu, mem):
|
|
# CLRMAC
|
|
macl = 0
|
|
mach = 0
|
|
cpu.macl = zero_extend32(macl)
|
|
cpu.mach = zero_extend32(mach)
|
|
|
|
def div0u__no_operand(cpu, mem):
|
|
# DIV0U
|
|
q = 0
|
|
m = 0
|
|
t = 0
|
|
cpu.sr.q = bit(q)
|
|
cpu.sr.m = bit(m)
|
|
cpu.sr.t = bit(t)
|
|
|
|
def nop__no_operand(cpu, mem):
|
|
# NOP
|
|
pass
|
|
|
|
def rte__no_operand(cpu, mem):
|
|
# RTE
|
|
pc = sign_extend32(cpu.pc)
|
|
if cpu.is_delay_slot:
|
|
raise ILLSLOT()
|
|
target = pc
|
|
delayedpc = target & (~0x1)
|
|
cpu.pc2 = register(delayedpc)
|
|
|
|
def rts__no_operand(cpu, mem):
|
|
# RTS
|
|
pr = sign_extend32(cpu.pr)
|
|
if cpu.is_delay_slot:
|
|
raise ILLSLOT()
|
|
target = pr
|
|
delayedpc = target & (~0x1)
|
|
cpu.pc2 = register(delayedpc)
|
|
|
|
def sett__no_operand(cpu, mem):
|
|
# SETT
|
|
t = 1
|
|
cpu.sr.t = bit(t)
|
|
|
|
def sleep__no_operand(cpu, mem):
|
|
# SLEEP
|
|
raise NotImplementedError()
|
|
|
|
def cmp_pl__destination_operand_only(cpu, mem, n):
|
|
# CMP/PL Rn
|
|
op1 = sign_extend32(cpu.reg[n])
|
|
t = int(op1 > 0)
|
|
cpu.sr.t = bit(t)
|
|
|
|
def cmp_pz__destination_operand_only(cpu, mem, n):
|
|
# CMP/PZ Rn
|
|
op1 = sign_extend32(cpu.reg[n])
|
|
t = int(op1 >= 0)
|
|
cpu.sr.t = bit(t)
|
|
|
|
def dt__destination_operand_only(cpu, mem, n):
|
|
# DT Rn
|
|
op1 = sign_extend32(cpu.reg[n])
|
|
op1 = op1 - 1
|
|
t = int(op1 == 0)
|
|
cpu.reg[n] = register(op1)
|
|
cpu.sr.t = bit(t)
|
|
|
|
def movt__destination_operand_only(cpu, mem, n):
|
|
# MOVT Rn
|
|
t = zero_extend1(cpu.sr.t)
|
|
op1 = t
|
|
cpu.reg[n] = register(op1)
|
|
|
|
def rotl__destination_operand_only(cpu, mem, n):
|
|
# ROTL Rn
|
|
op1 = zero_extend32(cpu.reg[n])
|
|
t = (op1 >> 31) & 1
|
|
op1 = (op1 << 1) | t
|
|
cpu.reg[n] = register(op1)
|
|
cpu.sr.t = bit(t)
|
|
|
|
def rotr__destination_operand_only(cpu, mem, n):
|
|
# ROTR Rn
|
|
op1 = zero_extend32(cpu.reg[n])
|
|
t = (op1 >> 0) & 1
|
|
op1 = (op1 >> 1) | (t << 31)
|
|
cpu.reg[n] = register(op1)
|
|
cpu.sr.t = bit(t)
|
|
|
|
def rotcl__destination_operand_only(cpu, mem, n):
|
|
# ROTCL Rn
|
|
t = zero_extend1(cpu.sr.t)
|
|
op1 = zero_extend32(cpu.reg[n])
|
|
op1 = (op1 << 1) | t
|
|
t = (op1 >> 32) & 1
|
|
cpu.reg[n] = register(op1)
|
|
cpu.sr.t = bit(t)
|
|
|
|
def rotcr__destination_operand_only(cpu, mem, n):
|
|
# ROTCR Rn
|
|
t = zero_extend1(cpu.sr.t)
|
|
op1 = zero_extend32(cpu.reg[n])
|
|
oldt = t
|
|
t = (op1 >> 0) & 1
|
|
op1 = (op1 >> 1) | (oldt << 31)
|
|
cpu.reg[n] = register(op1)
|
|
cpu.sr.t = bit(t)
|
|
|
|
def shal__destination_operand_only(cpu, mem, n):
|
|
# SHAL Rn
|
|
op1 = sign_extend32(cpu.reg[n])
|
|
t = (op1 >> 31) & 1
|
|
op1 = op1 << 1
|
|
cpu.reg[n] = register(op1)
|
|
cpu.sr.t = bit(t)
|
|
|
|
def shar__destination_operand_only(cpu, mem, n):
|
|
# SHAR Rn
|
|
op1 = sign_extend32(cpu.reg[n])
|
|
t = (op1 >> 0) & 1
|
|
op1 = op1 >> 1
|
|
cpu.reg[n] = register(op1)
|
|
cpu.sr.t = bit(t)
|
|
|
|
def shll__destination_operand_only(cpu, mem, n):
|
|
# SHLL Rn
|
|
op1 = zero_extend32(cpu.reg[n])
|
|
t = (op1 >> 31) & 1
|
|
op1 = op1 << 1
|
|
cpu.reg[n] = register(op1)
|
|
cpu.sr.t = bit(t)
|
|
|
|
def shlr__destination_operand_only(cpu, mem, n):
|
|
# SHLR Rn
|
|
op1 = zero_extend32(cpu.reg[n])
|
|
t = (op1 >> 0) & 1
|
|
op1 = op1 >> 1
|
|
cpu.reg[n] = register(op1)
|
|
cpu.sr.t = bit(t)
|
|
|
|
def shll2__destination_operand_only(cpu, mem, n):
|
|
# SHLL2 Rn
|
|
op1 = zero_extend32(cpu.reg[n])
|
|
op1 = op1 << 2
|
|
cpu.reg[n] = register(op1)
|
|
|
|
def shlr2__destination_operand_only(cpu, mem, n):
|
|
# SHLR2 Rn
|
|
op1 = zero_extend32(cpu.reg[n])
|
|
op1 = op1 >> 2
|
|
cpu.reg[n] = register(op1)
|
|
|
|
def shll8__destination_operand_only(cpu, mem, n):
|
|
# SHLL8 Rn
|
|
op1 = zero_extend32(cpu.reg[n])
|
|
op1 = op1 << 8
|
|
cpu.reg[n] = register(op1)
|
|
|
|
def shlr8__destination_operand_only(cpu, mem, n):
|
|
# SHLR8 Rn
|
|
op1 = zero_extend32(cpu.reg[n])
|
|
op1 = op1 >> 8
|
|
cpu.reg[n] = register(op1)
|
|
|
|
def shll16__destination_operand_only(cpu, mem, n):
|
|
# SHLL16 Rn
|
|
op1 = zero_extend32(cpu.reg[n])
|
|
op1 = op1 << 16
|
|
cpu.reg[n] = register(op1)
|
|
|
|
def shlr16__destination_operand_only(cpu, mem, n):
|
|
# SHLR16 Rn
|
|
op1 = zero_extend32(cpu.reg[n])
|
|
op1 = op1 >> 16
|
|
cpu.reg[n] = register(op1)
|
|
|
|
def add__source_and_destination_operands(cpu, mem, m, n):
|
|
# ADD Rm,Rn
|
|
op1 = sign_extend32(cpu.reg[m])
|
|
op2 = sign_extend32(cpu.reg[n])
|
|
op2 = op2 + op1
|
|
cpu.reg[n] = register(op2)
|
|
|
|
def addc__source_and_destination_operands(cpu, mem, m, n):
|
|
# ADDC Rm,Rn
|
|
t = zero_extend1(cpu.sr.t)
|
|
op1 = zero_extend32(sign_extend32(cpu.reg[m]))
|
|
op2 = zero_extend32(sign_extend32(cpu.reg[n]))
|
|
op2 = (op2 + op1) + t
|
|
t = (op2 >> 32) & 1
|
|
cpu.reg[n] = register(op2)
|
|
cpu.sr.t = bit(t)
|
|
|
|
def addv__source_and_destination_operands(cpu, mem, m, n):
|
|
# ADDV Rm,Rn
|
|
op1 = sign_extend32(cpu.reg[m])
|
|
op2 = sign_extend32(cpu.reg[n])
|
|
op2 = op2 + op1
|
|
t = int((op2 < (-(2**31))) or (op2 >= (2**31)))
|
|
cpu.reg[n] = register(op2)
|
|
cpu.sr.t = bit(t)
|
|
|
|
def and__source_and_destination_operands(cpu, mem, m, n):
|
|
# AND Rm,Rn
|
|
op1 = zero_extend32(cpu.reg[m])
|
|
op2 = zero_extend32(cpu.reg[n])
|
|
op2 = op2 & op1
|
|
cpu.reg[n] = register(op2)
|
|
|
|
def cmp_eq__source_and_destination_operands(cpu, mem, m, n):
|
|
# CMP/EQ Rm,Rn
|
|
op1 = sign_extend32(cpu.reg[m])
|
|
op2 = sign_extend32(cpu.reg[n])
|
|
t = int(op2 == op1)
|
|
cpu.sr.t = bit(t)
|
|
|
|
def cmp_hs__source_and_destination_operands(cpu, mem, m, n):
|
|
# CMP/HS Rm,Rn
|
|
op1 = zero_extend32(sign_extend32(cpu.reg[m]))
|
|
op2 = zero_extend32(sign_extend32(cpu.reg[n]))
|
|
t = int(op2 >= op1)
|
|
cpu.sr.t = bit(t)
|
|
|
|
def cmp_ge__source_and_destination_operands(cpu, mem, m, n):
|
|
# CMP/GE Rm,Rn
|
|
op1 = sign_extend32(cpu.reg[m])
|
|
op2 = sign_extend32(cpu.reg[n])
|
|
t = int(op2 >= op1)
|
|
cpu.sr.t = bit(t)
|
|
|
|
def cmp_hi__source_and_destination_operands(cpu, mem, m, n):
|
|
# CMP/HI Rm,Rn
|
|
op1 = zero_extend32(sign_extend32(cpu.reg[m]))
|
|
op2 = zero_extend32(sign_extend32(cpu.reg[n]))
|
|
t = int(op2 > op1)
|
|
cpu.sr.t = bit(t)
|
|
|
|
def cmp_gt__source_and_destination_operands(cpu, mem, m, n):
|
|
# CMP/GT Rm,Rn
|
|
op1 = sign_extend32(cpu.reg[m])
|
|
op2 = sign_extend32(cpu.reg[n])
|
|
t = int(op2 > op1)
|
|
cpu.sr.t = bit(t)
|
|
|
|
def cmp_str__source_and_destination_operands(cpu, mem, m, n):
|
|
# CMP/STR Rm,Rn
|
|
op1 = sign_extend32(cpu.reg[m])
|
|
op2 = sign_extend32(cpu.reg[n])
|
|
temp = op1 ^ op2
|
|
t = int(((temp >> 0 ) & 0xff) == 0)
|
|
t = int(((temp >> 8 ) & 0xff) == 0) | t
|
|
t = int(((temp >> 16) & 0xff) == 0) | t
|
|
t = int(((temp >> 24) & 0xff) == 0) | t
|
|
cpu.sr.t = bit(t)
|
|
|
|
def div1__source_and_destination_operands(cpu, mem, m, n):
|
|
# DIV1 Rm,Rn
|
|
q = zero_extend1(cpu.sr.q)
|
|
m = zero_extend1(cpu.sr.m)
|
|
t = zero_extend1(cpu.sr.t)
|
|
op1 = zero_extend32(sign_extend32(cpu.reg[m]))
|
|
op2 = zero_extend32(sign_extend32(cpu.reg[n]))
|
|
oldq = q
|
|
q = (op2 >> 31) & 1
|
|
op2 = zero_extend32(op2 << 1) | t
|
|
if oldq == m:
|
|
op2 = op2 - op1
|
|
else:
|
|
op2 = op2 + op1
|
|
q = (q ^ m) ^ (op2 >> 32) & 1
|
|
t = 1 - (q ^ m)
|
|
cpu.reg[n] = register(op2)
|
|
cpu.sr.q = bit(q)
|
|
cpu.sr.t = bit(t)
|
|
|
|
def div0s__source_and_destination_operands(cpu, mem, m, n):
|
|
# DIV0S Rm,Rn
|
|
op1 = sign_extend32(cpu.reg[m])
|
|
op2 = sign_extend32(cpu.reg[n])
|
|
q = (op2 >> 31) & 1
|
|
m = (op1 >> 31) & 1
|
|
t = m ^ q
|
|
cpu.sr.q = bit(q)
|
|
cpu.sr.m = bit(m)
|
|
cpu.sr.t = bit(t)
|
|
|
|
def dmuls_l__source_and_destination_operands(cpu, mem, m, n):
|
|
# DMULS.L Rm,Rn
|
|
op1 = sign_extend32(cpu.reg[m])
|
|
op2 = sign_extend32(cpu.reg[n])
|
|
mac = op2 * op1
|
|
macl = mac
|
|
mach = mac >> 32
|
|
cpu.macl = zero_extend32(macl)
|
|
cpu.mach = zero_extend32(mach)
|
|
|
|
def dmulu_l__source_and_destination_operands(cpu, mem, m, n):
|
|
# DMULU.L Rm,Rn
|
|
op1 = zero_extend32(sign_extend32(cpu.reg[m]))
|
|
op2 = zero_extend32(sign_extend32(cpu.reg[n]))
|
|
mac = op2 * op1
|
|
macl = mac
|
|
mach = mac >> 32
|
|
cpu.macl = zero_extend32(macl)
|
|
cpu.mach = zero_extend32(mach)
|
|
|
|
def exts_b__source_and_destination_operands(cpu, mem, m, n):
|
|
# EXTS.B Rm,Rn
|
|
op1 = sign_extend8(cpu.reg[m])
|
|
op2 = op1
|
|
cpu.reg[n] = register(op2)
|
|
|
|
def exts_w__source_and_destination_operands(cpu, mem, m, n):
|
|
# EXTS.W Rm,Rn
|
|
op1 = sign_extend16(cpu.reg[m])
|
|
op2 = op1
|
|
cpu.reg[n] = register(op2)
|
|
|
|
def extu_b__source_and_destination_operands(cpu, mem, m, n):
|
|
# EXTU.B Rm,Rn
|
|
op1 = zero_extend8(cpu.reg[m])
|
|
op2 = op1
|
|
cpu.reg[n] = register(op2)
|
|
|
|
def extu_w__source_and_destination_operands(cpu, mem, m, n):
|
|
# EXTU.W Rm,Rn
|
|
op1 = zero_extend16(cpu.reg[m])
|
|
op2 = op1
|
|
cpu.reg[n] = register(op2)
|
|
|
|
def mov__source_and_destination_operands(cpu, mem, m, n):
|
|
# MOV Rm,Rn
|
|
op1 = zero_extend32(cpu.reg[m])
|
|
op2 = op1
|
|
cpu.reg[n] = register(op2)
|
|
|
|
def mul_l__source_and_destination_operands(cpu, mem, m, n):
|
|
# MUL.L Rm,Rn
|
|
op1 = sign_extend32(cpu.reg[m])
|
|
op2 = sign_extend32(cpu.reg[n])
|
|
macl = op2 * op1
|
|
cpu.macl = zero_extend32(macl)
|
|
|
|
def muls_w__source_and_destination_operands(cpu, mem, m, n):
|
|
# MULS.W Rm,Rn
|
|
op1 = sign_extend16(sign_extend32(cpu.reg[m]))
|
|
op2 = sign_extend16(sign_extend32(cpu.reg[n]))
|
|
macl = op2 * op1
|
|
cpu.macl = zero_extend32(macl)
|
|
|
|
def mulu_w__source_and_destination_operands(cpu, mem, m, n):
|
|
# MULU.W Rm,Rn
|
|
op1 = zero_extend16(sign_extend32(cpu.reg[m]))
|
|
op2 = zero_extend16(sign_extend32(cpu.reg[n]))
|
|
macl = op2 * op1
|
|
cpu.macl = zero_extend32(macl)
|
|
|
|
def neg__source_and_destination_operands(cpu, mem, m, n):
|
|
# NEG Rm,Rn
|
|
op1 = sign_extend32(cpu.reg[m])
|
|
op2 = (-op1)
|
|
cpu.reg[n] = register(op2)
|
|
|
|
def negc__source_and_destination_operands(cpu, mem, m, n):
|
|
# NEGC Rm,Rn
|
|
t = zero_extend1(cpu.sr.t)
|
|
op1 = zero_extend32(cpu.reg[m])
|
|
op2 = (-op1) - t
|
|
t = (op2 >> 32) & 1
|
|
cpu.reg[n] = register(op2)
|
|
cpu.sr.t = bit(t)
|
|
|
|
def not__source_and_destination_operands(cpu, mem, m, n):
|
|
# NOT Rm,Rn
|
|
op1 = zero_extend32(cpu.reg[m])
|
|
op2 = (~op1)
|
|
cpu.reg[n] = register(op2)
|
|
|
|
def or__source_and_destination_operands(cpu, mem, m, n):
|
|
# OR Rm,Rn
|
|
op1 = sign_extend32(cpu.reg[m])
|
|
op2 = sign_extend32(cpu.reg[n])
|
|
op2 = op2 | op1
|
|
cpu.reg[n] = register(op2)
|
|
|
|
def sub__source_and_destination_operands(cpu, mem, m, n):
|
|
# SUB Rm,Rn
|
|
op1 = sign_extend32(cpu.reg[m])
|
|
op2 = sign_extend32(cpu.reg[n])
|
|
op2 = op2 - op1
|
|
cpu.reg[n] = register(op2)
|
|
|
|
def subc__source_and_destination_operands(cpu, mem, m, n):
|
|
# SUBC Rm,Rn
|
|
t = zero_extend1(cpu.sr.t)
|
|
op1 = sign_extend32(cpu.reg[m])
|
|
op2 = sign_extend32(cpu.reg[n])
|
|
op2 = op2 - op1 - t
|
|
t = (op2 >> 32) & 1
|
|
cpu.reg[n] = register(op2)
|
|
cpu.sr.t = bit(t)
|
|
|
|
def subv__source_and_destination_operands(cpu, mem, m, n):
|
|
# SUBV Rm,Rn
|
|
op1 = sign_extend32(cpu.reg[m])
|
|
op2 = sign_extend32(cpu.reg[n])
|
|
op2 = op2 - op1
|
|
t = int((op2 < (-(2**31))) or (op2 >= (2**31)))
|
|
cpu.reg[n] = register(op2)
|
|
cpu.sr.t = bit(t)
|
|
|
|
def swap_b__source_and_destination_operands(cpu, mem, m, n):
|
|
# SWAP.B Rm,Rn
|
|
op1 = zero_extend32(cpu.reg[m])
|
|
op2 = ((((op1 >> 16) & 0xffff) << 16)
|
|
| (((op1 >> 0 ) & 0xff ) << 8 )
|
|
| (((op1 >> 8 ) & 0xff ) << 0 ))
|
|
cpu.reg[n] = register(op2);
|
|
|
|
def swap_w__source_and_destination_operands(cpu, mem, m, n):
|
|
# SWAP.W Rm,Rn
|
|
op1 = zero_extend32(cpu.reg[m])
|
|
op2 = ((((op1 >> 0 ) & 0xffff) << 16)
|
|
| (((op1 >> 16) & 0xffff) << 0 ))
|
|
cpu.reg[n] = register(op2);
|
|
|
|
def tst__source_and_destination_operands(cpu, mem, m, n):
|
|
# TST Rm,Rn
|
|
op1 = sign_extend32(cpu.reg[m])
|
|
op2 = sign_extend32(cpu.reg[n])
|
|
t = int((op1 & op2) == 0)
|
|
cpu.sr.t = bit(t)
|
|
|
|
def xor__source_and_destination_operands(cpu, mem, m, n):
|
|
# XOR Rm,Rn
|
|
op1 = zero_extend32(cpu.reg[m])
|
|
op2 = zero_extend32(cpu.reg[n])
|
|
op2 = op2 ^ op1
|
|
cpu.reg[n] = register(op2)
|
|
|
|
def xtrct__source_and_destination_operands(cpu, mem, m, n):
|
|
# XTRCT Rm,Rn
|
|
op1 = zero_extend32(cpu.reg[m])
|
|
op2 = zero_extend32(cpu.reg[n])
|
|
op2 = ((op2 >> 16) & 0xffff) | (((op1 >> 0) & 0xffff) << 16)
|
|
cpu.reg[n] = register(op2)
|
|
|
|
def ldc__transfer_to_sr(cpu, mem, m):
|
|
# LDC Rm,SR
|
|
op1 = sign_extend32(cpu.reg[m])
|
|
sr = op1
|
|
cpu.sr.set_value(register(sr))
|
|
|
|
def ldc__transfer_to_gbr(cpu, mem, m):
|
|
# LDC Rm,GBR
|
|
op1 = sign_extend32(cpu.reg[m])
|
|
gbr = op1
|
|
cpu.gbr = register(gbr)
|
|
|
|
def ldc__transfer_to_vbr(cpu, mem, m):
|
|
# LDC Rm,VBR
|
|
op1 = sign_extend32(cpu.reg[m])
|
|
vbr = op1
|
|
cpu.vbr = register(vbr)
|
|
|
|
def lds__transfer_to_mach(cpu, mem, m):
|
|
# LDS Rm,MACH
|
|
op1 = sign_extend32(cpu.reg[m])
|
|
mach = op1
|
|
cpu.mach = register(mach)
|
|
|
|
def lds__transfer_to_macl(cpu, mem, m):
|
|
# LDS Rm,MACL
|
|
op1 = sign_extend32(cpu.reg[m])
|
|
macl = op1
|
|
cpu.macl = register(macl)
|
|
|
|
def lds__transfer_to_pr(cpu, mem, m):
|
|
# LDS Rm,PR
|
|
op1 = sign_extend32(cpu.reg[m])
|
|
newpr = op1
|
|
delayedpr = newpr
|
|
cpu.pr1 = register(newpr)
|
|
cpu.pr2 = register(delayedpr)
|
|
|
|
def stc__transfer_from_sr(cpu, mem, n):
|
|
# STC SR,Rn
|
|
sr = sign_extend32(cpu.sr.get_value())
|
|
op1 = sr
|
|
cpu.reg[n] = register(op1)
|
|
|
|
def stc__transfer_from_gbr(cpu, mem, n):
|
|
# STC GBR,Rn
|
|
gbr = sign_extend32(cpu.gbr)
|
|
op1 = gbr
|
|
cpu.reg[n] = register(op1)
|
|
|
|
def stc__transfer_from_vbr(cpu, mem, n):
|
|
# STC VBR,Rn
|
|
vbr = sign_extend32(cpu.vbr)
|
|
op1 = vbr
|
|
cpu.reg[n] = register(op1)
|
|
|
|
def sts__transfer_from_mach(cpu, mem, n):
|
|
# STS MACH,Rn
|
|
mach = sign_extend32(cpu.mach)
|
|
op1 = mach
|
|
cpu.reg[n] = register(op1)
|
|
|
|
def sts__transfer_from_macl(cpu, mem, n):
|
|
# STS MACL,Rn
|
|
macl = sign_extend32(cpu.macl)
|
|
op1 = macl
|
|
cpu.reg[n] = register(op1)
|
|
|
|
def sts__transfer_from_pr(cpu, mem, n):
|
|
# STS PR,Rn
|
|
pr = sign_extend32(cpu.pr1)
|
|
op1 = pr
|
|
cpu.reg[n] = register(op1)
|
|
|
|
def jmp__destination_operand_only(cpu, mem, n):
|
|
# JMP @Rn
|
|
op1 = sign_extend32(cpu.reg[n])
|
|
if cpu.is_delay_slot:
|
|
raise ILLSLOT()
|
|
target = op1
|
|
delayedpc = target & (~0x1)
|
|
cpu.pc2 = register(delayedpc)
|
|
|
|
def jsr__destination_operand_only(cpu, mem, n):
|
|
# JSR @Rn
|
|
pc = sign_extend32(cpu.pc)
|
|
op1 = sign_extend32(cpu.reg[n])
|
|
if cpu.is_delay_slot:
|
|
raise ILLSLOT()
|
|
delayedpr = pc + 4
|
|
target = op1
|
|
delayedpc = target & (~0x1)
|
|
cpu.pr2 = register(delayedpr)
|
|
cpu.pc2 = register(delayedpc)
|
|
|
|
def tas_b__destination_operand_only(cpu, mem, n):
|
|
# TAS.B @Rn
|
|
op1 = sign_extend32(cpu.reg[n])
|
|
address = zero_extend32(op1)
|
|
value = zero_extend8(mem.read8(address))
|
|
t = int(value == 0)
|
|
value = value | (1 << 7)
|
|
mem.write8(address, value)
|
|
cpu.sr.t = bit(t)
|
|
|
|
def mov_b__store_register_direct_data_transfer(cpu, mem, m, n):
|
|
# MOV.B Rm,@Rn
|
|
op1 = sign_extend32(cpu.reg[m])
|
|
op2 = sign_extend32(cpu.reg[n])
|
|
address = zero_extend32(op2)
|
|
mem.write8(address, op1)
|
|
|
|
def mov_w__store_register_direct_data_transfer(cpu, mem, m, n):
|
|
# MOV.W Rm,@Rn
|
|
op1 = sign_extend32(cpu.reg[m])
|
|
op2 = sign_extend32(cpu.reg[n])
|
|
address = zero_extend32(op2)
|
|
mem.write16(address, op1)
|
|
|
|
def mov_l__store_register_direct_data_transfer(cpu, mem, m, n):
|
|
# MOV.L Rm,@Rn
|
|
op1 = sign_extend32(cpu.reg[m])
|
|
op2 = sign_extend32(cpu.reg[n])
|
|
address = zero_extend32(op2)
|
|
mem.write32(address, op1)
|
|
|
|
def mov_b__load_register_direct_data_transfer(cpu, mem, m, n):
|
|
# MOV.B @Rm,Rn
|
|
op1 = sign_extend32(cpu.reg[m])
|
|
address = zero_extend32(op1)
|
|
op2 = sign_extend8(mem.read8(address))
|
|
cpu.reg[n] = register(op2)
|
|
|
|
def mov_w__load_register_direct_data_transfer(cpu, mem, m, n):
|
|
# MOV.W @Rm,Rn
|
|
op1 = sign_extend32(cpu.reg[m])
|
|
address = zero_extend32(op1)
|
|
op2 = sign_extend16(mem.read16(address))
|
|
cpu.reg[n] = register(op2)
|
|
|
|
def mov_l__load_register_direct_data_transfer(cpu, mem, m, n):
|
|
# MOV.L @Rm,Rn
|
|
op1 = sign_extend32(cpu.reg[m])
|
|
address = zero_extend32(op1)
|
|
op2 = sign_extend32(mem.read32(address))
|
|
cpu.reg[n] = register(op2)
|
|
|
|
def mac_l__multiply_and_accumulate_operation(cpu, mem, m, n):
|
|
# MAC.L @Rm+,@Rn+
|
|
macl = zero_extend32(cpu.macl)
|
|
mach = zero_extend32(cpu.mach)
|
|
s = zero_extend1(cpu.sr.s)
|
|
m_field = zero_extend4(m)
|
|
n_field = zero_extend4(n)
|
|
m_address = sign_extend32(cpu.reg[m])
|
|
n_address = sign_extend32(cpu.reg[n])
|
|
value2 = sign_extend32(mem.read32(zero_extend32(n_address)))
|
|
n_address = n_address + 4
|
|
if n_field == m_field:
|
|
m_address = m_address + 4
|
|
n_address = n_address + 4
|
|
value1 = sign_extend32(mem.read32(zero_extend32(m_address)))
|
|
m_address = m_address + 4
|
|
mul = value2 * value1
|
|
mac = sign_extend64((mach << 32) + macl)
|
|
# simulate 64-bit addition
|
|
result = (mac + mul) & 0xffff_ffff_ffff_ffff
|
|
if s == 1:
|
|
if (((result ^ mac) & (result ^ mul)) >> 63) & 1 == 1:
|
|
if (mac >> 63) & 1 == 0:
|
|
result = (2 ** 47) - 1
|
|
else:
|
|
result = -(2 ** 47)
|
|
else:
|
|
result = signed_saturate48(result)
|
|
macl = result
|
|
mach = result >> 32
|
|
cpu.reg[m] = register(m_address)
|
|
cpu.reg[n] = register(n_address)
|
|
cpu.macl = zero_extend32(macl)
|
|
cpu.mach = zero_extend32(mach)
|
|
|
|
def mac_w__multiply_and_accumulate_operation(cpu, mem, m, n):
|
|
# MAC.W @Rm+,@Rn+
|
|
macl = zero_extend32(cpu.macl)
|
|
mach = zero_extend32(cpu.mach)
|
|
s = zero_extend1(cpu.sr.s)
|
|
m_field = zero_extend4(m)
|
|
n_field = zero_extend4(n)
|
|
m_address = sign_extend32(cpu.reg[m])
|
|
n_address = sign_extend32(cpu.reg[n])
|
|
value2 = sign_extend16(mem.read16(zero_extend32(n_address)))
|
|
n_address = n_address + 2
|
|
if n_field == m_field:
|
|
m_address = m_address + 2
|
|
n_address = n_address + 2
|
|
value1 = sign_extend16(mem.read16(zero_extend32(m_address)))
|
|
m_address = m_address + 2
|
|
mul = value2 * value1
|
|
if s == 1:
|
|
macl = sign_extend32(macl) + mul
|
|
temp = signed_saturate32(macl)
|
|
if macl == temp:
|
|
result = (mach << 32) | zero_extend32(macl)
|
|
else:
|
|
result = (1 << 32) | zero_extend32(temp)
|
|
else:
|
|
result = sign_extend64((mach << 32) + macl) + mul
|
|
macl = result
|
|
mach = result >> 32
|
|
cpu.reg[m] = register(m_address)
|
|
cpu.reg[n] = register(n_address)
|
|
cpu.macl = zero_extend32(macl)
|
|
cpu.mach = zero_extend32(mach)
|
|
|
|
def mov_b__load_direct_data_transfer_from_register(cpu, mem, m, n):
|
|
# MOV.B @Rm+,Rn
|
|
m_field = zero_extend4(m)
|
|
n_field = zero_extend4(n)
|
|
op1 = sign_extend32(cpu.reg[m])
|
|
address = zero_extend32(op1)
|
|
op2 = sign_extend8(mem.read8(address))
|
|
if m_field == n_field:
|
|
op1 = op2
|
|
else:
|
|
op1 = op1 + 1
|
|
cpu.reg[m] = register(op1)
|
|
cpu.reg[n] = register(op2)
|
|
|
|
def mov_w__load_direct_data_transfer_from_register(cpu, mem, m, n):
|
|
# MOV.W @Rm+,Rn
|
|
m_field = zero_extend4(m)
|
|
n_field = zero_extend4(n)
|
|
op1 = sign_extend32(cpu.reg[m])
|
|
address = zero_extend32(op1)
|
|
op2 = sign_extend16(mem.read16(address))
|
|
if m_field == n_field:
|
|
op1 = op2
|
|
else:
|
|
op1 = op1 + 2
|
|
cpu.reg[m] = register(op1)
|
|
cpu.reg[n] = register(op2)
|
|
|
|
def mov_l__load_direct_data_transfer_from_register(cpu, mem, m, n):
|
|
# MOV.L @Rm+,Rn
|
|
m_field = zero_extend4(m)
|
|
n_field = zero_extend4(n)
|
|
op1 = sign_extend32(cpu.reg[m])
|
|
address = zero_extend32(op1)
|
|
op2 = sign_extend32(mem.read32(address))
|
|
if m_field == n_field:
|
|
op1 = op2
|
|
else:
|
|
op1 = op1 + 4
|
|
cpu.reg[m] = register(op1)
|
|
cpu.reg[n] = register(op2)
|
|
|
|
def ldc_l__load_to_sr(cpu, mem, m):
|
|
# LDC.L @Rm+,SR
|
|
op1 = sign_extend32(cpu.reg[m])
|
|
address = zero_extend32(op1)
|
|
sr = sign_extend32(mem.read32(address))
|
|
op1 = op1 + 4
|
|
cpu.reg[m] = register(op1)
|
|
cpu.sr.set_value(register(sr))
|
|
|
|
def ldc_l__load_to_gbr(cpu, mem, m):
|
|
# LDC.L @Rm+,GBR
|
|
op1 = sign_extend32(cpu.reg[m])
|
|
address = zero_extend32(op1)
|
|
gbr = sign_extend32(mem.read32(address))
|
|
op1 = op1 + 4
|
|
cpu.reg[m] = register(op1)
|
|
cpu.gbr = register(gbr)
|
|
|
|
def ldc_l__load_to_vbr(cpu, mem, m):
|
|
# LDC.L @Rm+,VBR
|
|
op1 = sign_extend32(cpu.reg[m])
|
|
address = zero_extend32(op1)
|
|
vbr = sign_extend32(mem.read32(address))
|
|
op1 = op1 + 4
|
|
cpu.reg[m] = register(op1)
|
|
cpu.vbr = register(vbr)
|
|
|
|
def lds_l__load_to_mach(cpu, mem, m):
|
|
# LDS.L @Rm+,MACH
|
|
op1 = sign_extend32(cpu.reg[m])
|
|
address = zero_extend32(op1)
|
|
mach = sign_extend32(mem.read32(address))
|
|
op1 = op1 + 4
|
|
cpu.reg[m] = register(op1)
|
|
cpu.mach = zero_extend32(mach)
|
|
|
|
def lds_l__load_to_macl(cpu, mem, m):
|
|
# LDS.L @Rm+,MACL
|
|
op1 = sign_extend32(cpu.reg[m])
|
|
address = zero_extend32(op1)
|
|
macl = sign_extend32(mem.read32(address))
|
|
op1 = op1 + 4
|
|
cpu.reg[m] = register(op1)
|
|
cpu.macl = zero_extend32(macl)
|
|
|
|
def lds_l__load_to_pr(cpu, mem, m):
|
|
# LDS.L @Rm+,PR
|
|
op1 = sign_extend32(cpu.reg[m])
|
|
address = zero_extend32(op1)
|
|
newpr = sign_extend32(mem.read32(address))
|
|
delayedpr = newpr
|
|
op1 = op1 + 4
|
|
cpu.reg[m] = register(op1)
|
|
cpu.pr1 = register(newpr)
|
|
cpu.pr2 = register(delayedpr)
|
|
|
|
def mov_b__store_direct_data_transfer_from_register(cpu, mem, m, n):
|
|
# MOV.B Rm,@-Rn
|
|
op1 = sign_extend32(cpu.reg[m])
|
|
op2 = sign_extend32(cpu.reg[n])
|
|
address = zero_extend32(op2 - 1)
|
|
mem.write8(address, op1)
|
|
op2 = address
|
|
cpu.reg[n] = register(op2)
|
|
|
|
def mov_w__store_direct_data_transfer_from_register(cpu, mem, m, n):
|
|
# MOV.W Rm,@-Rn
|
|
op1 = sign_extend32(cpu.reg[m])
|
|
op2 = sign_extend32(cpu.reg[n])
|
|
address = zero_extend32(op2 - 2)
|
|
mem.write16(address, op1)
|
|
op2 = address
|
|
cpu.reg[n] = register(op2)
|
|
|
|
def mov_l__store_direct_data_transfer_from_register(cpu, mem, m, n):
|
|
# MOV.L Rm,@-Rn
|
|
op1 = sign_extend32(cpu.reg[m])
|
|
op2 = sign_extend32(cpu.reg[n])
|
|
address = zero_extend32(op2 - 4)
|
|
mem.write32(address, op1)
|
|
op2 = address
|
|
cpu.reg[n] = register(op2)
|
|
|
|
def stc_l__store_from_sr(cpu, mem, n):
|
|
# STC.L SR,@-Rn
|
|
sr = sign_extend32(cpu.sr.get_value())
|
|
op1 = sign_extend32(cpu.reg[n])
|
|
address = zero_extend32(op1 - 4)
|
|
mem.write32(address, sr)
|
|
op1 = address
|
|
cpu.reg[n] = register(op1)
|
|
|
|
def stc_l__store_from_gbr(cpu, mem, n):
|
|
# STC.L GBR,@-Rn
|
|
gbr = sign_extend32(cpu.gbr)
|
|
op1 = sign_extend32(cpu.reg[n])
|
|
address = zero_extend32(op1 - 4)
|
|
mem.write32(address, gbr)
|
|
op1 = address
|
|
cpu.reg[n] = register(op1)
|
|
|
|
def stc_l__store_from_vbr(cpu, mem, n):
|
|
# STC.L VBR,@-Rn
|
|
vbr = sign_extend32(cpu.vbr)
|
|
op1 = sign_extend32(cpu.reg[n])
|
|
address = zero_extend32(op1 - 4)
|
|
mem.write32(address, vbr)
|
|
op1 = address
|
|
cpu.reg[n] = register(op1)
|
|
|
|
def sts_l__store_from_mach(cpu, mem, n):
|
|
# STS.L MACH,@-Rn
|
|
mach = sign_extend32(cpu.mach)
|
|
op1 = sign_extend32(cpu.reg[n])
|
|
address = zero_extend32(op1 - 4)
|
|
mem.write32(address, mach)
|
|
op1 = address
|
|
cpu.reg[n] = register(op1)
|
|
|
|
def sts_l__store_from_macl(cpu, mem, n):
|
|
# STS.L MACL,@-Rn
|
|
macl = sign_extend32(cpu.macl)
|
|
op1 = sign_extend32(cpu.reg[n])
|
|
address = zero_extend32(op1 - 4)
|
|
mem.write32(address, macl)
|
|
op1 = address
|
|
cpu.reg[n] = register(op1)
|
|
|
|
def sts_l__store_from_pr(cpu, mem, n):
|
|
# STS.L PR,@-Rn
|
|
pr = sign_extend32(cpu.pr1)
|
|
op1 = sign_extend32(cpu.reg[n])
|
|
address = zero_extend32(op1 - 4)
|
|
mem.write32(address, pr)
|
|
op1 = address
|
|
cpu.reg[n] = register(op1)
|
|
|
|
def mov_b__store_register_indirect_with_displacement(cpu, mem, d, n):
|
|
# MOV.B R0,@(disp,Rn)
|
|
r0 = sign_extend32(cpu.reg[0])
|
|
disp = zero_extend4(d)
|
|
op2 = sign_extend32(cpu.reg[n])
|
|
address = zero_extend32(disp + op2)
|
|
mem.write8(address, r0)
|
|
|
|
def mov_w__store_register_indirect_with_displacement(cpu, mem, d, n):
|
|
# MOV.W R0,@(disp,Rn)
|
|
r0 = sign_extend32(cpu.reg[0])
|
|
disp = zero_extend4(d) << 1
|
|
op2 = sign_extend32(cpu.reg[n])
|
|
address = zero_extend32(disp + op2)
|
|
mem.write16(address, r0)
|
|
|
|
def mov_l__store_register_indirect_with_displacement(cpu, mem, m, d, n):
|
|
# MOV.L Rm,@(disp,Rn)
|
|
op1 = sign_extend32(cpu.reg[m])
|
|
disp = zero_extend4(d) << 2
|
|
op3 = sign_extend32(cpu.reg[n])
|
|
address = zero_extend32(disp + op3)
|
|
mem.write32(address, op1)
|
|
|
|
def mov_b__load_register_indirect_with_displacement(cpu, mem, d, m):
|
|
# MOV.B @(disp,Rm),R0
|
|
disp = zero_extend4(d)
|
|
op2 = sign_extend32(cpu.reg[m])
|
|
address = zero_extend32(disp + op2)
|
|
r0 = sign_extend8(mem.read8(address))
|
|
cpu.reg[0] = register(r0)
|
|
|
|
def mov_w__load_register_indirect_with_displacement(cpu, mem, d, m):
|
|
# MOV.W @(disp,Rm),R0
|
|
disp = zero_extend4(d) << 1
|
|
op2 = sign_extend32(cpu.reg[m])
|
|
address = zero_extend32(disp + op2)
|
|
r0 = sign_extend16(mem.read16(address))
|
|
cpu.reg[0] = register(r0)
|
|
|
|
def mov_l__load_register_indirect_with_displacement(cpu, mem, d, m, n):
|
|
# MOV.L @(disp,Rm),Rn
|
|
disp = zero_extend4(d) << 2
|
|
op2 = sign_extend32(cpu.reg[m])
|
|
address = zero_extend32(disp + op2)
|
|
op3 = sign_extend16(mem.read16(address))
|
|
cpu.reg[n] = register(op3)
|
|
|
|
def mov_b__store_indexed_register_indirect(cpu, mem, m, n):
|
|
# MOV.B Rm,@(R0,Rn)
|
|
r0 = sign_extend32(cpu.reg[0])
|
|
op1 = sign_extend32(cpu.reg[m])
|
|
op2 = sign_extend32(cpu.reg[n])
|
|
address = zero_extend32(r0 + op2)
|
|
mem.write8(address, op1)
|
|
|
|
def mov_w__store_indexed_register_indirect(cpu, mem, m, n):
|
|
# MOV.W Rm,@(R0,Rn)
|
|
r0 = sign_extend32(cpu.reg[0])
|
|
op1 = sign_extend32(cpu.reg[m])
|
|
op2 = sign_extend32(cpu.reg[n])
|
|
address = zero_extend32(r0 + op2)
|
|
mem.write16(address, op1)
|
|
|
|
def mov_l__store_indexed_register_indirect(cpu, mem, m, n):
|
|
# MOV.L Rm,@(R0,Rn)
|
|
r0 = sign_extend32(cpu.reg[0])
|
|
op1 = sign_extend32(cpu.reg[m])
|
|
op2 = sign_extend32(cpu.reg[n])
|
|
address = zero_extend32(r0 + op2)
|
|
mem.write32(address, op1)
|
|
|
|
def mov_b__load_indexed_register_indirect(cpu, mem, m, n):
|
|
# MOV.B @(R0,Rm),Rn
|
|
r0 = sign_extend32(cpu.reg[0])
|
|
op1 = sign_extend32(cpu.reg[m])
|
|
address = zero_extend32(r0 + op1)
|
|
op2 = sign_extend8(mem.read8(address))
|
|
cpu.reg[n] = register(op2)
|
|
|
|
def mov_w__load_indexed_register_indirect(cpu, mem, m, n):
|
|
# MOV.W @(R0,Rm),Rn
|
|
r0 = sign_extend32(cpu.reg[0])
|
|
op1 = sign_extend32(cpu.reg[m])
|
|
address = zero_extend32(r0 + op1)
|
|
op2 = sign_extend16(mem.read16(address))
|
|
cpu.reg[n] = register(op2)
|
|
|
|
def mov_l__load_indexed_register_indirect(cpu, mem, m, n):
|
|
# MOV.L @(R0,Rm),Rn
|
|
r0 = sign_extend32(cpu.reg[0])
|
|
op1 = sign_extend32(cpu.reg[m])
|
|
address = zero_extend32(r0 + op1)
|
|
op2 = sign_extend32(mem.read32(address))
|
|
cpu.reg[n] = register(op2)
|
|
|
|
def mov_b__store_gbr_indirect_with_displacement(cpu, mem, d):
|
|
# MOV.B R0,@(disp,GBR)
|
|
gbr = sign_extend32(cpu.gbr)
|
|
r0 = sign_extend32(cpu.reg[0])
|
|
disp = zero_extend8(d)
|
|
address = zero_extend32(disp + gbr)
|
|
mem.write8(address, r0)
|
|
|
|
def mov_w__store_gbr_indirect_with_displacement(cpu, mem, d):
|
|
# MOV.W R0,@(disp,GBR)
|
|
gbr = sign_extend32(cpu.gbr)
|
|
r0 = sign_extend32(cpu.reg[0])
|
|
disp = zero_extend8(d) << 1
|
|
address = zero_extend32(disp + gbr)
|
|
mem.write16(address, r0)
|
|
|
|
def mov_l__store_gbr_indirect_with_displacement(cpu, mem, d):
|
|
# MOV.L R0,@(disp,GBR)
|
|
gbr = sign_extend32(cpu.gbr)
|
|
r0 = sign_extend32(cpu.reg[0])
|
|
disp = zero_extend8(d) << 2
|
|
address = zero_extend32(disp + gbr)
|
|
mem.write32(address, r0)
|
|
|
|
def mov_b__load_gbr_indirect_with_displacement(cpu, mem, d):
|
|
# MOV.B @(disp,GBR),R0
|
|
gbr = sign_extend32(cpu.gbr)
|
|
disp = zero_extend8(d)
|
|
address = zero_extend32(disp + gbr)
|
|
r0 = sign_extend8(mem.read8(address))
|
|
cpu.reg[0] = register(r0)
|
|
|
|
def mov_w__load_gbr_indirect_with_displacement(cpu, mem, d):
|
|
# MOV.W @(disp,GBR),R0
|
|
gbr = sign_extend32(cpu.gbr)
|
|
disp = zero_extend8(d) << 1
|
|
address = zero_extend32(disp + gbr)
|
|
r0 = sign_extend16(mem.read16(address))
|
|
cpu.reg[0] = register(r0)
|
|
|
|
def mov_l__load_gbr_indirect_with_displacement(cpu, mem, d):
|
|
# MOV.L @(disp,GBR),R0
|
|
gbr = sign_extend32(cpu.gbr)
|
|
disp = zero_extend8(d) << 2
|
|
address = zero_extend32(disp + gbr)
|
|
r0 = sign_extend32(mem.read32(address))
|
|
cpu.reg[0] = register(r0)
|
|
|
|
def and_b__store_indexed_gbr_indirect(cpu, mem, i):
|
|
# AND.B #imm,@(R0,GBR)
|
|
r0 = sign_extend32(cpu.reg[0])
|
|
gbr = sign_extend32(cpu.gbr)
|
|
imm = zero_extend8(i)
|
|
address = zero_extend32(r0 + gbr)
|
|
value = zero_extend8(mem.read8(address))
|
|
value = value & imm
|
|
mem.write8(address, value)
|
|
|
|
def or_b__store_indexed_gbr_indirect(cpu, mem, i):
|
|
# OR.B #imm,@(R0,GBR)
|
|
r0 = sign_extend32(cpu.reg[0])
|
|
gbr = sign_extend32(cpu.gbr)
|
|
imm = zero_extend8(i)
|
|
address = zero_extend32(r0 + gbr)
|
|
value = zero_extend8(mem.read8(address))
|
|
value = value | imm
|
|
mem.write8(address, value)
|
|
|
|
def tst_b__store_indexed_gbr_indirect(cpu, mem, i):
|
|
# TST.B #imm,@(R0,GBR)
|
|
r0 = sign_extend32(cpu.reg[0])
|
|
gbr = sign_extend32(cpu.gbr)
|
|
imm = zero_extend8(i)
|
|
address = zero_extend32(r0 + gbr)
|
|
value = zero_extend8(mem.read8(address))
|
|
t = int((value & imm) == 0)
|
|
cpu.sr.t = bit(t)
|
|
|
|
def xor_b__store_indexed_gbr_indirect(cpu, mem, i):
|
|
# XOR.B #imm,@(R0,GBR)
|
|
r0 = sign_extend32(cpu.reg[0])
|
|
gbr = sign_extend32(cpu.gbr)
|
|
imm = zero_extend8(i)
|
|
address = zero_extend32(r0 + gbr)
|
|
value = zero_extend8(mem.read8(address))
|
|
value = value ^ imm
|
|
mem.write8(address, value)
|
|
|
|
def mov_w__pc_relative_with_displacement(cpu, mem, d, n):
|
|
# MOV.W @(disp,PC),Rn
|
|
pc = sign_extend32(cpu.pc)
|
|
disp = zero_extend8(d) << 1
|
|
if cpu.is_delay_slot:
|
|
raise ILLSLOT()
|
|
address = zero_extend32(disp + (pc + 4))
|
|
op2 = sign_extend16(mem.read16(address))
|
|
cpu.reg[n] = register(op2)
|
|
|
|
def mov_l__pc_relative_with_displacement(cpu, mem, d, n):
|
|
# MOV.L @(disp,PC),Rn
|
|
pc = sign_extend32(cpu.pc)
|
|
disp = zero_extend8(d) << 2
|
|
if cpu.is_delay_slot:
|
|
raise ILLSLOT()
|
|
address = zero_extend32(disp + ((pc + 4) & (~0x3)))
|
|
op2 = sign_extend32(mem.read32(address))
|
|
cpu.reg[n] = register(op2)
|
|
|
|
def mova__pc_relative_with_displacement(cpu, mem, d):
|
|
# MOVA @(disp,PC),R0
|
|
pc = sign_extend32(cpu.pc)
|
|
disp = zero_extend8(d) << 2
|
|
if cpu.is_delay_slot:
|
|
raise ILLSLOT()
|
|
r0 = disp + ((pc + 4) & (~0x3))
|
|
cpu.reg[0] = register(r0)
|
|
|
|
def braf__destination_operand_only(cpu, mem, n):
|
|
# BRAF Rn
|
|
pc = sign_extend32(cpu.pc)
|
|
op1 = sign_extend32(cpu.reg[n])
|
|
if cpu.is_delay_slot:
|
|
raise ILLSLOT()
|
|
target = zero_extend32(pc + 4 + op1)
|
|
delayedpc = target & (~0x1)
|
|
cpu.pc2 = register(delayedpc)
|
|
|
|
def bsrf__destination_operand_only(cpu, mem, n):
|
|
# BSRF Rn
|
|
pc = sign_extend32(cpu.pc)
|
|
op1 = sign_extend32(cpu.reg[n])
|
|
if cpu.is_delay_slot:
|
|
raise ILLSLOT()
|
|
delayedpr = pc + 4
|
|
target = zero_extend32(pc + 4 + op1)
|
|
delayedpc = target & (~0x1)
|
|
cpu.pr2 = register(delayedpr)
|
|
cpu.pc2 = register(delayedpc)
|
|
|
|
def bf__pc_relative(cpu, mem, d):
|
|
# BF label
|
|
t = zero_extend1(cpu.sr.t)
|
|
pc = sign_extend32(cpu.pc)
|
|
newpc = sign_extend32(cpu.pc1)
|
|
delayedpc = sign_extend32(cpu.pc2)
|
|
label = sign_extend8(d) << 1
|
|
if cpu.is_delay_slot:
|
|
raise ILLSLOT()
|
|
if t == 0:
|
|
temp = zero_extend32(pc + 4 + label)
|
|
newpc = temp
|
|
delayedpc = temp + 2
|
|
cpu.pc1 = register(newpc)
|
|
cpu.pc2 = register(delayedpc)
|
|
|
|
def bf_s__pc_relative(cpu, mem, d):
|
|
# BF/S label
|
|
t = zero_extend1(cpu.sr.t)
|
|
pc = sign_extend32(cpu.pc)
|
|
delayedpc = sign_extend32(cpu.pc2)
|
|
label = sign_extend8(d) << 1
|
|
if cpu.is_delay_slot:
|
|
raise ILLSLOT()
|
|
if t == 0:
|
|
temp = zero_extend32(pc + 4 + label)
|
|
delayedpc = temp
|
|
cpu.pc2 = register(delayedpc)
|
|
|
|
def bt__pc_relative(cpu, mem, d):
|
|
# BT label
|
|
t = zero_extend1(cpu.sr.t)
|
|
pc = sign_extend32(cpu.pc)
|
|
newpc = sign_extend32(cpu.pc1)
|
|
delayedpc = sign_extend32(cpu.pc2)
|
|
label = sign_extend8(d) << 1
|
|
if cpu.is_delay_slot:
|
|
raise ILLSLOT()
|
|
if t == 1:
|
|
temp = zero_extend32(pc + 4 + label)
|
|
newpc = temp
|
|
delayedpc = temp + 2
|
|
cpu.pc1 = register(newpc)
|
|
cpu.pc2 = register(delayedpc)
|
|
|
|
def bt_s__pc_relative(cpu, mem, d):
|
|
# BT/S label
|
|
t = zero_extend1(cpu.sr.t)
|
|
pc = sign_extend32(cpu.pc)
|
|
delayedpc = sign_extend32(cpu.pc2)
|
|
label = sign_extend8(d) << 1
|
|
if cpu.is_delay_slot:
|
|
raise ILLSLOT()
|
|
if t == 1:
|
|
temp = zero_extend32(pc + 4 + label)
|
|
delayedpc = temp
|
|
cpu.pc2 = register(delayedpc)
|
|
|
|
def bra__pc_relative(cpu, mem, d):
|
|
# BRA label
|
|
pc = sign_extend32(cpu.pc)
|
|
label = sign_extend12(d) << 1
|
|
if cpu.is_delay_slot:
|
|
raise ILLSLOT()
|
|
temp = zero_extend32(pc + 4 + label)
|
|
delayedpc = temp
|
|
cpu.pc2 = register(delayedpc)
|
|
|
|
def bsr__pc_relative(cpu, mem, d):
|
|
# BSR label
|
|
pc = sign_extend32(cpu.pc)
|
|
label = sign_extend12(d) << 1
|
|
if cpu.is_delay_slot:
|
|
raise ILLSLOT()
|
|
delayedpr = pc + 4
|
|
temp = zero_extend32(pc + 4 + label)
|
|
delayedpc = temp
|
|
cpu.pr2 = register(delayedpr)
|
|
cpu.pc2 = register(delayedpc)
|
|
|
|
def add__immediate(cpu, mem, i, n):
|
|
# ADD #imm,Rn
|
|
imm = sign_extend8(i)
|
|
op2 = sign_extend32(cpu.reg[n])
|
|
op2 = op2 + imm
|
|
cpu.reg[n] = register(op2)
|
|
|
|
def and__immediate(cpu, mem, i):
|
|
# AND #imm,R0
|
|
r0 = sign_extend32(cpu.reg[0])
|
|
imm = sign_extend8(i)
|
|
r0 = r0 & imm
|
|
cpu.reg[0] = register(r0)
|
|
|
|
def cmp_eq__immediate(cpu, mem, i):
|
|
# CMP/EQ #imm,R0
|
|
r0 = sign_extend32(cpu.reg[0])
|
|
imm = sign_extend8(i)
|
|
t = int(r0 == imm)
|
|
cpu.sr.t = bit(t)
|
|
|
|
def mov__immediate(cpu, mem, i, n):
|
|
# MOV #imm,Rn
|
|
imm = sign_extend8(i)
|
|
op2 = imm
|
|
cpu.reg[n] = register(op2)
|
|
|
|
def or__immediate(cpu, mem, i):
|
|
# OR #imm,R0
|
|
r0 = sign_extend32(cpu.reg[0])
|
|
imm = sign_extend8(i)
|
|
r0 = r0 | imm
|
|
cpu.reg[0] = register(r0)
|
|
|
|
def tst__immediate(cpu, mem, i):
|
|
# TST #imm,R0
|
|
r0 = sign_extend32(cpu.reg[0])
|
|
imm = sign_extend8(i)
|
|
t = int((r0 & imm) == 0)
|
|
cpu.sr.t = bit(t)
|
|
|
|
def xor__immediate(cpu, mem, i):
|
|
# XOR #imm,R0
|
|
r0 = sign_extend32(cpu.reg[0])
|
|
imm = sign_extend8(i)
|
|
r0 = r0 ^ imm
|
|
cpu.reg[0] = register(r0)
|
|
|
|
def trapa__immediate(cpu, mem, i):
|
|
# TRAPA #imm
|
|
imm = zero_extend8(i)
|
|
if cpu.is_delay_slot:
|
|
raise ILLSLOT()
|
|
raise TRAP(imm)
|
|
|
|
lookup = {
|
|
('CLRT' , '' ): clrt__no_operand,
|
|
('CLRMAC' , '' ): clrmac__no_operand,
|
|
('DIV0U' , '' ): div0u__no_operand,
|
|
('NOP' , '' ): nop__no_operand,
|
|
('RTE' , '' ): rte__no_operand,
|
|
('RTS' , '' ): rts__no_operand,
|
|
('SETT' , '' ): sett__no_operand,
|
|
('SLEEP' , '' ): sleep__no_operand,
|
|
('CMP/PL' , 'Rn' ): cmp_pl__destination_operand_only,
|
|
('CMP/PZ' , 'Rn' ): cmp_pz__destination_operand_only,
|
|
('DT' , 'Rn' ): dt__destination_operand_only,
|
|
('MOVT' , 'Rn' ): movt__destination_operand_only,
|
|
('ROTL' , 'Rn' ): rotl__destination_operand_only,
|
|
('ROTR' , 'Rn' ): rotr__destination_operand_only,
|
|
('ROTCL' , 'Rn' ): rotcl__destination_operand_only,
|
|
('ROTCR' , 'Rn' ): rotcr__destination_operand_only,
|
|
('SHAL' , 'Rn' ): shal__destination_operand_only,
|
|
('SHAR' , 'Rn' ): shar__destination_operand_only,
|
|
('SHLL' , 'Rn' ): shll__destination_operand_only,
|
|
('SHLR' , 'Rn' ): shlr__destination_operand_only,
|
|
('SHLL2' , 'Rn' ): shll2__destination_operand_only,
|
|
('SHLR2' , 'Rn' ): shlr2__destination_operand_only,
|
|
('SHLL8' , 'Rn' ): shll8__destination_operand_only,
|
|
('SHLR8' , 'Rn' ): shlr8__destination_operand_only,
|
|
('SHLL16' , 'Rn' ): shll16__destination_operand_only,
|
|
('SHLR16' , 'Rn' ): shlr16__destination_operand_only,
|
|
('ADD' , 'Rm,Rn' ): add__source_and_destination_operands,
|
|
('ADDC' , 'Rm,Rn' ): addc__source_and_destination_operands,
|
|
('ADDV' , 'Rm,Rn' ): addv__source_and_destination_operands,
|
|
('AND' , 'Rm,Rn' ): and__source_and_destination_operands,
|
|
('CMP/EQ' , 'Rm,Rn' ): cmp_eq__source_and_destination_operands,
|
|
('CMP/HS' , 'Rm,Rn' ): cmp_hs__source_and_destination_operands,
|
|
('CMP/GE' , 'Rm,Rn' ): cmp_ge__source_and_destination_operands,
|
|
('CMP/HI' , 'Rm,Rn' ): cmp_hi__source_and_destination_operands,
|
|
('CMP/GT' , 'Rm,Rn' ): cmp_gt__source_and_destination_operands,
|
|
('CMP/STR', 'Rm,Rn' ): cmp_str__source_and_destination_operands,
|
|
('DIV1' , 'Rm,Rn' ): div1__source_and_destination_operands,
|
|
('DIV0S' , 'Rm,Rn' ): div0s__source_and_destination_operands,
|
|
('DMULS.L', 'Rm,Rn' ): dmuls_l__source_and_destination_operands,
|
|
('DMULU.L', 'Rm,Rn' ): dmulu_l__source_and_destination_operands,
|
|
('EXTS.B' , 'Rm,Rn' ): exts_b__source_and_destination_operands,
|
|
('EXTS.W' , 'Rm,Rn' ): exts_w__source_and_destination_operands,
|
|
('EXTU.B' , 'Rm,Rn' ): extu_b__source_and_destination_operands,
|
|
('EXTU.W' , 'Rm,Rn' ): extu_w__source_and_destination_operands,
|
|
('MOV' , 'Rm,Rn' ): mov__source_and_destination_operands,
|
|
('MUL.L' , 'Rm,Rn' ): mul_l__source_and_destination_operands,
|
|
('MULS.W' , 'Rm,Rn' ): muls_w__source_and_destination_operands,
|
|
('MULU.W' , 'Rm,Rn' ): mulu_w__source_and_destination_operands,
|
|
('NEG' , 'Rm,Rn' ): neg__source_and_destination_operands,
|
|
('NEGC' , 'Rm,Rn' ): negc__source_and_destination_operands,
|
|
('NOT' , 'Rm,Rn' ): not__source_and_destination_operands,
|
|
('OR' , 'Rm,Rn' ): or__source_and_destination_operands,
|
|
('SUB' , 'Rm,Rn' ): sub__source_and_destination_operands,
|
|
('SUBC' , 'Rm,Rn' ): subc__source_and_destination_operands,
|
|
('SUBV' , 'Rm,Rn' ): subv__source_and_destination_operands,
|
|
('SWAP.B' , 'Rm,Rn' ): swap_b__source_and_destination_operands,
|
|
('SWAP.W' , 'Rm,Rn' ): swap_w__source_and_destination_operands,
|
|
('TST' , 'Rm,Rn' ): tst__source_and_destination_operands,
|
|
('XOR' , 'Rm,Rn' ): xor__source_and_destination_operands,
|
|
('XTRCT' , 'Rm,Rn' ): xtrct__source_and_destination_operands,
|
|
('LDC' , 'Rm,SR' ): ldc__transfer_to_sr,
|
|
('LDC' , 'Rm,GBR' ): ldc__transfer_to_gbr,
|
|
('LDC' , 'Rm,VBR' ): ldc__transfer_to_vbr,
|
|
('LDS' , 'Rm,MACH' ): lds__transfer_to_mach,
|
|
('LDS' , 'Rm,MACL' ): lds__transfer_to_macl,
|
|
('LDS' , 'Rm,PR' ): lds__transfer_to_pr,
|
|
('STC' , 'SR,Rn' ): stc__transfer_from_sr,
|
|
('STC' , 'GBR,Rn' ): stc__transfer_from_gbr,
|
|
('STC' , 'VBR,Rn' ): stc__transfer_from_vbr,
|
|
('STS' , 'MACH,Rn' ): sts__transfer_from_mach,
|
|
('STS' , 'MACL,Rn' ): sts__transfer_from_macl,
|
|
('STS' , 'PR,Rn' ): sts__transfer_from_pr,
|
|
('JMP' , '@Rn' ): jmp__destination_operand_only,
|
|
('JSR' , '@Rn' ): jsr__destination_operand_only,
|
|
('TAS.B' , '@Rn' ): tas_b__destination_operand_only,
|
|
('MOV.B' , 'Rm,@Rn' ): mov_b__store_register_direct_data_transfer,
|
|
('MOV.W' , 'Rm,@Rn' ): mov_w__store_register_direct_data_transfer,
|
|
('MOV.L' , 'Rm,@Rn' ): mov_l__store_register_direct_data_transfer,
|
|
('MOV.B' , '@Rm,Rn' ): mov_b__load_register_direct_data_transfer,
|
|
('MOV.W' , '@Rm,Rn' ): mov_w__load_register_direct_data_transfer,
|
|
('MOV.L' , '@Rm,Rn' ): mov_l__load_register_direct_data_transfer,
|
|
('MAC.L' , '@Rm+,@Rn+' ): mac_l__multiply_and_accumulate_operation,
|
|
('MAC.W' , '@Rm+,@Rn+' ): mac_w__multiply_and_accumulate_operation,
|
|
('MOV.B' , '@Rm+,Rn' ): mov_b__load_direct_data_transfer_from_register,
|
|
('MOV.W' , '@Rm+,Rn' ): mov_w__load_direct_data_transfer_from_register,
|
|
('MOV.L' , '@Rm+,Rn' ): mov_l__load_direct_data_transfer_from_register,
|
|
('LDC.L' , '@Rm+,SR' ): ldc_l__load_to_sr,
|
|
('LDC.L' , '@Rm+,GBR' ): ldc_l__load_to_gbr,
|
|
('LDC.L' , '@Rm+,VBR' ): ldc_l__load_to_vbr,
|
|
('LDS.L' , '@Rm+,MACH' ): lds_l__load_to_mach,
|
|
('LDS.L' , '@Rm+,MACL' ): lds_l__load_to_macl,
|
|
('LDS.L' , '@Rm+,PR' ): lds_l__load_to_pr,
|
|
('MOV.B' , 'Rm,@-Rn' ): mov_b__store_direct_data_transfer_from_register,
|
|
('MOV.W' , 'Rm,@-Rn' ): mov_w__store_direct_data_transfer_from_register,
|
|
('MOV.L' , 'Rm,@-Rn' ): mov_l__store_direct_data_transfer_from_register,
|
|
('STC.L' , 'SR,@-Rn' ): stc_l__store_from_sr,
|
|
('STC.L' , 'GBR,@-Rn' ): stc_l__store_from_gbr,
|
|
('STC.L' , 'VBR,@-Rn' ): stc_l__store_from_vbr,
|
|
('STS.L' , 'MACH,@-Rn' ): sts_l__store_from_mach,
|
|
('STS.L' , 'MACL,@-Rn' ): sts_l__store_from_macl,
|
|
('STS.L' , 'PR,@-Rn' ): sts_l__store_from_pr,
|
|
('MOV.B' , 'R0,@(disp,Rn)' ): mov_b__store_register_indirect_with_displacement,
|
|
('MOV.W' , 'R0,@(disp,Rn)' ): mov_w__store_register_indirect_with_displacement,
|
|
('MOV.L' , 'Rm,@(disp,Rn)' ): mov_l__store_register_indirect_with_displacement,
|
|
('MOV.B' , '@(disp,Rm),R0' ): mov_b__load_register_indirect_with_displacement,
|
|
('MOV.W' , '@(disp,Rm),R0' ): mov_w__load_register_indirect_with_displacement,
|
|
('MOV.L' , '@(disp,Rm),Rn' ): mov_l__load_register_indirect_with_displacement,
|
|
('MOV.B' , 'Rm,@(R0,Rn)' ): mov_b__store_indexed_register_indirect,
|
|
('MOV.W' , 'Rm,@(R0,Rn)' ): mov_w__store_indexed_register_indirect,
|
|
('MOV.L' , 'Rm,@(R0,Rn)' ): mov_l__store_indexed_register_indirect,
|
|
('MOV.B' , '@(R0,Rm),Rn' ): mov_b__load_indexed_register_indirect,
|
|
('MOV.W' , '@(R0,Rm),Rn' ): mov_w__load_indexed_register_indirect,
|
|
('MOV.L' , '@(R0,Rm),Rn' ): mov_l__load_indexed_register_indirect,
|
|
('MOV.B' , 'R0,@(disp,GBR)'): mov_b__store_gbr_indirect_with_displacement,
|
|
('MOV.W' , 'R0,@(disp,GBR)'): mov_w__store_gbr_indirect_with_displacement,
|
|
('MOV.L' , 'R0,@(disp,GBR)'): mov_l__store_gbr_indirect_with_displacement,
|
|
('MOV.B' , '@(disp,GBR),R0'): mov_b__load_gbr_indirect_with_displacement,
|
|
('MOV.W' , '@(disp,GBR),R0'): mov_w__load_gbr_indirect_with_displacement,
|
|
('MOV.L' , '@(disp,GBR),R0'): mov_l__load_gbr_indirect_with_displacement,
|
|
('AND.B' , '#imm,@(R0,GBR)'): and_b__store_indexed_gbr_indirect,
|
|
('OR.B' , '#imm,@(R0,GBR)'): or_b__store_indexed_gbr_indirect,
|
|
('TST.B' , '#imm,@(R0,GBR)'): tst_b__store_indexed_gbr_indirect,
|
|
('XOR.B' , '#imm,@(R0,GBR)'): xor_b__store_indexed_gbr_indirect,
|
|
('MOV.W' , '@(disp,PC),Rn' ): mov_w__pc_relative_with_displacement,
|
|
('MOV.L' , '@(disp,PC),Rn' ): mov_l__pc_relative_with_displacement,
|
|
('MOVA' , '@(disp,PC),R0' ): mova__pc_relative_with_displacement,
|
|
('BRAF' , 'Rm' ): braf__destination_operand_only,
|
|
('BSRF' , 'Rm' ): bsrf__destination_operand_only,
|
|
('BF' , 'label' ): bf__pc_relative,
|
|
('BF/S' , 'label' ): bf_s__pc_relative,
|
|
('BT' , 'label' ): bt__pc_relative,
|
|
('BT/S' , 'label' ): bt_s__pc_relative,
|
|
('BRA' , 'label' ): bra__pc_relative,
|
|
('BSR' , 'label' ): bsr__pc_relative,
|
|
('ADD' , '#imm,Rn' ): add__immediate,
|
|
('AND' , '#imm,R0' ): and__immediate,
|
|
('CMP/EQ' , '#imm,R0' ): cmp_eq__immediate,
|
|
('MOV' , '#imm,Rn' ): mov__immediate,
|
|
('OR' , '#imm,R0' ): or__immediate,
|
|
('TST' , '#imm,R0' ): tst__immediate,
|
|
('XOR' , '#imm,R0' ): xor__immediate,
|
|
('TRAPA' , '#imm' ): trapa__immediate,
|
|
}
|