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/ape | |
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/ape')
-rw-r--r-- | sys/src/ape/lib/ap/386/main9p.s | 1 | ||||
-rw-r--r-- | sys/src/ape/lib/ap/alpha/main9p.s | 1 | ||||
-rw-r--r-- | sys/src/ape/lib/ap/amd64/main9p.s | 4 | ||||
-rw-r--r-- | sys/src/ape/lib/ap/arm/main9p.s | 1 | ||||
-rw-r--r-- | sys/src/ape/lib/ap/mips/main9p.s | 1 | ||||
-rw-r--r-- | sys/src/ape/lib/ap/plan9/profile.c | 27 | ||||
-rw-r--r-- | sys/src/ape/lib/ap/power/main9p.s | 1 | ||||
-rw-r--r-- | sys/src/ape/lib/ap/sparc/main9p.s | 1 |
8 files changed, 28 insertions, 9 deletions
diff --git a/sys/src/ape/lib/ap/386/main9p.s b/sys/src/ape/lib/ap/386/main9p.s index 1cd317eba..5d22c0f2e 100644 --- a/sys/src/ape/lib/ap/386/main9p.s +++ b/sys/src/ape/lib/ap/386/main9p.s @@ -40,6 +40,7 @@ loop: MOVL $0, AX JMP loop +TEXT _saveret(SB), 1, $0 TEXT _savearg(SB), 1, $0 RET diff --git a/sys/src/ape/lib/ap/alpha/main9p.s b/sys/src/ape/lib/ap/alpha/main9p.s index f8472fcd3..433671f3e 100644 --- a/sys/src/ape/lib/ap/alpha/main9p.s +++ b/sys/src/ape/lib/ap/alpha/main9p.s @@ -43,6 +43,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/ape/lib/ap/amd64/main9p.s b/sys/src/ape/lib/ap/amd64/main9p.s index dfd3450ea..fc4afe701 100644 --- a/sys/src/ape/lib/ap/amd64/main9p.s +++ b/sys/src/ape/lib/ap/amd64/main9p.s @@ -37,7 +37,11 @@ loop: 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 diff --git a/sys/src/ape/lib/ap/arm/main9p.s b/sys/src/ape/lib/ap/arm/main9p.s index 318291d81..2d6849c00 100644 --- a/sys/src/ape/lib/ap/arm/main9p.s +++ b/sys/src/ape/lib/ap/arm/main9p.s @@ -47,6 +47,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/ape/lib/ap/mips/main9p.s b/sys/src/ape/lib/ap/mips/main9p.s index a5430763a..195fba08b 100644 --- a/sys/src/ape/lib/ap/mips/main9p.s +++ b/sys/src/ape/lib/ap/mips/main9p.s @@ -49,6 +49,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/ape/lib/ap/plan9/profile.c b/sys/src/ape/lib/ap/plan9/profile.c index a69e65f2b..969a74076 100644 --- a/sys/src/ape/lib/ap/plan9/profile.c +++ b/sys/src/ape/lib/ap/plan9/profile.c @@ -23,7 +23,8 @@ typedef unsigned long long uvlong; 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 @@ struct Plink #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 @@ _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; @@ -96,16 +104,17 @@ out: 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 @@ _profout(void) break; } _tos->prof.pp = p->old; - return arg; + return _restore(arg, ret); } /* stdio may not be ready for us yet */ diff --git a/sys/src/ape/lib/ap/power/main9p.s b/sys/src/ape/lib/ap/power/main9p.s index 809ddc451..613594aaf 100644 --- a/sys/src/ape/lib/ap/power/main9p.s +++ b/sys/src/ape/lib/ap/power/main9p.s @@ -40,6 +40,7 @@ loop: MOVW $_profin(SB), R4 /* force loading of profile */ BR loop +TEXT _saveret(SB), 1, $0 TEXT _savearg(SB), 1, $0 RETURN diff --git a/sys/src/ape/lib/ap/sparc/main9p.s b/sys/src/ape/lib/ap/sparc/main9p.s index 0bd9b5aa6..b23ea6afa 100644 --- a/sys/src/ape/lib/ap/sparc/main9p.s +++ b/sys/src/ape/lib/ap/sparc/main9p.s @@ -48,6 +48,7 @@ loop: MOVW $_profin(SB), R0 /* force loading of profile */ JMP loop +TEXT _saveret(SB), 1, $0 TEXT _savearg(SB), 1, $0 RETURN |