Mercurial > hg > index.cgi
changeset 61:ccaecdff3fc2
Make structure definitions not affect current assembly address and fix up cosmetic offset display in listings
author | lost@l-w.ca |
---|---|
date | Wed, 06 Apr 2011 21:35:49 -0600 |
parents | 9ded7e6fc1b0 |
children | 5b10ff307463 |
files | lwasm/lwasm.h lwasm/struct.c |
diffstat | 2 files changed, 58 insertions(+), 79 deletions(-) [+] |
line wrap: on
line diff
--- a/lwasm/lwasm.h Wed Apr 06 20:31:37 2011 -0600 +++ b/lwasm/lwasm.h Wed Apr 06 21:35:49 2011 -0600 @@ -282,7 +282,7 @@ structtab_t *structs; // defined structures structtab_t *cstruct; // current structure - + lw_expr_t savedaddr; // old address counter before struct started int exportcheck; // set if we need to collapse out the section base to 0 };
--- a/lwasm/struct.c Wed Apr 06 20:31:37 2011 -0600 +++ b/lwasm/struct.c Wed Apr 06 21:35:49 2011 -0600 @@ -70,63 +70,70 @@ l -> len = 0; l -> symset = 1; + + // save current assembly address and initialize to 0 + as -> savedaddr = l -> addr; + l -> addr = lw_expr_build(lw_expr_type_int, 0); } -void pseudo_endstruct_aux(asmstate_t *as, line_t *l, structtab_field_t *e, const char *prefix, int *coff) +static void instantiate_struct(asmstate_t *as, line_t *l, structtab_t *s, char *pref, lw_expr_t baseaddr) { - char *symname = NULL; - lw_expr_t te1, te2; int len; + char *t; + int plen; + int addr = 0; + lw_expr_t te, te2; + structtab_field_t *e; + + if (baseaddr == NULL) + baseaddr = l -> addr; - while (e) + plen = strlen(pref); + for (e = s -> fields; e; e = e -> next) { if (e -> name) { - len = strlen(prefix) + strlen(e -> name) + 1; - symname = lw_alloc(len + 1); - sprintf(symname, "%s.%s", prefix, e -> name); + len = plen + strlen(e -> name) + 1; + t = lw_alloc(len + 1); + sprintf(t, "%s.%s", pref, e -> name); } else { - len = strlen(prefix) + 30; - symname = lw_alloc(len + 1); - sprintf(symname, "%s.____%d", prefix, *coff); + len = plen + 30; + t = lw_alloc(len + 1); + sprintf(t, "%s.____%d", pref, addr); } - - // register the symbol - te1 = lw_expr_build(lw_expr_type_int, *coff); - te2 = lw_expr_build(lw_expr_type_oper, lw_expr_oper_plus, te1, l -> addr); - register_symbol(as, l, symname, te2, symbol_flag_nocheck); - lw_expr_destroy(te2); - lw_expr_destroy(te1); + + te = lw_expr_build(lw_expr_type_int, addr); + te2 = lw_expr_build(lw_expr_type_oper, lw_expr_oper_plus, te, baseaddr); + register_symbol(as, l, t, te2, symbol_flag_nocheck); + lw_expr_destroy(te); if (e -> substruct) { - char *t; - len = strlen(symname) + 8; - t = lw_alloc(len + 1); - sprintf(t, "sizeof{%s}", symname); - te1 = lw_expr_build(lw_expr_type_int, e -> substruct -> size); - register_symbol(as, l, t, te1, symbol_flag_nocheck); - lw_expr_destroy(te1); - lw_free(t); - pseudo_endstruct_aux(as, l, e -> substruct -> fields, symname, coff); + instantiate_struct(as, l, e -> substruct, t, te2); } - else - { - *coff += e -> size; - } - e = e -> next; + + lw_expr_destroy(te2); + + lw_free(t); + addr += e -> size; } + + /* register the "sizeof" symbol */ + len = plen + 8; + t = lw_alloc(len + 1); + sprintf(t, "sizeof{%s}", pref); + te = lw_expr_build(lw_expr_type_int, s -> size); + register_symbol(as, l, t, te, symbol_flag_nocheck); + lw_expr_destroy(te); + lw_free(t); } PARSEFUNC(pseudo_parse_endstruct) { - char *t; - int coff = 0; lw_expr_t te; - int len; if (as -> instruct == 0) { @@ -135,20 +142,20 @@ return; } - len = strlen(as -> cstruct -> name) + 8; - t = lw_alloc(len + 1); - sprintf(t, "sizeof{%s}", as -> cstruct -> name); - te = lw_expr_build(lw_expr_type_int, as -> cstruct -> size); - register_symbol(as, l, t, te, symbol_flag_nocheck); + te = lw_expr_build(lw_expr_type_int, 0); + + // make all the relevant generic struct symbols + instantiate_struct(as, l, as -> cstruct, as -> cstruct -> name, te); lw_expr_destroy(te); - lw_free(t); l -> soff = as -> cstruct -> size; as -> instruct = 0; skip_operand(p); - pseudo_endstruct_aux(as, l, as -> cstruct -> fields, as -> cstruct -> name, &coff); + lw_expr_destroy(l -> addr); + l -> addr = as -> savedaddr; + as -> savedaddr = NULL; l -> len = 0; } @@ -182,10 +189,6 @@ int expand_struct(asmstate_t *as, line_t *l, char **p, char *opc) { structtab_t *s; - char *t; - lw_expr_t te; - int addr = 0; - int len; debug_message(as, 200, "Checking for structure expansion: %s", opc); @@ -206,48 +209,24 @@ return -1; } - if (as -> instruct) - { - lwasm_register_error(as, l, "Nested structures not currently supported"); - return -1; - } - l -> len = s -> size; if (as -> instruct) { -// len = strlen(as -> cstruct -> name) + strlen(l -> sym) + 9; -// t = lw_alloc(len + 1); -// sprintf(t, "sizeof{%s.%s}", as -> cstruct -> name, l -> sym); + /* register substruct here */ + register_struct_entry(as, l, s -> size, s); + /* mark the symbol consumed */ + l -> symset = 1; + l -> len = 0; + return 0; } else { - len = strlen(l -> sym) + 8; - t = lw_alloc(len + 1); - sprintf(t, "sizeof{%s}", l -> sym); - te = lw_expr_build(lw_expr_type_int, s -> size); - register_symbol(as, l, t, te, symbol_flag_nocheck); - lw_expr_destroy(te); - lw_free(t); + /* instantiate the struct here */ + instantiate_struct(as, l, s, l -> sym, NULL); + return 0; } - if (as -> instruct) - { -// len = strlen(as -> cstruct -> name) + strlen(l -> sym) + 1; -// t = lw_alloc(len + 1); -// sprintf(t, "%s.%s", as -> cstruct -> name, l -> sym); - } - else - { - t = lw_strdup(l -> sym); - pseudo_endstruct_aux(as, l, s -> fields, t, &addr); - lw_free(t); - } - - if (as -> instruct) - l -> symset = 1; - if (as -> instruct) - register_struct_entry(as, l, s -> size, s); return 0; }