diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2014-02-17 13:25:24 +0100 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2014-02-17 13:25:24 +0100 |
commit | 2c5c78425516590e894c9c334182073fcc56a10b (patch) | |
tree | ec4c8b58ec1d8144936bf8111382a6e7141d55c0 /sys/src/libc | |
parent | 87fcb107ef333f5dce7618e0f4c73d69ebc75eb5 (diff) |
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.
Diffstat (limited to 'sys/src/libc')
-rw-r--r-- | sys/src/libc/386/main9p.s | 1 | ||||
-rw-r--r-- | sys/src/libc/68000/main9p.s | 1 | ||||
-rw-r--r-- | sys/src/libc/68020/main9p.s | 1 | ||||
-rw-r--r-- | sys/src/libc/alpha/main9p.s | 1 | ||||
-rw-r--r-- | sys/src/libc/amd64/main9p.s | 3 | ||||
-rw-r--r-- | sys/src/libc/arm/main9p.s | 1 | ||||
-rw-r--r-- | sys/src/libc/mips/main9p.s | 1 | ||||
-rw-r--r-- | sys/src/libc/port/profile.c | 32 | ||||
-rw-r--r-- | sys/src/libc/power/main9p.s | 1 | ||||
-rw-r--r-- | sys/src/libc/sparc/main9p.s | 1 |
10 files changed, 28 insertions, 15 deletions
diff --git a/sys/src/libc/386/main9p.s b/sys/src/libc/386/main9p.s index a924d0aff..2aa130ca7 100644 --- a/sys/src/libc/386/main9p.s +++ b/sys/src/libc/386/main9p.s @@ -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 diff --git a/sys/src/libc/68000/main9p.s b/sys/src/libc/68000/main9p.s index 61e0294d5..ea773d6e3 100644 --- a/sys/src/libc/68000/main9p.s +++ b/sys/src/libc/68000/main9p.s @@ -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 diff --git a/sys/src/libc/68020/main9p.s b/sys/src/libc/68020/main9p.s index 6c64f6404..fe5b2ff1e 100644 --- a/sys/src/libc/68020/main9p.s +++ b/sys/src/libc/68020/main9p.s @@ -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 diff --git a/sys/src/libc/alpha/main9p.s b/sys/src/libc/alpha/main9p.s index defdb4842..6e24054d7 100644 --- a/sys/src/libc/alpha/main9p.s +++ b/sys/src/libc/alpha/main9p.s @@ -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 diff --git a/sys/src/libc/amd64/main9p.s b/sys/src/libc/amd64/main9p.s index 353b18088..c1a8fac2b 100644 --- a/sys/src/libc/amd64/main9p.s +++ b/sys/src/libc/amd64/main9p.s @@ -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 diff --git a/sys/src/libc/arm/main9p.s b/sys/src/libc/arm/main9p.s index cb51a4379..db98d6827 100644 --- a/sys/src/libc/arm/main9p.s +++ b/sys/src/libc/arm/main9p.s @@ -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 diff --git a/sys/src/libc/mips/main9p.s b/sys/src/libc/mips/main9p.s index 135d07522..f70c649b8 100644 --- a/sys/src/libc/mips/main9p.s +++ b/sys/src/libc/mips/main9p.s @@ -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 diff --git a/sys/src/libc/port/profile.c b/sys/src/libc/port/profile.c index 5647e3bf1..b1eb0afaa 100644 --- 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 @@ 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 diff --git a/sys/src/libc/power/main9p.s b/sys/src/libc/power/main9p.s index 76723cc10..c3dbcf125 100644 --- a/sys/src/libc/power/main9p.s +++ b/sys/src/libc/power/main9p.s @@ -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 diff --git a/sys/src/libc/sparc/main9p.s b/sys/src/libc/sparc/main9p.s index db464f485..73a3a4e22 100644 --- a/sys/src/libc/sparc/main9p.s +++ b/sys/src/libc/sparc/main9p.s @@ -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 |