summaryrefslogtreecommitdiff
path: root/sys/src/libc/386
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/386
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/libc/386')
-rwxr-xr-xsys/src/libc/386/387/asin.s40
-rwxr-xr-xsys/src/libc/386/387/atan.s5
-rwxr-xr-xsys/src/libc/386/387/atan2.s5
-rwxr-xr-xsys/src/libc/386/387/exp.s13
-rwxr-xr-xsys/src/libc/386/387/log.s31
-rwxr-xr-xsys/src/libc/386/387/mkfile14
-rwxr-xr-xsys/src/libc/386/387/sin.s9
-rwxr-xr-xsys/src/libc/386/387/sqrt.s16
-rwxr-xr-xsys/src/libc/386/387/tan.s5
-rwxr-xr-xsys/src/libc/386/argv0.s4
-rwxr-xr-xsys/src/libc/386/atom.s75
-rwxr-xr-xsys/src/libc/386/cycles.s8
-rwxr-xr-xsys/src/libc/386/getcallerpc.s4
-rwxr-xr-xsys/src/libc/386/getfcr.s27
-rwxr-xr-xsys/src/libc/386/main9.s21
-rwxr-xr-xsys/src/libc/386/main9p.s38
-rwxr-xr-xsys/src/libc/386/memccpy.s53
-rwxr-xr-xsys/src/libc/386/memchr.s23
-rwxr-xr-xsys/src/libc/386/memcmp.s47
-rwxr-xr-xsys/src/libc/386/memcpy.s57
-rwxr-xr-xsys/src/libc/386/memmove.s71
-rwxr-xr-xsys/src/libc/386/memset.s35
-rwxr-xr-xsys/src/libc/386/mkfile42
-rwxr-xr-xsys/src/libc/386/muldiv.s12
-rwxr-xr-xsys/src/libc/386/notejmp.c16
-rwxr-xr-xsys/src/libc/386/setjmp.s18
-rwxr-xr-xsys/src/libc/386/sqrt.s16
-rwxr-xr-xsys/src/libc/386/strcat.s43
-rwxr-xr-xsys/src/libc/386/strchr.s38
-rwxr-xr-xsys/src/libc/386/strcpy.s35
-rwxr-xr-xsys/src/libc/386/strlen.s16
-rwxr-xr-xsys/src/libc/386/tas.s6
-rwxr-xr-xsys/src/libc/386/vlop.s54
-rwxr-xr-xsys/src/libc/386/vlrt.c746
34 files changed, 1643 insertions, 0 deletions
diff --git a/sys/src/libc/386/387/asin.s b/sys/src/libc/386/387/asin.s
new file mode 100755
index 000000000..6c91d1fe3
--- /dev/null
+++ b/sys/src/libc/386/387/asin.s
@@ -0,0 +1,40 @@
+TEXT asin(SB), $0
+ FMOVD a+0(FP), F0 /* a */
+ FMOVD F0, F0 /* a,a */
+ FMULD F0, F0 /* a*a,a */
+ FLD1 /* 1,a*a,a */
+ FSUBRDP F0, F1 /* 1-a*a,a */
+
+ FTST
+ WAIT
+ FSTSW AX
+ SAHF
+ JLO bad
+
+ FSQRT /* sqrt(1-a*a),a */
+ FPATAN /* atan2(sqrt(1-a*a),a) */
+ RET
+
+TEXT acos(SB), $0
+ FMOVD a+0(FP), F0
+ FMOVD F0, F0
+ FMULD F0, F0
+ FLD1
+ FSUBRDP F0, F1
+
+ FTST
+ WAIT
+ FSTSW AX
+ SAHF
+ JLO bad
+
+ FSQRT
+ FXCHD F0, F1 /* identical except this */
+ FPATAN
+ RET
+
+bad:
+ FMOVDP F0, F0
+ FMOVDP F0, F0
+ CALL NaN(SB)
+ RET
diff --git a/sys/src/libc/386/387/atan.s b/sys/src/libc/386/387/atan.s
new file mode 100755
index 000000000..65496f2b6
--- /dev/null
+++ b/sys/src/libc/386/387/atan.s
@@ -0,0 +1,5 @@
+TEXT atan(SB), $0
+ FMOVD a+0(FP), F0
+ FLD1
+ FPATAN
+ RET
diff --git a/sys/src/libc/386/387/atan2.s b/sys/src/libc/386/387/atan2.s
new file mode 100755
index 000000000..00ca36e01
--- /dev/null
+++ b/sys/src/libc/386/387/atan2.s
@@ -0,0 +1,5 @@
+TEXT atan2(SB), $0
+ FMOVD a+0(FP), F0
+ FMOVD b+8(FP), F0
+ FPATAN
+ RET
diff --git a/sys/src/libc/386/387/exp.s b/sys/src/libc/386/387/exp.s
new file mode 100755
index 000000000..0c73465ab
--- /dev/null
+++ b/sys/src/libc/386/387/exp.s
@@ -0,0 +1,13 @@
+TEXT exp(SB), $0
+ FLDL2E
+ FMULD a+0(FP), F0 /* now we want 2^ this number */
+
+ FMOVD F0, F0 /* x, x */
+ FRNDINT /* ix, x -- this is best in round mode */
+ FSUBD F0, F1 /* ix, fx */
+ FXCHD F0, F1 /* fx, ix */
+ F2XM1 /* 2^fx-1, ix */
+ FADDD $1.0, F0 /* 2^fx, ix */
+ FSCALE /* 2^(fx+ix), ix */
+ FMOVDP F0, F1 /* 2^(fx+ix) == 2^x */
+ RET
diff --git a/sys/src/libc/386/387/log.s b/sys/src/libc/386/387/log.s
new file mode 100755
index 000000000..f53c05eb1
--- /dev/null
+++ b/sys/src/libc/386/387/log.s
@@ -0,0 +1,31 @@
+TEXT log(SB), $0
+ FMOVD $0.69314718055994530941, F0
+ FMOVD a+0(FP), F0
+
+ FTST
+ WAIT
+ FSTSW AX
+ SAHF
+ JLO bad
+
+ FYL2X
+ RET
+
+TEXT log10(SB), $0
+ FMOVD $0.30102999566398119521, F0
+ FMOVD a+0(FP), F0
+
+ FTST
+ WAIT
+ FSTSW AX
+ SAHF
+ JLO bad
+
+ FYL2X
+ RET
+
+bad:
+ FMOVDP F0, F0
+ FMOVDP F0, F0
+ CALL NaN(SB)
+ RET
diff --git a/sys/src/libc/386/387/mkfile b/sys/src/libc/386/387/mkfile
new file mode 100755
index 000000000..05343b63e
--- /dev/null
+++ b/sys/src/libc/386/387/mkfile
@@ -0,0 +1,14 @@
+</$objtype/mkfile
+
+LIB=/$objtype/lib/lib387.a
+
+OFILES=\
+ atan.$O\
+ tan.$O\
+ atan2.$O\
+ exp.$O\
+ asin.$O\
+ log.$O\
+ sin.$O\
+
+</sys/src/cmd/mksyslib
diff --git a/sys/src/libc/386/387/sin.s b/sys/src/libc/386/387/sin.s
new file mode 100755
index 000000000..998a63ff4
--- /dev/null
+++ b/sys/src/libc/386/387/sin.s
@@ -0,0 +1,9 @@
+TEXT sin(SB), $0
+ FMOVD a+0(FP), F0
+ FSIN
+ RET
+
+TEXT cos(SB), $0
+ FMOVD a+0(FP), F0
+ FCOS
+ RET
diff --git a/sys/src/libc/386/387/sqrt.s b/sys/src/libc/386/387/sqrt.s
new file mode 100755
index 000000000..219a8ac6b
--- /dev/null
+++ b/sys/src/libc/386/387/sqrt.s
@@ -0,0 +1,16 @@
+TEXT sqrt(SB), $0
+ FMOVD a+0(FP), F0
+
+ FTST
+ WAIT
+ FSTSW AX
+ SAHF
+ JLO bad
+
+ FSQRT
+ RET
+
+bad:
+ FMOVDP F0, F0
+ CALL NaN(SB)
+ RET
diff --git a/sys/src/libc/386/387/tan.s b/sys/src/libc/386/387/tan.s
new file mode 100755
index 000000000..01d9cdab1
--- /dev/null
+++ b/sys/src/libc/386/387/tan.s
@@ -0,0 +1,5 @@
+TEXT tan(SB), $0
+ FMOVD a+0(FP), F0
+ FPTAN
+ FMOVDP F0, F0 /* get rid of extra 1.0 */
+ RET
diff --git a/sys/src/libc/386/argv0.s b/sys/src/libc/386/argv0.s
new file mode 100755
index 000000000..8d9f9b29b
--- /dev/null
+++ b/sys/src/libc/386/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/386/atom.s b/sys/src/libc/386/atom.s
new file mode 100755
index 000000000..8fd8c75d0
--- /dev/null
+++ b/sys/src/libc/386/atom.s
@@ -0,0 +1,75 @@
+TEXT ainc(SB), $0 /* long ainc(long *); */
+ MOVL addr+0(FP), BX
+ainclp:
+ MOVL (BX), AX
+ MOVL AX, CX
+ INCL CX
+ LOCK
+ BYTE $0x0F; BYTE $0xB1; BYTE $0x0B /* CMPXCHGL CX, (BX) */
+ JNZ ainclp
+ MOVL CX, AX
+ RET
+
+TEXT adec(SB), $0 /* long adec(long*); */
+ MOVL addr+0(FP), BX
+adeclp:
+ MOVL (BX), AX
+ MOVL AX, CX
+ DECL CX
+ LOCK
+ BYTE $0x0F; BYTE $0xB1; BYTE $0x0B /* CMPXCHGL CX, (BX) */
+ JNZ adeclp
+ MOVL CX, AX
+ RET
+
+/*
+ * int cas32(u32int *p, u32int ov, u32int nv);
+ * int cas(uint *p, int ov, int nv);
+ * int casp(void **p, void *ov, void *nv);
+ * int casl(ulong *p, ulong ov, ulong nv);
+ */
+
+/*
+ * CMPXCHG (CX), DX: 0000 1111 1011 000w oorr rmmm,
+ * mmm = CX = 001; rrr = DX = 010
+ */
+
+#define CMPXCHG BYTE $0x0F; BYTE $0xB1; BYTE $0x11
+
+TEXT cas32+0(SB),0,$0
+TEXT cas+0(SB),0,$0
+TEXT casp+0(SB),0,$0
+TEXT casl+0(SB),0,$0
+ MOVL p+0(FP), CX
+ MOVL ov+4(FP), AX
+ MOVL nv+8(FP), DX
+ LOCK
+ CMPXCHG
+ JNE fail
+ MOVL $1,AX
+ RET
+fail:
+ MOVL $0,AX
+ RET
+
+/*
+ * int cas64(u64int *p, u64int ov, u64int nv);
+ */
+
+/*
+ * CMPXCHG64 (DI): 0000 1111 1100 0111 0000 1110,
+ */
+
+#define CMPXCHG64 BYTE $0x0F; BYTE $0xC7; BYTE $0x0F
+
+TEXT cas64+0(SB),0,$0
+ MOVL p+0(FP), DI
+ MOVL ov+0x4(FP), AX
+ MOVL ov+0x8(FP), DX
+ MOVL nv+0xc(FP), BX
+ MOVL nv+0x10(FP), CX
+ LOCK
+ CMPXCHG64
+ JNE fail
+ MOVL $1,AX
+ RET
diff --git a/sys/src/libc/386/cycles.s b/sys/src/libc/386/cycles.s
new file mode 100755
index 000000000..7f8810261
--- /dev/null
+++ b/sys/src/libc/386/cycles.s
@@ -0,0 +1,8 @@
+#define RDTSC BYTE $0x0F; BYTE $0x31
+
+TEXT cycles(SB),1,$0 /* time stamp counter; cycles since power up */
+ RDTSC
+ MOVL vlong+0(FP), CX /* &vlong */
+ MOVL AX, 0(CX) /* lo */
+ MOVL DX, 4(CX) /* hi */
+ RET
diff --git a/sys/src/libc/386/getcallerpc.s b/sys/src/libc/386/getcallerpc.s
new file mode 100755
index 000000000..bc4a5f1ea
--- /dev/null
+++ b/sys/src/libc/386/getcallerpc.s
@@ -0,0 +1,4 @@
+TEXT getcallerpc(SB), $0
+ MOVL v+0(FP), AX
+ MOVL -4(AX), AX
+ RET
diff --git a/sys/src/libc/386/getfcr.s b/sys/src/libc/386/getfcr.s
new file mode 100755
index 000000000..f646c369c
--- /dev/null
+++ b/sys/src/libc/386/getfcr.s
@@ -0,0 +1,27 @@
+
+TEXT setfcr(SB), $4
+ MOVL p+0(FP),AX
+ XORB $0x3f,AX
+ MOVW AX, 0(SP)
+ WAIT
+ FLDCW 0(SP)
+ MOVW 0(SP), AX
+ RET
+
+TEXT getfcr(SB), $4
+ MOVW AX, 0(SP)
+ WAIT
+ FSTCW 0(SP)
+ MOVW 0(SP), AX
+ XORB $0x3f,AX
+ RET
+
+TEXT getfsr(SB), $0
+ WAIT
+ FSTSW AX
+ RET
+
+TEXT setfsr(SB), $0
+ WAIT
+ FCLEX
+ RET
diff --git a/sys/src/libc/386/main9.s b/sys/src/libc/386/main9.s
new file mode 100755
index 000000000..ced3efde6
--- /dev/null
+++ b/sys/src/libc/386/main9.s
@@ -0,0 +1,21 @@
+#define NPRIVATES 16
+
+TEXT _main(SB), 1, $(8+NPRIVATES*4)
+ MOVL AX, _tos(SB)
+ LEAL 8(SP), AX
+ MOVL AX, _privates(SB)
+ MOVL $NPRIVATES, _nprivates(SB)
+ MOVL inargc-4(FP), AX
+ MOVL AX, 0(SP)
+ LEAL inargv+0(FP), AX
+ MOVL AX, 4(SP)
+ CALL main(SB)
+
+loop:
+ MOVL $_exits<>(SB), AX
+ MOVL AX, 0(SP)
+ CALL exits(SB)
+ JMP loop
+
+DATA _exits<>+0(SB)/4, $"main"
+GLOBL _exits<>+0(SB), $5
diff --git a/sys/src/libc/386/main9p.s b/sys/src/libc/386/main9p.s
new file mode 100755
index 000000000..a924d0aff
--- /dev/null
+++ b/sys/src/libc/386/main9p.s
@@ -0,0 +1,38 @@
+#define NPRIVATES 16
+
+TEXT _mainp(SB), 1, $(8+NPRIVATES*4)
+ /* _tos = arg */
+ MOVL AX, _tos(SB)
+ LEAL 8(SP), AX
+ MOVL AX, _privates(SB)
+ MOVL $NPRIVATES, _nprivates(SB)
+ /* _profmain(); */
+ CALL _profmain(SB)
+ /* _tos->prof.pp = _tos->prof.next; */
+ MOVL _tos+0(SB),DX
+ MOVL 4(DX),CX
+ MOVL CX,(DX)
+ /* main(argc, argv); */
+ MOVL inargc-4(FP), AX
+ MOVL AX, 0(SP)
+ LEAL inargv+0(FP), AX
+ MOVL AX, 4(SP)
+ CALL main(SB)
+
+loop:
+ MOVL $_exits<>(SB), AX
+ MOVL AX, 0(SP)
+ CALL exits(SB)
+ MOVL $_profin(SB), AX /* force loading of profile */
+ JMP loop
+
+TEXT _savearg(SB), 1, $0
+ RET
+
+TEXT _callpc(SB), 1, $0
+ MOVL argp+0(FP), AX
+ MOVL 4(AX), AX
+ RET
+
+DATA _exits<>+0(SB)/4, $"main"
+GLOBL _exits<>+0(SB), $5
diff --git a/sys/src/libc/386/memccpy.s b/sys/src/libc/386/memccpy.s
new file mode 100755
index 000000000..52af6a9cf
--- /dev/null
+++ b/sys/src/libc/386/memccpy.s
@@ -0,0 +1,53 @@
+ TEXT memccpy(SB),$0
+
+ MOVL n+12(FP), CX
+ CMPL CX, $0
+ JEQ none
+ MOVL p2+4(FP), DI
+ MOVBLZX c+8(FP), AX
+ CLD
+/*
+ * find the character in the second string
+ */
+
+ REPN; SCASB
+ JEQ found
+
+/*
+ * if not found, set count to 'n'
+ */
+none:
+ MOVL $0, AX
+ MOVL n+12(FP), BX
+ JMP memcpy
+
+/*
+ * if found, set count to bytes thru character
+ */
+found:
+ MOVL DI, AX
+ SUBL p2+4(FP), AX
+ MOVL AX, BX
+ ADDL p1+0(FP), AX
+
+/*
+ * copy the memory
+ */
+
+memcpy:
+ MOVL p1+0(FP), DI
+ MOVL p2+4(FP), SI
+/*
+ * copy whole longs
+ */
+ MOVL BX, CX
+ SHRL $2, CX
+ REP; MOVSL
+/*
+ * copy the rest, by bytes
+ */
+ ANDL $3, BX
+ MOVL BX, CX
+ REP; MOVSB
+
+ RET
diff --git a/sys/src/libc/386/memchr.s b/sys/src/libc/386/memchr.s
new file mode 100755
index 000000000..23a1982a3
--- /dev/null
+++ b/sys/src/libc/386/memchr.s
@@ -0,0 +1,23 @@
+ TEXT memchr(SB),$0
+
+ MOVL n+8(FP), CX
+ CMPL CX, $0
+ JEQ none
+ MOVL p+0(FP), DI
+ MOVBLZX c+4(FP), AX
+ CLD
+/*
+ * SCASB is memchr instruction
+ */
+
+ REPN; SCASB
+ JEQ found
+
+none:
+ MOVL $0, AX
+ RET
+
+found:
+ MOVL DI, AX
+ SUBL $1, AX
+ RET
diff --git a/sys/src/libc/386/memcmp.s b/sys/src/libc/386/memcmp.s
new file mode 100755
index 000000000..4e9d090cf
--- /dev/null
+++ b/sys/src/libc/386/memcmp.s
@@ -0,0 +1,47 @@
+ TEXT memcmp(SB),$0
+
+ MOVL n+8(FP), BX
+ CMPL BX, $0
+ JEQ none
+ MOVL p1+0(FP), DI
+ MOVL p2+4(FP), SI
+ CLD
+/*
+ * first by longs
+ */
+
+ MOVL BX, CX
+ SHRL $2, CX
+
+ REP; CMPSL
+ JNE found
+
+/*
+ * then by bytes
+ */
+ ANDL $3, BX
+ MOVL BX, CX
+ REP; CMPSB
+ JNE found1
+
+none:
+ MOVL $0, AX
+ RET
+
+/*
+ * if long found,
+ * back up and look by bytes
+ */
+found:
+ MOVL $4, CX
+ SUBL CX, DI
+ SUBL CX, SI
+ REP; CMPSB
+
+found1:
+ JLS lt
+ MOVL $-1, AX
+ RET
+lt:
+ MOVL $1, AX
+ RET
diff --git a/sys/src/libc/386/memcpy.s b/sys/src/libc/386/memcpy.s
new file mode 100755
index 000000000..bb9cfe40c
--- /dev/null
+++ b/sys/src/libc/386/memcpy.s
@@ -0,0 +1,57 @@
+ TEXT memcpy(SB), $0
+
+ MOVL p1+0(FP), DI
+ MOVL p2+4(FP), SI
+ MOVL n+8(FP), BX
+ CMPL BX, $0
+ JGE ok
+ MOVL $0, SI
+ok:
+ CLD
+/*
+ * check and set for backwards
+ */
+ CMPL SI, DI
+ JLS back
+/*
+ * copy whole longs
+ */
+ MOVL BX, CX
+ SHRL $2, CX
+ REP; MOVSL
+/*
+ * copy the rest, by bytes
+ */
+ ANDL $3, BX
+ MOVL BX, CX
+ REP; MOVSB
+
+ MOVL p+0(FP),AX
+ RET
+/*
+ * whole thing backwards has
+ * adjusted addresses
+ */
+back:
+ ADDL BX, DI
+ ADDL BX, SI
+ SUBL $4, DI
+ SUBL $4, SI
+ STD
+/*
+ * copy whole longs
+ */
+ MOVL BX, CX
+ SHRL $2, CX
+ ANDL $3, BX
+ REP; MOVSL
+/*
+ * copy the rest, by bytes
+ */
+ ADDL $3, DI
+ ADDL $3, SI
+ MOVL BX, CX
+ REP; MOVSB
+
+ MOVL p+0(FP),AX
+ RET
diff --git a/sys/src/libc/386/memmove.s b/sys/src/libc/386/memmove.s
new file mode 100755
index 000000000..90eee75c1
--- /dev/null
+++ b/sys/src/libc/386/memmove.s
@@ -0,0 +1,71 @@
+TEXT memmove(SB), $0
+ MOVL p1+0(FP), DI
+ MOVL DI, AX /* return value */
+ MOVL p2+4(FP), SI
+ MOVL n+8(FP), BX
+ CMPL BX, $0
+ JGT _ok
+ JEQ _return /* nothing to do if n == 0 */
+ MOVL $0, SI /* fault if n < 0 */
+
+/*
+ * check and set for backwards:
+ * (p2 < p1) && ((p2+n) > p1)
+ */
+_ok:
+ CMPL SI, DI
+ JGT _forward
+ JEQ _return /* nothing to do if p2 == p1 */
+ MOVL SI, DX
+ ADDL BX, DX
+ CMPL DX, DI
+ JGT _back
+
+/*
+ * copy whole longs
+ */
+_forward:
+ MOVL BX, CX
+ CLD
+ SHRL $2, CX
+ ANDL $3, BX
+ REP; MOVSL
+
+/*
+ * copy the rest, by bytes
+ */
+ JEQ _return /* flags set by above ANDL */
+ MOVL BX, CX
+ REP; MOVSB
+
+ RET
+
+/*
+ * whole thing backwards has
+ * adjusted addresses
+ */
+_back:
+ ADDL BX, DI
+ ADDL BX, SI
+ STD
+ SUBL $4, DI
+ SUBL $4, SI
+/*
+ * copy whole longs
+ */
+ MOVL BX, CX
+ SHRL $2, CX
+ ANDL $3, BX
+ REP; MOVSL
+/*
+ * copy the rest, by bytes
+ */
+ JEQ _return /* flags set by above ANDL */
+
+ ADDL $3, DI
+ ADDL $3, SI
+ MOVL BX, CX
+ REP; MOVSB
+
+_return:
+ RET
diff --git a/sys/src/libc/386/memset.s b/sys/src/libc/386/memset.s
new file mode 100755
index 000000000..6e482abee
--- /dev/null
+++ b/sys/src/libc/386/memset.s
@@ -0,0 +1,35 @@
+ TEXT memset(SB),$0
+
+ CLD
+ MOVL p+0(FP), DI
+ MOVBLZX c+4(FP), AX
+ MOVL n+8(FP), BX
+/*
+ * if not enough bytes, just set bytes
+ */
+ CMPL BX, $9
+ JLS c3
+/*
+ * build word in AX
+ */
+ MOVB AL, AH
+ MOVL AX, CX
+ SHLL $16, CX
+ ORL CX, AX
+/*
+ * set whole longs
+ */
+c1:
+ MOVL BX, CX
+ SHRL $2, CX
+ ANDL $3, BX
+ REP; STOSL
+/*
+ * set the rest, by bytes
+ */
+c3:
+ MOVL BX, CX
+ REP; STOSB
+ret:
+ MOVL p+0(FP),AX
+ RET
diff --git a/sys/src/libc/386/mkfile b/sys/src/libc/386/mkfile
new file mode 100755
index 000000000..417ea5ffb
--- /dev/null
+++ b/sys/src/libc/386/mkfile
@@ -0,0 +1,42 @@
+objtype=386
+</$objtype/mkfile
+
+LIB=/$objtype/lib/libc.a
+SFILES=\
+ argv0.s\
+ atom.s\
+ getfcr.s\
+ main9.s\
+ main9p.s\
+ memccpy.s\
+ memchr.s\
+ memcmp.s\
+ memcpy.s\
+ memmove.s\
+ memset.s\
+ muldiv.s\
+ cycles.s\
+ setjmp.s\
+ sqrt.s\
+ strcat.s\
+ strchr.s\
+ strcpy.s\
+ strlen.s\
+ tas.s\
+ vlop.s\
+
+CFILES=\
+ getcallerpc.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
diff --git a/sys/src/libc/386/muldiv.s b/sys/src/libc/386/muldiv.s
new file mode 100755
index 000000000..5f11a97e6
--- /dev/null
+++ b/sys/src/libc/386/muldiv.s
@@ -0,0 +1,12 @@
+TEXT umuldiv(SB), $0
+ MOVL a+0(FP), AX
+ MULL b+4(FP)
+ DIVL c+8(FP)
+ RET
+
+TEXT muldiv(SB), $0
+ MOVL a+0(FP), AX
+ IMULL b+4(FP)
+ IDIVL c+8(FP)
+ RET
+ END
diff --git a/sys/src/libc/386/notejmp.c b/sys/src/libc/386/notejmp.c
new file mode 100755
index 000000000..5d912767d
--- /dev/null
+++ b/sys/src/libc/386/notejmp.c
@@ -0,0 +1,16 @@
+#include <u.h>
+#include <libc.h>
+#include <ureg.h>
+
+void
+notejmp(void *vr, jmp_buf j, int ret)
+{
+ struct Ureg *r = vr;
+
+ r->ax = ret;
+ if(ret == 0)
+ r->ax = 1;
+ r->pc = j[JMPBUFPC];
+ r->sp = j[JMPBUFSP] + 4;
+ noted(NCONT);
+}
diff --git a/sys/src/libc/386/setjmp.s b/sys/src/libc/386/setjmp.s
new file mode 100755
index 000000000..697fa7359
--- /dev/null
+++ b/sys/src/libc/386/setjmp.s
@@ -0,0 +1,18 @@
+TEXT longjmp(SB), $0
+ MOVL r+4(FP), AX
+ CMPL AX, $0
+ JNE ok /* ansi: "longjmp(0) => longjmp(1)" */
+ MOVL $1, AX /* bless their pointed heads */
+ok: MOVL l+0(FP), BX
+ MOVL 0(BX), SP /* restore sp */
+ MOVL 4(BX), BX /* put return pc on the stack */
+ MOVL BX, 0(SP)
+ RET
+
+TEXT setjmp(SB), $0
+ MOVL l+0(FP), AX
+ MOVL SP, 0(AX) /* store sp */
+ MOVL 0(SP), BX /* store return pc */
+ MOVL BX, 4(AX)
+ MOVL $0, AX /* return 0 */
+ RET
diff --git a/sys/src/libc/386/sqrt.s b/sys/src/libc/386/sqrt.s
new file mode 100755
index 000000000..219a8ac6b
--- /dev/null
+++ b/sys/src/libc/386/sqrt.s
@@ -0,0 +1,16 @@
+TEXT sqrt(SB), $0
+ FMOVD a+0(FP), F0
+
+ FTST
+ WAIT
+ FSTSW AX
+ SAHF
+ JLO bad
+
+ FSQRT
+ RET
+
+bad:
+ FMOVDP F0, F0
+ CALL NaN(SB)
+ RET
diff --git a/sys/src/libc/386/strcat.s b/sys/src/libc/386/strcat.s
new file mode 100755
index 000000000..3f41fefa5
--- /dev/null
+++ b/sys/src/libc/386/strcat.s
@@ -0,0 +1,43 @@
+ TEXT strcat(SB),$0
+
+ MOVL $0, AX
+ MOVL $-1, CX
+ CLD
+
+/*
+ * find length of second string
+ */
+
+ MOVL p2+4(FP), DI
+ REPN; SCASB
+
+ MOVL DI, BX
+ SUBL p2+4(FP), BX
+
+/*
+ * find end of first string
+ */
+
+ MOVL p1+0(FP), DI
+ REPN; SCASB
+
+/*
+ * copy the memory
+ */
+ SUBL $1, DI
+ MOVL p2+4(FP), SI
+/*
+ * copy whole longs
+ */
+ MOVL BX, CX
+ SHRL $2, CX
+ REP; MOVSL
+/*
+ * copy the rest, by bytes
+ */
+ ANDL $3, BX
+ MOVL BX, CX
+ REP; MOVSB
+
+ MOVL p1+0(FP), AX
+ RET
diff --git a/sys/src/libc/386/strchr.s b/sys/src/libc/386/strchr.s
new file mode 100755
index 000000000..873bdcf12
--- /dev/null
+++ b/sys/src/libc/386/strchr.s
@@ -0,0 +1,38 @@
+ TEXT strchr(SB), $0
+
+ MOVL s+0(FP), DI
+ MOVB c+4(FP), AX
+ CMPB AX, $0
+ JEQ l2 /**/
+
+/*
+ * char is not null
+ */
+l1:
+ MOVB (DI), BX
+ CMPB BX, $0
+ JEQ ret0
+ ADDL $1, DI
+ CMPB AX, BX
+ JNE l1
+
+ MOVL DI, AX
+ SUBL $1, AX
+ RET
+
+/*
+ * char is null
+ */
+l2:
+ MOVL $-1, CX
+ CLD
+
+ REPN; SCASB
+
+ MOVL DI, AX
+ SUBL $1, AX
+ RET
+
+ret0:
+ MOVL $0, AX
+ RET
diff --git a/sys/src/libc/386/strcpy.s b/sys/src/libc/386/strcpy.s
new file mode 100755
index 000000000..83482e8a2
--- /dev/null
+++ b/sys/src/libc/386/strcpy.s
@@ -0,0 +1,35 @@
+ TEXT strcpy(SB),$0
+
+ MOVL $0, AX
+ MOVL $-1, CX
+ CLD
+/*
+ * find end of second string
+ */
+
+ MOVL p2+4(FP), DI
+ REPN; SCASB
+
+ MOVL DI, BX
+ SUBL p2+4(FP), BX
+
+/*
+ * copy the memory
+ */
+ MOVL p1+0(FP), DI
+ MOVL p2+4(FP), SI
+/*
+ * copy whole longs
+ */
+ MOVL BX, CX
+ SHRL $2, CX
+ REP; MOVSL
+/*
+ * copy the rest, by bytes
+ */
+ ANDL $3, BX
+ MOVL BX, CX
+ REP; MOVSB
+
+ MOVL p1+0(FP), AX
+ RET
diff --git a/sys/src/libc/386/strlen.s b/sys/src/libc/386/strlen.s
new file mode 100755
index 000000000..e0330ffcc
--- /dev/null
+++ b/sys/src/libc/386/strlen.s
@@ -0,0 +1,16 @@
+ TEXT strlen(SB),$0
+
+ MOVL $0, AX
+ MOVL $-1, CX
+ CLD
+/*
+ * look for end of string
+ */
+
+ MOVL p+0(FP), DI
+ REPN; SCASB
+
+ MOVL DI, AX
+ SUBL p+0(FP), AX
+ SUBL $1, AX
+ RET
diff --git a/sys/src/libc/386/tas.s b/sys/src/libc/386/tas.s
new file mode 100755
index 000000000..9649dcacf
--- /dev/null
+++ b/sys/src/libc/386/tas.s
@@ -0,0 +1,6 @@
+TEXT _tas(SB),$0
+
+ MOVL $0xdeadead,AX
+ MOVL l+0(FP),BX
+ XCHGL AX,(BX)
+ RET
diff --git a/sys/src/libc/386/vlop.s b/sys/src/libc/386/vlop.s
new file mode 100755
index 000000000..1ad69f274
--- /dev/null
+++ b/sys/src/libc/386/vlop.s
@@ -0,0 +1,54 @@
+TEXT _mulv(SB), $0
+ MOVL r+0(FP), CX
+ MOVL a+4(FP), AX
+ MULL b+12(FP)
+ MOVL AX, 0(CX)
+ MOVL DX, BX
+ MOVL a+4(FP), AX
+ MULL b+16(FP)
+ ADDL AX, BX
+ MOVL a+8(FP), AX
+ MULL b+12(FP)
+ ADDL AX, BX
+ MOVL BX, 4(CX)
+ RET
+
+TEXT _mul64by32(SB), $0
+ MOVL r+0(FP), CX
+ MOVL a+4(FP), AX
+ MULL b+12(FP)
+ MOVL AX, 0(CX)
+ MOVL DX, BX
+ MOVL a+8(FP), AX
+ MULL b+12(FP)
+ ADDL AX, BX
+ MOVL BX, 4(CX)
+ RET
+
+TEXT _div64by32(SB), $0
+ MOVL r+12(FP), CX
+ MOVL a+0(FP), AX
+ MOVL a+4(FP), DX
+ DIVL b+8(FP)
+ MOVL DX, 0(CX)
+ RET
+
+TEXT _addv(SB),1,$0 /* used in profiler, can't be profiled */
+ MOVL r+0(FP), CX
+ MOVL a+4(FP), AX
+ MOVL a+8(FP), BX
+ ADDL b+12(FP), AX
+ ADCL b+16(FP), BX
+ MOVL AX, 0(CX)
+ MOVL BX, 4(CX)
+ RET
+
+TEXT _subv(SB),1,$0 /* used in profiler, can't be profiled */
+ MOVL r+0(FP), CX
+ MOVL a+4(FP), AX
+ MOVL a+8(FP), BX
+ SUBL b+12(FP), AX
+ SBBL b+16(FP), BX
+ MOVL AX, 0(CX)
+ MOVL BX, 4(CX)
+ RET
diff --git a/sys/src/libc/386/vlrt.c b/sys/src/libc/386/vlrt.c
new file mode 100755
index 000000000..83fd09683
--- /dev/null
+++ b/sys/src/libc/386/vlrt.c
@@ -0,0 +1,746 @@
+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 lo;
+ ulong hi;
+ };
+ struct
+ {
+ ushort lols;
+ ushort loms;
+ ushort hils;
+ ushort hims;
+ };
+ };
+};
+
+void abort(void);
+
+void _subv(Vlong*, Vlong, Vlong);
+
+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);
+}
+
+ulong _div64by32(Vlong, ulong, ulong*);
+void _mul64by32(Vlong*, Vlong, ulong);
+
+static void
+slowdodiv(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;
+ }
+}
+
+static void
+dodiv(Vlong num, Vlong den, Vlong *qp, Vlong *rp)
+{
+ ulong n;
+ Vlong x, q, r;
+
+ if(den.hi > num.hi || (den.hi == num.hi && den.lo > num.lo)){
+ if(qp) {
+ qp->hi = 0;
+ qp->lo = 0;
+ }
+ if(rp) {
+ rp->hi = num.hi;
+ rp->lo = num.lo;
+ }
+ return;
+ }
+
+ if(den.hi != 0){
+ q.hi = 0;
+ n = num.hi/den.hi;
+ _mul64by32(&x, den, n);
+ if(x.hi > num.hi || (x.hi == num.hi && x.lo > num.lo))
+ slowdodiv(num, den, &q, &r);
+ else {
+ q.lo = n;
+ _subv(&r, num, x);
+ }
+ } else {
+ if(num.hi >= den.lo){
+ q.hi = n = num.hi/den.lo;
+ num.hi -= den.lo*n;
+ } else {
+ q.hi = 0;
+ }
+ q.lo = _div64by32(num, den.lo, &r.lo);
+ r.hi = 0;
+ }
+ if(qp) {
+ qp->lo = q.lo;
+ qp->hi = q.hi;
+ }
+ if(rp) {
+ rp->lo = r.lo;
+ rp->hi = r.hi;
+ }
+}
+
+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
+_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.lo = 0;
+ u.hi = 0;
+ 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);
+}