mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-29 12:10:48 +00:00
completely nuke the concept of "priority" from opcodes and use get_op_string
in emit_sub_expr instead of a redundant switch.
This commit is contained in:
parent
f029687ff0
commit
f8a41cb1bc
7 changed files with 133 additions and 228 deletions
|
@ -179,7 +179,6 @@ typedef struct
|
|||
const char *name;
|
||||
const char *opname;
|
||||
pr_opcode_e opcode;
|
||||
int priority;
|
||||
qboolean right_associative;
|
||||
etype_t type_a, type_b, type_c;
|
||||
int min_version;
|
||||
|
|
|
@ -46,128 +46,128 @@ static const char rcsid[] =
|
|||
hashtab_t *opcode_table;
|
||||
|
||||
opcode_t pr_opcodes[] = {
|
||||
{"<DONE>", "done", OP_DONE, -1, false, ev_entity, ev_field, ev_void, PROG_ID_VERSION},
|
||||
{"<DONE>", "done", OP_DONE, false, ev_entity, ev_field, ev_void, PROG_ID_VERSION},
|
||||
|
||||
{"*", "mul.f", OP_MUL_F, 2, false, ev_float, ev_float, ev_float, PROG_ID_VERSION},
|
||||
{"*", "mul.v", OP_MUL_V, 2, false, ev_vector, ev_vector, ev_float, PROG_ID_VERSION},
|
||||
{"*", "mul.fv", OP_MUL_FV, 2, false, ev_float, ev_vector, ev_vector, PROG_ID_VERSION},
|
||||
{"*", "mul.vf", OP_MUL_VF, 2, false, ev_vector, ev_float, ev_vector, PROG_ID_VERSION},
|
||||
{"*", "mul.f", OP_MUL_F, false, ev_float, ev_float, ev_float, PROG_ID_VERSION},
|
||||
{"*", "mul.v", OP_MUL_V, false, ev_vector, ev_vector, ev_float, PROG_ID_VERSION},
|
||||
{"*", "mul.fv", OP_MUL_FV, false, ev_float, ev_vector, ev_vector, PROG_ID_VERSION},
|
||||
{"*", "mul.vf", OP_MUL_VF, false, ev_vector, ev_float, ev_vector, PROG_ID_VERSION},
|
||||
|
||||
{"/", "div.f", OP_DIV_F, 2, false, ev_float, ev_float, ev_float, PROG_ID_VERSION},
|
||||
{"/", "div.f", OP_DIV_F, false, ev_float, ev_float, ev_float, PROG_ID_VERSION},
|
||||
|
||||
{"+", "add.f", OP_ADD_F, 3, false, ev_float, ev_float, ev_float, PROG_ID_VERSION},
|
||||
{"+", "add.v", OP_ADD_V, 3, false, ev_vector, ev_vector, ev_vector, PROG_ID_VERSION},
|
||||
{"+", "add.s", OP_ADD_S, 3, false, ev_string, ev_string, ev_string, PROG_VERSION},
|
||||
{"+", "add.f", OP_ADD_F, false, ev_float, ev_float, ev_float, PROG_ID_VERSION},
|
||||
{"+", "add.v", OP_ADD_V, false, ev_vector, ev_vector, ev_vector, PROG_ID_VERSION},
|
||||
{"+", "add.s", OP_ADD_S, false, ev_string, ev_string, ev_string, PROG_VERSION},
|
||||
|
||||
{"-", "sub.f", OP_SUB_F, 3, false, ev_float, ev_float, ev_float, PROG_ID_VERSION},
|
||||
{"-", "sub.v", OP_SUB_V, 3, false, ev_vector, ev_vector, ev_vector, PROG_ID_VERSION},
|
||||
{"-", "sub.f", OP_SUB_F, false, ev_float, ev_float, ev_float, PROG_ID_VERSION},
|
||||
{"-", "sub.v", OP_SUB_V, false, ev_vector, ev_vector, ev_vector, PROG_ID_VERSION},
|
||||
|
||||
{"==", "eq.f", OP_EQ_F, 4, false, ev_float, ev_float, ev_integer, PROG_ID_VERSION},
|
||||
{"==", "eq.v", OP_EQ_V, 4, false, ev_vector, ev_vector, ev_integer, PROG_ID_VERSION},
|
||||
{"==", "eq.s", OP_EQ_S, 4, false, ev_string, ev_string, ev_integer, PROG_ID_VERSION},
|
||||
{"==", "eq.e", OP_EQ_E, 4, false, ev_entity, ev_entity, ev_integer, PROG_ID_VERSION},
|
||||
{"==", "eq.fnc", OP_EQ_FNC, 4, false, ev_func, ev_func, ev_integer, PROG_ID_VERSION},
|
||||
{"==", "eq.f", OP_EQ_F, false, ev_float, ev_float, ev_integer, PROG_ID_VERSION},
|
||||
{"==", "eq.v", OP_EQ_V, false, ev_vector, ev_vector, ev_integer, PROG_ID_VERSION},
|
||||
{"==", "eq.s", OP_EQ_S, false, ev_string, ev_string, ev_integer, PROG_ID_VERSION},
|
||||
{"==", "eq.e", OP_EQ_E, false, ev_entity, ev_entity, ev_integer, PROG_ID_VERSION},
|
||||
{"==", "eq.fnc", OP_EQ_FNC, false, ev_func, ev_func, ev_integer, PROG_ID_VERSION},
|
||||
|
||||
{"!=", "ne.f", OP_NE_F, 4, false, ev_float, ev_float, ev_integer, PROG_ID_VERSION},
|
||||
{"!=", "ne.v", OP_NE_V, 4, false, ev_vector, ev_vector, ev_integer, PROG_ID_VERSION},
|
||||
{"!=", "ne.s", OP_NE_S, 4, false, ev_string, ev_string, ev_integer, PROG_ID_VERSION},
|
||||
{"!=", "ne.e", OP_NE_E, 4, false, ev_entity, ev_entity, ev_integer, PROG_ID_VERSION},
|
||||
{"!=", "ne.fnc", OP_NE_FNC, 4, false, ev_func, ev_func, ev_integer, PROG_ID_VERSION},
|
||||
{"!=", "ne.f", OP_NE_F, false, ev_float, ev_float, ev_integer, PROG_ID_VERSION},
|
||||
{"!=", "ne.v", OP_NE_V, false, ev_vector, ev_vector, ev_integer, PROG_ID_VERSION},
|
||||
{"!=", "ne.s", OP_NE_S, false, ev_string, ev_string, ev_integer, PROG_ID_VERSION},
|
||||
{"!=", "ne.e", OP_NE_E, false, ev_entity, ev_entity, ev_integer, PROG_ID_VERSION},
|
||||
{"!=", "ne.fnc", OP_NE_FNC, false, ev_func, ev_func, ev_integer, PROG_ID_VERSION},
|
||||
|
||||
{"<=", "le", OP_LE, 4, false, ev_float, ev_float, ev_integer, PROG_ID_VERSION},
|
||||
{">=", "ge", OP_GE, 4, false, ev_float, ev_float, ev_integer, PROG_ID_VERSION},
|
||||
{"<=", "le.s", OP_LE_S, 4, false, ev_string, ev_string, ev_integer, PROG_VERSION},
|
||||
{">=", "ge.s", OP_GE_S, 4, false, ev_string, ev_string, ev_integer, PROG_VERSION},
|
||||
{"<", "lt", OP_LT, 4, false, ev_float, ev_float, ev_integer, PROG_ID_VERSION},
|
||||
{">", "gt", OP_GT, 4, false, ev_float, ev_float, ev_integer, PROG_ID_VERSION},
|
||||
{"<", "lt.s", OP_LT_S, 4, false, ev_string, ev_string, ev_integer, PROG_VERSION},
|
||||
{">", "gt.s", OP_GT_S, 4, false, ev_string, ev_string, ev_integer, PROG_VERSION},
|
||||
{"<=", "le", OP_LE, false, ev_float, ev_float, ev_integer, PROG_ID_VERSION},
|
||||
{">=", "ge", OP_GE, false, ev_float, ev_float, ev_integer, PROG_ID_VERSION},
|
||||
{"<=", "le.s", OP_LE_S, false, ev_string, ev_string, ev_integer, PROG_VERSION},
|
||||
{">=", "ge.s", OP_GE_S, false, ev_string, ev_string, ev_integer, PROG_VERSION},
|
||||
{"<", "lt", OP_LT, false, ev_float, ev_float, ev_integer, PROG_ID_VERSION},
|
||||
{">", "gt", OP_GT, false, ev_float, ev_float, ev_integer, PROG_ID_VERSION},
|
||||
{"<", "lt.s", OP_LT_S, false, ev_string, ev_string, ev_integer, PROG_VERSION},
|
||||
{">", "gt.s", OP_GT_S, false, ev_string, ev_string, ev_integer, PROG_VERSION},
|
||||
|
||||
{".", "load.f", OP_LOAD_F, 1, false, ev_entity, ev_field, ev_float, PROG_ID_VERSION},
|
||||
{".", "load.v", OP_LOAD_V, 1, false, ev_entity, ev_field, ev_vector, PROG_ID_VERSION},
|
||||
{".", "load.s", OP_LOAD_S, 1, false, ev_entity, ev_field, ev_string, PROG_ID_VERSION},
|
||||
{".", "load.ent", OP_LOAD_ENT, 1, false, ev_entity, ev_field, ev_entity, PROG_ID_VERSION},
|
||||
{".", "load.fld", OP_LOAD_FLD, 1, false, ev_entity, ev_field, ev_field, PROG_ID_VERSION},
|
||||
{".", "load.fnc", OP_LOAD_FNC, 1, false, ev_entity, ev_field, ev_func, PROG_ID_VERSION},
|
||||
{".", "load.f", OP_LOAD_F, false, ev_entity, ev_field, ev_float, PROG_ID_VERSION},
|
||||
{".", "load.v", OP_LOAD_V, false, ev_entity, ev_field, ev_vector, PROG_ID_VERSION},
|
||||
{".", "load.s", OP_LOAD_S, false, ev_entity, ev_field, ev_string, PROG_ID_VERSION},
|
||||
{".", "load.ent", OP_LOAD_ENT, false, ev_entity, ev_field, ev_entity, PROG_ID_VERSION},
|
||||
{".", "load.fld", OP_LOAD_FLD, false, ev_entity, ev_field, ev_field, PROG_ID_VERSION},
|
||||
{".", "load.fnc", OP_LOAD_FNC, false, ev_entity, ev_field, ev_func, PROG_ID_VERSION},
|
||||
|
||||
{".", "address", OP_ADDRESS, 1, false, ev_entity, ev_field, ev_pointer, PROG_ID_VERSION},
|
||||
{".", "address", OP_ADDRESS, false, ev_entity, ev_field, ev_pointer, PROG_ID_VERSION},
|
||||
|
||||
{"=", "store.f", OP_STORE_F, 5, true, ev_float, ev_float, ev_void, PROG_ID_VERSION},
|
||||
{"=", "store.v", OP_STORE_V, 5, true, ev_vector, ev_vector, ev_void, PROG_ID_VERSION},
|
||||
{"=", "store.s", OP_STORE_S, 5, true, ev_string, ev_string, ev_void, PROG_ID_VERSION},
|
||||
{"=", "store.ent", OP_STORE_ENT, 5, true, ev_entity, ev_entity, ev_void, PROG_ID_VERSION},
|
||||
{"=", "store.fld", OP_STORE_FLD, 5, true, ev_field, ev_field, ev_void, PROG_ID_VERSION},
|
||||
{"=", "store.fnc", OP_STORE_FNC, 5, true, ev_func, ev_func, ev_void, PROG_ID_VERSION},
|
||||
{"=", "store.f", OP_STORE_F, true, ev_float, ev_float, ev_void, PROG_ID_VERSION},
|
||||
{"=", "store.v", OP_STORE_V, true, ev_vector, ev_vector, ev_void, PROG_ID_VERSION},
|
||||
{"=", "store.s", OP_STORE_S, true, ev_string, ev_string, ev_void, PROG_ID_VERSION},
|
||||
{"=", "store.ent", OP_STORE_ENT, true, ev_entity, ev_entity, ev_void, PROG_ID_VERSION},
|
||||
{"=", "store.fld", OP_STORE_FLD, true, ev_field, ev_field, ev_void, PROG_ID_VERSION},
|
||||
{"=", "store.fnc", OP_STORE_FNC, true, ev_func, ev_func, ev_void, PROG_ID_VERSION},
|
||||
|
||||
{"=", "storep.f", OP_STOREP_F, 5, true, ev_float, ev_pointer, ev_void, PROG_ID_VERSION},
|
||||
{"=", "storep.v", OP_STOREP_V, 5, true, ev_vector, ev_pointer, ev_void, PROG_ID_VERSION},
|
||||
{"=", "storep.s", OP_STOREP_S, 5, true, ev_string, ev_pointer, ev_void, PROG_ID_VERSION},
|
||||
{"=", "storep.ent", OP_STOREP_ENT, 5, true, ev_entity, ev_pointer, ev_void, PROG_ID_VERSION},
|
||||
{"=", "storep.fld", OP_STOREP_FLD, 5, true, ev_field, ev_pointer, ev_void, PROG_ID_VERSION},
|
||||
{"=", "storep.fnc", OP_STOREP_FNC, 5, true, ev_func, ev_pointer, ev_void, PROG_ID_VERSION},
|
||||
{"=", "storep.f", OP_STOREP_F, true, ev_float, ev_pointer, ev_void, PROG_ID_VERSION},
|
||||
{"=", "storep.v", OP_STOREP_V, true, ev_vector, ev_pointer, ev_void, PROG_ID_VERSION},
|
||||
{"=", "storep.s", OP_STOREP_S, true, ev_string, ev_pointer, ev_void, PROG_ID_VERSION},
|
||||
{"=", "storep.ent", OP_STOREP_ENT, true, ev_entity, ev_pointer, ev_void, PROG_ID_VERSION},
|
||||
{"=", "storep.fld", OP_STOREP_FLD, true, ev_field, ev_pointer, ev_void, PROG_ID_VERSION},
|
||||
{"=", "storep.fnc", OP_STOREP_FNC, true, ev_func, ev_pointer, ev_void, PROG_ID_VERSION},
|
||||
|
||||
{"<RETURN>", "return", OP_RETURN, -1, false, ev_void, ev_void, ev_void, PROG_ID_VERSION},
|
||||
{"<RETURN>", "return", OP_RETURN, false, ev_void, ev_void, ev_void, PROG_ID_VERSION},
|
||||
|
||||
{"!", "not.f", OP_NOT_F, -1, false, ev_float, ev_void, ev_integer, PROG_ID_VERSION},
|
||||
{"!", "not.v", OP_NOT_V, -1, false, ev_vector, ev_void, ev_integer, PROG_ID_VERSION},
|
||||
{"!", "not.s", OP_NOT_S, -1, false, ev_string, ev_void, ev_integer, PROG_ID_VERSION},
|
||||
{"!", "not.ent", OP_NOT_ENT, -1, false, ev_entity, ev_void, ev_integer, PROG_ID_VERSION},
|
||||
{"!", "not.fnc", OP_NOT_FNC, -1, false, ev_func, ev_void, ev_integer, PROG_ID_VERSION},
|
||||
{"!", "not.f", OP_NOT_F, false, ev_float, ev_void, ev_integer, PROG_ID_VERSION},
|
||||
{"!", "not.v", OP_NOT_V, false, ev_vector, ev_void, ev_integer, PROG_ID_VERSION},
|
||||
{"!", "not.s", OP_NOT_S, false, ev_string, ev_void, ev_integer, PROG_ID_VERSION},
|
||||
{"!", "not.ent", OP_NOT_ENT, false, ev_entity, ev_void, ev_integer, PROG_ID_VERSION},
|
||||
{"!", "not.fnc", OP_NOT_FNC, false, ev_func, ev_void, ev_integer, PROG_ID_VERSION},
|
||||
|
||||
{"<IF>", "if", OP_IF, -1, false, ev_integer, ev_integer, ev_void, PROG_ID_VERSION},
|
||||
{"<IFNOT>", "ifnot", OP_IFNOT, -1, false, ev_integer, ev_integer, ev_void, PROG_ID_VERSION},
|
||||
{"<IF>", "if", OP_IF, false, ev_integer, ev_integer, ev_void, PROG_ID_VERSION},
|
||||
{"<IFNOT>", "ifnot", OP_IFNOT, false, ev_integer, ev_integer, ev_void, PROG_ID_VERSION},
|
||||
|
||||
// calls returns REG_RETURN
|
||||
{"<CALL0>", "call0", OP_CALL0, -1, false, ev_func, ev_void, ev_void, PROG_ID_VERSION},
|
||||
{"<CALL1>", "call1", OP_CALL1, -1, false, ev_func, ev_void, ev_void, PROG_ID_VERSION},
|
||||
{"<CALL2>", "call2", OP_CALL2, -1, false, ev_func, ev_void, ev_void, PROG_ID_VERSION},
|
||||
{"<CALL3>", "call3", OP_CALL3, -1, false, ev_func, ev_void, ev_void, PROG_ID_VERSION},
|
||||
{"<CALL4>", "call4", OP_CALL4, -1, false, ev_func, ev_void, ev_void, PROG_ID_VERSION},
|
||||
{"<CALL5>", "call5", OP_CALL5, -1, false, ev_func, ev_void, ev_void, PROG_ID_VERSION},
|
||||
{"<CALL6>", "call6", OP_CALL6, -1, false, ev_func, ev_void, ev_void, PROG_ID_VERSION},
|
||||
{"<CALL7>", "call7", OP_CALL7, -1, false, ev_func, ev_void, ev_void, PROG_ID_VERSION},
|
||||
{"<CALL8>", "call8", OP_CALL8, -1, false, ev_func, ev_void, ev_void, PROG_ID_VERSION},
|
||||
{"<CALL0>", "call0", OP_CALL0, false, ev_func, ev_void, ev_void, PROG_ID_VERSION},
|
||||
{"<CALL1>", "call1", OP_CALL1, false, ev_func, ev_void, ev_void, PROG_ID_VERSION},
|
||||
{"<CALL2>", "call2", OP_CALL2, false, ev_func, ev_void, ev_void, PROG_ID_VERSION},
|
||||
{"<CALL3>", "call3", OP_CALL3, false, ev_func, ev_void, ev_void, PROG_ID_VERSION},
|
||||
{"<CALL4>", "call4", OP_CALL4, false, ev_func, ev_void, ev_void, PROG_ID_VERSION},
|
||||
{"<CALL5>", "call5", OP_CALL5, false, ev_func, ev_void, ev_void, PROG_ID_VERSION},
|
||||
{"<CALL6>", "call6", OP_CALL6, false, ev_func, ev_void, ev_void, PROG_ID_VERSION},
|
||||
{"<CALL7>", "call7", OP_CALL7, false, ev_func, ev_void, ev_void, PROG_ID_VERSION},
|
||||
{"<CALL8>", "call8", OP_CALL8, false, ev_func, ev_void, ev_void, PROG_ID_VERSION},
|
||||
|
||||
{"<STATE>", "state", OP_STATE, -1, false, ev_float, ev_float, ev_void, PROG_ID_VERSION},
|
||||
{"<STATE>", "state", OP_STATE, false, ev_float, ev_float, ev_void, PROG_ID_VERSION},
|
||||
|
||||
{"<GOTO>", "goto", OP_GOTO, -1, false, ev_float, ev_void, ev_void, PROG_ID_VERSION},
|
||||
{"<GOTO>", "goto", OP_GOTO, false, ev_float, ev_void, ev_void, PROG_ID_VERSION},
|
||||
|
||||
{"&&", "and", OP_AND, 6, false, ev_float, ev_float, ev_integer, PROG_ID_VERSION},
|
||||
{"||", "or", OP_OR, 6, false, ev_float, ev_float, ev_integer, PROG_ID_VERSION},
|
||||
{"&&", "and", OP_AND, false, ev_float, ev_float, ev_integer, PROG_ID_VERSION},
|
||||
{"||", "or", OP_OR, false, ev_float, ev_float, ev_integer, PROG_ID_VERSION},
|
||||
|
||||
{"<<", "shl.f", OP_SHL_F, 2, false, ev_float, ev_float, ev_float, PROG_VERSION},
|
||||
{">>", "shr.f", OP_SHR_F, 2, false, ev_float, ev_float, ev_float, PROG_VERSION},
|
||||
{"<<", "shl.i", OP_SHL_I, 2, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
|
||||
{">>", "shr.i", OP_SHR_I, 2, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
|
||||
{"<<", "shl.f", OP_SHL_F, false, ev_float, ev_float, ev_float, PROG_VERSION},
|
||||
{">>", "shr.f", OP_SHR_F, false, ev_float, ev_float, ev_float, PROG_VERSION},
|
||||
{"<<", "shl.i", OP_SHL_I, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
|
||||
{">>", "shr.i", OP_SHR_I, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
|
||||
|
||||
{"&", "bitand", OP_BITAND, 2, false, ev_float, ev_float, ev_float, PROG_ID_VERSION},
|
||||
{"|", "bitor", OP_BITOR, 2, false, ev_float, ev_float, ev_float, PROG_ID_VERSION},
|
||||
{"&", "bitand", OP_BITAND, false, ev_float, ev_float, ev_float, PROG_ID_VERSION},
|
||||
{"|", "bitor", OP_BITOR, false, ev_float, ev_float, ev_float, PROG_ID_VERSION},
|
||||
|
||||
{"+", "add.i", OP_ADD_I, 3, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
|
||||
{"-", "sub.i", OP_SUB_I, 3, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
|
||||
{"*", "mul.i", OP_MUL_I, 2, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
|
||||
{"/", "div.i", OP_DIV_I, 2, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
|
||||
{"%", "mod_i", OP_MOD_I, 2, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
|
||||
{"%", "mod.f", OP_MOD_F, 2, false, ev_float, ev_float, ev_float, PROG_VERSION},
|
||||
{"&", "bitand.i", OP_BITAND_I, 2, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
|
||||
{"|", "bitor.i", OP_BITOR_I, 2, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
|
||||
{">=", "ge.i", OP_GE_I, 4, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
|
||||
{"<=", "le.i", OP_LE_I, 4, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
|
||||
{">", "gt.i", OP_GT_I, 4, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
|
||||
{"<", "lt.i", OP_LT_I, 4, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
|
||||
{"&&", "and.i", OP_AND_I, 6, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
|
||||
{"||", "or.i", OP_OR_I, 6, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
|
||||
{"!", "not.i", OP_NOT_I, -1, false, ev_integer, ev_void, ev_integer, PROG_VERSION},
|
||||
{"==", "eq.i", OP_EQ_I, 4, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
|
||||
{"!=", "ne.i", OP_NE_I, 4, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
|
||||
{"=", "store.i", OP_STORE_I, 5, true, ev_integer, ev_integer, ev_void, PROG_VERSION},
|
||||
{"=", "storep.i", OP_STOREP_I, 5, true, ev_integer, ev_pointer, ev_void, PROG_VERSION},
|
||||
{".", "load.i", OP_LOAD_I, 1, false, ev_entity, ev_field, ev_integer, PROG_VERSION},
|
||||
{"+", "add.i", OP_ADD_I, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
|
||||
{"-", "sub.i", OP_SUB_I, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
|
||||
{"*", "mul.i", OP_MUL_I, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
|
||||
{"/", "div.i", OP_DIV_I, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
|
||||
{"%", "mod_i", OP_MOD_I, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
|
||||
{"%", "mod.f", OP_MOD_F, false, ev_float, ev_float, ev_float, PROG_VERSION},
|
||||
{"&", "bitand.i", OP_BITAND_I, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
|
||||
{"|", "bitor.i", OP_BITOR_I, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
|
||||
{">=", "ge.i", OP_GE_I, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
|
||||
{"<=", "le.i", OP_LE_I, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
|
||||
{">", "gt.i", OP_GT_I, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
|
||||
{"<", "lt.i", OP_LT_I, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
|
||||
{"&&", "and.i", OP_AND_I, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
|
||||
{"||", "or.i", OP_OR_I, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
|
||||
{"!", "not.i", OP_NOT_I, false, ev_integer, ev_void, ev_integer, PROG_VERSION},
|
||||
{"==", "eq.i", OP_EQ_I, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
|
||||
{"!=", "ne.i", OP_NE_I, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
|
||||
{"=", "store.i", OP_STORE_I, true, ev_integer, ev_integer, ev_void, PROG_VERSION},
|
||||
{"=", "storep.i", OP_STOREP_I, true, ev_integer, ev_pointer, ev_void, PROG_VERSION},
|
||||
{".", "load.i", OP_LOAD_I, false, ev_entity, ev_field, ev_integer, PROG_VERSION},
|
||||
|
||||
{"^", "bitxor.f", OP_BITXOR_F, 2, false, ev_float, ev_float, ev_float, PROG_VERSION},
|
||||
{"^", "bitxor.i", OP_BITXOR_I, 2, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
|
||||
{"~", "bitnot.f", OP_BITNOT_F, -1, false, ev_float, ev_void, ev_float, PROG_VERSION},
|
||||
{"~", "bitnot.i", OP_BITNOT_I, -1, false, ev_integer, ev_void, ev_integer, PROG_VERSION},
|
||||
{"^", "bitxor.f", OP_BITXOR_F, false, ev_float, ev_float, ev_float, PROG_VERSION},
|
||||
{"^", "bitxor.i", OP_BITXOR_I, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
|
||||
{"~", "bitnot.f", OP_BITNOT_F, false, ev_float, ev_void, ev_float, PROG_VERSION},
|
||||
{"~", "bitnot.i", OP_BITNOT_I, false, ev_integer, ev_void, ev_integer, PROG_VERSION},
|
||||
{0},
|
||||
};
|
||||
|
||||
|
|
|
@ -104,4 +104,6 @@ void emit_expr (expr_t *e);
|
|||
expr_t *error (expr_t *e, const char *fmt, ...) __attribute__((format(printf, 2,3)));
|
||||
void warning (expr_t *e, const char *fmt, ...) __attribute__((format(printf, 2,3)));
|
||||
|
||||
const char *get_op_string (int op);
|
||||
|
||||
extern int lineno_base;
|
||||
|
|
|
@ -397,7 +397,7 @@ extern opcode_t *op_goto;
|
|||
statref_t *PR_NewStatref (dstatement_t *st, int field);
|
||||
void PR_AddStatementRef (def_t *def, dstatement_t *st, int field);
|
||||
def_t *PR_Statement (opcode_t *op, def_t *var_a, def_t *var_b);
|
||||
opcode_t *PR_Opcode_Find (const char *name, int priority,
|
||||
opcode_t *PR_Opcode_Find (const char *name,
|
||||
def_t *var_a, def_t *var_b, def_t *var_c);
|
||||
void PR_Opcode_Init_Tables (void);
|
||||
|
||||
|
|
|
@ -145,16 +145,16 @@ emit_function_call (expr_t *e, def_t *dest)
|
|||
parm.type = types[extract_type (earg)];
|
||||
arg = emit_sub_expr (earg, &parm);
|
||||
if (earg->type != ex_expr && earg->type != ex_uexpr) {
|
||||
op = PR_Opcode_Find ("=", 5, arg, &parm, &def_void);
|
||||
op = PR_Opcode_Find ("=", arg, &parm, &def_void);
|
||||
emit_statement (e->line, op, arg, &parm, 0);
|
||||
}
|
||||
}
|
||||
op = PR_Opcode_Find (va ("<CALL%d>", count), -1, &def_function, &def_void, &def_void);
|
||||
op = PR_Opcode_Find (va ("<CALL%d>", count), &def_function, &def_void, &def_void);
|
||||
emit_statement (e->line, op, func, 0, 0);
|
||||
|
||||
def_ret.type = func->type->aux_type;
|
||||
if (dest) {
|
||||
op = PR_Opcode_Find ("=", 5, dest, &def_ret, &def_void);
|
||||
op = PR_Opcode_Find ("=", dest, &def_ret, &def_void);
|
||||
emit_statement (e->line, op, &def_ret, dest, 0);
|
||||
return dest;
|
||||
} else {
|
||||
|
@ -173,7 +173,7 @@ emit_assign_expr (expr_t *e)
|
|||
def_a = emit_sub_expr (e1, 0);
|
||||
if (def_a->type->type == ev_pointer) {
|
||||
def_b = emit_sub_expr (e2, 0);
|
||||
op = PR_Opcode_Find ("=", 5, def_b, def_a, &def_void);
|
||||
op = PR_Opcode_Find ("=", def_b, def_a, &def_void);
|
||||
emit_statement (e->line, op, def_b, def_a, 0);
|
||||
} else {
|
||||
if (def_a->constant) {
|
||||
|
@ -190,7 +190,7 @@ emit_assign_expr (expr_t *e)
|
|||
}
|
||||
def_b = emit_sub_expr (e2, def_a);
|
||||
if (def_b != def_a) {
|
||||
op = PR_Opcode_Find ("=", 5, def_b, def_a, &def_void);
|
||||
op = PR_Opcode_Find ("=", def_b, def_a, &def_void);
|
||||
emit_statement (e->line, op, def_b, def_a, 0);
|
||||
}
|
||||
}
|
||||
|
@ -203,9 +203,8 @@ def_t *
|
|||
emit_sub_expr (expr_t *e, def_t *dest)
|
||||
{
|
||||
opcode_t *op;
|
||||
char *operator;
|
||||
const char *operator;
|
||||
def_t *def_a, *def_b, *d = 0;
|
||||
int priority;
|
||||
|
||||
switch (e->type) {
|
||||
case ex_block:
|
||||
|
@ -236,102 +235,21 @@ emit_sub_expr (expr_t *e, def_t *dest)
|
|||
def_a = emit_sub_expr (e->e.expr.e1, 0);
|
||||
def_b = emit_sub_expr (e->e.expr.e2, 0);
|
||||
}
|
||||
switch (e->e.expr.op) {
|
||||
case AND:
|
||||
operator = "&&";
|
||||
priority = 6;
|
||||
break;
|
||||
case OR:
|
||||
operator = "||";
|
||||
priority = 6;
|
||||
break;
|
||||
case EQ:
|
||||
operator = "==";
|
||||
priority = 4;
|
||||
break;
|
||||
case NE:
|
||||
operator = "!=";
|
||||
priority = 4;
|
||||
break;
|
||||
case LE:
|
||||
operator = "<=";
|
||||
priority = 4;
|
||||
break;
|
||||
case GE:
|
||||
operator = ">=";
|
||||
priority = 4;
|
||||
break;
|
||||
case LT:
|
||||
operator = "<";
|
||||
priority = 4;
|
||||
break;
|
||||
case GT:
|
||||
operator = ">";
|
||||
priority = 4;
|
||||
break;
|
||||
case '+':
|
||||
operator = "+";
|
||||
priority = 3;
|
||||
break;
|
||||
case '-':
|
||||
operator = "-";
|
||||
priority = 3;
|
||||
break;
|
||||
case '*':
|
||||
operator = "*";
|
||||
priority = 2;
|
||||
break;
|
||||
case '/':
|
||||
operator = "/";
|
||||
priority = 2;
|
||||
break;
|
||||
case '&':
|
||||
operator = "&";
|
||||
priority = 2;
|
||||
break;
|
||||
case '^':
|
||||
operator = "^";
|
||||
priority = 2;
|
||||
break;
|
||||
case '|':
|
||||
operator = "|";
|
||||
priority = 2;
|
||||
break;
|
||||
case '%':
|
||||
operator = "%";
|
||||
priority = 2;
|
||||
break;
|
||||
case SHL:
|
||||
operator = "<<";
|
||||
priority = 2;
|
||||
break;
|
||||
case SHR:
|
||||
operator = ">>";
|
||||
priority = 2;
|
||||
break;
|
||||
case '.':
|
||||
operator = ".";
|
||||
priority = 1;
|
||||
break;
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
operator = get_op_string (e->e.expr.op);
|
||||
if (!dest) {
|
||||
dest = PR_GetTempDef (e->e.expr.type, pr_scope);
|
||||
dest->users += 2;
|
||||
}
|
||||
op = PR_Opcode_Find (operator, priority, def_a, def_b, dest);
|
||||
op = PR_Opcode_Find (operator, def_a, def_b, dest);
|
||||
d = emit_statement (e->line, op, def_a, def_b, dest);
|
||||
break;
|
||||
case ex_uexpr:
|
||||
if (e->e.expr.op == '!') {
|
||||
operator = "!";
|
||||
priority = -1;
|
||||
def_a = emit_sub_expr (e->e.expr.e1, 0);
|
||||
def_b = &def_void;
|
||||
} else if (e->e.expr.op == '~') {
|
||||
operator = "~";
|
||||
priority = -1;
|
||||
def_a = emit_sub_expr (e->e.expr.e1, 0);
|
||||
def_b = &def_void;
|
||||
} else if (e->e.expr.op == '-') {
|
||||
|
@ -340,7 +258,6 @@ emit_sub_expr (expr_t *e, def_t *dest)
|
|||
zero.type = expr_types[extract_type (e->e.expr.e1)];
|
||||
|
||||
operator = "-";
|
||||
priority = 3;
|
||||
def_a = PR_ReuseConstant (&zero, 0);
|
||||
def_b = emit_sub_expr (e->e.expr.e1, 0);
|
||||
if (!dest) {
|
||||
|
@ -350,7 +267,7 @@ emit_sub_expr (expr_t *e, def_t *dest)
|
|||
} else {
|
||||
abort ();
|
||||
}
|
||||
op = PR_Opcode_Find (operator, priority, def_a, def_b, dest);
|
||||
op = PR_Opcode_Find (operator, def_a, def_b, dest);
|
||||
d = emit_statement (e->line, op, def_a, def_b, dest);
|
||||
break;
|
||||
case ex_def:
|
||||
|
|
|
@ -216,6 +216,7 @@ get_op_string (int op)
|
|||
case '-': return "-";
|
||||
case '*': return "*";
|
||||
case '/': return "/";
|
||||
case '%': return "%";
|
||||
case '&': return "&";
|
||||
case '|': return "|";
|
||||
case '^': return "^";
|
||||
|
|
|
@ -27,9 +27,8 @@ static const char rcsid[] =
|
|||
|
||||
#include "qfcc.h"
|
||||
|
||||
hashtab_t *opcode_priority_table;
|
||||
hashtab_t *opcode_priority_type_table_ab;
|
||||
hashtab_t *opcode_priority_type_table_abc;
|
||||
hashtab_t *opcode_type_table_ab;
|
||||
hashtab_t *opcode_type_table_abc;
|
||||
|
||||
opcode_t *op_done;
|
||||
opcode_t *op_return;
|
||||
|
@ -66,12 +65,10 @@ get_hash (void *_op, void *_tab)
|
|||
hashtab_t **tab = (hashtab_t **)_tab;
|
||||
unsigned long hash;
|
||||
|
||||
if (tab == &opcode_priority_table) {
|
||||
hash = op->priority;
|
||||
} else if (tab == &opcode_priority_type_table_ab) {
|
||||
hash = ~op->priority + ROTL(~op->type_a, 8) + ROTL(~op->type_b, 16);
|
||||
} else if (tab == &opcode_priority_type_table_abc) {
|
||||
hash = ~op->priority + ROTL(~op->type_a, 8) + ROTL(~op->type_b, 16)
|
||||
if (tab == &opcode_type_table_ab) {
|
||||
hash = ROTL(~op->type_a, 8) + ROTL(~op->type_b, 16);
|
||||
} else if (tab == &opcode_type_table_abc) {
|
||||
hash = ROTL(~op->type_a, 8) + ROTL(~op->type_b, 16)
|
||||
+ ROTL(~op->type_c, 24);
|
||||
} else {
|
||||
abort ();
|
||||
|
@ -87,15 +84,11 @@ compare (void *_opa, void *_opb, void *_tab)
|
|||
hashtab_t **tab = (hashtab_t **)_tab;
|
||||
int cmp;
|
||||
|
||||
if (tab == &opcode_priority_table) {
|
||||
cmp = opa->priority == opb->priority;
|
||||
} else if (tab == &opcode_priority_type_table_ab) {
|
||||
cmp = (opa->priority == opb->priority)
|
||||
&& (opa->type_a == opb->type_a)
|
||||
if (tab == &opcode_type_table_ab) {
|
||||
cmp = (opa->type_a == opb->type_a)
|
||||
&& (opa->type_b == opb->type_b);
|
||||
} else if (tab == &opcode_priority_type_table_abc) {
|
||||
cmp = (opa->priority == opb->priority)
|
||||
&& (opa->type_a == opb->type_a)
|
||||
} else if (tab == &opcode_type_table_abc) {
|
||||
cmp = (opa->type_a == opb->type_a)
|
||||
&& (opa->type_b == opb->type_b)
|
||||
&& (opa->type_c == opb->type_c);
|
||||
} else {
|
||||
|
@ -105,27 +98,26 @@ compare (void *_opa, void *_opb, void *_tab)
|
|||
}
|
||||
|
||||
opcode_t *
|
||||
PR_Opcode_Find (const char *name, int priority, def_t *var_a, def_t *var_b, def_t *var_c)
|
||||
PR_Opcode_Find (const char *name, def_t *var_a, def_t *var_b, def_t *var_c)
|
||||
{
|
||||
opcode_t op;
|
||||
hashtab_t **tab;
|
||||
|
||||
op.name = name;
|
||||
op.priority = priority;
|
||||
if (var_a && var_b && var_c) {
|
||||
op.type_a = var_a->type->type;
|
||||
op.type_b = var_b->type->type;
|
||||
op.type_c = var_c->type->type;
|
||||
if (op.type_c == ev_void)
|
||||
tab = &opcode_priority_type_table_ab;
|
||||
tab = &opcode_type_table_ab;
|
||||
else
|
||||
tab = &opcode_priority_type_table_abc;
|
||||
tab = &opcode_type_table_abc;
|
||||
} else if (var_a && var_b) {
|
||||
op.type_a = var_a->type->type;
|
||||
op.type_b = var_b->type->type;
|
||||
tab = &opcode_priority_type_table_ab;
|
||||
tab = &opcode_type_table_ab;
|
||||
} else {
|
||||
tab = &opcode_priority_table;
|
||||
tab = 0;
|
||||
}
|
||||
return Hash_FindElement (*tab, &op);
|
||||
}
|
||||
|
@ -136,24 +128,18 @@ PR_Opcode_Init_Tables (void)
|
|||
opcode_t *op;
|
||||
|
||||
PR_Opcode_Init ();
|
||||
opcode_priority_table = Hash_NewTable (1021, 0, 0,
|
||||
&opcode_priority_table);
|
||||
opcode_priority_type_table_ab = Hash_NewTable (1021, 0, 0,
|
||||
&opcode_priority_type_table_ab);
|
||||
opcode_priority_type_table_abc = Hash_NewTable (1021, 0, 0,
|
||||
&opcode_priority_type_table_abc);
|
||||
Hash_SetHashCompare (opcode_priority_table, get_hash, compare);
|
||||
Hash_SetHashCompare (opcode_priority_type_table_ab, get_hash, compare);
|
||||
Hash_SetHashCompare (opcode_priority_type_table_abc, get_hash, compare);
|
||||
opcode_type_table_ab = Hash_NewTable (1021, 0, 0, &opcode_type_table_ab);
|
||||
opcode_type_table_abc = Hash_NewTable (1021, 0, 0, &opcode_type_table_abc);
|
||||
Hash_SetHashCompare (opcode_type_table_ab, get_hash, compare);
|
||||
Hash_SetHashCompare (opcode_type_table_abc, get_hash, compare);
|
||||
for (op = pr_opcodes; op->name; op++) {
|
||||
if (op->min_version > options.version)
|
||||
continue;
|
||||
if (options.version == PROG_ID_VERSION
|
||||
&& op->type_c == ev_integer)
|
||||
op->type_c = ev_float;
|
||||
Hash_AddElement (opcode_priority_table, op);
|
||||
Hash_AddElement (opcode_priority_type_table_ab, op);
|
||||
Hash_AddElement (opcode_priority_type_table_abc, op);
|
||||
Hash_AddElement (opcode_type_table_ab, op);
|
||||
Hash_AddElement (opcode_type_table_abc, op);
|
||||
if (!strcmp (op->name, "<DONE>")) {
|
||||
op_done = op;
|
||||
} else if (!strcmp (op->name, "<RETURN>")) {
|
||||
|
|
Loading…
Reference in a new issue