Consider the following (compiler=GCC3.4.3, host=I686, target=powerpc-eabi):
typedef void(*pVoid)(void);
static inline bool1 kSetVector(uint1 level, pVoid func, int type) { int r; const int code = 0; __asm__ __volatile__ ( " li 0, %1 \n" /* code */ " mr 3, %2 \n" /* level */ " mr 4, %3 \n" /* func */ " mr 5, %4 \n" /* type */ " sc \n" /* System Call: may corrupt regs: result in r3 */ " mr %0, 3 \n" /* Return result */ : "=r" (r) : "rI" (code), "0" (level), "r" (func), "r" (type) : "r0", "cc", "memory" ); return r; } ... (void)kSetVector(31, SerialIoInterrupt, 3);
This compiles, & runs fine (producing the code below). However I would like to improve the efficiency, by eliminating the "mr" instructions to move arguments to & from registers. The "sc" needs the data in precisely the registers shown, so GCC needs to be coaxed into using those registers itself.
Generated code (comments added):
54:h/services.h **** static inline bool1 kSetVector(uint1 level, pVoid func, int type) { 203 .loc 2 54 0 204 019c 3940001F li 10,31 /* level */ 205 01a0 3D200000 lis 9,SerialIoInterrupt@ha /* func */ 206 01a4 39290000 la 9,SerialIoInterrupt@l(9) 207 01a8 39600003 li 11,3 /* type */ 208 .LBB3: 55:h/services.h **** int r; 56:h/services.h **** const int code = 0; 57:h/services.h **** __asm__ __volatile__ ( 209 .loc 2 57 0 210 01ac 38000000 li 0, 0 211 01b0 7D435378 mr 3, 10 /* The "mr's" I want to remove */ 212 01b4 7D244B78 mr 4, 9 213 01b8 7D655B78 mr 5, 11 214 01bc 44000002 sc 215 01c0 7C6A1B78 mr 10, 3 /* result */In the X86 builds of GCC, there are "register loading codes", as "c", "a" & "D" in the following example (from: "Using Inline Assembly With gcc" by Clark L. Coleman).
asm ("cld\n\t" "rep\n\t" "stosl" : /* no output registers */ : "c" (count), "a" (fill_value), "D" (dest) : "%ecx", "%edi" );
Is there a similar device for the PowerPC, whereby I can tell GCC to create the values in specific registers, so eliminating the need for those "mr" instructions? TIA,