shithub: riscv

Download patch

ref: 2c5c78425516590e894c9c334182073fcc56a10b
parent: 87fcb107ef333f5dce7618e0f4c73d69ebc75eb5
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Mon Feb 17 08:25:24 EST 2014

prof: properly save and restore RARG for amd64

amd64 passes first argument in RARG (BP) register
which has the be preserved duing _profin() and
_profout() calls. to handle this we introduce
_saveret() and _savearg(). _saveret() returns
AX, _savearg() returns RARG (BP). for archs other
and amd64, _saveret() and _savearg() are the
same function, doing nothing.

restoing works with dummy function:

uintptr
_restore(uintptr, uintptr ret)
{
	return ret;
}

...

ret = _saveret();
arg = _savearg();
...
return _restore(arg, ret);

as we pass arg as the first argument, RARG (BP) is
restored.

--- a/sys/src/ape/lib/ap/386/main9p.s
+++ b/sys/src/ape/lib/ap/386/main9p.s
@@ -40,6 +40,7 @@
 	MOVL	$0, AX
 	JMP	loop
 
+TEXT	_saveret(SB), 1, $0
 TEXT	_savearg(SB), 1, $0
 	RET
 
--- a/sys/src/ape/lib/ap/alpha/main9p.s
+++ b/sys/src/ape/lib/ap/alpha/main9p.s
@@ -43,6 +43,7 @@
 	MOVQ	$_profin(SB), R31	/* force loading of profile */
 	JMP	loop
 
+TEXT	_saveret(SB), 1, $0
 TEXT	_savearg(SB), 1, $0
 	RET
 
--- a/sys/src/ape/lib/ap/amd64/main9p.s
+++ b/sys/src/ape/lib/ap/amd64/main9p.s
@@ -37,7 +37,11 @@
 	MOVL	$0, AX
 	JMP	loop
 
+TEXT	_saveret(SB), 1, $0
+	RET
+
 TEXT	_savearg(SB), 1, $0
+	MOVQ	RARG, AX
 	RET
 
 TEXT	_callpc(SB), 1, $0
--- a/sys/src/ape/lib/ap/arm/main9p.s
+++ b/sys/src/ape/lib/ap/arm/main9p.s
@@ -47,6 +47,7 @@
 	MOVW	$_profin(SB), R(arg)	/* force loading of profile */
 	B	loop
 
+TEXT	_saveret(SB), 1, $0
 TEXT	_savearg(SB), 1, $0
 	RET
 
--- a/sys/src/ape/lib/ap/mips/main9p.s
+++ b/sys/src/ape/lib/ap/mips/main9p.s
@@ -49,6 +49,7 @@
 	MOVW	$_profin(SB), R0	/* force loading of profile */
 	JMP	loop
 
+TEXT	_saveret(SB), 1, $0
 TEXT	_savearg(SB), 1, $0
 	RET
 
--- a/sys/src/ape/lib/ap/plan9/profile.c
+++ b/sys/src/ape/lib/ap/plan9/profile.c
@@ -23,7 +23,8 @@
 
 extern	void*	sbrk(ulong);
 extern	long	_callpc(void**);
-extern	long	_savearg(void);
+extern	void*	_savearg(void);
+extern	void*	_saveret(void);
 extern	void	_cycles(uvlong*);	/* 64-bit value of the cycle counter if there is one, 0 if there isn't */
 
 static ulong	khz;
@@ -43,20 +44,27 @@
 
 #pragma profile off
 
