binutils-esp32ulp
binutils-esp32ulp copied to clipboard
Incorrect relative address error
Apperance of an error:
coprocessor.ulp.pS:276: Error: rel too far BFD_JUMPR_STEP
do not depend on relative position of instructions but for some reason on absolute position of instruction. Above error appears in my code:
jumpr quit, 256, ge
halt
quit: wake
when those lines are very far away e.g.
276 ???? 00010182 jumpr quit, 256, ge
277 ???? 000000B0 halt
278 quit:
279 ???? 01000090 wake
but won't appear if those lines are at the beginning of code. The problem also affects jumps
instruction.
EDIT: I have found that if label which i selected to jump into is going to be over 0x0200
address in resultant code, such error appears, so I can generate code:
186 01f8 00000040 nop
187 test1:
188 01fc 00010182 jumpr test1, 256, ge
189 test2:
190 0200 00000040 nop
when i try to jump to test1
, but only when I try to jump into test2
I get:
coprocessor.ulp.pS: Assembler messages:
coprocessor.ulp.pS:188: Error: rel too far BFD_JUMPR_STEP
186 ???? 00000040 nop
187 test1:
188 ???? 00010182 jumpr test2, 256, ge
189 test2:
190 ???? 00000040 nop
the error is thrown by function md_apply_fix
in file gas/config/tc-esp32ulp.c
, but the condition checked there seems legit:
case BFD_RELOC_ESP32ULP_JUMPR_STEP:
if ((value > 0x1FF) || (value < -0x1ff))
as_bad_where(fixP->fx_file, fixP->fx_line, _("rel too far BFD_JUMPR_STEP"));
because it assume (i hope) that value
is relative offset of jump, but for some reason in this case it is not, and it happened to be absolute offset of jump, I am not sure from where this function is called, because I am not so familiar with binutils source code.
Hi Mucka!
To solve the problem you have two ways:
- You can just define the jump label as a global label, like:
.global quit
jumpr quit, 256, ge
halt
quit: wake
- You can just remove the lines that check the value. The relative shift will be calculated in next functions, and here are useless. The value here is an absolute address of the label, if the label is local. Just remove the lines that you have found.
if ((value > 0x1FF) || (value < -0x1ff))
as_bad_where(fixP->fx_file, fixP->fx_line, _("rel too far BFD_JUMPR_STEP"));
Thank you very much!
Dmitry
I suspect this is a related presentation of the same bug. Trying to compile assembler for the ULP a small jumps results in a error that the relative jump is too far. Here is a code snippet:
.global measurea
measurea:
/* measure and add value to accumulator */
adc r1, 0, adc_channel_a + 1
add r0, r0, r1
/* increment loop counter and check exit condition */
stage_inc 1
jumps measurea, adc_oversampling_factor, lt // Apparently a jump too far?!
It is very nearly a direct copy from one of the ulp-adc examples, but I haven't done any assembler since Z80A days so maybe I'm missing something obvious! I made measurea global in the hope it would help, it didn't.
adc.ulp.S:25: Error: rel too far BFD_JUMPS_THRESH
(BTW the "line numbers" the compiler reports are very difficult to track back to lines in the source- is there any trick to help with this?, thanks!)