mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-23 04:42:32 +00:00
[qfcc] Rewrite operand_address to be much simpler
It now creates a pointer value and returns that rather than generating an address statement.
This commit is contained in:
parent
a0c28a5ac5
commit
b58deb5680
1 changed files with 26 additions and 23 deletions
|
@ -658,39 +658,42 @@ expr_address (sblock_t *sblock, expr_t *e, operand_t **op)
|
||||||
return sblock;
|
return sblock;
|
||||||
}
|
}
|
||||||
|
|
||||||
static sblock_t *
|
static operand_t *
|
||||||
operand_address (sblock_t *sblock, operand_t *reference, operand_t **op,
|
operand_address (operand_t *reference, expr_t *e)
|
||||||
expr_t *e)
|
|
||||||
{
|
{
|
||||||
statement_t *s;
|
def_t *def;
|
||||||
type_t *type;
|
type_t *type;
|
||||||
|
int offset = 0;
|
||||||
|
|
||||||
|
type = reference->type;
|
||||||
switch (reference->op_type) {
|
switch (reference->op_type) {
|
||||||
case op_def:
|
case op_def:
|
||||||
case op_temp:
|
// assumes aliasing is only one level deep which should be the
|
||||||
case op_alias:
|
// case
|
||||||
// build an address expression so dags can extract the correct
|
def = reference->o.def;
|
||||||
// type. address_expr cannot be used because reference might not
|
if (def->alias) {
|
||||||
// be something it likes
|
offset = def->offset;
|
||||||
e = expr_file_line (new_unary_expr ('&', e), e);
|
def = def->alias;
|
||||||
type = pointer_type (reference->type);
|
|
||||||
e->e.expr.type = type;
|
|
||||||
|
|
||||||
s = new_statement (st_expr, "&", e);
|
|
||||||
s->opa = reference;
|
|
||||||
s->opc = temp_operand (type, e);
|
|
||||||
sblock_add_statement (sblock, s);
|
|
||||||
if (op) {
|
|
||||||
*(op) = s->opc;
|
|
||||||
}
|
}
|
||||||
return sblock;
|
return value_operand (new_pointer_val (offset, type, def, 0), e);
|
||||||
|
case op_temp:
|
||||||
|
// assumes aliasing is only one level deep which should be the
|
||||||
|
// case
|
||||||
|
if (reference->o.tempop.alias) {
|
||||||
|
offset = reference->o.tempop.offset;
|
||||||
|
reference = reference->o.tempop.alias;
|
||||||
|
}
|
||||||
|
return value_operand (new_pointer_val (offset, type, 0,
|
||||||
|
&reference->o.tempop), e);
|
||||||
|
case op_alias:
|
||||||
|
//op_alias comes only from alias_operand and that is called
|
||||||
|
// by dags, so not expected
|
||||||
case op_value:
|
case op_value:
|
||||||
case op_label:
|
case op_label:
|
||||||
case op_nil:
|
case op_nil:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
internal_error ((*op)->expr,
|
internal_error (e, "invalid operand type for operand address: %s",
|
||||||
"invalid operand type for operand address: %s",
|
|
||||||
op_type_names[reference->op_type]);
|
op_type_names[reference->op_type]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -763,7 +766,7 @@ expr_assign_copy (sblock_t *sblock, expr_t *e, operand_t **op, operand_t *src)
|
||||||
*op = src;
|
*op = src;
|
||||||
}
|
}
|
||||||
if (is_indirect (dst_expr) || is_indirect (src_expr)) {
|
if (is_indirect (dst_expr) || is_indirect (src_expr)) {
|
||||||
sblock = operand_address (sblock, src, &src, src_expr);
|
src = operand_address (src, src_expr);
|
||||||
goto dereference_dst;
|
goto dereference_dst;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue