Reputation: 7
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:
Upvotes: 0
Views: 72
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