mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-26 22:31:05 +00:00
Resurrect alias operands.
It turns out they are necessary for the code output from dags. This fixes the ice for *to = *from++;
This commit is contained in:
parent
8452f69a21
commit
7607c7d649
5 changed files with 45 additions and 6 deletions
|
@ -37,6 +37,7 @@ typedef enum {
|
|||
op_value,
|
||||
op_label,
|
||||
op_temp,
|
||||
op_alias,
|
||||
} op_type_e;
|
||||
|
||||
typedef struct {
|
||||
|
@ -59,6 +60,7 @@ typedef struct operand_s {
|
|||
struct ex_value_s *value;
|
||||
struct ex_label_s *label;
|
||||
tempop_t tempop;
|
||||
struct operand_s *alias;
|
||||
} o;
|
||||
} operand_t;
|
||||
|
||||
|
@ -111,6 +113,7 @@ struct dstring_s;
|
|||
const char *optype_str (op_type_e type);
|
||||
|
||||
operand_t *temp_operand (struct type_s *type);
|
||||
operand_t *alias_operand (etype_t type, operand_t *op);
|
||||
sblock_t *new_sblock (void);
|
||||
statement_t *new_statement (st_type_t type, const char *opcode,
|
||||
struct expr_s *expr);
|
||||
|
|
|
@ -560,6 +560,8 @@ build_statement (const char *opcode, operand_t **operands, expr_t *expr)
|
|||
|
||||
for (i = 0; i < 3; i++) {
|
||||
if ((op = operands[i])) {
|
||||
while (op->op_type == op_alias)
|
||||
op = op->o.alias;
|
||||
if (op->op_type == op_temp) {
|
||||
while (op->o.tempop.alias)
|
||||
op = op->o.tempop.alias;
|
||||
|
@ -606,6 +608,13 @@ dag_calc_node_costs (dagnode_t *dagnode)
|
|||
}
|
||||
}
|
||||
#endif
|
||||
static operand_t *
|
||||
fix_op_type (operand_t *op, etype_t type)
|
||||
{
|
||||
if (op && op->op_type != op_label && op->type != type)
|
||||
op = alias_operand (type, op);
|
||||
return op;
|
||||
}
|
||||
|
||||
static operand_t *
|
||||
generate_assignments (dag_t *dag, sblock_t *block, operand_t *src,
|
||||
|
@ -616,10 +625,10 @@ generate_assignments (dag_t *dag, sblock_t *block, operand_t *src,
|
|||
operand_t *operands[3] = {0, 0, 0};
|
||||
daglabel_t *var;
|
||||
|
||||
operands[0] = src;
|
||||
operands[0] = fix_op_type (src, type);
|
||||
for ( ; var_iter; var_iter = set_next (var_iter)) {
|
||||
var = dag->labels[var_iter->value];
|
||||
operands[1] = var->op;
|
||||
operands[1] = fix_op_type (var->op, type);
|
||||
if (!dst)
|
||||
dst = operands[1];
|
||||
|
||||
|
@ -635,6 +644,7 @@ make_operand (dag_t *dag, sblock_t *block, const dagnode_t *dagnode, int index)
|
|||
operand_t *op;
|
||||
|
||||
op = dagnode->children[index]->value;
|
||||
op = fix_op_type (op, dagnode->types[index]);
|
||||
return op;
|
||||
}
|
||||
|
||||
|
@ -655,9 +665,6 @@ dag_gencode (dag_t *dag, sblock_t *block, dagnode_t *dagnode)
|
|||
dst = dagnode->label->op;
|
||||
if ((var_iter = set_first (dagnode->identifiers))) {
|
||||
type = dst->type;
|
||||
//if (dst->op_type == op_def
|
||||
// && !strcmp (dst->o.def->name, ".return"))
|
||||
// type = dag->flownode->return_type.in;
|
||||
dst = generate_assignments (dag, block, dst, var_iter, type);
|
||||
}
|
||||
break;
|
||||
|
@ -671,7 +678,7 @@ dag_gencode (dag_t *dag, sblock_t *block, dagnode_t *dagnode)
|
|||
} else {
|
||||
daglabel_t *var = dag->labels[var_iter->value];
|
||||
|
||||
operands[2] = var->op;
|
||||
operands[2] = fix_op_type (var->op, type);
|
||||
var_iter = set_next (var_iter);
|
||||
}
|
||||
dst = operands[2];
|
||||
|
|
|
@ -96,6 +96,8 @@ get_operand_def (expr_t *expr, operand_t *op)
|
|||
if (!op->o.tempop.def)
|
||||
op->o.tempop.def = temp_def (op->type, op->size);
|
||||
return op->o.tempop.def;
|
||||
case op_alias:
|
||||
return get_operand_def (expr, op->o.alias);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -166,6 +166,8 @@ flowvar_get_def (flowvar_t *var)
|
|||
return 0;
|
||||
case op_temp:
|
||||
return op->o.tempop.def;
|
||||
case op_alias:
|
||||
internal_error (0, "unexpected alias operand");
|
||||
}
|
||||
internal_error (0, "oops, blue pill");
|
||||
return 0;
|
||||
|
|
|
@ -127,6 +127,13 @@ operand_string (operand_t *op)
|
|||
op->o.tempop.alias,
|
||||
op->o.tempop.alias->o.tempop.users);
|
||||
return va ("<tmp %p:%d>", op, op->o.tempop.users);
|
||||
case op_alias:
|
||||
{
|
||||
const char *alias = operand_string (op->o.alias);
|
||||
char *buf = alloca (strlen (alias) + 1);
|
||||
strcpy (buf, alias);
|
||||
return va ("alias(%s,%s)", pr_type_name[op->type], buf);
|
||||
}
|
||||
}
|
||||
return ("??");
|
||||
}
|
||||
|
@ -192,6 +199,10 @@ print_operand (operand_t *op)
|
|||
if (op->o.tempop.def)
|
||||
printf (" %s", op->o.tempop.def->name);
|
||||
break;
|
||||
case op_alias:
|
||||
printf ("alias(%s,", pr_type_name[op->type]);
|
||||
print_operand (op->o.alias);
|
||||
printf (")");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -292,6 +303,20 @@ temp_operand (type_t *type)
|
|||
return op;
|
||||
}
|
||||
|
||||
operand_t *
|
||||
alias_operand (etype_t type, operand_t *op)
|
||||
{
|
||||
operand_t *aop;
|
||||
|
||||
if (pr_type_size[type] != pr_type_size[op->type])
|
||||
internal_error (0, "aliasing operand with type of diffent size");
|
||||
aop = new_operand (op_alias);
|
||||
aop->o.alias = op;
|
||||
aop->type = type;
|
||||
aop->size = pr_type_size[type];
|
||||
return aop;
|
||||
}
|
||||
|
||||
static operand_t *
|
||||
short_operand (short short_val)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue