Skip to content

Commit 1662ba6

Browse files
committed
A: add factory.py about instruction process
1 parent ff224e3 commit 1662ba6

File tree

1 file changed

+176
-0
lines changed

1 file changed

+176
-0
lines changed

factory.py

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
from utils import hexCat
2+
class Instr_Factory:
3+
4+
def __init__(
5+
self, instr: str, OP: int, Rs: int,
6+
Rt: int, Rd: int, SA: int, FUNCT: int
7+
):
8+
self.instr = instr
9+
self.OP = OP
10+
self.Rs = Rs
11+
self.Rt = Rt
12+
self.Rd = Rd
13+
self.SA = SA
14+
self.FUNCT = FUNCT
15+
self.__instr_format_calcu(self.instr)
16+
17+
def __instr_format_calcu(self, instr: str):
18+
op_instridx = ["j", "jal"]
19+
op_rt_rs_immed = ["beq", "bne"]
20+
op_rs_rt_immed = [
21+
"addi", "addiu",
22+
"slti", "sltiu", "andi", "ori", "xori", "clz",
23+
"lb", "lh", "lw", "lbu", "lhu", "sb", "sh", "sw"
24+
]
25+
op_00_rt_immed = ["lui"]
26+
op_rs_rt_rd_00_funct = ["mul"]
27+
28+
# only op and funct can figure out instr type
29+
# but for more details here
30+
spe_rs_rt_rd_00_funct = [
31+
"sllv", "srlv", "srav", "add", "addu", "sub",
32+
"subu", "and", "or", "xor", "nor", "slt", "sltu"
33+
]
34+
spe_00_rt_rd_sa_funct = ["sll", "srl", "sra"]
35+
spe_rs_rt_00_00_funct = ["mult", "multu", "div", "divu"]
36+
spe_code_funct = ["syscall", "break"]
37+
spe_rs_rt_code_funct = ["teq"]
38+
spe_rs_00_rd_00_funct = ["jalr"]
39+
spe_00_00_rd_00_funct = ["mfhi", "mflo"]
40+
spe_rs_00_00_00_funct = ["jr", "mthi", "mtlo"]
41+
42+
regimm_rs_rt_offset = ["bgez"]
43+
cop0_mtf_rt_fs_0_0 = ["mfc0", "mtc0"]
44+
45+
all_need = ["eret"]
46+
47+
instr_type_prcs_set = [
48+
{"set": op_instridx, "prcs": self.__op_instridx_prcs},
49+
{"set": op_rt_rs_immed, "prcs": self.__op_rt_rs_immed_prcs},
50+
{"set": op_rs_rt_immed, "prcs": self.__op_rs_rt_immed_prcs},
51+
{"set": op_00_rt_immed, "prcs": self.__op_00_rt_immed_prcs},
52+
{"set": op_rs_rt_rd_00_funct, "prcs": self.__op_rs_rt_rd_00_funct_prcs},
53+
{"set": spe_rs_rt_rd_00_funct, "prcs": self.__spe_rs_rt_rd_00_funct_prcs},
54+
{"set": spe_00_rt_rd_sa_funct, "prcs": self.__spe_00_rt_rd_sa_funct_prcs},
55+
{"set": spe_rs_rt_00_00_funct, "prcs": self.__spe_rs_rt_00_00_funct_prcs},
56+
{"set": spe_code_funct, "prcs": self.__spe_code_funct_prcs},
57+
{"set": spe_rs_rt_code_funct, "prcs": self.__spe_rs_rt_code_funct_prcs},
58+
{"set": spe_rs_00_rd_00_funct, "prcs": self.__spe_rs_00_rd_00_funct_prcs},
59+
{"set": spe_00_00_rd_00_funct, "prcs": self.__spe_00_00_rd_00_funct_prcs},
60+
{"set": spe_rs_00_00_00_funct, "prcs": self.__spe_rs_00_00_00_funct_prcs},
61+
{"set": regimm_rs_rt_offset, "prcs": self.__regimm_rs_rt_offset_prcs},
62+
{"set": cop0_mtf_rt_fs_0_0, "prcs": self.__cop0_mtf_rt_fs_0_0_prcs},
63+
{"set": all_need, "prcs": self.__all_need_prcs}
64+
]
65+
66+
for instr_type_prcs in instr_type_prcs_set:
67+
if self.instr in instr_type_prcs["set"]:
68+
self.instr_txt = instr_type_prcs["prcs"]()
69+
break
70+
else:
71+
raise Exception("Instruction Parse Failed!", self.instr, self.OP, self.FUNCT)
72+
73+
# j and jal
74+
def __op_instridx_prcs(self) -> str:
75+
# j and jal need << 2 additionally
76+
target = hexCat(
77+
{"val": self.Rs, "len": 5}, {"val": self.Rt, "len": 5},
78+
{"val": self.Rd, "len": 5}, {"val": self.SA, "len": 5},
79+
{"val": self.FUNCT, "len": 6}, {"val": 0b00, "len": 2}
80+
)
81+
return self.instr+" "+target
82+
83+
# beq and bne
84+
def __op_rt_rs_immed_prcs(self) -> str:
85+
immed = immed = hexCat(
86+
{"val": self.Rd, "len": 5}, {"val": self.SA, "len": 5},
87+
{"val": self.FUNCT, "len": 6}
88+
)
89+
return self.instr+" "+("$"+str(self.Rs))+", "+("$"+str(self.Rt))+", "+(immed)
90+
91+
# addi addiu slti sltiu andi ori xori lb lh lw lbu lhu sb sh sw
92+
def __op_rs_rt_immed_prcs(self) -> str:
93+
immed = hexCat(
94+
{"val": self.Rd, "len": 5}, {"val": self.SA, "len": 5},
95+
{"val": self.FUNCT, "len": 6}
96+
)
97+
return self.instr+" "+("$"+str(self.Rt))+", "+("$"+str(self.Rs))+", "+(immed)
98+
99+
# lui
100+
def __op_00_rt_immed_prcs(self) -> str:
101+
assert self.Rs == 0
102+
immed = hexCat(
103+
{"val": self.Rd, "len": 5}, {"val": self.SA, "len": 5},
104+
{"val": self.FUNCT, "len": 6}
105+
)
106+
return self.instr+" "+("$"+str(self.Rt))+", "+(immed)
107+
108+
# mul
109+
def __op_rs_rt_rd_00_funct_prcs(self) -> str:
110+
assert self.SA == 0
111+
return self.instr+" "+("$"+str(self.Rd))+", "+("$"+str(self.Rs))+", "+("$"+str(self.Rt))
112+
113+
# sllv srlv srav add addu sub subu and or xor nor slt sltu
114+
def __spe_rs_rt_rd_00_funct_prcs(self) -> str:
115+
assert self.SA == 0 and self.OP == 0
116+
return self.instr+" "+("$"+str(self.Rd))+", "+("$"+str(self.Rs))+", "+("$"+str(self.Rt))
117+
118+
# sll srl sra
119+
def __spe_00_rt_rd_sa_funct_prcs(self) -> str:
120+
assert self.OP == 0 and self.Rs == 0
121+
return self.instr+" "+("$"+str(self.Rd))+", "+("$"+str(self.Rt))+", "+str(self.SA)
122+
123+
# mult multu div divu
124+
def __spe_rs_rt_00_00_funct_prcs(self) -> str:
125+
assert self.Rd == 0 and self.SA == 0
126+
return self.instr+" "+("$"+str(self.Rs))+", "+("$"+str(self.Rt))
127+
128+
# syscall break
129+
def __spe_code_funct_prcs(self) -> str:
130+
assert self.OP == 0
131+
code = hexCat(
132+
{"val": self.Rs, "len": 5}, {"val": self.Rt, "len": 5},
133+
{"val": self.Rd, "len": 5}, {"val": self.SA, "len": 5}
134+
)
135+
return self.instr
136+
137+
# teq
138+
def __spe_rs_rt_code_funct_prcs(self) -> str:
139+
assert self.OP == 0
140+
code = hexCat(
141+
{"val": self.Rd, "len": 5}, {"val": self.SA, "len": 5}
142+
)
143+
return self.instr+" "+("$"+str(self.Rs))+", "+("$"+str(self.Rt))
144+
145+
# jalr
146+
def __spe_rs_00_rd_00_funct_prcs(self) -> str:
147+
assert self.OP == 0 and self.Rt == 0 and self.SA == 0
148+
return self.instr+" "+("$"+str(self.Rd))+", "+("$"+str(self.Rs))
149+
150+
# mfhi mflo
151+
def __spe_00_00_rd_00_funct_prcs(self) -> str:
152+
assert self.OP == 0 and self.Rs == 0 and self.Rt == 0 and self.SA == 0
153+
return self.instr+" "+("$"+str(self.Rd))
154+
155+
# jr mthi mtlo
156+
def __spe_rs_00_00_00_funct_prcs(self) -> str:
157+
assert self.OP == 0 and self.Rt == 0 and self.Rd == 0 and self.SA == 0
158+
return self.instr+" "+("$"+str(self.Rs))
159+
160+
# bgez
161+
def __regimm_rs_rt_offset_prcs(self) -> str:
162+
assert self.OP == 0b000001 # REGIMM
163+
offset = hexCat(
164+
{"val": self.Rd, "len": 5}, {"val": self.SA, "len": 5},
165+
{"val": self.FUNCT, "len": 6}
166+
)
167+
return self.instr+" "+("$"+str(self.Rs))+", "+(offset)
168+
169+
# mfc0 mtc0
170+
def __cop0_mtf_rt_fs_0_0_prcs(self) -> str:
171+
assert self.OP == 0b010000 and self.Rs == 0 and self.SA == 0
172+
return self.instr+" "+("$"+str(self.Rt))+", "+str(self.Rd)
173+
174+
# eret
175+
def __all_need_prcs(self) -> str:
176+
return self.instr

0 commit comments

Comments
 (0)