Browse Source

riscv: fix setjmp/longjmp test regress/longjmp.c

regress/longjmp.c had an architectural dependency
in it; that's fixed.

setjmp/longjmp were a bit wrong for riscv. Note
that they're still wrong for FP.

regress needs to be built after kernel since we
include regression in riscv ramfs now.

Signed-off-by: Ronald G. Minnich <rminnich@gmail.com>
Ronald G. Minnich 3 years ago
parent
commit
38588c19da
6 changed files with 100 additions and 89 deletions
  1. 2 2
      build.json
  2. 4 4
      riscv/include/u.h
  3. 1 1
      sys/include/libc.h
  4. 1 0
      sys/src/9/riscv/build.json
  5. 74 73
      sys/src/libc/riscv/setjmp.S
  6. 18 9
      sys/src/regress/longjmp.c

+ 2 - 2
build.json

@@ -13,9 +13,9 @@
 			"/sys/src/cmd",
 			"/sys/src/games/games.json",
 			"/acme/build.json",
-			"/sys/src/9/$ARCH",
 			"/sys/src/regress",
-			"/sys/src/regress/fs"
+			"/sys/src/regress/fs",
+			"/sys/src/9/$ARCH"
 		]
 	},
 	"kernels": {

+ 4 - 4
riscv/include/u.h

@@ -25,12 +25,12 @@ typedef int64_t size_t;
 typedef	uint32_t		Rune;
 typedef union FPdbleword FPdbleword;
 // This is a guess! Assumes float!
-typedef uintptr		jmp_buf[28]; // for registers.
+typedef uintptr		jmp_buf[64]; // for registers.
 
-#define	JMPBUFSP	13
+#define	JMPBUFSP	1
 #define	JMPBUFPC	0
-#define	JMPBUFARG1	1
-#define	JMPBUFARG2	2
+#define	JMPBUFARG1	13
+#define	JMPBUFARG2	14
 
 #define	JMPBUFDPC	0 // What? 
 typedef unsigned int	mpdigit;	/* for /sys/include/mp.h */

+ 1 - 1
sys/include/libc.h

@@ -342,7 +342,7 @@ extern	double	pow10(int);
 extern	int	putenv(char*, char*);
 extern	void	qsort(void*, int32_t, int32_t,
 				int (*)(const void*, const void*));
-extern	int	setjmp(jmp_buf);
+extern	int	setjmp(jmp_buf) __attribute__((returns_twice));;
 extern	double	strtod(const char*, char**);
 extern	int32_t	strtol(const char*, char**, int);
 extern	uint32_t	strtoul(const char*, char**, int);

+ 1 - 0
sys/src/9/riscv/build.json

@@ -67,6 +67,7 @@
 				"echo": "/$ARCH/bin/echo",
 				"factotum": "/$ARCH/bin/auth/factotum",
 				"ipconfig": "/$ARCH/bin/ip/ipconfig",
+				"longjmp": "/$ARCH/bin/regress/longjmp",
 				"ls": "/$ARCH/bin/ls",
 				"mount": "/$ARCH/bin/mount",
 				"nvram": "/util/nvram",

+ 74 - 73
sys/src/libc/riscv/setjmp.S

@@ -1,82 +1,83 @@
-// We're going to assume 64 bits and hard float.
-// if you want 32 bits, don't do this nonsense.
-// Do it the plan 9 way: make a riscv32 directory
-// and fix things in there. 
-# define SZREG 8
-
 /* int setjmp (jmp_buf);  */
   .globl  setjmp
 setjmp:
-	sd ra,  0*SZREG(a0)
-	sd s0,  1*SZREG(a0)
-	sd s1,  2*SZREG(a0)
-	sd s2,  3*SZREG(a0)
-	sd s3,  4*SZREG(a0)
-	sd s4,  5*SZREG(a0)
-	sd s5,  6*SZREG(a0)
-	sd s6,  7*SZREG(a0)
-	sd s7,  8*SZREG(a0)
-	sd s8,  9*SZREG(a0)
-	sd s9, 10*SZREG(a0)
-	sd s10,11*SZREG(a0)
-	sd s11,12*SZREG(a0)
-	sd sp, 13*SZREG(a0)
-
-	frsr a3
-
-	fsd   fs0, 16*SZREG+ 0*8(a0)
-	fsd   fs1, 16*SZREG+ 1*8(a0)
-	fsd   fs2, 16*SZREG+ 2*8(a0)
-	fsd   fs3, 16*SZREG+ 3*8(a0)
-	fsd   fs4, 16*SZREG+ 4*8(a0)
-	fsd   fs5, 16*SZREG+ 5*8(a0)
-	fsd   fs6, 16*SZREG+ 6*8(a0)
-	fsd   fs7, 16*SZREG+ 7*8(a0)
-	fsd   fs8, 16*SZREG+ 8*8(a0)
-	fsd   fs9, 16*SZREG+ 9*8(a0)
-	fsd   fs10,16*SZREG+10*8(a0)
-	fsd   fs11,16*SZREG+11*8(a0)
-
-	sd a3, 15*SZREG(a0)
-
-	li    a0, 0
-	ret
+	SD	ra,0(a0) // X1
+	SD	sp,8(a0) // X14
+	SD	s0,16(a0) // X2
+	// X0 is zero
+	// X1 and X2 are done.
+	sd x3, 48(a0)
+	sd x4, 56(a0)
+	sd x5, 64(a0)
+	sd x6, 72(a0)
+	sd x7, 80(a0)
+	sd x8, 88(a0)
+	sd x9, 96(a0)
+	sd x10, 104(a0) // store a zero in jmp_buf
+	sd x11, 112(a0) // Don't touch a1.
+	sd x12, 120(a0)
+	sd x13, 128(a0)
+	// X14 done already
+	sd x15, 144(a0)
+	sd x16, 152(a0)
+	sd x17, 160(a0)
+	sd x18, 168(a0)
+	sd x19, 176(a0)
+	sd x20, 184(a0)
+	sd x21, 192(a0)
+	sd x22, 200(a0)
+	sd x23, 208(a0)
+	sd x24, 216(a0)
+	sd x25, 224(a0)
+	sd x26, 232(a0)
+	sd x27, 240(a0)
+	sd x28, 248(a0)
+	sd x29, 256(a0)
+	sd x30, 264(a0)
+	sd x31, 272(a0)
+	mv	a0, x0
+	RET
 
 /* volatile void longjmp (jmp_buf, int);  */
   .globl  longjmp
 longjmp:
-	ld ra,  0*SZREG(a0)
-	ld s0,  1*SZREG(a0)
-	ld s1,  2*SZREG(a0)
-	ld s2,  3*SZREG(a0)
-	ld s3,  4*SZREG(a0)
-	ld s4,  5*SZREG(a0)
-	ld s5,  6*SZREG(a0)
-	ld s6,  7*SZREG(a0)
-	ld s7,  8*SZREG(a0)
-	ld s8,  9*SZREG(a0)
-	ld s9, 10*SZREG(a0)
-	ld s10,11*SZREG(a0)
-	ld s11,12*SZREG(a0)
-	ld sp, 13*SZREG(a0)
-
-	ld a3, 15*SZREG(a0)
-
-	fld  fs0, 16*SZREG+ 0*8(a0)
-	fld  fs1, 16*SZREG+ 1*8(a0)
-	fld  fs2, 16*SZREG+ 2*8(a0)
-	fld  fs3, 16*SZREG+ 3*8(a0)
-	fld  fs4, 16*SZREG+ 4*8(a0)
-	fld  fs5, 16*SZREG+ 5*8(a0)
-	fld  fs6, 16*SZREG+ 6*8(a0)
-	fld  fs7, 16*SZREG+ 7*8(a0)
-	fld  fs8, 16*SZREG+ 8*8(a0)
-	fld  fs9, 16*SZREG+ 9*8(a0)
-	fld  fs10,16*SZREG+10*8(a0)
-
-	fssr a3
+	LD	sp,8(a0) // X14
+	LD	s0,16(a0) // X2
+	// X0 is zero
+	// X1 and X2 are done.
+	LD x3, 48(a0)
+	// Don't restore X4, that's reserved for Mach *
+	//LD x4, 56(a0)
+	LD x5, 64(a0)
+	LD x6, 72(a0)
+	LD x7, 80(a0)
+	LD x8, 88(a0)
+	LD x9, 96(a0)
+	//LD x10, 104(a0) this is a0
+	// LD x11, 112(a0)
+	LD x12, 120(a0)
+	LD x13, 128(a0)
+	// X14 done already
+	LD x15, 144(a0)
+	LD x16, 152(a0)
+	LD x17, 160(a0)
+	LD x18, 168(a0)
+	LD x19, 176(a0)
+	LD x20, 184(a0)
+	LD x21, 192(a0)
+	LD x22, 200(a0)
+	LD x23, 208(a0)
+	LD x24, 216(a0)
+	LD x25, 224(a0)
+	LD x26, 232(a0)
+	LD x27, 240(a0)
+	LD x28, 248(a0)
+	LD x29, 256(a0)
+	LD x30, 264(a0)
+	LD x30, 272(a0)
+	LD	a0,0(a0)
+	MV	ra,a0 // X1 (non zero by definition I hope.
+	mv	a0, a1
+	RET
 
-	seqz a0, a1
-	add  a0, a0, a1   # a0 = (a1 == 0) ? 1 : a1
-	ret
 

+ 18 - 9
sys/src/regress/longjmp.c

@@ -15,30 +15,39 @@ main(void)
 	int fail = 0;
 	jmp_buf label;
 
-	njmp = 0;
-	while((njmp = setjmp(label)) < Njmps)
+	while((njmp = setjmp(label)) < Njmps) {
 		longjmp(label, njmp+1);
+	}
 
 	for(i = 0; i < nelem(label); i++)
 		fprint(2, "label[%d] = %p\n", i, label[i]);
 	fprint(2, "main: %p foo: %p\n", main, foo);
 
-	if(njmp != Njmps)
-		fail++;
-	if(label[JMPBUFPC] < (uintptr_t)main)
+	if(njmp != Njmps) {
+		print("njmp is %d, wanted %d\n", njmp, Njmps);
 		fail++;
-	if(label[JMPBUFPC] > (uintptr_t)foo)
+	}
+	if(label[JMPBUFPC] < (uintptr_t)main) {
+		print("label[%d] is %p, which is < main(%p)\n",
+			JMPBUFPC, label[JMPBUFPC], main);
 		fail++;
-	if(label[JMPBUFSP] > (uintptr_t)&label[nelem(label)])
+	}
+	if(label[JMPBUFPC] > (uintptr_t)foo) {
+		print("label[%d] is %p, which is > foo(%p)\n",
+			JMPBUFPC, label[JMPBUFPC], foo);
 		fail++;
-	if(label[JMPBUFSP] < 0x7fffffd00000)
+	}
+	if(label[JMPBUFSP] > (uintptr_t)&label[nelem(label)]) {
+		print("label[%d] is %p, which is > (uintptr_t)&label[nelem(label)](%p)\n",
+			JMPBUFSP, label[JMPBUFSP], foo);
 		fail++;
+	}
 
 	if(fail == 0){
 		print("PASS\n");
 		exits("PASS");
 	}
-	print("FAIL\n");
+	print("FAIL (%d errors)\n", fail);
 	exits("FAIL");
 	return 0;
 }