diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2016-05-04 16:11:48 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2016-05-04 16:11:48 +0200 |
commit | 986886f2b8ab4a7e1b3d66e99934d8fdab537be9 (patch) | |
tree | c49e9711e7229a8d12f5b5b0ab38b5bd6c27b711 /sys/src/cmd/7l/obj.c | |
parent | f7703d6971383c39f981f5676a4e28a6371c3997 (diff) |
retire the dec alpha port
Diffstat (limited to 'sys/src/cmd/7l/obj.c')
-rw-r--r-- | sys/src/cmd/7l/obj.c | 1350 |
1 files changed, 0 insertions, 1350 deletions
diff --git a/sys/src/cmd/7l/obj.c b/sys/src/cmd/7l/obj.c deleted file mode 100644 index 793e5825e..000000000 --- a/sys/src/cmd/7l/obj.c +++ /dev/null @@ -1,1350 +0,0 @@ -#include "l.h" -#include <ar.h> - -#ifndef DEFAULT -#define DEFAULT '9' -#endif - -char *noname = "<none>"; -char symname[] = SYMDEF; -char thechar = '7'; -char *thestring = "alpha"; - -/* - * -H0 -T0x12000004C -D0x140000000 is abbrev unix - * -H1 -T0x20000000 -R4 is bootp() format - * -H2 -T8224 -R8192 is plan9 format - */ - -void -main(int argc, char *argv[]) -{ - int c; - char *a; - - Binit(&bso, 1, OWRITE); - cout = -1; - listinit(); - outfile = 0; - nerrors = 0; - curtext = P; - HEADTYPE = -1; - INITTEXT = -1; - INITDAT = -1; - INITRND = -1; - INITENTRY = 0; - - ARGBEGIN { - default: - c = ARGC(); - if(c >= 0 && c < sizeof(debug)) - debug[c]++; - break; - case 'o': - outfile = ARGF(); - break; - case 'E': - a = ARGF(); - if(a) - INITENTRY = a; - break; - case 'T': - a = ARGF(); - if(a) - INITTEXT = atolwhex(a); - break; - case 'D': - a = ARGF(); - if(a) - INITDAT = atolwhex(a); - break; - case 'R': - a = ARGF(); - if(a) - INITRND = atolwhex(a); - break; - case 'H': - a = ARGF(); - if(a) - HEADTYPE = atolwhex(a); - /* do something about setting INITTEXT */ - break; - } ARGEND - - USED(argc); - - if(*argv == 0) { - diag("usage: 7l [-options] objects"); - errorexit(); - } - if(!debug['9'] && !debug['B'] && !debug['U']) - debug[DEFAULT] = 1; - if(HEADTYPE == -1) { - if(debug['U']) - HEADTYPE = 0; - if(debug['B']) - HEADTYPE = 1; - if(debug['9']) - HEADTYPE = 2; - } - switch(HEADTYPE) { - default: - diag("unknown -H option"); - errorexit(); - - case 0: /* unix simple */ - HEADR = 32L+80L; - if(INITTEXT == -1) - INITTEXT = 0x120000070LL; /* BUG */ - if(INITDAT == -1) - INITDAT = 0x140000000LL; /* BUG */ - if(INITRND == -1) - INITRND = 0; - break; - - case 1: /* boot */ - HEADR = 32L+84L; - if(INITTEXT == -1) - INITTEXT = 0x20000074L; - if(INITDAT == -1) - INITDAT = 0; - if(INITRND == -1) - INITRND = 8; - break; - case 2: /* plan 9 */ - HEADR = 32L; - if(INITTEXT == -1) - INITTEXT = 8224; - if(INITDAT == -1) - INITDAT = 0; - if(INITRND == -1) - INITRND = 8192; - break; - case 3: /* ``headerless'' tftp boot -- uses branch as magic */ - HEADR = 32L; - if(INITTEXT == -1) - INITTEXT = 0x20000020L; - if(INITDAT == -1) - INITDAT = 0; - if(INITRND == -1) - INITRND = 8; - break; - } - if(INITDAT != 0 && INITRND != 0) - print("warning: -D0x%lux is ignored because of -R0x%lux\n", - INITDAT, INITRND); - if(debug['v']) - Bprint(&bso, "HEADER = -H0x%d -T0x%lux -D0x%lux -R0x%lux\n", - HEADTYPE, INITTEXT, INITDAT, INITRND); - Bflush(&bso); - zprg.as = AGOK; - zprg.reg = NREG; - zprg.from.name = D_NONE; - zprg.from.type = D_NONE; - zprg.from.reg = NREG; - zprg.to = zprg.from; - buildop(); - histgen = 0; - textp = P; - datap = P; - pc = 0; - dtype = 4; - if(outfile == 0) - outfile = "7.out"; - cout = create(outfile, 1, 0775); - if(cout < 0) { - diag("%s: cannot create", outfile); - errorexit(); - } - nuxiinit(); - - version = 0; - cbp = buf.cbuf; - cbc = sizeof(buf.cbuf); - firstp = prg(); - lastp = firstp; - - if(INITENTRY == 0) { - INITENTRY = "_main"; - if(debug['p']) - INITENTRY = "_mainp"; - if(!debug['l']) - lookup(INITENTRY, 0)->type = SXREF; - } else - lookup(INITENTRY, 0)->type = SXREF; - - while(*argv) - objfile(*argv++); - if(!debug['l']) - loadlib(); - firstp = firstp->link; - if(firstp == P) - goto out; - patch(); - if(debug['p']) - if(debug['1']) - doprof1(); - else - doprof2(); - follow(); - if(firstp == P) - goto out; - noops(); - dodata(); /* is before follow() on other arch */ - span(); - asmb(); - undef(); - -out: - if(debug['v']) { - Bprint(&bso, "%5.2f cpu time\n", cputime()); - Bprint(&bso, "%ld memory used\n", thunk); - Bprint(&bso, "%d sizeof adr\n", sizeof(Adr)); - Bprint(&bso, "%d sizeof prog\n", sizeof(Prog)); - } - Bflush(&bso); - errorexit(); -} - -void -loadlib(void) -{ - int i; - long h; - Sym *s; - -loop: - xrefresolv = 0; - for(i=0; i<libraryp; i++) { - if(debug['v']) - Bprint(&bso, "%5.2f autolib: %s\n", cputime(), library[i]); - objfile(library[i]); - } - if(xrefresolv) - for(h=0; h<nelem(hash); h++) - for(s = hash[h]; s != S; s = s->link) - if(s->type == SXREF) - goto loop; -} - -void -errorexit(void) -{ - - Bflush(&bso); - if(nerrors) { - if(cout >= 0) - remove(outfile); - exits("error"); - } - exits(0); -} - -void -objfile(char *file) -{ - long off, esym, cnt, l; - int f, work; - Sym *s; - char magbuf[SARMAG]; - char name[100], pname[150]; - struct ar_hdr arhdr; - char *e, *start, *stop; - - if(file[0] == '-' && file[1] == 'l') { - if(debug['9']) - snprint(name, sizeof name, "/%s/lib/lib%s.a", thestring, file+2); - else - snprint(name, sizeof name, "/usr/%clib/lib%s.a", thechar, file+2); - file = name; - } - if(debug['v']) - Bprint(&bso, "%5.2f ldobj: %s\n", cputime(), file); - Bflush(&bso); - f = open(file, 0); - if(f < 0) { - diag("cannot open file: %s", file); - errorexit(); - } - l = read(f, magbuf, SARMAG); - if(l != SARMAG || strncmp(magbuf, ARMAG, SARMAG)){ - /* load it as a regular file */ - l = seek(f, 0L, 2); - seek(f, 0L, 0); - ldobj(f, l, file); - close(f); - return; - } - - if(debug['v']) - Bprint(&bso, "%5.2f ldlib: %s\n", cputime(), file); - l = read(f, &arhdr, SAR_HDR); - if(l != SAR_HDR) { - diag("%s: short read on archive file symbol header", file); - goto out; - } - if(strncmp(arhdr.name, symname, strlen(symname))) { - diag("%s: first entry not symbol header", file); - goto out; - } - - esym = SARMAG + SAR_HDR + atolwhex(arhdr.size); - off = SARMAG + SAR_HDR; - - /* - * just bang the whole symbol file into memory - */ - seek(f, off, 0); - cnt = esym - off; - start = malloc(cnt + 10); - cnt = read(f, start, cnt); - if(cnt <= 0){ - close(f); - return; - } - stop = &start[cnt]; - memset(stop, 0, 10); - - work = 1; - while(work){ - if(debug['v']) - Bprint(&bso, "%5.2f library pass: %s\n", cputime(), file); - Bflush(&bso); - work = 0; - for(e = start; e < stop; e = strchr(e+5, 0) + 1) { - s = lookup(e+5, 0); - if(s->type != SXREF) - continue; - snprint(pname, sizeof pname, "%s(%s)", file, s->name); - if(debug['v']) - Bprint(&bso, "%5.2f library: %s\n", cputime(), pname); - Bflush(&bso); - l = e[1] & 0xff; - l |= (e[2] & 0xff) << 8; - l |= (e[3] & 0xff) << 16; - l |= (e[4] & 0xff) << 24; - seek(f, l, 0); - l = read(f, &arhdr, SAR_HDR); - if(l != SAR_HDR) - goto bad; - if(strncmp(arhdr.fmag, ARFMAG, sizeof(arhdr.fmag))) - goto bad; - l = atolwhex(arhdr.size); - ldobj(f, l, pname); - if(s->type == SXREF) { - diag("%s: failed to load: %s", file, s->name); - errorexit(); - } - work = 1; - xrefresolv = 1; - } - } - return; - -bad: - diag("%s: bad or out of date archive", file); -out: - close(f); -} - -int -zaddr(uchar *p, Adr *a, Sym *h[]) -{ - int i, c; - vlong l; - Sym *s; - Auto *u; - - c = p[2]; - if(c < 0 || c > NSYM){ - print("sym out of range: %d\n", c); - p[0] = ALAST+1; - return 0; - } - a->type = p[0]; - a->reg = p[1]; - a->sym = h[p[2]]; - a->name = p[3]; - c = 4; - - if(a->reg < 0 || a->reg > NREG) { - print("register out of range %d\n", a->reg); - p[0] = ALAST+1; - return 0; /* force real diagnostic */ - } - - switch(a->type) { - default: - print("unknown type %d\n", a->type); - p[0] = ALAST+1; - return 0; /* force real diagnostic */ - - case D_NONE: - case D_REG: - case D_FREG: - case D_PREG: - case D_FCREG: - case D_PCC: - break; - - case D_BRANCH: - case D_OREG: - case D_CONST: - a->offset = (uvlong)p[4] | ((uvlong)p[5]<<8L) | - ((uvlong) p[6]<<16L) | ((uvlong) p[7]<<24L) | - ((uvlong) p[8]<<32L) | ((uvlong) p[9]<<40L) | - ((uvlong) p[10]<<48L) | ((uvlong) p[11]<<56L); - c += 8; - break; - - case D_SCONST: - while(nhunk < NSNAME) - gethunk(); - a->sval = (char*)hunk; - nhunk -= NSNAME; - hunk += NSNAME; - - memmove(a->sval, p+4, NSNAME); - c += NSNAME; - break; - - case D_FCONST: - while(nhunk < sizeof(Ieee)) - gethunk(); - a->ieee = (Ieee*)hunk; - nhunk -= sizeof(Ieee); - hunk += sizeof(Ieee); - - a->ieee->l = p[4] | (p[5]<<8) | - (p[6]<<16) | (p[7]<<24); - a->ieee->h = p[8] | (p[9]<<8) | - (p[10]<<16) | (p[11]<<24); - c += 8; - break; - } - s = a->sym; - if(s == S) - return c; - i = a->name; - if(i != D_AUTO && i != D_PARAM) - return c; - - l = a->offset; - for(u=curauto; u; u=u->link) - if(u->sym == s) - if(u->type == i) { - if(u->offset > l) - u->offset = l; - return c; - } - - while(nhunk < sizeof(Auto)) - gethunk(); - u = (Auto*)hunk; - nhunk -= sizeof(Auto); - hunk += sizeof(Auto); - - u->link = curauto; - curauto = u; - u->sym = s; - u->offset = l; - u->type = i; - return c; -} - -void -addlib(char *obj) -{ - char name[1024], comp[256], *p; - int i; - - if(histfrogp <= 0) - return; - - if(histfrog[0]->name[1] == '/') { - name[0] = 0; - i = 1; - } else - if(histfrog[0]->name[1] == '.') { - snprint(name, sizeof name, "."); - i = 0; - } else { - if(debug['9']) - snprint(name, sizeof name, "/%s/lib", thestring); - else - snprint(name, sizeof name, "/usr/%clib", thechar); - i = 0; - } - - for(; i<histfrogp; i++) { - snprint(comp, sizeof comp, histfrog[i]->name+1); - for(;;) { - p = strstr(comp, "$O"); - if(p == 0) - break; - memmove(p+1, p+2, strlen(p+2)+1); - p[0] = thechar; - } - for(;;) { - p = strstr(comp, "$M"); - if(p == 0) - break; - if(strlen(comp)+strlen(thestring)-2+1 >= sizeof comp) { - diag("library component too long"); - return; - } - memmove(p+strlen(thestring), p+2, strlen(p+2)+1); - memmove(p, thestring, strlen(thestring)); - } - if(strlen(name) + strlen(comp) + 3 >= sizeof(name)) { - diag("library component too long"); - return; - } - strcat(name, "/"); - strcat(name, comp); - } - for(i=0; i<libraryp; i++) - if(strcmp(name, library[i]) == 0) - return; - if(libraryp == nelem(library)){ - diag("too many autolibs; skipping %s", name); - return; - } - - p = malloc(strlen(name) + 1); - strcpy(p, name); - library[libraryp] = p; - p = malloc(strlen(obj) + 1); - strcpy(p, obj); - libraryobj[libraryp] = p; - libraryp++; -} - -void -addhist(long line, int type) -{ - Auto *u; - Sym *s; - int i, j, k; - - u = malloc(sizeof(Auto)); - s = malloc(sizeof(Sym)); - s->name = malloc(2*(histfrogp+1) + 1); - - u->sym = s; - u->type = type; - u->offset = line; - u->link = curhist; - curhist = u; - - j = 1; - for(i=0; i<histfrogp; i++) { - k = histfrog[i]->value; - s->name[j+0] = k>>8; - s->name[j+1] = k; - j += 2; - } -} - -void -histtoauto(void) -{ - Auto *l; - - while(l = curhist) { - curhist = l->link; - l->link = curauto; - curauto = l; - } -} - -void -collapsefrog(Sym *s) -{ - int i; - - /* - * bad encoding of path components only allows - * MAXHIST components. if there is an overflow, - * first try to collapse xxx/.. - */ - for(i=1; i<histfrogp; i++) - if(strcmp(histfrog[i]->name+1, "..") == 0) { - memmove(histfrog+i-1, histfrog+i+1, - (histfrogp-i-1)*sizeof(histfrog[0])); - histfrogp--; - goto out; - } - - /* - * next try to collapse . - */ - for(i=0; i<histfrogp; i++) - if(strcmp(histfrog[i]->name+1, ".") == 0) { - memmove(histfrog+i, histfrog+i+1, - (histfrogp-i-1)*sizeof(histfrog[0])); - goto out; - } - - /* - * last chance, just truncate from front - */ - memmove(histfrog+0, histfrog+1, - (histfrogp-1)*sizeof(histfrog[0])); - -out: - histfrog[histfrogp-1] = s; -} - -void -nopout(Prog *p) -{ - p->as = ANOP; - p->from.type = D_NONE; - p->to.type = D_NONE; -} - -uchar* -readsome(int f, uchar *buf, uchar *good, uchar *stop, int max) -{ - int n; - - n = stop - good; - memmove(buf, good, stop - good); - stop = buf + n; - n = MAXIO - n; - if(n > max) - n = max; - n = read(f, stop, n); - if(n <= 0) - return 0; - return stop + n; -} - -void -ldobj(int f, long c, char *pn) -{ - long ipc; - Prog *p, *t; - uchar *bloc, *bsize, *stop; - Sym *h[NSYM], *s, *di; - int v, o, r, skip; - - bsize = buf.xbuf; - bloc = buf.xbuf; - di = S; - -newloop: - memset(h, 0, sizeof(h)); - version++; - histfrogp = 0; - ipc = pc; - skip = 0; - -loop: - if(c <= 0) - goto eof; - r = bsize - bloc; - if(r < 100 && r < c) { /* enough for largest prog */ - bsize = readsome(f, buf.xbuf, bloc, bsize, c); - if(bsize == 0) - goto eof; - bloc = buf.xbuf; - goto loop; - } - o = bloc[0]; /* as */ - if(o <= AXXX || o >= ALAST) { - diag("%s: line %ld: opcode out of range %d", pn, pc-ipc, o); - print(" probably not a .7 file\n"); - errorexit(); - } - if(o == ANAME) { - stop = memchr(&bloc[3], 0, bsize-&bloc[3]); - if(stop == 0){ - bsize = readsome(f, buf.xbuf, bloc, bsize, c); - if(bsize == 0) - goto eof; - bloc = buf.xbuf; - stop = memchr(&bloc[3], 0, bsize-&bloc[3]); - if(stop == 0){ - fprint(2, "%s: name too long\n", pn); - errorexit(); - } - } - v = bloc[1]; /* type */ - o = bloc[2]; /* sym */ - bloc += 3; - c -= 3; - - r = 0; - if(v == D_STATIC) - r = version; - s = lookup((char*)bloc, r); - c -= &stop[1] - bloc; - bloc = stop + 1; - - if(debug['W']) - print(" ANAME %s\n", s->name); - h[o] = s; - if((v == D_EXTERN || v == D_STATIC) && s->type == 0) - s->type = SXREF; - if(v == D_FILE) { - if(s->type != SFILE) { - histgen++; - s->type = SFILE; - s->value = histgen; - } - if(histfrogp < MAXHIST) { - histfrog[histfrogp] = s; - histfrogp++; - } else - collapsefrog(s); - } - goto loop; - } - - if(nhunk < sizeof(Prog)) - gethunk(); - p = (Prog*)hunk; - nhunk -= sizeof(Prog); - hunk += sizeof(Prog); - - p->as = o; - p->reg = bloc[1] & 0x7f; - if(bloc[1] & 0x80) - p->mark = NOSCHED; - p->line = bloc[2] | (bloc[3]<<8) | (bloc[4]<<16) | (bloc[5]<<24); - - r = zaddr(bloc+6, &p->from, h) + 6; - r += zaddr(bloc+r, &p->to, h); - bloc += r; - c -= r; - - if(p->reg < 0 || p->reg > NREG) - diag("register out of range %d", p->reg); - - p->link = P; - p->cond = P; - - if(debug['W']) - print("%P\n", p); - - switch(o) { - case AHISTORY: - if(p->to.offset == -1) { - addlib(pn); - histfrogp = 0; - goto loop; - } - addhist(p->line, D_FILE); /* 'z' */ - if(p->to.offset) - addhist(p->to.offset, D_PREG); /* 'Z' */ - histfrogp = 0; - goto loop; - - case AEND: - histtoauto(); - if(curtext != P) - curtext->to.autom = curauto; - curauto = 0; - curtext = P; - if(c) - goto newloop; - return; - - case AGLOBL: - s = p->from.sym; - if(s == S) { - diag("GLOBL must have a name\n%P", p); - errorexit(); - } - if(s->type == 0 || s->type == SXREF) { - s->type = SBSS; - s->value = 0; - } - if(s->type != SBSS) { - diag("redefinition: %s\n%P", s->name, p); - s->type = SBSS; - s->value = 0; - } - if(p->to.offset > s->value) - s->value = p->to.offset; - break; - - case ADYNT: - if(p->to.sym == S) { - diag("DYNT without a sym\n%P", p); - break; - } - di = p->to.sym; - p->reg = 4; - if(di->type == SXREF) { - if(debug['z']) - Bprint(&bso, "%P set to %d\n", p, dtype); - di->type = SCONST; - di->value = dtype; - dtype += 4; - } - if(p->from.sym == S) - break; - - p->from.offset = di->value; - p->from.sym->type = SDATA; - if(curtext == P) { - diag("DYNT not in text: %P", p); - break; - } - p->to.sym = curtext->from.sym; - p->to.type = D_CONST; - p->link = datap; - datap = p; - break; - - case AINIT: - if(p->from.sym == S) { - diag("INIT without a sym\n%P", p); - break; - } - if(di == S) { - diag("INIT without previous DYNT\n%P", p); - break; - } - p->from.offset = di->value; - p->from.sym->type = SDATA; - p->link = datap; - datap = p; - break; - - case ADATA: - if(p->from.sym == S) { - diag("DATA without a sym\n%P", p); - break; - } - p->link = datap; - datap = p; - break; - - case AGOK: - diag("unknown opcode\n%P", p); - p->pc = pc; - pc++; - break; - - case ATEXT: - if(curtext != P) { - histtoauto(); - curtext->to.autom = curauto; - curauto = 0; - } - skip = 0; - curtext = p; - autosize = (p->to.offset+3L) & ~3L; - if (autosize & 4) - autosize += 4; - p->to.offset = autosize; - autosize += 8; - s = p->from.sym; - if(s == S) { - diag("TEXT must have a name\n%P", p); - errorexit(); - } - if(s->type != 0 && s->type != SXREF) { - if(p->reg & DUPOK) { - skip = 1; - goto casedef; - } - diag("redefinition: %s\n%P", s->name, p); - } - s->type = STEXT; - s->value = pc; - lastp->link = p; - lastp = p; - p->pc = pc; - pc++; - if(textp == P) { - textp = p; - etextp = p; - goto loop; - } - etextp->cond = p; - etextp = p; - break; - - case AMOVS: - if(skip) - goto casedef; - - if(p->from.type == D_FCONST) { - /* size sb 9 max */ - snprint(literal, sizeof literal, "$%lux", ieeedtof(p->from.ieee)); - s = lookup(literal, 0); - if(s->type == 0) { - s->type = SBSS; - s->value = 4; - t = prg(); - t->as = ADATA; - t->line = p->line; - t->from.type = D_OREG; - t->from.sym = s; - t->from.name = D_EXTERN; - t->reg = 4; - t->to = p->from; - t->link = datap; - datap = t; - } - p->from.type = D_OREG; - p->from.sym = s; - p->from.name = D_EXTERN; - p->from.offset = 0; - } - goto casedef; - - case AMOVT: - if(skip) - goto casedef; - - if(p->from.type == D_FCONST) { - /* size sb 18 max */ - snprint(literal, sizeof literal, "$%lux.%lux", - p->from.ieee->l, p->from.ieee->h); - s = lookup(literal, 0); - if(s->type == 0) { - s->type = SBSS; - s->value = 8; - t = prg(); - t->as = ADATA; - t->line = p->line; - t->from.type = D_OREG; - t->from.sym = s; - t->from.name = D_EXTERN; - t->reg = 8; - t->to = p->from; - t->link = datap; - datap = t; - } - p->from.type = D_OREG; - p->from.sym = s; - p->from.name = D_EXTERN; - p->from.offset = 0; - } - goto casedef; - - case AMOVQ: - if(skip) - goto casedef; - - if (p->from.type == D_FREG || p->to.type == D_FREG) - p->as = AMOVT; /* stupid compiler optimiser kkludge */ - - case AMOVL: - case AMOVW: - case AMOVB: - /* BOTCH */ - if (p->from.type == D_CONST) - if (p->from.offset == 0LL && p->from.name == D_NONE) { - p->from.type = D_REG; - p->from.reg = REGZERO; - } - goto casedef; - - default: - casedef: - if(skip) - nopout(p); - - if(p->to.type == D_BRANCH) - p->to.offset += ipc; - lastp->link = p; - lastp = p; - p->pc = pc; - pc++; - break; - } - goto loop; - -eof: - diag("truncated object file: %s", pn); -} - -Sym* -lookup(char *symb, int v) -{ - Sym *s; - char *p; - long h; - int c0, l; - - h = v; - for(p=symb; c0 = *p; p++) - h = h+h+h + c0; - l = (p - symb) + 1; - if(h < 0) - h = ~h; - h %= NHASH; - for(s = hash[h]; s != S; s = s->link) - if(s->version == v) - if(memcmp(s->name, symb, l) == 0) - return s; - - while(nhunk < sizeof(Sym)) - gethunk(); - s = (Sym*)hunk; - nhunk -= sizeof(Sym); - hunk += sizeof(Sym); - - s->name = malloc(l); - memmove(s->name, symb, l); - - s->link = hash[h]; - s->type = 0; - s->version = v; - s->value = 0; - hash[h] = s; - return s; -} - -Prog* -prg(void) -{ - Prog *p; - - while(nhunk < sizeof(Prog)) - gethunk(); - p = (Prog*)hunk; - nhunk -= sizeof(Prog); - hunk += sizeof(Prog); - - *p = zprg; - return p; -} - -void -gethunk(void) -{ - char *h; - long nh; - - nh = NHUNK; - if(thunk >= 5L*NHUNK) { - nh = 5L*NHUNK; - if(thunk >= 25L*NHUNK) - nh = 25L*NHUNK; - } - h = mysbrk(nh); - if(h == (char*)-1) { - diag("out of memory"); - errorexit(); - } - hunk = h; - nhunk = nh; - thunk += nh; -} - -void -doprof1(void) -{ - Sym *s; - long n; - Prog *p, *q; - - if(debug['v']) - Bprint(&bso, "%5.2f profile 1\n", cputime()); - Bflush(&bso); - s = lookup("__mcount", 0); - n = 1; - for(p = firstp->link; p != P; p = p->link) { - if(p->as == ATEXT) { - q = prg(); - q->line = p->line; - q->link = datap; - datap = q; - q->as = ADATA; - q->from.type = D_OREG; - q->from.name = D_EXTERN; - q->from.offset = n*4; - q->from.sym = s; - q->reg = 4; - q->to = p->from; - q->to.type = D_CONST; - - q = prg(); - q->line = p->line; - q->pc = p->pc; - q->link = p->link; - p->link = q; - p = q; - p->as = AMOVL; - p->from.type = D_OREG; - p->from.name = D_EXTERN; - p->from.sym = s; - p->from.offset = n*4 + 4; - p->to.type = D_REG; - p->to.reg = REGTMP; - - q = prg(); - q->line = p->line; - q->pc = p->pc; - q->link = p->link; - p->link = q; - p = q; - p->as = AADDQ; - p->from.type = D_CONST; - p->from.offset = 1; - p->to.type = D_REG; - p->to.reg = REGTMP; - - q = prg(); - q->line = p->line; - q->pc = p->pc; - q->link = p->link; - p->link = q; - p = q; - p->as = AMOVL; - p->from.type = D_REG; - p->from.reg = REGTMP; - p->to.type = D_OREG; - p->to.name = D_EXTERN; - p->to.sym = s; - p->to.offset = n*4 + 4; - - n += 2; - continue; - } - } - q = prg(); - q->line = 0; - q->link = datap; - datap = q; - - q->as = ADATA; - q->from.type = D_OREG; - q->from.name = D_EXTERN; - q->from.sym = s; - q->reg = 4; - q->to.type = D_CONST; - q->to.offset = n; - - s->type = SBSS; - s->value = n*4; -} - -void -doprof2(void) -{ - Sym *s2, *s4; - Prog *p, *q, *q2, *ps2, *ps4; - - if(debug['v']) - Bprint(&bso, "%5.2f profile 2\n", cputime()); - Bflush(&bso); - - if(debug['e']){ - s2 = lookup("_tracein", 0); - s4 = lookup("_traceout", 0); - }else{ - s2 = lookup("_profin", 0); - s4 = lookup("_profout", 0); - } - if(s2->type != STEXT || s4->type != STEXT) { - if(debug['e']) - diag("_tracein/_traceout not defined %d %d", s2->type, s4->type); - else - diag("_profin/_profout not defined"); - return; - } - - ps2 = P; - ps4 = P; - for(p = firstp; p != P; p = p->link) { - if(p->as == ATEXT) { - if(p->from.sym == s2) { - ps2 = p; - p->reg = 1; - } - if(p->from.sym == s4) { - ps4 = p; - p->reg = 1; - } - } - } - for(p = firstp; p != P; p = p->link) { - if(p->as == ATEXT) { - if(p->reg != NREG) { - for(;;) { - q = p->link; - if(q == P) - break; - if(q->as == ATEXT) - break; - p = q; - } - continue; - } - - /* - * JSR profin, R2 - */ - q = prg(); - q->line = p->line; - q->pc = p->pc; - q->link = p->link; - if(debug['e']){ /* embedded tracing */ - q2 = prg(); - p->link = q2; - q2->link = q; - - q2->line = p->line; - q2->pc = p->pc; - - q2->as = AJMP; - q2->to.type = D_BRANCH; - q2->to.sym = p->to.sym; - q2->cond = q->link; - }else - p->link = q; - p = q; - p->as = AJSR; - p->to.type = D_BRANCH; - p->cond = ps2; - p->to.sym = s2; - - continue; - } - if(p->as == ARET) { - /* - * JSR (default) - */ - if(debug['e']){ /* embedded tracing */ - q = prg(); - q->line = p->line; - q->pc = p->pc; - q->link = p->link; - p->link = q; - p = q; - } - /* - * JSR profout - */ - p->as = AJSR; - p->to.type = D_BRANCH; - p->cond = ps4; - p->to.sym = s4; - - - /* - * RET - */ - q = prg(); - q->line = p->line; - q->pc = p->pc; - q->link = p->link; - p->link = q; - p = q; - p->as = ARET; - - continue; - } - } -} - -void -nuxiinit(void) -{ - int i, c; - - for(i=0; i<4; i++) { - c = find1(0x04030201L, i+1); - if(i <= 4) - inuxi4[i] = c; - if(i <= 2) - inuxi2[i] = c; - if(i <= 1) - inuxi1[i] = c; - } - for (i = 0; i < 4; i++) { - c = find1(0x04030201L, i+1); - fnuxi8[i] = c; - fnuxi8[i+4] = c + sizeof(long); - } - - if(debug['v']) { - Bprint(&bso, "inuxi = "); - for(i=0; i<1; i++) - Bprint(&bso, "%d", inuxi1[i]); - Bprint(&bso, " "); - for(i=0; i<2; i++) - Bprint(&bso, "%d", inuxi2[i]); - Bprint(&bso, " "); - for(i=0; i<4; i++) - Bprint(&bso, "%d", inuxi4[i]); - Bprint(&bso, " "); - Bprint(&bso, "\nfnuxi = "); - for(i=0; i<8; i++) - Bprint(&bso, "%d", fnuxi8[i]); - Bprint(&bso, "\n"); - } - Bflush(&bso); -} - -find1(long l, int c) -{ - char *p; - int i; - - p = (char*)&l; - for(i=0; i<4; i++) - if(*p++ == c) - return i; - return 0; -} - -long -ieeedtof(Ieee *ieee) -{ - int exp; - long v; - - if(ieee->h == 0) - return 0; - exp = (ieee->h>>20) & ((1L<<11)-1L); - exp -= (1L<<10) - 2L; - v = (ieee->h & 0xfffffL) << 3; - v |= (ieee->l >> 29) & 0x7L; - if((ieee->l >> 28) & 1) { - v++; - if(v & 0x800000L) { - v = (v & 0x7fffffL) >> 1; - exp++; - } - } - if(exp <= -126 || exp >= 130) - diag("double fp to single fp overflow"); - v |= ((exp + 126) & 0xffL) << 23; - v |= ieee->h & 0x80000000L; - return v; -} - -double -ieeedtod(Ieee *ieee) -{ - Ieee e; - double fr; - int exp; - - if(ieee->h & (1L<<31)) { - e.h = ieee->h & ~(1L<<31); - e.l = ieee->l; - return -ieeedtod(&e); - } - if(ieee->l == 0 && ieee->h == 0) - return 0; - fr = ieee->l & ((1L<<16)-1L); - fr /= 1L<<16; - fr += (ieee->l>>16) & ((1L<<16)-1L); - fr /= 1L<<16; - fr += (ieee->h & (1L<<20)-1L) | (1L<<20); - fr /= 1L<<21; - exp = (ieee->h>>20) & ((1L<<11)-1L); - exp -= (1L<<10) - 2L; - return ldexp(fr, exp); -} |