Bring back the unsigned type (PROGS version bump)

This is only low-level support (the unsigned keyword still does not work),
but sufficient to make switch statements using jump tables work.
This commit is contained in:
Bill Currie 2011-04-09 10:07:47 +09:00
parent b522853765
commit 55cc0f9206
16 changed files with 138 additions and 37 deletions

View file

@ -42,6 +42,7 @@ typedef enum {
ev_pointer, // end of v6 types
ev_quat,
ev_integer,
ev_uinteger,
ev_short, // value is embedded in the opcode
ev_invalid, // invalid type. used for instruction checking
@ -260,7 +261,6 @@ typedef enum {
OP_MOVEP,
OP_MOVEPI,
OP_SHL_U,
OP_SHR_U,
OP_STATE_F,
@ -362,7 +362,7 @@ typedef struct pr_va_list_s {
|(((0x##b) & 0xfff) << 12) \
|(((0x##c) & 0xfff) << 0) )
#define PROG_ID_VERSION 6
#define PROG_VERSION PROG_VERSION_ENCODE(0,fff,007)
#define PROG_VERSION PROG_VERSION_ENCODE(0,fff,008)
typedef struct dprograms_s {
pr_uint_t version;

View file

@ -660,6 +660,9 @@ value_string (progs_t *pr, etype_t type, pr_type_t *val)
case ev_integer:
dsprintf (line, "%d", val->integer_var);
break;
case ev_uinteger:
dsprintf (line, "$%08x", val->uinteger_var);
break;
default:
//dsprintf (line, "bad type %i", type);
dsprintf (line, "<%x %x %x %x>",
@ -1058,6 +1061,7 @@ ED_Print (progs_t *pr, edict_t *ed)
switch (type) {
case ev_entity:
case ev_integer:
case ev_uinteger:
case ev_pointer:
case ev_func:
case ev_field:

View file

@ -465,14 +465,13 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
OPC.float_var = (int) OPA.float_var >> (int) OPB.float_var;
break;
case OP_SHL_I:
case OP_SHL_U:
OPC.integer_var = OPA.integer_var << OPB.integer_var;
break;
case OP_SHR_I:
OPC.integer_var = OPA.integer_var >> OPB.integer_var;
break;
case OP_SHR_U:
OPC.uinteger_var = OPA.uinteger_var >> OPB.uinteger_var;
OPC.uinteger_var = OPA.uinteger_var >> OPB.integer_var;
break;
case OP_GE_F:
OPC.float_var = OPA.float_var >= OPB.float_var;

View file

@ -60,6 +60,7 @@ VISIBLE int pr_type_size[ev_type_count] = {
1, // ev_pointer
4, // ev_quat
1, // ev_integer
1, // ev_uinteger
0, // ev_short value in opcode
};
@ -74,6 +75,7 @@ VISIBLE const char *pr_type_name[ev_type_count] = {
"pointer",
"quaternion",
"integer",
"uinteger",
"short",
"invalid",
};
@ -873,12 +875,8 @@ VISIBLE opcode_t pr_opcodes[] = {
ev_integer, ev_integer, ev_integer,
PROG_VERSION,
},
{"<<", "shl.u", OP_SHL_U, false,
ev_integer, ev_integer, ev_integer,
PROG_VERSION,
},
{">>", "shr.u", OP_SHR_U, false,
ev_integer, ev_integer, ev_integer,
ev_uinteger, ev_integer, ev_uinteger,
PROG_VERSION,
},
@ -964,22 +962,22 @@ VISIBLE opcode_t pr_opcodes[] = {
PROG_VERSION,
},
// {">=", "ge.u", OP_GE_U, false,
// ev_integer, ev_integer, ev_integer,
// PROG_VERSION,
// },
// {"<=", "le.u", OP_LE_U, false,
// ev_integer, ev_integer, ev_integer,
// PROG_VERSION,
// },
// {">", "gt.u", OP_GT_U, false,
// ev_integer, ev_integer, ev_integer,
// PROG_VERSION,
// },
// {"<", "lt.u", OP_LT_U, false,
// ev_integer, ev_integer, ev_integer,
// PROG_VERSION,
// },
{">=", "ge.u", OP_GE_U, false,
ev_uinteger, ev_uinteger, ev_integer,
PROG_VERSION,
},
{"<=", "le.u", OP_LE_U, false,
ev_uinteger, ev_uinteger, ev_integer,
PROG_VERSION,
},
{">", "gt.u", OP_GT_U, false,
ev_uinteger, ev_uinteger, ev_integer,
PROG_VERSION,
},
{"<", "lt.u", OP_LT_U, false,
ev_uinteger, ev_uinteger, ev_integer,
PROG_VERSION,
},
{"^", "bitxor.f", OP_BITXOR_F, false,
ev_float, ev_float, ev_float,

View file

@ -370,6 +370,7 @@ set_address (sv_def_t *def, void *address)
case ev_func:
case ev_pointer:
case ev_integer:
case ev_uinteger:
*(int **)def->field = (int *) address;
break;
}

View file

@ -371,6 +371,7 @@ set_address (sv_def_t *def, void *address)
case ev_func:
case ev_pointer:
case ev_integer:
case ev_uinteger:
*(int **)def->field = (int *) address;
break;
}

View file

@ -423,6 +423,15 @@ const float *expr_quaternion (expr_t *e);
expr_t *new_integer_expr (int integer_val);
int expr_integer (expr_t *e);
/** Create a new integer constant expression node.
\param integer_val The integer constant being represented.
\return The new integer constant expression node
(expr_t::e::integer_val).
*/
expr_t *new_uinteger_expr (unsigned uinteger_val);
unsigned expr_uinteger (expr_t *e);
/** Create a new short constant expression node.
\param short_val The short constant being represented.

View file

@ -105,6 +105,7 @@ extern type_t type_pointer;
extern type_t type_floatfield;
extern type_t type_quaternion;
extern type_t type_integer;
extern type_t type_uinteger;
extern type_t type_short;
extern type_t *type_nil; // for passing nil into ...

View file

@ -477,10 +477,8 @@ do_op_pointer (int op, expr_t *e, expr_t *e1, expr_t *e2)
if (op != PAS && op != '.' && op != '&' && op != 'M'
&& extract_type (e1) != extract_type (e2))
return type_mismatch (e1, e2, op);
//if ((op == '.' || op == '&') && get_type (e2) == &type_uinteger) {
// //FIXME should implement unsigned addressing
// e->e.expr.e2 = cf_cast_expr (&type_integer, e2);
//}
if ((op == '.' || op == '&') && get_type (e2) == &type_uinteger)
e->e.expr.e2 = cf_cast_expr (&type_integer, e2);
return e;
}
@ -700,6 +698,12 @@ do_op_integer (int op, expr_t *e, expr_t *e1, expr_t *e2)
return e;
}
static expr_t *
do_op_uinteger (int op, expr_t *e, expr_t *e1, expr_t *e2)
{
return e;
}
static expr_t *
do_op_short (int op, expr_t *e, expr_t *e1, expr_t *e2)
{
@ -872,6 +876,7 @@ static operation_t op_void[ev_type_count] = {
do_op_invalid, // ev_pointer
do_op_invalid, // ev_quaternion
do_op_invalid, // ev_integer
do_op_invalid, // ev_uinteger
do_op_invalid, // ev_short
do_op_invalid, // ev_invalid
};
@ -887,6 +892,7 @@ static operation_t op_string[ev_type_count] = {
do_op_invalid, // ev_pointer
do_op_invalid, // ev_quaternion
do_op_invalid, // ev_integer
do_op_invalid, // ev_uinteger
do_op_invalid, // ev_short
do_op_invalid, // ev_invalid
};
@ -902,6 +908,7 @@ static operation_t op_float[ev_type_count] = {
do_op_invalid, // ev_pointer
do_op_quaternion, // ev_quaternion
do_op_float, // ev_integer
do_op_float, // ev_uinteger
do_op_float, // ev_short
do_op_invalid, // ev_invalid
};
@ -917,6 +924,7 @@ static operation_t op_vector[ev_type_count] = {
do_op_invalid, // ev_pointer
do_op_invalid, // ev_quaternion
do_op_vector, // ev_integer
do_op_vector, // ev_uinteger
do_op_vector, // ev_short
do_op_invalid, // ev_invalid
};
@ -932,6 +940,7 @@ static operation_t op_entity[ev_type_count] = {
do_op_invalid, // ev_pointer
do_op_invalid, // ev_quaternion
do_op_invalid, // ev_integer
do_op_invalid, // ev_uinteger
do_op_invalid, // ev_short
do_op_invalid, // ev_invalid
};
@ -947,6 +956,7 @@ static operation_t op_field[ev_type_count] = {
do_op_invalid, // ev_pointer
do_op_invalid, // ev_quaternion
do_op_invalid, // ev_integer
do_op_invalid, // ev_uinteger
do_op_invalid, // ev_short
do_op_invalid, // ev_invalid
};
@ -962,6 +972,7 @@ static operation_t op_func[ev_type_count] = {
do_op_func, // ev_pointer
do_op_func, // ev_quaternion
do_op_func, // ev_integer
do_op_func, // ev_uinteger
do_op_func, // ev_short
do_op_func, // ev_invalid
};
@ -977,6 +988,7 @@ static operation_t op_pointer[ev_type_count] = {
do_op_pointer, // ev_pointer
do_op_pointer, // ev_quaternion
do_op_pointer, // ev_integer
do_op_pointer, // ev_uinteger
do_op_pointer, // ev_short
do_op_pointer, // ev_invalid
};
@ -992,6 +1004,7 @@ static operation_t op_quaternion[ev_type_count] = {
do_op_invalid, // ev_pointer
do_op_quaternion, // ev_quaternion
do_op_quaternion, // ev_integer
do_op_quaternion, // ev_uinteger
do_op_quaternion, // ev_short
do_op_invalid, // ev_invalid
};
@ -1007,10 +1020,27 @@ static operation_t op_integer[ev_type_count] = {
do_op_invalid, // ev_pointer
do_op_quaternion, // ev_quaternion
do_op_integer, // ev_integer
do_op_uinteger, // ev_uinteger
do_op_integer, // ev_short
do_op_invalid, // ev_invalid
};
static operation_t op_uinteger[ev_type_count] = {
do_op_invalid, // ev_void
do_op_invalid, // ev_string
do_op_float, // ev_float
do_op_vector, // ev_vector
do_op_invalid, // ev_entity
do_op_invalid, // ev_field
do_op_invalid, // ev_func
do_op_invalid, // ev_pointer
do_op_quaternion, // ev_quaternion
do_op_uinteger, // ev_integer
do_op_uinteger, // ev_uinteger
do_op_uinteger, // ev_short
do_op_invalid, // ev_invalid
};
static operation_t op_short[ev_type_count] = {
do_op_invalid, // ev_void
do_op_invalid, // ev_string
@ -1022,6 +1052,7 @@ static operation_t op_short[ev_type_count] = {
do_op_invalid, // ev_pointer
do_op_quaternion, // ev_quaternion
do_op_integer, // ev_integer
do_op_uinteger, // ev_uinteger
do_op_short, // ev_short
do_op_invalid, // ev_invalid
};
@ -1037,6 +1068,7 @@ static operation_t op_compound[ev_type_count] = {
do_op_invalid, // ev_pointer
do_op_invalid, // ev_quaternion
do_op_compound, // ev_integer
do_op_compound, // ev_uinteger
do_op_compound, // ev_short
do_op_compound, // ev_invalid
};
@ -1052,6 +1084,7 @@ static operation_t *do_op[ev_type_count] = {
op_pointer, // ev_pointer
op_quaternion, // ev_quaternion
op_integer, // ev_integer
op_uinteger, // ev_uinteger
op_short, // ev_short
op_compound, // ev_invalid
};

View file

@ -332,6 +332,9 @@ print_value (expr_t *e, int level, int id)
case ev_integer:
label = va ("%d", e->e.value.v.integer_val);
break;
case ev_uinteger:
label = va ("%u", e->e.value.v.uinteger_val);
break;
case ev_short:
label = va ("%d", e->e.value.v.short_val);
break;

View file

@ -122,6 +122,8 @@ get_operand (operand_t *op)
return va ("func %d", op->o.value->v.integer_val);
case ev_integer:
return va ("int %d", op->o.value->v.integer_val);
case ev_uinteger:
return va ("uint %u", op->o.value->v.uinteger_val);
case ev_short:
return va ("short %d", op->o.value->v.short_val);
case ev_void:

View file

@ -78,6 +78,7 @@ type_t *ev_types[ev_type_count] = {
&type_pointer,
&type_quaternion,
&type_integer,
&type_uinteger,
&type_short,
&type_invalid,
};
@ -584,6 +585,16 @@ new_integer_expr (int integer_val)
return e;
}
expr_t *
new_uinteger_expr (unsigned uinteger_val)
{
expr_t *e = new_expr ();
e->type = ex_value;
e->e.value.type = ev_uinteger;
e->e.value.v.uinteger_val = uinteger_val;
return e;
}
expr_t *
new_short_expr (short short_val)
{
@ -771,6 +782,23 @@ expr_integer (expr_t *e)
internal_error (e, "not an integer constant");
}
unsigned
expr_uinteger (expr_t *e)
{
if (e->type == ex_nil)
return 0;
if (e->type == ex_value && e->e.value.type == ev_uinteger)
return e->e.value.v.uinteger_val;
if (e->type == ex_symbol && e->e.symbol->sy_type == sy_const
&& e->e.symbol->type->type == ev_uinteger)
return e->e.symbol->s.value.v.uinteger_val;
if (e->type == ex_symbol && e->e.symbol->sy_type == sy_var
&& e->e.symbol->s.def->constant
&& is_integral (e->e.symbol->s.def->type))
return D_INT (e->e.symbol->s.def);
internal_error (e, "not an unsigned constant");
}
int
is_short_val (expr_t *e)
{
@ -1029,7 +1057,7 @@ test_expr (expr_t *e)
case ev_string:
new = new_string_expr (0);
break;
// case ev_uinteger:
case ev_uinteger:
case ev_integer:
case ev_short:
if (type_default != &type_integer)
@ -1187,9 +1215,9 @@ convert_from_bool (expr_t *e, type_t *type)
zero = new_integer_expr (0);
} else if (is_enum (type) && enum_as_bool (type, &zero, &one)) {
// don't need to do anything
// } else if (type == &type_uinteger) {
// one = new_uinteger_expr (1);
// zero = new_uinteger_expr (0);
} else if (type == &type_uinteger) {
one = new_uinteger_expr (1);
zero = new_uinteger_expr (0);
} else {
return error (e, "can't convert from bool value");
}
@ -1567,6 +1595,8 @@ unary_expr (int op, expr_t *e)
return new_vector_expr (q);
case ev_integer:
return new_integer_expr (-expr_integer (e));
case ev_uinteger:
return new_uinteger_expr (-expr_uinteger (e));
case ev_short:
return new_short_expr (-expr_short (e));
case ev_invalid:
@ -1627,6 +1657,8 @@ unary_expr (int op, expr_t *e)
return new_integer_expr (!QuatIsZero (expr_quaternion (e)));
case ev_integer:
return new_integer_expr (!expr_integer (e));
case ev_uinteger:
return new_uinteger_expr (!expr_uinteger (e));
case ev_short:
return new_short_expr (!expr_short (e));
case ev_invalid:
@ -1682,6 +1714,8 @@ unary_expr (int op, expr_t *e)
return new_vector_expr (q);
case ev_integer:
return new_integer_expr (~expr_integer (e));
case ev_uinteger:
return new_uinteger_expr (~expr_uinteger (e));
case ev_short:
return new_short_expr (~expr_short (e));
case ev_invalid:
@ -2607,6 +2641,9 @@ cast_expr (type_t *type, expr_t *e)
if ((type == type_default && is_enum (e_type))
|| (is_enum (type) && e_type == type_default))
return e;
if ((type == &type_integer && e_type == &type_uinteger)
|| (type == &type_uinteger && e_type == &type_integer))
return new_alias_expr (type, e);
if (!(type->type == ev_pointer
&& (e_type->type == ev_pointer
|| e_type == &type_integer //|| e_type == &type_uinteger

View file

@ -98,6 +98,9 @@ print_operand (operand_t *op)
case ev_integer:
printf ("%d", op->o.value->v.integer_val);
break;
case ev_uinteger:
printf ("%u", op->o.value->v.uinteger_val);
break;
case ev_short:
printf ("%d", op->o.value->v.short_val);
break;

View file

@ -338,7 +338,6 @@ build_switch (expr_t *sw, case_node_t *tree, int op, expr_t *sw_val,
range = fold_constants (range);
//FIXME unsigned int better?
sym = make_symbol (name, array_type (&type_integer, high - low + 1),
pr.near_data, st_static);
table = new_symbol_expr (sym);
@ -348,8 +347,8 @@ build_switch (expr_t *sw, case_node_t *tree, int op, expr_t *sw_val,
branch = branch_expr (IFB, temp, low_label);
append_expr (sw, branch);
}
//FIXME unsigned int
test = binary_expr (GT, cast_expr (&type_integer, temp), range);
test = binary_expr (GT, cast_expr (&type_uinteger, temp),
cast_expr (&type_uinteger, range));
branch = branch_expr ('i', test, high_label);
append_expr (sw, branch);
branch = new_binary_expr ('g', table, temp);

View file

@ -75,6 +75,7 @@ type_t type_function = { ev_func, "function", ty_none, {{&type_void}} };
type_t type_pointer = { ev_pointer, "pointer", ty_none, {{&type_void}} };
type_t type_quaternion = { ev_quat, "quaternion" };
type_t type_integer = { ev_integer, "integer" };
type_t type_uinteger = { ev_uinteger, "uinteger" };
type_t type_short = { ev_short, "short" };
type_t *type_nil;
@ -154,6 +155,7 @@ free_type (type_t *type)
case ev_type_count:
case ev_quat:
case ev_integer:
case ev_uinteger:
case ev_short:
break;
case ev_field:
@ -188,6 +190,7 @@ append_type (type_t *type, type_t *new)
case ev_type_count:
case ev_quat:
case ev_integer:
case ev_uinteger:
case ev_short:
internal_error (0, "append to basic type");
case ev_field:
@ -593,6 +596,9 @@ encode_type (dstring_t *encoding, type_t *type)
case ev_integer:
dasprintf (encoding, "i");
break;
case ev_uinteger:
dasprintf (encoding, "I");
break;
case ev_short:
dasprintf (encoding, "s");
break;
@ -641,7 +647,7 @@ is_integral (type_t *type)
{
etype_t t = type->type;
if (t == ev_integer || t == ev_short)
if (t == ev_integer || t == ev_uinteger || t == ev_short)
return 1;
return is_enum (type);
}
@ -758,6 +764,7 @@ type_size (type_t *type)
case ev_pointer:
case ev_quat:
case ev_integer:
case ev_uinteger:
case ev_short:
case ev_type_count:
return pr_type_size[type->type];
@ -805,6 +812,7 @@ init_types (void)
{"pointer_val", &type_pointer},
{"vector_val", &type_vector},
{"integer_val", &type_integer},
{"uinteger_val", &type_uinteger},
{"quaternion_val", &type_quaternion},
{0, 0}
};
@ -817,6 +825,7 @@ init_types (void)
{"func_val", &type_function},
{"pointer_val", &type_pointer},
{"integer_val", &type_integer},
{"uinteger_val", &type_uinteger},
{"quaternion_val", &type_quaternion},
{0, 0}
};
@ -881,6 +890,7 @@ chain_initial_types (void)
if (!options.traditional) {
chain_type (&type_quaternion);
chain_type (&type_integer);
chain_type (&type_uinteger);
chain_type (&type_short);
}

View file

@ -237,6 +237,7 @@ emit_value (ex_value_t *value, def_t *def)
type = &type_pointer;
break;
case ev_integer:
case ev_uinteger:
if (!def || def->type != &type_float) {
tab = integer_imm_defs;
type = &type_integer;