I have just upgraded to MCUXpresso 11.1 and all the addresses calculated by the ADR instruction are now messed up.
See screenshots. . . (the software is for an LPC15xx)
Previously, the name of the label required "+1" after it to make sure that it set bit 0 in the destination address for Thumb mode.
Now it seems fairly random whether it does or doesn't. I thought it was something to do with the presence or absence of ".thumb_func", but that doesn't seem to make much difference either.
A simple workaround would be to use "|1" (OR 1) to set bit zero, but that gives an error every time saying that the parameters are wrong for the instruction.
Using the LDR instruction instead appears to work, but changing it throughout the code isn't so simple as the "=" has to be added before the name of the label.
Has anyone else noted this?
A further point, 11.1 seems to get out of sync with the program very easily and refuse to get itself realigned.
Even clicking "debug" doesn't seem always to rewrite the flash, and it appears to do the "attach" procedure instead
Hi, Ian,
Regarding your question, of course, you are right that the PC value must be an odd value for the thumb instruction for Cotem-M3 core.
If you use the Label to branch with B label1, or branch to a function for example BL func1, the func1 and label1 are label, in this way, the assembly compiler of MCUXpresso tools is smart enough to add 1.
I suppose if you use BLX Rm instruction, because user is responsible for computing the target address in Rm, adding 1 using ADR is required by user.
Hope it can help you
BR
XiangJun Rong
Having examined all of the disassembly, I find the following:
I always use ADR Rx,<label>+1
If the address of the label is GREATER than the current pc address, the compiler produces ADD.W PC,#offset, and offset is always ODD, so it works correctly.
If the address of the label is LESS than the current pc address, the compiler produces SUB.W PC,#offset and the offset is always EVEN, so it fails.
If I refer back to software that has not been complied since I upgraded to McuXpresso 11 I find that the offset is ALWAYS odd regardless of whether the instruction is ADDW or SUBW.
Your explanation please?
Why does ADR Rx,<label>|1 always produce an error?
That's mighty interesting reading
However, If my code says: ADR R0,startbreak+1
it assembles as: a84: f2af 20bc subw r0, pc, #700 ; 0x2bc
and if it says: ADR R0,startbreak
it assembles as: a84: f2af 20bd subw r0, pc, #701 ; 0x2bd
it has used "sub.w" both times! It has added an extra 1 twice, making the destination address 1 HIGHER than it should be.
If I specify "ADR.w" then it makes no difference.
But in older versions of MCU Xpresso it got it right. It's only when I was re-developing an old bit of software that I found the problem.
Maybe there was a bug introduced in GCC (or maybe it was a bug fix?). Did you try v11.1.1?
However, the official ARM manual says that the "LDR Rn,=value" pseudo-instruction will be automatically replaced by the fastest and least memory consuming instruction(s) that will load the value into Rn. So, you probably want to replace you ADR's with LDR Rn, [PC, #208] (or whatever is appropriate in your code).