Пример #1
0
def parse_insts(f):
	"""
		从文件中解析出所有的指令,生成 Inst 对象并加入到 insts 列表中
		假设 ins 文件中指令系统部分不会出现 \xff,故以此为循环结束条件
	"""
	tmp_data = handle_00_byte(f)
	log(f"开始解析指令部分,当前文件指针的位置为 {f.tell()}")
	while tmp_data != b'\xff':
		try:
			mnemonic_len = read(f)[0]
			tmp_mnemonic = ''.join([
				read(f).decode('ascii') for _ in range(mnemonic_len)
			])
			tmp_addr = read(f)[0]
			op_num1 = op_num_map[read(f)]
			op_num2 = op_num_map[read(f)]
			tmp_inst = Inst(tmp_mnemonic, tmp_addr, op_num1, op_num2)

			log(f"解析出指令 {tmp_inst}")
			insts.append(tmp_inst)
			handle_int_inst(f, tmp_mnemonic)
			tmp_data = handle_00_byte(f)
		except Exception as err:
			error(f"解析失败,原因 {err}")
	log("指令部分解析结束")
Пример #2
0
def decode(self):
    """Instruction decoder. Returns the number of bytes decoded."""
    inst = Inst(myInput = self.input, add = self.pc, mode = self.dis_mode, syntax = self.syntax)
    self.error = 0
    self.input.start ()
    if get_prefixes(self, inst) != 0:
        pass # ;print('prefixes error') # error 
    elif search_itab(self, inst) != 0:
        pass #; print('itab error') # error 
    elif do_mode(self, inst) != 0:
        pass #; print('mode error') # error 
    elif disasm_operands(self, inst) != 0:
        pass #; print('operand error') # error 
    elif resolve_operator(self, inst) != 0:
        pass #; print('operator error') # error 
    # Handle decode error.
    if self.error:
        inst.clear()
    inst.size = self.input.ctr + 1
    inst.raw = self.input.buffer[0:inst.size]
    inst.set_pc(inst.add + inst.size)
    return inst
Пример #3
0
def load_fd(fd):
    offsets = {
        'const': len(const_table),
        'label': len(label_table),
        'inst': len(inst_table),
    }

    # constants block
    num_constants = read_int(fd)
    for _ in range(0, num_constants):
        const = read_constant(fd)
        const_table.register(const)

    # symbols block
    num_symbols = read_int(fd)
    symbol_translation = [0] * num_symbols
    for i in range(0, num_symbols):
        val = read_str(fd)
        symbol_translation[i] = sym(val)

    num_labels = read_int(fd)
    for _ in range(0, num_labels):
        name = read_str(fd)
        addr = read_int(fd) + offsets['inst']
        trace = None
        has_trace = read_int(fd)
        trace = None
        if has_trace == 1: trace = read_str(fd)
        label = Label(name, addr, trace)
        register_label(label)

    num_insts = read_int(fd)
    for i in range(0, num_insts):
        command = read_str(fd)
        num_args = read_int(fd)
        raw_args = [999] * num_args
        for i in range(0, num_args):
            raw_args[i] = read_int(fd)
        inst_type = inst_type_table.get(command)
        args = inst_type.reindex(raw_args, offsets, symbol_translation)
        inst_table.register(Inst(inst_type.id, args))
