Sfoglia il codice sorgente

A number of changes to get libthread going

- added space to jmp_buf in amd64/include/u.h for callee-saves and 2 args
- adjusted main9.S to have _privates in the _main() stack frame like plan9
  generally did. not super carefully tested.
- adjusted longjmp to restore %rdi and %rsi to make longjmp() work for
  calling a function (eg. launcheramd64 in libthread) as well as returning from
  setjmp
- _threadinitstack: put f in %rdi and arg in %rsi for longjmp restore

Change-Id: I367673b8a5cd0b88d40aa8da522fed1879e05548
Aki Nyrhinen 9 anni fa
parent
commit
d476655ce5
4 ha cambiato i file con 55 aggiunte e 38 eliminazioni
  1. 7 3
      amd64/include/u.h
  2. 5 1
      sys/src/libc/amd64/main9.S
  3. 39 32
      sys/src/libc/amd64/setjmp.s
  4. 4 2
      sys/src/libthread/amd64.c

+ 7 - 3
amd64/include/u.h

@@ -23,9 +23,13 @@ typedef uint32_t	usize;
 typedef int64_t size_t;
 typedef	uint32_t		Rune;
 typedef union FPdbleword FPdbleword;
-typedef uintptr		jmp_buf[2];
-#define	JMPBUFSP	0
-#define	JMPBUFPC	1
+typedef uintptr		jmp_buf[10]; // for registers.
+
+#define	JMPBUFSP	6
+#define	JMPBUFPC	7
+#define	JMPBUFARG1	8
+#define	JMPBUFARG2	9
+
 #define	JMPBUFDPC	0
 typedef unsigned int	mpdigit;	/* for /sys/include/mp.h */
 

+ 5 - 1
sys/src/libc/amd64/main9.S

@@ -3,11 +3,15 @@
 .text
 
 // %rdi and %rsi are set up as argc, argv for main.
+// %rdx points to top of stack
 .globl	_main
 _main:
+
 	movq	%rdx, _tos
-	movq 	%rdx, _privates
+	movq 	$-128, _privates
+	addq	%rsp, _privates
 	movl 	$NPRIVATES, _nprivates
+	leaq	-160(%rsp), %rsp
 	call	main
 
 loop:

+ 39 - 32
sys/src/libc/amd64/setjmp.s

@@ -1,32 +1,39 @@
-.text
-
-.globl longjmp
-longjmp:
-        movq    0(%rdi), %rbx
-        movq    8(%rdi), %r12
-        movq    16(%rdi), %r13
-        movq    24(%rdi), %r14
-        movq    32(%rdi), %r15
-        movq    40(%rdi), %rbp
-        movq    48(%rdi), %rsp
-        movl    %esi, %eax
-        test    %eax, %eax      /* if val != 0          */
-        jnz     1f              /*      return val      */
-        incl    %eax            /* else return 1        */
-1:
-        movq    56(%rdi), %rdx  /* return to caller of setjmp */
-        jmp     *%rdx
-
-.globl setjmp
-setjmp:
-        movq    %rbx, 0(%rdi)
-        movq    %r12, 8(%rdi)
-        movq    %r13, 16(%rdi)
-        movq    %r14, 24(%rdi)
-        movq    %r15, 32(%rdi)
-        movq    %rbp, 40(%rdi)
-        popq    %rdx            /* return address */
-        movq    %rsp, 48(%rdi)
-        movq    %rdx, 56(%rdi)
-        xorl    %eax, %eax      /* return 0 */
-        jmp     *%rdx
+.text
+
+.globl longjmp
+longjmp:
+        movq    %rdi, %r9
+        movq    0(%r9), %rbx
+        movq    8(%r9), %r12
+        movq    16(%r9), %r13
+        movq    24(%r9), %r14
+        movq    32(%r9), %r15
+        movq    40(%r9), %rbp
+        movq    48(%r9), %rsp
+        movl    %esi, %eax
+        test    %eax, %eax      /* if val != 0          */
+        jnz     1f              /*      return val      */
+        incl    %eax            /* else return 1        */
+1:
+        movq    56(%r9), %r8  /* return to caller of setjmp */
+
+        movq	64(%r9), %rdi /* 1st function argument */
+        movq	72(%r9), %rsi /* 2nd function argument */
+
+        jmp     *%r8 
+
+.globl setjmp
+setjmp:
+        movq    %rbx, 0(%rdi)
+        movq    %r12, 8(%rdi)
+        movq    %r13, 16(%rdi)
+        movq    %r14, 24(%rdi)
+        movq    %r15, 32(%rdi)
+        movq    %rbp, 40(%rdi)
+        popq    %rdx            /* return address */
+        movq    %rsp, 48(%rdi)
+        movq    %rdx, 56(%rdi)
+
+
+        xorl    %eax, %eax      /* return 0 */
+        jmp     *%rdx

+ 4 - 2
sys/src/libthread/amd64.c

@@ -14,7 +14,7 @@
 
 /* first argument goes in a register; simplest just to ignore it */
 static void
-launcheramd64(int i, void (*f)(void *arg), void *arg)
+launcheramd64(void (*f)(void *arg), void *arg)
 {
 	(*f)(arg);
 	threadexits(nil);
@@ -28,8 +28,10 @@ _threadinitstack(Thread *t, void (*f)(void*), void *arg)
 	tos = (uint64_t*)&t->stk[t->stksize&~7];
 	*--tos = (uint64_t)arg;
 	*--tos = (uint64_t)f;
-	*--tos = 0;	/* first arg to launcheramd64 */
 	t->sched[JMPBUFPC] = (uint64_t)launcheramd64+JMPBUFDPC;
+	//t->sched[JMPBUFSP] = (uint64_t)tos - 2*8;		/* old PC and new PC */
 	t->sched[JMPBUFSP] = (uint64_t)tos - 2*8;		/* old PC and new PC */
+	t->sched[JMPBUFARG1] = (uint64_t)f;		/* old PC and new PC */
+	t->sched[JMPBUFARG2] = (uint64_t)arg;		/* old PC and new PC */
 }