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

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

Re: [avr-gcc-list] swap bits


From: Bruce D. Lightner
Subject: Re: [avr-gcc-list] swap bits
Date: Tue, 21 Jan 2003 12:49:16 -0800

Christian Ludlam wrote:

> On 21 Jan Klaus Rudolph wrote:
> 
> > 51 cycles total without wasting any register.
> > 10 words flash.
> > 51 cycles is very expensive. Any better ideas here :-)
> 
> Which processor is this running on?
> 
> You could use a table lookup in 4 bits to reduce flash usage - this code
> requires an architecture with enhanced LPM addressing modes:
> 
> ; E r16 = byte
> ; X r16 = reversed byte
> reverse_byte
>         ldi     ZL,(table * 2) & 0xff           ; 1
>         ldi     ZH,(table >> 7)                 ; 1
>                                                 ;
>         mov     r0,r16                          ; 1
>         andi    r16,0x0f                        ; 1
>         add     ZL,r16                          ; 1
>         adc     ZH,__zero_reg__                 ; 1
>         mov     r16,r0                          ; 1
>         lpm     R0,Z                            ; 2
>                                                 ;
>         ldi     ZL,(table * 2) & 0xff           ; 1
>         ldi     ZH,(table >> 7)                 ; 1
>                                                 ;
>         swap    r16                             ; 1
>         andi    r16,0x0f                        ; 1
>         add     ZL,r16                          ; 1
>         adc     ZH,__zero_reg__                 ; 1
>         lpm     R16,Z                           ; 2
>                                                 ;
>         swap    r0                              ; 1
>         or      r16,r0                          ; 1
> 
> table   db      0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15
> 
> Total 20 cycles, 24 flash words. You could optimise it further by ensuring
> the table doesn't cross a page boundary and removing the adc instructions.
> 
> --
> Christian Ludlam
> address@hidden
> avr-gcc-list at http://avr1.org

How about this "brute force" AVR gcc assembly language macro...

   #define reverse(a) ({ \
           unsigned char ch; \
           asm volatile ( \
           "ror %1" "\n\t" \
           "rol %0" "\n\t" \
           "ror %1" "\n\t" \
           "rol %0" "\n\t" \
           "ror %1" "\n\t" \
           "rol %0" "\n\t" \
           "ror %1" "\n\t" \
           "rol %0" "\n\t" \
           "ror %1" "\n\t" \
           "rol %0" "\n\t" \
           "ror %1" "\n\t" \
           "rol %0" "\n\t" \
           "ror %1" "\n\t" \
           "rol %0" "\n\t" \
           "ror %1" "\n\t" \
           "rol %0" "\n\t" \
           "ror %1"  /* restore input register */ \
           : /* output */ "=r&" (ch) \
           : /* input */ "r" ((uint8_t)(a)) \
           ); \
           ch; \
   })

A total of 17 cycles, 17 flash words.  

This macro, as written, forces the "input" and "output" registers
to be different (i.e., because of the "&").  Perhaps someone smarter
than I could reduce this by one cycle (and one flash word) by
deleting the last ROR and somehow telling the code generator you
were destroying the input register.

My test program...

    unsigned char test(unsigned char ch)
    {
        return reverse(ch);
    }

...generates the following assembly language listing (using
the avr-gcc switch "-Wa,-almshd=test.lst")...

     79            .section .text
     82            .global test
     84            test:
      35:utest.c       **** unsigned char test(unsigned char x)
      36:utest.c       **** {
     86            .LM1:
     87            /* prologue: frame size=0 */
     88            /* prologue end (size=0) */
     37:utest.c       ****     return reverse(x);
     90            .LM2:
     91            .LBB2:
     92            .LBB3:
     93            /* #APP */
     94 0000 9795          ror r25
     95 0002 881F          rol r24
     96 0004 9795          ror r25
     97 0006 881F          rol r24
     98 0008 9795          ror r25
     99 000a 881F          rol r24
    100 000c 9795          ror r25
    101 000e 881F          rol r24
    102 0010 9795          ror r25
    103 0012 881F          rol r24
    104 0014 9795          ror r25
    105 0016 881F          rol r24
    106 0018 9795          ror r25
    107 001a 881F          rol r24
    108 001c 9795          ror r25
    109 001e 881F          rol r24
    110 0020 9795          ror r25
    111
    112            /* #NOAPP */
    113            .LBE3:
    114 0022 9927          clr r25
     38:utest.c       **** }
    116            .LM3:
    117            .LBE2:
    118            /* epilogue: frame size=0 */
    119 0024 0895          ret
    120            /* epilogue end (size=1) */
    121            /* function test size 38 (37) */

Best regards,

Bruce

-- 
 Bruce D. Lightner
 Lightner Engineering
 La Jolla, California
 Voice: +1-858-551-4011
 FAX: +1-858-551-0777
 Email: address@hidden
 URL: http://www.lightner.net/lightner/bruce/
avr-gcc-list at http://avr1.org



reply via email to

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