mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-30 08:00:51 +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_value,
|
||||||
op_label,
|
op_label,
|
||||||
op_temp,
|
op_temp,
|
||||||
|
op_alias,
|
||||||
} op_type_e;
|
} op_type_e;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -59,6 +60,7 @@ typedef struct operand_s {
|
||||||
struct ex_value_s *value;
|
struct ex_value_s *value;
|
||||||
struct ex_label_s *label;
|
struct ex_label_s *label;
|
||||||
tempop_t tempop;
|
tempop_t tempop;
|
||||||
|
struct operand_s *alias;
|
||||||
} o;
|
} o;
|
||||||
} operand_t;
|
} operand_t;
|
||||||
|
|
||||||
|
@ -111,6 +113,7 @@ struct dstring_s;
|
||||||
const char *optype_str (op_type_e type);
|
const char *optype_str (op_type_e type);
|
||||||
|
|
||||||
operand_t *temp_operand (struct type_s *type);
|
operand_t *temp_operand (struct type_s *type);
|
||||||
|
operand_t *alias_operand (etype_t type, operand_t *op);
|
||||||
sblock_t *new_sblock (void);
|
sblock_t *new_sblock (void);
|
||||||
statement_t *new_statement (st_type_t type, const char *opcode,
|
statement_t *new_statement (st_type_t type, const char *opcode,
|
||||||
struct expr_s *expr);
|
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++) {
|
for (i = 0; i < 3; i++) {
|
||||||
if ((op = operands[i])) {
|
if ((op = operands[i])) {
|
||||||
|
while (op->op_type == op_alias)
|
||||||
|
op = op->o.alias;
|
||||||
if (op->op_type == op_temp) {
|
if (op->op_type == op_temp) {
|
||||||
while (op->o.tempop.alias)
|
while (op->o.tempop.alias)
|
||||||
op = op->o.tempop.alias;
|
op = op->o.tempop.alias;
|
||||||
|
@ -606,6 +608,13 @@ dag_calc_node_costs (dagnode_t *dagnode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#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 *
|
static operand_t *
|
||||||
generate_assignments (dag_t *dag, sblock_t *block, operand_t *src,
|
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};
|
operand_t *operands[3] = {0, 0, 0};
|
||||||
daglabel_t *var;
|
daglabel_t *var;
|
||||||
|
|
||||||
operands[0] = src;
|
operands[0] = fix_op_type (src, type);
|
||||||
for ( ; var_iter; var_iter = set_next (var_iter)) {
|
for ( ; var_iter; var_iter = set_next (var_iter)) {
|
||||||
var = dag->labels[var_iter->value];
|
var = dag->labels[var_iter->value];
|
||||||
operands[1] = var->op;
|
operands[1] = fix_op_type (var->op, type);
|
||||||
if (!dst)
|
if (!dst)
|
||||||
dst = operands[1];
|
dst = operands[1];
|
||||||
|
|
||||||
|
@ -635,6 +644,7 @@ make_operand (dag_t *dag, sblock_t *block, const dagnode_t *dagnode, int index)
|
||||||
operand_t *op;
|
operand_t *op;
|
||||||
|
|
||||||
op = dagnode->children[index]->value;
|
op = dagnode->children[index]->value;
|
||||||
|
op = fix_op_type (op, dagnode->types[index]);
|
||||||
return op;
|
return op;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -655,9 +665,6 @@ dag_gencode (dag_t *dag, sblock_t *block, dagnode_t *dagnode)
|
||||||
dst = dagnode->label->op;
|
dst = dagnode->label->op;
|
||||||
if ((var_iter = set_first (dagnode->identifiers))) {
|
if ((var_iter = set_first (dagnode->identifiers))) {
|
||||||
type = dst->type;
|
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);
|
dst = generate_assignments (dag, block, dst, var_iter, type);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -671,7 +678,7 @@ dag_gencode (dag_t *dag, sblock_t *block, dagnode_t *dagnode)
|
||||||
} else {
|
} else {
|
||||||
daglabel_t *var = dag->labels[var_iter->value];
|
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);
|
var_iter = set_next (var_iter);
|
||||||
}
|
}
|
||||||
dst = operands[2];
|
dst = operands[2];
|
||||||
|
|
|
@ -96,6 +96,8 @@ get_operand_def (expr_t *expr, operand_t *op)
|
||||||
if (!op->o.tempop.def)
|
if (!op->o.tempop.def)
|
||||||
op->o.tempop.def = temp_def (op->type, op->size);
|
op->o.tempop.def = temp_def (op->type, op->size);
|
||||||
return op->o.tempop.def;
|
return op->o.tempop.def;
|
||||||
|
case op_alias:
|
||||||
|
return get_operand_def (expr, op->o.alias);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -166,6 +166,8 @@ flowvar_get_def (flowvar_t *var)
|
||||||
return 0;
|
return 0;
|
||||||
case op_temp:
|
case op_temp:
|
||||||
return op->o.tempop.def;
|
return op->o.tempop.def;
|
||||||
|
case op_alias:
|
||||||
|
internal_error (0, "unexpected alias operand");
|
||||||
}
|
}
|
||||||
internal_error (0, "oops, blue pill");
|
internal_error (0, "oops, blue pill");
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -127,6 +127,13 @@ operand_string (operand_t *op)
|
||||||
op->o.tempop.alias,
|
op->o.tempop.alias,
|
||||||
op->o.tempop.alias->o.tempop.users);
|
op->o.tempop.alias->o.tempop.users);
|
||||||
return va ("<tmp %p:%d>", op, op->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 ("??");
|
return ("??");
|
||||||
}
|
}
|
||||||
|
@ -192,6 +199,10 @@ print_operand (operand_t *op)
|
||||||
if (op->o.tempop.def)
|
if (op->o.tempop.def)
|
||||||
printf (" %s", op->o.tempop.def->name);
|
printf (" %s", op->o.tempop.def->name);
|
||||||
break;
|
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;
|
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 *
|
static operand_t *
|
||||||
short_operand (short short_val)
|
short_operand (short short_val)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue