AVR Studio, Atmega32 Hallo, Gibt es einen Swap-Befehl, um eingelesene high und low Bits zutauschen und wie sieht der aus ? Also mache 0101 1100 (0x5C) zu 1100 0101 (0xC5)
mit __builtin_avr_insert_bits könnte das (und noch viel mehr) gehen, aber ob's schneller ist als per Hand maskieren und schieben? oder meintest du in ASM?
Εrnst B✶ schrieb: > mit __builtin_avr_insert_bits könnte das (und noch viel mehr) gehen, > aber ob's schneller ist als per Hand maskieren und schieben? > > oder meintest du in ASM? __builtin_avr_insert_bits sagt mir nichts! Per Hand wäre es möglich. Dachte aber es gibt einen Befehl dafür in C
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.
was spricht gegen:
1 | x = (x << 4) | (x >> 4) |
Ein halbwegs vernünftiger compiler sollte dann ein swp draus machen.
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.
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.
schon ein x >> 4 ist auf einem atmel langsam, weil es in 4 schritten gemacht werden muss. und was spricht dagegen (zumindest bei unsigned), das mit swap und and (0f) zu machen?
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 ;-)
eProfi schrieb: > und was spricht dagegen (zumindest bei unsigned), das mit swap und and > (0f) zu machen? dass der compiler einem die arbeit normalerweise abnimmt, das so zu schreiben? (siehe oben) ansonsten kann man gleich in assembler schreiben (was ich übrigens durchaus befürworte)...
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
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 ^^)...
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.