better relocations: pointers to structure members now work

This commit is contained in:
Bill Currie 2003-08-21 02:21:30 +00:00
parent 59d321ded5
commit 11c7c27f70
6 changed files with 89 additions and 22 deletions

View file

@ -45,6 +45,10 @@ typedef enum {
rel_def_func,
rel_def_string,
rel_def_field,
rel_op_a_def_ofs,
rel_op_b_def_ofs,
rel_op_c_def_ofs,
rel_def_def_ofs,
} reloc_type;
typedef struct reloc_s {
@ -59,7 +63,10 @@ struct statement_s;
reloc_t *new_reloc (int ofs, reloc_type type);
void relocate_refs (reloc_t *refs, int ofs);
void reloc_op_def (struct def_s *def, int ofs, int field);
void reloc_op_def_ofs (struct def_s *def, int ofs, int field);
void reloc_def_def (struct def_s *def, int ofs);
void reloc_def_def_ofs (struct def_s *def, int ofs);
void reloc_def_func (struct function_s *func, int ofs);
void reloc_def_string (int ofs);
void reloc_def_field (struct def_s *def, int ofs);

View file

@ -97,16 +97,16 @@ codespace_newstatement (codespace_t *codespace)
}
static void
add_statement_ref (def_t *def, dstatement_t *st, reloc_type type)
add_statement_ref (def_t *def, dstatement_t *st, int field)
{
if (def) {
reloc_t *ref = new_reloc (st - pr.code->code, type);
int st_ofs = st - pr.code->code;
if (def->alias)
if (def->alias) {
def = def->alias;
ref->next = def->refs;
def->refs = ref;
reloc_op_def_ofs (def, st_ofs, field);
} else
reloc_op_def (def, st_ofs, field);
def->users--;
def->used = 1;
@ -162,9 +162,9 @@ emit_statement (expr_t *e, opcode_t *op, def_t *var_a, def_t *var_b,
var_c ? var_c->name : "", statement->c);
#endif
add_statement_ref (var_a, statement, rel_op_a_def);
add_statement_ref (var_b, statement, rel_op_b_def);
add_statement_ref (var_c, statement, rel_op_c_def);
add_statement_ref (var_a, statement, 0);
add_statement_ref (var_b, statement, 1);
add_statement_ref (var_c, statement, 2);
if (op->right_associative)
return var_a;
@ -384,11 +384,10 @@ emit_deref_expr (expr_t *e, def_t *dest)
e = e->e.expr.e1;
if (e->type == ex_pointer) {
if (e->e.pointer.def) {
d = new_def (e->e.pointer.type, 0, current_scope);
d = new_def (e->e.pointer.type, 0, e->e.pointer.def->scope);
d->local = e->e.pointer.def->local;
d->ofs = POINTER_VAL (e->e.pointer);
if (d->ofs == e->e.pointer.def->ofs)
d->alias = e->e.pointer.def;
d->ofs = e->e.pointer.val;
d->alias = e->e.pointer.def;
} else if (e->e.pointer.val >= 0 && e->e.pointer.val < 65536) {
d = new_def (e->e.pointer.type, 0, current_scope);
d->ofs = e->e.pointer.val;

View file

@ -1249,7 +1249,7 @@ field_expr (expr_t *e1, expr_t *e2)
e = new_expr ();
e->type = ex_pointer;
e1 = e1->e.expr.e1;
i = POINTER_VAL (e1->e.pointer);
i = e1->e.pointer.val;
e->e.pointer.val = i + field->offset;
e->e.pointer.type = field->type;
return unary_expr ('.', e);

View file

@ -215,6 +215,9 @@ add_relocs (qfo_t *qfo)
case rel_op_a_def:
case rel_op_b_def:
case rel_op_c_def:
case rel_op_a_def_ofs:
case rel_op_b_def_ofs:
case rel_op_c_def_ofs:
reloc->ofs += code_base;
break;
case rel_op_a_op:
@ -232,6 +235,7 @@ add_relocs (qfo_t *qfo)
DATA (reloc->ofs)->func_var = reloc->def + 1;
break;
case rel_def_def:
case rel_def_def_ofs:
reloc->ofs += data_base;
break;
case rel_def_string:
@ -470,6 +474,10 @@ fixup_relocs (void)
case rel_op_c_def:
case rel_def_def:
case rel_def_field:
case rel_op_a_def_ofs:
case rel_op_b_def_ofs:
case rel_op_c_def_ofs:
case rel_def_def_ofs:
def = defs.defs + reloc->def;
if (def->flags & (QFOD_EXTERNAL | QFOD_LOCAL | QFOD_ABSOLUTE))
continue;
@ -498,6 +506,10 @@ fixup_relocs (void)
case rel_op_a_op:
case rel_op_b_op:
case rel_op_c_op:
case rel_op_a_def_ofs:
case rel_op_b_def_ofs:
case rel_op_c_def_ofs:
case rel_def_def_ofs:
break;
case rel_def_op:
DATA (reloc->ofs)->integer_var = reloc->def;
@ -806,8 +818,12 @@ undefined_def (qfo_def_t *def)
qfo_reloc_t *reloc = relocs.relocs + def->relocs;
for (i = 0; i < def->num_relocs; i++, reloc++) {
if ((reloc->type == rel_op_a_def || reloc->type == rel_op_b_def
|| reloc->type == rel_op_c_def)
if ((reloc->type == rel_op_a_def
|| reloc->type == rel_op_b_def
|| reloc->type == rel_op_c_def
|| reloc->type == rel_op_a_def_ofs
|| reloc->type == rel_op_b_def_ofs
|| reloc->type == rel_op_c_def_ofs)
&& lines.lines) {
qfo_func_t *func = funcs.funcs;
qfo_func_t *best = func;

View file

@ -426,11 +426,8 @@ finish_compilation (void)
st_global));
}
for (def = pr.scope->head; def; def = def->def_next) {
if (def->global || def->absolute)
continue;
for (def = pr.scope->head; def; def = def->def_next)
relocate_refs (def->refs, def->ofs);
}
pr.functions = calloc (pr.num_functions + 1, sizeof (dfunction_t));
for (df = pr.functions + 1, f = pr.func_head; f; df++, f = f->next) {
@ -452,8 +449,6 @@ finish_compilation (void)
}
df->parm_start = pr.near_data->size;
for (def = f->scope->head; def; def = def->def_next) {
if (def->absolute)
continue;
def->ofs += pr.near_data->size;
relocate_refs (def->refs, def->ofs);
}

View file

@ -114,6 +114,30 @@ relocate_refs (reloc_t *refs, int ofs)
break;
case rel_def_field:
break;
case rel_op_a_def_ofs:
o = ofs + pr.code->code[refs->ofs].a;
if (o < 0 || o > 65535)
error (0, "def offset out of range");
else
pr.code->code[refs->ofs].a = o;
break;
case rel_op_b_def_ofs:
o = ofs + pr.code->code[refs->ofs].b;
if (o < 0 || o > 65535)
error (0, "def offset out of range");
else
pr.code->code[refs->ofs].b = o;
break;
case rel_op_c_def_ofs:
o = ofs + pr.code->code[refs->ofs].c;
if (o < 0 || o > 65535)
error (0, "def offset out of range");
else
pr.code->code[refs->ofs].c = o;
break;
case rel_def_def_ofs:
G_INT (refs->ofs) += ofs;
break;
}
refs = refs->next;
}
@ -132,6 +156,24 @@ new_reloc (int ofs, reloc_type type)
return ref;
}
void
reloc_op_def (def_t *def, int ofs, int field)
{
reloc_t *ref = new_reloc (ofs, rel_op_a_def + field);
ref->next = def->refs;
def->refs = ref;
}
void
reloc_op_def_ofs (def_t *def, int ofs, int field)
{
reloc_t *ref = new_reloc (ofs, rel_op_a_def_ofs + field);
unsigned short x = (&pr.code->code[ofs].a)[field];
printf ("%3d %c %3d %3d %s\n", ofs, 'a' + field, x, def->ofs, def->name);
ref->next = def->refs;
def->refs = ref;
}
void
reloc_def_def (def_t *def, int ofs)
{
@ -140,6 +182,14 @@ reloc_def_def (def_t *def, int ofs)
def->refs = ref;
}
void
reloc_def_def_ofs (def_t *def, int ofs)
{
reloc_t *ref = new_reloc (ofs, rel_def_def_ofs);
ref->next = def->refs;
def->refs = ref;
}
void
reloc_def_func (function_t *func, int ofs)
{