diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/libc/68020 |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/libc/68020')
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); +} |