bitmap_txt = """ 0 0000 mmss load 0 0001 mmss store 0 0010 mmss push 0 0011 mmss pop 0 010c ccmm branch # while call and return are part of the branch block, they have different # handling for addressing and formatting 0 0101 11mm call (return specified st->c) 0 0101 1100 return (size in st->c) 0 0110 0nnn 0 0110 1100 convert (conversion mode in st->b) 0 0110 1101 with (mode in st->a, value in st->b, reg in st->c) 0 0110 111t state 0 0111 tooo vecops 0 1ccc ttss compare 1 0ooo ttss mathops 1 011r tuss shiftops 1 0110 o1oo string 1 1ccc t0ss compare2 1 1001 t1ss scale 1 1001 t100 swizzle 1 1010 d1xx 1 1011 00mm lea 1 1011 01ss any 1 1011 0100 lea_e 1 1011 10ss all 1 1011 1000 pushregs 1 1011 11ss none 1 1011 1100 popregs 1 1101 01oo move 1 1101 11oo memset 1 1110 d1xx 1 11dd t100 vecops2 1 1t00 ooss bitops n 1111 nnnn 0 1011 nnnn """ import copy load_fmt = [ "%Ga.%Gb(%Ea), %gc", "*%Ga, %gc", "*(%Ga + %sb), %gc", "*(%Ga + %Gb), %gc", ] branch_fmt = [ "branch %sa (%Oa)", "*%Ga", "%Ga[%sb]", "%Ga[%Gb]", ] compare_ccc = [ "eq", "lt", "gt", None, "ne", "ge", "le", None] type_tt = ['I', 'F', 'L', 'D'] etype_tt = ["ev_integer", "ev_float", "ev_long", "ev_double"] unsigned_t = ["ev_uinteger", "ev_ulong"] float_t = ["ev_float", "ev_double"] all_formats = { "opcode": "OP_ALL_{ss+1}", "mnemonic": "all", "opname": "all", "format": "%Ga, %gc", "widths": "{ss+1}, 0, 1", "types": "ev_integer, ev_integer, ev_integer", } any_formats = { "opcode": "OP_ANY_{ss+1}", "mnemonic": "any", "opname": "any", "format": "%Ga, %gc", "widths": "{ss+1}, 0, 1", "types": "ev_integer, ev_integer, ev_integer", } bitops_formats = { "opcode": "OP_{op_bit[oo].upper()}_{bit_type[t]}_{ss+1}", "mnemonic": "{op_bit[oo]}", "opname": "{op_bit[oo]}", "format": "{bit_fmt[oo]}", "widths": "{ss+1}, {ss+1}, {ss+1}", "types": "{bit_types[t]}, {bit_types[t]}, {bit_types[t]}", "args": { "op_bit": ["bitand", "bitor", "bitxor", "bitnot"], "bit_type": ["I", "L"], "bit_types": ["ev_integer", "ev_long"], "bit_fmt": [ "%Ga, %Gb, %gc", "%Ga, %Gb, %gc", "%Ga, %Gb, %gc", "%Ga, %gc", ], }, } branch_formats = { "opcode": "OP_{op_cond[ccc].upper()}_{op_mode[mm]}", "mnemonic": "{op_cond[ccc]}", "opname": "{op_cond[ccc]}", "format": "{cond_fmt[ccc]}{branch_fmt[mm]}", "widths": "{cond_widths[ccc]}", "types": "ev_void, ev_void, ev_integer", "args": { "op_mode": "ABCD", "op_cond": ["ifz", "ifb", "ifa", "jump", "ifnz", "ifae", "ifbe", None], #call and return seprate "branch_fmt": branch_fmt, "cond_fmt": ["%Gc ", "%Gc ", "%Gc ", "", "%Gc ", "%Gc ", "%Gc ", ""], "cond_widths": [ "0, 0, 1", "0, 0, 1", "0, 0, 1", "0, 0, 0", "0, 0, 1", "0, 0, 1", "0, 0, 1", "0, 0, 0", ], }, } call_formats = { "opcode": "OP_CALL_{op_mode[mm]}", "mnemonic": "call", "opname": "call", "format": "{call_fmt[mm]}", "widths": "0, 0, 0", "types": "ev_void, ev_void, ev_void", "args": { "op_mode": ".BCD", "call_fmt": [ None, # return handled seprately "%Ga, %gc", "%Ga[%sb], %gc", "%Ga[%Gb], %gc", ], }, } compare_formats = { "opcode": "OP_{op_cmp[ccc].upper()}_{cmp_type[tt]}_{ss+1}", "mnemonic": "{op_cmp[ccc]}.{cmp_type[tt]}", "opname": "{op_cmp[ccc]}", "widths": "{ss+1}, {ss+1}, {ss+1}", "types": "{cmp_types[tt]}, {cmp_types[tt]}, ev_integer", "args": { "op_cmp": compare_ccc, "cmp_type": type_tt, "cmp_types": etype_tt, }, } compare2_formats = { "opcode": "OP_{op_cmp[ccc].upper()}_{cmp_type[t]}_{ss+1}", "mnemonic": "{op_cmp[ccc]}.{cmp_type[t]}", "opname": "{op_cmp[ccc]}", "widths": "{ss+1}, {ss+1}, {ss+1}", "types": "{cmp_types[t]}, {cmp_types[t]}, ev_integer", "args": { "op_cmp": compare_ccc, "cmp_type": ['u', 'U'], "cmp_types": unsigned_t, }, } convert_formats = { "opcode": "OP_CONV", "mnemonic": "conv", "opname": "conv", "format": "%Ga %Cb %gc", "widths": "1, 0, 1", "types": "ev_void, ev_short, ev_void", } lea_formats = { "opcode": "OP_LEA_{op_mode[mm]}", "mnemonic": "lea", "opname": "lea", "format": "{lea_fmt[mm]}", "widths": "0, 0, 1", "types": "ev_pointer, ev_pointer, ev_pointer", "args": { "op_mode": "ABCD", "lea_fmt": [ "%ga, %gc", "*%Ga, %gc", "*(%Ga + %sb), %gc", "*(%Ga + %Gb), %gc", ], }, } lea_e_formats = { "opcode": "OP_LEA_E", "mnemonic": "lea", "opname": "lea", "format": "{load_fmt[0]}", "format": "%Ga.%Gb(%Ea), %gc", "types": "ev_entity, ev_field, ev_pointer", "widths": "0, 0, 1", } load_formats = { "opcode": "OP_LOAD_{op_mode[mm]}_{ss+1}", "mnemonic": "load", "opname": "load", "format": "{load_fmt[mm]}", "widths": "0, 0, {ss+1}", "types": "ev_void, ev_void, ev_void", "args": { "op_mode": "EBCD", "load_fmt": load_fmt, }, } mathops_formats = { "opcode": "OP_{op_math[ooo].upper()}_{math_type[tt]}_{ss+1}", "mnemonic": "{op_math[ooo]}.{math_type[tt]}", "opname": "{op_math[ooo]}", "widths": "{ss+1}, {ss+1}, {ss+1}", "types": "{math_types[tt]}, {math_types[tt]}, {math_types[tt]}", "args": { "op_math": ["mul", "div", "rem", "mod", "add", "sub", None, None], "math_type": type_tt, "math_types": etype_tt, }, } memset_formats = { "opcode": "OP_MEMSET_{op_memset[oo].upper()}", "mnemonic": "memset.{op_memset[oo]}", "opname": "memset", "format": "{memset_fmt[oo]}", "widths": "0, 0, 0", "types": "ev_integer, ev_void, ev_void", "args": { "op_memset": [None, "i", "p", "pi"], "memset_fmt": [None, "%Ga, %sb, %gc", "%Ga, %Gb, %Gc", "%Ga, %sb, %Gc"], }, } move_formats = { "opcode": "OP_MOVE_{op_move[oo].upper()}", "mnemonic": "memset.{op_move[oo]}", "opname": "memset", "format": "{move_fmt[oo]}", "widths": "0, 0, 0", "types": "ev_integer, ev_void, ev_void", "args": { "op_move": [None, "i", "p", "pi"], "move_fmt": [None, "%Ga, %sb, %gc", "%Ga, %Gb, %Gc", "%Ga, %sb, %Gc"], }, } none_formats = { "opcode": "OP_NONE_{ss+1}", "mnemonic": "none", "opname": "none", "format": "%Ga, %gc", "widths": "{ss+1}, 0, 1", "types": "ev_integer, ev_invalid, ev_integer", } push_formats = { "opcode": "OP_PUSH_{op_mode[mm]}_{ss+1}", "mnemonic": "push", "opname": "push", "format": "{push_fmt[mm]}", "widths": "{ss+1}, 0, 0", "types": "ev_void, ev_void, ev_invalid", "args": { "op_mode": "ABCD", "push_fmt": [ "%Ga", "*%Ga", "*(%Ga + %sb)", "*(%Ga + %Gb)", ], }, } pushregs_formats = { "opcode": "OP_PUSHREGS", "mnemonic": "pushregs", "opname": "pushregs", "widths": "0, 0, 0", "types": "ev_invalid, ev_invalid, ev_invalid", "format": None, } pop_formats = { "opcode": "OP_POP_{op_mode[mm]}_{ss+1}", "mnemonic": "pop", "opname": "pop", "format": "{pop_fmt[mm]}", "widths": "{ss+1}, 0, 0", "types": "ev_void, ev_void, ev_invalid", "args": { "op_mode": "ABCD", "pop_fmt": [ "%ga", "*%Ga", "*(%Ga + %sb)", "*(%Ga + %Gb)", ], }, } popregs_formats = { "opcode": "OP_POPREGS", "mnemonic": "popregs", "opname": "popregs", "widths": "0, 0, 0", "format": None, "types": "ev_invalid, ev_invalid, ev_invalid", } scale_formats = { "opcode": "OP_SCALE_{scale_type[t]}_{ss+1}", "mnemonic": "scale.{scale_type[t]}", "opname": "scale", "widths": "{ss+1}, 1, {ss+1}", "types": "{scale_types[t]}, {scale_types[t]}, {scale_types[t]}", "args": { "scale_type": ['F', 'D'], "scale_types": float_t, }, } shiftops_formats = { "opcode": "OP_{op_shift[u*2+r].upper()}_{shift_type[u*2+t]}_{ss+1}", "mnemonic": "{op_shift[u*2+r]}.{shift_type[u*2+t]}", "opname": "{op_shift[u*2+r]}", "widths": "{ss+1}, {ss+1}, {ss+1}", "types": "{shift_types[t][u]}, {shift_types[t][0]}, {shift_types[t][u]}", "args": { "op_shift": ["shl", "asr", "shl", "shr"], "shift_type": ['I', 'L', 'u', 'U'], "shift_types": [ ["ev_integer", "ev_uinteger"], ["ev_long", "ev_ulong"], ], }, } state_formats = { "opcode": "OP_STATE_{state[t]}", "mnemonic": "state.{state[t]}", "opname": "state", "format": "{state_fmt[t]}", "widths": "1, 1, 1", "types": "ev_float, ev_func, {state_types[t]}", "args": { "state": ["ft", "ftt"], "state_fmt": ["%Ga, %Gb", "%Ga, %Gb, %Gc"], "state_types": ["ev_invalid", "ev_float"], }, } store_formats = { "opcode": "OP_STORE_{op_mode[mm]}_{ss+1}", "mnemonic": "store", "opname": "store", "format": "{store_fmt[mm]}", "widths": "{ss+1}, 0, {ss+1}", "types": "ev_void, ev_void, ev_void", "args": { "op_mode": "ABCD", "store_fmt": [ "%Gc, %ga", "%Gc, *%Ga", "%Gc, *(%Ga + %sb)", "%Gc, *(%Ga + %Gb)", ], }, } string_formats = { "opcode": "OP_{op_str[o*4+oo].upper()}_S", "mnemonic": "{op_str[o*4+oo]}.s", "opname": "{op_str[o*4+oo]}", "format": "{str_fmt[o*4+oo]}", "widths": "1, 1, 1", "types": "{str_types[o*4+oo]}", "args": { "op_str": ["eq", "lt", "gt", "add", "cmp", "ge", "le", "not"], "str_fmt": [ "%Ga, %Gb, %gc", "%Ga, %Gb, %gc", "%Ga, %Gb, %gc", "%Ga, %Gb, %gc", "%Ga, %Gb, %gc", "%Ga, %Gb, %gc", "%Ga, %Gb, %gc", "%Ga, %gc", ], "str_types": [ "ev_string, ev_string, ev_integer", "ev_string, ev_string, ev_integer", "ev_string, ev_string, ev_integer", "ev_string, ev_string, ev_string", "ev_string, ev_string, ev_integer", "ev_string, ev_string, ev_integer", "ev_string, ev_string, ev_integer", "ev_string, ev_invalid, ev_integer", ], }, } swizzle_formats = { "opcode": "OP_SWIZZLE_{swiz_type[t]}", "mnemonic": "swizzle.{swiz_type[t]}", "opname": "swizzle", "format": "%Ga %sb %gc", "widths": "4, 0, 4", "types": "{swizzle_types[t]}", "args": { "swiz_type": ['F', 'D'], "swizzle_types": float_t, }, } return_formats = { "opcode": "OP_RETURN", "mnemonic": "return", "opname": "return", "widths": "0, 0, 0", # width specified by st->c "format": "FIXME", "types": "ev_void, ev_void, ev_void", } vecops_formats = { "opcode": "OP_{op_vop[ooo].upper()}_{vop_type[t]}", "mnemonic": "{op_vop[ooo]}.{vop_type[t]}", "opname": "{op_vop[ooo]}", "widths": "{vec_widths[ooo]}", "types": "{vec_types[t]}, {vec_types[t]}, {vec_types[t]}", "args": { "op_vop": ["cross", "cdot", "vdot", "qdot", "cmul", "qvmul", "vqmul", "qmul"], "vop_type": ['F', 'D'], "vec_widths": [ "2, 2, 2", "3, 3, 3", "4, 4, 4", "3, 3, 3", "2, 2, 2", "4, 3, 3", "3, 4, 3", "4, 4, 4", ], "vec_types": float_t, }, } vecops2_formats = { "opcode": "OP_{op_vop[dd].upper()}_{vop_type[t]}", "mnemonic": "{op_vop[dd]}.{vop_type[t]}", "opname": "{op_vop[dd]}", "widths": "4, 4, 4", "types": "{vec_types[t]}, {vec_types[t]}, {vec_types[t]}", "args": { "op_vop": [None, "qv4mul", "v4qmul", None], "vop_type": ['F', 'D'], "vec_types": float_t, }, } with_formats = { "opcode": "OP_WITH", "mnemonic": "with", "opname": "with", "format": "%sa, %sb, %sc", "widths": "0, 0, 0", "types": "ev_void, ev_void, ev_void", } group_map = { "all": all_formats, "any": any_formats, "bitops": bitops_formats, "branch": branch_formats, "call": call_formats, "compare": compare_formats, "compare2": compare2_formats, "convert": convert_formats, "lea": lea_formats, "lea_e": lea_e_formats, "load": load_formats, "mathops": mathops_formats, "memset": memset_formats, "move": move_formats, "none": none_formats, "push": push_formats, "pushregs": pushregs_formats, "pop": pop_formats, "popregs": popregs_formats, "scale": scale_formats, "shiftops": shiftops_formats, "state": state_formats, "store": store_formats, "string": string_formats, "swizzle": swizzle_formats, "return": return_formats, "vecops": vecops_formats, "vecops2": vecops2_formats, "with": with_formats, } def parse_bits(bit_string): bits = [""] isbit = bit_string[0] in ['0', '1'] lastbit = bit_string[0] while bit_string: bit = bit_string[0] bit_string = bit_string[1:] if isbit and bit in ['0', '1']: bits[-1] = bits[-1] + bit elif lastbit == bit: bits[-1] = bits[-1] + bit else: bits.append(bit) lastbit = bit isbit = bit in ['0', '1'] return bits opcodes = [None] * 512 def expand_opcodes(bits, group, num=0): if not bits: opcodes[num] = group return block = bits[0] bits = bits[1:] num <<= len(block) if block[0] in ['0', '1']: num |= int(block, 2) expand_opcodes(bits, group, num) else: for n in range(1<