avr-libc-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-libc-dev] [bug #21623] boot.h: Use the "z" register constraint


From: Wouter van Gulik
Subject: Re: [avr-libc-dev] [bug #21623] boot.h: Use the "z" register constraint
Date: Wed, 21 Nov 2007 10:38:00 +0100
User-agent: Thunderbird 2.0.0.9 (Windows/20071031)

Also consider the fuse bit get routine. This scheme gives more knowledge to the compiler, unfortunately gcc fails to see the loading of r31 can done once:

using this:

=========================================================================
static inline uint8_t boot_lock_fuse_bits_new(uint16_t address)
{
    uint8_t result;
register uint16_t adr asm("r30") = address; //make sure it's in z register aka r30:r31

    asm volatile(
        "sts %1, %2\n\t"
        "lpm %0, Z"
        : "=r" (result)
        : "i" (_SFR_MEM_ADDR(__SPM_REG)),
          "r" ((uint8_t)__BOOT_LOCK_BITS_SET),
          "z" (adr)
        : "r0"
    );
    return result;
}

uint8_t bar(void)
{
        uint8_t temp;
        uint16_t adr = 0;
        temp  = boot_lock_fuse_bits_new(adr++);
        temp += boot_lock_fuse_bits_new(adr++);
        temp += boot_lock_fuse_bits_new(adr++);
        temp += boot_lock_fuse_bits_new(adr++);
        return temp;
}

=========================================================================

It gives this assembler output:
.global bar
        .type   bar, @function
bar:
/* prologue: frame size=0 */
/* prologue end (size=0) */
        ldi r30,lo8(0)   ;  8   *movhi/4        [length = 2]
        ldi r31,hi8(0)
        ldi r25,lo8(9)   ;  10  *movqi/2        [length = 1]
/* #APP */
        sts 87, r25
        lpm r24, Z
/* #NOAPP */
        ldi r30,lo8(1)   ;  16  *movhi/4        [length = 2]
        ldi r31,hi8(1)
/* #APP */
        sts 87, r25
        lpm r30, Z
/* #NOAPP */
        add r24,r30      ;  22  addqi3/1        [length = 1]
        ldi r30,lo8(2)   ;  24  *movhi/4        [length = 2]
        ldi r31,hi8(2)
/* #APP */
        sts 87, r25
        lpm r18, Z
/* #NOAPP */
        ldi r30,lo8(3)   ;  29  *movhi/4        [length = 2]
        ldi r31,hi8(3)
/* #APP */
        sts 87, r25
        lpm r25, Z
/* #NOAPP */
        add r25,r18      ;  36  addqi3/1        [length = 1]
        add r24,r25      ;  37  addqi3/1        [length = 1]
        clr r25  ;  45  zero_extendqihi2/1      [length = 1]
/* epilogue: frame size=0 */
        ret
/* epilogue end (size=1) */
/* function bar size 30 (29) */
        .size   bar, .-bar


This is not smaller nor faster but it could have been. If gcc would leave r31, or do a adiw I tried against 4.1.2 using -Wall -Os -mmcu=atmega16. Maybe 4.2.2 or 4.3.0 is better?

It does however use r30 as output which could save some speed and code when no other register is available.

HTH,

Wouter





reply via email to

[Prev in Thread] Current Thread [Next in Thread]