Swap Befehl für Byte bei Atmega 32

#2828942
Lesenswert?

http://www.rn-wissen.de/index.php/Inline-Assembler_in_avr-gcc#swap_Nibbles

1
static inline unsigned char swap (unsigned char x)
2
{
3
    asm volatile ("swap %0" : "=r" (x) : "0" (x));
4
    return x;
5
}


Meinst du so? Einziger Nachteil (vielleicht): Hilfsfunktion musst du 
u.U. auf anderen Prozessor anpassen. Falls das kein low level Code ist - 
wobei ja dann eher swappen unwichtiger würde.
Gast #2829090
Lesenswert?

Clemens M. schrieb:
> http://www.rn-wissen.de/index.php/Inline-Assembler...
>
> static inline unsigned char swap (unsigned char x)
> {
>     asm volatile ("swap %0" : "=r" (x) : "0" (x));
>     return x;
> }
>
>
> Meinst du so? Einziger Nachteil (vielleicht): Hilfsfunktion musst du
> u.U. auf anderen Prozessor anpassen. Falls das kein low level Code ist -
> wobei ja dann eher swappen unwichtiger würde.

Das gibts schon als intrinsic function im Header: avr/builtin.h
1
extern unsigned char __builtin_avr_swap(unsigned char __b);

Ist aber natürlich auch nicht portabel.
#2829114
Lesenswert?

Peter II schrieb:
> Stefan Noack schrieb:
>> Ein halbwegs vernünftiger compiler sollte dann ein swp draus machen.
>
> daruf würde ich nicht wetten.
>
> schon ein
> x >> 4
>
> ist auf einem atmel langsam, weil es in 4 schritten gemacht werden muss.

http://sdcc.svn.sourceforge.net/viewvc/sdcc/trunk/sdcc/src/avr/gen.c?revision=8097&view=markup 
in Zeile 3116:
1
                if (shCount >= 4) {
2
                          if (AOP_ISHIGHREG(AOP(result),0)) {
3
                                  emitcode ("swap", "%s", aopGet (AOP (result), 0));
4
                                  emitcode ("andi", "%s,0xf0");
5
                          } else {
6
                                  emitcode ("ldi","r24,0xf0");
7
                                  emitcode ("swap", "%s", aopGet (AOP (result), 0));
8
                                  emitcode ("and", "%s,r24");
9
                          }
10
                          shCount -= 4;
11
                  }

Ich wette stark darauf, zumindest für diesen compiler, beim avr-gcc kann 
man ja auch mal gucken ;-)
#2829125
Lesenswert?

Peter II schrieb:
> schon ein
> x >> 4
>
> ist auf einem atmel langsam, weil es in 4 schritten gemacht werden muss.

Der avr-gcc erledigt das aber mit swap und andi und nicht über 
Schiebebefehle oder add. Also braucht das nur 2 Zyklen.
(Betrachtung ohne Speicherzugriffe)


Mit -Os erledigt der avr-gcc die swap-Geschichte in C zuverlässig:
1
uint8_t c;
2

3
void main(void)
4
{
5
  c = (c<<4) | (c>>4);
6
  7c:  80 91 60 00   lds  r24, 0x0060
7
  80:  82 95         swap  r24
8
  82:  80 93 60 00   sts  0x0060, r24
9
}
10
  86:  08 95         ret

Gruß Oliver
#2829134
Lesenswert?

Oliver J. schrieb:

> Mit -Os erledigt der avr-gcc die swap-Geschichte in C zuverlässig:
>
1
> uint8_t c;
2
> 
3
> void main(void)
4
> {
5
>   c = (c<<4) | (c>>4);
6
>   7c:  80 91 60 00   lds  r24, 0x0060
7
>   80:  82 95         swap  r24
8
>   82:  80 93 60 00   sts  0x0060, r24
9
> }
10
>   86:  08 95         ret
11
> 
12
>
>
> Gruß Oliver

Sehr schön, damit hätten wir das eindeutig geklärt (und die Wette hätte 
ich gewonnen ^^)...

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren