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.
This commit is contained in:
cinap_lenrek 2014-02-17 13:25:24 +01:00
parent 87fcb107ef
commit 2c5c784255
18 changed files with 56 additions and 24 deletions

View file

@ -26,6 +26,7 @@ loop:
MOVL $_profin(SB), AX /* force loading of profile */
JMP loop
TEXT _saveret(SB), 1, $0
TEXT _savearg(SB), 1, $0
RET

View file

@ -19,6 +19,7 @@ loop:
LEA _profin(SB), A0 /* force loading of profile */
BRA loop
TEXT _saveret(SB), 1, $0
TEXT _savearg(SB), 1, $0
RTS

View file

@ -20,6 +20,7 @@ loop:
LEA _profin(SB), A0 /* force loading of profile */
BRA loop
TEXT _saveret(SB), 1, $0
TEXT _savearg(SB), 1, $0
RTS

View file

@ -26,6 +26,7 @@ loop:
MOVQ $_profin(SB), R31 /* force loading of profile */
JMP loop
TEXT _saveret(SB), 1, $0
TEXT _savearg(SB), 1, $0
RET

View file

@ -28,9 +28,6 @@ TEXT _savearg(SB), 1, $0
RET
TEXT _saveret(SB), 1, $0
RET
TEXT _restorearg(SB), 1, $0
RET /* we want RARG in RARG */
TEXT _callpc(SB), 1, $0

View file

@ -31,6 +31,7 @@ loop:
MOVW $_profin(SB), R(arg) /* force loading of profile */
B loop
TEXT _saveret(SB), 1, $0
TEXT _savearg(SB), 1, $0
RET

View file

@ -25,6 +25,7 @@ loop:
MOVW $_profin(SB), R0 /* force loading of profile */
JMP loop
TEXT _saveret(SB), 1, $0
TEXT _savearg(SB), 1, $0
RET

View file

@ -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 @@ struct Plink
#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 @@ _profin(void)
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 @@ out:
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 @@ _profout(void)
break;
}
_tos->prof.pp = p->old;
return arg;
return _restore(arg, ret);
}
void

View file

@ -26,6 +26,7 @@ loop:
MOVW $_profin(SB), R3 /* force loading of profile */
BR loop
TEXT _saveret(SB), 1, $0
TEXT _savearg(SB), 1, $0
RETURN

View file

@ -33,6 +33,7 @@ loop:
MOVW $_profin(SB), R9 /* force loading of profile */
JMP loop
TEXT _saveret(SB), 1, $0
TEXT _savearg(SB), 1, $0
RETURN