mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-22 20:41:20 +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;
|
||||
}
|
||||
|
||||
static sblock_t *
|
||||
operand_address (sblock_t *sblock, operand_t *reference, operand_t **op,
|
||||
expr_t *e)
|
||||
static operand_t *
|
||||
operand_address (operand_t *reference, expr_t *e)
|
||||
{
|
||||
statement_t *s;
|
||||
def_t *def;
|
||||
type_t *type;
|
||||
int offset = 0;
|
||||
|
||||
type = reference->type;
|
||||
switch (reference->op_type) {
|
||||
case op_def:
|
||||
case op_temp:
|
||||
case op_alias:
|
||||
// build an address expression so dags can extract the correct
|
||||
// type. address_expr cannot be used because reference might not
|
||||
// be something it likes
|
||||
e = expr_file_line (new_unary_expr ('&', e), e);
|
||||
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;
|
||||
// assumes aliasing is only one level deep which should be the
|
||||
// case
|
||||
def = reference->o.def;
|
||||
if (def->alias) {
|
||||
offset = def->offset;
|
||||
def = def->alias;
|
||||
}
|
||||
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_label:
|
||||
case op_nil:
|
||||
break;
|
||||
}
|
||||
internal_error ((*op)->expr,
|
||||
"invalid operand type for operand address: %s",
|
||||
internal_error (e, "invalid operand type for operand address: %s",
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue