mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-22 20:41:20 +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;
|
||||
struct type_s *type;
|
||||
struct def_s *def;
|
||||
struct tempop_s *tempop;
|
||||
} ex_pointer_t;
|
||||
|
||||
typedef struct ex_func_s {
|
||||
|
|
|
@ -41,7 +41,7 @@ typedef enum {
|
|||
op_nil,
|
||||
} op_type_e;
|
||||
|
||||
typedef struct {
|
||||
typedef struct tempop_s {
|
||||
struct def_s *def;
|
||||
int offset;
|
||||
struct type_s *type;
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
|
||||
struct def_s;
|
||||
struct ex_value_s;
|
||||
struct tempop_s;
|
||||
struct type_s;
|
||||
|
||||
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 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 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_integer_val (int integer_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;
|
||||
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);
|
||||
st = build_statement ("<MOVEP>", operands, var->expr);
|
||||
sblock_add_statement (block, st);
|
||||
|
|
|
@ -60,16 +60,40 @@
|
|||
|
||||
static def_t zero_def;
|
||||
|
||||
static def_t *get_operand_def (expr_t *expr, operand_t *op);
|
||||
|
||||
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;
|
||||
|
||||
if (type == &type_short) {
|
||||
if (is_short (type)) {
|
||||
def = new_def (0, &type_short, 0, sc_extern);
|
||||
def->offset = value->v.short_val;
|
||||
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);
|
||||
if (type != def->type)
|
||||
return alias_def (def, type, 0);
|
||||
|
@ -85,25 +109,13 @@ get_operand_def (expr_t *expr, operand_t *op)
|
|||
case op_def:
|
||||
return op->o.def;
|
||||
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:
|
||||
op->type = &type_short;
|
||||
zero_def.type = &type_short;
|
||||
return &zero_def; //FIXME
|
||||
case op_temp:
|
||||
if (op->o.tempop.def) {
|
||||
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;
|
||||
return get_tempop_def (expr, &op->o.tempop, op->type);
|
||||
case op_alias:
|
||||
return get_operand_def (expr, op->o.alias);
|
||||
case op_nil:
|
||||
|
|
|
@ -800,7 +800,7 @@ new_pointer_expr (int val, type_t *type, def_t *def)
|
|||
{
|
||||
expr_t *e = new_expr ();
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -2152,7 +2152,7 @@ address_expr (expr_t *e1, expr_t *e2, type_t *t)
|
|||
if (is_array (type)) {
|
||||
e = e1;
|
||||
e->type = ex_value;
|
||||
e->e.value = new_pointer_val (0, t, def);
|
||||
e->e.value = new_pointer_val (0, t, def, 0);
|
||||
} else {
|
||||
e = new_pointer_expr (0, t, def);
|
||||
e->line = e1->line;
|
||||
|
@ -2218,7 +2218,7 @@ address_expr (expr_t *e1, expr_t *e2, type_t *t)
|
|||
return e2;
|
||||
if (e->type == ex_value && e->e.value->lltype == ev_pointer
|
||||
&& 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 {
|
||||
if (!is_short_val (e2) || expr_short (e2)) {
|
||||
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 *
|
||||
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;
|
||||
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.type = type;
|
||||
val.v.pointer.def = def;
|
||||
val.v.pointer.tempop = tempop;
|
||||
return find_value (&val);
|
||||
}
|
||||
|
||||
|
|
|
@ -40,18 +40,20 @@ Rect o = { { 5, 6}, {7, 8} };
|
|||
int main (void)
|
||||
{
|
||||
int ret = 0;
|
||||
int ok;
|
||||
|
||||
bar(&obj, nil, &o, obj.offset);
|
||||
printf ("%d %d %d %d\n", o.offset.x, o.offset.y,
|
||||
o.extent.width, o.extent.height);
|
||||
if not (o.offset.x == 0 && o.offset.y == 0
|
||||
&& o.extent.width == 3 && o.extent.height == 4)
|
||||
ret |= 1;
|
||||
ok = (o.offset.x == 0 && o.offset.y == 0
|
||||
&& o.extent.width == 3 && o.extent.height == 4);
|
||||
ret |= !ok;
|
||||
printf ("%d %d %d %d %d\n", o.offset.x, o.offset.y,
|
||||
o.extent.width, o.extent.height, ok);
|
||||
|
||||
baz(&obj, nil, &o, obj.offset);
|
||||
printf ("%d %d %d %d\n", o.offset.x, o.offset.y,
|
||||
o.extent.width, o.extent.height);
|
||||
if not (o.offset.x == 1 && o.offset.y == 2
|
||||
&& o.extent.width == 3 && o.extent.height == 4)
|
||||
ret |= 1;
|
||||
ok = (o.offset.x == 1 && o.offset.y == 2
|
||||
&& o.extent.width == 3 && o.extent.height == 4);
|
||||
ret |= !ok;
|
||||
printf ("%d %d %d %d %d\n", o.offset.x, o.offset.y,
|
||||
o.extent.width, o.extent.height, ok);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -138,6 +138,7 @@ init_qf (void)
|
|||
|
||||
cvar_t *debug = Cvar_Get ("pr_debug", "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) {
|
||||
Cvar_SetValue (debug, 4);
|
||||
|
|
Loading…
Reference in a new issue