Search code examples
avravr-gcc

Is it possible to force particular registers in inline assembly code?


I have the following assembly code:

  __asm__ __volatile__ (
  "1: subi %0, 1"        "\n\t"
  "brne 1b"
  : "=d" (__count)
  : "M" (__count));

which results in the following compiler ouptut

  ce:   81 50           subi    r24, 0x01   ; 1
  d0:   f1 f7           brne    .-4         ; 0xce <main>
  d2:   80 e0           ldi r24, 0x00   ; 0
  d4:   90 e0           ldi r25, 0x00   ; 0

How can i achieve the following:

  ce:   81 50           subi    r16, 0x01   ; 1
  d0:   f1 f7           brne    .-4         ; 0xce <main>
  d2:   80 e0           ldi r16, 0x00   ; 0

Is it even possible to tell the compiler to use r16 instead of r24:r25? That way i can reduce the cycle count by 1 which is used by the ldi r25,0x00 line.

Thanks Jack


Solution

  • This question is old and you most certainly already solved it, but for archiving purposes, let me answer it: yes, you can. Declare __count like this:

    register <type> __count __asm__ ("r16");
    

    And voilá! Using the GNU extension explicit register variables, you've declared that the C variable __count should always be placed in r16 wherever it is used - including outside of an ASM call.

    Note that this declaration should have local scope, otherwise the compiler will avoid using this register in other functions.