This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Most efficient way to do a SWAP32 ?

I'm looking for the most efficient way (in terms of code size first, but speed is also an issue) of doing a little-endian to big-endian convertion on a DWORD.

The commonly-used C macro:

#define SWAP32(x) (((x) & 0xff) << 24 | ((x) & 0xff00) << 8 | ((x) & 0xff0000) >> 8 | ((x) >> 24) & 0xff)

produces terrible code on the 8051.

I'm looking for either a macro or a function that would perform the equivalent swap using the minimum number of instructions. The macro/function is called in lots of places in my code and code size has become an issue.

Thanks!

Ran Shalgi

  • union U32_ {
        U32 l;
        U8  b[4];
    };
    Use a union and swap bytes around explicitly.

  • expanding on Dan's method;
    I use this method and, instead of "swapping bytes around explicitly" I load the union as bytes.

    Erik

  • How about

    ByteSwap.h:
    
    extern U32 ByteSwapU32 (U32 val);
    
    --
    ByteSwap.a51:
    
    PUBLIC  _ByteSwapU32
    _ByteSwapU32:
    
        MOV A, R7
        XCH A, R4
        MOV R7, A
    
        MOV A, R6
        XCH A, R5
        MOV R6, A
    
        RET
    
    

    Depending on your application, you might be able to fold the byte swap in with something else. For example, I have one project that has to access a device with 32 bit, little-endian registers. So, I have a set of register access routines that do the 4 8-bit xdata cycles required to write a 32-bit register, plus the DPTR changes, etc. The routines simply write bytes out in the reverse order. The set of routines also adds in bitwise set and clear operations, since you often want to do that to registers, so that the 32-bit or / and / not stuff all happens along with the byte swapping. There's no need for an explict swap anywhere in the code.