summaryrefslogtreecommitdiff
path: root/sys/src/libc/68020
diff options
context:
space:
mode:
authorTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
committerTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
commite5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch)
treed8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/libc/68020
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/libc/68020')
-rwxr-xr-xsys/src/libc/68020/68881/acos.s3
-rwxr-xr-xsys/src/libc/68020/68881/asin.s3
-rwxr-xr-xsys/src/libc/68020/68881/atan.s3
-rwxr-xr-xsys/src/libc/68020/68881/cos.s3
-rwxr-xr-xsys/src/libc/68020/68881/cosh.s3
-rwxr-xr-xsys/src/libc/68020/68881/exp.s3
-rwxr-xr-xsys/src/libc/68020/68881/fabs.s3
-rwxr-xr-xsys/src/libc/68020/68881/log.s3
-rwxr-xr-xsys/src/libc/68020/68881/log10.s3
-rwxr-xr-xsys/src/libc/68020/68881/mkfile31
-rwxr-xr-xsys/src/libc/68020/68881/pow10.s3
-rwxr-xr-xsys/src/libc/68020/68881/sin.s3
-rwxr-xr-xsys/src/libc/68020/68881/sinh.s3
-rwxr-xr-xsys/src/libc/68020/68881/sqrt.s3
-rwxr-xr-xsys/src/libc/68020/68881/tan.s3
-rwxr-xr-xsys/src/libc/68020/68881/tanh.s3
-rwxr-xr-xsys/src/libc/68020/argv0.s4
-rwxr-xr-xsys/src/libc/68020/getcallerpc.s3
-rwxr-xr-xsys/src/libc/68020/getfcr.s19
-rwxr-xr-xsys/src/libc/68020/main9.s19
-rwxr-xr-xsys/src/libc/68020/main9p.s32
-rwxr-xr-xsys/src/libc/68020/memccpy.s30
-rwxr-xr-xsys/src/libc/68020/memchr.s15
-rwxr-xr-xsys/src/libc/68020/memcmp.s18
-rwxr-xr-xsys/src/libc/68020/memcpy.s98
-rwxr-xr-xsys/src/libc/68020/memmove.s99
-rwxr-xr-xsys/src/libc/68020/memset.s47
-rwxr-xr-xsys/src/libc/68020/mkfile53
-rwxr-xr-xsys/src/libc/68020/notejmp.c17
-rwxr-xr-xsys/src/libc/68020/scale.s4
-rwxr-xr-xsys/src/libc/68020/setjmp.s15
-rwxr-xr-xsys/src/libc/68020/sqrt.s3
-rwxr-xr-xsys/src/libc/68020/strcat.s15
-rwxr-xr-xsys/src/libc/68020/strchr.s27
-rwxr-xr-xsys/src/libc/68020/strcmp.s20
-rwxr-xr-xsys/src/libc/68020/strcpy.s10
-rwxr-xr-xsys/src/libc/68020/strlen.s18
-rwxr-xr-xsys/src/libc/68020/tas.s9
-rwxr-xr-xsys/src/libc/68020/vlop.s23
-rwxr-xr-xsys/src/libc/68020/vlrt.c730
40 files changed, 1404 insertions, 0 deletions
diff --git a/sys/src/libc/68020/68881/acos.s b/sys/src/libc/68020/68881/acos.s
new file mode 100755
index 000000000..94c995c1f
--- /dev/null
+++ b/sys/src/libc/68020/68881/acos.s
@@ -0,0 +1,3 @@
+ TEXT acos(SB),$0
+ FACOSD a+0(FP),F0
+ RTS
diff --git a/sys/src/libc/68020/68881/asin.s b/sys/src/libc/68020/68881/asin.s
new file mode 100755
index 000000000..068c4ce2e
--- /dev/null
+++ b/sys/src/libc/68020/68881/asin.s
@@ -0,0 +1,3 @@
+ TEXT asin(SB),$0
+ FASIND a+0(FP),F0
+ RTS
diff --git a/sys/src/libc/68020/68881/atan.s b/sys/src/libc/68020/68881/atan.s
new file mode 100755
index 000000000..33f7bd8a4
--- /dev/null
+++ b/sys/src/libc/68020/68881/atan.s
@@ -0,0 +1,3 @@
+ TEXT atan(SB),$0
+ FATAND a+0(FP),F0
+ RTS
diff --git a/sys/src/libc/68020/68881/cos.s b/sys/src/libc/68020/68881/cos.s
new file mode 100755
index 000000000..faacddf30
--- /dev/null
+++ b/sys/src/libc/68020/68881/cos.s
@@ -0,0 +1,3 @@
+ TEXT cos(SB),$0
+ FCOSD a+0(FP),F0
+ RTS
diff --git a/sys/src/libc/68020/68881/cosh.s b/sys/src/libc/68020/68881/cosh.s
new file mode 100755
index 000000000..5269184ec
--- /dev/null
+++ b/sys/src/libc/68020/68881/cosh.s
@@ -0,0 +1,3 @@
+ TEXT cosh(SB),$0
+ FCOSHD a+0(FP),F0
+ RTS
diff --git a/sys/src/libc/68020/68881/exp.s b/sys/src/libc/68020/68881/exp.s
new file mode 100755
index 000000000..530334413
--- /dev/null
+++ b/sys/src/libc/68020/68881/exp.s
@@ -0,0 +1,3 @@
+ TEXT exp(SB),$0
+ FETOXD a+0(FP),F0
+ RTS
diff --git a/sys/src/libc/68020/68881/fabs.s b/sys/src/libc/68020/68881/fabs.s
new file mode 100755
index 000000000..e29620f25
--- /dev/null
+++ b/sys/src/libc/68020/68881/fabs.s
@@ -0,0 +1,3 @@
+ TEXT fabs(SB),$0
+ FABSD a+0(FP),F0
+ RTS
diff --git a/sys/src/libc/68020/68881/log.s b/sys/src/libc/68020/68881/log.s
new file mode 100755
index 000000000..3e39372da
--- /dev/null
+++ b/sys/src/libc/68020/68881/log.s
@@ -0,0 +1,3 @@
+ TEXT log(SB),$0
+ FLOGND a+0(FP),F0
+ RTS
diff --git a/sys/src/libc/68020/68881/log10.s b/sys/src/libc/68020/68881/log10.s
new file mode 100755
index 000000000..92ec78005
--- /dev/null
+++ b/sys/src/libc/68020/68881/log10.s
@@ -0,0 +1,3 @@
+ TEXT log10(SB),$0
+ FLOG10D a+0(FP),F0
+ RTS
diff --git a/sys/src/libc/68020/68881/mkfile b/sys/src/libc/68020/68881/mkfile
new file mode 100755
index 000000000..08ce52c0a
--- /dev/null
+++ b/sys/src/libc/68020/68881/mkfile
@@ -0,0 +1,31 @@
+objtype=68020
+</68020/mkfile
+CFLAGS=-I/sys/ninclude $CFLAGS
+
+LIB=/$objtype/lib/lib68881.a
+SFILES=\
+ acos.s\
+ asin.s\
+ atan.s\
+ cos.s\
+ cosh.s\
+ exp.s\
+ fabs.s\
+ log.s\
+ log10.s\
+ pow10.s\
+ sin.s\
+ sinh.s\
+ sqrt.s\
+ tan.s\
+ tanh.s\
+
+OFILES=${SFILES:%.s=%.$O}
+
+UPDATE=mkfile\
+ $SFILES\
+
+</sys/src/cmd/mksyslib
+
+installall:V:
+ mk install
diff --git a/sys/src/libc/68020/68881/pow10.s b/sys/src/libc/68020/68881/pow10.s
new file mode 100755
index 000000000..cdb83ec51
--- /dev/null
+++ b/sys/src/libc/68020/68881/pow10.s
@@ -0,0 +1,3 @@
+ TEXT pow10(SB),$0
+ FTENTOXL n+0(FP),F0
+ RTS
diff --git a/sys/src/libc/68020/68881/sin.s b/sys/src/libc/68020/68881/sin.s
new file mode 100755
index 000000000..568fab952
--- /dev/null
+++ b/sys/src/libc/68020/68881/sin.s
@@ -0,0 +1,3 @@
+ TEXT sin(SB),$0
+ FSIND a+0(FP),F0
+ RTS
diff --git a/sys/src/libc/68020/68881/sinh.s b/sys/src/libc/68020/68881/sinh.s
new file mode 100755
index 000000000..b05186374
--- /dev/null
+++ b/sys/src/libc/68020/68881/sinh.s
@@ -0,0 +1,3 @@
+ TEXT sinh(SB),$0
+ FSINHD a+0(FP),F0
+ RTS
diff --git a/sys/src/libc/68020/68881/sqrt.s b/sys/src/libc/68020/68881/sqrt.s
new file mode 100755
index 000000000..5109bc255
--- /dev/null
+++ b/sys/src/libc/68020/68881/sqrt.s
@@ -0,0 +1,3 @@
+ TEXT sqrt(SB),$0
+ FSQRTD a+0(FP),F0
+ RTS
diff --git a/sys/src/libc/68020/68881/tan.s b/sys/src/libc/68020/68881/tan.s
new file mode 100755
index 000000000..9cedef2e4
--- /dev/null
+++ b/sys/src/libc/68020/68881/tan.s
@@ -0,0 +1,3 @@
+ TEXT tan(SB),$0
+ FTAND a+0(FP),F0
+ RTS
diff --git a/sys/src/libc/68020/68881/tanh.s b/sys/src/libc/68020/68881/tanh.s
new file mode 100755
index 000000000..2f4e42728
--- /dev/null
+++ b/sys/src/libc/68020/68881/tanh.s
@@ -0,0 +1,3 @@
+ TEXT tanh(SB),$0
+ FTANHD a+0(FP),F0
+ RTS
diff --git a/sys/src/libc/68020/argv0.s b/sys/src/libc/68020/argv0.s
new file mode 100755
index 000000000..8d9f9b29b
--- /dev/null
+++ b/sys/src/libc/68020/argv0.s
@@ -0,0 +1,4 @@
+GLOBL argv0(SB), $4
+GLOBL _tos(SB), $4
+GLOBL _privates(SB), $4
+GLOBL _nprivates(SB), $4
diff --git a/sys/src/libc/68020/getcallerpc.s b/sys/src/libc/68020/getcallerpc.s
new file mode 100755
index 000000000..78f2f9db9
--- /dev/null
+++ b/sys/src/libc/68020/getcallerpc.s
@@ -0,0 +1,3 @@
+TEXT getcallerpc(SB), $0
+ MOVL (a+0(FP)), R0
+ RTS
diff --git a/sys/src/libc/68020/getfcr.s b/sys/src/libc/68020/getfcr.s
new file mode 100755
index 000000000..7f67d038f
--- /dev/null
+++ b/sys/src/libc/68020/getfcr.s
@@ -0,0 +1,19 @@
+TEXT getfsr(SB), $0
+ MOVL $0, R0
+ MOVL FPSR, R0
+ RTS
+
+TEXT setfsr(SB), $0
+ MOVL new+0(FP), R1
+ MOVL R1, FPSR
+ RTS
+
+TEXT getfcr(SB), $0
+ MOVL $0, R0
+ MOVL FPCR, R0
+ RTS
+
+TEXT setfcr(SB), $0
+ MOVL new+0(FP), R1
+ MOVL R1, FPCR
+ RTS
diff --git a/sys/src/libc/68020/main9.s b/sys/src/libc/68020/main9.s
new file mode 100755
index 000000000..38ed7322f
--- /dev/null
+++ b/sys/src/libc/68020/main9.s
@@ -0,0 +1,19 @@
+#define NPRIVATES 16
+
+TEXT _main(SB), 1, $(16 + NPRIVATES*4)
+ MOVL $a6base(SB), A6
+ MOVL R0, _tos(SB)
+ LEA p-64(SP),A0
+ MOVL A0,_privates+0(SB)
+ MOVL $16,R0
+ MOVL R0,_nprivates+0(SB)
+ PEA inargv+0(FP)
+ MOVL inargc-4(FP), TOS
+ BSR main(SB)
+ MOVL $_exits<>+0(SB), R0
+ MOVL R0,TOS
+ BSR exits(SB)
+ RTS
+
+DATA _exits<>+0(SB)/4, $"main"
+GLOBL _exits<>+0(SB), $5
diff --git a/sys/src/libc/68020/main9p.s b/sys/src/libc/68020/main9p.s
new file mode 100755
index 000000000..6c64f6404
--- /dev/null
+++ b/sys/src/libc/68020/main9p.s
@@ -0,0 +1,32 @@
+#define NPRIVATES 16
+
+TEXT _mainp(SB), 1, $(16 + NPRIVATES*4)
+ MOVL $a6base(SB), A6
+ MOVL R0, _tos(SB) /* return value of sys exec!! */
+ LEA p-64(SP),A0
+ MOVL A0,_privates+0(SB)
+ MOVL $16,R0
+ MOVL R0,_nprivates+0(SB)
+ BSR _profmain(SB)
+ MOVL __prof+4(SB), __prof+0(SB)
+ PEA inargv+0(FP)
+ MOVL inargc-4(FP), TOS
+ BSR main(SB)
+
+loop:
+ MOVL $_exits<>+0(SB), R0
+ MOVL R0,TOS
+ BSR exits(SB)
+ LEA _profin(SB), A0 /* force loading of profile */
+ BRA loop
+
+TEXT _savearg(SB), 1, $0
+ RTS
+
+TEXT _callpc(SB), 1, $0
+ MOVL argp+0(FP), A0
+ MOVL 4(A0), R0
+ RTS
+
+DATA _exits<>+0(SB)/4, $"main"
+GLOBL _exits<>+0(SB), $5
diff --git a/sys/src/libc/68020/memccpy.s b/sys/src/libc/68020/memccpy.s
new file mode 100755
index 000000000..3e494e915
--- /dev/null
+++ b/sys/src/libc/68020/memccpy.s
@@ -0,0 +1,30 @@
+ TEXT memccpy(SB),$0
+ MOVL n+12(FP),R0
+ BEQ ret
+ MOVL s1+0(FP),A2
+ MOVL s2+4(FP),A1
+ MOVL c+8(FP),R1
+ BEQ l2
+
+/*
+ * general case
+ */
+l1: MOVB (A1)+,R2
+ MOVB R2,(A2)+
+ CMPB R2,R1
+ BEQ eq
+ SUBL $1,R0
+ BNE l1
+ RTS
+
+/*
+ * special case for null character
+ */
+l2: MOVB (A1)+,(A2)+
+ BEQ eq
+ SUBL $1,R0
+ BNE l2
+ RTS
+
+eq: MOVL A2,R0
+ret: RTS
diff --git a/sys/src/libc/68020/memchr.s b/sys/src/libc/68020/memchr.s
new file mode 100755
index 000000000..ea2584df8
--- /dev/null
+++ b/sys/src/libc/68020/memchr.s
@@ -0,0 +1,15 @@
+ TEXT memchr(SB),$0
+ MOVL n+8(FP),R0
+ BEQ ret
+ MOVL s1+0(FP),A1
+ MOVL c+4(FP),R1
+
+l1: CMPB R1,(A1)+
+ BEQ eq
+ SUBL $1,R0
+ BNE l1
+ RTS
+
+eq: MOVL A1,R0
+ SUBL $1,R0
+ret: RTS
diff --git a/sys/src/libc/68020/memcmp.s b/sys/src/libc/68020/memcmp.s
new file mode 100755
index 000000000..97d208e3b
--- /dev/null
+++ b/sys/src/libc/68020/memcmp.s
@@ -0,0 +1,18 @@
+ TEXT memcmp(SB),$0
+ MOVL n+8(FP),R0
+ BEQ ret
+ MOVL s1+0(FP),A2
+ MOVL s2+4(FP),A1
+
+l1: CMPB (A1)+,(A2)+
+ BNE neq
+ SUBL $1,R0
+ BNE l1
+ RTS
+
+neq: BCS gtr
+ MOVL $-1,R0
+ RTS
+
+gtr: MOVL $1,R0
+ret: RTS
diff --git a/sys/src/libc/68020/memcpy.s b/sys/src/libc/68020/memcpy.s
new file mode 100755
index 000000000..2a37573da
--- /dev/null
+++ b/sys/src/libc/68020/memcpy.s
@@ -0,0 +1,98 @@
+ TEXT memcpy(SB), $0
+
+ MOVL n+8(FP),R0
+ BEQ return
+ BGT ok
+ MOVL 0, R0
+ok:
+ MOVL s1+0(FP),A2
+ MOVL s2+4(FP),A1
+
+ CMPL A2,A1
+ BHI back
+
+/*
+ * speed depends on source allignment
+ * destination allignment is secondary
+ * byte-at-a-time foreward copy to
+ * get source (A1) alligned.
+ */
+f1:
+ MOVL A1, R1
+ ANDL $3, R1
+ BEQ f2
+ SUBL $1, R0
+ BLT return
+ MOVB (A1)+, (A2)+
+ BRA f1
+/*
+ * quad-long-at-a-time forward copy
+ */
+f2:
+ SUBL $16, R0
+ BLT f3
+ MOVL (A1)+, (A2)+
+ MOVL (A1)+, (A2)+
+ MOVL (A1)+, (A2)+
+ MOVL (A1)+, (A2)+
+ BRA f2
+
+/*
+ * cleanup byte-at-a-time
+ */
+f3:
+ ADDL $15, R0
+ BLT return
+f4:
+ MOVB (A1)+, (A2)+
+ SUBL $1, R0
+ BGE f4
+ BRA return
+
+return:
+ MOVL s1+0(FP),R0
+ RTS
+
+/*
+ * everything the same, but
+ * copy backwards
+ */
+back:
+ ADDL R0, A1
+ ADDL R0, A2
+
+/*
+ * byte-at-a-time backward copy to
+ * get source (A1) alligned.
+ */
+b1:
+ MOVL A1, R1
+ ANDL $3, R1
+ BEQ b2
+ SUBL $1, R0
+ BLT return
+ MOVB -(A1), -(A2)
+ BRA b1
+/*
+ * quad-long-at-a-time backward copy
+ */
+b2:
+ SUBL $16, R0
+ BLT b3
+ MOVL -(A1), -(A2)
+ MOVL -(A1), -(A2)
+ MOVL -(A1), -(A2)
+ MOVL -(A1), -(A2)
+ BRA b2
+
+/*
+ * cleanup byte-at-a-time backward
+ */
+b3:
+ ADDL $15, R0
+ BLT return
+b4:
+ MOVB -(A1), -(A2)
+ SUBL $1, R0
+ BGE b4
+ BRA return
diff --git a/sys/src/libc/68020/memmove.s b/sys/src/libc/68020/memmove.s
new file mode 100755
index 000000000..482b3d690
--- /dev/null
+++ b/sys/src/libc/68020/memmove.s
@@ -0,0 +1,99 @@
+ TEXT memmove(SB), $0
+move:
+
+ MOVL n+8(FP),R0
+ BEQ return
+ BGT ok
+ MOVL 0, R0
+ok:
+ MOVL s1+0(FP),A2
+ MOVL s2+4(FP),A1
+
+ CMPL A2,A1
+ BHI back
+
+/*
+ * speed depends on source allignment
+ * destination allignment is secondary
+ * byte-at-a-time foreward copy to
+ * get source (A1) alligned.
+ */
+f1:
+ MOVL A1, R1
+ ANDL $3, R1
+ BEQ f2
+ SUBL $1, R0
+ BLT return
+ MOVB (A1)+, (A2)+
+ BRA f1
+/*
+ * quad-long-at-a-time forward copy
+ */
+f2:
+ SUBL $16, R0
+ BLT f3
+ MOVL (A1)+, (A2)+
+ MOVL (A1)+, (A2)+
+ MOVL (A1)+, (A2)+
+ MOVL (A1)+, (A2)+
+ BRA f2
+
+/*
+ * cleanup byte-at-a-time
+ */
+f3:
+ ADDL $15, R0
+ BLT return
+f4:
+ MOVB (A1)+, (A2)+
+ SUBL $1, R0
+ BGE f4
+ BRA return
+
+return:
+ MOVL s1+0(FP),R0
+ RTS
+
+/*
+ * everything the same, but
+ * copy backwards
+ */
+back:
+ ADDL R0, A1
+ ADDL R0, A2
+
+/*
+ * byte-at-a-time backward copy to
+ * get source (A1) alligned.
+ */
+b1:
+ MOVL A1, R1
+ ANDL $3, R1
+ BEQ b2
+ SUBL $1, R0
+ BLT return
+ MOVB -(A1), -(A2)
+ BRA b1
+/*
+ * quad-long-at-a-time backward copy
+ */
+b2:
+ SUBL $16, R0
+ BLT b3
+ MOVL -(A1), -(A2)
+ MOVL -(A1), -(A2)
+ MOVL -(A1), -(A2)
+ MOVL -(A1), -(A2)
+ BRA b2
+
+/*
+ * cleanup byte-at-a-time backward
+ */
+b3:
+ ADDL $15, R0
+ BLT return
+b4:
+ MOVB -(A1), -(A2)
+ SUBL $1, R0
+ BGE b4
+ BRA return
diff --git a/sys/src/libc/68020/memset.s b/sys/src/libc/68020/memset.s
new file mode 100755
index 000000000..d4b773416
--- /dev/null
+++ b/sys/src/libc/68020/memset.s
@@ -0,0 +1,47 @@
+ TEXT memset(SB), $0
+ MOVL n+8(FP), R0
+ BLE return
+ MOVL s1+0(FP), A1
+ CLRL R1
+ MOVB c+7(FP), R1
+ BEQ l1
+
+/*
+ * create 4 replicated copies
+ * of the byte in R1
+ */
+ MOVL R1, R2
+ ASLL $8, R2
+ ORL R2, R1
+ MOVL R1, R2
+ SWAP R2
+ ORL R2, R1
+
+/*
+ * quad-long-at-a-time set
+ * destination allignment is not
+ * very important.
+ */
+l1:
+ SUBL $16, R0
+ BLT l2
+ MOVL R1, (A1)+
+ MOVL R1, (A1)+
+ MOVL R1, (A1)+
+ MOVL R1, (A1)+
+ BRA l1
+
+/*
+ * cleanup byte-at-a-time
+ */
+l2:
+ ADDL $15, R0
+ BLT return
+l3:
+ MOVB R1, (A1)+
+ SUBL $1, R0
+ BGE l3
+
+return:
+ MOVL s1+0(FP),R0
+ RTS
diff --git a/sys/src/libc/68020/mkfile b/sys/src/libc/68020/mkfile
new file mode 100755
index 000000000..bdd359164
--- /dev/null
+++ b/sys/src/libc/68020/mkfile
@@ -0,0 +1,53 @@
+objtype=68020
+</$objtype/mkfile
+
+LIB=/$objtype/lib/libc.a
+SFILES=\
+ argv0.s\
+ getcallerpc.$O\
+ getfcr.s\
+ main9.s\
+ main9p.s\
+ memccpy.s\
+ memchr.s\
+ memcmp.s\
+ memcpy.s\
+ memmove.s\
+ memset.s\
+ scale.s\
+ setjmp.s\
+ sqrt.s\
+ strcat.s\
+ strchr.s\
+ strcmp.s\
+ strcpy.s\
+ strlen.s\
+ tas.s\
+ vlop.s\
+
+CFILES=\
+ cycles.c\
+ notejmp.c\
+ vlrt.c\
+
+HFILES=/sys/include/libc.h
+
+OFILES=${CFILES:%.c=%.$O} ${SFILES:%.s=%.$O}
+
+UPDATE=mkfile\
+ $HFILES\
+ $CFILES\
+ $SFILES\
+
+</sys/src/cmd/mksyslib
+
+install:V: install.68881
+installall:V:
+ mk install
+clean:V: clean.68881
+nuke:V: clean.68881
+update:V: update.68881
+
+%.68881:V:
+ cd 68881
+ mk $stem
diff --git a/sys/src/libc/68020/notejmp.c b/sys/src/libc/68020/notejmp.c
new file mode 100755
index 000000000..61562d441
--- /dev/null
+++ b/sys/src/libc/68020/notejmp.c
@@ -0,0 +1,17 @@
+#include <u.h>
+#include <libc.h>
+#define UREGVARSZ 4 /* not right but doesn't matter */
+#include <ureg.h>
+
+void
+notejmp(void *vr, jmp_buf j, int ret)
+{
+ struct Ureg *r = vr;
+
+ r->r0 = ret;
+ if(ret == 0)
+ r->r0 = 1;
+ r->pc = j[JMPBUFPC];
+ r->usp = j[JMPBUFSP] + 4;
+ noted(NCONT);
+}
diff --git a/sys/src/libc/68020/scale.s b/sys/src/libc/68020/scale.s
new file mode 100755
index 000000000..0e0e50a86
--- /dev/null
+++ b/sys/src/libc/68020/scale.s
@@ -0,0 +1,4 @@
+ TEXT fscale(SB), $0
+ FMOVED a+0(FP), F0
+ FSCALEL x+8(FP), F0
+ RTS
diff --git a/sys/src/libc/68020/setjmp.s b/sys/src/libc/68020/setjmp.s
new file mode 100755
index 000000000..827b71fc1
--- /dev/null
+++ b/sys/src/libc/68020/setjmp.s
@@ -0,0 +1,15 @@
+TEXT setjmp(SB), 1, $0
+ MOVL b+0(FP), A0
+ MOVL A7, (A0)+
+ MOVL (A7), (A0)
+ CLRL R0
+ RTS
+
+TEXT longjmp(SB), 1, $0
+ MOVL b+0(FP), A0
+ MOVL r+4(FP), R0
+ BNE ok /* ansi: "longjmp(0) => longjmp(1)" */
+ MOVL $1, R0 /* bless their pointed heads */
+ok: MOVL (A0)+, A7
+ MOVL (A0), (A7)
+ RTS
diff --git a/sys/src/libc/68020/sqrt.s b/sys/src/libc/68020/sqrt.s
new file mode 100755
index 000000000..5109bc255
--- /dev/null
+++ b/sys/src/libc/68020/sqrt.s
@@ -0,0 +1,3 @@
+ TEXT sqrt(SB),$0
+ FSQRTD a+0(FP),F0
+ RTS
diff --git a/sys/src/libc/68020/strcat.s b/sys/src/libc/68020/strcat.s
new file mode 100755
index 000000000..95821408b
--- /dev/null
+++ b/sys/src/libc/68020/strcat.s
@@ -0,0 +1,15 @@
+ TEXT strcat(SB), $0
+ MOVL s1+0(FP), A2
+ MOVL s2+4(FP), A1
+
+l1: TSTB (A2)+
+ BNE l1
+
+ MOVB (A1)+, -1(A2)
+ BEQ done
+
+l2: MOVB (A1)+, (A2)+
+ BNE l2
+
+done: MOVL s1+0(FP), R0
+ RTS
diff --git a/sys/src/libc/68020/strchr.s b/sys/src/libc/68020/strchr.s
new file mode 100755
index 000000000..a5d4be2c6
--- /dev/null
+++ b/sys/src/libc/68020/strchr.s
@@ -0,0 +1,27 @@
+ TEXT strchr(SB), $0
+
+ MOVL s+0(FP), A0
+ MOVB c+7(FP), R2
+ BEQ null
+
+l:
+ MOVB (A0)+, R1
+ BEQ out
+ CMPB R1, R2
+ BNE l
+
+ MOVL A0, R0
+ ADDL $-1, R0
+ RTS
+
+out:
+ CLRL R0
+ RTS
+
+null:
+ TSTB (A0)+
+ BNE null
+
+ MOVL A0, R0
+ ADDL $-1, R0
+ RTS
diff --git a/sys/src/libc/68020/strcmp.s b/sys/src/libc/68020/strcmp.s
new file mode 100755
index 000000000..c6072efd7
--- /dev/null
+++ b/sys/src/libc/68020/strcmp.s
@@ -0,0 +1,20 @@
+ TEXT strcmp(SB), $0
+ MOVL s1+0(FP), A2
+ MOVL s2+4(FP), A1
+
+l1: MOVB (A1)+, R0
+ BEQ end
+ CMPB R0, (A2)+
+ BEQ l1
+
+ BCS gtr
+ MOVL $-1, R0
+ RTS
+
+gtr: MOVL $1, R0
+ RTS
+
+end: TSTB (A2)
+ BNE gtr
+ CLRL R0
+ RTS
diff --git a/sys/src/libc/68020/strcpy.s b/sys/src/libc/68020/strcpy.s
new file mode 100755
index 000000000..ce5c30bdb
--- /dev/null
+++ b/sys/src/libc/68020/strcpy.s
@@ -0,0 +1,10 @@
+ TEXT strcpy(SB), $0
+
+ MOVL s1+0(FP), A2
+ MOVL s2+4(FP), A1
+
+l1: MOVB (A1)+, (A2)+
+ BNE l1
+
+ MOVL s1+0(FP), R0
+ RTS
diff --git a/sys/src/libc/68020/strlen.s b/sys/src/libc/68020/strlen.s
new file mode 100755
index 000000000..4d787c704
--- /dev/null
+++ b/sys/src/libc/68020/strlen.s
@@ -0,0 +1,18 @@
+ TEXT strlen(SB), $0
+ MOVL s+0(FP), A1
+
+ TSTB (A1)+
+ BEQ null
+ MOVL A1, A2
+
+l1:
+ TSTB (A1)+
+ BNE l1
+
+ SUBL A2, A1
+ MOVL A1, R0
+ RTS
+
+null:
+ MOVL $0, R0
+ RTS
diff --git a/sys/src/libc/68020/tas.s b/sys/src/libc/68020/tas.s
new file mode 100755
index 000000000..769472f71
--- /dev/null
+++ b/sys/src/libc/68020/tas.s
@@ -0,0 +1,9 @@
+TEXT _tas(SB), $0
+
+ MOVL $0, R0
+ MOVL a+0(FP), A0
+ TAS (A0)
+ BEQ tas_1
+ MOVL $1, R0
+tas_1:
+ RTS
diff --git a/sys/src/libc/68020/vlop.s b/sys/src/libc/68020/vlop.s
new file mode 100755
index 000000000..2f34fd645
--- /dev/null
+++ b/sys/src/libc/68020/vlop.s
@@ -0,0 +1,23 @@
+TEXT _mulv(SB), $0
+ MOVL r+0(FP), A0
+ MOVL a+8(FP), R0
+
+ WORD $0x4c2f
+ WORD $0x0401
+ WORD $0x0014
+/*
+ * MULUL b+16(FP), R0:R1
+ * philw made me do it!
+ */
+
+ MOVL a+4(FP), R2
+ MULUL b+16(FP), R2
+ ADDL R2, R1
+
+ MOVL a+8(FP), R2
+ MULUL b+12(FP), R2
+ ADDL R2, R1
+
+ MOVL R1, (A0)+
+ MOVL R0, (A0)
+ RTS
diff --git a/sys/src/libc/68020/vlrt.c b/sys/src/libc/68020/vlrt.c
new file mode 100755
index 000000000..cfad2afc0
--- /dev/null
+++ b/sys/src/libc/68020/vlrt.c
@@ -0,0 +1,730 @@
+typedef unsigned long ulong;
+typedef unsigned int uint;
+typedef unsigned short ushort;
+typedef unsigned char uchar;
+typedef signed char schar;
+
+#define SIGN(n) (1UL<<(n-1))
+
+typedef struct Vlong Vlong;
+struct Vlong
+{
+ union
+ {
+ struct
+ {
+ ulong hi;
+ ulong lo;
+ };
+ struct
+ {
+ ushort hims;
+ ushort hils;
+ ushort loms;
+ ushort lols;
+ };
+ };
+};
+
+void abort(void);
+
+void
+_addv(Vlong *r, Vlong a, Vlong b)
+{
+ ulong lo, hi;
+
+ lo = a.lo + b.lo;
+ hi = a.hi + b.hi;
+ if(lo < a.lo)
+ hi++;
+ r->lo = lo;
+ r->hi = hi;
+}
+
+void
+_subv(Vlong *r, Vlong a, Vlong b)
+{
+ ulong lo, hi;
+
+ lo = a.lo - b.lo;
+ hi = a.hi - b.hi;
+ if(lo > a.lo)
+ hi--;
+ r->lo = lo;
+ r->hi = hi;
+}
+
+void
+_d2v(Vlong *y, double d)
+{
+ union { double d; struct Vlong; } x;
+ ulong xhi, xlo, ylo, yhi;
+ int sh;
+
+ x.d = d;
+
+ xhi = (x.hi & 0xfffff) | 0x100000;
+ xlo = x.lo;
+ sh = 1075 - ((x.hi >> 20) & 0x7ff);
+
+ ylo = 0;
+ yhi = 0;
+ if(sh >= 0) {
+ /* v = (hi||lo) >> sh */
+ if(sh < 32) {
+ if(sh == 0) {
+ ylo = xlo;
+ yhi = xhi;
+ } else {
+ ylo = (xlo >> sh) | (xhi << (32-sh));
+ yhi = xhi >> sh;
+ }
+ } else {
+ if(sh == 32) {
+ ylo = xhi;
+ } else
+ if(sh < 64) {
+ ylo = xhi >> (sh-32);
+ }
+ }
+ } else {
+ /* v = (hi||lo) << -sh */
+ sh = -sh;
+ if(sh <= 10) {
+ ylo = xlo << sh;
+ yhi = (xhi << sh) | (xlo >> (32-sh));
+ } else {
+ /* overflow */
+ yhi = d; /* causes something awful */
+ }
+ }
+ if(x.hi & SIGN(32)) {
+ if(ylo != 0) {
+ ylo = -ylo;
+ yhi = ~yhi;
+ } else
+ yhi = -yhi;
+ }
+
+ y->hi = yhi;
+ y->lo = ylo;
+}
+
+void
+_f2v(Vlong *y, float f)
+{
+
+ _d2v(y, f);
+}
+
+double
+_v2d(Vlong x)
+{
+ if(x.hi & SIGN(32)) {
+ if(x.lo) {
+ x.lo = -x.lo;
+ x.hi = ~x.hi;
+ } else
+ x.hi = -x.hi;
+ return -((long)x.hi*4294967296. + x.lo);
+ }
+ return (long)x.hi*4294967296. + x.lo;
+}
+
+float
+_v2f(Vlong x)
+{
+ return _v2d(x);
+}
+
+static void
+dodiv(Vlong num, Vlong den, Vlong *q, Vlong *r)
+{
+ ulong numlo, numhi, denhi, denlo, quohi, quolo, t;
+ int i;
+
+ numhi = num.hi;
+ numlo = num.lo;
+ denhi = den.hi;
+ denlo = den.lo;
+
+ /*
+ * get a divide by zero
+ */
+ if(denlo==0 && denhi==0) {
+ numlo = numlo / denlo;
+ }
+
+ /*
+ * set up the divisor and find the number of iterations needed
+ */
+ if(numhi >= SIGN(32)) {
+ quohi = SIGN(32);
+ quolo = 0;
+ } else {
+ quohi = numhi;
+ quolo = numlo;
+ }
+ i = 0;
+ while(denhi < quohi || (denhi == quohi && denlo < quolo)) {
+ denhi = (denhi<<1) | (denlo>>31);
+ denlo <<= 1;
+ i++;
+ }
+
+ quohi = 0;
+ quolo = 0;
+ for(; i >= 0; i--) {
+ quohi = (quohi<<1) | (quolo>>31);
+ quolo <<= 1;
+ if(numhi > denhi || (numhi == denhi && numlo >= denlo)) {
+ t = numlo;
+ numlo -= denlo;
+ if(numlo > t)
+ numhi--;
+ numhi -= denhi;
+ quolo |= 1;
+ }
+ denlo = (denlo>>1) | (denhi<<31);
+ denhi >>= 1;
+ }
+
+ if(q) {
+ q->lo = quolo;
+ q->hi = quohi;
+ }
+ if(r) {
+ r->lo = numlo;
+ r->hi = numhi;
+ }
+}
+
+void
+_divvu(Vlong *q, Vlong n, Vlong d)
+{
+
+ if(n.hi == 0 && d.hi == 0) {
+ q->hi = 0;
+ q->lo = n.lo / d.lo;
+ return;
+ }
+ dodiv(n, d, q, 0);
+}
+
+void
+_modvu(Vlong *r, Vlong n, Vlong d)
+{
+
+ if(n.hi == 0 && d.hi == 0) {
+ r->hi = 0;
+ r->lo = n.lo % d.lo;
+ return;
+ }
+ dodiv(n, d, 0, r);
+}
+
+static void
+vneg(Vlong *v)
+{
+
+ if(v->lo == 0) {
+ v->hi = -v->hi;
+ return;
+ }
+ v->lo = -v->lo;
+ v->hi = ~v->hi;
+}
+
+void
+_divv(Vlong *q, Vlong n, Vlong d)
+{
+ long nneg, dneg;
+
+ if(n.hi == (((long)n.lo)>>31) && d.hi == (((long)d.lo)>>31)) {
+ q->lo = (long)n.lo / (long)d.lo;
+ q->hi = ((long)q->lo) >> 31;
+ return;
+ }
+ nneg = n.hi >> 31;
+ if(nneg)
+ vneg(&n);
+ dneg = d.hi >> 31;
+ if(dneg)
+ vneg(&d);
+ dodiv(n, d, q, 0);
+ if(nneg != dneg)
+ vneg(q);
+}
+
+void
+_modv(Vlong *r, Vlong n, Vlong d)
+{
+ long nneg, dneg;
+
+ if(n.hi == (((long)n.lo)>>31) && d.hi == (((long)d.lo)>>31)) {
+ r->lo = (long)n.lo % (long)d.lo;
+ r->hi = ((long)r->lo) >> 31;
+ return;
+ }
+ nneg = n.hi >> 31;
+ if(nneg)
+ vneg(&n);
+ dneg = d.hi >> 31;
+ if(dneg)
+ vneg(&d);
+ dodiv(n, d, 0, r);
+ if(nneg)
+ vneg(r);
+}
+
+void
+_rshav(Vlong *r, Vlong a, int b)
+{
+ long t;
+
+ t = a.hi;
+ if(b >= 32) {
+ r->hi = t>>31;
+ if(b >= 64) {
+ /* this is illegal re C standard */
+ r->lo = t>>31;
+ return;
+ }
+ r->lo = t >> (b-32);
+ return;
+ }
+ if(b <= 0) {
+ r->hi = t;
+ r->lo = a.lo;
+ return;
+ }
+ r->hi = t >> b;
+ r->lo = (t << (32-b)) | (a.lo >> b);
+}
+
+void
+_rshlv(Vlong *r, Vlong a, int b)
+{
+ ulong t;
+
+ t = a.hi;
+ if(b >= 32) {
+ r->hi = 0;
+ if(b >= 64) {
+ /* this is illegal re C standard */
+ r->lo = 0;
+ return;
+ }
+ r->lo = t >> (b-32);
+ return;
+ }
+ if(b <= 0) {
+ r->hi = t;
+ r->lo = a.lo;
+ return;
+ }
+ r->hi = t >> b;
+ r->lo = (t << (32-b)) | (a.lo >> b);
+}
+
+void
+_lshv(Vlong *r, Vlong a, int b)
+{
+ ulong t;
+
+ t = a.lo;
+ if(b >= 32) {
+ r->lo = 0;
+ if(b >= 64) {
+ /* this is illegal re C standard */
+ r->hi = 0;
+ return;
+ }
+ r->hi = t << (b-32);
+ return;
+ }
+ if(b <= 0) {
+ r->lo = t;
+ r->hi = a.hi;
+ return;
+ }
+ r->lo = t << b;
+ r->hi = (t >> (32-b)) | (a.hi << b);
+}
+
+void
+_andv(Vlong *r, Vlong a, Vlong b)
+{
+ r->hi = a.hi & b.hi;
+ r->lo = a.lo & b.lo;
+}
+
+void
+_orv(Vlong *r, Vlong a, Vlong b)
+{
+ r->hi = a.hi | b.hi;
+ r->lo = a.lo | b.lo;
+}
+
+void
+_xorv(Vlong *r, Vlong a, Vlong b)
+{
+ r->hi = a.hi ^ b.hi;
+ r->lo = a.lo ^ b.lo;
+}
+
+void
+_negv(Vlong *r, Vlong a)
+{
+ if(a.lo == 0) {
+ r->hi = -a.hi;
+ r->lo = 0;
+ return;
+ }
+ r->hi = ~a.hi;
+ r->lo = -a.lo;
+}
+
+void
+_vpp(Vlong *l, Vlong *r)
+{
+
+ l->hi = r->hi;
+ l->lo = r->lo;
+ r->lo++;
+ if(r->lo == 0)
+ r->hi++;
+}
+
+void
+_vmm(Vlong *l, Vlong *r)
+{
+
+ l->hi = r->hi;
+ l->lo = r->lo;
+ if(r->lo == 0)
+ r->hi--;
+ r->lo--;
+}
+
+void
+_ppv(Vlong *l, Vlong *r)
+{
+
+ r->lo++;
+ if(r->lo == 0)
+ r->hi++;
+ l->hi = r->hi;
+ l->lo = r->lo;
+}
+
+void
+_mmv(Vlong *l, Vlong *r)
+{
+
+ if(r->lo == 0)
+ r->hi--;
+ r->lo--;
+ l->hi = r->hi;
+ l->lo = r->lo;
+}
+
+void
+_vasop(Vlong *ret, void *lv, void fn(Vlong*, Vlong, Vlong), int type, Vlong rv)
+{
+ Vlong t, u;
+
+ u = *ret;
+ switch(type) {
+ default:
+ abort();
+ break;
+
+ case 1: /* schar */
+ t.lo = *(schar*)lv;
+ t.hi = t.lo >> 31;
+ fn(&u, t, rv);
+ *(schar*)lv = u.lo;
+ break;
+
+ case 2: /* uchar */
+ t.lo = *(uchar*)lv;
+ t.hi = 0;
+ fn(&u, t, rv);
+ *(uchar*)lv = u.lo;
+ break;
+
+ case 3: /* short */
+ t.lo = *(short*)lv;
+ t.hi = t.lo >> 31;
+ fn(&u, t, rv);
+ *(short*)lv = u.lo;
+ break;
+
+ case 4: /* ushort */
+ t.lo = *(ushort*)lv;
+ t.hi = 0;
+ fn(&u, t, rv);
+ *(ushort*)lv = u.lo;
+ break;
+
+ case 9: /* int */
+ t.lo = *(int*)lv;
+ t.hi = t.lo >> 31;
+ fn(&u, t, rv);
+ *(int*)lv = u.lo;
+ break;
+
+ case 10: /* uint */
+ t.lo = *(uint*)lv;
+ t.hi = 0;
+ fn(&u, t, rv);
+ *(uint*)lv = u.lo;
+ break;
+
+ case 5: /* long */
+ t.lo = *(long*)lv;
+ t.hi = t.lo >> 31;
+ fn(&u, t, rv);
+ *(long*)lv = u.lo;
+ break;
+
+ case 6: /* ulong */
+ t.lo = *(ulong*)lv;
+ t.hi = 0;
+ fn(&u, t, rv);
+ *(ulong*)lv = u.lo;
+ break;
+
+ case 7: /* vlong */
+ case 8: /* uvlong */
+ fn(&u, *(Vlong*)lv, rv);
+ *(Vlong*)lv = u;
+ break;
+ }
+ *ret = u;
+}
+
+void
+_p2v(Vlong *ret, void *p)
+{
+ long t;
+
+ t = (ulong)p;
+ ret->lo = t;
+ ret->hi = 0;
+}
+
+void
+_sl2v(Vlong *ret, long sl)
+{
+ long t;
+
+ t = sl;
+ ret->lo = t;
+ ret->hi = t >> 31;
+}
+
+void
+_ul2v(Vlong *ret, ulong ul)
+{
+ long t;
+
+ t = ul;
+ ret->lo = t;
+ ret->hi = 0;
+}
+
+void
+_si2v(Vlong *ret, int si)
+{
+ long t;
+
+ t = si;
+ ret->lo = t;
+ ret->hi = t >> 31;
+}
+
+void
+_ui2v(Vlong *ret, uint ui)
+{
+ long t;
+
+ t = ui;
+ ret->lo = t;
+ ret->hi = 0;
+}
+
+void
+_sh2v(Vlong *ret, long sh)
+{
+ long t;
+
+ t = (sh << 16) >> 16;
+ ret->lo = t;
+ ret->hi = t >> 31;
+}
+
+void
+_uh2v(Vlong *ret, ulong ul)
+{
+ long t;
+
+ t = ul & 0xffff;
+ ret->lo = t;
+ ret->hi = 0;
+}
+
+void
+_sc2v(Vlong *ret, long uc)
+{
+ long t;
+
+ t = (uc << 24) >> 24;
+ ret->lo = t;
+ ret->hi = t >> 31;
+}
+
+void
+_uc2v(Vlong *ret, ulong ul)
+{
+ long t;
+
+ t = ul & 0xff;
+ ret->lo = t;
+ ret->hi = 0;
+}
+
+long
+_v2sc(Vlong rv)
+{
+ long t;
+
+ t = rv.lo & 0xff;
+ return (t << 24) >> 24;
+}
+
+long
+_v2uc(Vlong rv)
+{
+
+ return rv.lo & 0xff;
+}
+
+long
+_v2sh(Vlong rv)
+{
+ long t;
+
+ t = rv.lo & 0xffff;
+ return (t << 16) >> 16;
+}
+
+long
+_v2uh(Vlong rv)
+{
+
+ return rv.lo & 0xffff;
+}
+
+long
+_v2sl(Vlong rv)
+{
+
+ return rv.lo;
+}
+
+long
+_v2ul(Vlong rv)
+{
+
+ return rv.lo;
+}
+
+long
+_v2si(Vlong rv)
+{
+
+ return rv.lo;
+}
+
+long
+_v2ui(Vlong rv)
+{
+
+ return rv.lo;
+}
+
+int
+_testv(Vlong rv)
+{
+ return rv.lo || rv.hi;
+}
+
+int
+_eqv(Vlong lv, Vlong rv)
+{
+ return lv.lo == rv.lo && lv.hi == rv.hi;
+}
+
+int
+_nev(Vlong lv, Vlong rv)
+{
+ return lv.lo != rv.lo || lv.hi != rv.hi;
+}
+
+int
+_ltv(Vlong lv, Vlong rv)
+{
+ return (long)lv.hi < (long)rv.hi ||
+ (lv.hi == rv.hi && lv.lo < rv.lo);
+}
+
+int
+_lev(Vlong lv, Vlong rv)
+{
+ return (long)lv.hi < (long)rv.hi ||
+ (lv.hi == rv.hi && lv.lo <= rv.lo);
+}
+
+int
+_gtv(Vlong lv, Vlong rv)
+{
+ return (long)lv.hi > (long)rv.hi ||
+ (lv.hi == rv.hi && lv.lo > rv.lo);
+}
+
+int
+_gev(Vlong lv, Vlong rv)
+{
+ return (long)lv.hi > (long)rv.hi ||
+ (lv.hi == rv.hi && lv.lo >= rv.lo);
+}
+
+int
+_lov(Vlong lv, Vlong rv)
+{
+ return lv.hi < rv.hi ||
+ (lv.hi == rv.hi && lv.lo < rv.lo);
+}
+
+int
+_lsv(Vlong lv, Vlong rv)
+{
+ return lv.hi < rv.hi ||
+ (lv.hi == rv.hi && lv.lo <= rv.lo);
+}
+
+int
+_hiv(Vlong lv, Vlong rv)
+{
+ return lv.hi > rv.hi ||
+ (lv.hi == rv.hi && lv.lo > rv.lo);
+}
+
+int
+_hsv(Vlong lv, Vlong rv)
+{
+ return lv.hi > rv.hi ||
+ (lv.hi == rv.hi && lv.lo >= rv.lo);
+}