diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2014-02-01 10:31:41 +0100 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2014-02-01 10:31:41 +0100 |
commit | ed9e9f98e9cc502c72b27c68612e9e187ec11e10 (patch) | |
tree | 42901d0156503dadce4bf1f0b60e9ef850c3c5e0 /sys/src/ape | |
parent | d4fb753c9c90e0ca745a1b3708ad3ec4ca523e71 (diff) |
libc and ape support for amd64
Diffstat (limited to 'sys/src/ape')
-rw-r--r-- | sys/src/ape/lib/9/amd64/getcallerpc.s | 3 | ||||
-rw-r--r-- | sys/src/ape/lib/9/amd64/getfcr.s | 38 | ||||
-rw-r--r-- | sys/src/ape/lib/ap/amd64/_seek.c | 11 | ||||
-rw-r--r-- | sys/src/ape/lib/ap/amd64/cycles.s | 5 | ||||
-rw-r--r-- | sys/src/ape/lib/ap/amd64/lock.c | 26 | ||||
-rw-r--r-- | sys/src/ape/lib/ap/amd64/main9.s | 26 | ||||
-rw-r--r-- | sys/src/ape/lib/ap/amd64/main9p.s | 45 | ||||
-rw-r--r-- | sys/src/ape/lib/ap/amd64/mkfile | 20 | ||||
-rw-r--r-- | sys/src/ape/lib/ap/amd64/notetramp.c | 81 | ||||
-rw-r--r-- | sys/src/ape/lib/ap/amd64/setjmp.s | 27 | ||||
-rw-r--r-- | sys/src/ape/lib/ap/amd64/strchr.s | 38 | ||||
-rw-r--r-- | sys/src/ape/lib/ap/amd64/strlen.s | 16 | ||||
-rw-r--r-- | sys/src/ape/lib/ap/amd64/tas.s | 5 |
13 files changed, 341 insertions, 0 deletions
diff --git a/sys/src/ape/lib/9/amd64/getcallerpc.s b/sys/src/ape/lib/9/amd64/getcallerpc.s new file mode 100644 index 000000000..15e55ea17 --- /dev/null +++ b/sys/src/ape/lib/9/amd64/getcallerpc.s @@ -0,0 +1,3 @@ +TEXT getcallerpc(SB), 1, $0 + MOVQ -8(RARG), AX + RET diff --git a/sys/src/ape/lib/9/amd64/getfcr.s b/sys/src/ape/lib/9/amd64/getfcr.s new file mode 100644 index 000000000..9fc2002da --- /dev/null +++ b/sys/src/ape/lib/9/amd64/getfcr.s @@ -0,0 +1,38 @@ + +TEXT setfcr(SB), $4 + XORL $(0x3F<<7),RARG /* bits are cleared in csr to enable them */ + ANDL $0xFFC0, RARG /* just the fcr bits */ + WAIT /* is this needed? */ + STMXCSR 0(SP) + MOVL 0(SP), AX + ANDL $~0x3F, AX + ORL RARG, AX + MOVL AX, 0(SP) + LDMXCSR 0(SP) + RET + +TEXT getfcr(SB), $4 + WAIT + STMXCSR 0(SP) + MOVWLZX 0(SP), AX + ANDL $0xFFC0, AX + XORL $(0x3F<<7),AX + RET + +TEXT getfsr(SB), $4 + WAIT + STMXCSR 0(SP) + MOVL 0(SP), AX + ANDL $0x3F, AX + RET + +TEXT setfsr(SB), $4 + ANDL $0x3F, RARG + WAIT + STMXCSR 0(SP) + MOVL 0(SP), AX + ANDL $~0x3F, AX + ORL RARG, AX + MOVL AX, 0(SP) + LDMXCSR 0(SP) + RET diff --git a/sys/src/ape/lib/ap/amd64/_seek.c b/sys/src/ape/lib/ap/amd64/_seek.c new file mode 100644 index 000000000..a9d92c7cb --- /dev/null +++ b/sys/src/ape/lib/ap/amd64/_seek.c @@ -0,0 +1,11 @@ +extern long __SEEK(long long*, int, long long, int); + +long long +_SEEK(int fd, long long o, int p) +{ + long long l; + + if(__SEEK(&l, fd, o, p) < 0) + l = -1; + return l; +} diff --git a/sys/src/ape/lib/ap/amd64/cycles.s b/sys/src/ape/lib/ap/amd64/cycles.s new file mode 100644 index 000000000..769f617bb --- /dev/null +++ b/sys/src/ape/lib/ap/amd64/cycles.s @@ -0,0 +1,5 @@ +TEXT _cycles(SB),1,$0 /* time stamp counter; cycles since power up */ + RDTSC + MOVL AX, 0(RARG) /* lo */ + MOVL DX, 4(RARG) /* hi */ + RET diff --git a/sys/src/ape/lib/ap/amd64/lock.c b/sys/src/ape/lib/ap/amd64/lock.c new file mode 100644 index 000000000..91c0ba233 --- /dev/null +++ b/sys/src/ape/lib/ap/amd64/lock.c @@ -0,0 +1,26 @@ +#define _LOCK_EXTENSION +#include "../plan9/sys9.h" +#include <lock.h> + +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/amd64/main9.s b/sys/src/ape/lib/ap/amd64/main9.s new file mode 100644 index 000000000..d461dc185 --- /dev/null +++ b/sys/src/ape/lib/ap/amd64/main9.s @@ -0,0 +1,26 @@ +#define NPRIVATES 16 + +GLOBL _tos(SB), $8 +GLOBL _errnoloc(SB), $8 +GLOBL _privates(SB), $8 +GLOBL _nprivates(SB), $8 + +TEXT _main(SB), 1, $(32+NPRIVATES*8) + + /* _tos = arg */ + MOVQ AX, _tos(SB) + LEAQ 24(SP), AX + MOVQ AX, _errnoloc(SB) + LEAQ 32(SP), AX + MOVQ AX, _privates(SB) + MOVQ $NPRIVATES, _nprivates(SB) + CALL _envsetup(SB) + MOVL inargc-8(FP), RARG + LEAQ inargv+0(FP), AX + MOVQ AX, 8(SP) + MOVQ environ(SB), AX + MOVQ AX, 16(SP) + CALL main(SB) + MOVQ AX, RARG + CALL exit(SB) + RET diff --git a/sys/src/ape/lib/ap/amd64/main9p.s b/sys/src/ape/lib/ap/amd64/main9p.s new file mode 100644 index 000000000..dfd3450ea --- /dev/null +++ b/sys/src/ape/lib/ap/amd64/main9p.s @@ -0,0 +1,45 @@ +#define NPRIVATES 16 + +GLOBL _tos(SB), $8 +GLOBL _privates(SB), $8 +GLOBL _nprivates(SB), $8 + +TEXT _mainp(SB), 1, $(3*8+NPRIVATES*8) + + /* _tos = arg */ + MOVQ AX, _tos(SB) + LEAQ 8(SP), AX + MOVQ AX, _privates(SB) + MOVQ $NPRIVATES, _nprivates(SB) + + /* _profmain(); */ + CALL _profmain(SB) + + /* _tos->prof.pp = _tos->prof.next; */ + MOVQ _tos+0(SB),DX + MOVQ 4(DX),CX + MOVQ CX,(DX) + + CALL _envsetup(SB) + + /* main(argc, argv, environ); */ + MOVL inargc-8(FP), RARG + LEAQ inargv+0(FP), AX + MOVQ AX, 8(SP) + MOVQ environ(SB), AX + MOVQ AX, 16(SP) + CALL main(SB) + +loop: + MOVL AX, RARG + CALL exit(SB) + MOVQ $_profin(SB), AX /* force loading of profile */ + MOVL $0, AX + JMP loop + +TEXT _savearg(SB), 1, $0 + RET + +TEXT _callpc(SB), 1, $0 + MOVQ 8(RARG), AX + RET diff --git a/sys/src/ape/lib/ap/amd64/mkfile b/sys/src/ape/lib/ap/amd64/mkfile new file mode 100644 index 000000000..5bb7f3271 --- /dev/null +++ b/sys/src/ape/lib/ap/amd64/mkfile @@ -0,0 +1,20 @@ +APE=/sys/src/ape +objtype=amd64 +<$APE/config +LIB=/$objtype/lib/ape/libap.a +OFILES=\ + _seek.$O\ + cycles.$O\ + lock.$O\ + main9.$O\ + main9p.$O\ + notetramp.$O\ + setjmp.$O\ + strchr.$O\ + strlen.$O\ + tas.$O\ + +</sys/src/cmd/mksyslib + +CFLAGS=-c -D_POSIX_SOURCE -D_PLAN9_SOURCE + diff --git a/sys/src/ape/lib/ap/amd64/notetramp.c b/sys/src/ape/lib/ap/amd64/notetramp.c new file mode 100644 index 000000000..c92205175 --- /dev/null +++ b/sys/src/ape/lib/ap/amd64/notetramp.c @@ -0,0 +1,81 @@ +#include "../plan9/lib.h" +#include "../plan9/sys9.h" +#include <signal.h> +#include <setjmp.h> + +/* 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 long restorepc; + 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->sig = sig; + p->hdlr = hdlr; + p->u = u; + nstack++; + u->pc = (unsigned long long) notecont; + _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; + nstack--; + (*f)(p->sig, s, u); + _NOTED(3); /* NRSTR */ +} + +#define JMPBUFPC 1 +#define JMPBUFSP 0 + +extern sigset_t _psigblocked; + +typedef struct { + sigset_t set; + sigset_t blocked; + unsigned long long jmpbuf[2]; +} sigjmp_buf_amd64; + +void +siglongjmp(sigjmp_buf j, int ret) +{ + struct Ureg *u; + sigjmp_buf_amd64 *jb; + + jb = (sigjmp_buf_amd64*)j; + + if(jb->set) + _psigblocked = jb->blocked; + if(nstack == 0 || pcstack[nstack-1].u->sp > jb->jmpbuf[JMPBUFSP]) + longjmp((void*)jb->jmpbuf, ret); + u = pcstack[nstack-1].u; + nstack--; + u->ax = ret; + if(ret == 0) + u->ax = 1; + u->pc = jb->jmpbuf[JMPBUFPC]; + u->sp = jb->jmpbuf[JMPBUFSP] + 8; + _NOTED(3); /* NRSTR */ +} diff --git a/sys/src/ape/lib/ap/amd64/setjmp.s b/sys/src/ape/lib/ap/amd64/setjmp.s new file mode 100644 index 000000000..67320cad9 --- /dev/null +++ b/sys/src/ape/lib/ap/amd64/setjmp.s @@ -0,0 +1,27 @@ +TEXT longjmp(SB), $0 + MOVL r+8(FP), AX + CMPL AX, $0 + JNE ok /* ansi: "longjmp(0) => longjmp(1)" */ + MOVL $1, AX /* bless their pointed heads */ +ok: + MOVQ 0(RARG), SP /* restore sp */ + MOVQ 8(RARG), BX /* put return pc on the stack */ + MOVQ BX, 0(SP) + RET + +TEXT setjmp(SB), $0 + MOVQ SP, 0(RARG) /* store sp */ + MOVQ 0(SP), BX /* store return pc */ + MOVQ BX, 8(RARG) + MOVL $0, AX /* return 0 */ + RET + +TEXT sigsetjmp(SB), $0 + MOVL savemask+8(FP), BX + MOVL BX, 0(RARG) + MOVL $_psigblocked(SB), 4(RARG) + MOVQ SP, 8(RARG) /* store sp */ + MOVQ 0(SP), BX /* store return pc */ + MOVQ BX, 16(RARG) + MOVL $0, AX /* return 0 */ + RET diff --git a/sys/src/ape/lib/ap/amd64/strchr.s b/sys/src/ape/lib/ap/amd64/strchr.s new file mode 100644 index 000000000..317537361 --- /dev/null +++ b/sys/src/ape/lib/ap/amd64/strchr.s @@ -0,0 +1,38 @@ + TEXT strchr(SB), $0 + + MOVQ RARG, DI + MOVB c+8(FP), AX + CMPB AX, $0 + JEQ l2 /**/ + +/* + * char is not null + */ +l1: + MOVB (DI), BX + CMPB BX, $0 + JEQ ret0 + ADDQ $1, DI + CMPB AX, BX + JNE l1 + + MOVQ DI, AX + SUBQ $1, AX + RET + +/* + * char is null + */ +l2: + MOVQ $-1, CX + CLD + + REPN; SCASB + + MOVQ DI, AX + SUBQ $1, AX + RET + +ret0: + MOVQ $0, AX + RET diff --git a/sys/src/ape/lib/ap/amd64/strlen.s b/sys/src/ape/lib/ap/amd64/strlen.s new file mode 100644 index 000000000..cf27cd56a --- /dev/null +++ b/sys/src/ape/lib/ap/amd64/strlen.s @@ -0,0 +1,16 @@ + TEXT strlen(SB),$0 + + MOVL $0, AX + MOVQ $-1, CX + CLD +/* + * look for end of string + */ + + MOVQ RARG, DI + REPN; SCASB + + MOVQ DI, AX + SUBQ RARG, AX + SUBQ $1, AX + RET diff --git a/sys/src/ape/lib/ap/amd64/tas.s b/sys/src/ape/lib/ap/amd64/tas.s new file mode 100644 index 000000000..7aa994b99 --- /dev/null +++ b/sys/src/ape/lib/ap/amd64/tas.s @@ -0,0 +1,5 @@ +TEXT tas(SB),$0 + + MOVL $0xdeadead,AX + XCHGL AX,(RARG) + RET |