13e12c5d1SDavid du Colombier #include "l.h" 23e12c5d1SDavid du Colombier #include <ar.h> 33e12c5d1SDavid du Colombier 43e12c5d1SDavid du Colombier #ifndef DEFAULT 53e12c5d1SDavid du Colombier #define DEFAULT '9' 63e12c5d1SDavid du Colombier #endif 73e12c5d1SDavid du Colombier 83e12c5d1SDavid du Colombier char *noname = "<none>"; 93e12c5d1SDavid du Colombier char symname[] = SYMDEF; 10*219b2ee8SDavid du Colombier char thechar = 'k'; 11*219b2ee8SDavid du Colombier char *thestring = "sparc"; 123e12c5d1SDavid du Colombier 133e12c5d1SDavid du Colombier /* 143e12c5d1SDavid du Colombier * -H0 -T0x200000 -R0 is boot 153e12c5d1SDavid du Colombier * -H2 -T4128 -R4096 is plan9 format 163e12c5d1SDavid du Colombier */ 173e12c5d1SDavid du Colombier 183e12c5d1SDavid du Colombier void 193e12c5d1SDavid du Colombier main(int argc, char *argv[]) 203e12c5d1SDavid du Colombier { 213e12c5d1SDavid du Colombier int c; 223e12c5d1SDavid du Colombier char *a; 233e12c5d1SDavid du Colombier 243e12c5d1SDavid du Colombier Binit(&bso, 1, OWRITE); 25*219b2ee8SDavid du Colombier cout = -1; 263e12c5d1SDavid du Colombier listinit(); 273e12c5d1SDavid du Colombier outfile = 0; 283e12c5d1SDavid du Colombier nerrors = 0; 293e12c5d1SDavid du Colombier curtext = P; 303e12c5d1SDavid du Colombier HEADTYPE = -1; 313e12c5d1SDavid du Colombier INITTEXT = -1; 323e12c5d1SDavid du Colombier INITDAT = -1; 333e12c5d1SDavid du Colombier INITRND = -1; 343e12c5d1SDavid du Colombier INITENTRY = 0; 353e12c5d1SDavid du Colombier 363e12c5d1SDavid du Colombier ARGBEGIN { 373e12c5d1SDavid du Colombier default: 383e12c5d1SDavid du Colombier c = ARGC(); 393e12c5d1SDavid du Colombier if(c >= 0 && c < sizeof(debug)) 403e12c5d1SDavid du Colombier debug[c]++; 413e12c5d1SDavid du Colombier break; 423e12c5d1SDavid du Colombier case 'o': 433e12c5d1SDavid du Colombier outfile = ARGF(); 443e12c5d1SDavid du Colombier break; 453e12c5d1SDavid du Colombier case 'E': 463e12c5d1SDavid du Colombier a = ARGF(); 473e12c5d1SDavid du Colombier if(a) 483e12c5d1SDavid du Colombier INITENTRY = a; 493e12c5d1SDavid du Colombier break; 503e12c5d1SDavid du Colombier case 'T': 513e12c5d1SDavid du Colombier a = ARGF(); 523e12c5d1SDavid du Colombier if(a) 533e12c5d1SDavid du Colombier INITTEXT = atolwhex(a); 543e12c5d1SDavid du Colombier break; 553e12c5d1SDavid du Colombier case 'D': 563e12c5d1SDavid du Colombier a = ARGF(); 573e12c5d1SDavid du Colombier if(a) 583e12c5d1SDavid du Colombier INITDAT = atolwhex(a); 593e12c5d1SDavid du Colombier break; 603e12c5d1SDavid du Colombier case 'R': 613e12c5d1SDavid du Colombier a = ARGF(); 623e12c5d1SDavid du Colombier if(a) 633e12c5d1SDavid du Colombier INITRND = atolwhex(a); 643e12c5d1SDavid du Colombier break; 653e12c5d1SDavid du Colombier case 'H': 663e12c5d1SDavid du Colombier a = ARGF(); 673e12c5d1SDavid du Colombier if(a) 683e12c5d1SDavid du Colombier HEADTYPE = atolwhex(a); 693e12c5d1SDavid du Colombier break; 703e12c5d1SDavid du Colombier } ARGEND 713e12c5d1SDavid du Colombier USED(argc); 723e12c5d1SDavid du Colombier if(*argv == 0) { 733e12c5d1SDavid du Colombier diag("usage: vl [-options] objects\n"); 743e12c5d1SDavid du Colombier errorexit(); 753e12c5d1SDavid du Colombier } 763e12c5d1SDavid du Colombier if(!debug['9'] && !debug['U'] && !debug['B']) 773e12c5d1SDavid du Colombier debug[DEFAULT] = 1; 783e12c5d1SDavid du Colombier if(HEADTYPE == -1) { 793e12c5d1SDavid du Colombier if(debug['U']) 803e12c5d1SDavid du Colombier HEADTYPE = 0; 813e12c5d1SDavid du Colombier if(debug['B']) 823e12c5d1SDavid du Colombier HEADTYPE = 1; 833e12c5d1SDavid du Colombier if(debug['9']) 843e12c5d1SDavid du Colombier HEADTYPE = 2; 853e12c5d1SDavid du Colombier } 863e12c5d1SDavid du Colombier switch(HEADTYPE) { 873e12c5d1SDavid du Colombier default: 883e12c5d1SDavid du Colombier diag("unknown -H option"); 893e12c5d1SDavid du Colombier errorexit(); 903e12c5d1SDavid du Colombier 913e12c5d1SDavid du Colombier case 0: /* boot */ 923e12c5d1SDavid du Colombier HEADR = 32L; 933e12c5d1SDavid du Colombier if(INITTEXT == -1) 943e12c5d1SDavid du Colombier INITTEXT = 0x200000L; 953e12c5d1SDavid du Colombier if(INITDAT == -1) 963e12c5d1SDavid du Colombier INITDAT = 0; 973e12c5d1SDavid du Colombier if(INITRND == -1) 983e12c5d1SDavid du Colombier INITRND = 4096L; 993e12c5d1SDavid du Colombier break; 1003e12c5d1SDavid du Colombier case 1: /* garbage */ 1013e12c5d1SDavid du Colombier HEADR = 20L+60L; 1023e12c5d1SDavid du Colombier if(INITTEXT == -1) 1033e12c5d1SDavid du Colombier INITTEXT = 0x80020000L; 1043e12c5d1SDavid du Colombier if(INITDAT == -1) 1053e12c5d1SDavid du Colombier INITDAT = 0; 1063e12c5d1SDavid du Colombier if(INITRND == -1) 1073e12c5d1SDavid du Colombier INITRND = 4; 1083e12c5d1SDavid du Colombier break; 1093e12c5d1SDavid du Colombier case 2: /* plan 9 */ 1103e12c5d1SDavid du Colombier HEADR = 32L; 1113e12c5d1SDavid du Colombier if(INITTEXT == -1) 1123e12c5d1SDavid du Colombier INITTEXT = 4128; 1133e12c5d1SDavid du Colombier if(INITDAT == -1) 1143e12c5d1SDavid du Colombier INITDAT = 0; 1153e12c5d1SDavid du Colombier if(INITRND == -1) 1163e12c5d1SDavid du Colombier INITRND = 4096; 1173e12c5d1SDavid du Colombier break; 1183e12c5d1SDavid du Colombier } 1193e12c5d1SDavid du Colombier if(INITDAT != 0 && INITRND != 0) 1203e12c5d1SDavid du Colombier print("warning: -D0x%lux is ignored because of -R0x%lux\n", 1213e12c5d1SDavid du Colombier INITDAT, INITRND); 1223e12c5d1SDavid du Colombier if(debug['v']) 1233e12c5d1SDavid du Colombier Bprint(&bso, "HEADER = -H0x%ld -T0x%lux -D0x%lux -R0x%lux\n", 1243e12c5d1SDavid du Colombier HEADTYPE, INITTEXT, INITDAT, INITRND); 1253e12c5d1SDavid du Colombier Bflush(&bso); 1263e12c5d1SDavid du Colombier zprg.as = AGOK; 1273e12c5d1SDavid du Colombier zprg.reg = NREG; 1283e12c5d1SDavid du Colombier zprg.from.name = D_NONE; 1293e12c5d1SDavid du Colombier zprg.from.type = D_NONE; 1303e12c5d1SDavid du Colombier zprg.from.reg = NREG; 1313e12c5d1SDavid du Colombier zprg.to = zprg.from; 1323e12c5d1SDavid du Colombier buildop(); 1333e12c5d1SDavid du Colombier histgen = 0; 1343e12c5d1SDavid du Colombier textp = P; 1353e12c5d1SDavid du Colombier datap = P; 1363e12c5d1SDavid du Colombier pc = 0; 137*219b2ee8SDavid du Colombier dtype = 4; 1383e12c5d1SDavid du Colombier if(outfile == 0) 1393e12c5d1SDavid du Colombier outfile = "k.out"; 1403e12c5d1SDavid du Colombier cout = create(outfile, 1, 0775); 1413e12c5d1SDavid du Colombier if(cout < 0) { 1423e12c5d1SDavid du Colombier diag("%s: cannot create\n", outfile); 1433e12c5d1SDavid du Colombier errorexit(); 1443e12c5d1SDavid du Colombier } 1453e12c5d1SDavid du Colombier nuxiinit(); 1463e12c5d1SDavid du Colombier version = 0; 1473e12c5d1SDavid du Colombier cbp = buf.cbuf; 1483e12c5d1SDavid du Colombier cbc = sizeof(buf.cbuf); 1493e12c5d1SDavid du Colombier firstp = prg(); 1503e12c5d1SDavid du Colombier lastp = firstp; 1513e12c5d1SDavid du Colombier 1523e12c5d1SDavid du Colombier if(INITENTRY == 0) { 1533e12c5d1SDavid du Colombier INITENTRY = "_main"; 1543e12c5d1SDavid du Colombier if(debug['p']) 1553e12c5d1SDavid du Colombier INITENTRY = "_mainp"; 1563e12c5d1SDavid du Colombier if(!debug['l']) 1573e12c5d1SDavid du Colombier lookup(INITENTRY, 0)->type = SXREF; 158*219b2ee8SDavid du Colombier } else 159*219b2ee8SDavid du Colombier lookup(INITENTRY, 0)->type = SXREF; 1603e12c5d1SDavid du Colombier 1613e12c5d1SDavid du Colombier while(*argv) 1623e12c5d1SDavid du Colombier objfile(*argv++); 1633e12c5d1SDavid du Colombier if(!debug['l']) 1643e12c5d1SDavid du Colombier loadlib(0, libraryp); 1653e12c5d1SDavid du Colombier firstp = firstp->link; 1663e12c5d1SDavid du Colombier if(firstp == P) 1673e12c5d1SDavid du Colombier goto out; 1683e12c5d1SDavid du Colombier patch(); 1693e12c5d1SDavid du Colombier if(debug['p']) 1703e12c5d1SDavid du Colombier if(debug['1']) 1713e12c5d1SDavid du Colombier doprof1(); 1723e12c5d1SDavid du Colombier else 1733e12c5d1SDavid du Colombier doprof2(); 1743e12c5d1SDavid du Colombier dodata(); 1753e12c5d1SDavid du Colombier follow(); 1763e12c5d1SDavid du Colombier if(firstp == P) 1773e12c5d1SDavid du Colombier goto out; 1783e12c5d1SDavid du Colombier noops(); 1793e12c5d1SDavid du Colombier span(); 1803e12c5d1SDavid du Colombier asmb(); 1813e12c5d1SDavid du Colombier undef(); 1823e12c5d1SDavid du Colombier 1833e12c5d1SDavid du Colombier out: 1843e12c5d1SDavid du Colombier if(debug['v']) { 1853e12c5d1SDavid du Colombier Bprint(&bso, "%5.2f cpu time\n", cputime()); 1863e12c5d1SDavid du Colombier Bprint(&bso, "%ld memory used\n", tothunk); 1873e12c5d1SDavid du Colombier Bprint(&bso, "%d sizeof adr\n", sizeof(Adr)); 1883e12c5d1SDavid du Colombier Bprint(&bso, "%d sizeof prog\n", sizeof(Prog)); 1893e12c5d1SDavid du Colombier } 1903e12c5d1SDavid du Colombier errorexit(); 1913e12c5d1SDavid du Colombier } 1923e12c5d1SDavid du Colombier 1933e12c5d1SDavid du Colombier void 1943e12c5d1SDavid du Colombier loadlib(int beg, int end) 1953e12c5d1SDavid du Colombier { 1963e12c5d1SDavid du Colombier int i, t; 1973e12c5d1SDavid du Colombier 1983e12c5d1SDavid du Colombier for(i=end-1; i>=beg; i--) { 1993e12c5d1SDavid du Colombier t = libraryp; 2003e12c5d1SDavid du Colombier if(debug['v']) 2013e12c5d1SDavid du Colombier Bprint(&bso, "%5.2f autolib: %s\n", cputime(), library[i]); 2023e12c5d1SDavid du Colombier objfile(library[i]); 2033e12c5d1SDavid du Colombier if(t != libraryp) 2043e12c5d1SDavid du Colombier loadlib(t, libraryp); 2053e12c5d1SDavid du Colombier } 2063e12c5d1SDavid du Colombier } 2073e12c5d1SDavid du Colombier 2083e12c5d1SDavid du Colombier void 2093e12c5d1SDavid du Colombier errorexit(void) 2103e12c5d1SDavid du Colombier { 2113e12c5d1SDavid du Colombier 2123e12c5d1SDavid du Colombier Bflush(&bso); 2133e12c5d1SDavid du Colombier if(nerrors) { 2143e12c5d1SDavid du Colombier if(cout >= 0) 2153e12c5d1SDavid du Colombier remove(outfile); 2163e12c5d1SDavid du Colombier exits("error"); 2173e12c5d1SDavid du Colombier } 2183e12c5d1SDavid du Colombier exits(0); 2193e12c5d1SDavid du Colombier } 2203e12c5d1SDavid du Colombier 2213e12c5d1SDavid du Colombier void 2223e12c5d1SDavid du Colombier objfile(char *file) 2233e12c5d1SDavid du Colombier { 224*219b2ee8SDavid du Colombier long off, esym, cnt, l; 2253e12c5d1SDavid du Colombier int f, work; 2263e12c5d1SDavid du Colombier Sym *s; 2273e12c5d1SDavid du Colombier char magbuf[SARMAG]; 2283e12c5d1SDavid du Colombier char name[100], pname[150]; 2293e12c5d1SDavid du Colombier struct ar_hdr arhdr; 230*219b2ee8SDavid du Colombier char *e, *start, *stop; 2313e12c5d1SDavid du Colombier 2323e12c5d1SDavid du Colombier if(file[0] == '-' && file[1] == 'l') { 2333e12c5d1SDavid du Colombier if(debug['9']) 234*219b2ee8SDavid du Colombier sprint(name, "/%s/lib/lib", thestring); 2353e12c5d1SDavid du Colombier else 236*219b2ee8SDavid du Colombier sprint(name, "/usr/%clib/lib", thechar); 2373e12c5d1SDavid du Colombier strcat(name, file+2); 2383e12c5d1SDavid du Colombier strcat(name, ".a"); 2393e12c5d1SDavid du Colombier file = name; 2403e12c5d1SDavid du Colombier } 2413e12c5d1SDavid du Colombier if(debug['v']) 2423e12c5d1SDavid du Colombier Bprint(&bso, "%5.2f ldobj: %s\n", cputime(), file); 2433e12c5d1SDavid du Colombier Bflush(&bso); 2443e12c5d1SDavid du Colombier f = open(file, 0); 2453e12c5d1SDavid du Colombier if(f < 0) { 2463e12c5d1SDavid du Colombier diag("cannot open file: %s\n", file); 2473e12c5d1SDavid du Colombier errorexit(); 2483e12c5d1SDavid du Colombier } 2493e12c5d1SDavid du Colombier l = read(f, magbuf, SARMAG); 250*219b2ee8SDavid du Colombier if(l != SARMAG || strncmp(magbuf, ARMAG, SARMAG)){ 251*219b2ee8SDavid du Colombier /* load it as a regular file */ 252*219b2ee8SDavid du Colombier l = seek(f, 0L, 2); 253*219b2ee8SDavid du Colombier seek(f, 0L, 0); 254*219b2ee8SDavid du Colombier ldobj(f, l, file); 255*219b2ee8SDavid du Colombier close(f); 256*219b2ee8SDavid du Colombier return; 257*219b2ee8SDavid du Colombier } 2583e12c5d1SDavid du Colombier 2593e12c5d1SDavid du Colombier l = read(f, &arhdr, sizeof(struct ar_hdr)); 2603e12c5d1SDavid du Colombier if(l != sizeof(struct ar_hdr)) { 2613e12c5d1SDavid du Colombier diag("%s: short read on archive file symbol header\n", file); 2623e12c5d1SDavid du Colombier goto out; 2633e12c5d1SDavid du Colombier } 2643e12c5d1SDavid du Colombier if(strncmp(arhdr.name, symname, strlen(symname))) { 2653e12c5d1SDavid du Colombier diag("%s: first entry not symbol header\n", file); 2663e12c5d1SDavid du Colombier goto out; 2673e12c5d1SDavid du Colombier } 2683e12c5d1SDavid du Colombier 269*219b2ee8SDavid du Colombier esym = SARMAG + sizeof(struct ar_hdr) + atolwhex(arhdr.size); 2703e12c5d1SDavid du Colombier off = SARMAG + sizeof(struct ar_hdr); 2713e12c5d1SDavid du Colombier 272*219b2ee8SDavid du Colombier /* 273*219b2ee8SDavid du Colombier * just bang the whole symbol file into memory 274*219b2ee8SDavid du Colombier */ 2753e12c5d1SDavid du Colombier seek(f, off, 0); 2763e12c5d1SDavid du Colombier cnt = esym - off; 277*219b2ee8SDavid du Colombier start = malloc(cnt + 10); 278*219b2ee8SDavid du Colombier cnt = read(f, start, cnt); 2793e12c5d1SDavid du Colombier if(cnt <= 0){ 2803e12c5d1SDavid du Colombier close(f); 2813e12c5d1SDavid du Colombier return; 2823e12c5d1SDavid du Colombier } 283*219b2ee8SDavid du Colombier stop = &start[cnt]; 284*219b2ee8SDavid du Colombier memset(stop, 0, 10); 285*219b2ee8SDavid du Colombier 286*219b2ee8SDavid du Colombier work = 1; 287*219b2ee8SDavid du Colombier while(work){ 288*219b2ee8SDavid du Colombier if(debug['v']) 289*219b2ee8SDavid du Colombier Bprint(&bso, "%5.2f library pass: %s\n", cputime(), file); 290*219b2ee8SDavid du Colombier Bflush(&bso); 291*219b2ee8SDavid du Colombier work = 0; 292*219b2ee8SDavid du Colombier for(e = start; e < stop; e = strchr(e+5, 0) + 1) { 293*219b2ee8SDavid du Colombier s = lookup(e+5, 0); 2943e12c5d1SDavid du Colombier if(s->type != SXREF) 2953e12c5d1SDavid du Colombier continue; 296*219b2ee8SDavid du Colombier sprint(pname, "%s(%s)", file, s->name); 2973e12c5d1SDavid du Colombier if(debug['v']) 2983e12c5d1SDavid du Colombier Bprint(&bso, "%5.2f library: %s\n", cputime(), pname); 2993e12c5d1SDavid du Colombier Bflush(&bso); 300*219b2ee8SDavid du Colombier l = e[1] & 0xff; 301*219b2ee8SDavid du Colombier l |= (e[2] & 0xff) << 8; 302*219b2ee8SDavid du Colombier l |= (e[3] & 0xff) << 16; 303*219b2ee8SDavid du Colombier l |= (e[4] & 0xff) << 24; 3043e12c5d1SDavid du Colombier seek(f, l, 0); 3053e12c5d1SDavid du Colombier l = read(f, &arhdr, sizeof(struct ar_hdr)); 3063e12c5d1SDavid du Colombier if(l != sizeof(struct ar_hdr)) 3073e12c5d1SDavid du Colombier goto bad; 3083e12c5d1SDavid du Colombier if(strncmp(arhdr.fmag, ARFMAG, sizeof(arhdr.fmag))) 3093e12c5d1SDavid du Colombier goto bad; 3103e12c5d1SDavid du Colombier l = atolwhex(arhdr.size); 3113e12c5d1SDavid du Colombier ldobj(f, l, pname); 3123e12c5d1SDavid du Colombier if(s->type == SXREF) { 3133e12c5d1SDavid du Colombier diag("%s: failed to load: %s\n", file, s->name); 3143e12c5d1SDavid du Colombier errorexit(); 3153e12c5d1SDavid du Colombier } 3163e12c5d1SDavid du Colombier work = 1; 3173e12c5d1SDavid du Colombier } 318*219b2ee8SDavid du Colombier } 3193e12c5d1SDavid du Colombier return; 3203e12c5d1SDavid du Colombier 3213e12c5d1SDavid du Colombier bad: 3223e12c5d1SDavid du Colombier diag("%s: bad or out of date archive\n", file); 3233e12c5d1SDavid du Colombier out: 3243e12c5d1SDavid du Colombier close(f); 3253e12c5d1SDavid du Colombier } 3263e12c5d1SDavid du Colombier 3273e12c5d1SDavid du Colombier int 3283e12c5d1SDavid du Colombier zaddr(uchar *p, Adr *a, Sym *h[]) 3293e12c5d1SDavid du Colombier { 3303e12c5d1SDavid du Colombier int i, c; 3313e12c5d1SDavid du Colombier long l; 3323e12c5d1SDavid du Colombier Sym *s; 3333e12c5d1SDavid du Colombier Auto *u; 3343e12c5d1SDavid du Colombier 335*219b2ee8SDavid du Colombier c = p[2]; 336*219b2ee8SDavid du Colombier if(c < 0 || c > NSYM){ 337*219b2ee8SDavid du Colombier print("sym out of range: %d\n", c); 338*219b2ee8SDavid du Colombier p[0] = AEND+1; 339*219b2ee8SDavid du Colombier return 0; 340*219b2ee8SDavid du Colombier } 3413e12c5d1SDavid du Colombier a->type = p[0]; 3423e12c5d1SDavid du Colombier a->reg = p[1]; 343*219b2ee8SDavid du Colombier a->sym = h[c]; 3443e12c5d1SDavid du Colombier a->name = p[3]; 3453e12c5d1SDavid du Colombier c = 4; 3463e12c5d1SDavid du Colombier 3473e12c5d1SDavid du Colombier if(a->reg < 0 || a->reg > NREG) { 3483e12c5d1SDavid du Colombier print("register out of range %d\n", a->reg); 3493e12c5d1SDavid du Colombier p[0] = AEND+1; 3503e12c5d1SDavid du Colombier return 0; /* force real diagnostic */ 3513e12c5d1SDavid du Colombier } 3523e12c5d1SDavid du Colombier 3533e12c5d1SDavid du Colombier switch(a->type) { 3543e12c5d1SDavid du Colombier default: 3553e12c5d1SDavid du Colombier print("unknown type %d\n", a->type); 3563e12c5d1SDavid du Colombier p[0] = AEND+1; 3573e12c5d1SDavid du Colombier return 0; /* force real diagnostic */ 3583e12c5d1SDavid du Colombier 3593e12c5d1SDavid du Colombier case D_NONE: 3603e12c5d1SDavid du Colombier case D_REG: 3613e12c5d1SDavid du Colombier case D_FREG: 3623e12c5d1SDavid du Colombier case D_CREG: 3633e12c5d1SDavid du Colombier case D_PREG: 3643e12c5d1SDavid du Colombier break; 3653e12c5d1SDavid du Colombier 3663e12c5d1SDavid du Colombier case D_BRANCH: 3673e12c5d1SDavid du Colombier case D_OREG: 3683e12c5d1SDavid du Colombier case D_ASI: 3693e12c5d1SDavid du Colombier case D_CONST: 3703e12c5d1SDavid du Colombier a->offset = p[4] | (p[5]<<8) | 3713e12c5d1SDavid du Colombier (p[6]<<16) | (p[7]<<24); 3723e12c5d1SDavid du Colombier c += 4; 3733e12c5d1SDavid du Colombier break; 3743e12c5d1SDavid du Colombier 3753e12c5d1SDavid du Colombier case D_SCONST: 3763e12c5d1SDavid du Colombier memmove(a->sval, p+4, NSNAME); 3773e12c5d1SDavid du Colombier c += NSNAME; 3783e12c5d1SDavid du Colombier break; 3793e12c5d1SDavid du Colombier 3803e12c5d1SDavid du Colombier case D_FCONST: 3813e12c5d1SDavid du Colombier a->ieee.l = p[4] | (p[5]<<8) | 3823e12c5d1SDavid du Colombier (p[6]<<16) | (p[7]<<24); 3833e12c5d1SDavid du Colombier a->ieee.h = p[8] | (p[9]<<8) | 3843e12c5d1SDavid du Colombier (p[10]<<16) | (p[11]<<24); 3853e12c5d1SDavid du Colombier c += 8; 3863e12c5d1SDavid du Colombier break; 3873e12c5d1SDavid du Colombier } 3883e12c5d1SDavid du Colombier s = a->sym; 3893e12c5d1SDavid du Colombier if(s == S) 3903e12c5d1SDavid du Colombier goto out; 3913e12c5d1SDavid du Colombier i = a->name; 3923e12c5d1SDavid du Colombier if(i != D_AUTO && i != D_PARAM) 3933e12c5d1SDavid du Colombier goto out; 3943e12c5d1SDavid du Colombier 3953e12c5d1SDavid du Colombier l = a->offset; 3963e12c5d1SDavid du Colombier for(u=curauto; u; u=u->link) 3973e12c5d1SDavid du Colombier if(u->sym == s) 3983e12c5d1SDavid du Colombier if(u->type == i) { 3993e12c5d1SDavid du Colombier if(u->offset > l) 4003e12c5d1SDavid du Colombier u->offset = l; 4013e12c5d1SDavid du Colombier goto out; 4023e12c5d1SDavid du Colombier } 4033e12c5d1SDavid du Colombier 4043e12c5d1SDavid du Colombier u = malloc(sizeof(Auto)); 4053e12c5d1SDavid du Colombier 4063e12c5d1SDavid du Colombier u->link = curauto; 4073e12c5d1SDavid du Colombier curauto = u; 4083e12c5d1SDavid du Colombier u->sym = s; 4093e12c5d1SDavid du Colombier u->offset = l; 4103e12c5d1SDavid du Colombier u->type = i; 4113e12c5d1SDavid du Colombier out: 4123e12c5d1SDavid du Colombier return c; 4133e12c5d1SDavid du Colombier } 4143e12c5d1SDavid du Colombier 4153e12c5d1SDavid du Colombier void 4163e12c5d1SDavid du Colombier addlib(long line) 4173e12c5d1SDavid du Colombier { 418*219b2ee8SDavid du Colombier char name[MAXHIST*NAMELEN], comp[4*NAMELEN], *p; 4193e12c5d1SDavid du Colombier int i; 4203e12c5d1SDavid du Colombier 4213e12c5d1SDavid du Colombier USED(line); 4223e12c5d1SDavid du Colombier if(histfrogp <= 0) 4233e12c5d1SDavid du Colombier return; 4243e12c5d1SDavid du Colombier 4253e12c5d1SDavid du Colombier if(histfrog[0]->name[1] == '/') { 4263e12c5d1SDavid du Colombier sprint(name, ""); 4273e12c5d1SDavid du Colombier i = 1; 4283e12c5d1SDavid du Colombier } else 4293e12c5d1SDavid du Colombier if(histfrog[0]->name[1] == '.') { 4303e12c5d1SDavid du Colombier sprint(name, "."); 4313e12c5d1SDavid du Colombier i = 0; 4323e12c5d1SDavid du Colombier } else { 4333e12c5d1SDavid du Colombier if(debug['9']) 434*219b2ee8SDavid du Colombier sprint(name, "/%s/lib", thestring); 4353e12c5d1SDavid du Colombier else 436*219b2ee8SDavid du Colombier sprint(name, "/usr/%clib", thechar); 4373e12c5d1SDavid du Colombier i = 0; 4383e12c5d1SDavid du Colombier } 4393e12c5d1SDavid du Colombier 4403e12c5d1SDavid du Colombier for(; i<histfrogp; i++) { 441*219b2ee8SDavid du Colombier snprint(comp, 2*NAMELEN, histfrog[i]->name+1); 4423e12c5d1SDavid du Colombier for(;;) { 4433e12c5d1SDavid du Colombier p = strstr(comp, "$O"); 4443e12c5d1SDavid du Colombier if(p == 0) 4453e12c5d1SDavid du Colombier break; 4463e12c5d1SDavid du Colombier memmove(p+1, p+2, strlen(p+2)+1); 447*219b2ee8SDavid du Colombier p[0] = thechar; 4483e12c5d1SDavid du Colombier } 4493e12c5d1SDavid du Colombier for(;;) { 4503e12c5d1SDavid du Colombier p = strstr(comp, "$M"); 4513e12c5d1SDavid du Colombier if(p == 0) 4523e12c5d1SDavid du Colombier break; 453*219b2ee8SDavid du Colombier memmove(p+strlen(thestring), p+2, strlen(p+2)+1); 454*219b2ee8SDavid du Colombier memmove(p, thestring, strlen(thestring)); 455*219b2ee8SDavid du Colombier if(strlen(comp) > NAMELEN) { 456*219b2ee8SDavid du Colombier diag("library component too long"); 457*219b2ee8SDavid du Colombier return; 4583e12c5d1SDavid du Colombier } 459*219b2ee8SDavid du Colombier } 460*219b2ee8SDavid du Colombier if(strlen(comp) > NAMELEN || strlen(name) + strlen(comp) + 3 >= sizeof(name)) { 4613e12c5d1SDavid du Colombier diag("library component too long"); 4623e12c5d1SDavid du Colombier return; 4633e12c5d1SDavid du Colombier } 4643e12c5d1SDavid du Colombier strcat(name, "/"); 4653e12c5d1SDavid du Colombier strcat(name, comp); 4663e12c5d1SDavid du Colombier } 4673e12c5d1SDavid du Colombier for(i=0; i<libraryp; i++) 4683e12c5d1SDavid du Colombier if(strcmp(name, library[i]) == 0) 4693e12c5d1SDavid du Colombier return; 4703e12c5d1SDavid du Colombier 471*219b2ee8SDavid du Colombier p = malloc(strlen(name) + 1); 4723e12c5d1SDavid du Colombier strcpy(p, name); 4733e12c5d1SDavid du Colombier library[libraryp] = p; 4743e12c5d1SDavid du Colombier libraryp++; 4753e12c5d1SDavid du Colombier } 476*219b2ee8SDavid du Colombier 4773e12c5d1SDavid du Colombier void 4783e12c5d1SDavid du Colombier addhist(long line, int type) 4793e12c5d1SDavid du Colombier { 4803e12c5d1SDavid du Colombier Auto *u; 4813e12c5d1SDavid du Colombier Sym *s; 4823e12c5d1SDavid du Colombier int i, j, k; 4833e12c5d1SDavid du Colombier 484*219b2ee8SDavid du Colombier u = malloc(sizeof(Auto)); 485*219b2ee8SDavid du Colombier s = malloc(sizeof(Sym)); 486*219b2ee8SDavid du Colombier s->name = malloc(2*(histfrogp+1) + 1); 4873e12c5d1SDavid du Colombier 4883e12c5d1SDavid du Colombier u->sym = s; 4893e12c5d1SDavid du Colombier u->type = type; 4903e12c5d1SDavid du Colombier u->offset = line; 4913e12c5d1SDavid du Colombier u->link = curhist; 4923e12c5d1SDavid du Colombier curhist = u; 4933e12c5d1SDavid du Colombier 4943e12c5d1SDavid du Colombier j = 1; 4953e12c5d1SDavid du Colombier for(i=0; i<histfrogp; i++) { 4963e12c5d1SDavid du Colombier k = histfrog[i]->value; 4973e12c5d1SDavid du Colombier s->name[j+0] = k>>8; 4983e12c5d1SDavid du Colombier s->name[j+1] = k; 4993e12c5d1SDavid du Colombier j += 2; 5003e12c5d1SDavid du Colombier } 5013e12c5d1SDavid du Colombier } 5023e12c5d1SDavid du Colombier 5033e12c5d1SDavid du Colombier void 5043e12c5d1SDavid du Colombier histtoauto(void) 5053e12c5d1SDavid du Colombier { 5063e12c5d1SDavid du Colombier Auto *l; 5073e12c5d1SDavid du Colombier 5083e12c5d1SDavid du Colombier while(l = curhist) { 5093e12c5d1SDavid du Colombier curhist = l->link; 5103e12c5d1SDavid du Colombier l->link = curauto; 5113e12c5d1SDavid du Colombier curauto = l; 5123e12c5d1SDavid du Colombier } 5133e12c5d1SDavid du Colombier } 5143e12c5d1SDavid du Colombier 5153e12c5d1SDavid du Colombier void 516*219b2ee8SDavid du Colombier collapsefrog(Sym *s) 517*219b2ee8SDavid du Colombier { 518*219b2ee8SDavid du Colombier int i; 519*219b2ee8SDavid du Colombier 520*219b2ee8SDavid du Colombier /* 521*219b2ee8SDavid du Colombier * bad encoding of path components only allows 522*219b2ee8SDavid du Colombier * MAXHIST components. if there is an overflow, 523*219b2ee8SDavid du Colombier * first try to collapse xxx/.. 524*219b2ee8SDavid du Colombier */ 525*219b2ee8SDavid du Colombier for(i=1; i<histfrogp; i++) 526*219b2ee8SDavid du Colombier if(strcmp(histfrog[i]->name+1, "..") == 0) { 527*219b2ee8SDavid du Colombier memmove(histfrog+i-1, histfrog+i+1, 528*219b2ee8SDavid du Colombier (histfrogp-i-1)*sizeof(histfrog[0])); 529*219b2ee8SDavid du Colombier histfrogp--; 530*219b2ee8SDavid du Colombier goto out; 531*219b2ee8SDavid du Colombier } 532*219b2ee8SDavid du Colombier 533*219b2ee8SDavid du Colombier /* 534*219b2ee8SDavid du Colombier * next try to collapse . 535*219b2ee8SDavid du Colombier */ 536*219b2ee8SDavid du Colombier for(i=0; i<histfrogp; i++) 537*219b2ee8SDavid du Colombier if(strcmp(histfrog[i]->name+1, ".") == 0) { 538*219b2ee8SDavid du Colombier memmove(histfrog+i, histfrog+i+1, 539*219b2ee8SDavid du Colombier (histfrogp-i-1)*sizeof(histfrog[0])); 540*219b2ee8SDavid du Colombier goto out; 541*219b2ee8SDavid du Colombier } 542*219b2ee8SDavid du Colombier 543*219b2ee8SDavid du Colombier /* 544*219b2ee8SDavid du Colombier * last chance, just truncate from front 545*219b2ee8SDavid du Colombier */ 546*219b2ee8SDavid du Colombier memmove(histfrog+0, histfrog+1, 547*219b2ee8SDavid du Colombier (histfrogp-1)*sizeof(histfrog[0])); 548*219b2ee8SDavid du Colombier 549*219b2ee8SDavid du Colombier out: 550*219b2ee8SDavid du Colombier histfrog[histfrogp-1] = s; 551*219b2ee8SDavid du Colombier } 552*219b2ee8SDavid du Colombier 553*219b2ee8SDavid du Colombier void 554*219b2ee8SDavid du Colombier nopout(Prog *p) 555*219b2ee8SDavid du Colombier { 556*219b2ee8SDavid du Colombier p->as = ANOP; 557*219b2ee8SDavid du Colombier p->from.type = D_NONE; 558*219b2ee8SDavid du Colombier p->to.type = D_NONE; 559*219b2ee8SDavid du Colombier } 560*219b2ee8SDavid du Colombier 561*219b2ee8SDavid du Colombier uchar* 562*219b2ee8SDavid du Colombier readsome(int f, uchar *buf, uchar *good, uchar *stop, int max) 563*219b2ee8SDavid du Colombier { 564*219b2ee8SDavid du Colombier int n; 565*219b2ee8SDavid du Colombier 566*219b2ee8SDavid du Colombier n = stop - good; 567*219b2ee8SDavid du Colombier memmove(buf, good, stop - good); 568*219b2ee8SDavid du Colombier stop = buf + n; 569*219b2ee8SDavid du Colombier n = MAXIO - n; 570*219b2ee8SDavid du Colombier if(n > max) 571*219b2ee8SDavid du Colombier n = max; 572*219b2ee8SDavid du Colombier n = read(f, stop, n); 573*219b2ee8SDavid du Colombier if(n <= 0) 574*219b2ee8SDavid du Colombier return 0; 575*219b2ee8SDavid du Colombier return stop + n; 576*219b2ee8SDavid du Colombier } 577*219b2ee8SDavid du Colombier 578*219b2ee8SDavid du Colombier void 5793e12c5d1SDavid du Colombier ldobj(int f, long c, char *pn) 5803e12c5d1SDavid du Colombier { 5813e12c5d1SDavid du Colombier Prog *p, *t; 582*219b2ee8SDavid du Colombier Sym *h[NSYM], *s, *di; 583*219b2ee8SDavid du Colombier int v, o, r, skip; 5843e12c5d1SDavid du Colombier long ipc; 585*219b2ee8SDavid du Colombier uchar *bloc, *bsize, *stop; 5863e12c5d1SDavid du Colombier 5873e12c5d1SDavid du Colombier bsize = buf.xbuf; 5883e12c5d1SDavid du Colombier bloc = buf.xbuf; 589*219b2ee8SDavid du Colombier di = S; 5903e12c5d1SDavid du Colombier 5913e12c5d1SDavid du Colombier newloop: 5923e12c5d1SDavid du Colombier memset(h, 0, sizeof(h)); 5933e12c5d1SDavid du Colombier histfrogp = 0; 5943e12c5d1SDavid du Colombier version++; 5953e12c5d1SDavid du Colombier ipc = pc; 596*219b2ee8SDavid du Colombier skip = 0; 5973e12c5d1SDavid du Colombier 5983e12c5d1SDavid du Colombier loop: 5993e12c5d1SDavid du Colombier if(c <= 0) 6003e12c5d1SDavid du Colombier goto eof; 6013e12c5d1SDavid du Colombier r = bsize - bloc; 6023e12c5d1SDavid du Colombier if(r < 100 && r < c) { /* enough for largest prog */ 603*219b2ee8SDavid du Colombier bsize = readsome(f, buf.xbuf, bloc, bsize, c); 604*219b2ee8SDavid du Colombier if(bsize == 0) 6053e12c5d1SDavid du Colombier goto eof; 606*219b2ee8SDavid du Colombier bloc = buf.xbuf; 6073e12c5d1SDavid du Colombier goto loop; 6083e12c5d1SDavid du Colombier } 6093e12c5d1SDavid du Colombier o = bloc[0]; /* as */ 610*219b2ee8SDavid du Colombier if(o <= 0 || o >= ALAST) { 6113e12c5d1SDavid du Colombier diag("%s: opcode out of range %d\n", pn, o); 6123e12c5d1SDavid du Colombier print(" probably not a .k file\n"); 6133e12c5d1SDavid du Colombier errorexit(); 6143e12c5d1SDavid du Colombier } 6153e12c5d1SDavid du Colombier if(o == ANAME) { 616*219b2ee8SDavid du Colombier stop = memchr(&bloc[3], 0, bsize-&bloc[3]); 617*219b2ee8SDavid du Colombier if(stop == 0){ 618*219b2ee8SDavid du Colombier bsize = readsome(f, buf.xbuf, bloc, bsize, c); 619*219b2ee8SDavid du Colombier if(bsize == 0) 620*219b2ee8SDavid du Colombier goto eof; 621*219b2ee8SDavid du Colombier bloc = buf.xbuf; 622*219b2ee8SDavid du Colombier stop = memchr(&bloc[3], 0, bsize-&bloc[3]); 623*219b2ee8SDavid du Colombier if(stop == 0){ 624*219b2ee8SDavid du Colombier fprint(2, "%s: name too long\n", pn); 625*219b2ee8SDavid du Colombier errorexit(); 626*219b2ee8SDavid du Colombier } 627*219b2ee8SDavid du Colombier } 6283e12c5d1SDavid du Colombier v = bloc[1]; /* type */ 6293e12c5d1SDavid du Colombier o = bloc[2]; /* sym */ 6303e12c5d1SDavid du Colombier bloc += 3; 6313e12c5d1SDavid du Colombier c -= 3; 632*219b2ee8SDavid du Colombier 6333e12c5d1SDavid du Colombier r = 0; 6343e12c5d1SDavid du Colombier if(v == D_STATIC) 6353e12c5d1SDavid du Colombier r = version; 636*219b2ee8SDavid du Colombier s = lookup((char*)bloc, r); 637*219b2ee8SDavid du Colombier c -= &stop[1] - bloc; 638*219b2ee8SDavid du Colombier bloc = stop + 1; 639*219b2ee8SDavid du Colombier 6403e12c5d1SDavid du Colombier if(debug['W']) 6413e12c5d1SDavid du Colombier print(" ANAME %s\n", s->name); 6423e12c5d1SDavid du Colombier h[o] = s; 643*219b2ee8SDavid du Colombier if((v == D_EXTERN || v == D_STATIC) && s->type == 0) 6443e12c5d1SDavid du Colombier s->type = SXREF; 6453e12c5d1SDavid du Colombier if(v == D_FILE) { 6463e12c5d1SDavid du Colombier if(s->type != SFILE) { 6473e12c5d1SDavid du Colombier histgen++; 6483e12c5d1SDavid du Colombier s->type = SFILE; 6493e12c5d1SDavid du Colombier s->value = histgen; 6503e12c5d1SDavid du Colombier } 651*219b2ee8SDavid du Colombier if(histfrogp < MAXHIST) { 6523e12c5d1SDavid du Colombier histfrog[histfrogp] = s; 6533e12c5d1SDavid du Colombier histfrogp++; 654*219b2ee8SDavid du Colombier } else 655*219b2ee8SDavid du Colombier collapsefrog(s); 6563e12c5d1SDavid du Colombier } 6573e12c5d1SDavid du Colombier goto loop; 6583e12c5d1SDavid du Colombier } 6593e12c5d1SDavid du Colombier 6603e12c5d1SDavid du Colombier if(nhunk < sizeof(Prog)) 6613e12c5d1SDavid du Colombier gethunk(); 6623e12c5d1SDavid du Colombier p = (Prog*)hunk; 6633e12c5d1SDavid du Colombier nhunk -= sizeof(Prog); 6643e12c5d1SDavid du Colombier hunk += sizeof(Prog); 6653e12c5d1SDavid du Colombier 6663e12c5d1SDavid du Colombier p->as = o; 667*219b2ee8SDavid du Colombier p->reg = bloc[1] & 0x7f; 668*219b2ee8SDavid du Colombier if(bloc[1] & 0x80) 669*219b2ee8SDavid du Colombier p->mark = NOSCHED; 6703e12c5d1SDavid du Colombier p->line = bloc[2] | (bloc[3]<<8) | (bloc[4]<<16) | (bloc[5]<<24); 6713e12c5d1SDavid du Colombier r = zaddr(bloc+6, &p->from, h) + 6; 6723e12c5d1SDavid du Colombier r += zaddr(bloc+r, &p->to, h); 6733e12c5d1SDavid du Colombier bloc += r; 6743e12c5d1SDavid du Colombier c -= r; 6753e12c5d1SDavid du Colombier 6763e12c5d1SDavid du Colombier if(p->reg < 0 || p->reg > NREG) 6773e12c5d1SDavid du Colombier diag("register out of range %d\n", p->reg); 6783e12c5d1SDavid du Colombier 6793e12c5d1SDavid du Colombier p->link = P; 6803e12c5d1SDavid du Colombier p->cond = P; 6813e12c5d1SDavid du Colombier 6823e12c5d1SDavid du Colombier if(debug['W']) 6833e12c5d1SDavid du Colombier print("%P\n", p); 6843e12c5d1SDavid du Colombier 6853e12c5d1SDavid du Colombier switch(o) { 6863e12c5d1SDavid du Colombier case AHISTORY: 6873e12c5d1SDavid du Colombier if(p->to.offset == -1) { 6883e12c5d1SDavid du Colombier addlib(p->line); 6893e12c5d1SDavid du Colombier histfrogp = 0; 6903e12c5d1SDavid du Colombier goto loop; 6913e12c5d1SDavid du Colombier } 692*219b2ee8SDavid du Colombier addhist(p->line, D_FILE); /* 'z' */ 6933e12c5d1SDavid du Colombier if(p->to.offset) 694*219b2ee8SDavid du Colombier addhist(p->to.offset, D_FILE1); /* 'Z' */ 6953e12c5d1SDavid du Colombier histfrogp = 0; 6963e12c5d1SDavid du Colombier goto loop; 6973e12c5d1SDavid du Colombier 6983e12c5d1SDavid du Colombier case AEND: 6993e12c5d1SDavid du Colombier histtoauto(); 7003e12c5d1SDavid du Colombier if(curtext != P) 7013e12c5d1SDavid du Colombier curtext->to.autom = curauto; 7023e12c5d1SDavid du Colombier curauto = 0; 7033e12c5d1SDavid du Colombier curtext = P; 7043e12c5d1SDavid du Colombier if(c) 7053e12c5d1SDavid du Colombier goto newloop; 7063e12c5d1SDavid du Colombier return; 7073e12c5d1SDavid du Colombier 7083e12c5d1SDavid du Colombier case AGLOBL: 7093e12c5d1SDavid du Colombier s = p->from.sym; 7103e12c5d1SDavid du Colombier if(s == S) { 7113e12c5d1SDavid du Colombier diag("GLOBL must have a name\n%P\n", p); 7123e12c5d1SDavid du Colombier errorexit(); 7133e12c5d1SDavid du Colombier } 7143e12c5d1SDavid du Colombier if(s->type == 0 || s->type == SXREF) { 7153e12c5d1SDavid du Colombier s->type = SBSS; 7163e12c5d1SDavid du Colombier s->value = 0; 7173e12c5d1SDavid du Colombier } 7183e12c5d1SDavid du Colombier if(s->type != SBSS) { 7193e12c5d1SDavid du Colombier diag("redefinition: %s\n%P\n", s->name, p); 7203e12c5d1SDavid du Colombier s->type = SBSS; 7213e12c5d1SDavid du Colombier s->value = 0; 7223e12c5d1SDavid du Colombier } 7233e12c5d1SDavid du Colombier if(p->to.offset > s->value) 7243e12c5d1SDavid du Colombier s->value = p->to.offset; 7253e12c5d1SDavid du Colombier break; 7263e12c5d1SDavid du Colombier 727*219b2ee8SDavid du Colombier case ADYNT: 728*219b2ee8SDavid du Colombier if(p->to.sym == S) { 729*219b2ee8SDavid du Colombier diag("DYNT without a sym\n%P\n", p); 730*219b2ee8SDavid du Colombier break; 731*219b2ee8SDavid du Colombier } 732*219b2ee8SDavid du Colombier di = p->to.sym; 733*219b2ee8SDavid du Colombier p->reg = 4; 734*219b2ee8SDavid du Colombier if(di->type == SXREF) { 735*219b2ee8SDavid du Colombier if(debug['z']) 736*219b2ee8SDavid du Colombier Bprint(&bso, "%P set to %d\n", p, dtype); 737*219b2ee8SDavid du Colombier di->type = SCONST; 738*219b2ee8SDavid du Colombier di->value = dtype; 739*219b2ee8SDavid du Colombier dtype += 4; 740*219b2ee8SDavid du Colombier } 741*219b2ee8SDavid du Colombier if(p->from.sym == S) 742*219b2ee8SDavid du Colombier break; 743*219b2ee8SDavid du Colombier 744*219b2ee8SDavid du Colombier p->from.offset = di->value; 745*219b2ee8SDavid du Colombier p->from.sym->type = SDATA; 746*219b2ee8SDavid du Colombier if(curtext == P) { 747*219b2ee8SDavid du Colombier diag("DYNT not in text: %P\n", p); 748*219b2ee8SDavid du Colombier break; 749*219b2ee8SDavid du Colombier } 750*219b2ee8SDavid du Colombier p->to.sym = curtext->from.sym; 751*219b2ee8SDavid du Colombier p->to.type = D_CONST; 752*219b2ee8SDavid du Colombier p->link = datap; 753*219b2ee8SDavid du Colombier datap = p; 754*219b2ee8SDavid du Colombier break; 755*219b2ee8SDavid du Colombier 756*219b2ee8SDavid du Colombier case AINIT: 757*219b2ee8SDavid du Colombier if(p->from.sym == S) { 758*219b2ee8SDavid du Colombier diag("INIT without a sym\n%P\n", p); 759*219b2ee8SDavid du Colombier break; 760*219b2ee8SDavid du Colombier } 761*219b2ee8SDavid du Colombier if(di == S) { 762*219b2ee8SDavid du Colombier diag("INIT without previous DYNT\n%P\n", p); 763*219b2ee8SDavid du Colombier break; 764*219b2ee8SDavid du Colombier } 765*219b2ee8SDavid du Colombier p->from.offset = di->value; 766*219b2ee8SDavid du Colombier p->from.sym->type = SDATA; 767*219b2ee8SDavid du Colombier p->link = datap; 768*219b2ee8SDavid du Colombier datap = p; 769*219b2ee8SDavid du Colombier break; 770*219b2ee8SDavid du Colombier 7713e12c5d1SDavid du Colombier case ADATA: 7723e12c5d1SDavid du Colombier p->link = datap; 7733e12c5d1SDavid du Colombier datap = p; 7743e12c5d1SDavid du Colombier break; 7753e12c5d1SDavid du Colombier 7763e12c5d1SDavid du Colombier case AGOK: 7773e12c5d1SDavid du Colombier diag("unknown opcode\n%P\n", p); 7783e12c5d1SDavid du Colombier p->pc = pc; 7793e12c5d1SDavid du Colombier pc++; 7803e12c5d1SDavid du Colombier break; 7813e12c5d1SDavid du Colombier 7823e12c5d1SDavid du Colombier case ATEXT: 7833e12c5d1SDavid du Colombier if(curtext != P) { 7843e12c5d1SDavid du Colombier histtoauto(); 7853e12c5d1SDavid du Colombier curtext->to.autom = curauto; 7863e12c5d1SDavid du Colombier curauto = 0; 7873e12c5d1SDavid du Colombier } 7883e12c5d1SDavid du Colombier curtext = p; 7893e12c5d1SDavid du Colombier autosize = (p->to.offset+3L) & ~3L; 7903e12c5d1SDavid du Colombier p->to.offset = autosize; 7913e12c5d1SDavid du Colombier autosize += 4; 7923e12c5d1SDavid du Colombier s = p->from.sym; 7933e12c5d1SDavid du Colombier if(s == S) { 7943e12c5d1SDavid du Colombier diag("TEXT must have a name\n%P\n", p); 7953e12c5d1SDavid du Colombier errorexit(); 7963e12c5d1SDavid du Colombier } 797*219b2ee8SDavid du Colombier if(s->type != 0 && s->type != SXREF) { 798*219b2ee8SDavid du Colombier if(p->reg & DUPOK) { 799*219b2ee8SDavid du Colombier skip = 1; 800*219b2ee8SDavid du Colombier goto casedef; 801*219b2ee8SDavid du Colombier } 8023e12c5d1SDavid du Colombier diag("redefinition: %s\n%P\n", s->name, p); 803*219b2ee8SDavid du Colombier } 8043e12c5d1SDavid du Colombier s->type = STEXT; 8053e12c5d1SDavid du Colombier s->value = pc; 8063e12c5d1SDavid du Colombier if(textp != P) { 8073e12c5d1SDavid du Colombier for(t = textp; t->cond != P; t = t->cond) 8083e12c5d1SDavid du Colombier ; 8093e12c5d1SDavid du Colombier t->cond = p; 8103e12c5d1SDavid du Colombier } else 8113e12c5d1SDavid du Colombier textp = p; 8123e12c5d1SDavid du Colombier lastp->link = p; 8133e12c5d1SDavid du Colombier lastp = p; 8143e12c5d1SDavid du Colombier p->pc = pc; 8153e12c5d1SDavid du Colombier pc++; 8163e12c5d1SDavid du Colombier break; 8173e12c5d1SDavid du Colombier 8183e12c5d1SDavid du Colombier case AFMOVF: 819*219b2ee8SDavid du Colombier if(skip) 820*219b2ee8SDavid du Colombier goto casedef; 821*219b2ee8SDavid du Colombier 8223e12c5d1SDavid du Colombier if(p->from.type == D_FCONST) { 8233e12c5d1SDavid du Colombier /* size sb 9 max */ 8243e12c5d1SDavid du Colombier sprint(literal, "$%lux", ieeedtof(&p->from.ieee)); 8253e12c5d1SDavid du Colombier s = lookup(literal, 0); 8263e12c5d1SDavid du Colombier if(s->type == 0) { 8273e12c5d1SDavid du Colombier s->type = SBSS; 8283e12c5d1SDavid du Colombier s->value = 4; 8293e12c5d1SDavid du Colombier t = prg(); 8303e12c5d1SDavid du Colombier t->as = ADATA; 8313e12c5d1SDavid du Colombier t->line = p->line; 8323e12c5d1SDavid du Colombier t->from.type = D_OREG; 8333e12c5d1SDavid du Colombier t->from.sym = s; 8343e12c5d1SDavid du Colombier t->from.name = D_EXTERN; 8353e12c5d1SDavid du Colombier t->reg = 4; 8363e12c5d1SDavid du Colombier t->to = p->from; 8373e12c5d1SDavid du Colombier t->link = datap; 8383e12c5d1SDavid du Colombier datap = t; 8393e12c5d1SDavid du Colombier } 8403e12c5d1SDavid du Colombier p->from.type = D_OREG; 8413e12c5d1SDavid du Colombier p->from.sym = s; 8423e12c5d1SDavid du Colombier p->from.name = D_EXTERN; 8433e12c5d1SDavid du Colombier p->from.offset = 0; 8443e12c5d1SDavid du Colombier } 8453e12c5d1SDavid du Colombier goto casedef; 8463e12c5d1SDavid du Colombier 8473e12c5d1SDavid du Colombier case AFMOVD: 848*219b2ee8SDavid du Colombier if(skip) 849*219b2ee8SDavid du Colombier goto casedef; 8503e12c5d1SDavid du Colombier if(p->from.type == D_FCONST) { 8513e12c5d1SDavid du Colombier /* size sb 18 max */ 8523e12c5d1SDavid du Colombier sprint(literal, "$%lux.%lux", 8533e12c5d1SDavid du Colombier p->from.ieee.l, p->from.ieee.h); 8543e12c5d1SDavid du Colombier s = lookup(literal, 0); 8553e12c5d1SDavid du Colombier if(s->type == 0) { 8563e12c5d1SDavid du Colombier s->type = SBSS; 8573e12c5d1SDavid du Colombier s->value = 8; 8583e12c5d1SDavid du Colombier t = prg(); 8593e12c5d1SDavid du Colombier t->as = ADATA; 8603e12c5d1SDavid du Colombier t->line = p->line; 8613e12c5d1SDavid du Colombier t->from.type = D_OREG; 8623e12c5d1SDavid du Colombier t->from.sym = s; 8633e12c5d1SDavid du Colombier t->from.name = D_EXTERN; 8643e12c5d1SDavid du Colombier t->reg = 8; 8653e12c5d1SDavid du Colombier t->to = p->from; 8663e12c5d1SDavid du Colombier t->link = datap; 8673e12c5d1SDavid du Colombier datap = t; 8683e12c5d1SDavid du Colombier } 8693e12c5d1SDavid du Colombier p->from.type = D_OREG; 8703e12c5d1SDavid du Colombier p->from.sym = s; 8713e12c5d1SDavid du Colombier p->from.name = D_EXTERN; 8723e12c5d1SDavid du Colombier p->from.offset = 0; 8733e12c5d1SDavid du Colombier } 8743e12c5d1SDavid du Colombier goto casedef; 8753e12c5d1SDavid du Colombier 8763e12c5d1SDavid du Colombier default: 8773e12c5d1SDavid du Colombier casedef: 878*219b2ee8SDavid du Colombier if(skip) 879*219b2ee8SDavid du Colombier nopout(p); 880*219b2ee8SDavid du Colombier 8813e12c5d1SDavid du Colombier if(p->to.type == D_BRANCH) 8823e12c5d1SDavid du Colombier p->to.offset += ipc; 8833e12c5d1SDavid du Colombier lastp->link = p; 8843e12c5d1SDavid du Colombier lastp = p; 8853e12c5d1SDavid du Colombier p->pc = pc; 8863e12c5d1SDavid du Colombier pc++; 8873e12c5d1SDavid du Colombier break; 8883e12c5d1SDavid du Colombier } 8893e12c5d1SDavid du Colombier goto loop; 8903e12c5d1SDavid du Colombier 8913e12c5d1SDavid du Colombier eof: 8923e12c5d1SDavid du Colombier diag("truncated object file: %s\n", pn); 8933e12c5d1SDavid du Colombier } 8943e12c5d1SDavid du Colombier 8953e12c5d1SDavid du Colombier Sym* 8963e12c5d1SDavid du Colombier lookup(char *symb, int v) 8973e12c5d1SDavid du Colombier { 8983e12c5d1SDavid du Colombier Sym *s; 8993e12c5d1SDavid du Colombier char *p; 9003e12c5d1SDavid du Colombier long h; 901*219b2ee8SDavid du Colombier int c, l; 9023e12c5d1SDavid du Colombier 9033e12c5d1SDavid du Colombier h = v; 904*219b2ee8SDavid du Colombier for(p=symb; c = *p; p++) 905*219b2ee8SDavid du Colombier h = h+h+h + c; 906*219b2ee8SDavid du Colombier l = (p - symb) + 1; 9073e12c5d1SDavid du Colombier if(h < 0) 9083e12c5d1SDavid du Colombier h = ~h; 9093e12c5d1SDavid du Colombier h %= NHASH; 9103e12c5d1SDavid du Colombier for(s = hash[h]; s != S; s = s->link) 9113e12c5d1SDavid du Colombier if(s->version == v) 912*219b2ee8SDavid du Colombier if(memcmp(s->name, symb, l) == 0) 9133e12c5d1SDavid du Colombier return s; 9143e12c5d1SDavid du Colombier 915*219b2ee8SDavid du Colombier while(nhunk < sizeof(Sym)) 916*219b2ee8SDavid du Colombier gethunk(); 917*219b2ee8SDavid du Colombier s = (Sym*)hunk; 918*219b2ee8SDavid du Colombier nhunk -= sizeof(Sym); 919*219b2ee8SDavid du Colombier hunk += sizeof(Sym); 9203e12c5d1SDavid du Colombier 921*219b2ee8SDavid du Colombier s->name = malloc(l + 1); 922*219b2ee8SDavid du Colombier memmove(s->name, symb, l); 923*219b2ee8SDavid du Colombier 9243e12c5d1SDavid du Colombier s->link = hash[h]; 9253e12c5d1SDavid du Colombier s->type = 0; 9263e12c5d1SDavid du Colombier s->version = v; 9273e12c5d1SDavid du Colombier s->value = 0; 9283e12c5d1SDavid du Colombier hash[h] = s; 9293e12c5d1SDavid du Colombier return s; 9303e12c5d1SDavid du Colombier } 9313e12c5d1SDavid du Colombier 9323e12c5d1SDavid du Colombier Prog* 9333e12c5d1SDavid du Colombier prg(void) 9343e12c5d1SDavid du Colombier { 9353e12c5d1SDavid du Colombier Prog *p; 9363e12c5d1SDavid du Colombier int n; 9373e12c5d1SDavid du Colombier 9383e12c5d1SDavid du Colombier n = (sizeof(Prog) + 3) & ~3; 9393e12c5d1SDavid du Colombier while(nhunk < n) 9403e12c5d1SDavid du Colombier gethunk(); 9413e12c5d1SDavid du Colombier 9423e12c5d1SDavid du Colombier p = (Prog*)hunk; 9433e12c5d1SDavid du Colombier nhunk -= n; 9443e12c5d1SDavid du Colombier hunk += n; 9453e12c5d1SDavid du Colombier 9463e12c5d1SDavid du Colombier *p = zprg; 9473e12c5d1SDavid du Colombier return p; 9483e12c5d1SDavid du Colombier } 9493e12c5d1SDavid du Colombier 9503e12c5d1SDavid du Colombier void 9513e12c5d1SDavid du Colombier gethunk(void) 9523e12c5d1SDavid du Colombier { 9533e12c5d1SDavid du Colombier char *h; 9543e12c5d1SDavid du Colombier 9553e12c5d1SDavid du Colombier h = sbrk((int)NHUNK); 9563e12c5d1SDavid du Colombier if(h == (char *)-1) { 9573e12c5d1SDavid du Colombier diag("out of memory\n"); 9583e12c5d1SDavid du Colombier errorexit(); 9593e12c5d1SDavid du Colombier } 9603e12c5d1SDavid du Colombier 9613e12c5d1SDavid du Colombier hunk = h; 9623e12c5d1SDavid du Colombier nhunk = NHUNK; 9633e12c5d1SDavid du Colombier tothunk += NHUNK; 9643e12c5d1SDavid du Colombier } 9653e12c5d1SDavid du Colombier 9663e12c5d1SDavid du Colombier void 9673e12c5d1SDavid du Colombier doprof1(void) 9683e12c5d1SDavid du Colombier { 9693e12c5d1SDavid du Colombier Sym *s; 9703e12c5d1SDavid du Colombier long n; 9713e12c5d1SDavid du Colombier Prog *p, *q; 9723e12c5d1SDavid du Colombier 9733e12c5d1SDavid du Colombier if(debug['v']) 9743e12c5d1SDavid du Colombier Bprint(&bso, "%5.2f profile 1\n", cputime()); 9753e12c5d1SDavid du Colombier Bflush(&bso); 9763e12c5d1SDavid du Colombier s = lookup("__mcount", 0); 9773e12c5d1SDavid du Colombier n = 1; 9783e12c5d1SDavid du Colombier for(p = firstp->link; p != P; p = p->link) { 9793e12c5d1SDavid du Colombier if(p->as == ATEXT) { 9803e12c5d1SDavid du Colombier q = prg(); 9813e12c5d1SDavid du Colombier q->line = p->line; 9823e12c5d1SDavid du Colombier q->link = datap; 9833e12c5d1SDavid du Colombier datap = q; 9843e12c5d1SDavid du Colombier q->as = ADATA; 9853e12c5d1SDavid du Colombier q->from.type = D_OREG; 9863e12c5d1SDavid du Colombier q->from.name = D_EXTERN; 9873e12c5d1SDavid du Colombier q->from.offset = n*4; 9883e12c5d1SDavid du Colombier q->from.sym = s; 9893e12c5d1SDavid du Colombier q->reg = 4; 9903e12c5d1SDavid du Colombier q->to = p->from; 9913e12c5d1SDavid du Colombier q->to.type = D_CONST; 9923e12c5d1SDavid du Colombier 9933e12c5d1SDavid du Colombier q = prg(); 9943e12c5d1SDavid du Colombier q->line = p->line; 9953e12c5d1SDavid du Colombier q->pc = p->pc; 9963e12c5d1SDavid du Colombier q->link = p->link; 9973e12c5d1SDavid du Colombier p->link = q; 9983e12c5d1SDavid du Colombier p = q; 9993e12c5d1SDavid du Colombier p->as = AMOVW; 10003e12c5d1SDavid du Colombier p->from.type = D_OREG; 10013e12c5d1SDavid du Colombier p->from.name = D_EXTERN; 10023e12c5d1SDavid du Colombier p->from.sym = s; 10033e12c5d1SDavid du Colombier p->from.offset = n*4 + 4; 10043e12c5d1SDavid du Colombier p->to.type = D_REG; 10053e12c5d1SDavid du Colombier p->to.reg = REGTMP; 10063e12c5d1SDavid du Colombier 10073e12c5d1SDavid du Colombier q = prg(); 10083e12c5d1SDavid du Colombier q->line = p->line; 10093e12c5d1SDavid du Colombier q->pc = p->pc; 10103e12c5d1SDavid du Colombier q->link = p->link; 10113e12c5d1SDavid du Colombier p->link = q; 10123e12c5d1SDavid du Colombier p = q; 10133e12c5d1SDavid du Colombier p->as = AADD; 10143e12c5d1SDavid du Colombier p->from.type = D_CONST; 10153e12c5d1SDavid du Colombier p->from.offset = 1; 10163e12c5d1SDavid du Colombier p->to.type = D_REG; 10173e12c5d1SDavid du Colombier p->to.reg = REGTMP; 10183e12c5d1SDavid du Colombier 10193e12c5d1SDavid du Colombier q = prg(); 10203e12c5d1SDavid du Colombier q->line = p->line; 10213e12c5d1SDavid du Colombier q->pc = p->pc; 10223e12c5d1SDavid du Colombier q->link = p->link; 10233e12c5d1SDavid du Colombier p->link = q; 10243e12c5d1SDavid du Colombier p = q; 10253e12c5d1SDavid du Colombier p->as = AMOVW; 10263e12c5d1SDavid du Colombier p->from.type = D_REG; 10273e12c5d1SDavid du Colombier p->from.reg = REGTMP; 10283e12c5d1SDavid du Colombier p->to.type = D_OREG; 10293e12c5d1SDavid du Colombier p->to.name = D_EXTERN; 10303e12c5d1SDavid du Colombier p->to.sym = s; 10313e12c5d1SDavid du Colombier p->to.offset = n*4 + 4; 10323e12c5d1SDavid du Colombier 10333e12c5d1SDavid du Colombier n += 2; 10343e12c5d1SDavid du Colombier continue; 10353e12c5d1SDavid du Colombier } 10363e12c5d1SDavid du Colombier } 10373e12c5d1SDavid du Colombier q = prg(); 10383e12c5d1SDavid du Colombier q->line = 0; 10393e12c5d1SDavid du Colombier q->link = datap; 10403e12c5d1SDavid du Colombier datap = q; 10413e12c5d1SDavid du Colombier 10423e12c5d1SDavid du Colombier q->as = ADATA; 10433e12c5d1SDavid du Colombier q->from.type = D_OREG; 10443e12c5d1SDavid du Colombier q->from.name = D_EXTERN; 10453e12c5d1SDavid du Colombier q->from.sym = s; 10463e12c5d1SDavid du Colombier q->reg = 4; 10473e12c5d1SDavid du Colombier q->to.type = D_CONST; 10483e12c5d1SDavid du Colombier q->to.offset = n; 10493e12c5d1SDavid du Colombier 10503e12c5d1SDavid du Colombier s->type = SBSS; 10513e12c5d1SDavid du Colombier s->value = n*4; 10523e12c5d1SDavid du Colombier } 10533e12c5d1SDavid du Colombier 10543e12c5d1SDavid du Colombier void 10553e12c5d1SDavid du Colombier doprof2(void) 10563e12c5d1SDavid du Colombier { 10573e12c5d1SDavid du Colombier Sym *s2, *s4; 10583e12c5d1SDavid du Colombier Prog *p, *q, *ps2, *ps4; 10593e12c5d1SDavid du Colombier 10603e12c5d1SDavid du Colombier if(debug['v']) 10613e12c5d1SDavid du Colombier Bprint(&bso, "%5.2f profile 2\n", cputime()); 10623e12c5d1SDavid du Colombier Bflush(&bso); 10633e12c5d1SDavid du Colombier 10643e12c5d1SDavid du Colombier s2 = lookup("_profin", 0); 10653e12c5d1SDavid du Colombier s4 = lookup("_profout", 0); 10663e12c5d1SDavid du Colombier 10673e12c5d1SDavid du Colombier ps2 = P; 10683e12c5d1SDavid du Colombier ps4 = P; 10693e12c5d1SDavid du Colombier for(p = firstp; p != P; p = p->link) { 10703e12c5d1SDavid du Colombier if(p->as == ATEXT) { 10713e12c5d1SDavid du Colombier if(p->from.sym == s2) { 10723e12c5d1SDavid du Colombier p->reg = 1; 10733e12c5d1SDavid du Colombier ps2 = p; 10743e12c5d1SDavid du Colombier } 10753e12c5d1SDavid du Colombier if(p->from.sym == s4) { 10763e12c5d1SDavid du Colombier p->reg = 1; 10773e12c5d1SDavid du Colombier ps4 = p; 10783e12c5d1SDavid du Colombier } 10793e12c5d1SDavid du Colombier } 10803e12c5d1SDavid du Colombier } 10813e12c5d1SDavid du Colombier for(p = firstp; p != P; p = p->link) { 10823e12c5d1SDavid du Colombier if(p->as == ATEXT) { 10833e12c5d1SDavid du Colombier curtext = p; 10843e12c5d1SDavid du Colombier 1085*219b2ee8SDavid du Colombier if(p->reg & NOPROF) { /* dont profile */ 10863e12c5d1SDavid du Colombier for(;;) { 10873e12c5d1SDavid du Colombier q = p->link; 10883e12c5d1SDavid du Colombier if(q == P) 10893e12c5d1SDavid du Colombier break; 10903e12c5d1SDavid du Colombier if(q->as == ATEXT) 10913e12c5d1SDavid du Colombier break; 10923e12c5d1SDavid du Colombier p = q; 10933e12c5d1SDavid du Colombier } 10943e12c5d1SDavid du Colombier continue; 10953e12c5d1SDavid du Colombier } 10963e12c5d1SDavid du Colombier 10973e12c5d1SDavid du Colombier /* 10983e12c5d1SDavid du Colombier * JMPL profin 10993e12c5d1SDavid du Colombier */ 11003e12c5d1SDavid du Colombier q = prg(); 11013e12c5d1SDavid du Colombier q->line = p->line; 11023e12c5d1SDavid du Colombier q->pc = p->pc; 11033e12c5d1SDavid du Colombier q->link = p->link; 11043e12c5d1SDavid du Colombier p->link = q; 11053e12c5d1SDavid du Colombier p = q; 11063e12c5d1SDavid du Colombier p->as = AJMPL; 11073e12c5d1SDavid du Colombier p->to.type = D_BRANCH; 11083e12c5d1SDavid du Colombier p->cond = ps2; 11093e12c5d1SDavid du Colombier p->to.sym = s2; 11103e12c5d1SDavid du Colombier 11113e12c5d1SDavid du Colombier continue; 11123e12c5d1SDavid du Colombier } 11133e12c5d1SDavid du Colombier if(p->as == ARETURN) { 11143e12c5d1SDavid du Colombier 11153e12c5d1SDavid du Colombier /* 1116*219b2ee8SDavid du Colombier * RETURN 1117*219b2ee8SDavid du Colombier */ 1118*219b2ee8SDavid du Colombier q = prg(); 1119*219b2ee8SDavid du Colombier q->as = ARETURN; 1120*219b2ee8SDavid du Colombier q->from = p->from; 1121*219b2ee8SDavid du Colombier q->to = p->to; 1122*219b2ee8SDavid du Colombier q->link = p->link; 1123*219b2ee8SDavid du Colombier p->link = q; 1124*219b2ee8SDavid du Colombier 1125*219b2ee8SDavid du Colombier /* 11263e12c5d1SDavid du Colombier * JMPL profout 11273e12c5d1SDavid du Colombier */ 11283e12c5d1SDavid du Colombier p->as = AJMPL; 11293e12c5d1SDavid du Colombier p->from = zprg.from; 11303e12c5d1SDavid du Colombier p->to = zprg.to; 11313e12c5d1SDavid du Colombier p->to.type = D_BRANCH; 11323e12c5d1SDavid du Colombier p->cond = ps4; 11333e12c5d1SDavid du Colombier p->to.sym = s4; 11343e12c5d1SDavid du Colombier 11353e12c5d1SDavid du Colombier p = q; 11363e12c5d1SDavid du Colombier 11373e12c5d1SDavid du Colombier continue; 11383e12c5d1SDavid du Colombier } 11393e12c5d1SDavid du Colombier } 11403e12c5d1SDavid du Colombier } 11413e12c5d1SDavid du Colombier 11423e12c5d1SDavid du Colombier void 11433e12c5d1SDavid du Colombier nuxiinit(void) 11443e12c5d1SDavid du Colombier { 11453e12c5d1SDavid du Colombier int i, c; 11463e12c5d1SDavid du Colombier 11473e12c5d1SDavid du Colombier for(i=0; i<4; i++) { 11483e12c5d1SDavid du Colombier c = find1(0x01020304L, i+1); 11493e12c5d1SDavid du Colombier if(i >= 2) 11503e12c5d1SDavid du Colombier inuxi2[i-2] = c; 11513e12c5d1SDavid du Colombier if(i >= 3) 11523e12c5d1SDavid du Colombier inuxi1[i-3] = c; 11533e12c5d1SDavid du Colombier inuxi4[i] = c; 11543e12c5d1SDavid du Colombier 11553e12c5d1SDavid du Colombier fnuxi8[i] = c+4; 11563e12c5d1SDavid du Colombier fnuxi8[i+4] = c; 11573e12c5d1SDavid du Colombier } 11583e12c5d1SDavid du Colombier if(debug['v']) { 11593e12c5d1SDavid du Colombier Bprint(&bso, "inuxi = "); 11603e12c5d1SDavid du Colombier for(i=0; i<1; i++) 11613e12c5d1SDavid du Colombier Bprint(&bso, "%d", inuxi1[i]); 11623e12c5d1SDavid du Colombier Bprint(&bso, " "); 11633e12c5d1SDavid du Colombier for(i=0; i<2; i++) 11643e12c5d1SDavid du Colombier Bprint(&bso, "%d", inuxi2[i]); 11653e12c5d1SDavid du Colombier Bprint(&bso, " "); 11663e12c5d1SDavid du Colombier for(i=0; i<4; i++) 11673e12c5d1SDavid du Colombier Bprint(&bso, "%d", inuxi4[i]); 11683e12c5d1SDavid du Colombier Bprint(&bso, "\nfnuxi = "); 11693e12c5d1SDavid du Colombier for(i=0; i<8; i++) 11703e12c5d1SDavid du Colombier Bprint(&bso, "%d", fnuxi8[i]); 11713e12c5d1SDavid du Colombier Bprint(&bso, "\n"); 11723e12c5d1SDavid du Colombier } 11733e12c5d1SDavid du Colombier Bflush(&bso); 11743e12c5d1SDavid du Colombier } 11753e12c5d1SDavid du Colombier 11763e12c5d1SDavid du Colombier int 11773e12c5d1SDavid du Colombier find1(long l, int c) 11783e12c5d1SDavid du Colombier { 11793e12c5d1SDavid du Colombier char *p; 11803e12c5d1SDavid du Colombier int i; 11813e12c5d1SDavid du Colombier 11823e12c5d1SDavid du Colombier p = (char*)&l; 11833e12c5d1SDavid du Colombier for(i=0; i<4; i++) 11843e12c5d1SDavid du Colombier if(*p++ == c) 11853e12c5d1SDavid du Colombier return i; 11863e12c5d1SDavid du Colombier return 0; 11873e12c5d1SDavid du Colombier } 11883e12c5d1SDavid du Colombier 11893e12c5d1SDavid du Colombier long 11903e12c5d1SDavid du Colombier ieeedtof(Ieee *ieee) 11913e12c5d1SDavid du Colombier { 11923e12c5d1SDavid du Colombier int exp; 11933e12c5d1SDavid du Colombier long v; 11943e12c5d1SDavid du Colombier 11953e12c5d1SDavid du Colombier if(ieee->h == 0) 11963e12c5d1SDavid du Colombier return 0; 11973e12c5d1SDavid du Colombier exp = (ieee->h>>20) & ((1L<<11)-1L); 11983e12c5d1SDavid du Colombier exp -= (1L<<10) - 2L; 11993e12c5d1SDavid du Colombier v = (ieee->h & 0xfffffL) << 3; 12003e12c5d1SDavid du Colombier v |= (ieee->l >> 29) & 0x7L; 12013e12c5d1SDavid du Colombier if((ieee->l >> 28) & 1) { 12023e12c5d1SDavid du Colombier v++; 12033e12c5d1SDavid du Colombier if(v & 0x800000L) { 12043e12c5d1SDavid du Colombier v = (v & 0x7fffffL) >> 1; 12053e12c5d1SDavid du Colombier exp++; 12063e12c5d1SDavid du Colombier } 12073e12c5d1SDavid du Colombier } 12083e12c5d1SDavid du Colombier if(exp <= -126 || exp >= 130) 12093e12c5d1SDavid du Colombier diag("double fp to single fp overflow\n"); 12103e12c5d1SDavid du Colombier v |= ((exp + 126) & 0xffL) << 23; 12113e12c5d1SDavid du Colombier v |= ieee->h & 0x80000000L; 12123e12c5d1SDavid du Colombier return v; 12133e12c5d1SDavid du Colombier } 12143e12c5d1SDavid du Colombier 12153e12c5d1SDavid du Colombier double 12163e12c5d1SDavid du Colombier ieeedtod(Ieee *ieee) 12173e12c5d1SDavid du Colombier { 12183e12c5d1SDavid du Colombier Ieee e; 12193e12c5d1SDavid du Colombier double fr; 12203e12c5d1SDavid du Colombier int exp; 12213e12c5d1SDavid du Colombier 12223e12c5d1SDavid du Colombier if(ieee->h & (1L<<31)) { 12233e12c5d1SDavid du Colombier e.h = ieee->h & ~(1L<<31); 12243e12c5d1SDavid du Colombier e.l = ieee->l; 12253e12c5d1SDavid du Colombier return -ieeedtod(&e); 12263e12c5d1SDavid du Colombier } 12273e12c5d1SDavid du Colombier if(ieee->l == 0 && ieee->h == 0) 12283e12c5d1SDavid du Colombier return 0; 12293e12c5d1SDavid du Colombier fr = ieee->l & ((1L<<16)-1L); 12303e12c5d1SDavid du Colombier fr /= 1L<<16; 12313e12c5d1SDavid du Colombier fr += (ieee->l>>16) & ((1L<<16)-1L); 12323e12c5d1SDavid du Colombier fr /= 1L<<16; 12333e12c5d1SDavid du Colombier fr += (ieee->h & (1L<<20)-1L) | (1L<<20); 12343e12c5d1SDavid du Colombier fr /= 1L<<21; 12353e12c5d1SDavid du Colombier exp = (ieee->h>>20) & ((1L<<11)-1L); 12363e12c5d1SDavid du Colombier exp -= (1L<<10) - 2L; 12373e12c5d1SDavid du Colombier return ldexp(fr, exp); 12383e12c5d1SDavid du Colombier } 12393e12c5d1SDavid du Colombier 12403e12c5d1SDavid du Colombier /* 12413e12c5d1SDavid du Colombier * fake malloc 12423e12c5d1SDavid du Colombier */ 12433e12c5d1SDavid du Colombier void* 12443e12c5d1SDavid du Colombier malloc(long n) 12453e12c5d1SDavid du Colombier { 12463e12c5d1SDavid du Colombier void *v; 12473e12c5d1SDavid du Colombier 1248*219b2ee8SDavid du Colombier n = (n + 7) & ~7; 12493e12c5d1SDavid du Colombier while(nhunk < n) 12503e12c5d1SDavid du Colombier gethunk(); 12513e12c5d1SDavid du Colombier 12523e12c5d1SDavid du Colombier v = (void*)hunk; 12533e12c5d1SDavid du Colombier nhunk -= n; 12543e12c5d1SDavid du Colombier hunk += n; 12553e12c5d1SDavid du Colombier 12563e12c5d1SDavid du Colombier memset(v, 0, n); 12573e12c5d1SDavid du Colombier return v; 12583e12c5d1SDavid du Colombier } 12593e12c5d1SDavid du Colombier 12603e12c5d1SDavid du Colombier void 12613e12c5d1SDavid du Colombier free(void *p) 12623e12c5d1SDavid du Colombier { 12633e12c5d1SDavid du Colombier USED(p); 12643e12c5d1SDavid du Colombier } 12653e12c5d1SDavid du Colombier 12663e12c5d1SDavid du Colombier void* 12673e12c5d1SDavid du Colombier calloc(long m, long n) 12683e12c5d1SDavid du Colombier { 12693e12c5d1SDavid du Colombier void *p; 12703e12c5d1SDavid du Colombier 12713e12c5d1SDavid du Colombier n *= m; 12723e12c5d1SDavid du Colombier p = malloc(n); 12733e12c5d1SDavid du Colombier memset(p, 0, n); 12743e12c5d1SDavid du Colombier return p; 12753e12c5d1SDavid du Colombier } 12763e12c5d1SDavid du Colombier 12773e12c5d1SDavid du Colombier void* 12783e12c5d1SDavid du Colombier realloc(void *p, long n) 12793e12c5d1SDavid du Colombier { 12803e12c5d1SDavid du Colombier fprint(2, "realloc called\n", p, n); 12813e12c5d1SDavid du Colombier abort(); 12823e12c5d1SDavid du Colombier return 0; 12833e12c5d1SDavid du Colombier } 1284