summaryrefslogtreecommitdiff
path: root/sys/src/ape
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2014-02-01 10:31:41 +0100
committercinap_lenrek <cinap_lenrek@felloff.net>2014-02-01 10:31:41 +0100
commited9e9f98e9cc502c72b27c68612e9e187ec11e10 (patch)
tree42901d0156503dadce4bf1f0b60e9ef850c3c5e0 /sys/src/ape
parentd4fb753c9c90e0ca745a1b3708ad3ec4ca523e71 (diff)
libc and ape support for amd64
Diffstat (limited to 'sys/src/ape')
-rw-r--r--sys/src/ape/lib/9/amd64/getcallerpc.s3
-rw-r--r--sys/src/ape/lib/9/amd64/getfcr.s38
-rw-r--r--sys/src/ape/lib/ap/amd64/_seek.c11
-rw-r--r--sys/src/ape/lib/ap/amd64/cycles.s5
-rw-r--r--sys/src/ape/lib/ap/amd64/lock.c26
-rw-r--r--sys/src/ape/lib/ap/amd64/main9.s26
-rw-r--r--sys/src/ape/lib/ap/amd64/main9p.s45
-rw-r--r--sys/src/ape/lib/ap/amd64/mkfile20
-rw-r--r--sys/src/ape/lib/ap/amd64/notetramp.c81
-rw-r--r--sys/src/ape/lib/ap/amd64/setjmp.s27
-rw-r--r--sys/src/ape/lib/ap/amd64/strchr.s38
-rw-r--r--sys/src/ape/lib/ap/amd64/strlen.s16
-rw-r--r--sys/src/ape/lib/ap/amd64/tas.s5
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