New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement ASM_COPY_STACK on ARM #24096
Conversation
asm(" mov sp, %0;\n" | ||
" mov lr, #0;\n" // Clear link register (lr) and frame pointer | ||
" mov fp, #0;\n" // (fp) to terminate unwinder. | ||
" b start_task;\n" // call `start_task` with fake stack frame |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This assumes that we'll emit .start_task
as an asm symbol (despite trying to tell the compiler not to, with use of static
and such). What was wrong with using indirect branch?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or add lr
and fp
to the clobbers list
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
despite trying to tell the compiler not to
No we don't. That's what the JL_USED_FUNC
is for. We are explicitly telling the compiler to emit that symbol.
What was wrong with using indirect branch?
More instructions, but more importantly, I can't find a better way to make sure the compiler don't use, sp
, lr
or fp
as the register to pass in the address. It seems that lr
is most likely a valid choise if the compiler want to do that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's what the clobbers list is for, although the compiler may also potentially attempt to save/restore those registers around it. Making the first instruction mov r1, %1
is another way to ensure it, although in that case, using {r1}
as the constraint is probably easier.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
using {r1} as the constraint is probably easier.
That's not supported.
That's what the clobbers list is for,
I want to be robust against different compiler options (they might have special behavior on fp
). GCC errors when fp
is in the clobber list but not for sp
and lr
.
Making the first instruction
mov r1, %1
is another way to ensure it,
Thought about that, which is why I decided that just using a branch directly is simpler. The used
attribute is explicitly documented for use like this.
Also change the AArch64 version to use a relative jump instead of loading the address in register. This should make the code robust even if the compiler decide to pick a unusual register (fp or lr) to store the function address. Add `jl_unreachable` so that the compiler can know that the inline asm never returns.
2e4bc66
to
28923d1
Compare
Also change the AArch64 version to use a relative jump instead of loading the address in register.
This should make the code robust even if the compiler decide to pick a unusual register (fp or lr)
to store the function address.
Add
jl_unreachable
so that the compiler can know that the inline asm never returns.