From 610e1f8727903412a12d94014733b73b3f11f5a4 Mon Sep 17 00:00:00 2001 From: Charles Forsyth Date: Mon, 4 May 2015 13:28:16 +0100 Subject: remove Hp-s800 --- libinterp/comp-s800.c | 2024 ------------------------------------------------- 1 file changed, 2024 deletions(-) delete mode 100644 libinterp/comp-s800.c (limited to 'libinterp/comp-s800.c') diff --git a/libinterp/comp-s800.c b/libinterp/comp-s800.c deleted file mode 100644 index 90d8afc3..00000000 --- a/libinterp/comp-s800.c +++ /dev/null @@ -1,2024 +0,0 @@ -#include "lib9.h" -#include "isa.h" -#include "interp.h" -#include "raise.h" - -#define P4(o) ((o) < (1 << 4)) -#define N4(o) (~(o) < (1 << 4)) -#define P13(o) ((o) < (1 << 13)) -#define N13(o) (~(o) < (1 << 13)) -#define B4(o) ((o) & M4) -#define B11(o) ((o) & M11) -#define B13(o) ((o) & M13) -#define B21(o) ((o) & M21) - -#define DOT ((ulong)code) -#define RELPC(pc) ((ulong)(base+pc)) - -#define nop() arith(Aor, RZ, RZ, RZ) -#define bra(o) BL(RZ, (o)) -#define add(r, c) LDSTpos(Oldo, c, r, r) -#define displ(ix) ((ulong)(base+patch[ix]-code-2)) -#define mdispl(ix) ((ulong)(base+macro[ix]-code-2)) -#define mbra(ix) bra(mdispl(ix)) - -enum -{ - R0 = 0, - R1 = 1, - R2 = 2, - - R19 = 19, - R20 = 20, - R21 = 21, - R22 = 22, - R23 = 23, - R24 = 24, - R25 = 25, - R26 = 26, - R27 = 27, - R28 = 28, - R29 = 29, - R30 = 30, - R31 = 31, - - RLINK = R2, /* Function linkage */ - - RZ = R0, /* Always 0 */ - RFP = R26, /* Frame Pointer */ - RMP = R25, /* Module Pointer */ - RREG = R24, /* Pointer to REG */ - RTA = R29, /* Intermediate address for double indirect */ - RCON = R23, /* Constant builder */ - RCALL = R31, /* Call temp and link dest */ - - RA3 = R22, /* gpr 3 */ - RA2 = R21, /* gpr 2 2+3 = big */ - RA1 = R20, /* gpr 1 */ - RA0 = R19, /* gpr 0 0+1 = big */ - - RCSP = R30, /* C stack pointer */ - RARG0 = R26, /* C arg0 */ - RMILLI0 = R22, /* Millicode arg0 */ - - /* Floating */ - FRZ = 0, /* Zero */ - FR0 = 4, - FR1 = 5, - - /* opcodes */ - Osys = 0x00, - Oarith = 0x02, - Oldwx = 0x03, - Oldil = 0x08, - Oldo = 0x0D, - Oldb = 0x10, - Oldh = 0x11, - Oldw = 0x12, - Ostb = 0x18, - Osth = 0x19, - Ostw = 0x1A, - Ocombt = 0x20, - Ocomibt = 0x21, - Ocombf = 0x22, - Ocomibf = 0x23, - Oaddibt = 0x29, - Oaddibf = 0x2B, - Oextrs = 0x34, - Obe = 0x38, - Oble = 0x39, - Obr = 0x3A, - - Oflldst = 0x0B, - Ofltc = 0x0C, - - Ftst = 0x2420, - Fload = 0, - Fstore = 1, - - /* psuedo opcodes */ - Pld = 0x10, /* base of loads */ - Pst = 0x18, /* base of stores */ - - /* sub opcodes */ - Aand = 0x10, - Aor = 0x12, - Axor = 0x14, - Asub = 0x20, - Aadd = 0x30, - Ash1add = 0x32, - Ash2add = 0x34, - - /* FP sub codes */ - Fadd = 0, - Fsub = 1, - Fmul = 2, - Fdiv = 3, - - Sldsid = 0x85, - Smtsp = 0xC1, - - /* conditions */ - Cnever = 0, - Cequal = 1, - Cless = 2, - Cleq = 3, - Clessu = 4, - Clequ = 5, - Csv = 6, - Codd = 7, - - /* FP conditions */ - Fnever = 0, - Fequal = 1, - Fless = 2, - Fleq = 3, - Fgrt = 4, - Fgeq = 5, - Fneq = 6, - Falways = 7, - - /* masks */ - M4 = 0xF, - M5 = 0x1F, - M10 = 0x3FF, - M11 = 0x7FF, - M13 = 0x1FFF, - M21 = 0x1FFFFF, - - /* spaces */ - STemp = 0, - SCode = 4, - SData = 5, - - PRESZ = 20, - - /* punt ops */ - SRCOP = (1<<0), - DSTOP = (1<<1), - WRTPC = (1<<2), - TCHECK = (1<<3), - NEWPC = (1<<4), - DBRAN = (1<<5), - THREOP = (1<<6), - - ANDAND = 1, - OROR = 2, - EQAND = 3, - - MacFRP = 0, - MacRET = 1, - MacCASE = 2, - MacCOLR = 3, - MacMCAL = 4, - MacFRAM = 5, - MacMFRA = 6, - NMACRO -}; - -static ulong* code; -static ulong* base; -static ulong* patch; -static int pass; -static Module* mod; -static uchar* tinit; -static ulong* litpool; -static int nlit; -static void macfrp(void); -static void macret(void); -static void maccase(void); -static void maccolr(void); -static void macmcal(void); -static void macfram(void); -static void macmfra(void); -static ulong macro[NMACRO]; - void (*comvec)(void); -extern void das(uchar*, int); -extern ulong *dataptr; -extern void calldata(); -extern void calltext(); -extern long dyncall; - -#define T(r) *((void**)(R.r)) - -static void -prlast() -{ - print("%x\t%x\n", code - 1, code[-1]); -} - -struct -{ - int idx; - void (*gen)(void); - char* name; -} mactab[] = -{ - MacFRP, macfrp, "FRP", /* decrement and free pointer */ - MacRET, macret, "RET", /* return instruction */ - MacCASE, maccase, "CASE", /* case instruction */ - MacCOLR, maccolr, "COLR", /* increment and color pointer */ - MacMCAL, macmcal, "MCAL", /* mcall bottom half */ - MacFRAM, macfram, "FRAM", /* frame instruction */ - MacMFRA, macmfra, "MFRA", /* punt mframe because t->initialize==0 */ -}; - -static void -rdestroy(void) -{ - destroy(R.s); -} - -static void -rmcall(void) -{ - Prog *p; - Frame *f; - - f = (Frame*)R.FP; - if(f == H) - error(exModule); - - f->mr = nil; - ((void(*)(Frame*))R.dt)(f); - R.SP = (uchar*)f; - R.FP = f->fp; - if(f->t == nil) - unextend(f); - else - freeptrs(f, f->t); - p = currun(); - if(p->kill) - error(p->kill); -} - -static void -rmfram(void) -{ - Type *t; - Frame *f; - uchar *nsp; - - t = (Type*)R.s; - nsp = R.SP + t->size; - if(nsp >= R.TS) { - R.s = t; - extend(); - T(d) = R.s; - return; - } - f = (Frame*)R.SP; - R.SP = nsp; - f->t = t; - f->mr = nil; - initmem(t, f); - T(d) = f; -} - -static void -urk(void) -{ - error("compile failed"); -} - -static int -mkspace(int s) -{ - return ((s & 4) << 11) | ((s & 3) << 14); -} - -static ulong -posdisp(int disp) -{ - return (((disp & M10) << 1) | ((disp >> 10) & 1)) << 2; -} - -static ulong -disp11(int disp) -{ - return posdisp(disp) | (disp < 0 ? 1 : 0); -} - -static void -opatch(ulong *b) -{ - *b |= posdisp(code - b - 2); -} - -static ulong -frig17(ulong v) -{ - return ((v & M10) << 3) | - ((v & (1 << 10)) >> 8) | - ((v & (M5 << 11)) << 5) | - ((v >> 16) & 1); -} - -static ulong -frig21(ulong v) -{ - return ((v >> 20) & 1) | - ((v >> 8) & (M11 << 1)) | - ((v & 3) << 12) | - ((v & (3 << 7)) << 7) | - ((v & (M5 << 2)) << 14); -} - -static void -BLE(int r, int off, int s) -{ - *code++ = (Oble << 26) | (r << 21) | mkspace(s) | frig17(off >> 2); -} - -static void -BE(int r, int off, int s) -{ - *code++ = (Obe << 26) | (r << 21) | mkspace(s) | frig17(off); -} - -static void -BL(int r, int off) -{ - *code++ = (Obr << 26) | (r << 21) | frig17(off); -} - -static void -BV(int r) -{ - *code++ = (Obr << 26) | (r << 21) | (6 << 13); -} - -static void -LDIL(int r, ulong imm) -{ - *code++ = (Oldil << 26) | (r << 21) | frig21(imm); -} - -static void -LDWX(int i, int b, int r, int t) -{ - *code++ = (Oldwx << 26) | (b << 21) | (r << 16) | ((i - Pld) << 6) | t; -} - -static void -LDSTneg(int i, ulong off, int b, int r) -{ - *code++ = (i << 26) | (b << 21) | (r << 16) | (B13(off) << 1) | 1; -} - -static void -LDSTpos(int i, ulong off, int b, int r) -{ - *code++ = (i << 26) | (b << 21) | (r << 16) | (off << 1); -} - -static void -FLDSTneg(int inst, ulong disp, int rm, int r) -{ - *code++ = (Oflldst << 26) | (rm << 21) | (B4(disp) << 17) | (1 << 16) | (1 << 12) | (inst << 9) | r; -} - -static void -FLDSTpos(int inst, ulong disp, int rm, int r) -{ - *code++ = (Oflldst << 26) | (rm << 21) | (disp << 17) | (1 << 12) | (inst << 9) | r; -} - -static void -FLDSTX(int inst, int b, int x, int r) -{ - *code++ = (Oflldst << 26) | (b << 21) | (x << 17) | (inst << 9) | r; -} - -static void -FCMP(int r, int c, int b) -{ - *code++ = (Ofltc << 26) | (r << 21) | (b << 16) | (6 << 9) | (c << 2); -} - -static void -FTEST() -{ - *code++ = (Ofltc << 26) | Ftst; -} - -static void -farith(int o, int r1, int r2, int t) -{ - *code++ = (Ofltc << 26) | (r1 << 21) | (r2 << 16) | (o << 13) | (7 << 9) | t; -} - -static void -arith(int o, int s, int m, int d) -{ - *code++ = (Oarith << 26) | (m << 21) | (s << 16) | (o << 5) | d; -} - -static void -mov(int s, int d) -{ - LDSTpos(Oldo, 0, s, d); -} - -static void -shrs(int r, int s, int t) -{ - *code++ = (Oextrs << 26) | (r << 21) | (t << 16) | (7 << 10) | ((31 - s) << 5) | s; -} - -static void -comb(int op, int r1, int c, int r2, int off) -{ - *code++ = (op << 26) | (r2 << 21) | (r1 << 16) | (c << 13) | disp11(off); -} - -static int -es5(int v) -{ - return (B4(v) << 1) | (v < 0 ? 1 : 0); -} - -static void -combt(int r1, int c, int r2, int off) -{ - comb(Ocombt, r1, c, r2, off); -} - -static void -comibt(int r1, int c, int v, int off) -{ - comb(Ocomibt, es5(v), c, r1, off); -} - -static void -combf(int r1, int c, int r2, int off) -{ - comb(Ocombf, r1, c, r2, off); -} - -static void -comibf(int r1, int c, int v, int off) -{ - comb(Ocomibf, es5(v), c, r1, off); -} - -static void -combdis(int r1, int c, int r2, int f, int ix) -{ - comb(f ? Ocombf : Ocombt, r1, c, r2, displ(ix)); -} - -static void -addibt(int r1, int c, int v, int off) -{ - comb(Oaddibt, es5(v), c, r1, off); -} - -static void -addibf(int r1, int c, int v, int off) -{ - comb(Oaddibf, es5(v), c, r1, off); -} - -static void -con(ulong o, int r, int opt) -{ - if(opt) { - if(P13(o)) { - LDSTpos(Oldo, o, RZ, r); - return; - } - if(N13(o)) { - LDSTneg(Oldo, o, RZ, r); - return; - } - LDIL(r, B21(o >> 11)); - if(B11(o) != 0) - LDSTpos(Oldo, B11(o), r, r); - } - else { - LDIL(r, B21(o >> 11)); - LDSTpos(Oldo, B11(o), r, r); - } -} - -static void -call(ulong a, int s) -{ - if (s == SCode) { - con(a, RMILLI0, 1); - a = dyncall; - } - LDIL(RCALL, a >> 11); - BLE(RCALL, B11(a), s); - mov(RCALL, RLINK); -} - -static void -callindir(int r) -{ - BLE(r, 0, SData); - mov(RCALL, RLINK); -} - -static void -leafret() -{ - BV(RLINK); - nop(); -} - -static void -linkage() -{ - LDSTneg(Ostw, -20, RCSP, RLINK); - LDSTpos(Oldo, 64, RCSP, RCSP); -} - -static void -ret() -{ - LDSTneg(Oldw, -84, RCSP, RLINK); - BV(RLINK); - LDSTneg(Oldo, -64, RCSP, RCSP); -} - -static void -mem(int inst, ulong disp, int rm, int r) -{ - if(P13(disp)) { - LDSTpos(inst, disp, rm, r); - return; - } - if(N13(disp)) { - LDSTneg(inst, disp, rm, r); - return; - } - con(disp, RCON, 1); - if(inst >= Pst) { - arith(Aadd, rm, RCON, RCON); - LDSTpos(inst, 0, RCON, r); - } - else - LDWX(inst, RCON, rm, r); -} - -static void -fmem(int inst, ulong disp, int rm, int r) -{ - if(P4(disp)) { - FLDSTpos(inst, disp, rm, r); - return; - } - if(N4(disp)) { - FLDSTneg(inst, disp, rm, r); - return; - } - con(disp, RCON, 1); - FLDSTX(inst, RCON, rm, r); -} - -static void -opwld(Inst *i, int mi, int r) -{ - int ir, rta; - - switch(UXSRC(i->add)) { - default: - print("%D\n", i); - urk(); - case SRC(AFP): - mem(mi, i->s.ind, RFP, r); - return; - case SRC(AMP): - mem(mi, i->s.ind, RMP, r); - return; - case SRC(AIMM): - con(i->s.imm, r, 1); - return; - case SRC(AIND|AFP): - ir = RFP; - break; - case SRC(AIND|AMP): - ir = RMP; - break; - } - rta = RTA; - if(mi == Oldo) - rta = r; - mem(Oldw, i->s.i.f, ir, rta); - mem(mi, i->s.i.s, rta, r); -} - -static void -opwst(Inst *i, int mi, int r) -{ - int ir, rta; - - switch(UXDST(i->add)) { - default: - print("%D\n", i); - urk(); - case DST(AIMM): - con(i->d.imm, r, 1); - return; - case DST(AFP): - mem(mi, i->d.ind, RFP, r); - return; - case DST(AMP): - mem(mi, i->d.ind, RMP, r); - return; - case DST(AIND|AFP): - ir = RFP; - break; - case DST(AIND|AMP): - ir = RMP; - break; - } - rta = RTA; - if(mi == Oldo) - rta = r; - mem(Oldw, i->d.i.f, ir, rta); - mem(mi, i->d.i.s, rta, r); -} - -static void -opbig(Adr *a, int am, int mi, int r) -{ - int ir; - - switch(am) { - default: - urk(); - case AFP: - mem(mi, a->ind, RFP, r); - mem(mi, a->ind+4, RFP, r+1); - return; - case AMP: - mem(mi, a->ind, RMP, r); - mem(mi, a->ind+4, RMP, r+1); - return; - case AIND|AFP: - ir = RFP; - break; - case AIND|AMP: - ir = RMP; - break; - } - mem(Oldw, a->i.f, ir, RTA); - mem(mi, a->i.s, RTA, r); - mem(mi, a->i.s+4, RTA, r+1); -} - -static void -opbigld(Inst *i, int r) -{ - opbig(&i->s, USRC(i->add), Oldw, r); -} - -static void -opbigst(Inst *i, int r) -{ - opbig(&i->d, UDST(i->add), Ostw, r); -} - -static void -opfloat(Adr *a, int am, int mi, int r) -{ - int ir; - - switch(am) { - default: - urk(); - case AFP: - fmem(mi, a->ind, RFP, r); - return; - case AMP: - fmem(mi, a->ind, RMP, r); - return; - case AIND|AFP: - ir = RFP; - break; - case AIND|AMP: - ir = RMP; - break; - } - mem(Oldw, a->i.f, ir, RTA); - fmem(mi, a->i.s, RTA, r); -} - -static void -opflld(Inst *i, int r) -{ - opfloat(&i->s, USRC(i->add), Fload, r); -} - -static void -opflst(Inst *i, int r) -{ - opfloat(&i->d, UDST(i->add), Fstore, r); -} - -static void -midfl(Inst *i, int r) -{ - int ir; - - switch(i->add&ARM) { - default: - opfloat(&i->d, UDST(i->add), Fload, r); - return; - case AXINF: - ir = RFP; - break; - case AXINM: - ir = RMP; - break; - } - fmem(Fload, i->reg, ir, r); -} - -static void -literal(ulong imm, int roff) -{ - nlit++; - - con((ulong)litpool, RTA, 0); - LDSTpos(Ostw, roff, RREG, RTA); - - if(pass == 0) - return; - - *litpool = imm; - litpool++; -} - -static -void -compdbg(void) -{ - print("%s:%d@%.8lux\n", R.M->m->name, *(ulong *)R.m, *(ulong *)R.s); -} - -static void -punt(Inst *i, int m, void (*fn)(void)) -{ - ulong pc; - - if(m & SRCOP) { - if(UXSRC(i->add) == SRC(AIMM)) - literal(i->s.imm, O(REG, s)); - else { - opwld(i, Oldo, RA0); - mem(Ostw, O(REG, s), RREG, RA0); - } - } - - if(m & DSTOP) { - opwst(i, Oldo, RA0); - mem(Ostw, O(REG, d), RREG, RA0); - } - - if(m & WRTPC) { - con(RELPC(patch[i-mod->prog+1]), RA0, 0); - mem(Ostw, O(REG, PC), RREG, RA0); - } - - if(m & DBRAN) { - pc = patch[(Inst*)i->d.imm-mod->prog]; - literal(RELPC(pc), O(REG, d)); - } - - switch(i->add&ARM) { - case AXNON: - if(m & THREOP) { - mem(Oldw, O(REG, d), RREG, RA0); - mem(Ostw, O(REG, m), RREG, RA0); - } - break; - case AXIMM: - literal((short)i->reg, O(REG, m)); - break; - case AXINF: - mem(Oldo, i->reg, RFP, RA0); - mem(Ostw, O(REG, m), RREG, RA0); - break; - case AXINM: - mem(Oldo, i->reg, RMP, RA0); - mem(Ostw, O(REG, m), RREG, RA0); - break; - } - - mem(Ostw, O(REG, FP), RREG, RFP); - call((ulong)fn, SCode); - - con((ulong)&R, RREG, 1); - if(m & TCHECK) { - mem(Oldw, O(REG, t), RREG, RA0); - combt(RA0, Cequal, RZ, 3); - nop(); - mem(Oldw, O(REG, xpc), RREG, RLINK); - leafret(); - } - - mem(Oldw, O(REG, FP), RREG, RFP); - mem(Oldw, O(REG, MP), RREG, RMP); - - if(m & NEWPC) { - mem(Oldw, O(REG, PC), RREG, RA0); - BV(RA0); - nop(); - } -} - -static void -mid(Inst *i, int mi, int r) -{ - int ir; - - switch(i->add&ARM) { - default: - opwst(i, mi, r); - return; - case AXIMM: - con((short)i->reg, r, 1); - return; - case AXINF: - ir = RFP; - break; - case AXINM: - ir = RMP; - break; - } - mem(mi, i->reg, ir, r); -} - -static void -cbral(Inst *i, int jmsw, int fm, int jlsw, int fl, int mode) -{ - ulong dst, *label; - - opwld(i, Oldo, RA1); - mid(i, Oldo, RA3); - mem(Oldw, 0, RA1, RA2); - mem(Oldw, 0, RA3, RA0); - label = nil; - dst = i->d.ins-mod->prog; - switch(mode) { - case ANDAND: - label = code; - comb(RA0, jmsw, RA2, fm, 0); - break; - case OROR: - combdis(RA0, jmsw, RA2, fm, dst); - break; - case EQAND: - combdis(RA0, jmsw, RA2, fm, dst); - nop(); - label = code; - combf(RA0, Cequal, RA2, 0); - break; - } - nop(); - mem(Oldw, 4, RA3, RA0); - mem(Oldw, 4, RA1, RA2); - combdis(RA0, jlsw, RA2, fl, dst); - if(label != nil) - opatch(label); -} - -static void -commcall(Inst *i) -{ - int o; - - opwld(i, Oldw, RA2); - con(RELPC(patch[i-mod->prog+1]), RA0, 0); - mem(Ostw, O(Frame, lr), RA2, RA0); - mem(Ostw, O(Frame, fp), RA2, RFP); - mem(Oldw, O(REG, M), RREG, RA3); - mem(Ostw, O(Frame, mr), RA2, RA3); - opwst(i, Oldw, RA3); - o = OA(Modlink, links)+i->reg*sizeof(Modl)+O(Modl, u.pc); - mem(Oldw, o, RA3, RA0); - call(base+macro[MacMCAL], SData); -} - -static void -comcase(Inst *i, int w) -{ - int l; - WORD *t, *e; - - if(w != 0) { - opwld(i, Oldw, RA0); // v - opwst(i, Oldo, RCON); // table - mbra(MacCASE); - nop(); - } - - t = (WORD*)(mod->origmp+i->d.ind+4); - l = t[-1]; - - /* have to take care not to relocate the same table twice - - * the limbo compiler can duplicate a case instruction - * during its folding phase - */ - - if(pass == 0) { - if(l >= 0) - t[-1] = -l-1; /* Mark it not done */ - return; - } - if(l >= 0) /* Check pass 2 done */ - return; - t[-1] = -l-1; /* Set real count */ - e = t + t[-1]*3; - while(t < e) { - t[2] = RELPC(patch[t[2]]); - t += 3; - } - t[0] = RELPC(patch[t[0]]); -} - -static void -comcasel(Inst *i) -{ - int l; - WORD *t, *e; - - t = (WORD*)(mod->origmp+i->d.ind+8); - l = t[-2]; - if(pass == 0) { - if(l >= 0) - t[-2] = -l-1; /* Mark it not done */ - return; - } - if(l >= 0) /* Check pass 2 done */ - return; - t[-2] = -l-1; /* Set real count */ - e = t + t[-2]*6; - while(t < e) { - t[4] = RELPC(patch[t[4]]); - t += 6; - } - t[0] = RELPC(patch[t[0]]); -} - -static void -commframe(Inst *i) -{ - int o; - ulong *punt, *mlnil; - - opwld(i, Oldw, RA0); - mlnil = code; - comibt(RA0, Cequal, -1, 0); - nop(); - - o = OA(Modlink, links)+i->reg*sizeof(Modl)+O(Modl, frame); - mem(Oldw, o, RA0, RA3); - mem(Oldw, O(Type, initialize), RA3, RA1); - punt = code; - combf(RA1, Cequal, RZ, 0); - nop(); - - opwst(i, Oldo, RA0); - - /* Type in RA3, destination in RA0 */ - opatch(mlnil); - con(RELPC(patch[i-mod->prog+1]), RLINK, 0); - mbra(MacMFRA); - nop(); - - /* Type in RA3 */ - opatch(punt); - call(base+macro[MacFRAM], SData); - opwst(i, Ostw, RA2); -} - -static void -movloop(Inst *i, int ld, int st) -{ - int s; - - if(ld == Oldw) - s = 4; - else - s = 1; - opwld(i, Oldo, RA1); - opwst(i, Oldo, RA2); - mem(ld, 0, RA1, RA0); - mem(st, 0, RA2, RA0); - add(RA2, s); - addibf(RA3, Cequal, -1, -5); - add(RA1, s); -} - -static void -comp(Inst *i) -{ - int r, f; - WORD *t, *e; - char buf[64]; - - if(0) { - Inst xx; - xx.add = AXIMM|SRC(AIMM); - xx.s.imm = (ulong)code; - xx.reg = i-mod->prog; - punt(&xx, SRCOP, compdbg); - } - - switch(i->op) { - default: - snprint(buf, sizeof buf, "%s compile, no '%D'", mod->name, i); - error(buf); - break; - case IMCALL: - if((i->add&ARM) == AXIMM) - commcall(i); - else - punt(i, SRCOP|DSTOP|THREOP|WRTPC|NEWPC, optab[i->op]); - break; - case ISEND: - case IRECV: - case IALT: - punt(i, SRCOP|DSTOP|TCHECK|WRTPC, optab[i->op]); - break; - case ISPAWN: - punt(i, SRCOP|DBRAN, optab[i->op]); - break; - case IBNEC: - case IBEQC: - case IBLTC: - case IBLEC: - case IBGTC: - case IBGEC: - punt(i, SRCOP|DBRAN|NEWPC|WRTPC, optab[i->op]); - break; - case ICASEC: - comcase(i, 0); - punt(i, SRCOP|DSTOP|NEWPC, optab[i->op]); - break; - case ICASEL: - comcasel(i); - punt(i, SRCOP|DSTOP|NEWPC, optab[i->op]); - break; - case IADDC: - case IMULL: - case IDIVL: - case IMODL: - case IMULW: - case IDIVW: - case IMODW: - case IMULB: - case IDIVB: - case IMODB: - case ISHRW: - case ISHLW: - case ISHRB: - case ISHLB: - case IADDL: - case ISUBL: - case IORL: - case IANDL: - case IXORL: - case ICVTWL: - case ISHLL: - case ISHRL: - case IINDX: - punt(i, SRCOP|DSTOP|THREOP, optab[i->op]); - break; - case ILOAD: - case INEWA: - case INEW: - case ISLICEA: - case ISLICELA: - case ICONSB: - case ICONSW: - case ICONSL: - case ICONSF: - case ICONSM: - case ICONSMP: - case ICONSP: - case IMOVMP: - case IHEADMP: - case IHEADM: - case IHEADB: - case IHEADW: - case IHEADL: - case IHEADF: - case IINDC: - case ILENC: - case IINSC: - case ICVTAC: - case ICVTCW: - case ICVTWC: - case ICVTLC: - case ICVTCL: - case ICVTFC: - case ICVTCF: - case ICVTFL: - case ICVTLF: - case ICVTWF: - case ICVTFW: - case IMSPAWN: - case ICVTCA: - case ISLICEC: - case INBALT: - punt(i, SRCOP|DSTOP, optab[i->op]); - break; - case INEWCM: - case INEWCMP: - punt(i, SRCOP|DSTOP|THREOP, optab[i->op]); - break; - case IMFRAME: - if((i->add&ARM) == AXIMM) - commframe(i); - else - punt(i, SRCOP|DSTOP|THREOP, optab[i->op]); - break; - case ICASE: - comcase(i, 1); - // comcase(i, 0); - // punt(i, SRCOP|DSTOP|NEWPC, optab[i->op]); - break; - case IGOTO: - opwld(i, Oldw, RA1); - opwst(i, Oldo, RA0); - arith(Ash2add, RA1, RZ, RA1); - LDWX(Oldw, RA0, RA1, RA0); - BV(RA0); - nop(); - - if(pass == 0) - break; - - t = (WORD*)(mod->origmp+i->d.ind); - e = t + t[-1]; - t[-1] = 0; - while(t < e) { - t[0] = RELPC(patch[t[0]]); - t++; - } - break; - case IMOVL: - movl: - opbigld(i, RA0); - opbigst(i, RA0); - break; - case IMOVM: - if((i->add&ARM) == AXIMM) { - if(i->reg == 8) - goto movl; - if((i->reg&3) == 0) { - con(i->reg>>2, RA3, 1); - movloop(i, Oldw, Ostw); - break; - } - } - mid(i, Oldw, RA3); - movloop(i, Oldb, Ostb); - break; - case IFRAME: - if(UXSRC(i->add) != SRC(AIMM)) { - punt(i, SRCOP|DSTOP, optab[i->op]); - break; - } - tinit[i->s.imm] = 1; - con((ulong)mod->type[i->s.imm], RA3, 1); - call(base+macro[MacFRAM], SData); - opwst(i, Ostw, RA2); - break; - case INEWCB: - case INEWCW: - case INEWCF: - case INEWCP: - case INEWCL: - punt(i, DSTOP|THREOP, optab[i->op]); - break; - case IEXIT: - punt(i, 0, optab[i->op]); - break; - case ICVTBW: - opwld(i, Oldb, RA0); - opwst(i, Ostw, RA0); - break; - case ICVTWB: - opwld(i, Oldw, RA0); - opwst(i, Ostb, RA0); - break; - case ILEA: - opwld(i, Oldo, RA0); - opwst(i, Ostw, RA0); - break; - case IMOVW: - opwld(i, Oldw, RA0); - opwst(i, Ostw, RA0); - break; - case IMOVB: - opwld(i, Oldb, RA0); - opwst(i, Ostb, RA0); - break; - case ITAIL: - opwld(i, Oldw, RA0); - mem(Oldw, O(List, tail), RA0, RA1); - goto movp; - case IMOVP: - case IHEADP: - opwld(i, Oldw, RA1); - if(i->op == IHEADP) - mem(Oldw, OA(List, data), RA1, RA1); - movp: - comibt(RA1, Cequal, (ulong)H, 3); // H is small (-1) - nop(); - call(base+macro[MacCOLR], SData); // 3 instrs - opwst(i, Oldw, RA0); - opwst(i, Ostw, RA1); - call(base+macro[MacFRP], SData); - break; - case ILENA: - opwld(i, Oldw, RA1); - comibt(RA1, Cequal, (ulong)H, 0); - mov(RZ, RA0); - mem(Oldw, O(Array, len), RA1, RA0); - opwst(i, Ostw, RA0); - break; - case ILENL: - mov(RZ, RA0); - opwld(i, Oldw, RA1); - comibt(RA1, Cequal, (ulong)H, 3); - nop(); - mem(Oldw, O(List, tail), RA1, RA1); - bra(-5); - add(RA0, 1); - opwst(i, Ostw, RA0); - break; - case ICALL: - opwld(i, Oldw, RA0); - con(RELPC(patch[i-mod->prog+1]), RA1, 0); - mem(Ostw, O(Frame, lr), RA0, RA1); - mem(Ostw, O(Frame, fp), RA0, RFP); - bra(displ(i->d.ins-mod->prog)); - mov(RA0, RFP); - break; - case IJMP: - bra(displ(i->d.ins-mod->prog)); - nop(); - break; - case IBEQW: - r = Cequal; - f = 0; - braw: - opwld(i, Oldw, RA0); - mid(i, Oldw, RA1); - combdis(RA0, r, RA1, f, i->d.ins-mod->prog); - nop(); - break; - case IBNEW: - r = Cequal; - f = 1; - goto braw; - case IBLTW: - r = Cless; - f = 0; - goto braw; - case IBLEW: - r = Cleq; - f = 0; - goto braw; - case IBGTW: - r = Cleq; - f = 1; - goto braw; - case IBGEW: - r = Cless; - f = 1; - goto braw; - case IBEQB: - r = Cequal; - f = 0; - brab: - opwld(i, Oldb, RA0); - mid(i, Oldb, RA1); - combdis(RA0, r, RA1, f, i->d.ins-mod->prog); - nop(); - break; - case IBNEB: - r = Cequal; - f = 1; - goto brab; - case IBLTB: - r = Cless; - f = 0; - goto brab; - case IBLEB: - r = Cleq; - f = 0; - goto brab; - case IBGTB: - r = Cleq; - f = 1; - goto brab; - case IBGEB: - r = Cless; - f = 1; - goto brab; - case IBEQF: - r = Fneq; - braf: - opflld(i, FR1); - midfl(i, FR0); - FCMP(FR1, r, FR0); - bra(displ(i->d.ins-mod->prog)); - nop(); - break; - case IBNEF: - r = Fequal; - goto braf; - case IBLTF: - r = Fgeq; - goto braf; - case IBLEF: - r = Fgrt; - goto braf; - case IBGTF: - r = Fleq; - goto braf; - case IBGEF: - r = Fless; - goto braf; - case IRET: - // punt(i, NEWPC, optab[i->op]); - mbra(MacRET); - mem(Oldw, O(Frame, t), RFP, RA1); - break; - case IORW: - r = Aor; - goto arithw; - case IANDW: - r = Aand; - goto arithw; - case IXORW: - r = Axor; - goto arithw; - case ISUBW: - r = Asub; - goto arithw; - case IADDW: - r = Aadd; - arithw: - mid(i, Oldw, RA1); - opwld(i, Oldw, RA0); - arith(r, RA1, RA0, RA1); - opwst(i, Ostw, RA1); - break; - case IORB: - r = Aor; - goto arithb; - case IANDB: - r = Aand; - goto arithb; - case IXORB: - r = Axor; - goto arithb; - case ISUBB: - r = Asub; - goto arithb; - case IADDB: - r = Aadd; - arithb: - mid(i, Oldb, RA1); - opwld(i, Oldb, RA0); - arith(r, RA1, RA0, RA1); - opwst(i, Ostb, RA1); - break; - case IINDL: - case IINDF: - case IINDW: - case IINDB: - opwld(i, Oldw, RA0); /* a */ - r = 0; - switch(i->op) { - case IINDL: - case IINDF: - r = 3; - break; - case IINDW: - r = 2; - break; - } - opwst(i, Oldw, RA1); - mem(Oldw, O(Array, data), RA0, RA0); - switch(r) { - default: - urk(); - case 0: - arith(Aadd, RA0, RA1, RA0); - break; - case 2: - arith(Ash2add, RA1, RA0, RA0); - break; - case 3: - arith(Ash2add, RA1, RZ, RA1); - arith(Ash1add, RA1, RA0, RA0); - break; - } - r = RMP; - if((i->add&ARM) == AXINF) - r = RFP; - mem(Ostw, i->reg, r, RA0); - break; - case ICVTLW: - opwld(i, Oldo, RA0); - mem(Oldw, 4, RA0, RA0); - opwst(i, Ostw, RA0); - break; - case IBEQL: - cbral(i, Cequal, 1, Cequal, 0, ANDAND); - break; - case IBNEL: - cbral(i, Cequal, 1, Cequal, 1, OROR); - break; - case IBLEL: - cbral(i, Cless, 0, Clequ, 0, EQAND); - break; - case IBGTL: - cbral(i, Cleq, 1, Clequ, 1, EQAND); - break; - case IBLTL: - cbral(i, Cless, 0, Clessu, 0, EQAND); - break; - case IBGEL: - cbral(i, Cleq, 1, Clessu, 1, EQAND); - break; - case IMOVF: - opflld(i, FR0); - opflst(i, FR0); - break; - case IDIVF: - r = Fdiv; - goto arithf; - case IMULF: - r = Fmul; - goto arithf; - case ISUBF: - r = Fsub; - goto arithf; - case IADDF: - r = Fadd; - arithf: - midfl(i, FR1); - opflld(i, FR0); - farith(r, FR1, FR0, FR1); - opflst(i, FR1); - break; - case INEGF: - opflld(i, FR0); - farith(Fsub, FRZ, FR0, FR0); - opflst(i, FR0); - break; - case IRAISE: - punt(i, SRCOP|WRTPC|NEWPC, optab[i->op]); - break; - case IMULX: - case IDIVX: - case ICVTXX: - case IMULX0: - case IDIVX0: - case ICVTXX0: - case IMULX1: - case IDIVX1: - case ICVTXX1: - case ICVTFX: - case ICVTXF: - case IEXPW: - case IEXPL: - case IEXPF: - punt(i, SRCOP|DSTOP|THREOP, optab[i->op]); - break; - case ISELF: - punt(i, DSTOP, optab[i->op]); - break; - } -} - -/* - * Preamble. This is complicated by the space registers. - * We point comvec at calldata which does a dataspace call - * to dataptr. The code at dataptr calls the real preamble - * code at start which saves the link register and branches - * to the new pc. When the compiled code finally returns - * by branching indirect through the saved link it will - * return into the dataptr code which will return to text - * space (calldata) which will return to the outside. - */ -static void -preamble(void) -{ - ulong *start; - - if (comvec) - return; - - code = (ulong*)malloc(PRESZ * sizeof(*code)); - - if (code == nil) - urk(); - - start = code; - con((ulong)&R, RREG, 1); // load R - mem(Ostw, O(REG, xpc), RREG, RLINK); // save link - mem(Oldw, O(REG, PC), RREG, RA0); // load new PC - mem(Oldw, O(REG, FP), RREG, RFP); // load FP - BV(RA0); // jump to new PC - mem(Oldw, O(REG, MP), RREG, RMP); // load MP (delay) - - dataptr = code; - LDSTneg(Ostw, -20, RCSP, RLINK); // save return link - LDSTpos(Oldo, 64, RCSP, RCSP); // stack frame - con((ulong)start, RA0, 1); // load start - BLE(RA0, 0, SData); // call real preamble - mov(RCALL, RLINK); // linkage (delay) - LDSTneg(Oldw, -84, RCSP, RLINK); // fetch return link - BE(RLINK, 0, SCode); // return to text space - LDSTneg(Oldo, -64, RCSP, RCSP); // stack frame (delay) - - if (code > start + PRESZ) - error("preamble overrun"); - - segflush(start, PRESZ * sizeof(*code)); - - if(cflag > 4) { - print("preamble:\n"); - das(start, code-start); - } - - comvec = calldata; -} - -static void -maccase(void) -{ - ulong *loop, *def, *lab1; - - mem(Oldw, 0, RCON, RA3); // n = t[0] - mem(Oldo, 4, RCON, RCON); // t = &t[1] - arith(Ash1add, RA3, RA3, RA1); // n1 = 3*n - arith(Ash2add, RA1, RZ, RA1); // n1 = 12*n - LDWX(Oldw, RCON, RA1, RLINK); // rlink = default - - loop = code; // loop: - def = code; - combt(RA3, Cleq, RZ, 0); // if (n <= 0) goto out - // nop(); - - shrs(RA3, 1, RA2); // n' = n>>1 - arith(Ash1add, RA2, RA2, RTA); // n2 = 3*n' - arith(Ash2add, RTA, RCON, RA1); // l = &t[n2] - - mem(Oldw, 0, RA1, RTA); // l[0] - lab1 = code; - combt(RTA, Cleq, RA0, 0); // if (l[0] <= v) goto 1f - nop(); - bra(loop-code-2); // goto loop - mov(RA2, RA3); // n = n2 (delay) - - opatch(lab1); // 1f: - mem(Oldw, 4, RA1, RTA); // l[1] - lab1 = code; - combt(RA0, Cless, RTA, 0); // if (v < l[1]) goto 1f - nop(); - - mem(Oldo, 12, RA1, RCON); // t = &l[3] - arith(Asub, RA3, RA2, RA3); // n -= n' - bra(loop-code-2); // goto loop - mem(Oldo, -1, RA3, RA3); // n -= 1 (delay) - - opatch(lab1); // 1f: - mem(Oldw, 8, RA1, RLINK); // rlink = l[2] - - opatch(def); // out: - BV(RLINK); // jmp rlink - nop(); -} - -static void -macfrp(void) -{ - ulong *lab1, *lab2; - - /* destroy the pointer in RA0 */ - lab1 = code; - comibt(RA0, Cequal, -1, 0); // if (p == h) goto out - nop(); - - mem(Oldw, O(Heap, ref)-sizeof(Heap), RA0, RA2); // r = D2H(v)->ref - lab2 = code; - addibf(RA2, Cequal, -1, 0); // if (--r != 0) goto store - nop(); - - mem(Ostw, O(REG, FP), RREG, RFP); // call destroy - mem(Ostw, O(REG, st), RREG, RLINK); - mem(Ostw, O(REG, s), RREG, RA0); - call((ulong)rdestroy, SCode); - - con((ulong)&R, RREG, 1); - mem(Oldw, O(REG, st), RREG, RLINK); - mem(Oldw, O(REG, FP), RREG, RFP); - mem(Oldw, O(REG, MP), RREG, RMP); - leafret(); - - opatch(lab2); // store - mem(Ostw, O(Heap, ref)-sizeof(Heap), RA0, RA2); - opatch(lab1); // out - leafret(); -} - -static void -macret(void) -{ - Inst i; - ulong *cp1, *cp2, *cp3, *cp4, *cp5, *cp6; - - cp1 = code; - combt(RA1, Cequal, RZ, 0); // if (t(Rfp) == 0) goto punt - nop(); - - mem(Oldw, O(Type, destroy), RA1, RA0); - cp2 = code; - combt(RA0, Cequal, RZ, 0); // if (destroy(t(fp)) == 0) goto punt - nop(); - - mem(Oldw, O(Frame, fp), RFP, RA2); - cp3 = code; - combt(RA2, Cequal, RZ, 0); // if (fp(Rfp) == 0) goto punt - nop(); - - mem(Oldw, O(Frame, mr), RFP, RA3); - cp4 = code; - combt(RA3, Cequal, RZ, 0); // if (mr(Rfp) == 0) goto call - nop(); - - mem(Oldw, O(REG, M), RREG, RA2); - mem(Oldw, O(Heap, ref)-sizeof(Heap), RA2, RA3); - cp5 = code; - addibt(RA3, Cequal, -1, 0); // if (--ref(arg) == 0) goto punt - nop(); - mem(Ostw, O(Heap, ref)-sizeof(Heap), RA2, RA3); - - mem(Oldw, O(Frame, mr), RFP, RA1); - mem(Ostw, O(REG, M), RREG, RA1); - mem(Oldw, O(Modlink, compiled), RA1, RA2); // check for uncompiled code - mem(Oldw, O(Modlink, MP), RA1, RMP); - cp6 = code; - combt(RA2, Cequal, RZ, 0); - nop(); - mem(Ostw, O(REG, MP), RREG, RMP); - - opatch(cp4); - callindir(RA0); // call destroy(t(fp)) - - mem(Ostw, O(REG, SP), RREG, RFP); - mem(Oldw, O(Frame, lr), RFP, RA1); - mem(Oldw, O(Frame, fp), RFP, RFP); - mem(Ostw, O(REG, FP), RREG, RFP); - BV(RA1); // goto lr(Rfp) - mem(Oldw, O(Frame, fp), RFP, RFP); // (delay) - - opatch(cp6); - callindir(RA0); // call destroy(t(fp)) - - mem(Ostw, O(REG, SP), RREG, RFP); - mem(Oldw, O(Frame, lr), RFP, RA1); - mem(Oldw, O(Frame, fp), RFP, RFP); - mem(Ostw, O(REG, FP), RREG, RFP); - mem(Oldw, O(REG, xpc), RREG, RA2); - BV(RA2); // return to uncompiled code - mem(Oldw, O(REG, PC), RREG, RA1); - - opatch(cp1); - opatch(cp2); - opatch(cp3); - opatch(cp5); - i.add = AXNON; - punt(&i, TCHECK|NEWPC, optab[IRET]); -} - -static void -maccolr(void) -{ - ulong *br; - - /* color the pointer in RA1 */ - mem(Oldw, O(Heap, ref)-sizeof(Heap), RA1, RA0); // inc ref - add(RA0, 1); - mem(Ostw, O(Heap, ref)-sizeof(Heap), RA1, RA0); - con((ulong)&mutator, RA2, 1); - mem(Oldw, O(Heap, color)-sizeof(Heap), RA1, RA0); - mem(Oldw, 0, RA2, RA2); - br = code; - combt(RA0, Cequal, RA2, 0); // if (color == mutator) goto out - con(propagator, RA2, 1); - mem(Ostw, O(Heap, color)-sizeof(Heap), RA1, RA2); // color = propagator - con((ulong)&nprop, RA2, 1); - mem(Ostw, 0, RA2, RA1); // nprop = !0 - opatch(br); - leafret(); -} - -static void -macmcal(void) -{ - ulong *lab1, *lab2; - - mem(Oldw, O(Modlink, prog), RA3, RA1); - lab1 = code; - combf(RA1, Cequal, RZ, 0); // if (m->prog != nil) goto 1f - nop(); - - mem(Ostw, O(REG, st), RREG, RLINK); - mem(Ostw, O(REG, FP), RREG, RA2); - mem(Ostw, O(REG, dt), RREG, RA0); - call((ulong)rmcall, SCode); // CALL rmcall - - con((ulong)&R, RREG, 1); - mem(Oldw, O(REG, st), RREG, RLINK); - mem(Oldw, O(REG, FP), RREG, RFP); - mem(Oldw, O(REG, MP), RREG, RMP); - leafret(); - - opatch(lab1); // 1f - mov(RA2, RFP); - mem(Ostw, O(REG, M), RREG, RA3); - mem(Oldw, O(Heap, ref)-sizeof(Heap), RA3, RA1); - add(RA1, 1); - mem(Ostw, O(Heap, ref)-sizeof(Heap), RA3, RA1); - mem(Oldw, O(Modlink, compiled), RA3, RA1); - mem(Oldw, O(Modlink, MP), RA3, RMP); - lab2 = code; - combt(RA1, Cequal, RZ, 0); - mem(Ostw, O(REG, MP), RREG, RMP); - - BV(RA0); - nop(); - - opatch(lab2); - mem(Ostw, O(REG, FP), RREG, RFP); - mem(Oldw, O(REG, xpc), RREG, RA1); - BV(RA1); // call to uncompiled code - mem(Ostw, O(REG, PC), RREG, RA0); -} - -static void -macfram(void) -{ - ulong *lab1; - - mem(Oldw, O(REG, SP), RREG, RA0); - mem(Oldw, O(Type, size), RA3, RA1); - arith(Aadd, RA0, RA1, RA0); // new frame - mem(Oldw, O(REG, TS), RREG, RA1); // top of stack - lab1 = code; - combt(RA0, Cless, RA1, 0); - nop(); - - mem(Ostw, O(REG, s), RREG, RA3); - mem(Ostw, O(REG, st), RREG, RLINK); - mem(Ostw, O(REG, FP), RREG, RFP); - call((ulong)extend, SCode); // CALL extend - - con((ulong)&R, RREG, 1); - mem(Oldw, O(REG, st), RREG, RLINK); - mem(Oldw, O(REG, FP), RREG, RFP); - mem(Oldw, O(REG, s), RREG, RA2); - mem(Oldw, O(REG, MP), RREG, RMP); - leafret(); - - opatch(lab1); - mem(Oldw, O(REG, SP), RREG, RA2); // old frame - mem(Ostw, O(REG, SP), RREG, RA0); // new frame - - mem(Ostw, O(Frame, t), RA2, RA3); // f->t = t - mem(Oldw, O(Type, initialize), RA3, RA3); - BV(RA3); // initialize - mem(Ostw, O(Frame, mr), RA2, RZ); // f->mr = nil -} - -static void -macmfra(void) -{ - mem(Ostw, O(REG, st), RREG, RLINK); - mem(Ostw, O(REG, s), RREG, RA3); // save type - mem(Ostw, O(REG, d), RREG, RA0); // save destination - mem(Ostw, O(REG, FP), RREG, RFP); - call((ulong)rmfram, SCode); // call rmfram - - con((ulong)&R, RREG, 1); // reload - mem(Oldw, O(REG, st), RREG, RLINK); - mem(Oldw, O(REG, FP), RREG, RFP); - BV(RLINK); - mem(Oldw, O(REG, MP), RREG, RMP); -} - -void -comd(Type *t) -{ - int i, j, m, c; - ulong frp; - - frp = (ulong)(base+macro[MacFRP]); - mem(Ostw, O(REG, dt), RREG, RLINK); - for(i = 0; i < t->np; i++) { - c = t->map[i]; - j = i<<5; - for(m = 0x80; m != 0; m >>= 1) { - if(c & m) { - mem(Oldw, j, RFP, RA0); - call(frp, SData); - } - j += sizeof(WORD*); - } - } - mem(Oldw, O(REG, dt), RREG, RLINK); - leafret(); -} - -void -comi(Type *t) -{ - int i, j, m, c; - - con((ulong)H, RA0, 1); - for(i = 0; i < t->np; i++) { - c = t->map[i]; - j = i<<5; - for(m = 0x80; m != 0; m >>= 1) { - if(c & m) - mem(Ostw, j, RA2, RA0); - j += sizeof(WORD*); - } - } - leafret(); -} - -void -typecom(Type *t) -{ - int n; - ulong tmp[4096], *start; - - if(t == nil || t->initialize != 0) - return; - - code = tmp; - comi(t); - n = code - tmp; - code = tmp; - comd(t); - n += code - tmp; - - n *= sizeof(*code); - code = mallocz(n, 0); - if(code == nil) - return; - - start = code; - t->initialize = code; - comi(t); - t->destroy = code; - comd(t); - - if (code - start != n / sizeof(*code)) - error("typecom mismatch"); - - segflush(start, n); - - if(cflag > 1) - print("typ= %.8lux %4d i %.8lux d %.8lux asm=%d\n", - t, t->size, t->initialize, t->destroy, n); -} - -static void -patchex(Module *m, ulong *p) -{ - Handler *h; - Except *e; - - if((h = m->htab) == nil) - return; - for( ; h->etab != nil; h++){ - h->pc1 = p[h->pc1]; - h->pc2 = p[h->pc2]; - for(e = h->etab; e->s != nil; e++) - e->pc = p[e->pc]; - if(e->pc != -1) - e->pc = p[e->pc]; - } -} - -int -compile(Module *m, int size, Modlink *ml) -{ - ulong v; - Link *l; - Modl *e; - int i, n; - ulong *s, tmp[4096]; - - base = nil; - patch = mallocz(size*sizeof(*patch), 0); - tinit = malloc(m->ntype*sizeof(*tinit)); - if(tinit == nil || patch == nil) - goto bad; - - preamble(); - - mod = m; - n = 0; - pass = 0; - nlit = 0; - - for(i = 0; i < size; i++) { - code = tmp; - comp(&m->prog[i]); - patch[i] = n; - n += code - tmp; - } - - for(i = 0; i < nelem(mactab); i++) { - code = tmp; - mactab[i].gen(); - macro[mactab[i].idx] = n; - n += code - tmp; - } - - base = mallocz((n + nlit) * sizeof(ulong), 0); - if(base == nil) - goto bad; - - if(cflag > 1) - print("dis=%5d %5d s800=%5d asm=%.8lux lit=%d: %s\n", - size, size*sizeof(Inst), n, base, nlit, m->name); - - pass++; - nlit = 0; - litpool = (ulong*)base + n; - code = base; - - for(i = 0; i < size; i++) { - s = code; - comp(&m->prog[i]); - if(cflag > 2) { - print("%D\n", &m->prog[i]); - das(s, code-s); - } - } - - for(i = 0; i < nelem(mactab); i++) { - s = code; - mactab[i].gen(); - if(cflag > 2) { - print("%s:\n", mactab[i].name); - das(s, code-s); - } - } - - if (code - base != n) - error("typecom mismatch"); - - segflush(base, n * sizeof(*base)); - - for(l = m->ext; l->name; l++) { - l->u.pc = (Inst*)RELPC(patch[l->u.pc-m->prog]); - typecom(l->frame); - } - if(ml != nil) { - e = &ml->links[0]; - for(i = 0; i < ml->nlinks; i++) { - e->u.pc = (Inst*)RELPC(patch[e->u.pc-m->prog]); - typecom(e->frame); - e++; - } - } - for(i = 0; i < m->ntype; i++) { - if(tinit[i] != 0) - typecom(m->type[i]); - } - patchex(m, patch); - m->entry = (Inst*)RELPC(patch[mod->entry-mod->prog]); - if(cflag > 2) - print("entry %lx\n", m->entry); - free(patch); - free(tinit); - free(m->prog); - m->prog = (Inst*)base; - m->compiled = 1; - return 1; -bad: - free(patch); - free(tinit); - free(base); - return 0; -} -- cgit v1.2.3