-ulong
+static void*
+_restore(void*, void *ret)
+{
+	return ret;
+}
+
+void*
 _profin(void)
 {
 	void *dummy;
 	long pc;
 	Plink *pp, *p;
-	ulong arg;
+	void *ret, *arg;
 	vlong t;
 
+	ret = _saveret();
 	arg = _savearg();
 	pc = _callpc(&dummy);
 	pp = _tos->prof.pp;
 	if(pp == 0 || (_tos->prof.pid && _tos->pid != _tos->prof.pid))
-		return arg;
+		return _restore(arg, ret);
 
 	for(p=pp->down; p; p=p->link)
 		if(p->pc == pc)
@@ -65,7 +73,7 @@
 	if(p >= _tos->prof.last){
 		_tos->prof.pp = 0;
 		perr++;
-		return arg;
+		return _restore(arg, ret);
 	}
 	_tos->prof.next = p;
 	p->link = pp->down;
@@ -96,16 +104,17 @@
 		p->time = p->time - _tos->clock;
 		break;
 	}
-	return arg;		/* disgusting linkage */
+	return _restore(arg, ret);
 }
 
-ulong
+void*
 _profout(void)
 {
 	Plink *p;
-	ulong arg;
+	void *ret, *arg;
 	vlong t;
 
+	ret = _saveret();
 	arg = _savearg();
 	p = _tos->prof.pp;
 	if (p == NULL || (_tos->prof.pid != 0 && _tos->pid != _tos->prof.pid))
@@ -127,7 +136,7 @@
 		break;
 	}
 	_tos->prof.pp = p->old;
-	return arg;
+	return _restore(arg, ret);
 }
 
 /* stdio may not be ready for us yet */
--- a/sys/src/ape/lib/ap/power/main9p.s
+++ b/sys/src/ape/lib/ap/power/main9p.s
@@ -40,6 +40,7 @@
 	MOVW	$_profin(SB), R4	/* force loading of profile */
 	BR	loop
 
+TEXT	_saveret(SB), 1, $0
 TEXT	_savearg(SB), 1, $0
 	RETURN
 
--- a/sys/src/ape/lib/ap/sparc/main9p.s
+++ b/sys/src/ape/lib/ap/sparc/main9p.s
@@ -48,6 +48,7 @@
 	MOVW	$_profin(SB), R0	/* force loading of profile */
 	JMP	loop
 
+TEXT	_saveret(SB), 1, $0
 TEXT	_savearg(SB), 1, $0
 	RETURN
 
--- a/sys/src/libc/386/main9p.s
+++ b/sys/src/libc/386/main9p.s
@@ -26,6 +26,7 @@
 	MOVL	$_profin(SB), AX	/* force loading of profile */
 	JMP	loop
 
+TEXT	_saveret(SB), 1, $0
 TEXT	_savearg(SB), 1, $0
 	RET
 
--- a/sys/src/libc/68000/main9p.s
+++ b/sys/src/libc/68000/main9p.s
@@ -19,6 +19,7 @@
 	LEA	_profin(SB), A0		/* force loading of profile */
 	BRA	loop
 
+TEXT	_saveret(SB), 1, $0
 TEXT	_savearg(SB), 1, $0
 	RTS
 
--- a/sys/src/libc/68020/main9p.s
+++ b/sys/src/libc/68020/main9p.s
@@ -20,6 +20,7 @@
 	LEA	_profin(SB), A0		/* force loading of profile */
 	BRA	loop
 
+TEXT	_saveret(SB), 1, $0
 TEXT	_savearg(SB), 1, $0
 	RTS
 
--- a/sys/src/libc/alpha/main9p.s
+++ b/sys/src/libc/alpha/main9p.s
@@ -26,6 +26,7 @@
 	MOVQ	$_profin(SB), R31	/* force loading of profile */
 	JMP	loop
 
+TEXT	_saveret(SB), 1, $0
 TEXT	_savearg(SB), 1, $0
 	RET
 
--- a/sys/src/libc/amd64/main9p.s
+++ b/sys/src/libc/amd64/main9p.s
@@ -28,9 +28,6 @@
 	RET
 
 TEXT	_saveret(SB), 1, $0
-	RET
-
-TEXT	_restorearg(SB), 1, $0
 	RET				/* we want RARG in RARG */
 
 TEXT	_callpc(SB), 1, $0
