I'm trying to use some PPC assembly code in C, but I'm having trouble understanding and transposing this particular piece of ASM into the GNU GCC format:
...
b 1f
1:
lis p0, HI(2f)
ori p0, p0, LO(2f)
mtsrr0 p0
rfi
2:
mtssr0 p1 /* Restore srr0 & srr1 */
mtssr1 p2
...
The lines in question are those that reference 2f. I'm aware of Local Labels and I can only assume that is what is meant by 2f in those two instructions. Looking at the more general mtspr instruction, the RS parameter should be a register.
EDIT: Peter Cordes helped me understand the intent of this code. It looks like we're using lis
and ori
to build the 32 bit address of the label 2:
to load into ssr0. The following quote from the PowerPC Architecture Primer completely explains the intent of this assembly.
Save/restore registers (SRR0 and SRR1) — SRR0 holds the address of the instruction where an interrupted process should resume. When rfi executes, instruction execution continues at the address in SRR0. In Book E, SRR0 is used for non-critical interrupts.— SRR1 holds machine state information. When an interrupt is taken, MSR contents are placed in SRR1. When rfi executes, SRR1 contents are placed into MSR. In Book E, SRR1 is used for non-critical interrupts.
Now that I understand what the code is doing, I need to represent this code with GNU GCC in C:
__asm__ __volatile__ (
"b 1f\n\t"
"1:\n\t"
"lis %2, %hi(2f)\n\t"
"ori %2, %2, %lo(2f)\n\t"
"mtsrr0 %2\n\t"
"rfi\n\t"
"2:\n\t"
"mtsrr0 %0\n\t" /* srr0 = p1 */
"mtsrr1 %1\n\t" /* srr1 = p2 */
: "=r" (p1), "=r" (p2)
: "r" (val), "r" (p1), "r" (p2));
This yields the following error (twice, for each instance of 2f
I assume:
invalid 'asm': operand number missing after %-letter
Commenting out the lines with instructions lis
and ori
allows the code to compile without errors.