After composing the below, I remembered the ethernut tutorial. He has virtually the same answer,
asm volatile(
"mov lr, %1\n\t"
"bx %0\n\t"
: : "r" (main), "r" (JMPADDR));
The OP would do well to read this tutorial; even though it is for traditional ARM as opposed to an 'm0'.
You may use the 'r' constraint to place the address in a register and branch to it.
An example can be found on the online compiler godbolt.
extern int my_function(void);
void f(void)
{
__asm volatile (
" cmp r3,#0 \n"
" b %[my_function] \n" //Call function
" bx r14 \n"
: // no output
: [my_function] "r" (my_function) // input
: "r0" // clobber
);
}
With the output,
f():
ldr r3, .L2
cmp r3,#0
b r3
bx r14
bx lr
.L2:
.word my_function()
We can see several issues with the output. r14 is lr and the b r3 will transfer control directly and return to the caller of f. The cmp r3, #0 seems completely un-needed (given limited context of question).
The sample above answers the question and it could be used for a tail-call macro or other use, but it obviously needs some work. A function pointer like,
int (*g)(void) = my_function;
will also work as the parameter 'my_function' to the GCC extended assembler.
Another method is just to use 'C' macro string concatenation. Here is a starting sample,
#define xstr(s) str(s)
#define str(s) #s
#define TAIL_CALL(func) __asm volatile(" b " str(func) "\n")
For most code sizes (jump distance), the branch will be able to resolve (4MB?). If you use the function pointer method, then there is no issue.
my_functionas immediate argument? And how wouldmay_functionreturn, as you only branch? The following line will never be executed. - too honest for this sitemy_function. Then compile with the-Soption and take a look at the assembly that the compiler generates. - user3386109bmnemonic takes a symbol as an argument, not an immediate, the appropriate constraint would appear to beS, if just writing"b my_function\n"in the asm isn't good enough. The fact that this code won't assemble is at least saving you the fun of debugging the "bogus clobber list" and/or "tail call with unknown return address and without popping the stack frame" issues... - Notlikethat