Forum: Compiler & IDEs SWAP in GCC


von ein verzweifelter (Gast)


Lesenswert?

Gibt es in GCC auch den SWAP Befehl analog zu Assembler
der das untere mit dem oberen Nibbel bei einem Byte vertauscht?

Danke schonmal

von dins (Gast)


Lesenswert?


von Andreas Paulin (Gast)


Lesenswert?

Wenns nicht DERMASSEN(!!) schnell gehen muss..... warum nicht einfach in 
C mit einer Hilfsvariablen:

tmpbyte = swapbyte;
swapbyte = <<=4;
tmpbyte >>=4;
swapbyte |= tmpbyte;

Setzt der Compiler normal 1:1 um.

Grüßle

von Jörg X. (Gast)


Lesenswert?

hättest du gesucht, hättest du das gefunden
1
uint8_t swapbyte
2
swapbyte = (swapbyte << 4) && (swapbyte >> 4);
vorher ggf. nach unsigned casten

von Jörg X. (Gast)


Lesenswert?

oups!
natürlich:
1
swapbyte = (swapbyte << 4) & (swapbyte >> 4);
sorry

von Rolf Magnus (Gast)


Lesenswert?

> Geht mit inline Assembler:

Der Code, den man dort sieht:
1
static inline unsigned char swap (unsigned char x)
2
{
3
    asm volatile ("swap %0" : "=r" (x) : "0" (x));
4
    return x;
5
}

kann übrigens noch einen Tick verbessert werden. Inline-Assembler 
verhindert leider ein "constant folding", weshalb diese Berechnung auch 
in den Fällen zur Laufzeit durchgeführt wird, in denen es eigentlich 
nicht nötig wäre. Es gibt bei gcc einen Trick, um auch diese 
Optimierungen zu ermöglichen. Der geht so:
1
static inline unsigned char swap (unsigned char x)
2
{
3
    if (__builtin_constant_p(x))
4
        x = (x << 4) | (x >> 4);
5
    else
6
        asm volatile ("swap %0" : "=r" (x) : "0" (x));
7
8
    return x;
9
}

__builtin_constant_p wird zur Compileeit ausgewertet, wodurch das if() 
auch zur Compilezeit aufgelöst wird. Wenn swap() inline expandiert wird, 
wird ein zur Compilezeit bekannter übergebener Wert als solche erkannt 
und die C-Implementation verwendet, die dann ebenfalls zur Compilezeit 
durchgeführt wird.

von Walter (Gast)


Lesenswert?

@Jörg

"oups!
natürlich:

swapbyte = (swapbyte << 4) & (swapbyte >> 4);

sorry"

Sollte da nicht ein | anstatt des & stehen?!

von Rolf Magnus (Gast)


Lesenswert?

Doch, sollte es.

von Jörg X. (Gast)


Lesenswert?

@ Walter (Gast):
autsch,
ja natürlich!

von ein nicht mehr verzweifelter (Gast)


Lesenswert?

Vielen Dankfür die schnelle Hilfe.

Habe wieder was gelernt. Klasse Forum.

Bis dann 73 & 55





von Malte _. (malte) Benutzerseite


Lesenswert?

Bei mir optimiert der Compiler leider
  a = (a<<4) | (a>>4);
überhaupt nicht zu einem SWAP Befehl.
Aus
1
typedef uint8_t u08;
2
static void rs232_receiveconfig(void) {
3
u08 k;
4
u08 a, b;
5
u08 * addr = (u08 *)eep_config;
6
for (k = 0; k < sizeof(eep_config); k++) {
7
  a = hextobyte(rs232_get_nextbyte());
8
  //swap the byte (the lower 4 bits will be zero afterwards)
9
  a = (a<<4) | (a>>4);
10
  b = hextobyte(rs232_get_nextbyte());
11
  eeprom_write_byte(addr+k, a | b);
12
  rs232_put_byte('A');
13
}
14
}
wird ein völlig umständliches
1
  rcall rs232_get_nextbyte
2
  rcall hextobyte
3
  mov r17,r24
4
  .stabn 68,0,64,.LM25-rs232_thread
5
.LM25:
6
  clr r25
7
  ldi r18,4
8
1:  lsl r24
9
  rol r25
10
  dec r18
11
  brne 1b
12
  swap r17
13
  andi r17,0x0f
14
  or r17,r24
15
  .stabn 68,0,65,.LM26-rs232_thread
16
.LM26:
17
  rcall rs232_get_nextbyte
18
  rcall hextobyte

mit einem Typecast
1
a = ((u08)(a<<4)) | ((u08)(a>>4));
sieht es nur geringfügig besser aus:
1
  rcall rs232_get_nextbyte
2
  rcall hextobyte
3
  mov r17,r24
4
  .stabn 68,0,64,.LM25-rs232_thread
5
.LM25:
6
  swap r24
7
  andi r24,0xf0
8
  swap r17
9
  andi r17,0x0f
10
  or r17,r24
11
  .stabn 68,0,65,.LM26-rs232_thread
12
.LM26:
13
  rcall rs232_get_nextbyte
14
  rcall hextobyte

Der GCC Compiler ist: 3.4.3

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Besser als das zweite wird's wohl im Moment nicht.  Es müsste jemand,
der hinreichend viel RTL versteht, sich mal hinsetzen und gucken,
wie man es erreicht, dass er die überflüssigen 4 Befehle einfach
weglässt.

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
Noch kein Account? Hier anmelden.