bitmap_txt = """ 0 0000 mmss load 0 0001 mmss store 0 0010 mmss push 0 0011 mmss pop 0 1ccc ttss compare 0 0000 00nn 0 0000 0000 noop 0 0000 0001 adjstk 0 0000 0010 constant 0 1011 nnnn 0 1111 nnnn 1 0ooo ttss mathops 1 011r tuss shiftops 1 0110 o1oo string 1 1ccc t0ss compare2 1 1t00 ooss bitops 1 1001 01mm jump 1 1001 11mm call (return specified st->c) 1 1001 1100 return (size in st->c) 1 1010 t1ss scale 1 1010 t100 swizzle 1 1011 tooo vecops 1 1101 01oo move 1 1101 11oo memset 1 1101 c111 statef 1 1110 c1cc branch 1 1110 c111 stated 1 1111 00mm lea 1 1111 01td vecops2 1 1111 10nn 1 1111 1100 convert (conversion mode in st->b) 1 1111 1101 with (mode in st->a, value in st->b, reg in st->c) 1 1111 1110 1 1111 1111 hops """ import copy address_mode = "ABCD" address_types = [ "ev_void, ev_invalid", "ev_entity, ev_field", "ev_ptr, ev_short", "ev_ptr, ev_int", ] address_widths = [ [ "1, 0", "1, 1", "1, 0", "1, 1", ], [ "2, 0", "1, 1", "1, 0", "1, 1", ], [ "3, 0", "1, 1", "1, 0", "1, 1", ], [ "4, 0", "1, 1", "1, 0", "1, 1", ], [ "-1, 0", "1, 1", "1, 0", "1, 1", ], ] #store, pop and lea store_fmt = [ "%ga", "%Ga.%Gb(%Ea)", "*(%Ga + %sb)", "*(%Ga + %Gb)", ] # load and push load_fmt = [ "*%Ga, %gc", "%Ga.%Gb(%Ea)", "*(%Ga + %sb)", "*(%Ga + %Gb)", ] 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_int", "ev_float", "ev_long", "ev_double"] unsigned_t = ["ev_uint", "ev_ulong"] float_t = ["ev_float", "ev_double"] adjstk_formats = { "opcode": "OP_ADJSTK", "mnemonic": "adjstk", "opname": "adjstk", "format": "%sa, %sb", "widths": "0, 0, 0", "types": "ev_short, ev_short, ev_invalid", } 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_int", "ev_long"], "bit_fmt": [ "%Ga, %Gb, %gc", "%Ga, %Gb, %gc", "%Ga, %Gb, %gc", "%Ga, %gc", ], }, } branch_formats = { "opcode": "OP_{op_cond[c*4+cc].upper()}", "mnemonic": "{op_cond[c*4+cc]}", "opname": "{op_cond[c*4+cc]}", "format": "{cond_fmt[c*4+cc]}{branch_fmt[0]}", "widths": "0, 0, 1", "types": "ev_short, ev_invalid, ev_int", "args": { "op_mode": "ABCD", "op_cond": ["ifz", "ifb", "ifa", None, "ifnz", "ifae", "ifbe", None], "branch_fmt": branch_fmt, "cond_fmt": ["%Gc ", "%Gc ", "%Gc ", "", "%Gc ", "%Gc ", "%Gc ", ""], }, } call_formats = { "opcode": "OP_CALL_{op_mode[mm]}", "mnemonic": "call", "opname": "call", "format": "{call_fmt[mm]}", "widths": "{call_widths[mm]}, -1", "types": "{call_types[mm]}, ev_void", "args": { "op_mode": ".BCD", "call_fmt": [ None, # return handled seprately "%Ga, %gc", "%Ga[%sb], %gc", "%Ga[%Gb], %gc", ], "call_types": [ None, "ev_void, ev_invalid", "ev_ptr, ev_short", "ev_ptr, ev_int", ], "call_widths": [ None, "1, 0", "1, 0", "1, 1" ] }, } 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_int", "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_int", "args": { "op_cmp": compare_ccc, "cmp_type": ['u', 'U'], "cmp_types": unsigned_t, }, } constant_formats = { "opcode": "OP_LDCONST", "mnemonic": "ldconst", "opname": "ldconst", "format": "%sa, %sb, %gc", "widths": "0, 0, -1", "types": "ev_short, ev_short, ev_void", } convert_formats = { "opcode": "OP_CONV", "mnemonic": "conv", "opname": "conv", "format": "%Ga %Cb %gc", "widths": "-1, 0, -1", "types": "ev_void, ev_short, ev_void", } hops_formats = { "opcode": "OP_HOPS", "mnemonic": "hops", "opname": "hops", "format": "%Ga %Hb %gc", "widths": "-1, 0, 1", "types": "ev_void, ev_short, ev_void", } jump_formats = { "opcode": "OP_JUMP_{op_mode[mm]}", "mnemonic": "jump", "opname": "jump", "format": "{jump_fmt[mm]}", "widths": "{jump_widths[mm]}, 0", "types": "{jump_types[mm]}", "args": { "op_mode": "ABCD", "jump_fmt": branch_fmt, "jump_types": [ "ev_short, ev_invalid, ev_invalid", "ev_ptr, ev_invalid, ev_invalid", "ev_ptr, ev_short, ev_invalid", "ev_ptr, ev_int, ev_invalid", ], "jump_widths": [ "0, 0", "1, 0", "1, 0", "1, 1" ] }, } lea_formats = { "opcode": "OP_LEA_{op_mode[mm]}", "mnemonic": "lea", "opname": "lea", "format": "{lea_fmt[mm]}, %gc", "widths": "{lea_widths[mm]}, 1", "types": "{lea_types[mm]}, ev_ptr", "args": { "op_mode": address_mode, "lea_fmt": store_fmt, "lea_types": address_types, "lea_widths": address_widths[4], }, } load_formats = { "opcode": "OP_LOAD_{op_mode[mm]}_{ss+1}", "mnemonic": "load", "opname": "load", "format": "{load_fmt[mm]}, %gc", "widths": "{load_widths[ss][mm]}, {ss+1}", "types": "{load_types[mm]}, ev_void", "args": { "op_mode": address_mode, "load_fmt": load_fmt, "load_types": address_types, "load_widths": address_widths, }, } 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": "{memset_widths[oo]}", "types": "ev_int, ev_void, ev_void", "args": { "op_memset": ["i", "p", "pi", None], "memset_fmt": ["%Ga, %sb, %gc", "%Ga, %Gb, %Gc", "%Ga, %sb, %Gc", None], "memset_widths": [ "1, 0, -1", "1, 1, 1", "1, 0, 1", None, ], }, } move_formats = { "opcode": "OP_MOVE_{op_move[oo].upper()}", "mnemonic": "memset.{op_move[oo]}", "opname": "memset", "format": "{move_fmt[oo]}", "widths": "{move_widths[oo]}", "types": "ev_int, ev_void, ev_void", "args": { "op_move": ["i", "p", "pi", None], "move_fmt": ["%Ga, %sb, %gc", "%Ga, %Gb, %Gc", "%Ga, %sb, %Gc", None], "move_widths": [ "-1, 0, -1", "1, 1, 1", "1, 0, 1", None, ], }, } noop_formats = { "opcode": "OP_NOP", "mnemonic": "nop", "opname": "nop", "format": "there were plums...", "widths": "0, 0, 0", "types": "ev_invalid, ev_invalid, ev_invalid", } push_formats = { "opcode": "OP_PUSH_{op_mode[mm]}_{ss+1}", "mnemonic": "push", "opname": "push", "format": "{push_fmt[mm]}", "widths": "{ss+1}, 0, 0", "types": "{push_types[mm]}, ev_invalid", "args": { "op_mode": address_mode, "push_fmt": load_fmt, "push_types": address_types, }, } 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": "{pop_types[mm]}, ev_invalid", "args": { "op_mode": address_mode, "pop_fmt": store_fmt, "pop_types": address_types, }, } 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_int", "ev_uint"], ["ev_long", "ev_ulong"], ], }, } statef_formats = { "opcode": "OP_STATE_{state[c]}", "mnemonic": "state.{state[c]}", "opname": "state", "format": "{state_fmt[c]}", "widths": "1, 1, {c}", "types": "ev_float, ev_func, {state_types[c]}", "args": { "state": ["ft", "ftt"], "state_fmt": ["%Ga, %Gb", "%Ga, %Gb, %Gc"], "state_types": ["ev_invalid", "ev_float"], }, } stated_formats = { "opcode": "OP_STATE_{state[c]}", "mnemonic": "state.{state[c]}", "opname": "state", "format": "{state_fmt[c]}", "widths": "1, 1, {c}", "types": "ev_float, ev_func, {state_types[c]}", "args": { "state": ["dt", "dtt"], "state_fmt": ["%Ga, %Gb", "%Ga, %Gb, %Gc"], "state_types": ["ev_invalid", "ev_double"], }, } store_formats = { "opcode": "OP_STORE_{op_mode[mm]}_{ss+1}", "mnemonic": "{store_op[mm]}", "opname": "{store_op[mm]}", "format": "%Gc, {store_fmt[mm]}", "widths": "{store_widths[ss][mm]}, {ss+1}", "types": "{store_types[mm]}, ev_void", "args": { "op_mode": address_mode, "store_fmt": store_fmt, "store_op": ["assign", "store", "store", "store"], "store_types": address_types, "store_widths": address_widths, }, } 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, {(o*4+oo)<7 and 1 or 0}, 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_int", "ev_string, ev_string, ev_int", "ev_string, ev_string, ev_int", "ev_string, ev_string, ev_string", "ev_string, ev_string, ev_int", "ev_string, ev_string, ev_int", "ev_string, ev_string, ev_int", "ev_string, ev_invalid, ev_int", ], }, } 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": "-1, -1, 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[d].upper()}_{vop_type[t]}", "mnemonic": "{op_vop[d]}.{vop_type[t]}", "opname": "{op_vop[d]}", "widths": "4, 4, 4", "types": "{vec_types[t]}, {vec_types[t]}, {vec_types[t]}", "args": { "op_vop": ["qv4mul", "v4qmul"], "vop_type": ['F', 'D'], "vec_types": float_t, }, } with_formats = { "opcode": "OP_WITH", "mnemonic": "with", "opname": "with", "format": "%sa, %sb, %sc", "widths": "0, -1, 0", "types": "ev_short, ev_void, ev_short", } group_map = { "adjstk": adjstk_formats, "bitops": bitops_formats, "branch": branch_formats, "call": call_formats, "compare": compare_formats, "compare2": compare2_formats, "constant": constant_formats, "convert": convert_formats, "hops": hops_formats, "jump": jump_formats, "lea": lea_formats, "load": load_formats, "mathops": mathops_formats, "memset": memset_formats, "move": move_formats, "noop": noop_formats, "push": push_formats, "pushregs": pushregs_formats, "pop": pop_formats, "popregs": popregs_formats, "scale": scale_formats, "shiftops": shiftops_formats, "statef": statef_formats, "stated": stated_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<