mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-23 04:42:32 +00:00
[qfcc] Support pointers to temp operands
This is necessary for correctly taking the address of operands.
This commit is contained in:
parent
2f07d9a310
commit
a0c28a5ac5
9 changed files with 53 additions and 33 deletions
|
@ -126,6 +126,7 @@ typedef struct ex_pointer_s {
|
||||||
int val;
|
int val;
|
||||||
struct type_s *type;
|
struct type_s *type;
|
||||||
struct def_s *def;
|
struct def_s *def;
|
||||||
|
struct tempop_s *tempop;
|
||||||
} ex_pointer_t;
|
} ex_pointer_t;
|
||||||
|
|
||||||
typedef struct ex_func_s {
|
typedef struct ex_func_s {
|
||||||
|
|
|
@ -41,7 +41,7 @@ typedef enum {
|
||||||
op_nil,
|
op_nil,
|
||||||
} op_type_e;
|
} op_type_e;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct tempop_s {
|
||||||
struct def_s *def;
|
struct def_s *def;
|
||||||
int offset;
|
int offset;
|
||||||
struct type_s *type;
|
struct type_s *type;
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
|
|
||||||
struct def_s;
|
struct def_s;
|
||||||
struct ex_value_s;
|
struct ex_value_s;
|
||||||
|
struct tempop_s;
|
||||||
struct type_s;
|
struct type_s;
|
||||||
|
|
||||||
struct ex_value_s *new_string_val (const char *string_val);
|
struct ex_value_s *new_string_val (const char *string_val);
|
||||||
|
@ -49,7 +50,8 @@ struct ex_value_s *new_field_val (int field_val, struct type_s *type,
|
||||||
struct def_s *def);
|
struct def_s *def);
|
||||||
struct ex_value_s *new_func_val (int func_val, struct type_s *type);
|
struct ex_value_s *new_func_val (int func_val, struct type_s *type);
|
||||||
struct ex_value_s *new_pointer_val (int val, struct type_s *type,
|
struct ex_value_s *new_pointer_val (int val, struct type_s *type,
|
||||||
struct def_s *def);
|
struct def_s *def,
|
||||||
|
struct tempop_s *tempop);
|
||||||
struct ex_value_s *new_quaternion_val (const float *quaternion_val);
|
struct ex_value_s *new_quaternion_val (const float *quaternion_val);
|
||||||
struct ex_value_s *new_integer_val (int integer_val);
|
struct ex_value_s *new_integer_val (int integer_val);
|
||||||
struct ex_value_s *new_uinteger_val (int uinteger_val);
|
struct ex_value_s *new_uinteger_val (int uinteger_val);
|
||||||
|
|
|
@ -884,7 +884,7 @@ generate_moveps (dag_t *dag, sblock_t *block, dagnode_t *dagnode)
|
||||||
offset = dstDef->offset;
|
offset = dstDef->offset;
|
||||||
dstDef = dstDef->alias;
|
dstDef = dstDef->alias;
|
||||||
}
|
}
|
||||||
operands[2] = value_operand (new_pointer_val (offset, type, dstDef),
|
operands[2] = value_operand (new_pointer_val (offset, type, dstDef, 0),
|
||||||
operands[1]->expr);
|
operands[1]->expr);
|
||||||
st = build_statement ("<MOVEP>", operands, var->expr);
|
st = build_statement ("<MOVEP>", operands, var->expr);
|
||||||
sblock_add_statement (block, st);
|
sblock_add_statement (block, st);
|
||||||
|
|
|
@ -60,16 +60,40 @@
|
||||||
|
|
||||||
static def_t zero_def;
|
static def_t zero_def;
|
||||||
|
|
||||||
|
static def_t *get_operand_def (expr_t *expr, operand_t *op);
|
||||||
|
|
||||||
static def_t *
|
static def_t *
|
||||||
get_value_def (ex_value_t *value, type_t *type)
|
get_tempop_def (expr_t *expr, tempop_t *tempop, type_t *type)
|
||||||
|
{
|
||||||
|
if (tempop->def) {
|
||||||
|
return tempop->def;
|
||||||
|
}
|
||||||
|
if (tempop->alias) {
|
||||||
|
def_t *tdef = get_operand_def (expr, tempop->alias);
|
||||||
|
int offset = tempop->offset;
|
||||||
|
tempop->def = alias_def (tdef, type, offset);
|
||||||
|
}
|
||||||
|
if (!tempop->def) {
|
||||||
|
tempop->def = temp_def (type);
|
||||||
|
}
|
||||||
|
return tempop->def;
|
||||||
|
}
|
||||||
|
|
||||||
|
static def_t *
|
||||||
|
get_value_def (expr_t *expr, ex_value_t *value, type_t *type)
|
||||||
{
|
{
|
||||||
def_t *def;
|
def_t *def;
|
||||||
|
|
||||||
if (type == &type_short) {
|
if (is_short (type)) {
|
||||||
def = new_def (0, &type_short, 0, sc_extern);
|
def = new_def (0, &type_short, 0, sc_extern);
|
||||||
def->offset = value->v.short_val;
|
def->offset = value->v.short_val;
|
||||||
return def;
|
return def;
|
||||||
}
|
}
|
||||||
|
if (is_pointer (type) && value->v.pointer.tempop
|
||||||
|
&& !value->v.pointer.def) {
|
||||||
|
value->v.pointer.def = get_tempop_def (expr, value->v.pointer.tempop,
|
||||||
|
type->t.fldptr.type);
|
||||||
|
}
|
||||||
def = emit_value (value, 0);
|
def = emit_value (value, 0);
|
||||||
if (type != def->type)
|
if (type != def->type)
|
||||||
return alias_def (def, type, 0);
|
return alias_def (def, type, 0);
|
||||||
|
@ -85,25 +109,13 @@ get_operand_def (expr_t *expr, operand_t *op)
|
||||||
case op_def:
|
case op_def:
|
||||||
return op->o.def;
|
return op->o.def;
|
||||||
case op_value:
|
case op_value:
|
||||||
return get_value_def (op->o.value, op->type);
|
return get_value_def (expr, op->o.value, op->type);
|
||||||
case op_label:
|
case op_label:
|
||||||
op->type = &type_short;
|
op->type = &type_short;
|
||||||
zero_def.type = &type_short;
|
zero_def.type = &type_short;
|
||||||
return &zero_def; //FIXME
|
return &zero_def; //FIXME
|
||||||
case op_temp:
|
case op_temp:
|
||||||
if (op->o.tempop.def) {
|
return get_tempop_def (expr, &op->o.tempop, op->type);
|
||||||
return op->o.tempop.def;
|
|
||||||
}
|
|
||||||
if (op->o.tempop.alias) {
|
|
||||||
def_t *tdef = get_operand_def (expr, op->o.tempop.alias);
|
|
||||||
int offset = op->o.tempop.offset;
|
|
||||||
type_t *type = op->type;
|
|
||||||
op->o.tempop.def = alias_def (tdef, type, offset);
|
|
||||||
}
|
|
||||||
if (!op->o.tempop.def) {
|
|
||||||
op->o.tempop.def = temp_def (op->type);
|
|
||||||
}
|
|
||||||
return op->o.tempop.def;
|
|
||||||
case op_alias:
|
case op_alias:
|
||||||
return get_operand_def (expr, op->o.alias);
|
return get_operand_def (expr, op->o.alias);
|
||||||
case op_nil:
|
case op_nil:
|
||||||
|
|
|
@ -800,7 +800,7 @@ new_pointer_expr (int val, type_t *type, def_t *def)
|
||||||
{
|
{
|
||||||
expr_t *e = new_expr ();
|
expr_t *e = new_expr ();
|
||||||
e->type = ex_value;
|
e->type = ex_value;
|
||||||
e->e.value = new_pointer_val (val, type, def);
|
e->e.value = new_pointer_val (val, type, def, 0);
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2152,7 +2152,7 @@ address_expr (expr_t *e1, expr_t *e2, type_t *t)
|
||||||
if (is_array (type)) {
|
if (is_array (type)) {
|
||||||
e = e1;
|
e = e1;
|
||||||
e->type = ex_value;
|
e->type = ex_value;
|
||||||
e->e.value = new_pointer_val (0, t, def);
|
e->e.value = new_pointer_val (0, t, def, 0);
|
||||||
} else {
|
} else {
|
||||||
e = new_pointer_expr (0, t, def);
|
e = new_pointer_expr (0, t, def);
|
||||||
e->line = e1->line;
|
e->line = e1->line;
|
||||||
|
@ -2218,7 +2218,7 @@ address_expr (expr_t *e1, expr_t *e2, type_t *t)
|
||||||
return e2;
|
return e2;
|
||||||
if (e->type == ex_value && e->e.value->lltype == ev_pointer
|
if (e->type == ex_value && e->e.value->lltype == ev_pointer
|
||||||
&& is_short_val (e2)) {
|
&& is_short_val (e2)) {
|
||||||
e->e.value = new_pointer_val (e->e.value->v.pointer.val + expr_short (e2), t, e->e.value->v.pointer.def);
|
e->e.value = new_pointer_val (e->e.value->v.pointer.val + expr_short (e2), t, e->e.value->v.pointer.def, 0);
|
||||||
} else {
|
} else {
|
||||||
if (!is_short_val (e2) || expr_short (e2)) {
|
if (!is_short_val (e2) || expr_short (e2)) {
|
||||||
if (e->type == ex_expr && e->e.expr.op == '&') {
|
if (e->type == ex_expr && e->e.expr.op == '&') {
|
||||||
|
|
|
@ -197,7 +197,8 @@ new_func_val (int func_val, type_t *type)
|
||||||
}
|
}
|
||||||
|
|
||||||
ex_value_t *
|
ex_value_t *
|
||||||
new_pointer_val (int pointer_val, type_t *type, def_t *def)
|
new_pointer_val (int pointer_val, type_t *type, def_t *def,
|
||||||
|
struct tempop_s *tempop)
|
||||||
{
|
{
|
||||||
ex_value_t val;
|
ex_value_t val;
|
||||||
if (!type) {
|
if (!type) {
|
||||||
|
@ -208,6 +209,7 @@ new_pointer_val (int pointer_val, type_t *type, def_t *def)
|
||||||
val.v.pointer.val = pointer_val;
|
val.v.pointer.val = pointer_val;
|
||||||
val.v.pointer.type = type;
|
val.v.pointer.type = type;
|
||||||
val.v.pointer.def = def;
|
val.v.pointer.def = def;
|
||||||
|
val.v.pointer.tempop = tempop;
|
||||||
return find_value (&val);
|
return find_value (&val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,18 +40,20 @@ Rect o = { { 5, 6}, {7, 8} };
|
||||||
int main (void)
|
int main (void)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
int ok;
|
||||||
|
|
||||||
bar(&obj, nil, &o, obj.offset);
|
bar(&obj, nil, &o, obj.offset);
|
||||||
printf ("%d %d %d %d\n", o.offset.x, o.offset.y,
|
ok = (o.offset.x == 0 && o.offset.y == 0
|
||||||
o.extent.width, o.extent.height);
|
&& o.extent.width == 3 && o.extent.height == 4);
|
||||||
if not (o.offset.x == 0 && o.offset.y == 0
|
ret |= !ok;
|
||||||
&& o.extent.width == 3 && o.extent.height == 4)
|
printf ("%d %d %d %d %d\n", o.offset.x, o.offset.y,
|
||||||
ret |= 1;
|
o.extent.width, o.extent.height, ok);
|
||||||
|
|
||||||
baz(&obj, nil, &o, obj.offset);
|
baz(&obj, nil, &o, obj.offset);
|
||||||
printf ("%d %d %d %d\n", o.offset.x, o.offset.y,
|
ok = (o.offset.x == 1 && o.offset.y == 2
|
||||||
o.extent.width, o.extent.height);
|
&& o.extent.width == 3 && o.extent.height == 4);
|
||||||
if not (o.offset.x == 1 && o.offset.y == 2
|
ret |= !ok;
|
||||||
&& o.extent.width == 3 && o.extent.height == 4)
|
printf ("%d %d %d %d %d\n", o.offset.x, o.offset.y,
|
||||||
ret |= 1;
|
o.extent.width, o.extent.height, ok);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -138,6 +138,7 @@ init_qf (void)
|
||||||
|
|
||||||
cvar_t *debug = Cvar_Get ("pr_debug", "2", 0, 0, 0);
|
cvar_t *debug = Cvar_Get ("pr_debug", "2", 0, 0, 0);
|
||||||
Cvar_Get ("pr_boundscheck", "2", 0, 0, 0);
|
Cvar_Get ("pr_boundscheck", "2", 0, 0, 0);
|
||||||
|
Cvar_Get ("pr_deadbeef_locals", "1", 0, 0, 0);
|
||||||
|
|
||||||
if (options.trace > 1) {
|
if (options.trace > 1) {
|
||||||
Cvar_SetValue (debug, 4);
|
Cvar_SetValue (debug, 4);
|
||||||
|
|
Loading…
Reference in a new issue