PowerPC function returning long long
I was playing with the inline assembler and the ppc timebase facility and created the following function -
unsigned long long get_timebase(void) {
unsigned long tbu;
unsigned long tbl;
unsigned long junk;
__asm__ __volatile__ ("
1: mftbu %2
mftb %1
mftbu %0
cmpw %0,%2
bne 1b"
: "=r" (tbu), "=r" (tbl), "=r" (junk));
return ((unsigned long long)tbu << 32) | tbl;
}This function compiles to (gcc 2.95.1) :
get_timebase:
1: mftbu 5
mftb 6
mftbu 0
cmpw 0,5
bne 1b
mr 10,0
li 9,0
mr 7,10
mr 12,6
li 8,0
li 11,0
or 3,7,11
or 4,8,12
blrAs one can see, most of this is a bunch of register thrashing. I expected it to generate something along this:
1: mftbu 5
mftb 4
mftbu 3
cmpw 3,4
bne 1bblr
I assume it is because gcc is struggling with the code in the return statement.
Is there a better way to write the return statement?
Is there a register constraint for a long long register (like the "A" constraint for the x86 which returns the 64 bit data in edx:eax)?
Any ideas?
Yes I know that there is a similar function in arch/ppc/kernel/apus_setup.c which isn't quite what I want.
Bob
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
Quoted 4 lines · Bob Doyle
I was playing with the inline assembler and the ppc timebase facility and created the following function -
Quoted 13 lines
unsigned long long get_timebase(void) {
unsigned long tbu;
unsigned long tbl;
unsigned long junk;
__asm__ __volatile__ ("
1: mftbu %2
mftb %1
mftbu %0
cmpw %0,%2
bne 1b"
: "=r" (tbu), "=r" (tbl), "=r" (junk));
return ((unsigned long long)tbu << 32) | tbl;
}Rather write:
unsigned long long get_timebase(void) {
unsigned long long retval;
unsigned long junk;
__asm__ __volatile__ ("
1: mftbu %1
mftb %0+1
mftbu %0
cmpw %0,%1
bne 1b"
: "=r" (retval), "=r" (junk));
return retval;
}which generates on my machine (with optimization of course):
Disassembly of section .text:
00000000 <get_timebase>:
0: 7c 0d 42 e6 mftbu r0 4: 7c 8c 42 e6 mftb r4 8: 7c 6d 42 e6 mftbu r3 c: 7c 03 00 00 cmpw r3,r0 10: 40 82 ff f0 bne 0 <get_timebase> 14: 4e 80 00 20 blr
Note: as you see you can access the second register of a 64 bit value with %n+1. At this point I'd rather declarre the function inline...
Quoted 2 lines
I assume it is because gcc is struggling with the code in the return statement.
Indeed. 64 bit integer handling is currently poor on PPC (except PPC64 of course).
Quoted 5 lines
Is there a better way to write the return statement?
Is there a register constraint for a long long register (like the "A" constraint for the x86 which returns the 64 bit data in edx:eax)?
No, because for 64 bit values, gcc always allocates a register pair Rn/Rn+1. That why you can use the %n+1 trick. Register numbering on Intel is a mess, the HW order atually is eax,ecx,edx,ebx,esp,ebp,esi,edi from the register encoding and the pusha/popa instruction (but then it is completely different for 16 bit adressing modes). And for 8 bit registers it is al,cl,dl,bl,ah,ch,dh,bh.
Regards,
Gabriel.
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
Quoted 24 lines · Gabriel Paubert
Quoted 4 lines · Bob Doyle
I was playing with the inline assembler and the ppc timebase facility and created the following function -
Quoted 13 lines
unsigned long long get_timebase(void) { unsigned long tbu; unsigned long tbl; unsigned long junk; __asm__ __volatile__ (" 1: mftbu %2 mftb %1 mftbu %0 cmpw %0,%2 bne 1b" : "=r" (tbu), "=r" (tbl), "=r" (junk)); return ((unsigned long long)tbu << 32) | tbl; }Rather write:
Quoted 12 lines
unsigned long long get_timebase(void) {
unsigned long long retval;
unsigned long junk;
__asm__ __volatile__ ("
1: mftbu %1
mftb %0+1
mftbu %0
cmpw %0,%1
bne 1b"
: "=r" (retval), "=r" (junk));
return retval;
}The above doesn't work with -mreg-names and/or -pedantic. Instead you should write:
unsigned long long get_timebase(void) {
unsigned long long retval;
unsigned long junk;
__asm__ __volatile__ ("\n\
1: mftbu %1\n\
mftb %L0\n\
mftbu %0\n\
cmpw %0,%1\n\
bne 1b"
: "=r" (retval), "=r" (junk));
return retval;
}Signature · 5 lines
Michael Meissner, Cygnus Solutions PMB 198, 174 Littleton Road #3, Westford, Massachusetts 01886 email: [email protected] phone: 978-486-9304 fax: 978-692-4482 ** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
Quoted 5 lines · Michael Meissner
Quoted 3 lines · Gabriel Paubert
On Wed, 13 Oct 1999, Bob Doyle wrote:
[snip]
Quoted 15 lines
The above doesn't work with -mreg-names and/or -pedantic. Instead you should write:
unsigned long long get_timebase(void) { unsigned long long retval; unsigned long junk; __asm__ __volatile__ ("\n\ 1: mftbu %1\n\ mftb %L0\n\ mftbu %0\n\ cmpw %0,%1\n\ bne 1b" : "=r" (retval), "=r" (junk)); return retval; }
Thanks, thats just what I was looking for...
I've found several tutorials on x86 GNU inline asm but none on the PowerPC.
If I were to write a HOWTO would anyone volunteer to proof read and/or contribute code examples? I suspect I'm not the only one struggling through this.
Bob Doyle
[email protected]
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
Quoted 26 lines · Bob Doyle
Quoted 5 lines · Michael Meissner
Quoted 3 lines · Gabriel Paubert
On Wed, 13 Oct 1999, Bob Doyle wrote:
[snip]
Quoted 15 lines
The above doesn't work with -mreg-names and/or -pedantic. Instead you should write:
unsigned long long get_timebase(void) { unsigned long long retval; unsigned long junk; __asm__ __volatile__ ("\n\ 1: mftbu %1\n\ mftb %L0\n\ mftbu %0\n\ cmpw %0,%1\n\ bne 1b" : "=r" (retval), "=r" (junk)); return retval; }
Quoted 7 lines
Thanks, thats just what I was looking for...
I've found several tutorials on x86 GNU inline asm but none on the PowerPC.
If I were to write a HOWTO would anyone volunteer to proof read and/or contribute code examples? I suspect I'm not the only one struggling through this.
I don't know whether he reads this list, but the two PowerPC GCC maintainers are David Edelsohn <[email protected]> and myself <[email protected]>. We can probably offer suggestions, though I suspect we probably don't have as much time to actually write anything.
Signature · 5 lines
Michael Meissner, Cygnus Solutions PMB 198, 174 Littleton Road #3, Westford, Massachusetts 01886 email: [email protected] phone: 978-486-9304 fax: 978-692-4482 ** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
[TANGENT] GNU as [was: Re: PowerPC function returning long long]
In reply to Bob DoyleQuoted 2 lines · Bob Doyle
I've found several tutorials on x86 GNU inline asm but none on the PowerPC.
As an aside, does GNU as actually work on the PPC? The GNU manuals for the assembler at:
www.gnu.org/manual/gas-2.9.1/html_chapter/as_toc.html
make no mention of this arch.
Bill
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
Re: [TANGENT] GNU as [was: Re: PowerPC function returning long long]
Wow, that manual is out of date. Browse around under
<http://sourceware.cygnus.com/binutils>.
Quoted 5 lines · Bill Brooks
Quoted 2 lines · Bob Doyle
I've found several tutorials on x86 GNU inline asm but none on the PowerPC.
Quoted 11 lines
As an aside, does GNU as actually work on the PPC? The GNU manuals for the assembler at:
www.gnu.org/manual/gas-2.9.1/html_chapter/as_toc.html
make no mention of this arch.
Bill
Dan
/--------------------------------\ /--------------------------------\
| Daniel Jacobowitz |__| SCS Class of 2002 | | Debian GNU/Linux Developer __ Carnegie Mellon University | | [email protected] | | [email protected] | \--------------------------------/ \--------------------------------/
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
Re: [TANGENT] GNU as [was: Re: PowerPC function returning long long]
In reply to Bill BrooksQuoted 11 lines · Bill Brooks
Quoted 2 lines · Bob Doyle
I've found several tutorials on x86 GNU inline asm but none on the PowerPC.
As an aside, does GNU as actually work on the PPC? The GNU manuals for the assembler at:
www.gnu.org/manual/gas-2.9.1/html_chapter/as_toc.html
make no mention of this arch.
Yes it supports the rs6000 and PowerPC.
Signature · 5 lines
Michael Meissner, Cygnus Solutions PMB 198, 174 Littleton Road #3, Westford, Massachusetts 01886 email: [email protected] phone: 978-486-9304 fax: 978-692-4482 ** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
Quoted 7 lines · Bob Doyle
Thanks, thats just what I was looking for...
I've found several tutorials on x86 GNU inline asm but none on the PowerPC.
If I were to write a HOWTO would anyone volunteer to proof read and/or contribute code examples? I suspect I'm not the only one struggling through this.
Yes! I'd certainly help as I could, and I would love to see someone put such a document together.
Dan
/--------------------------------\ /--------------------------------\
| Daniel Jacobowitz |__| SCS Class of 2002 | | Debian GNU/Linux Developer __ Carnegie Mellon University | | [email protected] | | [email protected] | \--------------------------------/ \--------------------------------/
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/