Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Example 1. Here we alter the output "msr" early on (in the first instruction, in fact) so we use the ampersand. We also mark it as output-only ("=") instead of in-out ("+") because we don't care what the value is before the asm. The use of "volatile" and "memory" make sure that the compiler won't move instructions across the inline assembler code during the course of optimization. We need that because the inline code is changing the Machine State Register and hence the context in which instructions are executed; the isync instruction just affects reordering by the processor not the compiler. The compiler doesn't look at the instructions inside the asm, just at the lists of inputs, output and clobbers. (The "\n\t" at the end of each instruction just makes the assembly code output generated with -S look nice.)

Code Block
	register unsigned msr;
	asm volatile
	  (
	   // Make sure that address translation is disabled.
	   "mfmsr  %[msr]                 \n\t"
	   "rlwimi %[msr],%[zero],0,26,27 \n\t" // Clear translation bits (26-27) in MSR.
	   "mtmsr  %[msr]                 \n\t"
	   // Perform a context sync since we need to wait for translation
	   // to turn off. This will also purge any shadowed TLB entries
	   // which must be done before we turn translation back on.
	   "isync \n\t"
	   // Clear the zone-protection and PID registers.
	   "mtzpr %[zero] \n\t"
	   "mtpid %[zero] \n\t"
	   // Mark all TLB entries as invalid.
	   "tlbia"
	   : [msr]"=&r"(msr)
	   : [zero]"r"(0)
	   : "memory"
	   );

...

This is what was intended (to get it the constraint for "tmp" should be "=&r" instead of just "=r"):

Instruction

_head

first

%2

%1

%0

Setup

&first

&empty

&_head

?

?

lwarx

&first

&empty

&_head

?

&first

lwzx

&first

&empty

&_head

&empty

&first

stwcx.

&empty

&empty

&_head

&empty

&first