[X86] Adding a new instruction JUMPB

Hi llvm-dev,

In the review of the LLVM-side changes to support XRay (which is now upstream as http://reviews.llvm.org/rL275367) we hit one particular case where we had to hack around the fact that we have no way to force the emission of a short relative jump. It’s even come up that jump relaxation can come in and (at least with clang -O0) relax jumps to use the longer version of the jump instruction rather than the shorter version that XRay requires.

One suggestion that came up was to introduce a new instruction which forces the emission of a short relative jump with an 8-bit operand, which will fail if at assembly time the offset is outside the bounds of the relative jump.

I mentioned that I liked this idea in the review, but I’m opening it up to the list before actually introducing a new instruction and potentially change some parts of the lower levels of the assembler (MC lowering?) for X86. Some questions before I get stuck in and make this happen:

  • Is the documentation in “Extending LLVM”, in particular the SelectionDAG node addition (http://llvm.org/docs/ExtendingLLVM.html#adding-a-new-selectiondag-node) the right guide to follow?
  • Is there an example of how to enforce some assertions when assembling on say the computed operands for a given instruction? For example, if the MachineInstr for the JUMPB instruction was computed as an offset between the current instruction and a label, and the distance was out-of-bounds indicating a bad MachineInstr was used, is there a way to error out? Is this purely implemented in the legalisation of the instruction?
  • I’ve recently heard about and listened to the talk on the ongoing developments for global instruction selection – is there something there that I’d need to worry about?
  • If I’d like to make the instruction be recognised in FastISel, will the SelectionDAG changes suffice for the instruction or will I need to be making changes there too? How about in other ISel passes for X86 (if any)?

Looking forward to your thoughts on this!

Cheers

Personally, I think we should add this. I’ve personally been annoyed that it is difficult to convince gas to use the short jump encoding. If you use just the right kinds of labels, it uses the short encoding, but apparently because of -mc-relax-all, that won’t actually work with clang either. It’s all quite complicated, and we should just expose a simple way for the user to ask for what they want.

Assuming we go with this, I propose we use the mneumonic “jmpb”. It seems consistent with gas’s size suffixes, but I’m open to other ideas.

Normal (non-xray) ISel should never produce this instruction, so we don’t need any SDAG patterns for it. You should be able to look at existing rare x86 instructions that don’t have SDAG nodes, like PUSHF, SAHF, CPUID, etc to see the minimal amount of tablegen you need to add.

Personally, I think we should add this. I've personally been annoyed that it is difficult to convince gas to use the short jump encoding. If you use just the right kinds of labels, it uses the short encoding, but apparently because of -mc-relax-all, that won't actually work with clang either. It's all quite complicated, and we should just expose a simple way for the user to ask for what they want.

Yes, -mrelax-all is the problem from clang (and I suppose if llvm-lc was used with -relax-all).

Assuming we go with this, I propose we use the mneumonic "jmpb". It seems consistent with gas's size suffixes, but I'm open to other ideas.

jmpb sounds good to me. :slight_smile:

Normal (non-xray) ISel should never produce this instruction, so we don't need any SDAG patterns for it. You should be able to look at existing rare x86 instructions that don't have SDAG nodes, like PUSHF, SAHF, CPUID, etc to see the minimal amount of tablegen you need to add.

Cool, thanks. I'll prepare something if I don't hear any dissent in the next couple of days.

Cheers