Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 4.0

Reference: GCC docs. A lot of the material here seems to have been written assuming that the inline assembly consists of a single instruction which reads inputs and then writes outputs (possibly overwriting inputs).

Wiki MarkupInline assembler code for the memory management package uses the GNU extension of named operands, e.g., "%\[foo\]". We generally use the "&" constraint for output operands; otherwise, the compiler assumes that the output operands are set as the very last actions of the code, after all input operands have been used. In such a case the compiler may use the same register for an input operand and an output operand. Using "&" marks the output operand as "early clobber",i.e., the register is altered early on, perhaps before all the inputs have been used.

We also use the trick of creating a register variable to use as an output only ("=") or input-output ("+") operand when we want the compiler to pick which register to use. Sometimes when we do that we want the compiler to avoid r0 because it can't be used as a base register. Then we use the "b" constraint instead of "r", where "b" means "register that can be a base register".

...

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 the PPC405 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"
	   );

...

*Example 2.* This code changes a specific memory location so it uses the "m" constraint; the compiler will replace "%\[saved\]" in the instruction with the correct addressing mode, e.g., base + offset. Note that if necessary the compiler will generate extra code to load the value of "this" into a base register.

Code Block
      register unsigned oldmsr;
      register unsigned newmsr;
      asm volatile
	(
	 // Save the exception-enabling bits of the current PPC405 MSR value.
	 "mfmsr %[oldmsr]                   \n\t"
	 "and   %[newmsr],%[oldmsr],%[mask] \n\t"
	 "stw   %[newmsr],%[save]           \n\t"
	 // Reset those enabling bits in the MSR.
	 "andc  %[newmsr],%[oldmsr],%[mask] \n\t"
	 "mtmsr %[newmsr]                   \n\t"
	 // Perform a context sync since the MSR value may have changed.
	 "isync"
	 :[save]"=m"(this->mSavedExcBits), [oldmsr]"=&r"(oldmsr), [newmsr]"=&r"(newmsr)
	 :[mask]"r"(ExceptionBitMask)
	 :
	 );

...