Some prodding from the kernel folk here at Red Hat has lead me to
implementing a mechanism by which an asm statement can branch to a C
label.
There is a major restriction on this form of asm statement, in that
we cannot support output reloads on jump instructions, and therefore
we cannot support outputs from the branching asm.
However, the usage case from the kernel folk doesn't actually need
outputs. They want to perform some code patching for (essentially)
zero cost tracing. Their use case looks vaguely like
+#define TRACE1(NUM) \
+ do { \
+ asm goto ("0: nop;" \
+ ".pushsection trace_table;" \
+ ".long 0b, %l0;" \
+ ".popsection" \
+ : : : : trace#NUM); \
+ if (0) { trace#NUM: trace(); } \
+ } while (0)
+#define TRACE TRACE1(__COUNTER__)
where instances of the TRACE macro get sprinkled about the kernel.
It's expected that the compiler rearranges the blocks here such that
the straight-line code path normally consists of only the nop insn.
But we've recorded enough information in the trace_table section to
allow that nop insn to be patched to be direct jump to the trace#NUM
label, which calls the trace function followed by a branch back into
the straight-line code.
I've implemented this only for the C front-end at present, awaiting
feedback that might change the syntax. I'll adjust the C++ front
end and add a bunch of parsing test cases following general approval
of the idea.
So. Comments?
r~
<d-asmgoto-2.txt>