avr-gcc-list
[Top][All Lists]
Advanced

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

[avr-gcc-list] Missed optimisations when manipulating bytes


From: David Brown
Subject: [avr-gcc-list] Missed optimisations when manipulating bytes
Date: Thu, 04 Oct 2007 16:35:14 +0200
User-agent: Thunderbird 2.0.0.6 (Windows/20070728)

I was looking at the assembly generated from a program I'm working on, and it strikes me that there is a lot of scope for improvement in the register manipulation when mixing bytes and 16-bit words like in the code below. I've only tested using the latest winavr release (gcc 4.1.2), so maybe newer versions are better.


typedef unsigned char uint8_t;
typedef unsigned int uint16_t;

// Relevant exerts from <avr/io.h> for quick test
#define SPIF    7
//#define SPDR    _SFR_IO8 (0x2E)
#define SPDR (*(volatile uint8_t*)(0x4E))

uint8_t spiByte(uint8_t b) {
        SPDR = b;
        while (!(SPSR & Bit(SPIF))) ;
        return SPDR;
}

uint16_t spiWord(uint16_t w) {
        uint16_t r;
        r = spiByte(w & 0xff);              // LSB first
        r |= (spiByte(w >> 8)) << 8;
        return r;
}


Relevant parts of listing file:

  21                    spiByte:
  28 0000 8EBD          out 78-0x20,r24
  29                    .L2:
  31 0002 0DB4          in __tmp_reg__,77-0x20
  32 0004 07FE          sbrs __tmp_reg__,7
  33 0006 00C0          rjmp .L2
  35 0008 8EB5          in r24,78-0x20
  38 000a 9927          clr r25
  39                    
  40 000c 0895          ret
  41                    
  68                    spiWord:
  77 0018 8EBD          out 78-0x20,r24
  78                    .L10:
  80 001a 0DB4          in __tmp_reg__,77-0x20
  81 001c 07FE          sbrs __tmp_reg__,7
  82 001e 00C0          rjmp .L10
  84 0020 3EB5          in r19,78-0x20
  88 0022 892F          mov r24,r25
  89 0024 9927          clr r25

  94 0026 8EBD          out 78-0x20,r24
  95                    .L12:
  97 0028 0DB4          in __tmp_reg__,77-0x20
  98 002a 07FE          sbrs __tmp_reg__,7
  99 002c 00C0          rjmp .L12
 101 002e 2EB5          in r18,78-0x20
 105 0030 832F          mov r24,r19
 106 0032 9927          clr r25

 108 0034 3327          clr r19
 109 0036 322F          mov r19,r18
 110 0038 2227          clr r18
 112 003a 822B          or r24,r18
 113 003c 932B          or r25,r19
 116 003e 0895          ret


The spiByte function is fine, but the spiWord function leaves plenty of scope for improvement:

spiWord:
        out 78-0x20, r24
.L1:
        in __tmp_reg__, 77-0x20
        sbrs __tmp_reg__, 7
        rjmp .L1
        in r24, 77-0x20

        out 78-0x20, r25
.L1:
        in __tmp_reg__, 77-0x20
        sbrs __tmp_reg__, 7
        rjmp .L1
        in r25, 77-0x20

        ret


mvh.,

David




reply via email to

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