Skip to content

Commit a718fe8

Browse files
committed
Merge branch 'tmp' into main
2 parents e25ac02 + fcd0478 commit a718fe8

File tree

2 files changed

+240
-0
lines changed

2 files changed

+240
-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

main.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
from factory import Instr_Factory
2+
from utils import separate, trans
3+
import argparse
4+
5+
'''
6+
input: file_path
7+
mode: STD | FILE
8+
'''
9+
def main(mode: str, infile_path: str, outfile_path=None):
10+
assert not (mode == "FILE" and outfile_path is None)
11+
12+
fin = open(infile_path)
13+
lines = fin.readlines()
14+
lines = [int(line.strip('\n'), 16) for line in lines]
15+
16+
if mode == "FILE":
17+
fout = open(outfile_path, "w", encoding="utf-8")
18+
19+
sepa_lst = [separate(line) for line in lines]
20+
trans_lst = [trans(line) for line in sepa_lst]
21+
instr_txt_lst = []
22+
for line in trans_lst:
23+
instr = line[0]
24+
instr_fact = Instr_Factory(
25+
instr["instr"], instr["OP"], instr["Rs"],
26+
instr["Rt"], instr["Rd"], instr["SA"], instr["FUNCT"]
27+
)
28+
instr_txt_lst.append(instr_fact.instr_txt)
29+
30+
if mode == "FILE":
31+
# add '\n'
32+
instr_txt_lst = [instr_txt+'\n' for instr_txt in instr_txt_lst]
33+
fout.writelines(instr_txt_lst)
34+
elif mode == "STD":
35+
for instr_txt in instr_txt_lst:
36+
print(instr_txt)
37+
else:
38+
pass
39+
40+
parser = argparse.ArgumentParser()
41+
42+
choices = [
43+
{ "method": "-d", "vmethod": "--dsasmb", "help": "disassemble *.txt" },
44+
{ "method": "-o", "vmethod": "--output", "help": "output to *.txt" }
45+
]
46+
47+
for choice in choices:
48+
parser.add_argument(
49+
choice["method"], choice["vmethod"], type=str,
50+
help=choice["help"]
51+
)
52+
53+
args = parser.parse_args()
54+
55+
if __name__ == "__main__":
56+
infile_path = args.dsasmb
57+
outfile_path = args.output
58+
59+
assert infile_path is not None
60+
61+
if outfile_path is None:
62+
main("STD", infile_path)
63+
else:
64+
main("FILE", infile_path, outfile_path)

0 commit comments

Comments
 (0)