#include "lib9.h"#include "isa.h"#include "interp.h"#include "raise.h" /* * Copyright © 1997 C H Forsyth (forsyth@terzarima.net) */ #define ROMABLE 0 /* costs something to zero patch vectors */#define RESCHED 1 /* check for interpreter reschedule */ #define PATCH(ptr) *ptr |= ((ulong)code-(ulong)ptr) & 0xfffc #define T(r) *((void**)(R.r)) #define XO(o,xo) (((o)<<26)|((xo)<<1)) /* botch: ARRR, AIRR, LRRR, etc have dest first (will fix soon) */ #define OPARRR(o,d,a,b) ((o)|((d)<<21)|((a)<<16)|((b)<<11))#define ARRR(o,d,a,b) gen((o)|((d)<<21)|((a)<<16)|((b)<<11))#define AIRR(o,d,a,v) gen((o)|((d)<<21)|((a)<<16)|((v)&0xFFFF))#define IRR(o,v,a,d) AIRR((o),(d),(a),(v))#define RRR(o,b,a,d) ARRR((o),(d),(a),(b))#define LRRR(o,a,s,b) ARRR((o),(s),(a),(b))#define LIRR(o,a,s,v) AIRR((o),(s),(a),(v))#define Bx(li,aa) gen((18<<26)|((li)&0x3FFFFFC)|((aa)<<1))#define RLW(op,a,s,sh,mb,me) ((op)|(((s)&31L)<<21)|(((a)&31L)<<16)|(((sh)&31L)<<11)|\ (((mb)&31L)<<6)|(((me)&31L)<<1))#define MFSPR(s, d) gen(XO(31,339) | ((d)<<21) | ((s)<<11))#define MTSPR(s, d) gen(XO(31,467) | ((s)<<21) | ((d)<<11)); #define SLWI(d,a,n) gen(slw((d),(a),(n),0))#define LRET() gen(Oblr) #define SETR0() if(macjit){ AIRR(Oaddi, Rzero, 0, 0); } /* set R0 to 0 */ /* assumes H can be formed from signed halfword */#define CMPH(r) AIRR(Ocmpi, Rcrf0, (r), (ulong)H);#define NOTNIL(r) (CMPH((r)), CCALL(EQ, bounds)) enum{ Rzero = 0, /* zero by design, not definition (P9/Inferno) */ Rsp = 1, Rsb = 2, Rarg = 3, Ro1 = 8, Ro2 = 9, Ro3 = 10, Ri = 11, Rj = 12, Rmp = 13, Rfp = 14, Rreg = 15, Rta = 16, /* unused */ Rpic = 17, /* address for computed goto, for move to CTR or LR */ Rcon = 26, /* constant builder; temporary */ /* 27, 28, 29, 30 are potentially external registers (P9/Inferno) */ Rlink = 31, /* holds copies of LR; linker temp */ Rfret = 0, Rf1 = 4, Rf2 = 6, Rfcvi = 27, /* floating conversion constant (P9/Inferno) */ Rfzero = 28, /* 0.0 (P9/Inferno) */ Rfhalf = 29, /* 0.5 (P9/Inferno) */ Rlr = 8<<5, /* SPR(LR) */ Rctr = 9<<5, /* SPR(CTR) */ Rcrf0 = 0, /* condition code field 0 */ Rcrf1 = 1<<2, /* condition code field 1 */ Rcrbrel = 31, /* condition code bit set to force relinquish */ Olwz = XO(32, 0), Olwzu = XO(33, 0), Olwzx = XO(31, 23), Olbz = XO(34, 0), Olbzu = XO(35, 0), Olbzx = XO(31, 87), Olfd = XO(50, 0), Olhz = XO(40, 0), Olhzx = XO(31, 279), Ostw = XO(36, 0), Ostwu = XO(37, 0), Ostwx = XO(31, 151), Ostb = XO(38, 0), Ostbu = XO(39, 0), Ostbx = XO(31, 215), Osth = XO(44,0), Osthx = XO(31, 407), Ostfd = XO(54, 0), Ostfdu = XO(55, 0), Oaddc = XO(31,10), Oadde = XO(31, 138), Oaddi = XO(14, 0), /* simm */ Oaddic_ = XO(13, 0), Oaddis = XO(15, 0), Ocrxor = XO(19, 193), Ofadd = XO(63, 21), Ofcmpo = XO(63, 32), Ofctiwz = XO(63, 15), Ofsub = XO(63, 20), Ofmr = XO(63, 72), Ofmul = XO(63, 25), Ofdiv = XO(63, 18), Ofneg = XO(63, 40), Oori = XO(24,0), /* uimm */ Ooris = XO(25,0), /* uimm */ Odivw = XO(31, 491), Odivwu = XO(31, 459), Omulhw = XO(31, 75), Omulhwu = XO(31, 11), Omulli = XO(7, 0), Omullw = XO(31, 235), Osubf = XO(31, 40), Osubfc = XO(31,8), Osubfe = XO(31,136), Osubfic = XO(8, 0), Oadd = XO(31, 266), Oand = XO(31, 28), Oneg = XO(31, 104), Oor = XO(31, 444), Oxor = XO(31, 316), Ocmpi = XO(11, 0), Ocmp = XO(31, 0), Ocmpl = XO(31, 32), Ocmpli = XO(10,0), Orlwinm = XO(21, 0), Oslw = XO(31, 24), Osraw = XO(31,792), Osrawi = XO(31,824), Osrw = XO(31,536), Cnone = OPARRR(0,20,0,0), /* unconditional */ Ceq = OPARRR(0,12,2,0), Cle = OPARRR(0,4,1,0), Clt = OPARRR(0,12,0,0), Cdnz = OPARRR(0,16,0,0), Cgt = OPARRR(0,12,1,0), Cne = OPARRR(0,4,2,0), Cge = OPARRR(0,4,0,0), Cle1 = OPARRR(0,4,5,0), /* Cle on CR1 */ Crelq = OPARRR(0,12,Rcrbrel,0), /* relinquish */ Cnrelq = OPARRR(0,4,Rcrbrel,0), /* not relinquish */ Cpredict = OPARRR(0,1,0,0), /* reverse prediction */ Lk = 1, Aa = 2, Obeq = OPARRR(16<<26,12,2,0), Obge = OPARRR(16<<26,4,0,0), Obgt = OPARRR(16<<26,12,1,0), Oble = OPARRR(16<<26,4,1,0), Oblt = OPARRR(16<<26,12,0,0), Obne = OPARRR(16<<26,4,2,0), Ob = XO(18, 0), Obc = XO(16, 0), Obcctr = XO(19,528), Obcctrl = Obcctr | Lk, Obctr = Obcctr | Cnone, Obctrl = Obctr | Lk, Obclr = XO(19, 16), Oblr = Obclr | Cnone, Oblrl = Oblr | Lk, Olea = 100, // pseudo op SRCOP = (1<<0), DSTOP = (1<<1), WRTPC = (1<<2), /* update R.PC */ TCHECK = (1<<3), /* check R.t for continue/ret */ NEWPC = (1<<4), /* goto R.PC */ DBRAN = (1<<5), /* dest is branch */ THREOP = (1<<6), ANDAND = 1, OROR, EQAND, MacRET = 0, MacFRP, MacCASE, MacFRAM, MacCOLR, MacMCAL, MacMFRA, MacCVTFW, MacRELQ, MacEND, NMACRO}; void (*comvec)(void); int macjit;extern long das(ulong*);static ulong* code;static ulong* base;static ulong* patch;static int pass;static Module* mod;static ulong* tinit;static ulong* litpool;static int nlit;static ulong macro[NMACRO];static void ldbigc(long, int);static void rdestroy(void);static void macret(void);static void macfrp(void);static void maccase(void);static void maccvtfw(void);static void macfram(void);static void maccolr(void);static void macend(void);static void macmcal(void);static void macmfra(void);static void macrelq(void);static void movmem(Inst*); struct{ int o; void (*f)(void);} macinit[] ={ MacFRP, macfrp, /* decrement and free pointer */ MacRET, macret, /* return instruction */ MacCASE, maccase, /* case instruction */ MacCOLR, maccolr, /* increment and color pointer */ MacFRAM, macfram, /* frame instruction */ MacMCAL, macmcal, /* mcall bottom half */ MacMFRA, macmfra, /* punt mframe because t->initialize==0 */ MacCVTFW, maccvtfw, MacRELQ, macrelq, /* reschedule */ MacEND, macend, 0}; static voidrdestroy(void){ destroy(R.s);} static voidrmcall(void){ Frame *f; Prog *p; if((void*)R.dt == H) error(exModule); 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 != nil) error(p->kill);} static voidrmfram(void){ Type *t; Frame *f; uchar *nsp; t = (Type*)R.s; if(t == H) error(exModule); 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;} voidurk(char *s){ print("compile failed: %s\n", s); // debugging error(exCompile); // production} static voidgen(ulong o){ *code++ = o;} static voidbr(ulong op, ulong disp){ *code++ = op | (disp & 0xfffc);} static voidmfspr(int d, int s){ MFSPR(s, d);} static voidmtspr(int d, int s){ MTSPR(s, d);} static ulongslw(int d, int s, int v, int rshift){ int m0, m1; if(v < 0 || v > 32) urk("slw v"); if(v < 0) v = 0; else if(v > 32) v = 32; if(rshift) { /* shift right */ m0 = v; m1 = 31; v = 32-v; } else { m0 = 0; m1 = 31-v; } return RLW(Orlwinm, d, s, v, m0, m1);} static voidjr(int reg){ mtspr(Rctr, reg); /* code would be faster if this were loaded well before branch */ gen(Obctr);} static voidjrl(int reg){ mtspr(Rctr, reg); gen(Obctrl);} static voidjrc(int op, int reg){ mtspr(Rctr, reg); gen(Obcctr | op);} static longbrdisp(ulong *dest){ ulong d, top; d = (ulong)dest - (ulong)code; if(!ROMABLE) return d & 0x3fffffc; top = d>>25; if(top == 0 || top == 0x7F){ /* fits in 26-bit signed displacement */ return d & 0x3fffffc; } return -1;} static voidjmp(ulong *dest){ long d; if((d = brdisp(dest)) < 0){ ldbigc((ulong)dest, Rpic); /* Rpic & Rctr must be free */ jr(Rpic); } else gen(Ob | d);} static voidjmpl(ulong *dest){ long d; if((d = brdisp(dest)) < 0){ ldbigc((ulong)dest, Rpic); /* Rpic must be free */ jrl(Rpic); } else gen(Ob | d | Lk);} static voidjmpc(int op, ulong *dest){ ldbigc((ulong)dest, Rpic); jrc(op, Rpic);} static intbigc(long c){ if(c >= -0x8000 && c <= 0x7FFF) return 0; return 1;} static voidldbigc(long c, int reg){ AIRR(Oaddis, reg,Rzero,c>>16); LIRR(Oori, reg,reg,c);} static voidldc(long c, int reg){ if(!bigc(c)) AIRR(Oaddi, reg, Rzero, c); else if((ulong)c <= 0xFFFF) LIRR(Oori, reg, Rzero, c); else if((c&0xFFFF) == 0) LIRR(Ooris, reg, Rzero, c>>16); else { AIRR(Oaddis, reg,Rzero,c>>16); LIRR(Oori, reg,reg,c); }} static voidmem(int inst, long disp, int rm, int r){ if(bigc(disp)) { ldc(disp, Rcon); switch(inst){ default: urk("mem op"); break; case Olea: inst = Oadd; break; case Olwz: inst = Olwzx; break; case Olbz: inst = Olbzx; break; case Olhz: inst = Olhzx; break; case Ostw: inst = Ostwx; break; case Ostb: inst = Ostbx; break; case Osth: inst = Osthx; break; } ARRR(inst, r, Rcon, rm); } else { if(inst == Olea) inst = Oaddi; AIRR(inst, r, rm,disp); }} static voidopx(int mode, Adr *a, int op, int reg){ ulong c; int r, rx, lea; lea = 0; if(op == Olea){ lea = 1; op = Oaddi; } switch(mode) { case AFP: c = a->ind; if(bigc(c)) urk("bigc op1b 1"); AIRR(op, reg, Rfp,c); break; case AMP: c = a->ind; if(bigc(c))Lines 1–500 of 2257. Load more
#include "lib9.h" #include "isa.h" #include "interp.h" #include "raise.h" /* * Copyright © 1997 C H Forsyth (forsyth@terzarima.net) */ #define ROMABLE 0 /* costs something to zero patch vectors */ #define RESCHED 1 /* check for interpreter reschedule */ #define PATCH(ptr) *ptr |= ((ulong)code-(ulong)ptr) & 0xfffc #define T(r) *((void**)(R.r)) #define XO(o,xo) (((o)<<26)|((xo)<<1)) /* botch: ARRR, AIRR, LRRR, etc have dest first (will fix soon) */ #define OPARRR(o,d,a,b) ((o)|((d)<<21)|((a)<<16)|((b)<<11)) #define ARRR(o,d,a,b) gen((o)|((d)<<21)|((a)<<16)|((b)<<11)) #define AIRR(o,d,a,v) gen((o)|((d)<<21)|((a)<<16)|((v)&0xFFFF)) #define IRR(o,v,a,d) AIRR((o),(d),(a),(v)) #define RRR(o,b,a,d) ARRR((o),(d),(a),(b)) #define LRRR(o,a,s,b) ARRR((o),(s),(a),(b)) #define LIRR(o,a,s,v) AIRR((o),(s),(a),(v)) #define Bx(li,aa) gen((18<<26)|((li)&0x3FFFFFC)|((aa)<<1)) #define RLW(op,a,s,sh,mb,me) ((op)|(((s)&31L)<<21)|(((a)&31L)<<16)|(((sh)&31L)<<11)|\ (((mb)&31L)<<6)|(((me)&31L)<<1)) #define MFSPR(s, d) gen(XO(31,339) | ((d)<<21) | ((s)<<11)) #define MTSPR(s, d) gen(XO(31,467) | ((s)<<21) | ((d)<<11)); #define SLWI(d,a,n) gen(slw((d),(a),(n),0)) #define LRET() gen(Oblr) #define SETR0() if(macjit){ AIRR(Oaddi, Rzero, 0, 0); } /* set R0 to 0 */ /* assumes H can be formed from signed halfword */ #define CMPH(r) AIRR(Ocmpi, Rcrf0, (r), (ulong)H); #define NOTNIL(r) (CMPH((r)), CCALL(EQ, bounds)) enum { Rzero = 0, /* zero by design, not definition (P9/Inferno) */ Rsp = 1, Rsb = 2, Rarg = 3, Ro1 = 8, Ro2 = 9, Ro3 = 10, Ri = 11, Rj = 12, Rmp = 13, Rfp = 14, Rreg = 15, Rta = 16, /* unused */ Rpic = 17, /* address for computed goto, for move to CTR or LR */ Rcon = 26, /* constant builder; temporary */ /* 27, 28, 29, 30 are potentially external registers (P9/Inferno) */ Rlink = 31, /* holds copies of LR; linker temp */ Rfret = 0, Rf1 = 4, Rf2 = 6, Rfcvi = 27, /* floating conversion constant (P9/Inferno) */ Rfzero = 28, /* 0.0 (P9/Inferno) */ Rfhalf = 29, /* 0.5 (P9/Inferno) */ Rlr = 8<<5, /* SPR(LR) */ Rctr = 9<<5, /* SPR(CTR) */ Rcrf0 = 0, /* condition code field 0 */ Rcrf1 = 1<<2, /* condition code field 1 */ Rcrbrel = 31, /* condition code bit set to force relinquish */ Olwz = XO(32, 0), Olwzu = XO(33, 0), Olwzx = XO(31, 23), Olbz = XO(34, 0), Olbzu = XO(35, 0), Olbzx = XO(31, 87), Olfd = XO(50, 0), Olhz = XO(40, 0), Olhzx = XO(31, 279), Ostw = XO(36, 0), Ostwu = XO(37, 0), Ostwx = XO(31, 151), Ostb = XO(38, 0), Ostbu = XO(39, 0), Ostbx = XO(31, 215), Osth = XO(44,0), Osthx = XO(31, 407), Ostfd = XO(54, 0), Ostfdu = XO(55, 0), Oaddc = XO(31,10), Oadde = XO(31, 138), Oaddi = XO(14, 0), /* simm */ Oaddic_ = XO(13, 0), Oaddis = XO(15, 0), Ocrxor = XO(19, 193), Ofadd = XO(63, 21), Ofcmpo = XO(63, 32), Ofctiwz = XO(63, 15), Ofsub = XO(63, 20), Ofmr = XO(63, 72), Ofmul = XO(63, 25), Ofdiv = XO(63, 18), Ofneg = XO(63, 40), Oori = XO(24,0), /* uimm */ Ooris = XO(25,0), /* uimm */ Odivw = XO(31, 491), Odivwu = XO(31, 459), Omulhw = XO(31, 75), Omulhwu = XO(31, 11), Omulli = XO(7, 0), Omullw = XO(31, 235), Osubf = XO(31, 40), Osubfc = XO(31,8), Osubfe = XO(31,136), Osubfic = XO(8, 0), Oadd = XO(31, 266), Oand = XO(31, 28), Oneg = XO(31, 104), Oor = XO(31, 444), Oxor = XO(31, 316), Ocmpi = XO(11, 0), Ocmp = XO(31, 0), Ocmpl = XO(31, 32), Ocmpli = XO(10,0), Orlwinm = XO(21, 0), Oslw = XO(31, 24), Osraw = XO(31,792), Osrawi = XO(31,824), Osrw = XO(31,536), Cnone = OPARRR(0,20,0,0), /* unconditional */ Ceq = OPARRR(0,12,2,0), Cle = OPARRR(0,4,1,0), Clt = OPARRR(0,12,0,0), Cdnz = OPARRR(0,16,0,0), Cgt = OPARRR(0,12,1,0), Cne = OPARRR(0,4,2,0), Cge = OPARRR(0,4,0,0), Cle1 = OPARRR(0,4,5,0), /* Cle on CR1 */ Crelq = OPARRR(0,12,Rcrbrel,0), /* relinquish */ Cnrelq = OPARRR(0,4,Rcrbrel,0), /* not relinquish */ Cpredict = OPARRR(0,1,0,0), /* reverse prediction */ Lk = 1, Aa = 2, Obeq = OPARRR(16<<26,12,2,0), Obge = OPARRR(16<<26,4,0,0), Obgt = OPARRR(16<<26,12,1,0), Oble = OPARRR(16<<26,4,1,0), Oblt = OPARRR(16<<26,12,0,0), Obne = OPARRR(16<<26,4,2,0), Ob = XO(18, 0), Obc = XO(16, 0), Obcctr = XO(19,528), Obcctrl = Obcctr | Lk, Obctr = Obcctr | Cnone, Obctrl = Obctr | Lk, Obclr = XO(19, 16), Oblr = Obclr | Cnone, Oblrl = Oblr | Lk, Olea = 100, // pseudo op SRCOP = (1<<0), DSTOP = (1<<1), WRTPC = (1<<2), /* update R.PC */ TCHECK = (1<<3), /* check R.t for continue/ret */ NEWPC = (1<<4), /* goto R.PC */ DBRAN = (1<<5), /* dest is branch */ THREOP = (1<<6), ANDAND = 1, OROR, EQAND, MacRET = 0, MacFRP, MacCASE, MacFRAM, MacCOLR, MacMCAL, MacMFRA, MacCVTFW, MacRELQ, MacEND, NMACRO }; void (*comvec)(void); int macjit; extern long das(ulong*); static ulong* code; static ulong* base; static ulong* patch; static int pass; static Module* mod; static ulong* tinit; static ulong* litpool; static int nlit; static ulong macro[NMACRO]; static void ldbigc(long, int); static void rdestroy(void); static void macret(void); static void macfrp(void); static void maccase(void); static void maccvtfw(void); static void macfram(void); static void maccolr(void); static void macend(void); static void macmcal(void); static void macmfra(void); static void macrelq(void); static void movmem(Inst*); struct { int o; void (*f)(void); } macinit[] = { MacFRP, macfrp, /* decrement and free pointer */ MacRET, macret, /* return instruction */ MacCASE, maccase, /* case instruction */ MacCOLR, maccolr, /* increment and color pointer */ MacFRAM, macfram, /* frame instruction */ MacMCAL, macmcal, /* mcall bottom half */ MacMFRA, macmfra, /* punt mframe because t->initialize==0 */ MacCVTFW, maccvtfw, MacRELQ, macrelq, /* reschedule */ MacEND, macend, 0 }; static void rdestroy(void) { destroy(R.s); } static void rmcall(void) { Frame *f; Prog *p; if((void*)R.dt == H) error(exModule); 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 != nil) error(p->kill); } static void rmfram(void) { Type *t; Frame *f; uchar *nsp; t = (Type*)R.s; if(t == H) error(exModule); 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; } void urk(char *s) { print("compile failed: %s\n", s); // debugging error(exCompile); // production } static void gen(ulong o) { *code++ = o; } static void br(ulong op, ulong disp) { *code++ = op | (disp & 0xfffc); } static void mfspr(int d, int s) { MFSPR(s, d); } static void mtspr(int d, int s) { MTSPR(s, d); } static ulong slw(int d, int s, int v, int rshift) { int m0, m1; if(v < 0 || v > 32) urk("slw v"); if(v < 0) v = 0; else if(v > 32) v = 32; if(rshift) { /* shift right */ m0 = v; m1 = 31; v = 32-v; } else { m0 = 0; m1 = 31-v; } return RLW(Orlwinm, d, s, v, m0, m1); } static void jr(int reg) { mtspr(Rctr, reg); /* code would be faster if this were loaded well before branch */ gen(Obctr); } static void jrl(int reg) { mtspr(Rctr, reg); gen(Obctrl); } static void jrc(int op, int reg) { mtspr(Rctr, reg); gen(Obcctr | op); } static long brdisp(ulong *dest) { ulong d, top; d = (ulong)dest - (ulong)code; if(!ROMABLE) return d & 0x3fffffc; top = d>>25; if(top == 0 || top == 0x7F){ /* fits in 26-bit signed displacement */ return d & 0x3fffffc; } return -1; } static void jmp(ulong *dest) { long d; if((d = brdisp(dest)) < 0){ ldbigc((ulong)dest, Rpic); /* Rpic & Rctr must be free */ jr(Rpic); } else gen(Ob | d); } static void jmpl(ulong *dest) { long d; if((d = brdisp(dest)) < 0){ ldbigc((ulong)dest, Rpic); /* Rpic must be free */ jrl(Rpic); } else gen(Ob | d | Lk); } static void jmpc(int op, ulong *dest) { ldbigc((ulong)dest, Rpic); jrc(op, Rpic); } static int bigc(long c) { if(c >= -0x8000 && c <= 0x7FFF) return 0; return 1; } static void ldbigc(long c, int reg) { AIRR(Oaddis, reg,Rzero,c>>16); LIRR(Oori, reg,reg,c); } static void ldc(long c, int reg) { if(!bigc(c)) AIRR(Oaddi, reg, Rzero, c); else if((ulong)c <= 0xFFFF) LIRR(Oori, reg, Rzero, c); else if((c&0xFFFF) == 0) LIRR(Ooris, reg, Rzero, c>>16); else { AIRR(Oaddis, reg,Rzero,c>>16); LIRR(Oori, reg,reg,c); } } static void mem(int inst, long disp, int rm, int r) { if(bigc(disp)) { ldc(disp, Rcon); switch(inst){ default: urk("mem op"); break; case Olea: inst = Oadd; break; case Olwz: inst = Olwzx; break; case Olbz: inst = Olbzx; break; case Olhz: inst = Olhzx; break; case Ostw: inst = Ostwx; break; case Ostb: inst = Ostbx; break; case Osth: inst = Osthx; break; } ARRR(inst, r, Rcon, rm); } else { if(inst == Olea) inst = Oaddi; AIRR(inst, r, rm,disp); } } static void opx(int mode, Adr *a, int op, int reg) { ulong c; int r, rx, lea; lea = 0; if(op == Olea){ lea = 1; op = Oaddi; } switch(mode) { case AFP: c = a->ind; if(bigc(c)) urk("bigc op1b 1"); AIRR(op, reg, Rfp,c); break; case AMP: c = a->ind; if(bigc(c))