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:
Bill Currie 2001-10-25 17:48:35 +00:00
parent f029687ff0
commit f8a41cb1bc
7 changed files with 133 additions and 228 deletions

View file

@ -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;

View file

@ -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},
};

View file

@ -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;

View file

@ -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);

View file

@ -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:

View file

@ -216,6 +216,7 @@ get_op_string (int op)
case '-': return "-";
case '*': return "*";
case '/': return "/";
case '%': return "%";
case '&': return "&";
case '|': return "|";
case '^': return "^";

View file

@ -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>")) {