diff options
Diffstat (limited to 'os/cerf405/l.s')
| -rw-r--r-- | os/cerf405/l.s | 795 |
1 files changed, 795 insertions, 0 deletions
diff --git a/os/cerf405/l.s b/os/cerf405/l.s new file mode 100644 index 00000000..28990ef6 --- /dev/null +++ b/os/cerf405/l.s @@ -0,0 +1,795 @@ +#include "mem.h" + +#define MB (1024*1024) + +/* + * common ppc special purpose registers + */ +#define DSISR 18 +#define SRR0 26 /* Saved Registers (exception) */ +#define SRR1 27 +#define SPRG0 272 /* Supervisor Private Registers */ +#define SPRG1 273 +#define SPRG2 274 +#define SPRG3 275 +#define TBRU 269 /* Time base Upper/Lower (Reading) */ +#define TBRL 268 +#define TBWU 285 /* Time base Upper/Lower (Writing) */ +#define TBWL 284 +#define PVR 287 /* Processor Version */ + +/* + * 4xx-specific special purpose registers of interest here + */ +#define ICCR 1019 /* instruction cache control */ +#define DCCR 1018 /* data cache control */ +#define DBCR0 1010 /* debug control register 0 */ +#define DCWR 964 /* data cache write-through */ +#define PID 945 /* TLB process ID */ +#define CCR0 947 /* core configuration register 0 */ +#define SLER 955 /* storage little-endian */ +#define SU0R 956 /* storage user-defined 0 */ +#define SRR2 990 +#define SRR3 991 +/* SPRGn up to 7, if needed, on the 400 series */ +#define DEAR 961 /* data error address */ +#define ESR 980 /* exception syndrome */ +#define EVPR 982 /* exception vector prefix */ +#define PIT 987 /* interval timer */ +#define SGR 953 /* storage guarded */ +#define TCR 986 /* timer control */ +#define TSR 984 /* timer status */ +#define ZPR 944 /* zone protection */ + +/* + * 4xx-specific(?) device control registers + */ +#define OCM0_DSCNTL 0x1B /* OCM data-side control register */ + +/* use of SPRG registers in save/restore */ +#define SAVER0 SPRG0 +#define SAVER1 SPRG1 +#define SAVELR SPRG2 +#define SAVEXX SPRG3 + +/* special instruction definitions */ +#define BDNZ BC 16,0, +#define BDNE BC 0,2, +#define TLBIA WORD $((31<<26)|(370<<1)) +#define TLBSYNC WORD $((31<<26)|(566<<1)) +#define MFTB(tbr,d) WORD $((31<<26)|((d)<<21)|((tbr&0x1f)<<16)|(((tbr>>5)&0x1f)<<11)|(371<<1)) + +/* 603/603e specific: load tlb entries */ +#define TLBLD(x) WORD $((31<<26)|(978<<1)|((x&0x1F)<<11)) +#define TLBLI(x) WORD $((31<<26)|(1010<<1)|((x&0x1F)<<11)) + +/* 400 models; perhaps others */ +#define ICCCI(a,b) WORD $((31<<26)|((a)<<16)|((b)<<11)|(966<<1)) +#define DCCCI(a,b) WORD $((31<<26)|((a)<<16)|((b)<<11)|(454<<1)) +/* these follow the source -> dest ordering */ +#define DCREAD(s,t) WORD $((31<<26)|((t)<<21)|((s)<<11)|(486<<1)) +#define DCRF(n) ((((n)>>5)&0x1F)|(((n)&0x1F)<<5)) +#define MTDCR(s,n) WORD $((31<<26)|((s)<<21)|(DCRF(n)<<11)|(451<<1)) +#define MFDCR(n,t) WORD $((31<<26)|((t)<<21)|(DCRF(n)<<11)|(323<<1)) +#define TLBRELO(a,t) WORD $((31<<26)|((t)<<21)|((a)<<16)|(1<<11)|(946<<1)) +#define TLBREHI(a,t) WORD $((31<<26)|((t)<<21)|((a)<<16)|(0<<11)|(946<<1)) +#define TLBWELO(s,a) WORD $((31<<26)|((s)<<21)|((a)<<16)|(1<<11)|(978<<1)) +#define TLBWEHI(s,a) WORD $((31<<26)|((s)<<21)|((a)<<16)|(0<<11)|(978<<1)) +#define TLBSX(a,b,t) WORD $((31<<26)|((t)<<21)|((a)<<16)|((b)<<11)|(914<<1)) +#define TLBSXCC(a,b,t) WORD $((31<<26)|((t)<<21)|((a)<<16)|((b)<<11)|(914<<1)|1) +#define WRTMSR_EE(s) WORD $((31<<26)|((s)<<21)|(131<<1)) +#define WRTMSR_EEI(e) WORD $((31<<26)|((e)<<16)|(163<<1)) + +/* on some models mtmsr doesn't synchronise enough (eg, 603e) */ +#define MSRSYNC SYNC; ISYNC + +/* on the 400 series, the prefetcher madly fetches across RFI, sys call, and others; use BR 0(PC) to stop */ +#define RFI WORD $((19<<26)|(50<<1)); BR 0(PC) +#define RFCI WORD $((19<<26)|(51<<1)); BR 0(PC) + +#define UREGSPACE (UREGSIZE+8) + +/* could define STEP to set an LED to mark progress */ +#define STEP(x) + +/* + * Boot first processor + */ + TEXT start(SB), $-4 + + MOVW MSR, R3 + RLWNM $0, R3, $~MSR_EE, R3 + OR $MSR_ME, R3 + ISYNC + MOVW R3, MSR /* turn off interrupts but enable traps */ + MSRSYNC + MOVW $0, R0 /* except during trap handling, R0 is zero from now on */ + MOVW R0, CR + + MOVW $setSB-KZERO(SB), R2 /* SB until mmu on */ + +/* + * reset the caches and disable them until mmu on + */ + MOVW R0, SPR(ICCR) + ICCCI(0, 2) /* the errata reveals that EA is used; we'll use SB */ + ISYNC + + MOVW $((CACHEWAYSIZE/CACHELINESZ)-1), R3 + MOVW R3, CTR + MOVW R0, R3 +dcinv: + DCCCI(0,3) + ADD $32, R3 + BDNZ dcinv + + /* cache is copy-back, disabled; no user-defined 0; big endian throughout */ + MOVW R0, SPR(DCWR) + MOVW R0, SPR(DCCR) + MOVW R0, SPR(SU0R) + MOVW R0, SPR(SLER) + ISYNC + + /* guard everything above 0x20000000 */ + MOVW $~(0xF000<<16), R3 + MOVW R3, SPR(SGR) + ISYNC + + /* set access to LED */ + MOVW $PHYSGPIO, R4 + MOVW $(1<<31), R6 + MOVW $(0xC000<<16), R5 + MOVW 4(R4), R3 + OR R6, R3 + MOVW R3, 4(R4) /* tcr set */ + MOVW 0x18(R4), R3 + ANDN R6, R3 + MOVW R3, 0x18(R4) /* odr reset */ + MOVW 8(R4), R3 + ANDN R5, R3 + MOVW R3, 8(R4) /* osrh uses or */ + MOVW 0x10(R4), R3 + ANDN R5, R3 + MOVW R3, 0x10(R4) /* tsr uses tcr */ + + MOVW $(1<<31), R4 /* reset MAL */ + MTDCR(0x180, 4) + +/* + MOVW $'H', R3 + BL uartputc(SB) + MOVW $'\n', R3 + BL uartputc(SB) +*/ + +/* + * set other system configuration values + */ + MOVW R0, SPR(PIT) + MOVW $~0, R3 + MOVW R3, SPR(TSR) + +STEP(1) + + BL kernelmmu(SB) + /* now running with correct addresses, mmu on */ + + MOVW $setSB(SB), R2 + + /* enable caches for kernel 128mb in real mode; data is copy-back */ + MOVW R0, SPR(DCWR) + MOVW $(1<<31), R3 + MOVW R3, SPR(DCCR) + MOVW R3, SPR(ICCR) + +/* + BL ledoff(SB) + + MOVW $0x800, R8 + MOVW R8, LR + BL (LR) + BR 0(PC) +*/ + +STEP(2) + /* no kfpinit on 4xx */ + + MOVW $mach0(SB), R(MACH) + ADD $(MACHSIZE-8), R(MACH), R1 + SUB $4, R(MACH), R3 + ADD $4, R1, R4 +clrmach: + MOVWU R0, 4(R3) + CMP R3, R4 + BNE clrmach + + MOVW R0, R(USER) + MOVW R0, 0(R(MACH)) + + MOVW $edata(SB), R3 + MOVW $end(SB), R4 + ADD $4, R4 + SUB $4, R3 +clrbss: + MOVWU R0, 4(R3) + CMP R3, R4 + BNE clrbss + +STEP(3) + BL main(SB) + BR 0(PC) + +TEXT kernelmmu(SB), $-4 + TLBIA + ISYNC + SYNC + + /* make following TLB entries shared, TID=PID=0 */ + MOVW R0, SPR(PID) + + /* all zones are supervisor, access controlled by TLB */ + MOVW R0, SPR(ZPR) + + /* map various things 1:1 */ + MOVW $tlbtab-KZERO(SB), R4 + MOVW $tlbtabe-KZERO(SB), R5 + SUB R4, R5 + MOVW $(2*4), R6 + DIVW R6, R5 + SUB $4, R4 + MOVW R5, CTR + MOVW R0, R3 +ltlb: + MOVWU 4(R4), R5 /* TLBHI */ + TLBWEHI(5,3) + MOVWU 4(R4), R5 /* TLBLO */ + TLBWELO(5,3) + ADD $1, R3 + BDNZ ltlb + + MOVW LR, R3 + OR $KZERO, R3 + MOVW R3, SPR(SRR0) + MOVW MSR, R4 + OR $(MSR_IR|MSR_DR), R4 + MOVW R4, SPR(SRR1) + + RFI /* resume in kernel mode in caller */ + +TEXT ledoff(SB), $0 + MOVW $PHYSGPIO, R4 + MOVW 0(R4), R3 + RLWNM $0, R3, $~(1<<31), R3 /* LED off */ + MOVW R3, 0(R4) + RETURN + +TEXT splhi(SB), $0 + MOVW MSR, R3 + RLWNM $0, R3, $~MSR_EE, R4 + SYNC + MOVW R4, MSR + MSRSYNC + MOVW LR, R31 + MOVW R31, 4(R(MACH)) /* save PC in m->splpc */ + RETURN + +TEXT splx(SB), $0 + MOVW MSR, R4 + RLWMI $0, R3, $MSR_EE, R4 + RLWNMCC $0, R3, $MSR_EE, R5 + BNE splx0 + MOVW LR, R31 + MOVW R31, 4(R(MACH)) /* save PC in m->splpc */ +splx0: + SYNC + MOVW R4, MSR + MSRSYNC + RETURN + +TEXT splxpc(SB), $0 + MOVW MSR, R4 + RLWMI $0, R3, $MSR_EE, R4 + RLWNMCC $0, R3, $MSR_EE, R5 + SYNC + MOVW R4, MSR + MSRSYNC + RETURN + +TEXT spllo(SB), $0 + MFTB(TBRL, 3) + MOVW R3, spltbl(SB) + MOVW MSR, R3 + OR $MSR_EE, R3, R4 + SYNC + MOVW R4, MSR + MSRSYNC + RETURN + +TEXT spldone(SB), $0 + RETURN + +TEXT islo(SB), $0 + MOVW MSR, R3 + RLWNM $0, R3, $MSR_EE, R3 + RETURN + +TEXT setlabel(SB), $-4 + MOVW LR, R31 + MOVW R1, 0(R3) + MOVW R31, 4(R3) + MOVW $0, R3 + RETURN + +TEXT gotolabel(SB), $-4 + MOVW 4(R3), R31 + MOVW R31, LR + MOVW 0(R3), R1 + MOVW $1, R3 + RETURN + +TEXT tlbwelo(SB), $-4 + MOVW v+4(FP), R5 + SYNC + TLBWELO(5, 3) + ISYNC + SYNC + RETURN + +TEXT tlbwehi(SB), $-4 + MOVW v+4(FP), R5 + SYNC + TLBWEHI(5, 3) + ISYNC + SYNC + RETURN + +TEXT tlbrehi(SB), $-4 + TLBREHI(3, 3) + RETURN + +TEXT tlbrelo(SB), $-4 + TLBRELO(3, 3) + RETURN + +TEXT tlbsxcc(SB), $-4 + TLBSXCC(0, 3, 3) + BEQ tlbsxcc0 + MOVW $-1, R3 /* not found */ +tlbsxcc0: + RETURN + +/* + * enter with stack set and mapped. + * on return, SB (R2) has been set, and R3 has the Ureg*, + * the MMU has been re-enabled, kernel text and PC are in KSEG, + * R(MACH) has been set, and R0 contains 0. + * + * this can be simplified in the Inferno regime + */ +TEXT saveureg(SB), $-4 +/* + * save state + */ + MOVMW R2, 48(R1) /* r2:r31 */ + MOVW $setSB(SB), R2 + MOVW SPR(SAVER1), R4 + MOVW R4, 44(R1) + MOVW SPR(SAVER0), R5 + MOVW R5, 40(R1) + MOVW CTR, R6 + MOVW R6, 36(R1) + MOVW XER, R4 + MOVW R4, 32(R1) + MOVW CR, R5 + MOVW R5, 28(R1) + MOVW SPR(SAVELR), R6 /* LR */ + MOVW R6, 24(R1) + /* pad at 20(R1) */ + /* old PC(16) and status(12) saved earlier */ + MOVW SPR(SAVEXX), R0 + MOVW R0, 8(R1) /* cause/vector */ + ADD $8, R1, R3 /* Ureg* */ + STWCCC R3, (R1) /* break any pending reservations */ + MOVW $0, R0 /* compiler/linker expect R0 to be zero */ + + MOVW MSR, R5 + OR $(MSR_IR|MSR_DR), R5 /* enable MMU */ + MOVW R5, SPR(SRR1) + MOVW LR, R31 + OR $KZERO, R31 /* return PC in KSEG0 */ + MOVW R31, SPR(SRR0) + SYNC + ISYNC + RFI /* returns to trap handler */ + +TEXT icflush(SB), $-4 /* icflush(virtaddr, count) */ + MOVW n+4(FP), R4 + CMP R4, R0 + BLE icf1 + RLWNM $0, R3, $~(CACHELINESZ-1), R5 + SUB R5, R3 + ADD R3, R4 + ADD $(CACHELINESZ-1), R4 + SRAW $CACHELINELOG, R4 + MOVW R4, CTR +icf0: ICBI (R5) + ADD $CACHELINESZ, R5 + BDNZ icf0 +icf1: + ISYNC + RETURN + +/* + * flush to store and invalidate globally + */ +TEXT dcflush(SB), $-4 /* dcflush(virtaddr, count) */ + SYNC + MOVW n+4(FP), R4 + RLWNM $0, R3, $~(CACHELINESZ-1), R5 + CMP R4, $0 + BLE dcf1 + SUB R5, R3 + ADD R3, R4 + ADD $(CACHELINESZ-1), R4 + SRAW $CACHELINELOG, R4 + MOVW R4, CTR +dcf0: DCBF (R5) + ADD $CACHELINESZ, R5 + BDNZ dcf0 + SYNC +dcf1: + ISYNC + MOVW R5, R3 /* check its operation */ + RETURN + +/* + * invalidate without flush, globally + */ +TEXT dcinval(SB), $-4 /* dcinval(virtaddr, count) */ + SYNC + MOVW n+4(FP), R4 + RLWNM $0, R3, $~(CACHELINESZ-1), R5 + CMP R4, $0 + BLE dci1 + SUB R5, R3 + ADD R3, R4 + ADD $(CACHELINESZ-1), R4 + SRAW $CACHELINELOG, R4 + MOVW R4, CTR +dci0: DCBI (R5) + ADD $CACHELINESZ, R5 + BDNZ dci0 + SYNC + ISYNC +dci1: + RETURN + +TEXT dccci(SB), $-4 + SYNC + DCCCI(0, 3) + ISYNC + RETURN + +TEXT _tas(SB), $0 + SYNC + MOVW R3, R4 + MOVW $0xdeaddead,R5 +tas1: + DCBF (R4) /* fix for 603x bug */ + LWAR (R4), R3 + CMP R3, $0 + BNE tas0 + STWCCC R5, (R4) + BNE tas1 +tas0: + SYNC + ISYNC + RETURN + +TEXT gettbl(SB), $0 + MFTB(TBRL, 3) + RETURN + +TEXT gettbu(SB), $0 + MFTB(TBRU, 3) + RETURN + +TEXT getpvr(SB), $0 + MOVW SPR(PVR), R3 + RETURN + +TEXT getcallerpc(SB), $-4 + MOVW 0(R1), R3 + RETURN + +TEXT getdear(SB), $0 + MOVW SPR(DEAR), R3 + RETURN + +TEXT getdsisr(SB), $0 + MOVW SPR(DSISR), R3 + RETURN + +TEXT getmsr(SB), $0 + MOVW MSR, R3 + RETURN + +TEXT putmsr(SB), $0 + SYNC + MOVW R3, MSR + MSRSYNC + RETURN + +TEXT putevpr(SB), $0 + MOVW R3, SPR(EVPR) + RETURN + +TEXT getesr(SB), $0 + MOVW SPR(ESR), R3 + RETURN + +TEXT putesr(SB), $0 + MOVW R3, SPR(ESR) + RETURN + +TEXT getpit(SB), $0 + MOVW SPR(PIT), R3 + RETURN + +TEXT putpit(SB), $0 + MOVW R3, SPR(PIT) + RETURN + +TEXT gettsr(SB), $0 + MOVW SPR(TSR), R3 + RETURN + +TEXT puttsr(SB), $0 + MOVW R3, SPR(TSR) + RETURN + +TEXT puttcr(SB), $0 + MOVW R3, SPR(TCR) + RETURN + +TEXT eieio(SB), $0 + EIEIO + RETURN + +TEXT gotopc(SB), $0 + MOVW R3, CTR + MOVW LR, R31 /* for trace back */ + BR (CTR) + +TEXT getccr0(SB), $-4 + MOVW SPR(CCR0), R3 + RETURN + +TEXT dcread(SB), $-4 + MOVW 4(FP), R4 + MOVW SPR(CCR0), R5 + RLWNM $0, R5, $~0xFF, R5 + OR R4, R5 + MOVW R5, SPR(CCR0) + SYNC + ISYNC + DCREAD(3, 3) + RETURN + +TEXT getdcr(SB), $-4 + MOVW $_getdcr(SB), R5 + SLW $3, R3 + ADD R3, R5 + MOVW R5, CTR + BR (CTR) + +TEXT putdcr(SB), $-4 + MOVW $_putdcr(SB), R5 + SLW $3, R3 + ADD R3, R5 + MOVW R5, CTR + MOVW 8(R1), R3 + BR (CTR) + +TEXT firmware(SB), $0 + MOVW $(3<<28), R3 + MOVW R3, SPR(DBCR0) /* system reset */ + BR 0(PC) + +/* + * byte swapping of arrays of long and short; + * could possibly be avoided with more changes to drivers + */ +TEXT swabl(SB), $0 + MOVW v+4(FP), R4 + MOVW n+8(FP), R5 + SRAW $2, R5, R5 + MOVW R5, CTR + SUB $4, R4 + SUB $4, R3 +swabl1: + ADD $4, R3 + MOVWU 4(R4), R7 + MOVWBR R7, (R3) + BDNZ swabl1 + RETURN + +TEXT swabs(SB), $0 + MOVW v+4(FP), R4 + MOVW n+8(FP), R5 + SRAW $1, R5, R5 + MOVW R5, CTR + SUB $2, R4 + SUB $2, R3 +swabs1: + ADD $2, R3 + MOVHZU 2(R4), R7 + MOVHBR R7, (R3) + BDNZ swabs1 + RETURN + +TEXT legetl(SB), $0 + MOVWBR (R3), R3 + RETURN + +TEXT lesetl(SB), $0 + MOVW v+4(FP), R4 + MOVWBR R4, (R3) + RETURN + +TEXT legets(SB), $0 + MOVHBR (R3), R3 + RETURN + +TEXT lesets(SB), $0 + MOVW v+4(FP), R4 + MOVHBR R4, (R3) + RETURN + +TEXT itlbmiss(SB), $-4 + BR traps + +TEXT dtlbmiss(SB), $-4 + BR traps + +/* + * traps force memory mapping off. + * this code goes to much effort to restore it; + * (a little more effort than needed for the Inferno environment) + */ +TEXT trapvec(SB), $-4 +traps: + MOVW LR, R0 + +pagefault: + +/* + * map data virtually and make space to save + */ + MOVW R0, SPR(SAVEXX) /* vector */ +trapcomm: + MOVW R1, SPR(SAVER1) + SYNC + ISYNC + MOVW MSR, R0 + OR $(MSR_DR|MSR_ME), R0 /* make data space usable */ + SYNC + MOVW R0, MSR + MSRSYNC + SUB $UREGSPACE, R1 + + MOVW SPR(SRR0), R0 /* save SRR0/SRR1 now, since DLTB might be missing stack page */ + MOVW R0, LR + MOVW SPR(SRR1), R0 + RLWNM $0, R0, $~MSR_WE, R0 /* remove wait state */ + MOVW R0, 12(R1) /* save status: could take DLTB miss here */ + MOVW LR, R0 + MOVW R0, 16(R1) /* old PC */ + BL saveureg(SB) + BL trap(SB) + BR restoreureg + +/* + * critical trap/interrupt + */ +TEXT trapcvec(SB), $-4 + MOVW LR, R0 + /* for now we'll just restore the state to the conventions that trap expects, since we don't use critical intrs yet */ + MOVW R0, SPR(SAVEXX) + MOVW SPR(SRR2), R0 + MOVW R0, SPR(SRR0) + MOVW SPR(SRR3), R0 + MOVW R0, SPR(SRR1) + BR trapcomm + +TEXT intrvec(SB), $-4 + MOVW LR, R0 + +/* + * map data virtually and make space to save + */ + MOVW R0, SPR(SAVEXX) /* vector */ + MOVW R1, SPR(SAVER1) + SYNC + ISYNC + MOVW MSR, R0 + OR $MSR_DR, R0 /* make data space usable */ + SYNC + MOVW R0, MSR + MSRSYNC + SUB $UREGSPACE, R1 + + MFTB(TBRL, 0) + MOVW R0, intrtbl(SB) + + MOVW SPR(SRR0), R0 + MOVW R0, LR + MOVW SPR(SRR1), R0 + RLWNM $0, R0, $~MSR_WE, R0 /* remove wait state */ + MOVW R0, 12(R1) + MOVW LR, R0 + MOVW R0, 16(R1) + BL saveureg(SB) + + MFTB(TBRL, 5) + MOVW R5, isavetbl(SB) + + BL intr(SB) + +/* + * restore state from Ureg and return from trap/interrupt + */ +restoreureg: + MOVMW 48(R1), R2 /* r2:r31 */ + /* defer R1 */ + MOVW 40(R1), R0 + MOVW R0, SPR(SAVER0) + MOVW 36(R1), R0 + MOVW R0, CTR + MOVW 32(R1), R0 + MOVW R0, XER + MOVW 28(R1), R0 + MOVW R0, CR /* CR */ + MOVW 24(R1), R0 + MOVW R0, SPR(SAVELR) /* LR */ + /* pad, skip */ + MOVW 16(R1), R0 + MOVW R0, SPR(SRR0) /* old PC */ + MOVW 12(R1), R0 + MOVW R0, SPR(SRR1) /* old MSR */ + /* cause, skip */ + MOVW 44(R1), R1 /* old SP */ + MOVW SPR(SAVELR), R0 + MOVW R0, LR + MOVW SPR(SAVER0), R0 + RFI + +TEXT mul64fract(SB), $0 + MOVW a0+8(FP), R9 + MOVW a1+4(FP), R10 + MOVW b0+16(FP), R4 + MOVW b1+12(FP), R5 + + MULLW R10, R5, R13 /* c2 = lo(a1*b1) */ + + MULLW R10, R4, R12 /* c1 = lo(a1*b0) */ + MULHWU R10, R4, R7 /* hi(a1*b0) */ + ADD R7, R13 /* c2 += hi(a1*b0) */ + + MULLW R9, R5, R6 /* lo(a0*b1) */ + MULHWU R9, R5, R7 /* hi(a0*b1) */ + ADDC R6, R12 /* c1 += lo(a0*b1) */ + ADDE R7, R13 /* c2 += hi(a0*b1) + carry */ + + MULHWU R9, R4, R7 /* hi(a0*b0) */ + ADDC R7, R12 /* c1 += hi(a0*b0) */ + ADDE R0, R13 /* c2 += carry */ + + MOVW R12, 4(R3) + MOVW R13, 0(R3) + RETURN + +GLOBL mach0+0(SB), $MACHSIZE +GLOBL spltbl+0(SB), $4 +GLOBL intrtbl+0(SB), $4 +GLOBL isavetbl+0(SB), $4 |
