From e5888a1ffdae813d7575f5fb02275c6bb07e5199 Mon Sep 17 00:00:00 2001 From: Taru Karttunen Date: Wed, 30 Mar 2011 15:46:40 +0300 Subject: Import sources from 2011-03-30 iso image --- sys/src/ape/lib/ap/sparc/cycles.c | 5 + sys/src/ape/lib/ap/sparc/lock.c | 26 ++ sys/src/ape/lib/ap/sparc/main9.s | 14 + sys/src/ape/lib/ap/sparc/main9p.s | 53 +++ sys/src/ape/lib/ap/sparc/memchr.s | 26 ++ sys/src/ape/lib/ap/sparc/memcmp.s | 122 ++++++ sys/src/ape/lib/ap/sparc/memmove.s | 169 +++++++++ sys/src/ape/lib/ap/sparc/memset.s | 88 +++++ sys/src/ape/lib/ap/sparc/mkfile | 26 ++ sys/src/ape/lib/ap/sparc/muldiv.s | 310 +++++++++++++++ sys/src/ape/lib/ap/sparc/notetramp.c | 81 ++++ sys/src/ape/lib/ap/sparc/setjmp.s | 36 ++ sys/src/ape/lib/ap/sparc/strchr.s | 73 ++++ sys/src/ape/lib/ap/sparc/strcmp.s | 27 ++ sys/src/ape/lib/ap/sparc/strcpy.s | 84 ++++ sys/src/ape/lib/ap/sparc/tas.s | 7 + sys/src/ape/lib/ap/sparc/vlop.s | 112 ++++++ sys/src/ape/lib/ap/sparc/vlrt.c | 718 +++++++++++++++++++++++++++++++++++ 18 files changed, 1977 insertions(+) create mode 100755 sys/src/ape/lib/ap/sparc/cycles.c create mode 100755 sys/src/ape/lib/ap/sparc/lock.c create mode 100755 sys/src/ape/lib/ap/sparc/main9.s create mode 100755 sys/src/ape/lib/ap/sparc/main9p.s create mode 100755 sys/src/ape/lib/ap/sparc/memchr.s create mode 100755 sys/src/ape/lib/ap/sparc/memcmp.s create mode 100755 sys/src/ape/lib/ap/sparc/memmove.s create mode 100755 sys/src/ape/lib/ap/sparc/memset.s create mode 100755 sys/src/ape/lib/ap/sparc/mkfile create mode 100755 sys/src/ape/lib/ap/sparc/muldiv.s create mode 100755 sys/src/ape/lib/ap/sparc/notetramp.c create mode 100755 sys/src/ape/lib/ap/sparc/setjmp.s create mode 100755 sys/src/ape/lib/ap/sparc/strchr.s create mode 100755 sys/src/ape/lib/ap/sparc/strcmp.s create mode 100755 sys/src/ape/lib/ap/sparc/strcpy.s create mode 100755 sys/src/ape/lib/ap/sparc/tas.s create mode 100755 sys/src/ape/lib/ap/sparc/vlop.s create mode 100755 sys/src/ape/lib/ap/sparc/vlrt.c (limited to 'sys/src/ape/lib/ap/sparc') diff --git a/sys/src/ape/lib/ap/sparc/cycles.c b/sys/src/ape/lib/ap/sparc/cycles.c new file mode 100755 index 000000000..1c32bc732 --- /dev/null +++ b/sys/src/ape/lib/ap/sparc/cycles.c @@ -0,0 +1,5 @@ +void +_cycles(unsigned long long *u) +{ + *u = 0; +} diff --git a/sys/src/ape/lib/ap/sparc/lock.c b/sys/src/ape/lib/ap/sparc/lock.c new file mode 100755 index 000000000..91c0ba233 --- /dev/null +++ b/sys/src/ape/lib/ap/sparc/lock.c @@ -0,0 +1,26 @@ +#define _LOCK_EXTENSION +#include "../plan9/sys9.h" +#include + +int tas(int*); + +void +lock(Lock *lk) +{ + while(tas(&lk->val)) + _SLEEP(0); +} + +int +canlock(Lock *lk) +{ + if(tas(&lk->val)) + return 0; + return 1; +} + +void +unlock(Lock *lk) +{ + lk->val = 0; +} diff --git a/sys/src/ape/lib/ap/sparc/main9.s b/sys/src/ape/lib/ap/sparc/main9.s new file mode 100755 index 000000000..24a9f6f53 --- /dev/null +++ b/sys/src/ape/lib/ap/sparc/main9.s @@ -0,0 +1,14 @@ + TEXT _main(SB), $16 + MOVW $setSB(SB), R2 + JMPL _envsetup(SB) + MOVW inargc-4(FP), R7 + MOVW $inargv+0(FP), R8 + MOVW R7, 4(R1) + MOVW R8, 8(R1) + JMPL main(SB) + +loop: + MOVW R7, 4(R1) + JMPL exit(SB) + MOVW $_mul(SB),R7 + JMP loop diff --git a/sys/src/ape/lib/ap/sparc/main9p.s b/sys/src/ape/lib/ap/sparc/main9p.s new file mode 100755 index 000000000..17cc3e2af --- /dev/null +++ b/sys/src/ape/lib/ap/sparc/main9p.s @@ -0,0 +1,53 @@ +#define NPRIVATES 16 + +GLOBL _tos(SB), $4 +GLOBL _privates(SB), $4 +GLOBL _nprivates(SB), $4 + +TEXT _mainp(SB), 1, $(3*4+NPRIVATES*4) + MOVW $setSB(SB), R2 + + /* _tos = arg */ + MOVW R7, _tos(SB) +/* + MOVW _fpsr+0(SB), FSR + FMOVD $0.5, F26 + FSUBD F26, F26, F24 + FADDD F26, F26, F28 + FADDD F28, F28, F30 +*/ + MOVW $8(SP), R1 + MOVW R1, _privates(SB) + MOVW $NPRIVATES, R1 + MOVW R1, _nprivates(SB) + + /* _profmain(); */ + JMPL _profmain(SB) + + /* _tos->prof.pp = _tos->prof.next; */ + MOVW _tos+0(SB),R7 + MOVW 4(R7),R8 + MOVW R8,(R7) + + JMPL _envsetup(SB) + + /* main(argc, argv, environ); */ + MOVW inargc-4(FP), R7 + MOVW $inargv+0(FP), R8 + MOVW environ(SB), R9 + MOVW R8, 8(R1) + MOVW R9, 12(R1) + JMPL main(SB) + +loop: + JMPL exit(SB) + MOVW $_mul(SB), R0 /* force loading of muldiv */ + MOVW $_profin(SB), R0 /* force loading of profile */ + JMP loop + +TEXT _savearg(SB), 1, $0 + RETURN + +TEXT _callpc(SB), 1, $0 + MOVW argp-4(FP), R7 + RETURN diff --git a/sys/src/ape/lib/ap/sparc/memchr.s b/sys/src/ape/lib/ap/sparc/memchr.s new file mode 100755 index 000000000..81e67f6f2 --- /dev/null +++ b/sys/src/ape/lib/ap/sparc/memchr.s @@ -0,0 +1,26 @@ + TEXT memchr(SB), $0 + +MOVW R7, 0(FP) + MOVW n+8(FP), R7 + SUBCC R0,R7, R0 + BE ret + MOVW s1+0(FP), R8 + MOVBU c+7(FP), R9 + ADD R7,R8, R11 + +l1: + MOVBU (R8), R10 + SUBCC R9,R10, R0 + ADD $1, R8 + BE eq + SUBCC R8,R11, R0 + BNE l1 + + MOVW R0, R7 + RETURN + +eq: + SUB $1,R8, R7 + +ret: + RETURN diff --git a/sys/src/ape/lib/ap/sparc/memcmp.s b/sys/src/ape/lib/ap/sparc/memcmp.s new file mode 100755 index 000000000..2b470d549 --- /dev/null +++ b/sys/src/ape/lib/ap/sparc/memcmp.s @@ -0,0 +1,122 @@ +#define Bxx BE + + TEXT memcmp(SB), $0 + +/* + * performance: + * (tba) + */ + +MOVW R7, 0(FP) + MOVW n+8(FP), R9 /* R9 is count */ + MOVW s1+0(FP), R10 /* R10 is pointer1 */ + MOVW s2+4(FP), R11 /* R11 is pointer2 */ + ADD R9,R10, R12 /* R12 is end pointer1 */ + +/* + * if not at least 4 chars, + * dont even mess around. + * 3 chars to guarantee any + * rounding up to a word + * boundary and 4 characters + * to get at least maybe one + * full word cmp. + */ + SUBCC $4,R9, R0 + BL out + +/* + * test if both pointers + * are similarly word alligned + */ + XOR R10,R11, R7 + ANDCC $3,R7, R0 + BNE out + +/* + * byte at a time to word allign + */ +l1: + ANDCC $3,R10, R0 + BE l2 + MOVB 0(R10), R16 + MOVB 0(R11), R17 + ADD $1, R10 + SUBCC R16,R17, R0 + BNE ne + ADD $1, R11 + JMP l1 + +/* + * turn R9 into end pointer1-15 + * cmp 16 at a time while theres room + */ +l2: + SUB $15,R12, R9 +l3: + SUBCC R10,R9, R0 + BLEU l4 + MOVW 0(R10), R16 + MOVW 0(R11), R17 + MOVW 4(R10), R18 + SUBCC R16,R17, R0 + BNE ne + MOVW 4(R11), R19 + MOVW 8(R10), R16 + SUBCC R18,R19, R0 + BNE ne + MOVW 8(R11), R17 + MOVW 12(R10), R18 + SUBCC R16,R17, R0 + BNE ne + MOVW 12(R11), R19 + ADD $16, R10 + SUBCC R18,R19, R0 + BNE ne + SUBCC R16,R17, R0 + BNE ne + ADD $16, R11 + JMP l3 + +/* + * turn R9 into end pointer1-3 + * cmp 4 at a time while theres room + */ +l4: + SUB $3,R12, R9 +l5: + SUBCC R10,R9, R0 + BLEU out + MOVW 0(R10), R16 + MOVW 0(R11), R17 + ADD $4, R10 + SUBCC R16,R17, R0 /* only works because big endian */ + BNE ne + ADD $4, R11 + JMP l5 + +/* + * last loop, cmp byte at a time + */ +out: + SUBCC R10,R12, R0 + BE zero + MOVB 0(R10), R16 + MOVB 0(R11), R17 + ADD $1, R10 + SUBCC R16,R17, R0 + BNE ne + ADD $1, R11 + JMP out + +ne: + BG plus + MOVW $1, R7 + RETURN +plus: + MOVW $-1, R7 + RETURN + +zero: + MOVW R0, R7 + RETURN diff --git a/sys/src/ape/lib/ap/sparc/memmove.s b/sys/src/ape/lib/ap/sparc/memmove.s new file mode 100755 index 000000000..8879a74e8 --- /dev/null +++ b/sys/src/ape/lib/ap/sparc/memmove.s @@ -0,0 +1,169 @@ + TEXT memmove(SB), $0 + JMP move + + TEXT memcpy(SB), $0 +move: + +/* + * performance: + * (tba) + */ + + MOVW R7, s1+0(FP) + MOVW n+8(FP), R9 /* R9 is count */ + MOVW R7, R10 /* R10 is to-pointer */ + SUBCC R0,R9, R0 + BGE ok + MOVW 0(R0), R0 + +ok: + MOVW s2+4(FP), R11 /* R11 is from-pointer */ + ADD R9,R11, R13 /* R13 is end from-pointer */ + ADD R9,R10, R12 /* R12 is end to-pointer */ + +/* + * easiest test is copy backwards if + * destination string has higher mem address + */ + SUBCC R11,R10, R0 + BGU back + +/* + * if not at least 4 chars, + * dont even mess around. + * 3 chars to guarantee any + * rounding up to a word + * boundary and 4 characters + * to get at least maybe one + * full word store. + */ + SUBCC $4,R9, R0 + BL fout + +/* + * test if both pointers + * are similarly word aligned + */ + XOR R10,R11, R7 + ANDCC $3,R7, R0 + BNE fout + +/* + * byte at a time to word align + */ +f1: + ANDCC $3,R10, R0 + BE f2 + MOVB 0(R11), R16 + ADD $1, R11 + MOVB R16, 0(R10) + ADD $1, R10 + JMP f1 + +/* + * turn R9 into to-end pointer-15 + * copy 16 at a time while theres room. + * R12 is smaller than R13 -- + * there are problems if R13 is 0. + */ +f2: + SUB $15,R12, R9 +f3: + SUBCC R10,R9, R0 + BLEU f4 + MOVW 0(R11), R16 + MOVW 4(R11), R17 + MOVW R16, 0(R10) + MOVW 8(R11), R16 + MOVW R17, 4(R10) + MOVW 12(R11), R17 + ADD $16, R11 + MOVW R16, 8(R10) + MOVW R17, 12(R10) + ADD $16, R10 + JMP f3 + +/* + * turn R9 into to-end pointer-3 + * copy 4 at a time while theres room + */ +f4: + SUB $3,R12, R9 +f5: + SUBCC R10,R9, R0 + BLEU fout + MOVW 0(R11), R16 + ADD $4, R11 + MOVW R16, 0(R10) + ADD $4, R10 + JMP f5 + +/* + * last loop, copy byte at a time + */ +fout: + SUBCC R11,R13, R0 + BLEU ret + MOVB 0(R11), R16 + ADD $1, R11 + MOVB R16, 0(R10) + ADD $1, R10 + JMP fout + +/* + * whole thing repeated for backwards + */ +back: + SUBCC $4,R9, R0 + BL bout + + XOR R12,R13, R7 + ANDCC $3,R7, R0 + BNE bout +b1: + ANDCC $3,R13, R0 + BE b2 + MOVB -1(R13), R16 + SUB $1, R13 + MOVB R16, -1(R12) + SUB $1, R12 + JMP b1 +b2: + ADD $15,R11, R9 +b3: + SUBCC R9,R13, R0 + BLEU b4 + MOVW -4(R13), R16 + MOVW -8(R13), R17 + MOVW R16, -4(R12) + MOVW -12(R13), R16 + MOVW R17, -8(R12) + MOVW -16(R13), R17 + SUB $16, R13 + MOVW R16, -12(R12) + MOVW R17, -16(R12) + SUB $16, R12 + JMP b3 +b4: + ADD $3,R11, R9 +b5: + SUBCC R9,R13, R0 + BLEU bout + MOVW -4(R13), R16 + SUB $4, R13 + MOVW R16, -4(R12) + SUB $4, R12 + JMP b5 + +bout: + SUBCC R11,R13, R0 + BLEU ret + MOVB -1(R13), R16 + SUB $1, R13 + MOVB R16, -1(R12) + SUB $1, R12 + JMP bout + +ret: + MOVW s1+0(FP), R7 + RETURN diff --git a/sys/src/ape/lib/ap/sparc/memset.s b/sys/src/ape/lib/ap/sparc/memset.s new file mode 100755 index 000000000..8c7b26c86 --- /dev/null +++ b/sys/src/ape/lib/ap/sparc/memset.s @@ -0,0 +1,88 @@ + TEXT memset(SB),$0 + +/* + * performance: + * (tba) + */ + +MOVW R7, 0(FP) + MOVW n+8(FP), R9 /* R9 is count */ + MOVW p+0(FP), R10 /* R10 is pointer */ + MOVW c+4(FP), R11 /* R11 is char */ + ADD R9,R10, R12 /* R12 is end pointer */ + +/* + * if not at least 4 chars, + * dont even mess around. + * 3 chars to guarantee any + * rounding up to a word + * boundary and 4 characters + * to get at least maybe one + * full word store. + */ + SUBCC $4,R9, R0 + BL out + +/* + * turn R11 into a word of characters + */ + AND $0xff, R11 + SLL $8,R11, R7 + OR R7, R11 + SLL $16,R11, R7 + OR R7, R11 + +/* + * store one byte at a time until pointer + * is alligned on a word boundary + */ +l1: + ANDCC $3,R10, R0 + BE l2 + MOVB R11, 0(R10) + ADD $1, R10 + JMP l1 + +/* + * turn R9 into end pointer-15 + * store 16 at a time while theres room + */ +l2: + ADD $-15,R12, R9 + SUBCC R10,R9, R0 + BLEU l4 +l3: + MOVW R11, 0(R10) + MOVW R11, 4(R10) + ADD $16, R10 + SUBCC R10,R9, R0 + MOVW R11, -8(R10) + MOVW R11, -4(R10) + BGU l3 + +/* + * turn R9 into end pointer-3 + * store 4 at a time while theres room + */ +l4: + ADD $-3,R12, R9 +l5: + SUBCC R10,R9, R0 + BLEU out + MOVW R11, 0(R10) + ADD $4, R10 + JMP l5 + +/* + * last loop, store byte at a time + */ +out: + SUBCC R10,R12, R0 + BLEU ret + MOVB R11, 0(R10) + ADD $1, R10 + JMP out + +ret: + MOVW s1+0(FP), R7 + RETURN diff --git a/sys/src/ape/lib/ap/sparc/mkfile b/sys/src/ape/lib/ap/sparc/mkfile new file mode 100755 index 000000000..9723ec2c3 --- /dev/null +++ b/sys/src/ape/lib/ap/sparc/mkfile @@ -0,0 +1,26 @@ +APE=/sys/src/ape +<$APE/config +LIB=/$objtype/lib/ape/libap.a +OFILES=\ + cycles.$O\ + lock.$O\ + main9.$O\ + main9p.$O\ + memchr.$O\ + memcmp.$O\ + memmove.$O\ + memset.$O\ + muldiv.$O\ + notetramp.$O\ + setjmp.$O\ + strchr.$O\ + strcmp.$O\ + strcpy.$O\ + tas.$O\ + vlop.$O\ + vlrt.$O\ + + 1<<(32-1)) + * quo = 1<<(32-1); + * for(i=0; den=0; i--) { + * quo <<= 1; + * if(num >= den) { + * num -= den; + * quo |= 1; + * } + * den >>= 1; + * } + * return quo::num; + * } + */ + +#define NOPROF 1 + +/* + * calling sequence: + * num: 4(R1) + * den: 8(R1) + * returns + * quo: 4(R1) + * rem: 8(R1) + */ +TEXT _udivmod(SB), NOPROF, $-4 + + MOVW $(1<<31), R11 + MOVW 4(R1), R13 /* numerator */ + MOVW 8(R1), R10 /* denominator */ + CMP R10, R0 + BNE udm20 + MOVW R0, -1(R0) /* fault -- divide by zero */ +udm20: + MOVW R13, R12 + CMP R13, R11 + BLEU udm34 + MOVW R11, R12 +udm34: + MOVW R0, R11 +udm38: + CMP R10, R12 + BCC udm54 + SLL $1, R10 + ADD $1, R11 + BA udm38 +udm54: + MOVW R0, R12 +udm58: + CMP R11, R0 + BL udm8c + SLL $1, R12 + CMP R13, R10 + BCS udm7c + SUB R10, R13 + OR $1, R12 +udm7c: + SRL $1, R10 + SUB $1, R11 + BA udm58 +udm8c: + MOVW R12, 4(R1) /* quotent */ + MOVW R13, 8(R1) /* remainder */ + JMPL 8(R15) + +/* + * save working registers + * and bring in num/den parameters + */ +TEXT _unsarg(SB), NOPROF, $-4 + MOVW R10, 12(R1) + MOVW R11, 16(R1) + MOVW R12, 20(R1) + MOVW R13, 24(R1) + + MOVW R14, 4(R1) + MOVW 32(R1), R14 + MOVW R14, 8(R1) + + JMPL 8(R15) + +/* + * save working registers + * and bring in absolute value + * of num/den parameters + */ +TEXT _absarg(SB), NOPROF, $-4 + MOVW R10, 12(R1) + MOVW R11, 16(R1) + MOVW R12, 20(R1) + MOVW R13, 24(R1) + + MOVW R14, 28(R1) + CMP R14, R0 + BGE ab1 + SUB R14, R0, R14 +ab1: + MOVW R14, 4(R1) /* numerator */ + + MOVW 32(R1), R14 + CMP R14, R0 + BGE ab2 + SUB R14, R0, R14 +ab2: + MOVW R14, 8(R1) /* denominator */ + JMPL 8(R15) + +/* + * restore registers and + * return to original caller + * answer is in R14 + */ +TEXT _retarg(SB), NOPROF, $-4 + MOVW 12(R1), R10 + MOVW 16(R1), R11 + MOVW 20(R1), R12 + MOVW 24(R1), R13 + MOVW 0(R1), R15 + + ADD $28, R1 + JMP 8(R15) /* back to main sequence */ + +/* + * calling sequence + * num: R14 + * den: 8(R1) + * returns + * quo: R14 + */ +TEXT _div(SB), NOPROF, $-4 + SUB $28, R1 /* 4 reg save, 2 parameters, link */ + MOVW R15, 0(R1) + + JMPL _absarg(SB) + JMPL _udivmod(SB) + MOVW 4(R1), R14 + + MOVW 28(R1), R10 /* clean up the sign */ + MOVW 32(R1), R11 + XORCC R11, R10, R0 + BGE div1 + SUB R14, R0, R14 +div1: + + JMPL _retarg(SB) + JMP 8(R15) /* not executed */ + +/* + * calling sequence + * num: R14 + * den: 8(R1) + * returns + * quo: R14 + */ +TEXT _divl(SB), NOPROF, $-4 + SUB $((4+2+1)*4), R1 /* 4 reg save, 2 parameters, link */ + MOVW R15, 0(R1) + + JMPL _unsarg(SB) + JMPL _udivmod(SB) + MOVW 4(R1), R14 + + JMPL _retarg(SB) + JMP 8(R15) /* not executed */ + +/* + * calling sequence + * num: R14 + * den: 8(R1) + * returns + * rem: R14 + */ +TEXT _mod(SB), NOPROF, $-4 + SUB $28, R1 /* 4 reg save, 2 parameters, link */ + + MOVW R15, 0(R1) + JMPL _absarg(SB) + JMPL _udivmod(SB) + MOVW 8(R1), R14 + + MOVW 28(R1), R10 /* clean up the sign */ + CMP R10, R0 + BGE mod1 + SUB R14, R0, R14 +mod1: + + JMPL _retarg(SB) + JMP 8(R15) /* not executed */ + +/* + * calling sequence + * num: R14 + * den: 8(R1) + * returns + * rem: R14 + */ +TEXT _modl(SB), NOPROF, $-4 + SUB $28, R1 /* 4 reg save, 2 parameters, link */ + + + MOVW R15, 0(R1) + JMPL _unsarg(SB) + JMPL _udivmod(SB) + MOVW 8(R1), R14 + + JMPL _retarg(SB) + JMP 8(R15) /* not executed */ + +/* + * special calling sequence: + * arg1 in R14 + * arg2 in 4(R1), will save R9 + * nothing in 0(R1), will save R8 + * result in R14 + */ +TEXT _mul+0(SB), NOPROF, $-4 + + /* + * exchange stack and registers + */ + MOVW R8, 0(R1) + MOVW 4(R1), R8 + MOVW R9, 4(R1) + + CMP R14, R8 + BLE mul1 + MOVW R14, R9 + MOVW R8, R14 + MOVW R9, R8 +mul1: + MOVW R14, Y + ANDNCC $0xFFF, R14, R0 + BE mul_shortway + ANDCC R0, R0, R9 /* zero partial product and clear N and V cond's */ + + /* long multiply */ + MULSCC R8, R9, R9 /* 0 */ + MULSCC R8, R9, R9 /* 1 */ + MULSCC R8, R9, R9 /* 2 */ + MULSCC R8, R9, R9 /* 3 */ + MULSCC R8, R9, R9 /* 4 */ + MULSCC R8, R9, R9 /* 5 */ + MULSCC R8, R9, R9 /* 6 */ + MULSCC R8, R9, R9 /* 7 */ + MULSCC R8, R9, R9 /* 8 */ + MULSCC R8, R9, R9 /* 9 */ + MULSCC R8, R9, R9 /* 10 */ + MULSCC R8, R9, R9 /* 11 */ + MULSCC R8, R9, R9 /* 12 */ + MULSCC R8, R9, R9 /* 13 */ + MULSCC R8, R9, R9 /* 14 */ + MULSCC R8, R9, R9 /* 15 */ + MULSCC R8, R9, R9 /* 16 */ + MULSCC R8, R9, R9 /* 17 */ + MULSCC R8, R9, R9 /* 18 */ + MULSCC R8, R9, R9 /* 19 */ + MULSCC R8, R9, R9 /* 20 */ + MULSCC R8, R9, R9 /* 21 */ + MULSCC R8, R9, R9 /* 22 */ + MULSCC R8, R9, R9 /* 23 */ + MULSCC R8, R9, R9 /* 24 */ + MULSCC R8, R9, R9 /* 25 */ + MULSCC R8, R9, R9 /* 26 */ + MULSCC R8, R9, R9 /* 27 */ + MULSCC R8, R9, R9 /* 28 */ + MULSCC R8, R9, R9 /* 29 */ + MULSCC R8, R9, R9 /* 30 */ + MULSCC R8, R9, R9 /* 31 */ + MULSCC R0, R9, R9 /* 32; shift only */ + + MOVW Y, R14 /* get low part */ + BA mul_return + +mul_shortway: + ANDCC R0, R0, R9 /* zero partial product and clear N and V cond's */ + MULSCC R8, R9, R9 /* 0 */ + MULSCC R8, R9, R9 /* 1 */ + MULSCC R8, R9, R9 /* 2 */ + MULSCC R8, R9, R9 /* 3 */ + MULSCC R8, R9, R9 /* 4 */ + MULSCC R8, R9, R9 /* 5 */ + MULSCC R8, R9, R9 /* 6 */ + MULSCC R8, R9, R9 /* 7 */ + MULSCC R8, R9, R9 /* 8 */ + MULSCC R8, R9, R9 /* 9 */ + MULSCC R8, R9, R9 /* 10 */ + MULSCC R8, R9, R9 /* 11 */ + MULSCC R0, R9, R9 /* 12; shift only */ + + MOVW Y, R8 + SLL $12, R9 + SRL $20, R8 + OR R8, R9, R14 + +mul_return: + MOVW 0(R1), R8 + MOVW 4(R1), R9 + JMP 8(R15) diff --git a/sys/src/ape/lib/ap/sparc/notetramp.c b/sys/src/ape/lib/ap/sparc/notetramp.c new file mode 100755 index 000000000..c033d62cb --- /dev/null +++ b/sys/src/ape/lib/ap/sparc/notetramp.c @@ -0,0 +1,81 @@ +#include "../plan9/lib.h" +#include "../plan9/sys9.h" +#include +#include + +/* A stack to hold pcs when signals nest */ +#define MAXSIGSTACK 20 +typedef struct Pcstack Pcstack; +static struct Pcstack { + int sig; + void (*hdlr)(int, char*, Ureg*); + unsigned long restorepc; + unsigned long restorenpc; + Ureg *u; +} pcstack[MAXSIGSTACK]; +static int nstack = 0; + +static void notecont(Ureg*, char*); + +void +_notetramp(int sig, void (*hdlr)(int, char*, Ureg*), Ureg *u) +{ + Pcstack *p; + + if(nstack >= MAXSIGSTACK) + _NOTED(1); /* nesting too deep; just do system default */ + p = &pcstack[nstack]; + p->restorepc = u->pc; + p->restorenpc = u->npc; + p->sig = sig; + p->hdlr = hdlr; + p->u = u; + nstack++; + u->pc = (unsigned long) notecont; + u->npc = u->pc+4; + _NOTED(2); /* NSAVE: clear note but hold state */ +} + +static void +notecont(Ureg *u, char *s) +{ + Pcstack *p; + void(*f)(int, char*, Ureg*); + + p = &pcstack[nstack-1]; + f = p->hdlr; + u->pc = p->restorepc; + u->npc = p->restorenpc; + nstack--; + (*f)(p->sig, s, u); + _NOTED(3); /* NRSTR */ +} + +int __noterestore(void); + +#define JMPBUFPC 1 +#define JMPBUFSP 0 +#define JMPBUFDPC (-8) + +extern sigset_t _psigblocked; + +void +siglongjmp(sigjmp_buf j, int ret) +{ + struct Ureg *u; + + if(j[0]) + _psigblocked = j[1]; + if(nstack == 0 || pcstack[nstack-1].u->sp > j[2+JMPBUFSP]) + longjmp(j+2, ret); + u = pcstack[nstack-1].u; + nstack--; + u->r8 = ret; + if(ret == 0) + u->r8 = 1; + u->r9 = j[JMPBUFPC] - JMPBUFDPC; + u->pc = (unsigned long)__noterestore; + u->npc = (unsigned long)__noterestore + 4; + u->sp = j[JMPBUFSP]; + _NOTED(3); /* NRSTR */ +} diff --git a/sys/src/ape/lib/ap/sparc/setjmp.s b/sys/src/ape/lib/ap/sparc/setjmp.s new file mode 100755 index 000000000..8194a1d20 --- /dev/null +++ b/sys/src/ape/lib/ap/sparc/setjmp.s @@ -0,0 +1,36 @@ +TEXT setjmp(SB), 1, $0 + + MOVW R1, (R7) + MOVW R15, 4(R7) + MOVW $0, R7 + RETURN + +TEXT sigsetjmp(SB), 1, $0 + + MOVW savemask+4(FP), R8 + MOVW R8, 0(R7) + MOVW $_psigblocked(SB), R8 + MOVW R8, 4(R7) + MOVW R1, 8(R7) + MOVW R15, 12(R7) + MOVW $0, R7 + RETURN + +TEXT longjmp(SB), 1, $0 + + MOVW R7, R8 + MOVW r+4(FP), R7 + CMP R7, R0 + BNE ok /* ansi: "longjmp(0) => longjmp(1)" */ + MOVW $1, R7 /* bless their pointed heads */ +ok: MOVW (R8), R1 + MOVW 4(R8), R15 + RETURN + +/* + * trampoline functions because the kernel smashes r7 + * in the uregs given to notejmp + */ +TEXT __noterestore(SB), 1, $-4 + MOVW R8, R7 + JMP (R9) diff --git a/sys/src/ape/lib/ap/sparc/strchr.s b/sys/src/ape/lib/ap/sparc/strchr.s new file mode 100755 index 000000000..192beab13 --- /dev/null +++ b/sys/src/ape/lib/ap/sparc/strchr.s @@ -0,0 +1,73 @@ + TEXT strchr(SB), $0 + +MOVW R7, 0(FP) + MOVB c+7(FP), R10 + MOVW s+0(FP), R9 + + SUBCC R0,R10, R0 + BE l2 + +/* + * char is not null + */ +l1: + MOVB (R9), R7 + ADD $1, R9 + SUBCC R0,R7, R0 + BE ret + SUBCC R7,R10, R0 + BNE l1 + JMP rm1 + +/* + * char is null + * align to word + */ +l2: + ANDCC $3,R9, R0 + BE l3 + MOVB (R9), R7 + ADD $1, R9 + SUBCC R0,R7, R0 + BNE l2 + JMP rm1 + +/* + * develop byte masks + */ +l3: + MOVW $0xff, R17 + SLL $8,R17, R16 + SLL $16,R17, R13 + SLL $24,R17, R12 + +l4: + MOVW (R9), R11 + ADD $4, R9 + ANDCC R12,R11, R0 + BE b0 + ANDCC R13,R11, R0 + BE b1 + ANDCC R16,R11, R0 + BE b2 + ANDCC R17,R11, R0 + BNE l4 + +rm1: + SUB $1,R9, R7 + JMP ret + +b2: + SUB $2,R9, R7 + JMP ret + +b1: + SUB $3,R9, R7 + JMP ret + +b0: + SUB $4,R9, R7 + JMP ret + +ret: + RETURN diff --git a/sys/src/ape/lib/ap/sparc/strcmp.s b/sys/src/ape/lib/ap/sparc/strcmp.s new file mode 100755 index 000000000..e9539ebf8 --- /dev/null +++ b/sys/src/ape/lib/ap/sparc/strcmp.s @@ -0,0 +1,27 @@ +TEXT strcmp(SB), $0 + + MOVW s2+4(FP), R10 + +l1: + MOVB 0(R7), R8 + MOVB 0(R10), R9 + ADD $1, R7 + ADD $1, R10 + + CMP R8, R9 + BNE l2 + + CMP R8, $0 + BNE l1 + + MOVW R0, R7 + RETURN + +l2: + BLEU l3 + MOVW $1, R7 + RETURN + +l3: + MOVW $-1, R7 + RETURN diff --git a/sys/src/ape/lib/ap/sparc/strcpy.s b/sys/src/ape/lib/ap/sparc/strcpy.s new file mode 100755 index 000000000..6fd6aef05 --- /dev/null +++ b/sys/src/ape/lib/ap/sparc/strcpy.s @@ -0,0 +1,84 @@ + TEXT strcpy(SB), $0 + +MOVW R7, 0(FP) + MOVW s1+0(FP), R9 /* R9 is to pointer */ + MOVW s2+4(FP), R10 /* R10 is from pointer */ + +/* + * test if both pointers + * are similarly word aligned + */ + XOR R9,R10, R7 + ANDCC $3,R7, R0 + BNE una + +/* + * make byte masks + */ + MOVW $0xff, R17 + SLL $8,R17, R16 + SLL $16,R17, R13 + SLL $24,R17, R12 + +/* + * byte at a time to word align + */ +al1: + ANDCC $3,R10, R0 + BE al2 + MOVB (R10), R11 + ADD $1, R10 + MOVB R11, (R9) + ADD $1, R9 + SUBCC R0,R11, R0 + BNE al1 + JMP out + +/* + * word at a time + */ +al2: + ADD $4, R9 + MOVW (R10), R11 /* fetch */ + ADD $4, R10 + ANDCC R12,R11, R0 /* is it byte 0 */ + BE b0 + ANDCC R13,R11, R0 /* is it byte 1 */ + BE b1 + ANDCC R16,R11, R0 /* is it byte 2 */ + BE b2 + MOVW R11, -4(R9) /* store */ + ANDCC R17,R11, R0 /* is it byte 3 */ + BNE al2 + + JMP out + +b0: + MOVB R0, -4(R9) + JMP out + +b1: + SRL $24, R11 + MOVB R11, -4(R9) + MOVB R0, -3(R9) + JMP out + +b2: + SRL $24,R11, R7 + MOVB R7, -4(R9) + SRL $16, R11 + MOVB R11, -3(R9) + MOVB R0, -2(R9) + JMP out + +una: + MOVB (R10), R11 + ADD $1, R10 + MOVB R11, (R9) + ADD $1, R9 + SUBCC R0,R11, R0 + BNE una + +out: + MOVW s1+0(FP),R7 + RETURN diff --git a/sys/src/ape/lib/ap/sparc/tas.s b/sys/src/ape/lib/ap/sparc/tas.s new file mode 100755 index 000000000..70cce835d --- /dev/null +++ b/sys/src/ape/lib/ap/sparc/tas.s @@ -0,0 +1,7 @@ +/* + * tas uses LDSTUB + */ + TEXT tas(SB),$-4 + + TAS (R7),R7 + RETURN diff --git a/sys/src/ape/lib/ap/sparc/vlop.s b/sys/src/ape/lib/ap/sparc/vlop.s new file mode 100755 index 000000000..ac36b4143 --- /dev/null +++ b/sys/src/ape/lib/ap/sparc/vlop.s @@ -0,0 +1,112 @@ +TEXT _mulv(SB), $0 + MOVW u1+8(FP), R8 + MOVW u2+16(FP), R13 + + MOVW R13, R16 /* save low parts for later */ + MOVW R8, R12 + + /* + * unsigned 32x32 => 64 multiply + */ + CMP R13, R8 + BLE mul1 + MOVW R12, R13 + MOVW R16, R8 +mul1: + MOVW R13, Y + ANDNCC $0xFFF, R13, R0 + BE mul_shortway + ANDCC R0, R0, R9 /* zero partial product and clear N and V cond's */ + + /* long multiply */ + MULSCC R8, R9, R9 /* 0 */ + MULSCC R8, R9, R9 /* 1 */ + MULSCC R8, R9, R9 /* 2 */ + MULSCC R8, R9, R9 /* 3 */ + MULSCC R8, R9, R9 /* 4 */ + MULSCC R8, R9, R9 /* 5 */ + MULSCC R8, R9, R9 /* 6 */ + MULSCC R8, R9, R9 /* 7 */ + MULSCC R8, R9, R9 /* 8 */ + MULSCC R8, R9, R9 /* 9 */ + MULSCC R8, R9, R9 /* 10 */ + MULSCC R8, R9, R9 /* 11 */ + MULSCC R8, R9, R9 /* 12 */ + MULSCC R8, R9, R9 /* 13 */ + MULSCC R8, R9, R9 /* 14 */ + MULSCC R8, R9, R9 /* 15 */ + MULSCC R8, R9, R9 /* 16 */ + MULSCC R8, R9, R9 /* 17 */ + MULSCC R8, R9, R9 /* 18 */ + MULSCC R8, R9, R9 /* 19 */ + MULSCC R8, R9, R9 /* 20 */ + MULSCC R8, R9, R9 /* 21 */ + MULSCC R8, R9, R9 /* 22 */ + MULSCC R8, R9, R9 /* 23 */ + MULSCC R8, R9, R9 /* 24 */ + MULSCC R8, R9, R9 /* 25 */ + MULSCC R8, R9, R9 /* 26 */ + MULSCC R8, R9, R9 /* 27 */ + MULSCC R8, R9, R9 /* 28 */ + MULSCC R8, R9, R9 /* 29 */ + MULSCC R8, R9, R9 /* 30 */ + MULSCC R8, R9, R9 /* 31 */ + MULSCC R0, R9, R9 /* 32; shift only; r9 is high part */ + + /* + * need to correct top word if top bit set + */ + CMP R8, R0 + BGE mul_tstlow + ADD R13, R9 /* adjust the high parts */ + +mul_tstlow: + MOVW Y, R13 /* get low part */ + BA mul_done + +mul_shortway: + ANDCC R0, R0, R9 /* zero partial product and clear N and V cond's */ + MULSCC R8, R9, R9 /* 0 */ + MULSCC R8, R9, R9 /* 1 */ + MULSCC R8, R9, R9 /* 2 */ + MULSCC R8, R9, R9 /* 3 */ + MULSCC R8, R9, R9 /* 4 */ + MULSCC R8, R9, R9 /* 5 */ + MULSCC R8, R9, R9 /* 6 */ + MULSCC R8, R9, R9 /* 7 */ + MULSCC R8, R9, R9 /* 8 */ + MULSCC R8, R9, R9 /* 9 */ + MULSCC R8, R9, R9 /* 10 */ + MULSCC R8, R9, R9 /* 11 */ + MULSCC R0, R9, R9 /* 12; shift only; r9 is high part */ + + MOVW Y, R8 /* make low part of partial low part & high part */ + SLL $12, R9, R13 + SRL $20, R8 + OR R8, R13 + + SRA $20, R9 /* high part */ + +mul_done: + + /* + * mul by high halves if needed + */ + MOVW R13, 4(R7) + MOVW u2+12(FP), R11 + CMP R11, R0 + BE nomul1 + MUL R11, R12 + ADD R12, R9 + +nomul1: + MOVW u1+4(FP), R11 + CMP R11, R0 + BE nomul2 + MUL R11, R16 + ADD R16, R9 + +nomul2: + + MOVW R9, 0(R7) + RETURN diff --git a/sys/src/ape/lib/ap/sparc/vlrt.c b/sys/src/ape/lib/ap/sparc/vlrt.c new file mode 100755 index 000000000..6fbd83ca8 --- /dev/null +++ b/sys/src/ape/lib/ap/sparc/vlrt.c @@ -0,0 +1,718 @@ +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 +_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); +} -- cgit v1.2.3