Discussion:
Bad xasm in __lwp_getprivate_fast
Anders Magnusson
2014-10-15 10:06:18 UTC
Permalink
While doing some testing I came across this not-so-correct extended
assembler in mcontext.h:

static __inline void *
__lwp_getprivate_fast(void)
{
register void *tcb __asm("r0");
__asm("chmk %0" :: "i"(SYS__lwp_getprivate) : "r0");
return tcb;
}

The result from chmk will be in r0.

The asm line says that r0 will be destroyed in the asm statement. In
this particular case it will most likely work because gcc handles tcb as
an uninitialized variable and it will get the r0 value anyway as long as
the code is not reordered (which it may be). If tcb is assigned 0 before
the asm statement it will fail.

Correct would be to write something like

__asm("chmk %0" : "=r"(tcb): "i"(SYS__lwp_getprivate));

which tells that the result will be in tcb (e.g. r0).

Comments? Otherwise I will go ahead and fix this.

-- Ragge
Matt Thomas
2014-10-15 15:42:25 UTC
Permalink
Post by Anders Magnusson
static __inline void *
__lwp_getprivate_fast(void)
{
register void *tcb __asm("r0");
__asm("chmk %0" :: "i"(SYS__lwp_getprivate) : "r0");
return tcb;
}
The result from chmk will be in r0.
The asm line says that r0 will be destroyed in the asm statement. In this particular case it will most likely work because gcc handles tcb as an uninitialized variable and it will get the r0 value anyway as long as the code is not reordered (which it may be). If tcb is assigned 0 before the asm statement it will fail.
Correct would be to write something like
__asm("chmk %0" : "=r"(tcb): "i"(SYS__lwp_getprivate));
which tells that the result will be in tcb (e.g. r0).
Comments? Otherwise I will go ahead and fix this.
That won't do the right thing since that will emit chmk %r0.
Anders Magnusson
2014-10-15 19:47:15 UTC
Permalink
Post by Matt Thomas
Post by Anders Magnusson
static __inline void *
__lwp_getprivate_fast(void)
{
register void *tcb __asm("r0");
__asm("chmk %0" :: "i"(SYS__lwp_getprivate) : "r0");
return tcb;
}
The result from chmk will be in r0.
The asm line says that r0 will be destroyed in the asm statement. In this particular case it will most likely work because gcc handles tcb as an uninitialized variable and it will get the r0 value anyway as long as the code is not reordered (which it may be). If tcb is assigned 0 before the asm statement it will fail.
Correct would be to write something like
__asm("chmk %0" : "=r"(tcb): "i"(SYS__lwp_getprivate));
which tells that the result will be in tcb (e.g. r0).
Comments? Otherwise I will go ahead and fix this.
That won't do the right thing since that will emit chmk %r0.
Yetch, of course not, it should be %1. Thanks.

-- Ragge
Matt Thomas
2014-10-15 20:04:38 UTC
Permalink
Post by Anders Magnusson
Post by Matt Thomas
Post by Anders Magnusson
static __inline void *
__lwp_getprivate_fast(void)
{
register void *tcb __asm("r0");
__asm("chmk %0" :: "i"(SYS__lwp_getprivate) : "r0");
return tcb;
}
The result from chmk will be in r0.
The asm line says that r0 will be destroyed in the asm statement. In this particular case it will most likely work because gcc handles tcb as an uninitialized variable and it will get the r0 value anyway as long as the code is not reordered (which it may be). If tcb is assigned 0 before the asm statement it will fail.
Correct would be to write something like
__asm("chmk %0" : "=r"(tcb): "i"(SYS__lwp_getprivate));
which tells that the result will be in tcb (e.g. r0).
Comments? Otherwise I will go ahead and fix this.
That won't do the right thing since that will emit chmk %r0.
Yetch, of course not, it should be %1. Thanks.
The problem is that %0 isn't referenced and it may not be r0.

Maybe combining the two?
Anders Magnusson
2014-10-15 20:19:55 UTC
Permalink
Post by Matt Thomas
Post by Anders Magnusson
Post by Matt Thomas
Post by Anders Magnusson
static __inline void *
__lwp_getprivate_fast(void)
{
register void *tcb __asm("r0");
__asm("chmk %0" :: "i"(SYS__lwp_getprivate) : "r0");
return tcb;
}
The result from chmk will be in r0.
The asm line says that r0 will be destroyed in the asm statement. In this particular case it will most likely work because gcc handles tcb as an uninitialized variable and it will get the r0 value anyway as long as the code is not reordered (which it may be). If tcb is assigned 0 before the asm statement it will fail.
Correct would be to write something like
__asm("chmk %0" : "=r"(tcb): "i"(SYS__lwp_getprivate));
which tells that the result will be in tcb (e.g. r0).
Comments? Otherwise I will go ahead and fix this.
That won't do the right thing since that will emit chmk %r0.
Yetch, of course not, it should be %1. Thanks.
The problem is that %0 isn't referenced and it may not be r0.
Maybe combining the two?
Hm. Looking in
https://gcc.gnu.org/onlinedocs/gcc/Local-Reg-Vars.html#Local-Reg-Vars it
looks like it should be safe even if tcb is not referenced other than in
the argument list. Or did I miss something?

-- Ragge

Loading...