When we only have a 16-bit pc-relative branch instruction we generate a table of address for a jump table. Currently this is placed inline, but this won't work with execute-only memory. In this case generate the jump table out-of-line.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
I'd prefer if the Thumb1 and Thumb2 codepaths work as close to the same way as possible; this looks significantly different. (Thumb2 execute-only has basically the same issues as Thumb1 execute-only, as far as I can tell; we only get away with "loading" from the text segment if we can form tbb/tbh.)
(Do we care about execute-only PIC?)
llvm/lib/Target/ARM/ARMISelLowering.cpp | ||
---|---|---|
3498 | What relevant instructions does v8m.base have? |
The thumb1 and thumb2 handling of jump tables is already different, and the only difference of execute-only thumb1 from non-execute-only is the location of the jump table (inline vs out-of-line).
(Do we care about execute-only PIC?)
No.
llvm/lib/Target/ARM/ARMISelLowering.cpp | ||
---|---|---|
3498 | t2B, the 32-bit direct branch instruction. |
Oh, I didn't remember JUMPTABLE_INSTS was a thing. This is making more sense now; Thumb2/armv8m.base defaults to jumping to a table of jumps, which works fine with execute-only, but Thumb1 (and apparently ARM-mode) loads offsets from a table instead, which doesn't work with execute-only. So to make Thumb1 work, you force the table to be emitted out-of-line.
That makes sense, but depending how much we care, there are probably better sequences. We can use "bl" as a 32-bit branch on Thumb1, like we do in other places. And we can then compress those 32-bit branches to 16-bit branches if the offsets aren't too big.
If you just care about getting it working, this is okay as-is. LGTM
What relevant instructions does v8m.base have?