Assembler messages: Error: attempt to move .org backwards

1.6k views Asked by At

I am using xtensa-esp32-elf-8.2.0 toolchain for compilation (which is based on gcc 8). I also tried with xtensa-esp32-elf-5.2.0 toolchain (which is based on gcc 5). Both generate the same error message.

I have written a jumptable which has following instructions 10 times , which are basically used to jump at the particular address and execute particular instruction. But I am getting an error while compilation which is

Assembler Messages: Error: attempt to move .org backwards

    .org    .LSAC_jumptable_base + (16 * 6)
    mov     a6, a4
    l32i    a2, sp, 0x08
    l32i    a4, sp, 0x10
    mov     a1, a0
    rsr     a0, excsave1
    rfe

I have surfed the web for the same but, either most of the pages do not provide viable answer or they say its a compiler version problem ( which I dont think is the right solution as I use latest toolchain )

Can somebody please help

example use of my jumptable:

    movi    a3, .LSAC_jumptable_base
    l32i    a0, sp, 0
    addx8   a2, a2, a3      // a2 is now the address to jump to
    l32i    a3, sp, 0x0c

    jx      a2

    .org    .LSAC_jumptable_base + (16 * 5)
    mov     a5, a4 //Here, a4 is the correctly read value
    l32i    a2, sp, 0x08
    l32i    a4, sp, 0x10
    mov     a1, a0
    rsr     a0, excsave1
    rfe

    .org    .LSAC_jumptable_base + (16 * 6)
    mov     a6, a4
    l32i    a2, sp, 0x08
    l32i    a4, sp, 0x10
    mov     a1, a0
    rsr     a0, excsave1
    rfe
1

There are 1 answers

3
jcmvbkbc On
.org    .LSAC_jumptable_base + (16 * 5)
mov     a5, a4 //Here, a4 is the correctly read value
l32i    a2, sp, 0x08
l32i    a4, sp, 0x10
mov     a1, a0
rsr     a0, excsave1
rfe

.org    .LSAC_jumptable_base + (16 * 6)

The code between the .orgs is supposed to fit into 16 bytes, but it will not fit unless the assembler relaxes some instructions in it: all used instructions are 3-byte long by default and there are 6 of them. But there are 2-byte variants for the mov and l32i instructions, so you can rewrite it as follows:

.org    .LSAC_jumptable_base + (16 * 5)

_mov.n  a5, a4 //Here, a4 is the correctly read value
_l32i.n a2, sp, 0x08
_l32i.n a4, sp, 0x10
_mov.n  a1, a0
rsr     a0, excsave1
rfe

.org    .LSAC_jumptable_base + (16 * 6)

OTOH instead of table that consists of chunks of code of fixed size it may be easier to have a table of addresses of entry points. So your example could be rewritten as follows:

.section ".rodata", "a"
.align 4
.LSAC_jumptable_base:
.word   .L0, .L1
.previous

movi    a3, .LSAC_jumptable_base
l32i    a0, sp, 0
addx4   a2, a2, a3      // a2 is now the address in the table
l32i    a2, a2, 0       // a2 is now the address to jump to
l32i    a3, sp, 0x0c

jx      a2

.L0:
mov     a5, a4 //Here, a4 is the correctly read value
l32i    a2, sp, 0x08
l32i    a4, sp, 0x10
mov     a1, a0
rsr     a0, excsave1
rfe

.L1:
mov     a6, a4
l32i    a2, sp, 0x08
l32i    a4, sp, 0x10
mov     a1, a0
rsr     a0, excsave1
rfe