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 *name;
const char *opname; const char *opname;
pr_opcode_e opcode; pr_opcode_e opcode;
int priority;
qboolean right_associative; qboolean right_associative;
etype_t type_a, type_b, type_c; etype_t type_a, type_b, type_c;
int min_version; int min_version;

View file

@ -46,128 +46,128 @@ static const char rcsid[] =
hashtab_t *opcode_table; hashtab_t *opcode_table;
opcode_t pr_opcodes[] = { 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.f", OP_MUL_F, 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.v", OP_MUL_V, 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.fv", OP_MUL_FV, 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.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.f", OP_ADD_F, 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.v", OP_ADD_V, 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.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.f", OP_SUB_F, 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.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.f", OP_EQ_F, 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.v", OP_EQ_V, 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.s", OP_EQ_S, 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.e", OP_EQ_E, 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.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.f", OP_NE_F, 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.v", OP_NE_V, 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.s", OP_NE_S, 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.e", OP_NE_E, 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.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}, {"<=", "le", OP_LE, false, ev_float, ev_float, ev_integer, PROG_ID_VERSION},
{">=", "ge", OP_GE, 4, 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, 4, false, ev_string, ev_string, ev_integer, PROG_VERSION}, {"<=", "le.s", OP_LE_S, false, ev_string, ev_string, ev_integer, PROG_VERSION},
{">=", "ge.s", OP_GE_S, 4, 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, 4, false, ev_float, ev_float, ev_integer, PROG_ID_VERSION}, {"<", "lt", OP_LT, false, ev_float, ev_float, ev_integer, PROG_ID_VERSION},
{">", "gt", OP_GT, 4, 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, 4, false, ev_string, ev_string, ev_integer, PROG_VERSION}, {"<", "lt.s", OP_LT_S, false, ev_string, ev_string, ev_integer, PROG_VERSION},
{">", "gt.s", OP_GT_S, 4, 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.f", OP_LOAD_F, 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.v", OP_LOAD_V, 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.s", OP_LOAD_S, 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.ent", OP_LOAD_ENT, 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.fld", OP_LOAD_FLD, 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.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.f", OP_STORE_F, 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.v", OP_STORE_V, 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.s", OP_STORE_S, 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.ent", OP_STORE_ENT, 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.fld", OP_STORE_FLD, 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.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.f", OP_STOREP_F, 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.v", OP_STOREP_V, 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.s", OP_STOREP_S, 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.ent", OP_STOREP_ENT, 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.fld", OP_STOREP_FLD, 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.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.f", OP_NOT_F, 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.v", OP_NOT_V, 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.s", OP_NOT_S, 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.ent", OP_NOT_ENT, 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.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}, {"<IF>", "if", OP_IF, 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}, {"<IFNOT>", "ifnot", OP_IFNOT, false, ev_integer, ev_integer, ev_void, PROG_ID_VERSION},
// calls returns REG_RETURN // calls returns REG_RETURN
{"<CALL0>", "call0", OP_CALL0, -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, -1, 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, -1, 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, -1, 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, -1, 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, -1, 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, -1, 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, -1, 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, -1, 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}, {"&&", "and", OP_AND, false, ev_float, ev_float, ev_integer, PROG_ID_VERSION},
{"||", "or", OP_OR, 6, 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}, {"<<", "shl.f", OP_SHL_F, false, ev_float, ev_float, ev_float, PROG_VERSION},
{">>", "shr.f", OP_SHR_F, 2, 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, 2, false, ev_integer, ev_integer, ev_integer, PROG_VERSION}, {"<<", "shl.i", OP_SHL_I, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
{">>", "shr.i", OP_SHR_I, 2, 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}, {"&", "bitand", OP_BITAND, false, ev_float, ev_float, ev_float, PROG_ID_VERSION},
{"|", "bitor", OP_BITOR, 2, 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}, {"+", "add.i", OP_ADD_I, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
{"-", "sub.i", OP_SUB_I, 3, 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, 2, 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, 2, 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, 2, 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, 2, false, ev_float, ev_float, ev_float, PROG_VERSION}, {"%", "mod.f", OP_MOD_F, false, ev_float, ev_float, ev_float, PROG_VERSION},
{"&", "bitand.i", OP_BITAND_I, 2, false, ev_integer, ev_integer, ev_integer, PROG_VERSION}, {"&", "bitand.i", OP_BITAND_I, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
{"|", "bitor.i", OP_BITOR_I, 2, 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, 4, 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, 4, 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, 4, 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, 4, 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, 6, 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, 6, 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, -1, false, ev_integer, ev_void, ev_integer, PROG_VERSION}, {"!", "not.i", OP_NOT_I, false, ev_integer, ev_void, ev_integer, PROG_VERSION},
{"==", "eq.i", OP_EQ_I, 4, false, ev_integer, ev_integer, ev_integer, PROG_VERSION}, {"==", "eq.i", OP_EQ_I, false, ev_integer, ev_integer, ev_integer, PROG_VERSION},
{"!=", "ne.i", OP_NE_I, 4, 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, 5, true, ev_integer, ev_integer, ev_void, PROG_VERSION}, {"=", "store.i", OP_STORE_I, true, ev_integer, ev_integer, ev_void, PROG_VERSION},
{"=", "storep.i", OP_STOREP_I, 5, true, ev_integer, ev_pointer, ev_void, PROG_VERSION}, {"=", "storep.i", OP_STOREP_I, true, ev_integer, ev_pointer, ev_void, PROG_VERSION},
{".", "load.i", OP_LOAD_I, 1, false, ev_entity, ev_field, ev_integer, 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.f", OP_BITXOR_F, false, ev_float, ev_float, ev_float, PROG_VERSION},
{"^", "bitxor.i", OP_BITXOR_I, 2, false, ev_integer, ev_integer, ev_integer, PROG_VERSION}, {"^", "bitxor.i", OP_BITXOR_I, 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.f", OP_BITNOT_F, false, ev_float, ev_void, ev_float, PROG_VERSION},
{"~", "bitnot.i", OP_BITNOT_I, -1, false, ev_integer, ev_void, ev_integer, PROG_VERSION}, {"~", "bitnot.i", OP_BITNOT_I, false, ev_integer, ev_void, ev_integer, PROG_VERSION},
{0}, {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))); 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))); void warning (expr_t *e, const char *fmt, ...) __attribute__((format(printf, 2,3)));
const char *get_op_string (int op);
extern int lineno_base; extern int lineno_base;

View file

@ -397,7 +397,7 @@ extern opcode_t *op_goto;
statref_t *PR_NewStatref (dstatement_t *st, int field); statref_t *PR_NewStatref (dstatement_t *st, int field);
void PR_AddStatementRef (def_t *def, 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); 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); def_t *var_a, def_t *var_b, def_t *var_c);
void PR_Opcode_Init_Tables (void); 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)]; parm.type = types[extract_type (earg)];
arg = emit_sub_expr (earg, &parm); arg = emit_sub_expr (earg, &parm);
if (earg->type != ex_expr && earg->type != ex_uexpr) { 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); 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); emit_statement (e->line, op, func, 0, 0);
def_ret.type = func->type->aux_type; def_ret.type = func->type->aux_type;
if (dest) { 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); emit_statement (e->line, op, &def_ret, dest, 0);
return dest; return dest;
} else { } else {
@ -173,7 +173,7 @@ emit_assign_expr (expr_t *e)
def_a = emit_sub_expr (e1, 0); def_a = emit_sub_expr (e1, 0);
if (def_a->type->type == ev_pointer) { if (def_a->type->type == ev_pointer) {
def_b = emit_sub_expr (e2, 0); 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); emit_statement (e->line, op, def_b, def_a, 0);
} else { } else {
if (def_a->constant) { if (def_a->constant) {
@ -190,7 +190,7 @@ emit_assign_expr (expr_t *e)
} }
def_b = emit_sub_expr (e2, def_a); def_b = emit_sub_expr (e2, def_a);
if (def_b != 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); 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) emit_sub_expr (expr_t *e, def_t *dest)
{ {
opcode_t *op; opcode_t *op;
char *operator; const char *operator;
def_t *def_a, *def_b, *d = 0; def_t *def_a, *def_b, *d = 0;
int priority;
switch (e->type) { switch (e->type) {
case ex_block: 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_a = emit_sub_expr (e->e.expr.e1, 0);
def_b = emit_sub_expr (e->e.expr.e2, 0); def_b = emit_sub_expr (e->e.expr.e2, 0);
} }
switch (e->e.expr.op) { operator = get_op_string (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 ();
}
if (!dest) { if (!dest) {
dest = PR_GetTempDef (e->e.expr.type, pr_scope); dest = PR_GetTempDef (e->e.expr.type, pr_scope);
dest->users += 2; 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); d = emit_statement (e->line, op, def_a, def_b, dest);
break; break;
case ex_uexpr: case ex_uexpr:
if (e->e.expr.op == '!') { if (e->e.expr.op == '!') {
operator = "!"; operator = "!";
priority = -1;
def_a = emit_sub_expr (e->e.expr.e1, 0); def_a = emit_sub_expr (e->e.expr.e1, 0);
def_b = &def_void; def_b = &def_void;
} else if (e->e.expr.op == '~') { } else if (e->e.expr.op == '~') {
operator = "~"; operator = "~";
priority = -1;
def_a = emit_sub_expr (e->e.expr.e1, 0); def_a = emit_sub_expr (e->e.expr.e1, 0);
def_b = &def_void; def_b = &def_void;
} else if (e->e.expr.op == '-') { } 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)]; zero.type = expr_types[extract_type (e->e.expr.e1)];
operator = "-"; operator = "-";
priority = 3;
def_a = PR_ReuseConstant (&zero, 0); def_a = PR_ReuseConstant (&zero, 0);
def_b = emit_sub_expr (e->e.expr.e1, 0); def_b = emit_sub_expr (e->e.expr.e1, 0);
if (!dest) { if (!dest) {
@ -350,7 +267,7 @@ emit_sub_expr (expr_t *e, def_t *dest)
} else { } else {
abort (); 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); d = emit_statement (e->line, op, def_a, def_b, dest);
break; break;
case ex_def: 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 "%";
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" #include "qfcc.h"
hashtab_t *opcode_priority_table; hashtab_t *opcode_type_table_ab;
hashtab_t *opcode_priority_type_table_ab; hashtab_t *opcode_type_table_abc;
hashtab_t *opcode_priority_type_table_abc;
opcode_t *op_done; opcode_t *op_done;
opcode_t *op_return; opcode_t *op_return;
@ -66,12 +65,10 @@ get_hash (void *_op, void *_tab)
hashtab_t **tab = (hashtab_t **)_tab; hashtab_t **tab = (hashtab_t **)_tab;
unsigned long hash; unsigned long hash;
if (tab == &opcode_priority_table) { if (tab == &opcode_type_table_ab) {
hash = op->priority; hash = ROTL(~op->type_a, 8) + ROTL(~op->type_b, 16);
} else if (tab == &opcode_priority_type_table_ab) { } else if (tab == &opcode_type_table_abc) {
hash = ~op->priority + ROTL(~op->type_a, 8) + ROTL(~op->type_b, 16); hash = 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)
+ ROTL(~op->type_c, 24); + ROTL(~op->type_c, 24);
} else { } else {
abort (); abort ();
@ -87,15 +84,11 @@ compare (void *_opa, void *_opb, void *_tab)
hashtab_t **tab = (hashtab_t **)_tab; hashtab_t **tab = (hashtab_t **)_tab;
int cmp; int cmp;
if (tab == &opcode_priority_table) { if (tab == &opcode_type_table_ab) {
cmp = opa->priority == opb->priority; cmp = (opa->type_a == opb->type_a)
} else if (tab == &opcode_priority_type_table_ab) {
cmp = (opa->priority == opb->priority)
&& (opa->type_a == opb->type_a)
&& (opa->type_b == opb->type_b); && (opa->type_b == opb->type_b);
} else if (tab == &opcode_priority_type_table_abc) { } else if (tab == &opcode_type_table_abc) {
cmp = (opa->priority == opb->priority) cmp = (opa->type_a == opb->type_a)
&& (opa->type_a == opb->type_a)
&& (opa->type_b == opb->type_b) && (opa->type_b == opb->type_b)
&& (opa->type_c == opb->type_c); && (opa->type_c == opb->type_c);
} else { } else {
@ -105,27 +98,26 @@ compare (void *_opa, void *_opb, void *_tab)
} }
opcode_t * 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; opcode_t op;
hashtab_t **tab; hashtab_t **tab;
op.name = name; op.name = name;
op.priority = priority;
if (var_a && var_b && var_c) { if (var_a && var_b && var_c) {
op.type_a = var_a->type->type; op.type_a = var_a->type->type;
op.type_b = var_b->type->type; op.type_b = var_b->type->type;
op.type_c = var_c->type->type; op.type_c = var_c->type->type;
if (op.type_c == ev_void) if (op.type_c == ev_void)
tab = &opcode_priority_type_table_ab; tab = &opcode_type_table_ab;
else else
tab = &opcode_priority_type_table_abc; tab = &opcode_type_table_abc;
} else if (var_a && var_b) { } else if (var_a && var_b) {
op.type_a = var_a->type->type; op.type_a = var_a->type->type;
op.type_b = var_b->type->type; op.type_b = var_b->type->type;
tab = &opcode_priority_type_table_ab; tab = &opcode_type_table_ab;
} else { } else {
tab = &opcode_priority_table; tab = 0;
} }
return Hash_FindElement (*tab, &op); return Hash_FindElement (*tab, &op);
} }
@ -136,24 +128,18 @@ PR_Opcode_Init_Tables (void)
opcode_t *op; opcode_t *op;
PR_Opcode_Init (); PR_Opcode_Init ();
opcode_priority_table = Hash_NewTable (1021, 0, 0, opcode_type_table_ab = Hash_NewTable (1021, 0, 0, &opcode_type_table_ab);
&opcode_priority_table); opcode_type_table_abc = Hash_NewTable (1021, 0, 0, &opcode_type_table_abc);
opcode_priority_type_table_ab = Hash_NewTable (1021, 0, 0, Hash_SetHashCompare (opcode_type_table_ab, get_hash, compare);
&opcode_priority_type_table_ab); Hash_SetHashCompare (opcode_type_table_abc, get_hash, compare);
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);
for (op = pr_opcodes; op->name; op++) { for (op = pr_opcodes; op->name; op++) {
if (op->min_version > options.version) if (op->min_version > options.version)
continue; continue;
if (options.version == PROG_ID_VERSION if (options.version == PROG_ID_VERSION
&& op->type_c == ev_integer) && op->type_c == ev_integer)
op->type_c = ev_float; op->type_c = ev_float;
Hash_AddElement (opcode_priority_table, op); Hash_AddElement (opcode_type_table_ab, op);
Hash_AddElement (opcode_priority_type_table_ab, op); Hash_AddElement (opcode_type_table_abc, op);
Hash_AddElement (opcode_priority_type_table_abc, op);
if (!strcmp (op->name, "<DONE>")) { if (!strcmp (op->name, "<DONE>")) {
op_done = op; op_done = op;
} else if (!strcmp (op->name, "<RETURN>")) { } else if (!strcmp (op->name, "<RETURN>")) {