"=rXX" asm constraints on powerpc?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

I want to implement system call stubs on PPC.  The code I want to end up
this is the following ("tlbia" is really used as a slow system call here,
that returns a pointer and three ints in r3 to r6):

00000000 <get_kip>:
 0:   7c 6a 1b 78     mr      r10,r3
 4:   7c 88 23 78     mr      r8,r4
 8:   7c a7 2b 78     mr      r7,r5
 c:   7c 00 02 e4     tlbia
10:   90 8a 00 00     stw     r4,0(r10)
14:   90 a8 00 00     stw     r5,0(r8)
18:   90 c7 00 00     stw     r6,0(r7)
1c:   4e 80 00 20     blr

Normally, I would do this like this (which works on ia32 for EAX, EBX, etc):

void *get_kip (int *r_version, int *r_flags, int *r_id)
{
  void *kip;
  asm ("tlbia\n"
       : "=r3" (kip), "=r4" (*r_version), "=r5" (*r_flags), "=r6" (*r_id));
  return kip;
}

However, "=rX" are not valid output register constraints, as defined in
rs6000.h.  You can only specify generic register classes, not individual
registers.  But the system calls are laid out to allow maximum performance
if you make proper use of it.  For example, what you want to return from the C
function is usually already in r3 (and r3/r4 if it is 64 bit).

I tried various things, like using local variables, mr and stw instructions
to move data around.  The best I could come up with is this:

void *
get_kip (int *r_version, int *r_flags, int *r_id)
{
  void *kip;
                                                                                
  asm ("tlbia\n"
       "stw %%r4, 0(%1)\n"
       "stw %%r5, 0(%2)\n"
       "stw %%r6, 0(%3)\n"
       "mr %0, %%r3\n"
       : "=&r" (kip)
       : "r" (r_version), "r" (r_flags), "r" (r_id)
       : "r3", "r4", "r5", "r6");
                                                                                
  return kip;
}

Which is assembled to:
00000000 <get_kip>:
   0:   7c 6a 1b 78     mr      r10,r3
   4:   7c 8b 23 78     mr      r11,r4
   8:   7c a0 2b 78     mr      r0,r5
   c:   7c 00 02 e4     tlbia
  10:   90 8a 00 00     stw     r4,0(r10)
  14:   90 ab 00 00     stw     r5,0(r11)
  18:   90 c0 00 00     stw     r6,0(r0)
  1c:   7c 69 1b 78     mr      r9,r3
  20:   7d 23 4b 78     mr      r3,r9
  24:   4e 80 00 20     blr

That comes close, but unnecessarily moves r3 to r9 forth and back.  GCC
doesn't opimize such inline assembler, and I can not remove the mr
instruction because I can not otherwise ensure that register r3 is used.

It gets funny if you specify register variables:

void *
get_kip (int *r_version, int *r_flags, int *r_id)
{
  register void *kip asm ("r3");
  register int version asm ("r4");
  register int flags asm ("r5");
  register int id asm ("r6");
 
  asm ("tlbia\n"
       "mr %0, %%r3\n"
       "mr %1, %%r4\n"
       "mr %2, %%r5\n"
       "mr %3, %%r6\n"
       : "=r" (kip), "=r" (version), "=r" (flags), "=r" (id) : );
 
  *r_version = version;
  *r_flags = flags;
  *r_id = id;
 
  return kip;
}

Which is compiled to:
00000000 <get_kip>:
   0:   7c 69 1b 78     mr      r9,r3
   4:   7c 8b 23 78     mr      r11,r4
   8:   7c aa 2b 78     mr      r10,r5
   c:   7c 00 02 e4     tlbia
  10:   7c 63 1b 78     mr      r3,r3
  14:   7c 84 23 78     mr      r4,r4
  18:   7c a5 2b 78     mr      r5,r5
  1c:   7c c6 33 78     mr      r6,r6
  20:   90 89 00 00     stw     r4,0(r9)
  24:   90 ab 00 00     stw     r5,0(r11)
  28:   90 ca 00 00     stw     r6,0(r10)
  2c:   4e 80 00 20     blr

It's clear what goes wrong here: gcc already allocates the right register
for all variables, but it can not take advantage of that fact because it can
not optimize away the mr instructions.

This shows to me that the rX output constraints should be supported, to make
programming such things possible.  Or am I overlooking something?

Thanks,
Marcus





-- 
`Rhubarb is no Egyptian god.' GNU      http://www.gnu.org    marcus@xxxxxxx
Marcus Brinkmann              The Hurd http://www.gnu.org/software/hurd/
Marcus.Brinkmann@xxxxxxxxxxxxxxxxxx
http://www.marcus-brinkmann.de/


[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux