llvm.org GIT mirror llvm / bb1734f
[AMDGPU] Implement AMDGPUMCInstrAnalysis Implement MCInstrAnalysis for AMDGPU, with default implementations save for `evaluateBranch`. Differential Revision: https://reviews.llvm.org/D58400 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@355373 91177308-0d34-0410-b5e6-96231b3b80d8 Scott Linder 1 year, 7 months ago
3 changed file(s) with 75 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
7575 uint64_t Addr, const void *Decoder) {
7676 auto DAsm = static_cast(Decoder);
7777
78 // Our branches take a simm16, but we need two extra bits to account for the
79 // factor of 4.
7880 APInt SignedOffset(18, Imm * 4, true);
7981 int64_t Offset = (SignedOffset.sext(64) + 4 + Addr).getSExtValue();
8082
1919 #include "llvm/MC/MCAsmBackend.h"
2020 #include "llvm/MC/MCCodeEmitter.h"
2121 #include "llvm/MC/MCContext.h"
22 #include "llvm/MC/MCInstrAnalysis.h"
2223 #include "llvm/MC/MCInstrInfo.h"
2324 #include "llvm/MC/MCObjectWriter.h"
2425 #include "llvm/MC/MCRegisterInfo.h"
102103 std::move(Emitter), RelaxAll);
103104 }
104105
106 namespace {
107
108 class AMDGPUMCInstrAnalysis : public MCInstrAnalysis {
109 public:
110 explicit AMDGPUMCInstrAnalysis(const MCInstrInfo *Info)
111 : MCInstrAnalysis(Info) {}
112
113 bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size,
114 uint64_t &Target) const override {
115 if (Inst.getNumOperands() == 0 || !Inst.getOperand(0).isImm() ||
116 Info->get(Inst.getOpcode()).OpInfo[0].OperandType !=
117 MCOI::OPERAND_PCREL)
118 return false;
119
120 int64_t Imm = Inst.getOperand(0).getImm();
121 // Our branches take a simm16, but we need two extra bits to account for
122 // the factor of 4.
123 APInt SignedOffset(18, Imm * 4, true);
124 Target = (SignedOffset.sext(64) + Addr + Size).getZExtValue();
125 return true;
126 }
127 };
128
129 } // end anonymous namespace
130
131 static MCInstrAnalysis *createAMDGPUMCInstrAnalysis(const MCInstrInfo *Info) {
132 return new AMDGPUMCInstrAnalysis(Info);
133 }
134
105135 extern "C" void LLVMInitializeAMDGPUTargetMC() {
106136
107137 TargetRegistry::RegisterMCInstrInfo(getTheGCNTarget(), createAMDGPUMCInstrInfo);
112142 TargetRegistry::RegisterMCRegInfo(*T, createAMDGPUMCRegisterInfo);
113143 TargetRegistry::RegisterMCSubtargetInfo(*T, createAMDGPUMCSubtargetInfo);
114144 TargetRegistry::RegisterMCInstPrinter(*T, createAMDGPUMCInstPrinter);
145 TargetRegistry::RegisterMCInstrAnalysis(*T, createAMDGPUMCInstrAnalysis);
115146 TargetRegistry::RegisterMCAsmBackend(*T, createAMDGPUAsmBackend);
116147 TargetRegistry::RegisterELFStreamer(*T, createMCStreamer);
117148 }
0 // 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
1
2 // FIXME: Immediate operands to sopp_br instructions are currently scaled by a
3 // factor of 4, are unsigned, are always PC relative, don't accept most
4 // expressions, and are not range checked.
5
6 loop_start_nosym:
7 s_branch loop_start_nosym
8 // BIN-NOT: loop_start_nosym:
9 // BIN: s_branch 65535 // 000000000000: BF82FFFF <.text>
10
11 s_branch loop_end_nosym
12 // BIN: s_branch 0 // 000000000004: BF820000 <.text+0x8>
13 // BIN-NOT: loop_end_nosym:
14 loop_end_nosym:
15 s_nop 0
16
17 keep_symbol:
18 s_nop 0
19
20 loop_start_sym:
21 s_branch loop_start_sym
22 // BIN-NOT: loop_start_sym:
23 // BIN: s_branch 65535 // 000000000010: BF82FFFF
24
25 s_branch loop_end_sym
26 // BIN: s_branch 0 // 000000000014: BF820000
27 // BIN-NOT: loop_end_sym:
28 loop_end_sym:
29 s_nop 0
30
31 s_branch 65535
32 // BIN: s_branch 65535 // 00000000001C: BF82FFFF
33
34 s_branch 32768
35 // BIN: s_branch 32768 // 000000000020: BF828000
36
37 s_branch 32767
38 // BIN: s_branch 32767 // 000000000024: BF827FFF
39
40 s_branch 0x80000000ffff
41 // BIN: s_branch 65535 // 000000000028: BF82FFFF