Use value for pointer operands.

This allows daglabels on pointer operands without a redundant daglabel
pointer.
This commit is contained in:
Bill Currie 2012-07-19 10:51:44 +09:00
parent 0c58cd9067
commit a22260030a
4 changed files with 13 additions and 14 deletions

View file

@ -55,7 +55,6 @@ typedef struct operand_s {
struct symbol_s *symbol;
struct ex_value_s *value;
struct ex_label_s *label;
struct ex_pointer_s *pointer;
tempop_t tempop;
struct operand_s *alias;
} o;

View file

@ -109,16 +109,13 @@ operand_label (operand_t *op)
label = new_label ();
label->op = op;
sym->daglabel = label;
} else if (o->op_type == op_value) {
} else if (o->op_type == op_value || o->op_type == op_pointer) {
val = o->o.value;
if (val->daglabel)
return val->daglabel;
label = new_label ();
label->op = op;
val->daglabel = label;
} else if (o->op_type == op_pointer) {
label = new_label ();
label->op = op;
} else {
internal_error (0, "unexpected operand type: %d", o->op_type);
}

View file

@ -111,10 +111,10 @@ get_operand_def (expr_t *expr, operand_t *op)
op->o.tempop.def = temp_def (op->type, op->size);
return op->o.tempop.def;
case op_pointer:
def = op->o.pointer->def;
if (op->o.pointer->val || op->type != def->type->type) {
def = op->o.value->v.pointer.def;
if (op->o.value->v.pointer.val || op->type != def->type->type) {
def = alias_def (def, ev_types[op->type]);
def->offset = op->o.pointer->val;
def->offset = op->o.value->v.pointer.val;
def->offset_reloc = 1;
}
return def;

View file

@ -109,15 +109,16 @@ operand_string (operand_t *op)
case op_temp:
return va ("tmp %p", op);
case op_pointer:
type = op->o.pointer->type;
if (op->o.pointer->def)
type = op->o.value->v.pointer.type;
if (op->o.value->v.pointer.def)
return va ("(%s)[%d]<%s>",
type ? pr_type_name[type->type] : "???",
op->o.pointer->val, op->o.pointer->def->name);
op->o.value->v.pointer.val,
op->o.value->v.pointer.def->name);
else
return va ("(%s)[%d]",
type ? pr_type_name[type->type] : "???",
op->o.pointer->val);
op->o.value->v.pointer.val);
case op_alias:
return operand_string (op->o.alias);//FIXME better output
}
@ -184,7 +185,9 @@ print_operand (operand_t *op)
printf ("tmp (%s) %p", pr_type_name[op->type], op);
break;
case op_pointer:
printf ("ptr %p", op->o.pointer);
printf ("ptr (%s)[%d]",
pr_type_name[op->o.value->v.pointer.type->type],
op->o.value->v.pointer.val);
break;
case op_alias:
printf ("alias %s ", pr_type_name[op->type]);
@ -662,7 +665,7 @@ expr_deref (sblock_t *sblock, expr_t *deref, operand_t **op)
} else if (e->type == ex_value && e->e.value->type == ev_pointer) {
*op = new_operand (op_pointer);
(*op)->type = low_level_type (e->e.value->v.pointer.type);
(*op)->o.pointer = &e->e.value->v.pointer;
(*op)->o.value = e->e.value;
} else {
statement_t *s;
operand_t *ptr = 0;