Пример #4
0
def filter_change(origin_inst, dump_file_content, base, newcode, line_index,
                  reversal_bit_id):
    """Compare the origin inst and redisassember inst, and record the changed part
    @:return: It currently presents the judgment of operands' different
    """
    tmp_result2 = code_line_reg.findall(dump_file_content)
    if not tmp_result2:
        logging.warning("generated file %s has no legal content" % newcode)
    tmp_line = tmp_result2[line_index]
    tmp_inst = Inst(tmp_line)
    # confirm opcode part
    if tmp_inst.op != origin_inst.op:
        logging.info(
            "Opcode changes: %s => %s when bit [%d] is flipped from [%d]\t\tChange to:%s",
            origin_inst.op, tmp_inst.op, reversal_bit_id,
            (base >> reversal_bit_id) & 0x1, tmp_line[0])

        # bits = bits | (((base >> i) & 0x1) << i)
        origin_inst.opcode_positions.append(reversal_bit_id)
    # confirm modifier part
    elif tmp_inst.modifier != origin_inst.modifier:
        logging.info(
            "Modifier changes: %s => %s when bit [%d] is flipped from [%d]\t\tChange to:%s",
            origin_inst.modifier, tmp_inst.modifier, reversal_bit_id,
            (base >> reversal_bit_id) & 0x1, tmp_line[0])
        origin_inst.modifier_positions.append(reversal_bit_id)
    else:
        len_origin = len(origin_inst.operands)
        len_tmp = len(tmp_inst.operands)

        for i in range(min(len_origin, len_tmp)):
            if origin_inst.operands[i] != tmp_inst.operands[i]:
                return i, tmp_inst
        # if len_tmp > len_origin:
        #     return len_origin
    return None, None
Пример #5
0
def work(input_file_name, output_file, section_start):
    global sass_content, ops_bits

    arch = "sm_75"
    # for debug
    # input_file_name = 'gaussian.cubin'
    init_sass_cubin_files(input_file_name, arch)
    logging.basicConfig(format="%(message)s",
                        filename="./log/%s" % output_file,
                        filemode="a",
                        level=logging.INFO)
    logging.info("Time:\t%s" %
                 time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))

    com_lib.kernel_section_start_offset = int(section_start, 16)

    with open("%s.sass" % os.path.splitext(input_file_name)[0], 'r') as fin:
        sass_content = fin.read()
    tmp_result = code_line_reg.findall(sass_content)
    if not tmp_result:
        logging.error("Not found pairs")
        return
    # @todo: check is there any irregular code
    # how many lines will be checked.
    for j, line in enumerate(tmp_result[:1]):
        logging.info("================================")
        logging.info("raw line:\t\t%s" % line[0])
        a_origin_inst = Inst(line)
        instructions.append(a_origin_inst)

        base = a_origin_inst.enc
        bits = 0x0
        origin_operand_types = check_operand_types(a_origin_inst)
        if FLAG_CHECK_OPERAND:
            if len(a_origin_inst.operands) and origin_operand_types:
                logging.info(
                    "Original op and modifier:%s:\t%s" %
                    (a_origin_inst.op, "".join(a_origin_inst.modifier)))
                logging.info("0b{:0128b}".format(base) + ": " +
                             "".join(a_origin_inst.operands))
                logging.info("newcode operand:")
            # if you just want to check operand, uncomment the following else branch
            else:
                continue
        # In volta and turing, len of the instruction code is 128bitk
        for i in range(0, 128):
            # i from right to left
            mask = 2**i
            newcode = base ^ mask
            dump_file_content = dump("0x{:032x}".format(newcode), arch, j)

            # print(dump_file_content)
            # Compare the disassemble to check which field changes: opcode, operand or modifer
            if dump_file_content and dump_file_content.find(
                    "?") == -1 and dump_file_content.find("error") == -1:
                tmp_pp, tmp_inst = filter_change(a_origin_inst,
                                                 dump_file_content, base,
                                                 newcode, j, i)
                if tmp_pp is not None:
                    # the ith bit affects tmp_ppth operand
                    a_origin_inst.operand_positions[tmp_pp].append(i)
                    # @todo print the reverse bit
                    logging.info("%s: %d\t%s" %
                                 ("0b{:0128b}".format(newcode), i, " ".join(
                                     tmp_inst.operands)))
            # if len(positions) > 0:
            #     logging.info("0b{:0128b}".format(bits) + ": %s opcode bits %s: ", origin_inst.op, positions)

        if len(a_origin_inst.opcode_positions) > 0:
            ops_bits[a_origin_inst.op] = list(
                set(
                    ops_bits.get(a_origin_inst.op, []) +
                    a_origin_inst.opcode_positions))
        logging.info("Operand combination types: %s", origin_operand_types)
        for i in range(0, len(a_origin_inst.operand_positions)):
            if len(origin_operand_types) > i:
                tmp_type = origin_operand_types[i]
            else:
                tmp_type = 'None'
            logging.info("Operand type: %s", tmp_type)
            logging.info("Encoding: %s", a_origin_inst.operand_positions[i])

    for node in ops_bits:
        logging.info("%s:\t[%s]", node,
                     ",".join(str(x) for x in ops_bits[node]))
Пример #6
0
from sets import Set
from inst import Inst
import subprocess
import sys

if __name__ == "__main__":
    opset = Set([])
    with open(sys.argv[1]) as f:
        for line in f:
            field = line.split()
            inst = Inst(field, False)
            if not inst.op() in opset:
                opset.add(inst.op())
                sys.stdout.write(line)
Пример #7
0
 if len(sys.argv) >= 5:
     limit = sys.argv[4]
 else:
     limit = 100
 count = 0
 version = int(arch.split("_")[1])
 with open(sass) as f:
     for line in f:
         pos = []
         bits = 0x0
         count += 1
         if count == limit:
             break
         line_split = line.split()
         # Construct instruction structure
         origin = Inst(line_split)
         # Find the 64-bit encodings
         base = int(origin.enc(), 16)
         # Bit by bit xor, observe whether opcode changes and guess what this bit represent
         for i in range(0, 64):
             mask = 2**i
             newcode = base ^ mask
             # Disassemble the new code
             dump_file = dump("0x{:016x}".format(newcode), arch)
             # Compare the disassemble to check which field changes: opcode, operand or modifer
             if dump_file and dump_file.find("?") == -1 and dump_file.find(
                     "error") == -1:
                 line = dump_file.split("\n")
                 if version < 40:
                     line_inst = line[1].split()
                 else:
Пример #8
0
from inst import Inst, asm, print_asm, print_ihex

rd = []
for i in range(50):
    rd.append(i)

rs = []
for i in range(50):
    rs.append(i)

seg_pattern = [0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xBE,0xE0,0xFE,0xF6]

program = [
    Inst.LUI(5,0x10001000),
]

for i in range(10):
    program.append(Inst.ADDI(rd[6],rs[0],seg_pattern[i]))
    program.append(Inst.SB(rd[5],rs[6],i))

program_main = [    
    Inst.LUI(rd[6], 0x04000000),
    Inst.ADD(rd[7],rs[0],rs[0]), 
    Inst.LW(rd[10], rs[6], 0x48),
    'mainloop',
    Inst.ADD(rd[8],rs[7],rs[5]),
    Inst.ANDI(rd[11],rs[10],0x01),
    Inst.LBEQ(rd[11],0,'dontpush'),

    'push',
    Inst.LBU(rd[9],rs[8],0),
Пример #9
0
from inst import Inst, asm, print_asm, print_ihex

program = [
Inst.LUI(5, 0x10000000), # memory = 0x10000000
Inst.ADD(6, 0, 0), # x6 = 0 (counter)
'loop',
Inst.SW(5, 6, 0x100), # memory[x5+0x100] = x6
Inst.ADDI(6, 6, 1), # x6++
Inst.LJAL(0, 'loop') # goto loop
]

r = asm(program)
print_asm(r)
print()
print_ihex(r)
Пример #10
0
from inst import Inst, asm, print_asm, print_ihex

program = [
    Inst.LUI(5, 0x04000000),  # r5 に7 セグのアドレスを代入
    Inst.ADDI(10, 0, 0x60),  # セグ「1」のパタンをr10 に代入
    Inst.SB(5, 10, 0x00),  # r5[0] = 0x60 (7 セグのアドレスに0x60 をストア)
    Inst.JAL(0, -4 * 1)  # 1 命令前に無条件分岐
]

r = asm(program)
print_asm(r)
print()
print_ihex(r)
Пример #11
0
_score2		= 22
_counterX	= 23
_intervalX	= 24
_counterY	= 25
_intervalY	= 26

_memAddr	= 27
_memBase	= 28
_count		= 29
_tmp2		= 30

# 初期化部分
sys_init = [

Inst.LUI(_addrBase, 0x0400_0000),			# addrBase = [0x0400_0000]
Inst.ADDI(_wr, _num0, 1),					# wr = 1
Inst.SLLI(_wr, _wr, 14),					# wr <<= 14
Inst.ADDI(_barY1u, _num0, 1),				# barY1u = 1
Inst.ADDI(_barY1d, _num0, 2),				# barY1d = 2
Inst.ADDI(_barY2u, _num0, 1),				# barY2u = 1
Inst.ADDI(_barY2d, _num0, 2),				# barY2d = 2
Inst.ADDI(_velX, _num0, 1),					# velX = 1
Inst.ADDI(_velY, _num0, 1),					# velY = 1
Inst.ADDI(_score1, _num0, 0),				# score1 = 0
Inst.ADDI(_score2, _num0, 0),				# score2 = 0
Inst.ADDI(_counterX, _num0, 0),				# counterX = 0
Inst.ADDI(_counterY, _num0, 0),				# counterY = 0
Inst.ADDI(_intervalX, _num0, 3),			# interval = 1
Inst.ADDI(_intervalY, _num0, 3),			# interval = 1
Inst.ADDI(_num1, _num0, 1),					# num1 = 1
Пример #12
0
def bin_decode(bin_line):
    if bin_line == '0':
        inst = Inst()
        d = {
            "op": "pass",
            "dests": [],
            "srcs": []
        }
        inst.fromDict(d)
        return inst
    op_bits = bin_line[:op_bit]
    dests = []
    srcs = []

    op = code.op_inv[int(op_bits, 2)]
    start_point = op_bit
    for i in range(3):
        ns_bits = bin_line[start_point:start_point + ns_bit]
        ns = code.ns_inv[int(ns_bits, 2)]
        if ns == "NN":
            pe_pu_bit = bin_line[start_point + ns_bit + index_bit + nn_nb_bit - 1]
            if pe_pu_bit == '0':
                ns = "NN0_out"
            else:
                ns = "NN1_out"
        elif ns == "NB":
            pe_pu_bit = bin_line[start_point + ns_bit + index_bit + nn_nb_bit - 1]
            if pe_pu_bit == '0':
                ns = "NB0_out"
            else:
                ns = "NB1_out"
        index_bits = bin_line[start_point + ns_bit:start_point + ns_bit + index_bit]
        index = int(index_bits, 2)
        dest = {
            "dest_nid": ns,
            "dest_index": index
            }
        dests.append(dest)
        start_point += (ns_bit + index_bit + nn_nb_bit)
    for i in range(3):
        ns_bits = bin_line[start_point:start_point + ns_bit]
        ns = code.ns_inv[int(ns_bits, 2)]
        if ns == "NN":
            pe_pu_bit = bin_line[start_point + ns_bit + index_bit + nn_nb_bit - 1]
            if pe_pu_bit == '0':
                ns = "NN0_in"
            else:
                ns = "NN1_in"
        elif ns == "NB":
            pe_pu_bit = bin_line[start_point + ns_bit + index_bit + nn_nb_bit - 1]
            if pe_pu_bit == '0':
                ns = "NB0_in"
            else:
                ns = "NB1_in"
        index_bits = bin_line[start_point + ns_bit:start_point + ns_bit + index_bit]
        index = int(index_bits, 2)
        src = {
            "src_nid": ns,
            "src_index": index
            }
        srcs.append(src)
        start_point += (ns_bit + index_bit + nn_nb_bit)
    inst = Inst()
    d = {
        "op": op,
        "dests": dests,
        "srcs": srcs
        }
    inst.fromDict(d)
    return inst        
Пример #13
0
# 0~9をループするカウンタ
## わかっているクソ仕様
## SBを一回使用した後にADDIを実行すると機能しない。
## これを回避するためにはダミーのSBが必要。

from inst import Inst, asm, print_asm, print_ihex

program = [
    # Store 7seg led patterns
    Inst.LUI(5, 0x10001000),  # memory = 0x10001000
    Inst.ADDI(6, 0, 0b11111100),  # 7seg: 0
    Inst.SB(5, 6, 0x0),
    Inst.SB(5, 6, 0x1),  #dummySB
    Inst.ADDI(6, 0, 0b01100000),  # 1
    Inst.SB(5, 6, 0x1),
    Inst.SB(5, 6, 0x2),  #dummySB
    Inst.ADDI(6, 0, 0b11011010),  # 2
    Inst.SB(5, 6, 0x2),
    Inst.SB(5, 6, 0x3),  #dummySB
    Inst.ADDI(6, 0, 0b11110010),  # 3
    Inst.SB(5, 6, 0x3),
    Inst.SB(5, 6, 0x4),  #dummySB
    Inst.ADDI(6, 0, 0b01100110),  # 4
    Inst.SB(5, 6, 0x4),
    Inst.SB(5, 6, 0x5),  #dummySB
    Inst.ADDI(6, 0, 0b10110110),  # 5
    Inst.SB(5, 6, 0x5),
    Inst.SB(5, 6, 0x6),  #dummySB
    Inst.ADDI(6, 0, 0b10111110),  # 6
    Inst.SB(5, 6, 0x6),
    Inst.SB(5, 6, 0x7),  #dummySB
Пример #14
0
 def disassemble(self, add):
     try:
         self.seek(add)
         return self.decode()
     except DecodeException:
         return Inst(self.input)
Пример #15
0
from inst import Inst, asm, print_asm, print_ihex

seg_pattern = [0xFC, 0x60, 0xDA, 0xF2, 0x66, 0xB6, 0xBE, 0xE0, 0xFE, 0xF6]

x_0 = 0
pattern_mem = 5
pattern_tmp = 6

program = [Inst.LUI(pattern_mem, 0x10001000)]

for i in range(10):
    print(seg_pattern[i])
    program.append(Inst.ADDI(pattern_tmp, 0, seg_pattern[i]))
    program.append(Inst.SB(pattern_mem, pattern_tmp, i))

seg = 6
counter = 7
pattern_mem_addr = 8
pattern = 9
max = 15

program_main = [
    'main',
    Inst.LUI(seg, 0x04000000),
    Inst.ADDI(counter, x_0, 0),
    Inst.ADDI(max, x_0, 9), 'loop',
    Inst.ADD(pattern_mem_addr, counter, pattern_mem),
    Inst.LBU(pattern, pattern_mem_addr, 0),
    Inst.SB(seg, pattern, 0),
    Inst.ADDI(counter, counter, 1),
    Inst.LBEQ(counter, max, 'reset'),
Пример #16
0
from inst import Inst, asm, print_asm, print_ihex

program = [
# Store 7seg led patterns
Inst.LUI(5, 0x10001000), # memory = 0x10001000
Inst.ADDI(6, 0, 0b11111100), # 7seg: 0
Inst.SB(5, 6, 0x0),
Inst.ADDI(6, 0, 0b01100000), # 1
Inst.SB(5, 6, 0x1),
Inst.ADDI(6, 0, 0b11011010), # 2
Inst.SB(5, 6, 0x2),
Inst.ADDI(6, 0, 0b11110010), # 3
Inst.SB(5, 6, 0x3),
Inst.ADDI(6, 0, 0b01100110), # 4
Inst.SB(5, 6, 0x4),
Inst.ADDI(6, 0, 0b10110110), # 5
Inst.SB(5, 6, 0x5),
Inst.ADDI(6, 0, 0b10111110), # 6
Inst.SB(5, 6, 0x6),
Inst.ADDI(6, 0, 0b11100000), # 7
Inst.SB(5, 6, 0x7),
Inst.ADDI(6, 0, 0b11111110), # 8
Inst.SB(5, 6, 0x8),
Inst.ADDI(6, 0, 0b11110110), # 9
Inst.SB(5, 6, 0x9),
# Main
Inst.LUI(6, 0x04000000),
Inst.ADD(7, 0, 0), # x7 = 0 (counter)
’loop’,
Inst.ADD(8, 7, 5), # address of memory[x7]
Inst.LBU(9, 8, 0), # x9 = memory[x7]
Пример #17
0
#! /usr/bin/env python3

from inst import Inst

filename = 'sample1_7seg.hex'

program = []
program.append(Inst.LUI(5, 0x04000000))
program.append(Inst.ADDI(10, 0, 0xff))
program.append(Inst.SB(5, 10, 0x00))
program.append(Inst.JAL(0, -4 * 2))

# generate assembly
#print('')
print('sample program 1')
for i in program:
    print('{:08x} | {}'.format(i.gen_code(), i.gen_mnemonic()))

# generate intel hex format
with open(filename, 'w', encoding='utf-8') as file:
    for offset, inst in enumerate(program):
        file.write(inst.gen_HEX(offset))
        file.write("\n")
    file.write(':00000001FF\n')
Пример #18
0
 arch = sys.argv[2]
 if len(sys.argv) >= 5:
     limit = sys.argv[4]
 else:
     limit = 100
 count = 0
 version = int(arch.split("_")[1])
 with open(sass) as f:
     for line in f:
         pos = []
         count += 1
         if count == limit:
             break
         line_split = line.split()
         # Construct instruction structure
         origin = Inst(line_split)
         # Find the 64-bit encodings
         base = int(origin.enc(), 16)
         # Bit by bit xor, observe whether opcode changes and guess what this bit represent
         for i in range(0, 64):
             mask = 2**i
             newcode = base ^ mask
             # Disassemble the new code
             dump_file = dump("0x{:016x}".format(newcode), arch)
             # Compare the disassemble to check which field changes: opcode, operand or modifer
             if dump_file and dump_file.find("?") == -1 and dump_file.find(
                     "error") == -1:
                 line = dump_file.split("\n")
                 if version < 40:
                     line_inst = line[1].split()
                 else:
Пример #19
0
 arch = sys.argv[2]
 if len(sys.argv) >= 5:
     limit = sys.argv[4]
 else:
     limit = 100
 count = 0
 version = int(arch.split("_")[1])
 with open(sys.argv[1]) as f:
     for line in f:
         pos = []
         count += 1
         if count == limit:
             break
         line_split = line.split()
         # Construct instruction structure
         origin = Inst(line_split)
         # Find the 64-bit encodings
         base = int(origin.enc(), 16)
         origin_operand_types = check_operand_types(origin)
         if len(origin.operands()) and origin_operand_types.find('X') == -1:
             pp = [[] for i in range(len(origin_operand_types))]
             logging.info(origin.op() + " " + origin.modifier())
             logging.info("0b{:064b}".format(base) + ": " +
                          origin.operands())
             for i in range(0, 64):
                 mask = 2**i
                 newcode = base ^ mask
                 # Disassemble the new code
                 dump_file = dump("0x{:016x}".format(newcode), arch)
                 if dump_file and dump_file.find(
                         "?") == -1 and dump_file.find("error") == -1:
Пример #20
0
from inst import Inst, asm, print_asm, print_ihex

program = [
    Inst.LUI(5, 0x04000000),
    Inst.ADDI(6, 0, 0xFF),
    Inst.LW(10, 5, 0x48),
    Inst.ANDI(11, 10, 0x01),
    Inst.BEQ(11, 0, 0x08),
    Inst.SB(5, 6, 0x000),
    Inst.JAL(0, 4),
    Inst.SB(5, 0, 0x000),
    Inst.JAL(0, -28)
]

r = asm(program)
print_asm(r)
print()
print_ihex(r)