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

How to generate little endian code

Hi guys,

Does anyone know how to make the Keil tool generate little endian code? Is that possible? I am using uVision 1.32

Can newest version of Keil tools generate little endian code?

Thanks,

Anh

Parents
  • I'm currently working on an 8051 with a custom register interface that was designed to be little endian

    I have a similar situation, except that my device has 32-bit little endian registers.

    My solution was simply to define functions along the lines of

    RegRead (addr)
    RegWrite (addr, val)
    RegOrEq (addr, val)
    RegAndEqNot (addr, val)
    etc

    When the endianness of your device matches the endianness of your processor/toolchain, these functions can become macros with straightforward assignments, and the compiler handles the details.

    #define RegRead(addr) *addr
    #define RegWrite(addr, val) *addr = val;
    #define RegOrEq (addr, val) *addr |= val;
    #define RegAndEqNot (addr, val) *addr &= ~val;

    When the endianess of your device does not match the toolchain, you write a function.

    Note that you do not need to explicitly byte swap as a separate operation from access. These functions know they're moving to swapped registers, and can do both jobs at the same time. Let's say you read a 16-bit value, returned in R6/R7. Your device is in xdata space. You'll have a routine that looks something like:

    init DPTR
    mov @DPTR to R7
    inc DPTR
    mov @DPTR to R6

    Notice that while the DPTR is moving from lower addresses to higher, the store into the bytes of the result, as determined by the sequence of the code, is moving from higher to lower. This order costs no more than reading the registers in the "correct" order, and results in swapping the bytes while they're read. If the device were big endian, the routine would be the same, only with the registers used in the opposite order:

    init DPTR
    mov @DPTR to R6
    inc DPTR
    mov @DPTR to R7

    Either way, the execution cost is the same.

    Software can internally deal with the values always big-endian, and the Reg* routines flip them only on actual hardware access.

Reply
  • I'm currently working on an 8051 with a custom register interface that was designed to be little endian

    I have a similar situation, except that my device has 32-bit little endian registers.

    My solution was simply to define functions along the lines of

    RegRead (addr)
    RegWrite (addr, val)
    RegOrEq (addr, val)
    RegAndEqNot (addr, val)
    etc

    When the endianness of your device matches the endianness of your processor/toolchain, these functions can become macros with straightforward assignments, and the compiler handles the details.

    #define RegRead(addr) *addr
    #define RegWrite(addr, val) *addr = val;
    #define RegOrEq (addr, val) *addr |= val;
    #define RegAndEqNot (addr, val) *addr &= ~val;

    When the endianess of your device does not match the toolchain, you write a function.

    Note that you do not need to explicitly byte swap as a separate operation from access. These functions know they're moving to swapped registers, and can do both jobs at the same time. Let's say you read a 16-bit value, returned in R6/R7. Your device is in xdata space. You'll have a routine that looks something like:

    init DPTR
    mov @DPTR to R7
    inc DPTR
    mov @DPTR to R6

    Notice that while the DPTR is moving from lower addresses to higher, the store into the bytes of the result, as determined by the sequence of the code, is moving from higher to lower. This order costs no more than reading the registers in the "correct" order, and results in swapping the bytes while they're read. If the device were big endian, the routine would be the same, only with the registers used in the opposite order:

    init DPTR
    mov @DPTR to R6
    inc DPTR
    mov @DPTR to R7

    Either way, the execution cost is the same.

    Software can internally deal with the values always big-endian, and the Reg* routines flip them only on actual hardware access.

Children
No data