mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-14 08:50:58 +00:00
2b82533526
This has been a long-held wishlist item, really, and I thought I might as well take the opportunity to add the instructions. The double versions of STATE require both the nextthink field and time global to be double (but they're not resolved properly yet: marked with "FIXME double time" comments). Also, the frame number for double time state is integer rather than float.
616 lines
17 KiB
Python
616 lines
17 KiB
Python
bitmap_txt = """
|
|
0 0000 mmss load
|
|
0 0001 mmss store
|
|
0 0010 mmss push
|
|
0 0011 mmss pop
|
|
0 1ccc ttss compare
|
|
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
|
|
|
|
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[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": "{cond_widths[c*4+cc]}",
|
|
"types": "ev_void, ev_void, ev_integer",
|
|
"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 ", ""],
|
|
"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",
|
|
}
|
|
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": "{branch_fmt[mm]}",
|
|
"widths": "0, 0, 0",
|
|
"types": "ev_void, ev_void, ev_invalid",
|
|
"args": {
|
|
"op_mode": "ABCD",
|
|
"branch_fmt": branch_fmt,
|
|
},
|
|
}
|
|
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": "AECD",
|
|
"lea_fmt": [
|
|
"%ga, %gc",
|
|
"%Ga.%Gb(%Ea), %gc",
|
|
"*(%Ga + %sb), %gc",
|
|
"*(%Ga + %Gb), %gc",
|
|
],
|
|
},
|
|
}
|
|
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": ["i", "p", "pi", None],
|
|
"memset_fmt": ["%Ga, %sb, %gc", "%Ga, %Gb, %Gc", "%Ga, %sb, %Gc", None],
|
|
},
|
|
}
|
|
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": ["i", "p", "pi", None],
|
|
"move_fmt": ["%Ga, %sb, %gc", "%Ga, %Gb, %Gc", "%Ga, %sb, %Gc", None],
|
|
},
|
|
}
|
|
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"],
|
|
],
|
|
},
|
|
}
|
|
statef_formats = {
|
|
"opcode": "OP_STATE_{state[c]}",
|
|
"mnemonic": "state.{state[c]}",
|
|
"opname": "state",
|
|
"format": "{state_fmt[c]}",
|
|
"widths": "1, 1, 1",
|
|
"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, 1",
|
|
"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",
|
|
"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[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, 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,
|
|
"hops": hops_formats,
|
|
"jump": jump_formats,
|
|
"lea": lea_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,
|
|
"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<<len(block)):
|
|
if group is not None:
|
|
expand_opcodes(bits, group + f",{block}={n}", num | n)
|
|
else:
|
|
expand_opcodes(bits, group, num | n)
|
|
|
|
|
|
def process_opcode(opcode, group):
|
|
data = group.split(',')
|
|
params = {}
|
|
for d in data[1:]:
|
|
p = d.split('=')
|
|
params[p[0]] = int(p[1])
|
|
gm = group_map[data[0]]
|
|
if "args" in gm:
|
|
params.update(gm["args"])
|
|
inst = {}
|
|
opcodes[opcode] = inst
|
|
#print(f"{opcode:03x}", group)
|
|
inst["op"] = eval(f'''f"{gm['opcode']}"''', params)
|
|
mn = eval(f'''f"{gm['mnemonic']}"''', params)
|
|
inst["mn"] = f'"{mn}"'
|
|
on = eval(f'''f"{gm['opname']}"''', params)
|
|
inst["on"] = f'"{on}"'
|
|
fmt = "%Ga, %Gb, %gc"
|
|
if "format" in gm:
|
|
if gm["format"] is not None:
|
|
fmt = eval(f'''f"{gm['format']}"''', params)
|
|
else:
|
|
fmt = None
|
|
if fmt is None:
|
|
fmt = "0"
|
|
else:
|
|
fmt = f'"{fmt}"'
|
|
inst["fmt"] = fmt
|
|
inst["wd"] = "{%s}" % eval(f'''f"{gm['widths']}"''', params)
|
|
inst["ty"] = "{%s}" % eval(f'''f"{gm['types']}"''', params)
|
|
|
|
import sys
|
|
|
|
if len (sys.argv) < 2 or sys.argv[1] not in ["enum", "table"]:
|
|
sys.stderr.write ("specify output type: enum or table\n")
|
|
sys.exit(1)
|
|
|
|
lines = bitmap_txt.split('\n')
|
|
for l in lines:
|
|
l = l.strip()
|
|
if not l or l[0] == '#':
|
|
continue
|
|
c = l.split(' ')
|
|
bits = "".join(c[0:3])
|
|
group = c[3:] and c[3] or None
|
|
descr = ' '.join(c[4:])
|
|
#print(bits, group, descr)
|
|
#print(parse_bits(bits))
|
|
expand_opcodes(parse_bits(bits), group)
|
|
for i, group in enumerate(opcodes):
|
|
if group is not None:
|
|
process_opcode (i, group)
|
|
if sys.argv[1] == "enum":
|
|
N = 4
|
|
W = 15
|
|
for i in range(len(opcodes)//N):
|
|
row = opcodes[i * N:i * N + N]
|
|
#row = map(lambda op: (op and op["op"] or f"OP_spare_{i}"), row)
|
|
row = [(op and op["op"] or f"OP_spare_{i*N+x}")
|
|
for x, op in enumerate(row)]
|
|
row = map(lambda op: f"%-{W}.{W}s" % (op + ','), row)
|
|
if sys.argv[2:3] == ["debug"]:
|
|
print("%03x" % (i << 3), " ".join(row))
|
|
else:
|
|
print(" ".join(row))
|
|
elif sys.argv[1] == "table":
|
|
for i, group in enumerate(opcodes):
|
|
if group is not None:
|
|
print(eval('f"[{op}] = {{\\n'
|
|
'\\t.opname = {on},\\n'
|
|
'\\t.mnemonic = {mn},\\n'
|
|
'\\t.widths = {wd},\\n'
|
|
'\\t.types = {ty},\\n'
|
|
'\\t.fmt = {fmt},\\n'
|
|
'}},"', group))
|