/* ---------------------------------------------------------------------- */ /* Copyright (C) 1991 by Natrlich! */ /* This file is copyrighted! */ /* Refer to the documentation for details. */ /* ---------------------------------------------------------------------- */ #include "defines.h" #include "nasm.h" #include "labels.h" #include "seg.h" #include "object.h" #include "debug.h" #include "code.h" #include "imm.h" #if __NSTDC__ static unsigned cnt_refs( ref huge *), help_tree( expr huge *); static void hdump_tree( expr huge *), cnt_tree( expr huge *), dump_tree( expr huge *); #else static unsigned cnt_refs(), help_tree(); static void hdump_tree(), cnt_tree(), dump_tree(); #endif static byte huge *dspace; extern label huge *h_global[], huge *h_macro[]; extern lword __lx; #define loop_symbols( p, i, k) \ for( k = 0; k != 2; k++) \ for( i = 0; i != SEP; i++) \ if( p = k ? h_macro[ i] : h_global[ i]) /* ---------------------------------------------------------- */ /* If I weren't so enamored of having all structures kept in */ /* seperate little file areas,this might be done a bit easier */ /* For clean_labels: Get rid of leftover expression trees */ /* that fix nothing (--> error ??) */ /* ---------------------------------------------------------- */ void clean_labels() { register label huge *p; register ref huge *q, huge *old; register expr huge *e; register int i, j; clean_mats(); /* clean macro @... labels */ loop_symbols( p, i, j) do if( dumpable( p) && (q = p->refs)) for( old = 0; q; q = q->next) { for( e = q->ref; ! e->fix; e = e->zonk.t); /* ;; */ if( e->fix == FIX_NOTHING) if( ! old) p->refs = q->next; else old->next = q->next; else old = q; } while( p = p->next); } static unsigned cnt_refs( p) register ref huge *p; { register unsigned i; ENTER("cnt_refs"); for( i = 0; p; i++, p = p->next); LEAVE(); return( i); } lword sym_size() { register lword x = 0; register label huge *p; static unsigned index = 1; register int i; int j; ENTER("sym_size"); loop_symbols( p, i, j) do if( dumpable( p) && (! j || (p->refs))) { x += sizeof( linksymbol); p->no = index++; } while( p = p->next); LEAVE(); return( x); } void sym_makbuf() { register label huge *p; register byte huge *q = __program; register byte huge *s; register int i, j; int k; ENTER("sym_makbuf"); loop_symbols( p, i, k) do if( dumpable( p) && (! k || (p->refs))) { if( ! p->refs) { pdbyte( q, p->val); } else { pdbyte( q, 0); } pdbyte( q, p->no); pdbyte( q, p->type); j = cnt_refs( p->refs); pdbyte( q, 0xC002); /* just a filler */ plbyte( q, j); /* VORSICHT! MACRO */ s = (byte *) p->name; j = 0; while( j++ < SIGNIFICANT && (*q++ = *s++)); while( j++ < SIGNIFICANT) *q++ = 0; } while( p = p->next); LEAVE(); } lword rel_size() { register label huge *p; register lword x = 0; int i, j; ENTER("rel_size"); loop_symbols( p, i, j) do if( dumpable( p) && p->refs) x += (lword) (cnt_refs( p->refs) << 1); while( p = p->next); LEAVE(); return( x); } void rel_makbuf() { register label huge *p; register byte huge *q = __program; register ref huge *s; int i, k; ENTER("rel_makbuf"); loop_symbols( p, i, k) do if( dumpable( p) && (s = p->refs)) do { pdbyte( q, s->ref->no); } while( s = s->next); while( p = p->next); LEAVE(); } static unsigned fixes; lword fix_size() { return( (lword) fixes * sizeof( f_dropped)); } void fix_makbuf() { register label huge *p; register ref huge *q; register expr huge *e; register int i, k; ENTER("fix_makbuf"); dspace = __program; loop_symbols( p, i, k) do if( dumpable( p) && (q = p->refs)) do { register byte huge *x = dspace; for( e = q->ref; ! e->fix; e = e->zonk.t); dspace += sizeof( f_dropped); if( e->fix == FIX_LABEL) { pdbyte( x, e->zonk.fixp->poof.label->no); pdclr( x); dclr( x); } else { register fix huge *f = e->zonk.fixp; pdbyte( x, f->poof.block->no); if( f->imm) { pdbyte( x, f->imm->no); } else { pdclr( x); } dbyte( x, f->index); } } while( q = q->next); while( p = p->next); LEAVE(); } /* ---------------------------------------------------------- */ /* Can do this only ONCE!! */ /* ---------------------------------------------------------- */ static unsigned xindex = 1; static unsigned help_tree( p) register expr huge *p; { p->no = xindex++; if( p->l) { help_tree( p->l); if( p->r) help_tree( p->r); } } static void cnt_tree( p) expr huge *p; { ENTER("cnt_tree"); if( ! p->no) { while( ! p->fix) /* walk to the top */ p = p->zonk.t; p->zonk.fixp->no = fixes++; help_tree( p); } } lword exp_size() { register label huge *p; register ref huge *q; int i, k; ENTER("exp_size"); loop_symbols( p, i, k) do if( dumpable( p) && (q = p->refs)) do cnt_tree( q->ref); while( q = q->next); while( p = p->next); LEAVE(); return( (lword) (xindex - 1) * sizeof( e_dropped)); } static void hdump_tree( x) expr huge *x; { ENTER("hdump_tree"); { /* ; */ register expr huge *p = x; register byte huge *q = dspace; dspace += sizeof( e_dropped); pdbyte( q, p->val); pdbyte( q, p->aux); pdbyte( q, p->label ? p->label->no : 0); *q++ = p->op; if( *q++ = p->fix) if( p->fix == FIX_LABEL) { pdbyte( q, ((label *) p->zonk.t)->no); } else { pdbyte( q, p->zonk.fixp->no); } else { pdbyte( q, p->zonk.t ? p->zonk.t->no : 0); } pdbyte( q, p->l ? p->l->no : 0); dbyte( q, p->r ? p->r->no : 0); } if( x->l) { hdump_tree( x->l); if( x->r) hdump_tree( x->r); } x->no = 0; /* clear >no< so that expr */ LEAVE(); /* won't be dumped again */ } void dump_tree( p) expr huge *p; { ENTER("dump_tree"); if( p->no) { while( ! p->fix) /* walk to the top */ p = p->zonk.t; hdump_tree( p); } LEAVE(); } void exp_makbuf() { register label huge *p; register ref huge *q; int i, k; ENTER("exp_makbuf"); dspace = __program; loop_symbols( p, i, k) do if( dumpable( p) && (q = p->refs)) do dump_tree( q->ref); while( q = q->next); while( p = p->next); LEAVE(); } extern imm huge *hip, huge *cip; lword imm_size() { register imm huge *p; register word i = 1; ENTER("imm_size"); for( p = hip; p; p = p->next) p->no = i++; LEAVE(); return( (lword) (i - 1) * sizeof( i_dropped)); } void imm_makbuf() { register imm huge *p; register byte huge *q = __program; ENTER("imm_makbuf"); for( p = hip; p; p = p->next) { pdbyte( q, p->block->no); pdbyte( q, p->type); pdbyte( q, p->offset); pdbyte( q, p->val); } LEAVE(); } extern seg huge *h_seg, *sp; lword seg_size() { register seg huge *p; register word i; for( p = h_seg, i = 0; p; i++, p = p->next) p->no = i; return( (lword) i * sizeof( s_dropped)); } void seg_makbuf() { register seg huge *p; register byte huge *q; for( p = h_seg, q = __program; p ; p = p->next) { pdbyte( q, p->type); pdbyte( q, p->index); pdbyte( q, p->size); } } /* ; -- "This looks exceptionally braindead, son. What where you dreaming about, when you wrote this ??" -- "Well ackshually *hic* there ish a shertain rashional behind *hic* all shat." -- "Swine! Have you been drinking again ? Well I just gonna have to teach you some ... ..manners <*crack*> -- "No need to break my arm, I was just kidding.." -- "Well that'll teach you to make fun of your old dad, now son about this piece of shit up there..." -- -- "Well!!" -- "Don't hit me again! I am telling you, I am telling you!!" -- "I am listening son, and I am getting impatient" [and so do we...] -- "Ok just assume for a moment, that we have some really large expression and some compiler that rather prefers to not use registers, for parameter passing (as there are some). Now for the little piece enclosed in the { } it would be preferable, to have this executed with register variables, but we certainly don't want those to be stacked when the recursive calls take place." -- "Oh son, why didn't you say so in the first place. I needn't have to hit you then. Lets be good again, shall we ?" -- "Oh yes . -- uh Dad ?? -- "..Yes.." -- "Could you -er- drive me to the hospital? My arm is hurting pretty badly." -- "Don't push your luck again son!" -- (later: That was when I was still learning to write C-programs. Of course this doesn't make sense on a more profound level of understanding.) (much later: I must have dropped down a level of profoundness again) */ /* ;; If the top fix is FIX_NOTHING, that means it is an assembler internal expression, that wasn't used anywhere. Presently this only happenes when macros are started. -> LEXPR -> COPYEXPR ... lexpr->expr remains unused except for copying. (later: well not completely true anymore, still "about right") */