体系结构基础知识: 六-体系结构 Architecture_华仔142的博客-CSDN博客
实验要求:
输入:汇编语言程序文件
输出:二进制或十六进制文件,采用Xilinx Vivado的COE文件格式
比如,对类似下面的汇编语言程序,能够顺利翻译为机器指令:
# 这是注释
addi $t1, $0, 100 #这也是注释,空行应该能够顺利跳过
addi $t2, $0, 200
add $t3, $t1, $t2 # #符号后面的是注释
addi $t4, $0, 400
and $t5, $t1, $t4
sub $t2, $t3, $t4
COE文件格式:
;This .COE file specifies the content for a block memory of depth=6, and width=32
memory_initialization_radix=6;
memory_initialization_vector=
20090064,
200A00C8,
012A5820,
200C0190,
012C6824,
016C5022;
设计思路:两遍扫描法
Pass1:解释所有伪指令、记录label的地址
比如li伪指令,可能生成两条机器指令
Pass2:对所有分支目标地址进行填充,生成机器码
代码实现(与牛仔共同完成):
1. 最顶层部分:assembler_MISP.py
import re
from functions import*
# 处理一行指令
def process_text(op, param, row, label2addr, address):
# input a line of instruction, output its hexcode
func = functions.get(op, "error")
if func == "error":
raise Exception('Line %d : No such operator.' % row)
bicodestr = func(param, row, label2addr, address)
return bicodestr
# def process(aline):
# line, op = process_text(aline, 1, {}, 0)
# if op == 'li':
# line1 = line[0:31]
# line2 = line[33:64]
# line1 = hex(int(line1, 2))[2:].zfill(8).upper()
# line2 = hex(int(line2, 2))[2:].zfill(8).upper()
# return line1 + '\n' + line2
# else:
# line = hex(int(line, 2))[2:].zfill(8).upper()
# return line
def check_report_error(op, param, labels, line):
instructions_with_labels = ['bltz', 'blez', 'j', 'jal', 'beq', 'bne']
R_instructions = ['sll', 'srl', 'sra', 'add', 'sub', 'and', 'or', 'xor', 'nor', 'slt']
imm_instructions = ['addi', 'slti', 'andi','ori', 'xori', 'lui']
if op not in functions.keys():
print("in line %d, No such instruction"%(line))
return False
if op in R_instructions:
for i in range(len(param)):
try:
param[i] = int(param[i])
if op in ['sll', 'srl', 'sra'] and i == 2:
if param[i] > 31 or param[i] < -32:
print("in line %d:The shamt out of limit" %(line))
return False
break
print("in line %d:The R_instructions don't accept imm" %(line))
return False
except:
pass
if op in imm_instructions:
if op == 'lui':
imm = param[1]
else: imm = param[2]
try:
imm = int(imm)
except:
print("in line %d:require imm" %(line))
return False
if imm > 32767 or imm<-32768:
print("in line %d:the imm out of limit" %(line))
return False
if op in instructions_with_labels:
if op in ['blez', 'bltz']:
label = param[1]
elif op in ['j', 'jal']:
label = param[0]
else: label = param[2]
if label not in labels.keys():
print("in line %d:no such label" %(line))
return False
if op in ['jr', 'jalr']:
rs = param[0]
if rs not in register:
print("in line %d:no such register" %(line))
return False
return True
def process_file(infname, outfname):
with open(infname, 'r',encoding='utf-8' ) as file:
instructions = file.readlines()
file.close()
label_lines = first_scan(instructions)
label2addr, processed_instructions = second_scan(instructions, label_lines)
mcode_list = third_scan(processed_instructions, label_lines, label2addr)
with open(outfname, 'w') as out:
out.write(";This .COE file specifies the content for a block memory of depth=%d, and width=32\n"%(len(mcode_list)))
out.write("memory_initialization_radix=%d;\n"%len(mcode_list))
out.write("memory_initialization_vector=\n")
for i, line in enumerate(mcode_list[0:-1]):
#line = str(i*4) + ' ' + hex(int(line, 2))[2:].zfill(8).upper()
line = hex(int(line, 2))[2:].zfill(8).upper()
#print(line)
out.write(line+','+'\n')
line = mcode_list[len(mcode_list) - 1]
line = hex(int(line, 2))[2:].zfill(8).upper()
out.write(line + ';')
def first_scan(rows):
labels_line = {}
for i, row in enumerate(rows, 1):
#处理空行
row = row.strip()
if row == '':
continue
#处理注释
if re.search('#', row):
pos = re.search('#', row).span()[0]
if row[0: pos].strip() == '':
continue
row = row[0: pos]
#记录label行数
if re.search(':', row):
pos = re.search(':', row).span()[0]
label_name = row[0: pos].strip()
labels_line[label_name] = i
#label2addr[label_name] = addr
continue
return labels_line
def second_scan(rows, label_line):
label2addr = {}
proecess_instructions = []
addr = 0
for line, row in enumerate(rows, 1):
#处理空行
row = row.strip()
if row == '':
continue
#处理注释
if re.search('#', row):
pos = re.search('#', row).span()[0]
if row[0: pos].strip() == '':
continue
row = row[0: pos]
#单独处理标签行
if re.search(':', row):
pos = re.search(':', row).span()[0]
label_name = row[0: pos].strip()
label2addr[label_name] = addr
continue
#标准化指令格式
param = row.split(' ')
for i in range(len(param)):
param[i]=param[i].strip(',')
param[i]=param[i].strip('\t')
#处理括号里有立即数的情况
if re.search("[(]",param[i]):
pos = re.search("[(]",param[i]).span()[0]
param.append(param[i][pos+1:-1])
param[i] = param[i][0:pos]
#将其他进制的立即数转化为十进制
try:
param[i] = eval(param[i])
except:
pass
for i in range(len(param)-1,-1,-1):
if param[i] == '':
del param[i]
#判断指令是否有误
op = param[0]
del param[0]
#print(op, param, line)
if check_report_error(op, param, label_line, line) == True: #当前指令没有报错
addr += 4
proecess_instructions.append(row)
else: continue
return label2addr, proecess_instructions
def third_scan(rows, label_line, label2addr):
addr = 0
mcode_list = []
for line, row in enumerate(rows, 1):
#处理空行
row = row.strip()
if row == '':
continue
#处理注释
if re.search('#', row):
pos = re.search('#', row).span()[0]
if row[0: pos].strip() == '':
continue
row = row[0: pos]
#若此行为标签,则跳过此行
if re.search(':', row):
continue
#标准化指令格式
param = row.split(' ')
for i in range(len(param)):
param[i]=param[i].strip(',')
param[i]=param[i].strip('\t')
#处理括号里有立即数的情况
if re.search("[(]",param[i]):
pos = re.search("[(]",param[i]).span()[0]
param.append(param[i][pos+1:-1])
param[i] = param[i][0:pos]
#将其他进制的立即数转化为十进制
try:
param[i] = eval(param[i])
except:
pass
for i in range(len(param)-1,-1,-1):
if param[i] == '':
del param[i]
#判断指令是否有误
op = param[0]
del param[0]
#if check_report_error(op, param, label_line, line) == True: #当前指令没有报错
machinecode = process_text(op, param, line, label2addr, addr)
mcode_list.append(machinecode)
#print(addr, op, param, machinecode)
#print("the mcode is", end=" ")
#print(machinecode)
addr += 4
#else: continue
return mcode_list
2. 处理指令的函数:functions.py
from resourses import *
import re
def num2bin(num,length):
if(num >= 0):
temp = bin(num).replace('0b','')
while(len(temp) < length):
temp = '0' + temp
return temp
else:
num = 2**length+num
res = bin(num).replace('0b','')
return res
# opRS
# def asm_bltz(param, line, symbol_table, address):
# rs = regiser.get(param[0], 'error')
# label= regiser.get(param[1], 'error')
# return IS['bltz']['opcode'] + rs
def asm_j(param, line, symbol_table, address):
# result = IS['j']['opcode']
place = symbol_table.get(param[0], 'error')
# print('\n')
# print(place)
# print('\n')
if(place=='error'):
raise Exception('Line %d : No such symbol.' % line)
return num2bin(IS['j']['opcode'],6) + num2bin(int(place/4), 26)
def asm_jal(param, line, symbol_table, address):
place = symbol_table.get(param[0], 'error')
# print('\n')
# print(place)
# print('\n')
if(place=='error'):
raise Exception('Line %d : No such symbol.' % line)
return num2bin(IS['jal']['opcode'], 6) + num2bin(int(place/4), 26)
def asm_jalr(param, line, symbol_table, address):
rs = register.get(param[0], 'error')
if rs =='error' :
raise Exception('Line %d : No such register.' % line)
return num2bin(IS['jalr']['opcode'], 6) + rs + '000001111100000' + num2bin(IS['jalr']['func'], 6)
def asm_beq(param, line, symbol_table, address):
rs = register.get(param[0], 'error')
rt = register.get(param[1], 'error')
place = symbol_table.get(param[2], 'error')
diff = place - address - 4
if(place=='error'):
raise Exception('Line %d : No such symbol.' % line)
return num2bin(IS['beq']['opcode'],6) + rs + rt + num2bin(int(diff/4), 16)
def asm_bne(param, line, symbol_table, address):
rs = register.get(param[0], 'error')
rt = register.get(param[1], 'error')
place = symbol_table.get(param[2], 'error')
if(place == 'error'):
raise Exception('Line %d : No such symbol.' % line)
return num2bin(IS['bne']['opcode'],6) + num2bin(int(place/4), 26)
def blez(param, line, symbol_table, address):
rs = register.get(param[0], 'error')
place = symbol_table.get(param[1], 'error')
if(place == 'error'):
raise Exception('Line %d : No such symbol.' % line)
return num2bin(IS['blez']['opcode'], 6) + rs + '000000000000000' + num2bin(IS['blez']['opcode', 6])
def blzt(param, line, symbol_table, address):
rs = register.get(param[0], 'error')
place = symbol_table.get(param[1], 'error')
if(place == 'error'):
raise Exception('Line %d : No such symbol.' % line)
return num2bin(IS['blzt']['opcode'], 6) + rs + '000000000000000' + num2bin(IS['blzt']['opcode', 6])
def asm_addi(param, line, symbol_table, address):
rt = register.get(param[0], 'error')
rs = register.get(param[1], 'error')
imm = param[2]
if rs =='error' or rt == 'error':
raise Exception('Line %d : No such register.' % line)
return num2bin(IS['addi']['opcode'], 6) + rs + rt + num2bin(int(imm), 16)
def asm_slti(param, line, symbol_table, address):
rt = register.get(param[0], 'error')
rs = register.get(param[1], 'error')
imm = param[2]
if rs =='error' or rt == 'error':
raise Exception('Line %d : No such register.' % line)
return num2bin(IS['slti']['opcode'], 6) + rs + rt + num2bin(int(imm), 16)
def asm_andi(param, line, symbol_table, address):
rt = register.get(param[0], 'error')
rs = register.get(param[1], 'error')
imm = param[2]
if rs =='error' or rt == 'error':
raise Exception('Line %d : No such register.' % line)
return num2bin(IS['andi']['opcode'], 6) + rs + rt + num2bin(int(imm), 16)
def asm_ori(param, line, symbol_table, address):
rt = register.get(param[0], 'error')
rs = register.get(param[1], 'error')
imm = param[2]
if rs =='error' or rt == 'error':
raise Exception('Line %d : No such register.' % line)
return num2bin(IS['ori']['opcode'], 6) + rs + rt + num2bin(int(imm), 16)
def asm_xori(param, line, symbol_table, address):
rt = register.get(param[0], 'error')
rs = register.get(param[1], 'error')
imm = param[2]
if rs =='error' or rt == 'error':
raise Exception('Line %d : No such register.' % line)
return num2bin(IS['xori']['opcode'], 6) + rs + rt + num2bin(int(imm), 16)
def asm_lui(param, line, symbol_table, address):
rt = register.get(param[0], 'error')
imm = param[1]
if rt =='error':
raise Exception('Line %d : No such register.' % line)
return num2bin(IS['lui']['opcode'], 6) + '00000' + rt + num2bin(int(imm), 16)
def asm_lb(param, line, symbol_table, address):
rt = register.get(param[0], 'error')
imm = param[1][0]
rs = register.get(param[1][2:-1], 'error')
if rs =='error' or rt == 'error':
raise Exception('Line %d : No such register.' % line)
return num2bin(IS['lb']['opcode'], 6) + rs + rt + num2bin(int(imm), 16)
def asm_lh(param, line, symbol_table, address):
rt = register.get(param[0], 'error')
imm = param[1][0]
rs = register.get(param[1][2:-1], 'error')
if rs =='error' or rt == 'error':
raise Exception('Line %d : No such register.' % line)
return num2bin(IS['lh']['opcode'], 6) + rs + rt + num2bin(int(imm), 16)
def asm_lw(param, line, symbol_table, address):
rt = register.get(param[0], 'error')
imm = param[1]
rs = register.get(param[2], 'error')
if rt == 'error' or rs == 'error':
raise Exception('Line %d : No such register.' % line)
return num2bin(IS['lw']['opcode'], 6) + rs + rt + num2bin(int(imm), 16)
def asm_sb(param, line, symbol_table, address):
rt = register.get(param[0], 'error')
imm = param[1][0]
rs = register.get(param[1][2:-1], 'error')
if rs =='error' or rt == 'error':
raise Exception('Line %d : No such register.' % line)
return num2bin(IS['sb']['opcode'], 6) + rs + rt + num2bin(int(imm), 16)
def asm_sh(param, line, symbol_table, address):
rt = register.get(param[0], 'error')
imm = param[1][0]
rs = register.get(param[1][2:-1], 'error')
if rs =='error' or rt == 'error':
raise Exception('Line %d : No such register.' % line)
return num2bin(IS['sh']['opcode'], 6) + rs + rt + num2bin(int(imm), 16)
def asm_sw(param, line, symbol_table, address):
rt = register.get(param[0], 'error')
imm = param[1]
rs = register.get(param[2], 'error')
if rt == 'error' or rs == 'error':
raise Exception('Line %d : No such register.' % line)
return num2bin(IS['sw']['opcode'], 6) + rs + rt + num2bin(int(imm), 16)
# RIS
def asm_sll(param, line, symbol_table, address):
rd = register.get(param[0], 'error')
rt = register.get(param[1], 'error')
shamt = param[2]
if rd =='error' or rt == 'error':
raise Exception('Line %d : No such register.' % line)
return num2bin(IS['sll']['opcode'], 6) + '00000' + rt + rd + num2bin(int(shamt), 5) + num2bin(IS['sll']['func'], 6)
def asm_srl(param, line, symbol_table, address):
rd = register.get(param[0], 'error')
rt = register.get(param[1], 'error')
shamt = param[2]
if rd =='error' or rt == 'error':
raise Exception('Line %d : No such register.' % line)
return num2bin(IS['srl']['opcode'], 6) + '00000' + rt + rd + num2bin(int(shamt), 5) + num2bin(IS['srl']['func'], 6)
def asm_sra(param, line, symbol_table, address):
rd = register.get(param[0], 'error')
rt = register.get(param[1], 'error')
shamt = param[2]
if rd =='error' or rt == 'error':
raise Exception('Line %d : No such register.' % line)
return num2bin(IS['sra']['opcode'], 6) + '00000' + rt + rd + num2bin(int(shamt), 5) + num2bin(IS['sra']['func'], 6)
def asm_sllv(param, line, symbol_table, address):
rd = register.get(param[0], 'error')
rt = register.get(param[1], 'error')
rs = register.get(param[2], 'error')
if rd =='error' or rs == 'error' or rt =='error':
raise Exception('Line %d : No such register.' % line)
return num2bin(IS['sllv']['opcode'],6) + rs + rt + rd + '00000' + num2bin(IS['sllv']['func'],6)
def asm_srlv(param, line, symbol_table, address):
rd = register.get(param[0], 'error')
rt = register.get(param[1], 'error')
rs = register.get(param[2], 'error')
if rd =='error' or rs == 'error' or rt =='error':
raise Exception('Line %d : No such register.' % line)
return num2bin(IS['srlv']['opcode'],6) + rs + rt + rd + '00000' + num2bin(IS['srlv']['func'],6)
def asm_srav(param, line, symbol_table, address):
rd = register.get(param[0], 'error')
rt = register.get(param[1], 'error')
rs = register.get(param[2], 'error')
if rd =='error' or rs == 'error' or rt =='error':
raise Exception('Line %d : No such register.' % line)
return num2bin(IS['srav']['opcode'],6) + rs + rt + rd + '00000' + num2bin(IS['srav']['func'],6)
def asm_jr(param, line, symbol_table, address):
rs = register.get(param[0], 'error')
if rs == 'error':
raise Exception('Line %d : No such register.' % line)
return num2bin(IS['jr']['opcode'], 6) + rs + '000000000000000' + num2bin(IS['jr']['func'], 6)
def asm_add(param, line, symbol_table, address):
rd = register.get(param[0], 'error')
rs = register.get(param[1], 'error')
rt = register.get(param[2], 'error')
if rd =='error' or rs == 'error' or rt =='error':
raise Exception('Line %d : No such register.' % line)
return num2bin(IS['add']['opcode'],6) + rs + rt + rd + '00000' + num2bin(IS['add']['func'],6)
def asm_sub(param, line, symbol_table, address):
rd = register.get(param[0], 'error')
rs = register.get(param[1], 'error')
rt = register.get(param[2], 'error')
if rd =='error' or rs == 'error' or rt =='error':
raise Exception('Line %d : No such register.' % line)
return num2bin(IS['sub']['opcode'], 6) + rs + rt + rd + '00000' + num2bin(IS['sub']['func'], 6)
def asm_and(param, line, symbol_table, address):
rd = register.get(param[0], 'error')
rs = register.get(param[1], 'error')
rt = register.get(param[2], 'error')
if rd =='error' or rs == 'error' or rt =='error':
raise Exception('Line %d : No such register.' % line)
return num2bin(IS['and']['opcode'], 6) + rs + rt + rd + '00000' + num2bin(IS['and']['func'], 6)
def asm_or(param, line, symbol_table, address):
rd = register.get(param[0], 'error')
rs = register.get(param[1], 'error')
rt = register.get(param[2], 'error')
if rd =='error' or rs == 'error' or rt =='error':
raise Exception('Line %d : No such register.' % line)
return num2bin(IS['or']['opcode'], 6) + rs + rt + rd + '00000' + num2bin(IS['or']['func'], 6)
def asm_xor(param, line, symbol_table, address):
rd = register.get(param[0], 'error')
rs = register.get(param[1], 'error')
rt = register.get(param[2], 'error')
if rd =='error' or rs == 'error' or rt =='error':
raise Exception('Line %d : No such register.' % line)
return num2bin(IS['xor']['opcode'], 6) + rs + rt + rd + '00000' + num2bin(IS['xor']['func'], 6)
def asm_nor(param, line, symbol_table, address):
rd = register.get(param[0], 'error')
rs = register.get(param[1], 'error')
rt = register.get(param[2], 'error')
if rd =='error' or rs == 'error' or rt =='error':
raise Exception('Line %d : No such register.' % line)
return num2bin(IS['nor']['opcode'], 6) + rs + rt + rd + '00000' + num2bin(IS['nor']['func'], 6)
def asm_slt(param, line, symbol_table, address):
rd = register.get(param[0], 'error')
rs = register.get(param[1], 'error')
rt = register.get(param[2], 'error')
if rd =='error' or rs == 'error' or rt =='error':
raise Exception('Line %d : No such register.' % line)
return num2bin(IS['slt']['opcode'], 6) + rs + rt + rd + '00000' + num2bin(IS['slt']['func'], 6)
#pseudoIS
def asm_nop(param, line, symbol_table, address):
return '100010000100000000000000000000'
def asm_li(param, line, symbol_table, address):
rt = register.get(param[0], 'error')
imm = num2bin(int(param[1]), 32)
imm_high = imm[0:15]
imm_low = imm[16:31]
if rt == 'error':
raise Exception('Line %d : No such register.' % line)
c1 = num2bin(IS['lui']['opcode'], 6) + '00000' + rt + imm_high
c2 = num2bin(IS['ori']['opcode'], 6) + rt + rt + imm_low
return c1 + '\n' + c2
def asm_mv(param, line, symbol_table, address):
a = param[0]
b = param[1]
p = [a, b, 0]
return asm_addi(p, line, symbol_table, address)
def asm_not(param, line, symbol_table, address):
a = param[0]
b = param[1]
p = [a, b, -1]
return asm_xori(p, line, symbol_table, address)
def asm_neg(param, line, symbol_table, address):
rd = param[0]
rs = '$0'
rt = param[1]
p = [rd, rs, rt]
return asm_sub(p, line, symbol_table, address)
def asm_mfhi(param, line, symbol_table, address):
rd = register.get(param[0], 'error')
if rd =='error':
raise Exception('Line %d : No such register.' % line)
return num2bin(IS['mfhi']['opcode'], 6) + '0000000000' + rd + '00000' + num2bin(IS['mfhi']['func'], 6)
def asm_mflo(param, line, symbol_table, address):
rd = register.get(param[0], 'error')
if rd =='error':
raise Exception('Line %d : No such register.' % line)
return num2bin(IS['mflo']['opcode'], 6) + '0000000000' + rd + '00000' + num2bin(IS['mflo']['func'], 6)
def asm_mult(param, line, symbol_table, address):
rs = register.get(param[0], 'error')
rt = register.get(param[1], 'error')
if rs =='error' or rt == 'error' :
raise Exception('Line %d : No such register.' % line)
return num2bin(IS['mult']['opcode'], 6) + rs + rt + '0000000000' + num2bin(IS['mult']['func'], 6)
def asm_mthi(param, line, symbol_table, address):
rs = register.get(param[0], 'error')
if rs =='error':
raise Exception('Line %d : No such register.' % line)
return num2bin(IS['mthi']['opcode'], 6) + rs + '0000000000' + '00000' + num2bin(IS['mthi']['func'], 6)
def asm_mtlo(param, line, symbol_table, address):
rs = register.get(param[0], 'error')
if rs =='error':
raise Exception('Line %d : No such register.' % line)
return num2bin(IS['mtlo']['opcode'], 6) + rs + '0000000000' + '00000' + num2bin(IS['mtlo']['func'], 6)
functions = {
'add': asm_add,
'addi': asm_addi,
'and': asm_and,
'andi': asm_andi,
'sra':asm_sra,
'srav':asm_srav,
'beq': asm_beq,
#'bltz': asm_bltz,
'bne': asm_bne,
'j': asm_j,
'jal': asm_jal,
'jalr': asm_jalr,
'jr': asm_jr,
'lb': asm_lb,
'lui': asm_lui,
'lw': asm_lw,
'mfhi':asm_mfhi,
'mflo':asm_mflo,
'mthi': asm_mthi,
'mtlo': asm_mtlo,
#'mulo': asm_mulo,
'mult': asm_mult,
'nop': asm_nop,
'nor': asm_nor,
'or': asm_or,
'ori': asm_ori,
'sb': asm_sb,
'sh': asm_sh,
'sll': asm_sll,
'sllv': asm_sllv,
'slt': asm_slt,
'slti': asm_slti,
#'sltu': asm_sltu,
'srl': asm_srl,
'srlv': asm_srlv,
'sub': asm_sub,
'sw': asm_sw,
'xor': asm_xor,
'xori': asm_xori,
# pseudo
'nop' : asm_nop,
'li' : asm_li,
'mv' : asm_mv,
'not' : asm_not,
'neg' : asm_neg
}
3. 资源模块:resources.py
register = {'$a0': '00100', '$t5': '01101', '$gp': '11100',
'$0' : '00000', '$s3': '10011', '$s2': '10010',
'$s1': '10001', '$s0': '10000', '$s7': '10111',
'$s6': '10110', '$s5': '10101', '$s4': '10100',
'$ra': '11111', '$fp': '11110', '$v0': '00010',
'$v1': '00011', '$a3': '00111', '$a2': '00110',
'$a1': '00101', '$t8': '11000', '$t9': '11001',
'$t6': '01110', '$t7': '01111', '$t4': '01100',
'$sp': '11101', '$t2': '01010', '$t3': '01011',
'$t0': '01000', '$t1': '01001', '$at': '00001'}
reverse_register = {0:'$zero',1:'$at',2:'$v0',3:'$v1',4:'$a0',5:'$a1',6:'$a2',7:'$a3',8:'$t0',9:'$t1',10:'$t2',
11:'$t3',12:'$t4',13:'$t5',14:'$t6',15:'$t7',16:'$s0',17:'$s1',18:'$s2',19:'$s3',
20:'$s4',21:'$s5',22:'$s6',23:'$s7',24:'$t8',25:'$t9',26:'$k0',27:'$k1',28:'$gp',29:'$sp',30:'$fp',31:'$ra'}
IS = {
# 实现成类
# opcode IS
'bltz':{'type': 'I', 'opcode': 1, 'form': ['rs', 'label']},
'j' :{'type': 'I', 'opcode': 2, 'form': ['label']},
'jal' :{'type': 'I', 'opcode': 3, 'form': ['label']},
'beq' :{'type': 'I', 'opcode': 4, 'form': ['rs', 'rt', 'label']},
'bne' :{'type': 'I', 'opcode': 5, 'form': ['rs', 'rt', 'label']},
'blez':{'type': 'I', 'opcode': 6, 'form': ['rs', 'label']},
'bgtz':{},
'addi':{'type': 'I', 'opcode': 8, 'form': ['rt', 'rs', 'imm']},
'addiu':{},
'slti':{'type': 'I', 'opcode': 10, 'form': ['rt', 'rs', 'imm']},
'sltiu':{},
'andi':{'type': 'I', 'opcode': 12, 'form': ['rt', 'rs', 'imm']},
'ori' :{'type': 'I', 'opcode': 13, 'form': ['rt', 'rs', 'imm']},
'xori':{'type': 'I', 'opcode': 14, 'form': ['rt', 'rs', 'imm']},
'lui' :{'type': 'I', 'opcode': 15, 'form': ['rt', 'imm']},
'lb' :{'type': 'I', 'opcode': 32, 'form': ['rt', 'imm', 'rs']},
'lh' :{'type': 'I', 'opcode': 33, 'form': ['rt', 'imm', 'rs']},
'lw' :{'type': 'I', 'opcode': 35, 'form': ['rt', 'imm', 'rs']},
'sb' :{'type': 'I', 'opcode': 40, 'form': ['rt', 'imm', 'rs']},
'sh' :{'type': 'I', 'opcode': 41, 'form': ['rt', 'imm', 'rs']},
'sw' :{'type': 'I', 'opcode': 43, 'form': ['rt', 'imm', 'rs']},
# R IS
'sll' :{'type': 'R', 'opcode': 0, 'func': 0, 'form': ['rd', 'rt', 'shamt']},
'srl' :{'type': 'R', 'opcode': 0, 'func': 2, 'form': ['rd', 'rt', 'shamt']},
'sra' :{'type': 'R', 'opcode': 0, 'func': 3, 'form': ['rd', 'rt', 'shamt']},
'sllv':{'type': 'R', 'opcode': 0, 'func': 4, 'form': ['rd', 'rt', 'rs']},
'srlv':{'type': 'R', 'opcode': 0, 'func': 6, 'form': ['rd', 'rt', 'rs']},
'srav':{'type': 'R', 'opcode': 0, 'func': 7, 'form': ['rd', 'rt', 'rs']},
'jr' :{'type': 'R', 'opcode': 0, 'func': 8, 'form': ['rs']},
'jalr':{'type': 'R', 'opcode': 0, 'func': 9, 'form': ['rs']},
'mfhi':{'type': 'R', 'opcode': 0, 'func': 16, 'form': ['rs']},
'mthi':{'type': 'R', 'opcode': 0, 'func': 17, 'form': ['rs']},
'mflo':{'type': 'R', 'opcode': 0, 'func': 18, 'form': ['rs']},
'mtlo':{'type': 'R', 'opcode': 0, 'func': 19, 'form': ['rs']},
'mult':{'type': 'R', 'opcode': 0, 'func': 24, 'form': ['rs']},
'add' :{'type': 'R', 'opcode': 0, 'func': 32, 'form': ['rd', 'rs', 'rt']},
'sub' :{'type': 'R', 'opcode': 0, 'func': 34, 'form': ['rd', 'rs', 'rt']},
'and' :{'type': 'R', 'opcode': 0, 'func': 36, 'form': ['rd', 'rs', 'rt']},
'or' :{'type': 'R', 'opcode': 0, 'func': 37, 'form': ['rd', 'rs', 'rt']},
'xor' :{'type': 'R', 'opcode': 0, 'func': 38, 'form': ['rd', 'rs', 'rt']},
'nor' :{'type': 'R', 'opcode': 0, 'func': 39, 'form': ['rd', 'rs', 'rt']},
'slt' :{'type': 'R', 'opcode': 0, 'func': 42, 'form': ['rd', 'rs', 'rt']},
}
pseudoIS={
'nop' :{'type': 'P', 'instruction': 'addi $0, $0, 0'},
'li' :{'type': 'P', 'instruction': ''},
'mv' :{'type': 'P', 'instruction': ''},
'not' :{'type': 'P', 'instruction': ''},
'neg' :{'type': 'P', 'instruction': ''},
}