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_func,
rel_def_string, rel_def_string,
rel_def_field, rel_def_field,
rel_op_a_def_ofs,
rel_op_b_def_ofs,
rel_op_c_def_ofs,
rel_def_def_ofs,
} reloc_type; } reloc_type;
typedef struct reloc_s { typedef struct reloc_s {
@ -59,7 +63,10 @@ struct statement_s;
reloc_t *new_reloc (int ofs, reloc_type type); reloc_t *new_reloc (int ofs, reloc_type type);
void relocate_refs (reloc_t *refs, int ofs); 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 (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_func (struct function_s *func, int ofs);
void reloc_def_string (int ofs); void reloc_def_string (int ofs);
void reloc_def_field (struct def_s *def, 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 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) { 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; def = def->alias;
reloc_op_def_ofs (def, st_ofs, field);
ref->next = def->refs; } else
def->refs = ref; reloc_op_def (def, st_ofs, field);
def->users--; def->users--;
def->used = 1; 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); var_c ? var_c->name : "", statement->c);
#endif #endif
add_statement_ref (var_a, statement, rel_op_a_def); add_statement_ref (var_a, statement, 0);
add_statement_ref (var_b, statement, rel_op_b_def); add_statement_ref (var_b, statement, 1);
add_statement_ref (var_c, statement, rel_op_c_def); add_statement_ref (var_c, statement, 2);
if (op->right_associative) if (op->right_associative)
return var_a; return var_a;
@ -384,11 +384,10 @@ emit_deref_expr (expr_t *e, def_t *dest)
e = e->e.expr.e1; e = e->e.expr.e1;
if (e->type == ex_pointer) { if (e->type == ex_pointer) {
if (e->e.pointer.def) { 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->local = e->e.pointer.def->local;
d->ofs = POINTER_VAL (e->e.pointer); d->ofs = e->e.pointer.val;
if (d->ofs == e->e.pointer.def->ofs) d->alias = e->e.pointer.def;
d->alias = e->e.pointer.def;
} else if (e->e.pointer.val >= 0 && e->e.pointer.val < 65536) { } else if (e->e.pointer.val >= 0 && e->e.pointer.val < 65536) {
d = new_def (e->e.pointer.type, 0, current_scope); d = new_def (e->e.pointer.type, 0, current_scope);
d->ofs = e->e.pointer.val; d->ofs = e->e.pointer.val;

View file

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

View file

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

View file

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

View file

@ -114,6 +114,30 @@ relocate_refs (reloc_t *refs, int ofs)
break; break;
case rel_def_field: case rel_def_field:
break; 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; refs = refs->next;
} }
@ -132,6 +156,24 @@ new_reloc (int ofs, reloc_type type)
return ref; 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 void
reloc_def_def (def_t *def, int ofs) reloc_def_def (def_t *def, int ofs)
{ {
@ -140,6 +182,14 @@ reloc_def_def (def_t *def, int ofs)
def->refs = ref; 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 void
reloc_def_func (function_t *func, int ofs) reloc_def_func (function_t *func, int ofs)
{ {