xiaoroubao
xiaoroubao

Reputation: 7

How to limit the range of jump instructions

I am writing my own LLVM backend and have an instruction set designed with various jump instructions which have jump range restrictions, for example, the range should be within [-128,127]. After referencing other LLVM backends I found that some of them use "brtargetXXX" in XXXInstrInfo.td like the following:

def brtarget16    : Operand<OtherVT> {
  let EncoderMethod = "getBranch16TargetOpValue";
  let OperandType = "OPERAND_PCREL";
  let DecoderMethod = "DecodeBranch16Target";
}

and is used :

class CBranch16<bits<8> op, string instrAsm, PatFrag cond_op, RegisterClass RC>
  : FL<op, (outs), (ins RC:$ra, RC:$rb, brtarget16:$imm16),
       !strconcat(instrAsm, "\t$ra, $rb, $imm16"),
       [(brcond (i32 (cond_op RC:$ra, RC:$rb)), bb:$imm16)], IIBranch>,
       Requires<[HasSlt]> {
  let isBranch = 1;
  let isTerminator = 1;
  let hasDelaySlot = 1;
  let Defs = [AT];
}

I have two questions here:

  1. What's the meaning of brtarget and its fields' value? (I can't find a detailed reference.)
  2. Is it the right way the add jump scope restriction? (I have tried this way but triggered some error related to XXXGenAsmWrite.inc while compiling my backend; I guess I miss something important.)

Upvotes: 0

Views: 72

Answers (1)

Anton Korobeynikov
Anton Korobeynikov

Reputation: 9324

There is no way to ensure "branch range" restriction during the instruction selection as code size might change after subsequent backend passes. What you need is so called "branch relaxation" that iteratively turns out-of-range branches into their long range counterparts. You'd need to implement several hooks, e.g. to define what is in-range branch target, what is instruction size, etc.

There are in-tree targets with lots of examples.

Upvotes: 1

Related Questions