summaryrefslogtreecommitdiff
path: root/utils/ka/l.s
diff options
context:
space:
mode:
Diffstat (limited to 'utils/ka/l.s')
-rw-r--r--utils/ka/l.s696
1 files changed, 696 insertions, 0 deletions
diff --git a/utils/ka/l.s b/utils/ka/l.s
new file mode 100644
index 00000000..b982e553
--- /dev/null
+++ b/utils/ka/l.s
@@ -0,0 +1,696 @@
+/*
+ * Memory and machine-specific definitions. Used in C and assembler.
+ */
+
+/*
+ * Sizes
+ */
+
+#define BI2BY 8 /* bits per byte */
+#define BI2WD 32 /* bits per word */
+#define BY2WD 4 /* bytes per word */
+#define BY2PG 4096 /* bytes per page */
+#define WD2PG (BY2PG/BY2WD) /* words per page */
+#define PGSHIFT 12 /* log(BY2PG) */
+#define PGROUND(s) (((s)+(BY2PG-1))&~(BY2PG-1))
+
+#define MAXMACH 1 /* max # cpus system can run */
+
+/*
+ * Time
+ */
+#define HZ 20 /* clock frequency */
+#define MS2HZ (1000/HZ) /* millisec per clock tick */
+#define TK2SEC(t) ((t)/HZ) /* ticks to seconds */
+#define TK2MS(t) ((((ulong)(t))*1000)/HZ) /* ticks to milliseconds */
+#define MS2TK(t) ((((ulong)(t))*HZ)/1000) /* milliseconds to ticks */
+
+/*
+ * PSR bits
+ */
+#define PSREC 0x00002000
+#define PSREF 0x00001000
+#define PSRSUPER 0x00000080
+#define PSRPSUPER 0x00000040
+#define PSRET 0x00000020
+#define SPL(n) (n<<8)
+
+/*
+ * Magic registers
+ */
+
+#define MACH 6 /* R6 is m-> */
+#define USER 5 /* R5 is u-> */
+
+/*
+ * Fundamental addresses
+ */
+
+#define USERADDR 0xE0000000
+#define UREGADDR (USERADDR+BY2PG-((32+6)*BY2WD))
+#define BOOTSTACK (KTZERO-0*BY2PG)
+#define TRAPS (KTZERO-2*BY2PG)
+
+/*
+ * MMU
+ */
+
+#define VAMASK 0x3FFFFFFF
+#define NPMEG (1<<12)
+#define BY2SEGM (1<<18)
+#define PG2SEGM (1<<6)
+#define NTLBPID (1+NCONTEXT) /* TLBPID 0 is unallocated */
+#define NCONTEXT 8
+#define CONTEXT 0x30000000 /* in ASI 2 */
+
+/*
+ * MMU regions
+ */
+#define INVALIDSEGM 0xFFFC0000 /* highest seg of VA reserved as invalid */
+#define INVALIDPMEG 0x7F
+#define SCREENSEGM 0xFFF80000
+#define SCREENPMEG 0x7E
+#define ROMSEGM 0xFFE80000
+#define ROMEND 0xFFEA0000
+#define PG2ROM ((ROMEND-ROMSEGM)/BY2PG)
+#define IOSEGM0 ROMSEGM /* see mmuinit() */
+#define NIOSEGM ((SCREENSEGM-ROMSEGM)/BY2SEGM)
+#define IOPMEG0 (SCREENPMEG-NIOSEGM)
+#define IOSEGM ROMEND
+#define IOEND SCREENSEGM
+#define TOPPMEG IOPMEG0
+
+/*
+ * MMU entries
+ */
+#define PTEVALID (1<<31)
+#define PTERONLY (0<<30)
+#define PTEWRITE (1<<30)
+#define PTEKERNEL (1<<29)
+#define PTENOCACHE (1<<28)
+#define PTEMAINMEM (0<<26)
+#define PTEIO (1<<26)
+#define PTEACCESS (1<<25)
+#define PTEMODIFY (1<<24)
+#define PTEUNCACHED 0
+#define PTEMAPMEM (1024*1024)
+#define PTEPERTAB (PTEMAPMEM/BY2PG)
+#define SEGMAPSIZE 16
+
+#define INVALIDPTE 0
+#define PPN(pa) ((pa>>12)&0xFFFF)
+
+/*
+ * Weird addresses in various ASI's
+ */
+#define CACHETAGS 0x80000000 /* ASI 2 */
+#define CACHEDATA 0x90000000 /* ASI 2 */
+#define SER 0x60000000 /* ASI 2 */
+#define SEVAR 0x60000004 /* ASI 2 */
+#define ASER 0x60000008 /* ASI 2 */
+#define ASEVAR 0x6000000C /* ASI 2 */
+#define ENAB 0x40000000 /* ASI 2 */
+#define ENABCACHE 0x10
+#define ENABRESET 0x04
+
+/*
+ * Virtual addresses
+ */
+#define VTAG(va) ((va>>22)&0x03F)
+#define VPN(va) ((va>>13)&0x1FF)
+
+#define PARAM ((char*)0x40500000)
+#define TLBFLUSH_ 0x01
+
+/*
+ * Address spaces
+ */
+
+#define UZERO 0x00000000 /* base of user address space */
+#define UTZERO (UZERO+BY2PG) /* first address in user text */
+#define TSTKTOP 0x10000000 /* end of new stack in sysexec */
+#define TSTKSIZ 32
+#define USTKTOP (TSTKTOP-TSTKSIZ*BY2PG) /* byte just beyond user stack */
+#define KZERO 0xE0000000 /* base of kernel address space */
+#define KTZERO (KZERO+4*BY2PG) /* first address in kernel text */
+#define USTKSIZE (4*1024*1024) /* size of user stack */
+
+#define MACHSIZE 4096
+
+#define isphys(x) (((ulong)(x)&0xF0000000) == KZERO)
+
+#define SYSPSR (SPL(0x0)|PSREF|PSRSUPER|0)
+#define NOOP OR R0, R0; OR R0, R0; OR R0, R0
+
+TEXT start(SB), $-4
+
+ /* get virtual, fast */
+ /* we are executing in segment 0, mapped to pmeg 0. stack is there too */
+ /* get virtual by mapping segment(KZERO) to pmeg 0., and next to 1 */
+ MOVW $KZERO, R7
+ MOVB R0, (R7, 3)
+ MOVW $(KZERO+BY2SEGM), R7
+ MOVW $1, R8
+ MOVB R8, (R7, 3)
+ /* now mapped correctly. jmpl to where we want to be */
+ MOVW $setSB(SB), R2
+ MOVW $startvirt(SB), R7
+ JMPL (R7)
+ MOVW $_mul(SB), R0 /* touch _mul etc.; doesn't need to execute */
+ RETURN /* can't get here */
+
+TEXT startvirt(SB), $-4
+
+ MOVW $BOOTSTACK, R1
+
+ MOVW $(SPL(0xF)|PSREF|PSRSUPER), R7
+ MOVW R7, PSR
+
+ MOVW $(0x35<<22), R7 /* NVM OFM DZM AU */
+ MOVW R7, fsr+0(SB)
+ MOVW fsr+0(SB), FSR
+ FMOVD $0.5, F26 /* 0.5 -> F26 */
+ FSUBD F26, F26, F24 /* 0.0 -> F24 */
+ FADDD F26, F26, F28 /* 1.0 -> F28 */
+ FADDD F28, F28, F30 /* 2.0 -> F30 */
+
+ FMOVD F24, F0
+ FMOVD F24, F2
+ FMOVD F24, F4
+ FMOVD F24, F6
+ FMOVD F24, F8
+ FMOVD F24, F10
+ FMOVD F24, F12
+ FMOVD F24, F14
+ FMOVD F24, F16
+ FMOVD F24, F18
+ FMOVD F24, F20
+ FMOVD F24, F22
+
+ MOVW $mach0(SB), R(MACH)
+/* MOVW $0x8, R7 /**/
+ MOVW R0, WIM
+ JMPL main(SB)
+ MOVW (R0), R0
+ RETURN
+
+TEXT swap1(SB), $0
+
+ TAS (R7), R7 /* LDSTUB, thank you ken */
+ RETURN
+
+TEXT swap1_should_work(SB), $0
+
+ MOVW R7, R8
+ MOVW $1, R7
+ SWAP (R8), R7
+ RETURN
+
+TEXT swap1x(SB), $0
+
+ MOVW PSR, R9
+ MOVW R9, R10
+ AND $~PSRET, R10 /* BUG: book says this is buggy */
+ MOVW R10, PSR
+ NOOP
+ MOVW (R7), R7
+ CMP R7, R0
+ BNE was1
+ MOVW $1, R10
+ MOVW R10, (R8)
+was1:
+ MOVW R9, PSR
+ RETURN
+
+TEXT spllo(SB), $0
+
+ MOVW PSR, R7
+ MOVW R7, R10
+ OR $PSRET, R10
+ MOVW R10, PSR
+ NOOP
+ RETURN
+
+TEXT splhi(SB), $0
+
+ MOVW R15, 4(R(MACH)) /* save PC in m->splpc */
+ MOVW PSR, R7
+ MOVW R7, R10
+ AND $~PSRET, R10 /* BUG: book says this is buggy */
+ MOVW R10, PSR
+ NOOP
+ RETURN
+
+TEXT splx(SB), $0
+
+ MOVW R15, 4(R(MACH)) /* save PC in m->splpc */
+ MOVW R7, PSR /* BUG: book says this is buggy */
+ NOOP
+ RETURN
+
+TEXT spldone(SB), $0
+
+ RETURN
+
+TEXT touser(SB), $0
+ MOVW $(SYSPSR&~PSREF), R8
+ MOVW R8, PSR
+ NOOP
+
+ MOVW R7, R1
+ SAVE R0, R0 /* RETT is implicit RESTORE */
+ MOVW $(UTZERO+32), R7 /* PC; header appears in text */
+ MOVW $(UTZERO+32+4), R8 /* nPC */
+ RETT R7, R8
+
+TEXT rfnote(SB), $0
+
+ MOVW R7, R1 /* 1st arg is &uregpointer */
+ ADD $4, R1 /* point at ureg */
+ JMP restore
+
+TEXT traplink(SB), $-4
+
+ /* R8 to R23 are free to play with */
+ /* R17 contains PC, R18 contains nPC */
+ /* R19 has PSR loaded from vector code */
+
+ ANDCC $PSRPSUPER, R19, R0
+ BE usertrap
+
+kerneltrap:
+ /*
+ * Interrupt or fault from kernel
+ */
+ ANDN $7, R1, R20 /* dbl aligned */
+ MOVW R1, (0-(4*(32+6))+(4*1))(R20) /* save R1=SP */
+ /* really clumsy: store these in Ureg so can be restored below */
+ MOVW R2, (0-(4*(32+6))+(4*2))(R20) /* SB */
+ MOVW R5, (0-(4*(32+6))+(4*5))(R20) /* USER */
+ MOVW R6, (0-(4*(32+6))+(4*6))(R20) /* MACH */
+ SUB $(4*(32+6)), R20, R1
+
+trap1:
+ MOVW Y, R20
+ MOVW R20, (4*(32+0))(R1) /* Y */
+ MOVW TBR, R20
+ MOVW R20, (4*(32+1))(R1) /* TBR */
+ AND $~0x1F, R19 /* force CWP=0 */
+ MOVW R19, (4*(32+2))(R1) /* PSR */
+ MOVW R18, (4*(32+3))(R1) /* nPC */
+ MOVW R17, (4*(32+4))(R1) /* PC */
+ MOVW R0, (4*0)(R1)
+ MOVW R3, (4*3)(R1)
+ MOVW R4, (4*4)(R1)
+ MOVW R7, (4*7)(R1)
+ RESTORE R0, R0
+ /* now our registers R8-R31 are same as before trap */
+ /* save registers two at a time */
+ MOVD R8, (4*8)(R1)
+ MOVD R10, (4*10)(R1)
+ MOVD R12, (4*12)(R1)
+ MOVD R14, (4*14)(R1)
+ MOVD R16, (4*16)(R1)
+ MOVD R18, (4*18)(R1)
+ MOVD R20, (4*20)(R1)
+ MOVD R22, (4*22)(R1)
+ MOVD R24, (4*24)(R1)
+ MOVD R26, (4*26)(R1)
+ MOVD R28, (4*28)(R1)
+ MOVD R30, (4*30)(R1)
+ /* SP and SB and u and m are already set; away we go */
+ MOVW R1, R7 /* pointer to Ureg */
+ SUB $8, R1
+ MOVW $SYSPSR, R8
+ MOVW R8, PSR
+ NOOP
+ JMPL trap(SB)
+
+ ADD $8, R1
+restore:
+ MOVW (4*(32+2))(R1), R8 /* PSR */
+ MOVW R8, PSR
+ NOOP
+
+ MOVD (4*30)(R1), R30
+ MOVD (4*28)(R1), R28
+ MOVD (4*26)(R1), R26
+ MOVD (4*24)(R1), R24
+ MOVD (4*22)(R1), R22
+ MOVD (4*20)(R1), R20
+ MOVD (4*18)(R1), R18
+ MOVD (4*16)(R1), R16
+ MOVD (4*14)(R1), R14
+ MOVD (4*12)(R1), R12
+ MOVD (4*10)(R1), R10
+ MOVD (4*8)(R1), R8
+ SAVE R0, R0
+ MOVD (4*6)(R1), R6
+ MOVD (4*4)(R1), R4
+ MOVD (4*2)(R1), R2
+ MOVW (4*(32+0))(R1), R20 /* Y */
+ MOVW R20, Y
+ MOVW (4*(32+4))(R1), R17 /* PC */
+ MOVW (4*(32+3))(R1), R18 /* nPC */
+ MOVW (4*1)(R1), R1 /* restore R1=SP */
+ RETT R17, R18
+
+usertrap:
+ /*
+ * Interrupt or fault from user
+ */
+ MOVW R1, R8
+ MOVW R2, R9
+ MOVW $setSB(SB), R2
+ MOVW $(USERADDR+BY2PG), R1
+ MOVW R8, (0-(4*(32+6))+(4*1))(R1) /* save R1=SP */
+ MOVW R9, (0-(4*(32+6))+(4*2))(R1) /* save R2=SB */
+ MOVW R5, (0-(4*(32+6))+(4*5))(R1) /* save R5=USER */
+ MOVW R6, (0-(4*(32+6))+(4*6))(R1) /* save R6=MACH */
+ MOVW $USERADDR, R(USER)
+ MOVW $mach0(SB), R(MACH)
+ SUB $(4*(32+6)), R1
+ JMP trap1
+
+TEXT syslink(SB), $-4
+
+ /* R8 to R23 are free to play with */
+ /* R17 contains PC, R18 contains nPC */
+ /* R19 has PSR loaded from vector code */
+ /* assume user did it; syscall checks */
+
+ MOVW R1, R8
+ MOVW R2, R9
+ MOVW $setSB(SB), R2
+ MOVW $(USERADDR+BY2PG), R1
+ MOVW R8, (0-(4*(32+6))+4)(R1) /* save R1=SP */
+ SUB $(4*(32+6)), R1
+ MOVW R9, (4*2)(R1) /* save R2=SB */
+ MOVW R3, (4*3)(R1) /* global register */
+ MOVD R4, (4*4)(R1) /* global register, R5=USER */
+ MOVD R6, (4*6)(R1) /* save R6=MACH, R7=syscall# */
+ MOVW $USERADDR, R(USER)
+ MOVW $mach0(SB), R(MACH)
+ MOVW TBR, R20
+ MOVW R20, (4*(32+1))(R1) /* TBR */
+ AND $~0x1F, R19
+ MOVW R19, (4*(32+2))(R1) /* PSR */
+ MOVW R18, (4*(32+3))(R1) /* nPC */
+ MOVW R17, (4*(32+4))(R1) /* PC */
+ RESTORE R0, R0
+ /* now our registers R8-R31 are same as before trap */
+ MOVW R15, (4*15)(R1)
+ /* SP and SB and u and m are already set; away we go */
+ MOVW R1, R7 /* pointer to Ureg */
+ SUB $8, R1
+ MOVW $SYSPSR, R8
+ MOVW R8, PSR
+ JMPL syscall(SB)
+ /* R7 contains return value from syscall */
+
+ ADD $8, R1
+ MOVW (4*(32+2))(R1), R8 /* PSR */
+ MOVW R8, PSR
+ NOOP
+
+ MOVW (4*15)(R1), R15
+ SAVE R0, R0
+ MOVW (4*6)(R1), R6
+ MOVD (4*4)(R1), R4
+ MOVD (4*2)(R1), R2
+ MOVW (4*(32+4))(R1), R17 /* PC */
+ MOVW (4*(32+3))(R1), R18 /* nPC */
+ MOVW (4*1)(R1), R1 /* restore R1=SP */
+ RETT R17, R18
+
+TEXT puttbr(SB), $0
+
+ MOVW R7, TBR
+ NOOP
+ RETURN
+
+TEXT gettbr(SB), $0
+
+ MOVW TBR, R7
+ RETURN
+
+TEXT r1(SB), $0
+
+ MOVW R1, R7
+ RETURN
+
+TEXT getwim(SB), $0
+
+ MOVW WIM, R7
+ RETURN
+
+TEXT setlabel(SB), $0
+
+ MOVW R1, (R7)
+ MOVW R15, 4(R7)
+ MOVW $0, R7
+ RETURN
+
+TEXT gotolabel(SB), $0
+
+ MOVW (R7), R1
+ MOVW 4(R7), R15
+ MOVW $1, R7
+ RETURN
+
+TEXT putcxsegm(SB), $0
+
+ MOVW R7, R8 /* context */
+ MOVW 4(FP), R9 /* segment addr */
+ MOVW 8(FP), R10 /* segment value */
+ MOVW $0xFFE80118, R7
+ JMPL (R7)
+ RETURN
+
+TEXT getpsr(SB), $0
+
+ MOVW PSR, R7
+ RETURN
+
+TEXT putcxreg(SB), $0
+
+ MOVW $CONTEXT, R8
+ MOVB R7, (R8, 2)
+ RETURN
+
+TEXT putb2(SB), $0
+
+ MOVW 4(FP), R8
+ MOVB R8, (R7, 2)
+ RETURN
+
+TEXT getb2(SB), $0
+
+ MOVB (R7, 2), R7
+ RETURN
+
+TEXT getw2(SB), $0
+
+ MOVW (R7, 2), R7
+ RETURN
+
+TEXT putw2(SB), $0
+
+ MOVW 4(FP), R8
+ MOVW R8, (R7, 2)
+ RETURN
+
+TEXT putw4(SB), $0
+
+ MOVW 4(FP), R8
+ MOVW R8, (R7, 4)
+ RETURN
+
+TEXT getw4(SB), $0
+
+ MOVW (R7, 4), R7
+ RETURN
+
+TEXT putwC(SB), $0
+
+ MOVW 4(FP), R8
+ MOVW R8, (R7, 0xC)
+ RETURN
+
+TEXT putwD(SB), $0
+
+ MOVW 4(FP), R8
+ MOVW R8, (R7, 0xD)
+ RETURN
+
+TEXT putwD16(SB), $0
+
+ MOVW 4(FP), R8
+ MOVW R8, (R7, 0xD)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xD)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xD)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xD)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xD)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xD)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xD)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xD)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xD)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xD)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xD)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xD)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xD)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xD)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xD)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xD)
+ RETURN
+
+TEXT putwE(SB), $0
+
+ MOVW 4(FP), R8
+ MOVW R8, (R7, 0xE)
+ RETURN
+
+TEXT putwE16(SB), $0
+
+ MOVW 4(FP), R8
+ MOVW R8, (R7, 0xE)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xE)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xE)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xE)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xE)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xE)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xE)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xE)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xE)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xE)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xE)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xE)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xE)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xE)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xE)
+ ADD $(1<<4), R7
+ MOVW R8, (R7, 0xE)
+ RETURN
+
+TEXT putsegm(SB), $0
+
+ MOVW 4(FP), R8
+ MOVW R8, (R7, 3)
+ RETURN
+
+/*
+ * in savefpregs and restfpregs, incoming R7 points to doubleword
+ * below where F0 will go; doubleword align in and backfill FSR
+ */
+TEXT savefpregs(SB), $0
+
+ ADD $8, R7
+ ANDN $7, R7 /* now MOVD-aligned */
+ MOVW FSR, -4(R7)
+
+ MOVD F0, (0*4)(R7)
+ MOVD F2, (2*4)(R7)
+ MOVD F4, (4*4)(R7)
+ MOVD F6, (6*4)(R7)
+ MOVD F8, (8*4)(R7)
+ MOVD F10, (10*4)(R7)
+ MOVD F12, (12*4)(R7)
+ MOVD F14, (14*4)(R7)
+ MOVD F16, (16*4)(R7)
+ MOVD F18, (18*4)(R7)
+ MOVD F20, (20*4)(R7)
+ MOVD F22, (22*4)(R7)
+ MOVD F24, (24*4)(R7)
+ MOVD F26, (26*4)(R7)
+ MOVD F28, (28*4)(R7)
+ MOVD F30, (30*4)(R7)
+
+ MOVW PSR, R8
+ ANDN $PSREF, R8
+ MOVW R8, PSR
+ RETURN
+
+TEXT restfpregs(SB), $0
+
+ MOVW PSR, R8
+ OR $PSREF, R8
+ MOVW R8, PSR
+
+ ADD $8, R7
+ ANDN $7, R7 /* now MOVD-aligned */
+ OR R0, R0
+
+ MOVW -4(R7), FSR
+
+ MOVD (0*4)(R7), F0
+ MOVD (2*4)(R7), F2
+ MOVD (4*4)(R7), F4
+ MOVD (6*4)(R7), F6
+ MOVD (8*4)(R7), F8
+ MOVD (10*4)(R7), F10
+ MOVD (12*4)(R7), F12
+ MOVD (14*4)(R7), F14
+ MOVD (16*4)(R7), F16
+ MOVD (18*4)(R7), F18
+ MOVD (20*4)(R7), F20
+ MOVD (22*4)(R7), F22
+ MOVD (24*4)(R7), F24
+ MOVD (26*4)(R7), F26
+ MOVD (28*4)(R7), F28
+ MOVD (30*4)(R7), F30
+
+ ANDN $PSREF, R8
+ MOVW R8, PSR
+ RETURN
+
+TEXT clearfpintr(SB), $0
+
+ MOVW $fpq+BY2WD(SB), R7
+ ANDN $0x7, R7 /* must be D aligned */
+ MOVW $fsr+0(SB), R9
+clrq:
+ MOVD FQ, (R7)
+ MOVW FSR, (R9)
+ MOVW (R9), R8
+ AND $(1<<13), R8 /* queue not empty? */
+ BNE clrq
+ RETURN
+
+TEXT getfsr(SB), $0
+ MOVW $fsr+0(SB), R7
+ MOVW FSR, (R7)
+ MOVW (R7), R7
+ RETURN
+
+GLOBL mach0+0(SB), $MACHSIZE
+GLOBL fpq+0(SB), $(3*BY2WD)
+GLOBL fsr+0(SB), $BY2WD