From ce96738dee560a9a3ad08301860d1483df3356d4 Mon Sep 17 00:00:00 2001 From: Yonghong Song Date: Thu, 16 Nov 2017 19:15:36 +0000 Subject: [PATCH] bpf: print backward branch target properly Currently, it prints the backward branch offset as unsigned value like below: 7: 7d 34 0b 00 00 00 00 00 if r4 s>= r3 goto 11 8: b7 00 00 00 00 00 00 00 r0 = 0 LBB0_2: 9: 07 00 00 00 01 00 00 00 r0 += 1 ...... 17: bf 31 00 00 00 00 00 00 r1 = r3 18: 6d 32 f6 ff 00 00 00 00 if r2 s> r3 goto 65526 The correct print insn 18 should be: 18: 6d 32 f6 ff 00 00 00 00 if r2 s> r3 goto -10 To provide better clarity and be consistent with kernel verifier output, the insn 7 output is changed to the following with "+" added to non-negative branch offset: 7: 7d 34 0b 00 00 00 00 00 if r4 s>= r3 goto +11 Signed-off-by: Yonghong Song Acked-by: Alexei Starovoitov llvm-svn: 318442 --- llvm/lib/Target/BPF/BPFInstrInfo.td | 4 ++- llvm/lib/Target/BPF/InstPrinter/BPFInstPrinter.cpp | 13 +++++++ llvm/lib/Target/BPF/InstPrinter/BPFInstPrinter.h | 1 + .../Target/BPF/MCTargetDesc/BPFMCTargetDesc.cpp | 2 +- llvm/test/CodeGen/BPF/objdump_cond_op.ll | 6 ++-- llvm/test/CodeGen/BPF/objdump_cond_op_2.ll | 39 ++++++++++++++++++++ llvm/test/MC/BPF/insn-unit.s | 42 +++++++++++----------- 7 files changed, 81 insertions(+), 26 deletions(-) create mode 100644 llvm/test/CodeGen/BPF/objdump_cond_op_2.ll diff --git a/llvm/lib/Target/BPF/BPFInstrInfo.td b/llvm/lib/Target/BPF/BPFInstrInfo.td index a3ad2ee..27b26b9 100644 --- a/llvm/lib/Target/BPF/BPFInstrInfo.td +++ b/llvm/lib/Target/BPF/BPFInstrInfo.td @@ -46,7 +46,9 @@ def BPFWrapper : SDNode<"BPFISD::Wrapper", SDT_BPFWrapper>; def BPFIsLittleEndian : Predicate<"CurDAG->getDataLayout().isLittleEndian()">; def BPFIsBigEndian : Predicate<"!CurDAG->getDataLayout().isLittleEndian()">; -def brtarget : Operand; +def brtarget : Operand { + let PrintMethod = "printBrTargetOperand"; +} def calltarget : Operand; def u64imm : Operand { diff --git a/llvm/lib/Target/BPF/InstPrinter/BPFInstPrinter.cpp b/llvm/lib/Target/BPF/InstPrinter/BPFInstPrinter.cpp index 536ae4d..6f81e02 100644 --- a/llvm/lib/Target/BPF/InstPrinter/BPFInstPrinter.cpp +++ b/llvm/lib/Target/BPF/InstPrinter/BPFInstPrinter.cpp @@ -94,3 +94,16 @@ void BPFInstPrinter::printImm64Operand(const MCInst *MI, unsigned OpNo, else O << Op; } + +void BPFInstPrinter::printBrTargetOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) { + const MCOperand &Op = MI->getOperand(OpNo); + if (Op.isImm()) { + int16_t Imm = Op.getImm(); + O << ((Imm >= 0) ? "+" : "") << Imm; + } else if (Op.isExpr()) { + printExpr(Op.getExpr(), O); + } else { + O << Op; + } +} diff --git a/llvm/lib/Target/BPF/InstPrinter/BPFInstPrinter.h b/llvm/lib/Target/BPF/InstPrinter/BPFInstPrinter.h index 4276d08..bb0b0d7 100644 --- a/llvm/lib/Target/BPF/InstPrinter/BPFInstPrinter.h +++ b/llvm/lib/Target/BPF/InstPrinter/BPFInstPrinter.h @@ -30,6 +30,7 @@ public: void printMemOperand(const MCInst *MI, int OpNo, raw_ostream &O, const char *Modifier = nullptr); void printImm64Operand(const MCInst *MI, unsigned OpNo, raw_ostream &O); + void printBrTargetOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); // Autogenerated by tblgen. void printInstruction(const MCInst *MI, raw_ostream &O); diff --git a/llvm/lib/Target/BPF/MCTargetDesc/BPFMCTargetDesc.cpp b/llvm/lib/Target/BPF/MCTargetDesc/BPFMCTargetDesc.cpp index 5c3bba6..cbf1ea7 100644 --- a/llvm/lib/Target/BPF/MCTargetDesc/BPFMCTargetDesc.cpp +++ b/llvm/lib/Target/BPF/MCTargetDesc/BPFMCTargetDesc.cpp @@ -79,7 +79,7 @@ public: bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size, uint64_t &Target) const override { // The target is the 3rd operand of cond inst and the 1st of uncond inst. - int64_t Imm; + int16_t Imm; if (isConditionalBranch(Inst)) { Imm = Inst.getOperand(2).getImm(); } else if (isUnconditionalBranch(Inst)) diff --git a/llvm/test/CodeGen/BPF/objdump_cond_op.ll b/llvm/test/CodeGen/BPF/objdump_cond_op.ll index 3abbb76..b9dc122 100644 --- a/llvm/test/CodeGen/BPF/objdump_cond_op.ll +++ b/llvm/test/CodeGen/BPF/objdump_cond_op.ll @@ -27,7 +27,7 @@ define i32 @test(i32, i32) local_unnamed_addr #0 { br label %13 ; CHECK: r1 <<= 32 ; CHECK: r1 >>= 32 -; CHECK: if r1 != 2 goto 6 +; CHECK: if r1 != 2 goto +6 ;