--- a/sys/src/libc/arm/main9p.s
+++ b/sys/src/libc/arm/main9p.s
@@ -31,6 +31,7 @@
 	MOVW	$_profin(SB), R(arg)	/* force loading of profile */
 	B	loop
 
+TEXT	_saveret(SB), 1, $0
 TEXT	_savearg(SB), 1, $0
 	RET
 
--- a/sys/src/libc/mips/main9p.s
+++ b/sys/src/libc/mips/main9p.s
@@ -25,6 +25,7 @@
 	MOVW	$_profin(SB), R0	/* force loading of profile */
 	JMP	loop
 
+TEXT	_saveret(SB), 1, $0
 TEXT	_savearg(SB), 1, $0
 	RET
 
--- a/sys/src/libc/port/profile.c
+++ b/sys/src/libc/port/profile.c
@@ -2,8 +2,9 @@
 #include	<libc.h>
 #include	<tos.h>
 
-extern	long	_callpc(void**);
-extern	long	_savearg(void);
+extern	uintptr	_callpc(void**);
+extern	uintptr	_saveret(void);
+extern	uintptr	_savearg(void);
 
 static	ulong	khz;
 static	ulong	perr;
@@ -22,21 +23,27 @@
 
 #pragma profile off
 
-ulong
+static uintptr
+_restore(uintptr, uintptr ret)
+{
+	return ret;
+}
+
+uintptr
 _profin(void)
 {
 	void *dummy;
 	long pc;
 	Plink *pp, *p;
-	ulong arg;
+	uintptr arg, ret;
 	vlong t;
 
+	ret = _saveret();
 	arg = _savearg();
 	pc = _callpc(&dummy);
 	pp = _tos->prof.pp;
 	if(pp == 0 || (_tos->prof.pid && _tos->pid != _tos->prof.pid))
-		return arg;
-
+		return _restore(arg, ret);
 	for(p=pp->down; p; p=p->link)
 		if(p->pc == pc)
 			goto out;
@@ -44,7 +51,7 @@
 	if(p >= _tos->prof.last) {
 		_tos->prof.pp = 0;
 		perr++;
-		return arg;
+		return _restore(arg, ret);
 	}
 	_tos->prof.next = p;
 	p->link = pp->down;
@@ -75,20 +82,21 @@
 		p->time = p->time - _tos->clock;
 		break;
 	}
-	return arg;		/* disgusting linkage */
+	return _restore(arg, ret);
 }
 
-ulong
+uintptr
 _profout(void)
 {
 	Plink *p;
-	ulong arg;
+	uintptr ret, arg;
 	vlong t;
 
+	ret = _saveret();
 	arg = _savearg();
 	p = _tos->prof.pp;
 	if (p == nil || (_tos->prof.pid != 0 && _tos->pid != _tos->prof.pid))
-		return arg;	/* Not our process */
+		return _restore(arg, ret);	/* Not our process */
 	switch(_tos->prof.what){
 	case Profkernel:		/* Add proc cycles on proc entry */
 		p->time = p->time + _tos->pcycles;
@@ -106,7 +114,7 @@
 		break;
 	}
 	_tos->prof.pp = p->old;
-	return arg;
+	return _restore(arg, ret);
 }
 
 void
--- a/sys/src/libc/power/main9p.s
+++ b/sys/src/libc/power/main9p.s
@@ -26,6 +26,7 @@
 	MOVW	$_profin(SB), R3	/* force loading of profile */
 	BR	loop
 
+TEXT	_saveret(SB), 1, $0
 TEXT	_savearg(SB), 1, $0
 	RETURN
 
--- a/sys/src/libc/sparc/main9p.s
+++ b/sys/src/libc/sparc/main9p.s
@@ -33,6 +33,7 @@
 	MOVW	$_profin(SB), R9	/* force loading of profile */
 	JMP	loop
 
+TEXT	_saveret(SB), 1, $0
 TEXT	_savearg(SB), 1, $0
 	RETURN