summaryrefslogtreecommitdiff
path: root/sys/src/libc
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2014-02-17 13:25:24 +0100
committercinap_lenrek <cinap_lenrek@felloff.net>2014-02-17 13:25:24 +0100
commit2c5c78425516590e894c9c334182073fcc56a10b (patch)
treeec4c8b58ec1d8144936bf8111382a6e7141d55c0 /sys/src/libc
parent87fcb107ef333f5dce7618e0f4c73d69ebc75eb5 (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.s1
-rw-r--r--sys/src/libc/68000/main9p.s1
-rw-r--r--sys/src/libc/68020/main9p.s1
-rw-r--r--sys/src/libc/alpha/main9p.s1
-rw-r--r--sys/src/libc/amd64/main9p.s3
-rw-r--r--sys/src/libc/arm/main9p.s1
-rw-r--r--sys/src/libc/mips/main9p.s1
-rw-r--r--sys/src/libc/port/profile.c32
-rw-r--r--sys/src/libc/power/main9p.s1
-rw-r--r--sys/src/libc/sparc/main9p.s1
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