ARM thumb: why call_via_rX?
Phil Blundell
pb@nexus.co.uk
Fri Jan 25 06:04:00 GMT 2002
On Fri, 2002-01-25 at 12:17, Adrian von Bidder wrote:
> If it's sure that gcc does not generate any function returns with bx lr,
> but always does mov pc, lr or pop {..., pc} (which seems to be the
> case), function calls should be possible with just "mov lr, pc; mov pc,
> rX" in the non-interworking case.
Well, it's complicated. In ARMv4T, "pop {pc}" isn't an
interworking-aware instruction; it will throw away bit zero and just
return in Thumb mode. But in ARMv5, the semantics have changed to
complement the new "blx" instruction -- "pop {pc}" now looks at the low
bit and switches to ARM or Thumb mode in the same way that BX does.
This is all a little bit unfortunate from the point of view of forwards
compatibility.
But yes, in principle you're right. I don't think it would be all that
big a deal to allow you to write something like:
void (*fp)(int) __attribute__ ((no-interworking)) = my_func;
fp(1);
and get the code sequence you are looking for.
> Our CPU has an internal 8K static (fast) RAM, and external (slow) Flash.
> So my collegue had the idea of copying the most time-consuming code into
> the fast on chip RAM. So, of course, calls between non-copied and copied
> code with bl (such as calling call_via_rX) fail horribly.
Ah, I see. If this copying is done just once at startup and then the
map stays fixed, you could write a custom linker script defining the
right memory regions, and then PC-relative branches would "just work"
(so long as the regions aren't too far apart, anyway).
p.
More information about the Gcc
mailing list