Reputation: 49
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
Upvotes: 1
Views: 1891
Reputation: 873
.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
Upvotes: 1