Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,42 @@ static MCPhysReg getRegForPrinting(MCPhysReg Reg, const MCRegisterInfo &MRI) {
return RC->getRegister(Idx % 0x100);
}

// Restore MSBs of a VGPR above 255 from the MCInstrAnalysis.
static MCPhysReg getRegFromMIA(MCPhysReg Reg, unsigned OpNo,
const MCInstrDesc &Desc,
const MCRegisterInfo &MRI,
const AMDGPUMCInstrAnalysis &MIA) {
unsigned VgprMSBs = MIA.getVgprMSBs();
if (!VgprMSBs)
return Reg;

unsigned Enc = MRI.getEncodingValue(Reg);
if (!(Enc & AMDGPU::HWEncoding::IS_VGPR))
return Reg;

auto Ops = AMDGPU::getVGPRLoweringOperandTables(Desc);
if (!Ops.first)
return Reg;
unsigned Opc = Desc.getOpcode();
unsigned I;
for (I = 0; I < 4; ++I) {
if (Ops.first[I] != AMDGPU::OpName::NUM_OPERAND_NAMES &&
(unsigned)AMDGPU::getNamedOperandIdx(Opc, Ops.first[I]) == OpNo)
break;
if (Ops.second && Ops.second[I] != AMDGPU::OpName::NUM_OPERAND_NAMES &&
(unsigned)AMDGPU::getNamedOperandIdx(Opc, Ops.second[I]) == OpNo)
break;
}
if (I == 4)
return Reg;
unsigned OpMSBs = (VgprMSBs >> (I * 2)) & 3;
if (!OpMSBs)
return Reg;
if (MCRegister NewReg = AMDGPU::getVGPRWithMSBs(Reg, OpMSBs, MRI))
return NewReg;
return Reg;
}

void AMDGPUInstPrinter::printRegOperand(MCRegister Reg, raw_ostream &O,
const MCRegisterInfo &MRI) {
#if !defined(NDEBUG)
Expand All @@ -359,6 +395,9 @@ void AMDGPUInstPrinter::printRegOperand(MCRegister Reg, raw_ostream &O,
void AMDGPUInstPrinter::printRegOperand(MCRegister Reg, unsigned Opc,
unsigned OpNo, raw_ostream &O,
const MCRegisterInfo &MRI) {
if (MIA)
Reg = getRegFromMIA(Reg, OpNo, MII.get(Opc), MRI,
*static_cast<const AMDGPUMCInstrAnalysis *>(MIA));
printRegOperand(Reg, O, MRI);
}

Expand Down
48 changes: 26 additions & 22 deletions llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCTargetDesc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@
#include "TargetInfo/AMDGPUTargetInfo.h"
#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCELFStreamer.h"
#include "llvm/MC/MCInstPrinter.h"
#include "llvm/MC/MCInstrAnalysis.h"
#include "llvm/MC/MCInstrDesc.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCObjectWriter.h"
Expand Down Expand Up @@ -130,31 +130,35 @@ static MCStreamer *createMCStreamer(const Triple &T, MCContext &Context,
std::move(Emitter));
}

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()).operands()[0].OperandType !=
MCOI::OPERAND_PCREL)
return false;
namespace llvm {
namespace AMDGPU {

bool AMDGPUMCInstrAnalysis::evaluateBranch(const MCInst &Inst, uint64_t Addr,
uint64_t Size,
uint64_t &Target) const {
if (Inst.getNumOperands() == 0 || !Inst.getOperand(0).isImm() ||
Info->get(Inst.getOpcode()).operands()[0].OperandType !=
MCOI::OPERAND_PCREL)
return false;

int64_t Imm = Inst.getOperand(0).getImm();
// Our branches take a simm16.
Target = SignExtend64<16>(Imm) * 4 + Addr + Size;
return true;
}

int64_t Imm = Inst.getOperand(0).getImm();
// Our branches take a simm16.
Target = SignExtend64<16>(Imm) * 4 + Addr + Size;
return true;
}
};
void AMDGPUMCInstrAnalysis::updateState(const MCInst &Inst, uint64_t Addr) {
if (Inst.getOpcode() == AMDGPU::S_SET_VGPR_MSB_gfx12)
VgprMSBs = Inst.getOperand(0).getImm();
else if (isTerminator(Inst))
VgprMSBs = 0;
}

} // end anonymous namespace
} // end namespace AMDGPU
} // end namespace llvm

static MCInstrAnalysis *createAMDGPUMCInstrAnalysis(const MCInstrInfo *Info) {
return new AMDGPUMCInstrAnalysis(Info);
return new AMDGPU::AMDGPUMCInstrAnalysis(Info);
}

extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void
Expand Down
23 changes: 23 additions & 0 deletions llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCTargetDesc.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#ifndef LLVM_LIB_TARGET_AMDGPU_MCTARGETDESC_AMDGPUMCTARGETDESC_H
#define LLVM_LIB_TARGET_AMDGPU_MCTARGETDESC_AMDGPUMCTARGETDESC_H

#include "llvm/MC/MCInstrAnalysis.h"
#include <cstdint>
#include <memory>

Expand Down Expand Up @@ -44,6 +45,28 @@ MCAsmBackend *createAMDGPUAsmBackend(const Target &T,
std::unique_ptr<MCObjectTargetWriter>
createAMDGPUELFObjectWriter(bool Is64Bit, uint8_t OSABI,
bool HasRelocationAddend);

namespace AMDGPU {
class AMDGPUMCInstrAnalysis : public MCInstrAnalysis {
private:
unsigned VgprMSBs = 0;

public:
explicit AMDGPUMCInstrAnalysis(const MCInstrInfo *Info)
: MCInstrAnalysis(Info) {}

bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size,
uint64_t &Target) const override;

void resetState() override { VgprMSBs = 0; }

void updateState(const MCInst &Inst, uint64_t Addr) override;

unsigned getVgprMSBs() const { return VgprMSBs; }
};

} // namespace AMDGPU

} // namespace llvm

#define GET_REGINFO_ENUM
Expand Down
1 change: 1 addition & 0 deletions llvm/test/CodeGen/AMDGPU/vgpr-lowering-gfx1250.mir
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# RUN: llc -mtriple=amdgcn -mcpu=gfx1250 -start-before=amdgpu-lower-vgpr-encoding -o - %s | FileCheck -check-prefixes=GCN,ASM %s
# RUN: llc -mtriple=amdgcn -mcpu=gfx1250 -start-before=amdgpu-lower-vgpr-encoding -o - %s | llvm-mc -triple=amdgcn -mcpu=gfx1250 -filetype=obj -o - | llvm-objdump -d --mcpu=gfx1250 - | FileCheck -check-prefixes=GCN,DIS %s

# ASM-LABEL: {{^}}high_vgprs:
# DIS-LABEL: <high_vgprs>:
Expand Down