mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-17 01:11:45 +00:00
[qfcc] Save operand creator return address
This commit is contained in:
parent
51a30de9c5
commit
7d5644e055
2 changed files with 23 additions and 9 deletions
|
@ -58,6 +58,7 @@ typedef struct operand_s {
|
||||||
struct type_s *type; ///< possibly override def's type
|
struct type_s *type; ///< possibly override def's type
|
||||||
int size; ///< for structures
|
int size; ///< for structures
|
||||||
struct expr_s *expr; ///< expression generating this operand
|
struct expr_s *expr; ///< expression generating this operand
|
||||||
|
void *return_addr; ///< who created this operand
|
||||||
union {
|
union {
|
||||||
struct def_s *def;
|
struct def_s *def;
|
||||||
struct ex_value_s *value;
|
struct ex_value_s *value;
|
||||||
|
@ -126,6 +127,7 @@ int tempop_visit_all (tempop_t *tempop, int overlap,
|
||||||
int (*visit) (tempop_t *, void *), void *data);
|
int (*visit) (tempop_t *, void *), void *data);
|
||||||
operand_t *alias_operand (struct type_s *type, operand_t *op,
|
operand_t *alias_operand (struct type_s *type, operand_t *op,
|
||||||
struct expr_s *expr);
|
struct expr_s *expr);
|
||||||
|
operand_t *label_operand (struct expr_s *label);
|
||||||
void free_operand (operand_t *op);
|
void free_operand (operand_t *op);
|
||||||
|
|
||||||
sblock_t *new_sblock (void);
|
sblock_t *new_sblock (void);
|
||||||
|
|
|
@ -274,12 +274,13 @@ new_statement (st_type_t type, const char *opcode, expr_t *expr)
|
||||||
}
|
}
|
||||||
|
|
||||||
static operand_t *
|
static operand_t *
|
||||||
new_operand (op_type_e op, expr_t *expr)
|
new_operand (op_type_e op, expr_t *expr, void *return_addr)
|
||||||
{
|
{
|
||||||
operand_t *operand;
|
operand_t *operand;
|
||||||
ALLOC (256, operand_t, operands, operand);
|
ALLOC (256, operand_t, operands, operand);
|
||||||
operand->op_type = op;
|
operand->op_type = op;
|
||||||
operand->expr = expr;
|
operand->expr = expr;
|
||||||
|
operand->return_addr = return_addr;
|
||||||
return operand;
|
return operand;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -319,7 +320,7 @@ def_operand (def_t *def, type_t *type, expr_t *expr)
|
||||||
|
|
||||||
if (!type)
|
if (!type)
|
||||||
type = def->type;
|
type = def->type;
|
||||||
op = new_operand (op_def, expr);
|
op = new_operand (op_def, expr, __builtin_return_address (0));
|
||||||
op->type = type;
|
op->type = type;
|
||||||
op->size = type_size (type);
|
op->size = type_size (type);
|
||||||
op->o.def = def;
|
op->o.def = def;
|
||||||
|
@ -339,7 +340,7 @@ operand_t *
|
||||||
value_operand (ex_value_t *value, expr_t *expr)
|
value_operand (ex_value_t *value, expr_t *expr)
|
||||||
{
|
{
|
||||||
operand_t *op;
|
operand_t *op;
|
||||||
op = new_operand (op_value, expr);
|
op = new_operand (op_value, expr, __builtin_return_address (0));
|
||||||
op->type = value->type;
|
op->type = value->type;
|
||||||
op->o.value = value;
|
op->o.value = value;
|
||||||
return op;
|
return op;
|
||||||
|
@ -348,7 +349,7 @@ value_operand (ex_value_t *value, expr_t *expr)
|
||||||
operand_t *
|
operand_t *
|
||||||
temp_operand (type_t *type, expr_t *expr)
|
temp_operand (type_t *type, expr_t *expr)
|
||||||
{
|
{
|
||||||
operand_t *op = new_operand (op_temp, expr);
|
operand_t *op = new_operand (op_temp, expr, __builtin_return_address (0));
|
||||||
|
|
||||||
op->o.tempop.type = type;
|
op->o.tempop.type = type;
|
||||||
op->type = type;
|
op->type = type;
|
||||||
|
@ -423,13 +424,26 @@ alias_operand (type_t *type, operand_t *op, expr_t *expr)
|
||||||
"aliasing operand with type of different size: %d, %d",
|
"aliasing operand with type of different size: %d, %d",
|
||||||
type_size (type), type_size (op->type));
|
type_size (type), type_size (op->type));
|
||||||
}
|
}
|
||||||
aop = new_operand (op_alias, expr);
|
aop = new_operand (op_alias, expr, __builtin_return_address (0));
|
||||||
aop->o.alias = op;
|
aop->o.alias = op;
|
||||||
aop->type = type;
|
aop->type = type;
|
||||||
aop->size = type_size (type);
|
aop->size = type_size (type);
|
||||||
return aop;
|
return aop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
operand_t *
|
||||||
|
label_operand (expr_t *label)
|
||||||
|
{
|
||||||
|
operand_t *lop;
|
||||||
|
|
||||||
|
if (label->type != ex_label) {
|
||||||
|
internal_error (label, "not a label expression");
|
||||||
|
}
|
||||||
|
lop = new_operand (op_label, label, __builtin_return_address (0));
|
||||||
|
lop->o.label = &label->e.label;
|
||||||
|
return lop;
|
||||||
|
}
|
||||||
|
|
||||||
static operand_t *
|
static operand_t *
|
||||||
short_operand (short short_val, expr_t *expr)
|
short_operand (short short_val, expr_t *expr)
|
||||||
{
|
{
|
||||||
|
@ -595,8 +609,7 @@ statement_branch (sblock_t *sblock, expr_t *e)
|
||||||
|
|
||||||
if (e->type == ex_uexpr && e->e.expr.op == 'g') {
|
if (e->type == ex_uexpr && e->e.expr.op == 'g') {
|
||||||
s = new_statement (st_flow, "<GOTO>", e);
|
s = new_statement (st_flow, "<GOTO>", e);
|
||||||
s->opa = new_operand (op_label, e);
|
s->opa = label_operand (e->e.expr.e1);
|
||||||
s->opa->o.label = &e->e.expr.e1->e.label;
|
|
||||||
} else {
|
} else {
|
||||||
if (e->e.expr.op == 'g') {
|
if (e->e.expr.op == 'g') {
|
||||||
s = new_statement (st_flow, "<JUMPB>", e);
|
s = new_statement (st_flow, "<JUMPB>", e);
|
||||||
|
@ -606,8 +619,7 @@ statement_branch (sblock_t *sblock, expr_t *e)
|
||||||
opcode = convert_op (e->e.expr.op);
|
opcode = convert_op (e->e.expr.op);
|
||||||
s = new_statement (st_flow, opcode, e);
|
s = new_statement (st_flow, opcode, e);
|
||||||
sblock = statement_subexpr (sblock, e->e.expr.e1, &s->opa);
|
sblock = statement_subexpr (sblock, e->e.expr.e1, &s->opa);
|
||||||
s->opb = new_operand (op_label, e);
|
s->opb = label_operand (e->e.expr.e2);
|
||||||
s->opb->o.label = &e->e.expr.e2->e.label;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue