[gamecode] Generate instruction widths and types

Not everything is correct, but this is enough to get started on
supporting disassembly in the various tools and code generation in qfcc.
This commit is contained in:
Bill Currie 2022-01-05 22:33:59 +09:00
parent c9b2a740a0
commit c74cfb9bf6
2 changed files with 128 additions and 7 deletions

View file

@ -625,8 +625,8 @@ const v6p_opcode_t *PR_v6p_Opcode (pr_ushort_t opcode) __attribute__((const));
typedef struct opcode_s { typedef struct opcode_s {
const char *opname; const char *opname;
const char *mnemonic; const char *mnemonic;
int width; ///< number of components (1-4) int widths[3]; ///< component count for each argument (1-4)
int size; ///< component size in words (1-2) etype_t types[3]; ///< component type for each argument
const char *fmt; const char *fmt;
} opcode_t; } opcode_t;
extern const opcode_t pr_opcodes[512]; extern const opcode_t pr_opcodes[512];

View file

@ -42,25 +42,34 @@ branch_fmt=[
"%Ga[%sb]", "%Ga[%sb]",
"%Ga[%Gb]", "%Ga[%Gb]",
] ]
compare_ccc=[ "eq", "lt", "gt", None, "ne", "ge", "le", None] compare_ccc = [ "eq", "lt", "gt", None, "ne", "ge", "le", None]
type_tt=['I', 'F', 'L', 'D'] 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 = { all_formats = {
"opcode": "OP_ALL_{ss+1}", "opcode": "OP_ALL_{ss+1}",
"mnemonic": "all", "mnemonic": "all",
"opname": "all", "opname": "all",
"format": "%Ga, %gc", "format": "%Ga, %gc",
"widths": "{ss+1}, 0, 1",
"types": "ev_integer, ev_integer, ev_integer",
} }
any_formats = { any_formats = {
"opcode": "OP_ANY_{ss+1}", "opcode": "OP_ANY_{ss+1}",
"mnemonic": "any", "mnemonic": "any",
"opname": "any", "opname": "any",
"format": "%Ga, %gc", "format": "%Ga, %gc",
"widths": "{ss+1}, 0, 1",
"types": "ev_integer, ev_integer, ev_integer",
} }
bitops_formats = { bitops_formats = {
"opcode": "OP_{op_bit[oo].upper()}_I_{ss+1}", "opcode": "OP_{op_bit[oo].upper()}_I_{ss+1}",
"mnemonic": "{op_bit[oo]}", "mnemonic": "{op_bit[oo]}",
"opname": "{op_bit[oo]}", "opname": "{op_bit[oo]}",
"format": "{bit_fmt[oo]}", "format": "{bit_fmt[oo]}",
"widths": "{ss+1}, {ss+1}, {ss+1}",
"types": "ev_integer, ev_integer, ev_integer",
"args": { "args": {
"op_bit":["bitand", "bitor", "bitxor", "bitnot"], "op_bit":["bitand", "bitor", "bitxor", "bitnot"],
"bit_fmt": [ "bit_fmt": [
@ -76,6 +85,8 @@ boolops_formats = {
"mnemonic": "{op_bool[oo]}", "mnemonic": "{op_bool[oo]}",
"opname": "{op_bool[oo]}", "opname": "{op_bool[oo]}",
"format": "{bool_fmt[oo]}", "format": "{bool_fmt[oo]}",
"widths": "{ss+1}, {ss+1}, {ss+1}",
"types": "ev_integer, ev_integer, ev_integer",
"args": { "args": {
"op_bool":["and", "or", "xor", "not"], "op_bool":["and", "or", "xor", "not"],
"bool_fmt": [ "bool_fmt": [
@ -91,11 +102,19 @@ branch_formats = {
"mnemonic": "{op_cond[cc]}", "mnemonic": "{op_cond[cc]}",
"opname": "{op_cond[cc]}", "opname": "{op_cond[cc]}",
"format": "{cond_fmt[cc]}{branch_fmt[mm]}", "format": "{cond_fmt[cc]}{branch_fmt[mm]}",
"widths": "{cond_widths[cc]}",
"types": "ev_void, ev_void, ev_integer",
"args": { "args": {
"op_mode": "ABCD", "op_mode": "ABCD",
"op_cond": ["ifnot", "if", "jump", "call"], "op_cond": ["ifnot", "if", "jump", "call"],
"branch_fmt": branch_fmt, "branch_fmt": branch_fmt,
"cond_fmt": ["%Gc ", "%Gc ", "", ""], "cond_fmt": ["%Gc ", "%Gc ", "", ""],
"cond_widths": [
"0, 0, 1",
"0, 0, 1",
"0, 0, 0",
"0, 0, 0",
],
}, },
} }
branch2_formats = { branch2_formats = {
@ -103,28 +122,42 @@ branch2_formats = {
"mnemonic": "{op_cond[cc]}", "mnemonic": "{op_cond[cc]}",
"opname": "{op_cond[cc]}", "opname": "{op_cond[cc]}",
"format": "%Gc {branch_fmt[mm]}", "format": "%Gc {branch_fmt[mm]}",
"widths": "{cond_widths[cc]}",
"types": "ev_void, ev_void, ev_integer",
"args": { "args": {
"op_mode": "ABCD", "op_mode": "ABCD",
"op_cond": ["ifa", "ifbe", "ifb", "ifae"], "op_cond": ["ifa", "ifbe", "ifb", "ifae"],
"branch_fmt": branch_fmt, "branch_fmt": branch_fmt,
"cond_widths": [
"0, 0, 1",
"0, 0, 1",
"0, 0, 1",
"0, 0, 1",
],
}, },
} }
compare_formats = { compare_formats = {
"opcode": "OP_{op_cmp[ccc].upper()}_{cmp_type[tt]}_{ss+1}", "opcode": "OP_{op_cmp[ccc].upper()}_{cmp_type[tt]}_{ss+1}",
"mnemonic": "{op_cmp[ccc]}.{cmp_type[tt]}", "mnemonic": "{op_cmp[ccc]}.{cmp_type[tt]}",
"opname": "{op_cmp[ccc]}", "opname": "{op_cmp[ccc]}",
"widths": "{ss+1}, {ss+1}, {ss+1}",
"types": "{cmp_types[tt]}, {cmp_types[tt]}, ev_integer",
"args": { "args": {
"op_cmp": compare_ccc, "op_cmp": compare_ccc,
"cmp_type":type_tt, "cmp_type":type_tt,
"cmp_types":etype_tt,
}, },
} }
compare2_formats = { compare2_formats = {
"opcode": "OP_{op_cmp[ccc].upper()}_{cmp_type[t]}_{ss+1}", "opcode": "OP_{op_cmp[ccc].upper()}_{cmp_type[t]}_{ss+1}",
"mnemonic": "{op_cmp[ccc]}.{cmp_type[t]}", "mnemonic": "{op_cmp[ccc]}.{cmp_type[t]}",
"opname": "{op_cmp[ccc]}", "opname": "{op_cmp[ccc]}",
"widths": "{ss+1}, {ss+1}, {ss+1}",
"types": "{cmp_types[t]}, {cmp_types[t]}, ev_integer",
"args": { "args": {
"op_cmp": compare_ccc, "op_cmp": compare_ccc,
"cmp_type":['u', 'U'], "cmp_type":['u', 'U'],
"cmp_types":unsigned_t,
}, },
} }
convert_formats = { convert_formats = {
@ -132,8 +165,16 @@ convert_formats = {
"mnemonic": "conv.{op_conv[d*4+xx]}", "mnemonic": "conv.{op_conv[d*4+xx]}",
"opname": "conv", "opname": "conv",
"format": "%Ga %gc", "format": "%Ga %gc",
"widths": "1, 0, 1",
"types": "{cnv_types[xx][d]}, ev_invalid, {cnv_types[xx][1-d]}",
"args": { "args": {
"op_conv": ["IF", "LD", "uF", "UD", "FI", "DL", "Fu", "DU"], "op_conv": ["IF", "LD", "uF", "UD", "FI", "DL", "Fu", "DU"],
"cnv_types": [
["ev_integer", "ev_float"],
["ev_long", "ev_double"],
["ev_uinteger", "ev_float"],
["ev_ulong", "ev_double"],
],
}, },
} }
lea_formats = { lea_formats = {
@ -141,6 +182,8 @@ lea_formats = {
"mnemonic": "lea", "mnemonic": "lea",
"opname": "lea", "opname": "lea",
"format": "{lea_fmt[mm]}", "format": "{lea_fmt[mm]}",
"widths": "0, 0, 1",
"types": "ev_pointer, ev_pointer, ev_pointer",
"args": { "args": {
"op_mode": "ABCD", "op_mode": "ABCD",
"lea_fmt": [ "lea_fmt": [
@ -156,12 +199,16 @@ lea_e_formats = {
"mnemonic": "lea", "mnemonic": "lea",
"opname": "lea", "opname": "lea",
"format": "%Ga.%Gb(%Ec), %gc", "format": "%Ga.%Gb(%Ec), %gc",
"types": "ev_entity, ev_field, ev_pointer",
"widths": "0, 0, 1",
} }
load_formats = { load_formats = {
"opcode": "OP_LOAD_{op_mode[mm]}_{ss+1}", "opcode": "OP_LOAD_{op_mode[mm]}_{ss+1}",
"mnemonic": "load", "mnemonic": "load",
"opname": "load", "opname": "load",
"format": "{load_fmt[mm]}", "format": "{load_fmt[mm]}",
"widths": "0, 0, {ss+1}",
"types": "ev_void, ev_void, ev_void",
"args": { "args": {
"op_mode": "EBCD", "op_mode": "EBCD",
"load_fmt": [ "load_fmt": [
@ -176,9 +223,12 @@ mathops_formats = {
"opcode": "OP_{op_math[ooo].upper()}_{math_type[tt]}_{ss+1}", "opcode": "OP_{op_math[ooo].upper()}_{math_type[tt]}_{ss+1}",
"mnemonic": "{op_math[ooo]}.{math_type[tt]}", "mnemonic": "{op_math[ooo]}.{math_type[tt]}",
"opname": "{op_math[ooo]}", "opname": "{op_math[ooo]}",
"widths": "{ss+1}, {ss+1}, {ss+1}",
"types": "{math_types[tt]}, {math_types[tt]}, {math_types[tt]}",
"args": { "args": {
"op_math": ["mul", "div", "rem", "mod", "add", "sub", None, None], "op_math": ["mul", "div", "rem", "mod", "add", "sub", None, None],
"math_type":type_tt, "math_type":type_tt,
"math_types": etype_tt,
}, },
} }
memset_formats = { memset_formats = {
@ -186,6 +236,8 @@ memset_formats = {
"mnemonic": "memset.{op_memset[oo]}", "mnemonic": "memset.{op_memset[oo]}",
"opname": "memset", "opname": "memset",
"format": "{memset_fmt[oo]}", "format": "{memset_fmt[oo]}",
"widths": "0, 0, 0",
"types": "ev_integer, ev_void, ev_void",
"args": { "args": {
"op_memset": [None, "i", "p", "pi"], "op_memset": [None, "i", "p", "pi"],
"memset_fmt": [None, "%Ga, %sb, %gc", "%Ga, %Gb, %Gc", "%Ga, %sb, %Gc"], "memset_fmt": [None, "%Ga, %sb, %gc", "%Ga, %Gb, %Gc", "%Ga, %sb, %Gc"],
@ -196,6 +248,8 @@ move_formats = {
"mnemonic": "memset.{op_move[oo]}", "mnemonic": "memset.{op_move[oo]}",
"opname": "memset", "opname": "memset",
"format": "{move_fmt[oo]}", "format": "{move_fmt[oo]}",
"widths": "0, 0, 0",
"types": "ev_integer, ev_void, ev_void",
"args": { "args": {
"op_move": [None, "i", "p", "pi"], "op_move": [None, "i", "p", "pi"],
"move_fmt": [None, "%Ga, %sb, %gc", "%Ga, %Gb, %Gc", "%Ga, %sb, %Gc"], "move_fmt": [None, "%Ga, %sb, %gc", "%Ga, %Gb, %Gc", "%Ga, %sb, %Gc"],
@ -206,12 +260,16 @@ none_formats = {
"mnemonic": "none", "mnemonic": "none",
"opname": "none", "opname": "none",
"format": "%Ga, %gc", "format": "%Ga, %gc",
"widths": "{ss+1}, 0, 1",
"types": "ev_integer, ev_invalid, ev_integer",
} }
push_formats = { push_formats = {
"opcode": "OP_PUSH_{op_mode[mm]}_{ss+1}", "opcode": "OP_PUSH_{op_mode[mm]}_{ss+1}",
"mnemonic": "push", "mnemonic": "push",
"opname": "push", "opname": "push",
"format": "{push_fmt[mm]}", "format": "{push_fmt[mm]}",
"widths": "{ss+1}, 0, 0",
"types": "ev_void, ev_void, ev_invalid",
"args": { "args": {
"op_mode": "ABCD", "op_mode": "ABCD",
"push_fmt": [ "push_fmt": [
@ -226,6 +284,8 @@ pushregs_formats = {
"opcode": "OP_PUSHREGS", "opcode": "OP_PUSHREGS",
"mnemonic": "pushregs", "mnemonic": "pushregs",
"opname": "pushregs", "opname": "pushregs",
"widths": "0, 0, 0",
"types": "ev_invalid, ev_invalid, ev_invalid",
"format": None, "format": None,
} }
pop_formats = { pop_formats = {
@ -233,6 +293,8 @@ pop_formats = {
"mnemonic": "pop", "mnemonic": "pop",
"opname": "pop", "opname": "pop",
"format": "{pop_fmt[mm]}", "format": "{pop_fmt[mm]}",
"widths": "{ss+1}, 0, 0",
"types": "ev_void, ev_void, ev_invalid",
"args": { "args": {
"op_mode": "ABCD", "op_mode": "ABCD",
"pop_fmt": [ "pop_fmt": [
@ -247,23 +309,34 @@ popregs_formats = {
"opcode": "OP_POPREGS", "opcode": "OP_POPREGS",
"mnemonic": "popregs", "mnemonic": "popregs",
"opname": "popregs", "opname": "popregs",
"widths": "0, 0, 0",
"format": None, "format": None,
"types": "ev_invalid, ev_invalid, ev_invalid",
} }
scale_formats = { scale_formats = {
"opcode": "OP_SCALE_{scale_type[t]}_{ss+1}", "opcode": "OP_SCALE_{scale_type[t]}_{ss+1}",
"mnemonic": "scale.{scale_type[t]}", "mnemonic": "scale.{scale_type[t]}",
"opname": "scale", "opname": "scale",
"widths": "{ss+1}, 1, {ss+1}",
"types": "{scale_types[t]}, {scale_types[t]}, {scale_types[t]}",
"args": { "args": {
"scale_type":['F', 'D'], "scale_type": ['F', 'D'],
"scale_types": float_t,
}, },
} }
shiftops_formats = { shiftops_formats = {
"opcode": "OP_{op_shift[u*2+r].upper()}_{shift_type[u*2+t]}_{ss+1}", "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]}", "mnemonic": "{op_shift[u*2+r]}.{shift_type[u*2+t]}",
"opname": "{op_shift[u*2+r]}", "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": { "args": {
"op_shift": ["shl", "asr", "shl", "shr"], "op_shift": ["shl", "asr", "shl", "shr"],
"shift_type":['I', 'L', 'u', 'U'], "shift_type": ['I', 'L', 'u', 'U'],
"shift_types": [
["ev_integer", "ev_uinteger"],
["ev_long", "ev_ulong"],
],
}, },
} }
state_formats = { state_formats = {
@ -271,9 +344,12 @@ state_formats = {
"mnemonic": "state.{state[t]}", "mnemonic": "state.{state[t]}",
"opname": "state", "opname": "state",
"format": "{state_fmt[t]}", "format": "{state_fmt[t]}",
"widths": "1, 1, 1",
"types": "ev_float, ev_func, {state_types[t]}",
"args": { "args": {
"state": ["ft", "ftt"], "state": ["ft", "ftt"],
"state_fmt": ["%Ga, %Gb", "%Ga, %Gb, %Gc"], "state_fmt": ["%Ga, %Gb", "%Ga, %Gb, %Gc"],
"state_types": ["ev_invalid", "ev_float"],
}, },
} }
store_formats = { store_formats = {
@ -281,6 +357,8 @@ store_formats = {
"mnemonic": "store", "mnemonic": "store",
"opname": "store", "opname": "store",
"format": "{store_fmt[mm]}", "format": "{store_fmt[mm]}",
"widths": "{ss+1}, 0, {ss+1}",
"types": "ev_void, ev_void, ev_void",
"args": { "args": {
"op_mode": "ABCD", "op_mode": "ABCD",
"store_fmt": [ "store_fmt": [
@ -296,6 +374,8 @@ string_formats = {
"mnemonic": "{op_str[o*4+oo]}.s", "mnemonic": "{op_str[o*4+oo]}.s",
"opname": "{op_str[o*4+oo]}", "opname": "{op_str[o*4+oo]}",
"format": "{str_fmt[o*4+oo]}", "format": "{str_fmt[o*4+oo]}",
"widths": "1, 1, 1",
"types": "{str_types[o*4+oo]}",
"args": { "args": {
"op_str": ["eq", "lt", "gt", "add", "cmp", "ge", "le", "not"], "op_str": ["eq", "lt", "gt", "add", "cmp", "ge", "le", "not"],
"str_fmt": [ "str_fmt": [
@ -308,6 +388,16 @@ string_formats = {
"%Ga, %Gb, %gc", "%Ga, %Gb, %gc",
"%Ga, %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 = { swizzle_formats = {
@ -315,8 +405,11 @@ swizzle_formats = {
"mnemonic": "swizzle.{swiz_type[t]}", "mnemonic": "swizzle.{swiz_type[t]}",
"opname": "swizzle", "opname": "swizzle",
"format": "%Ga %sb %gc", "format": "%Ga %sb %gc",
"widths": "4, 0, 4",
"types": "{swizzle_types[t]}",
"args": { "args": {
"swiz_type":['F', 'D'], "swiz_type": ['F', 'D'],
"swizzle_types": float_t,
}, },
} }
rcall_formats = { rcall_formats = {
@ -324,6 +417,8 @@ rcall_formats = {
"mnemonic": "rcall{nnn+1}", "mnemonic": "rcall{nnn+1}",
"opname": "rcall{nnn+1}", "opname": "rcall{nnn+1}",
"format": "{rcall_fmt[nnn]}", "format": "{rcall_fmt[nnn]}",
"widths": "0, 0, 0",
"types": "ev_func, ev_void, ev_void",
"args": { "args": {
"rcall_fmt": [ "rcall_fmt": [
"%Fa (%P0b)", "%Fa (%P0b)",
@ -341,31 +436,51 @@ return_formats = {
"opcode": "OP_RETURN_{ss+1}", "opcode": "OP_RETURN_{ss+1}",
"mnemonic": "return{ss+1}", "mnemonic": "return{ss+1}",
"opname": "return{ss+1}", "opname": "return{ss+1}",
"widths": "0, 0, 0",
"format": "%Ra", "format": "%Ra",
"types": "ev_void, ev_invalid, ev_invalid",
} }
returnv_formats = { returnv_formats = {
"opcode": "OP_RETURN_0", "opcode": "OP_RETURN_0",
"mnemonic": "return", "mnemonic": "return",
"opname": "return", "opname": "return",
"widths": "0, 0, 0",
"format": None, "format": None,
"types": "ev_invalid, ev_invalid, ev_invalid",
} }
vecops_formats = { vecops_formats = {
"opcode": "OP_{op_vop[ooo].upper()}_{vop_type[t]}", "opcode": "OP_{op_vop[ooo].upper()}_{vop_type[t]}",
"mnemonic": "{op_vop[ooo]}.{vop_type[t]}", "mnemonic": "{op_vop[ooo]}.{vop_type[t]}",
"opname": "{op_vop[ooo]}", "opname": "{op_vop[ooo]}",
"widths": "{vec_widths[ooo]}",
"types": "{vec_types[t]}, {vec_types[t]}, {vec_types[t]}",
"args": { "args": {
"op_vop": ["cdot", "vdot", "qdot", "cross", "op_vop": ["cdot", "vdot", "qdot", "cross",
"cmul", "qvmul", "vqmul", "qmul"], "cmul", "qvmul", "vqmul", "qmul"],
"vop_type": ['F', 'D'], "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 = { vecops2_formats = {
"opcode": "OP_{op_vop[dd].upper()}_{vop_type[t]}", "opcode": "OP_{op_vop[dd].upper()}_{vop_type[t]}",
"mnemonic": "{op_vop[dd]}.{vop_type[t]}", "mnemonic": "{op_vop[dd]}.{vop_type[t]}",
"opname": "{op_vop[dd]}", "opname": "{op_vop[dd]}",
"widths": "4, 4, 4",
"types": "{vec_types[t]}, {vec_types[t]}, {vec_types[t]}",
"args": { "args": {
"op_vop": [None, "qv4mul", "v4qmul", None], "op_vop": [None, "qv4mul", "v4qmul", None],
"vop_type": ['F', 'D'], "vop_type": ['F', 'D'],
"vec_types": float_t,
}, },
} }
with_formats = { with_formats = {
@ -373,6 +488,8 @@ with_formats = {
"mnemonic": "with", "mnemonic": "with",
"opname": "with", "opname": "with",
"format": "%sa, %sb, $sc", "format": "%sa, %sb, $sc",
"widths": "0, 0, 0",
"types": "ev_void, ev_void, ev_void",
} }
group_map = { group_map = {
@ -475,6 +592,8 @@ def process_opcode(opcode, group):
else: else:
fmt = f'"{fmt}"' fmt = f'"{fmt}"'
inst["fmt"] = fmt inst["fmt"] = fmt
inst["wd"] = "{%s}" % eval(f'''f"{gm['widths']}"''', params)
inst["ty"] = "{%s}" % eval(f'''f"{gm['types']}"''', params)
lines = bitmap_txt.split('\n') lines = bitmap_txt.split('\n')
for l in lines: for l in lines:
@ -499,5 +618,7 @@ for i, group in enumerate(opcodes):
print(eval('f"[{op}] = {{\\n' print(eval('f"[{op}] = {{\\n'
'\\t.opname = {on},\\n' '\\t.opname = {on},\\n'
'\\t.mnemonic = {mn},\\n' '\\t.mnemonic = {mn},\\n'
'\\t.widths = {wd},\\n'
'\\t.types = {ty},\\n'
'\\t.fmt = {fmt},\\n' '\\t.fmt = {fmt},\\n'
'}},"', group)) '}},"', group))