From efec1396accbff7e6e652ffb0e77c56e6c0b7a42 Mon Sep 17 00:00:00 2001 From: Scott Linder Date: Tue, 5 Mar 2019 03:02:00 +0000 Subject: [PATCH] [AMDGPU] Implement AMDGPUMCInstrAnalysis Implement MCInstrAnalysis for AMDGPU, with default implementations save for `evaluateBranch`. Differential Revision: https://reviews.llvm.org/D58400 llvm-svn: 355373 --- .../AMDGPU/Disassembler/AMDGPUDisassembler.cpp | 2 ++ .../AMDGPU/MCTargetDesc/AMDGPUMCTargetDesc.cpp | 31 ++++++++++++++++ llvm/test/MC/AMDGPU/branch-comment.s | 42 ++++++++++++++++++++++ 3 files changed, 75 insertions(+) create mode 100644 llvm/test/MC/AMDGPU/branch-comment.s diff --git a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp index 0acd30f..58c9c93 100644 --- a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp +++ b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp @@ -76,6 +76,8 @@ static DecodeStatus decodeSoppBrTarget(MCInst &Inst, unsigned Imm, uint64_t Addr, const void *Decoder) { auto DAsm = static_cast(Decoder); + // Our branches take a simm16, but we need two extra bits to account for the + // factor of 4. APInt SignedOffset(18, Imm * 4, true); int64_t Offset = (SignedOffset.sext(64) + 4 + Addr).getSExtValue(); diff --git a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCTargetDesc.cpp b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCTargetDesc.cpp index 9cb7705..ee75cca 100644 --- a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCTargetDesc.cpp +++ b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCTargetDesc.cpp @@ -20,6 +20,7 @@ #include "llvm/MC/MCAsmBackend.h" #include "llvm/MC/MCCodeEmitter.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCInstrAnalysis.h" #include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCObjectWriter.h" #include "llvm/MC/MCRegisterInfo.h" @@ -103,6 +104,35 @@ static MCStreamer *createMCStreamer(const Triple &T, MCContext &Context, std::move(Emitter), RelaxAll); } +namespace { + +class AMDGPUMCInstrAnalysis : public MCInstrAnalysis { +public: + explicit AMDGPUMCInstrAnalysis(const MCInstrInfo *Info) + : MCInstrAnalysis(Info) {} + + bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size, + uint64_t &Target) const override { + if (Inst.getNumOperands() == 0 || !Inst.getOperand(0).isImm() || + Info->get(Inst.getOpcode()).OpInfo[0].OperandType != + MCOI::OPERAND_PCREL) + return false; + + int64_t Imm = Inst.getOperand(0).getImm(); + // Our branches take a simm16, but we need two extra bits to account for + // the factor of 4. + APInt SignedOffset(18, Imm * 4, true); + Target = (SignedOffset.sext(64) + Addr + Size).getZExtValue(); + return true; + } +}; + +} // end anonymous namespace + +static MCInstrAnalysis *createAMDGPUMCInstrAnalysis(const MCInstrInfo *Info) { + return new AMDGPUMCInstrAnalysis(Info); +} + extern "C" void LLVMInitializeAMDGPUTargetMC() { TargetRegistry::RegisterMCInstrInfo(getTheGCNTarget(), createAMDGPUMCInstrInfo); @@ -113,6 +143,7 @@ extern "C" void LLVMInitializeAMDGPUTargetMC() { TargetRegistry::RegisterMCRegInfo(*T, createAMDGPUMCRegisterInfo); TargetRegistry::RegisterMCSubtargetInfo(*T, createAMDGPUMCSubtargetInfo); TargetRegistry::RegisterMCInstPrinter(*T, createAMDGPUMCInstPrinter); + TargetRegistry::RegisterMCInstrAnalysis(*T, createAMDGPUMCInstrAnalysis); TargetRegistry::RegisterMCAsmBackend(*T, createAMDGPUAsmBackend); TargetRegistry::RegisterELFStreamer(*T, createMCStreamer); } diff --git a/llvm/test/MC/AMDGPU/branch-comment.s b/llvm/test/MC/AMDGPU/branch-comment.s new file mode 100644 index 0000000..e9cada6 --- /dev/null +++ b/llvm/test/MC/AMDGPU/branch-comment.s @@ -0,0 +1,42 @@ +// RUN: llvm-mc -arch=amdgcn -mcpu=fiji -filetype=obj %s | llvm-objcopy -S -K keep_symbol - | llvm-objdump -disassemble -mcpu=fiji - | FileCheck %s --check-prefix=BIN + +// FIXME: Immediate operands to sopp_br instructions are currently scaled by a +// factor of 4, are unsigned, are always PC relative, don't accept most +// expressions, and are not range checked. + +loop_start_nosym: +s_branch loop_start_nosym +// BIN-NOT: loop_start_nosym: +// BIN: s_branch 65535 // 000000000000: BF82FFFF <.text> + +s_branch loop_end_nosym +// BIN: s_branch 0 // 000000000004: BF820000 <.text+0x8> +// BIN-NOT: loop_end_nosym: +loop_end_nosym: + s_nop 0 + +keep_symbol: + s_nop 0 + +loop_start_sym: +s_branch loop_start_sym +// BIN-NOT: loop_start_sym: +// BIN: s_branch 65535 // 000000000010: BF82FFFF + +s_branch loop_end_sym +// BIN: s_branch 0 // 000000000014: BF820000 +// BIN-NOT: loop_end_sym: +loop_end_sym: + s_nop 0 + +s_branch 65535 +// BIN: s_branch 65535 // 00000000001C: BF82FFFF + +s_branch 32768 +// BIN: s_branch 32768 // 000000000020: BF828000 + +s_branch 32767 +// BIN: s_branch 32767 // 000000000024: BF827FFF + +s_branch 0x80000000ffff +// BIN: s_branch 65535 // 000000000028: BF82FFFF -- 2.7.4