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/