2024-12-03 19:41:01 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_value(b:bytearray):
|
|
|
|
ret=0
|
|
|
|
for i,item in enumerate(b):
|
|
|
|
ret|=item<<(8*i)
|
|
|
|
return ret
|
|
|
|
|
|
|
|
def set_value(b:bytearray,value:int):
|
|
|
|
for i in range(len(b)):
|
|
|
|
b[i]=(value>>(8*i))&0xff
|
|
|
|
|
|
|
|
|
|
|
|
class cpu(object):
|
|
|
|
def __init__(self,rom_addr:int,rom_size:int,mem_addr:int,mem_size:int) -> None:
|
|
|
|
self.rom_addr=rom_addr
|
|
|
|
self.rom=bytearray(rom_size)
|
|
|
|
self.mem_addr=mem_addr
|
|
|
|
self.mem=bytearray(mem_size)
|
2024-12-04 11:39:53 +08:00
|
|
|
self.pc=self.mem_addr
|
|
|
|
self.sp=self.mem_addr
|
|
|
|
self.rp=self.pc
|
|
|
|
self.fp=self.sp
|
2024-12-04 18:52:34 +08:00
|
|
|
self.regs=[]
|
|
|
|
for i in range(32):
|
|
|
|
self.regs.append(0)
|
2024-12-03 19:41:01 +08:00
|
|
|
def get_value(self,addr:int,size:int):
|
|
|
|
if not (size in [1,2,4,8]):
|
|
|
|
raise Exception(f"CPU 异常 因为地址未对齐 {size}")
|
|
|
|
if(addr>=self.rom_addr) and (addr<self.rom_addr+len(self.rom)):
|
|
|
|
return get_value(self.rom[addr-self.rom_addr,addr-self.rom_addr+size])
|
|
|
|
def set_value(self,addr:int,size:int,value:int):
|
|
|
|
if not (size in [1,2,4,8]):
|
|
|
|
raise Exception(f"CPU 异常 因为地址未对齐 {size}")
|
|
|
|
if(addr>=self.rom_addr) and (addr<self.rom_addr+len(self.rom)):
|
|
|
|
set_value(self.rom[addr-self.rom_addr,addr-self.rom_addr+size],value)
|
2024-12-04 11:39:53 +08:00
|
|
|
def opt_add(self,src_addr1:int,src_addr2:int,out_addr:int):
|
|
|
|
src1=self.get_value(src_addr1,4)
|
|
|
|
src2=self.get_value(src_addr2,4)
|
|
|
|
self.set_value(out_addr,4,src1+src2)
|
|
|
|
def opt_sub(self,src_addr1:int,src_addr2:int,out_addr:int):
|
|
|
|
src1=self.get_value(src_addr1,4)
|
|
|
|
src2=self.get_value(src_addr2,4)
|
|
|
|
self.set_value(out_addr,4,src1-src2)
|
|
|
|
def opt_bitor(self,src_addr1:int,src_addr2:int,out_addr:int):
|
|
|
|
src1=self.get_value(src_addr1,4)
|
|
|
|
src2=self.get_value(src_addr2,4)
|
|
|
|
self.set_value(out_addr,4,src1|src2)
|
|
|
|
def opt_bitand(self,src_addr1:int,src_addr2:int,out_addr:int):
|
|
|
|
src1=self.get_value(src_addr1,4)
|
|
|
|
src2=self.get_value(src_addr2,4)
|
|
|
|
self.set_value(out_addr,4,src1&src2)
|
|
|
|
def opt_bitxor(self,src_addr1:int,src_addr2:int,out_addr:int):
|
|
|
|
src1=self.get_value(src_addr1,4)
|
|
|
|
src2=self.get_value(src_addr2,4)
|
|
|
|
self.set_value(out_addr,4,src1^src2)
|
|
|
|
def opt_jmp(self,jmp_addr:int):
|
|
|
|
self.pc=jmp_addr
|
|
|
|
# 要进入子函数 先enter 再设置形式参数
|
|
|
|
def opt_enter(self,enter_addr:int):
|
|
|
|
self.set_value(self.sp,4,self.rp)
|
|
|
|
self.rp=self.pc
|
|
|
|
self.sp+=4
|
|
|
|
self.set_value(self.sp,4,self.fp)
|
|
|
|
self.sp+=4
|
|
|
|
self.fp=self.sp
|
|
|
|
self.pc=enter_addr
|
|
|
|
# 返回的时候先回溯sp指针 然后把pc指针指定到之前的pc指针+4的位置
|
|
|
|
def opt_return(self,return_value:int):
|
|
|
|
self.sp=self.fp
|
|
|
|
self.sp-=4
|
|
|
|
self.fp=self.get_value(self.sp,4)
|
|
|
|
self.pc=self.rp+4
|
|
|
|
self.sp-=4
|
|
|
|
self.rp=self.get_value(self.sp,4)
|
|
|
|
self.set_value(self.sp,4,return_value)
|
|
|
|
# 在栈上创建变量的存储空间
|
|
|
|
def create_var(self,size:int):
|
|
|
|
ret=self.sp
|
|
|
|
self.sp+=((size+3)//4)*4
|
|
|
|
return ret
|
2024-12-03 19:41:01 +08:00
|
|
|
|
|
|
|
|
2024-12-04 18:52:34 +08:00
|
|
|
# 数据操作指令 1000_xxxx_0000_0000_0000_0000_0000_0000
|
|
|
|
# 加法指令 1000_0001_src1[8]_src2[8]_dst[8]
|
|
|
|
# 减法指令 1000_0010_src1[8]_src2[8]_dst[8]
|
|
|
|
# 乘法指令 1000_0011_src1[8]_src2[8]_dst[8]
|
|
|
|
# 除法指令 1000_0100_src1[8]_src2[8]_dst[8]
|
|
|
|
# 按位与指令 1000_0101_src1[8]_src2[8]_dst[8]
|
|
|
|
# 按位或指令 1000_0110_src1[8]_src2[8]_dst[8]
|
|
|
|
# 按位异或指令 1000_0111_src1[8]_src2[8]_dst[8]
|
|
|
|
# 复制数据指令 1000_1000_0000_0000_src[8]_dst[8]
|
|
|
|
# 左移数据指令 1000_1001_shit[8]_src[8]_dst[8]
|
|
|
|
# 右移数据指令 1000_1010_shit[8]_src[8]_dst[8]
|
|
|
|
# 取反指令 1000_1011_0000_0000_src[8]_dst[8]
|
|
|
|
|
|
|
|
# 数据搬运指令 1001_xxxx_0000_0000_0000_0000_0000_0000
|
|
|
|
# 从内存绝对地址搬运数据到指定寄存器,mem_addr_reg是要保存在内存的地址
|
|
|
|
# 1001_0001_0000_0000_reg[8]_mem_addr_reg[8]
|
|
|
|
# 从指定寄存器搬运数据到内存,mem_addr_reg是要保存在内存的地址
|
|
|
|
# 1001_0010_0000_0000_reg[8]_mem_addr_reg[8]
|
|
|
|
|
|
|
|
# 跳转指令 1010_xxxx_0000_0000_0000_0000_0000_0000
|
|
|
|
# 无条件跳转指令 跳转地址保存在reg中
|
|
|
|
# 1010_0000_0000_0000_0000_0000_reg[8]
|
|
|
|
# 在指定寄存器为0时跳转
|
|
|
|
# 1010_0001_0000_0000_juge_reg[8]_reg[8]
|
|
|
|
# 在指定寄存器不为0时跳转
|
|
|
|
# 1010_0010_0000_0000_juge_reg[8]_reg[8]
|
|
|
|
|
2024-12-05 11:16:00 +08:00
|
|
|
# 栈操作指令 1011_xxxx_0000_0000_0000_0000_0000_0000
|
|
|
|
# 所有寄存器入栈 fp sp rp regs[32]
|
|
|
|
# 1011_0000_0000_0000_0000_0000_0000_0000
|
|
|
|
# 所有寄存器出栈 fp sp rp regs[32]
|
|
|
|
# 1011_0001_0000_0000_0000_0000_0000_0000
|
|
|
|
# 栈增一个字长 并在原栈位置设置初值
|
|
|
|
# 1011_0010_0000_0000_0000_0000_reg[8]
|
|
|
|
# 栈增reg_num个字长 并在原栈位置reg_addr所指地址的初值
|
|
|
|
# 1011_0011_0000_0000_reg_num[8]_reg_addr[8]
|
|
|
|
# 栈减reg_num个字长
|
|
|
|
# 1011_0100_0000_0000_0000_0000_reg_num[8]
|
|
|
|
|
2024-12-04 18:52:34 +08:00
|
|
|
|
|
|
|
class instruction(object):
|
|
|
|
def __init__(self) -> None:
|
2024-12-05 11:16:00 +08:00
|
|
|
pass
|
|
|
|
def add(self,src1:int,src2:int,dst:int):
|
|
|
|
return (0x81<<24)|(src1<<16)|(src2<<8)|(dst)
|
|
|
|
def sub(self,src1:int,src2:int,dst:int):
|
|
|
|
return (0x82<<24)|(src1<<16)|(src2<<8)|(dst)
|
|
|
|
def mul(self,src1:int,src2:int,dst:int):
|
|
|
|
return (0x83<<24)|(src1<<16)|(src2<<8)|(dst)
|
|
|
|
def div(self,src1:int,src2:int,dst:int):
|
|
|
|
return (0x84<<24)|(src1<<16)|(src2<<8)|(dst)
|
|
|
|
def bitand(self,src1:int,src2:int,dst:int):
|
|
|
|
return (0x85<<24)|(src1<<16)|(src2<<8)|(dst)
|
|
|
|
def bitor(self,src1:int,src2:int,dst:int):
|
|
|
|
return (0x86<<24)|(src1<<16)|(src2<<8)|(dst)
|
|
|
|
def bitxor(self,src1:int,src2:int,dst:int):
|
|
|
|
return (0x87<<24)|(src1<<16)|(src2<<8)|(dst)
|
|
|
|
def mov(self,src:int,dst:int):
|
|
|
|
return (0x88<<24)|(src<<8)|(dst)
|
|
|
|
def lsh(self,shift_bit:int,src:int,dst:int):
|
|
|
|
return (0x89<<24)|(shift_bit<<16)|(src<<8)|(dst)
|
|
|
|
def rsh(self,shift_bit:int,src:int,dst:int):
|
|
|
|
return (0x8a<<24)|(shift_bit<<16)|(src<<8)|(dst)
|
|
|
|
def neg(self,src:int,dst:int):
|
|
|
|
return (0x8b<<24)|(src<<8)|(dst)
|
|
|
|
|
|
|
|
def load(self,reg:int,mem_addr_reg:int):
|
|
|
|
return (0x91<<24)|(reg<<8)|(mem_addr_reg)
|
|
|
|
def save(self,reg:int,mem_addr_reg:int):
|
|
|
|
return (0x92<<24)|(reg<<8)|(mem_addr_reg)
|
|
|
|
|
|
|
|
def jmp(self,addr_reg:int):
|
|
|
|
return (0xa0<<24)|(addr_reg)
|
|
|
|
def jmp_zero(self,juge_reg:int,reg:int):
|
|
|
|
return (0xa1<<24)|(juge_reg<<8)|(reg)
|
|
|
|
def jmp_no_zero(self,juge_reg:int,reg:int):
|
|
|
|
return (0xa2<<24)|(juge_reg<<8)|(reg)
|
|
|
|
|
|
|
|
def push_all(self):
|
|
|
|
return (0xb0<<24)
|
|
|
|
def pop_all(self):
|
|
|
|
return (0xb1<<24)
|
|
|
|
def sp_add(self,reg:int):
|
|
|
|
return (0xb2<<24)|(reg)
|
|
|
|
def sp_add_count(self,count_reg:int,data_addr_reg:int):
|
|
|
|
return (0xb3<<24)|(count_reg<<8)|(data_addr_reg)
|
|
|
|
def sp_sub(self,count_reg:int):
|
|
|
|
return (0xb4<<24)|(count_reg)
|
2024-12-04 18:52:34 +08:00
|
|
|
|