aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/AMDGPU/MCTargetDesc
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/AMDGPU/MCTargetDesc')
-rw-r--r--lib/Target/AMDGPU/MCTargetDesc/AMDGPUAsmBackend.cpp32
-rw-r--r--lib/Target/AMDGPU/MCTargetDesc/AMDGPUELFObjectWriter.cpp12
-rw-r--r--lib/Target/AMDGPU/MCTargetDesc/AMDGPUELFStreamer.cpp37
-rw-r--r--lib/Target/AMDGPU/MCTargetDesc/AMDGPUELFStreamer.h9
-rw-r--r--lib/Target/AMDGPU/MCTargetDesc/AMDGPUHSAMetadataStreamer.cpp407
-rw-r--r--lib/Target/AMDGPU/MCTargetDesc/AMDGPUHSAMetadataStreamer.h96
-rw-r--r--lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCCodeEmitter.cpp2
-rw-r--r--lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCCodeEmitter.h2
-rw-r--r--lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCTargetDesc.cpp36
-rw-r--r--lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCTargetDesc.h29
-rw-r--r--lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.cpp288
-rw-r--r--lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.h34
-rw-r--r--lib/Target/AMDGPU/MCTargetDesc/CMakeLists.txt2
-rw-r--r--lib/Target/AMDGPU/MCTargetDesc/R600MCCodeEmitter.cpp43
-rw-r--r--lib/Target/AMDGPU/MCTargetDesc/R600MCTargetDesc.cpp27
-rw-r--r--lib/Target/AMDGPU/MCTargetDesc/SIMCCodeEmitter.cpp34
16 files changed, 482 insertions, 608 deletions
diff --git a/lib/Target/AMDGPU/MCTargetDesc/AMDGPUAsmBackend.cpp b/lib/Target/AMDGPU/MCTargetDesc/AMDGPUAsmBackend.cpp
index 778d4a7ba9d0..abc88c02adca 100644
--- a/lib/Target/AMDGPU/MCTargetDesc/AMDGPUAsmBackend.cpp
+++ b/lib/Target/AMDGPU/MCTargetDesc/AMDGPUAsmBackend.cpp
@@ -26,14 +26,14 @@ namespace {
class AMDGPUAsmBackend : public MCAsmBackend {
public:
- AMDGPUAsmBackend(const Target &T)
- : MCAsmBackend() {}
+ AMDGPUAsmBackend(const Target &T) : MCAsmBackend(support::little) {}
unsigned getNumFixupKinds() const override { return AMDGPU::NumTargetFixupKinds; };
void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
const MCValue &Target, MutableArrayRef<char> Data,
- uint64_t Value, bool IsResolved) const override;
+ uint64_t Value, bool IsResolved,
+ const MCSubtargetInfo *STI) const override;
bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
const MCRelaxableFragment *DF,
const MCAsmLayout &Layout) const override {
@@ -43,10 +43,13 @@ public:
MCInst &Res) const override {
llvm_unreachable("Not implemented");
}
- bool mayNeedRelaxation(const MCInst &Inst) const override { return false; }
+ bool mayNeedRelaxation(const MCInst &Inst,
+ const MCSubtargetInfo &STI) const override {
+ return false;
+ }
unsigned getMinimumNopSize() const override;
- bool writeNopData(uint64_t Count, MCObjectWriter *OW) const override;
+ bool writeNopData(raw_ostream &OS, uint64_t Count) const override;
const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override;
};
@@ -103,7 +106,8 @@ static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
void AMDGPUAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
const MCValue &Target,
MutableArrayRef<char> Data, uint64_t Value,
- bool IsResolved) const {
+ bool IsResolved,
+ const MCSubtargetInfo *STI) const {
Value = adjustFixupValue(Fixup, Value, &Asm.getContext());
if (!Value)
return; // Doesn't change encoding.
@@ -140,11 +144,11 @@ unsigned AMDGPUAsmBackend::getMinimumNopSize() const {
return 4;
}
-bool AMDGPUAsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const {
+bool AMDGPUAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count) const {
// If the count is not 4-byte aligned, we must be writing data into the text
// section (otherwise we have unaligned instructions, and thus have far
// bigger problems), so just write zeros instead.
- OW->WriteZeros(Count % 4);
+ OS.write_zeros(Count % 4);
// We are properly aligned, so write NOPs as requested.
Count /= 4;
@@ -154,7 +158,7 @@ bool AMDGPUAsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const {
const uint32_t Encoded_S_NOP_0 = 0xbf800000;
for (uint64_t I = 0; I != Count; ++I)
- OW->write32(Encoded_S_NOP_0);
+ support::endian::write<uint32_t>(OS, Encoded_S_NOP_0, Endian);
return true;
}
@@ -189,18 +193,18 @@ public:
}
}
- std::unique_ptr<MCObjectWriter>
- createObjectWriter(raw_pwrite_stream &OS) const override {
- return createAMDGPUELFObjectWriter(Is64Bit, OSABI, HasRelocationAddend, OS);
+ std::unique_ptr<MCObjectTargetWriter>
+ createObjectTargetWriter() const override {
+ return createAMDGPUELFObjectWriter(Is64Bit, OSABI, HasRelocationAddend);
}
};
} // end anonymous namespace
MCAsmBackend *llvm::createAMDGPUAsmBackend(const Target &T,
+ const MCSubtargetInfo &STI,
const MCRegisterInfo &MRI,
- const Triple &TT, StringRef CPU,
const MCTargetOptions &Options) {
// Use 64-bit ELF for amdgcn
- return new ELFAMDGPUAsmBackend(T, TT);
+ return new ELFAMDGPUAsmBackend(T, STI.getTargetTriple());
}
diff --git a/lib/Target/AMDGPU/MCTargetDesc/AMDGPUELFObjectWriter.cpp b/lib/Target/AMDGPU/MCTargetDesc/AMDGPUELFObjectWriter.cpp
index e443b0729606..07bef9103c0d 100644
--- a/lib/Target/AMDGPU/MCTargetDesc/AMDGPUELFObjectWriter.cpp
+++ b/lib/Target/AMDGPU/MCTargetDesc/AMDGPUELFObjectWriter.cpp
@@ -66,6 +66,8 @@ unsigned AMDGPUELFObjectWriter::getRelocType(MCContext &Ctx,
return ELF::R_AMDGPU_REL32_LO;
case MCSymbolRefExpr::VK_AMDGPU_REL32_HI:
return ELF::R_AMDGPU_REL32_HI;
+ case MCSymbolRefExpr::VK_AMDGPU_REL64:
+ return ELF::R_AMDGPU_REL64;
}
switch (Fixup.getKind()) {
@@ -82,11 +84,9 @@ unsigned AMDGPUELFObjectWriter::getRelocType(MCContext &Ctx,
llvm_unreachable("unhandled relocation type");
}
-std::unique_ptr<MCObjectWriter>
+std::unique_ptr<MCObjectTargetWriter>
llvm::createAMDGPUELFObjectWriter(bool Is64Bit, uint8_t OSABI,
- bool HasRelocationAddend,
- raw_pwrite_stream &OS) {
- auto MOTW = llvm::make_unique<AMDGPUELFObjectWriter>(Is64Bit, OSABI,
- HasRelocationAddend);
- return createELFObjectWriter(std::move(MOTW), OS, true);
+ bool HasRelocationAddend) {
+ return llvm::make_unique<AMDGPUELFObjectWriter>(Is64Bit, OSABI,
+ HasRelocationAddend);
}
diff --git a/lib/Target/AMDGPU/MCTargetDesc/AMDGPUELFStreamer.cpp b/lib/Target/AMDGPU/MCTargetDesc/AMDGPUELFStreamer.cpp
index 1497edc7a054..c627a08e7463 100644
--- a/lib/Target/AMDGPU/MCTargetDesc/AMDGPUELFStreamer.cpp
+++ b/lib/Target/AMDGPU/MCTargetDesc/AMDGPUELFStreamer.cpp
@@ -12,37 +12,28 @@
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCCodeEmitter.h"
+#include "llvm/MC/MCObjectWriter.h"
using namespace llvm;
-AMDGPUELFStreamer::AMDGPUELFStreamer(const Triple &T, MCContext &Context,
- std::unique_ptr<MCAsmBackend> MAB,
- raw_pwrite_stream &OS,
- std::unique_ptr<MCCodeEmitter> Emitter)
- : MCELFStreamer(Context, std::move(MAB), OS, std::move(Emitter)) {
- unsigned Arch = ELF::EF_AMDGPU_ARCH_NONE;
- switch (T.getArch()) {
- case Triple::r600:
- Arch = ELF::EF_AMDGPU_ARCH_R600;
- break;
- case Triple::amdgcn:
- Arch = ELF::EF_AMDGPU_ARCH_GCN;
- break;
- default:
- break;
- }
+namespace {
+
+class AMDGPUELFStreamer : public MCELFStreamer {
+public:
+ AMDGPUELFStreamer(const Triple &T, MCContext &Context,
+ std::unique_ptr<MCAsmBackend> MAB,
+ std::unique_ptr<MCObjectWriter> OW,
+ std::unique_ptr<MCCodeEmitter> Emitter)
+ : MCELFStreamer(Context, std::move(MAB), std::move(OW),
+ std::move(Emitter)) {}
+};
- MCAssembler &MCA = getAssembler();
- unsigned EFlags = MCA.getELFHeaderEFlags();
- EFlags &= ~ELF::EF_AMDGPU_ARCH;
- EFlags |= Arch;
- MCA.setELFHeaderEFlags(EFlags);
}
MCELFStreamer *llvm::createAMDGPUELFStreamer(
const Triple &T, MCContext &Context, std::unique_ptr<MCAsmBackend> MAB,
- raw_pwrite_stream &OS, std::unique_ptr<MCCodeEmitter> Emitter,
+ std::unique_ptr<MCObjectWriter> OW, std::unique_ptr<MCCodeEmitter> Emitter,
bool RelaxAll) {
- return new AMDGPUELFStreamer(T, Context, std::move(MAB), OS,
+ return new AMDGPUELFStreamer(T, Context, std::move(MAB), std::move(OW),
std::move(Emitter));
}
diff --git a/lib/Target/AMDGPU/MCTargetDesc/AMDGPUELFStreamer.h b/lib/Target/AMDGPU/MCTargetDesc/AMDGPUELFStreamer.h
index 0cc0a4c5cd5d..41e9063a759e 100644
--- a/lib/Target/AMDGPU/MCTargetDesc/AMDGPUELFStreamer.h
+++ b/lib/Target/AMDGPU/MCTargetDesc/AMDGPUELFStreamer.h
@@ -23,16 +23,9 @@ class MCCodeEmitter;
class MCContext;
class MCSubtargetInfo;
-class AMDGPUELFStreamer : public MCELFStreamer {
-public:
- AMDGPUELFStreamer(const Triple &T, MCContext &Context,
- std::unique_ptr<MCAsmBackend> MAB, raw_pwrite_stream &OS,
- std::unique_ptr<MCCodeEmitter> Emitter);
-};
-
MCELFStreamer *createAMDGPUELFStreamer(const Triple &T, MCContext &Context,
std::unique_ptr<MCAsmBackend> MAB,
- raw_pwrite_stream &OS,
+ std::unique_ptr<MCObjectWriter> OW,
std::unique_ptr<MCCodeEmitter> Emitter,
bool RelaxAll);
} // namespace llvm.
diff --git a/lib/Target/AMDGPU/MCTargetDesc/AMDGPUHSAMetadataStreamer.cpp b/lib/Target/AMDGPU/MCTargetDesc/AMDGPUHSAMetadataStreamer.cpp
deleted file mode 100644
index 463e700f13b7..000000000000
--- a/lib/Target/AMDGPU/MCTargetDesc/AMDGPUHSAMetadataStreamer.cpp
+++ /dev/null
@@ -1,407 +0,0 @@
-//===--- AMDGPUHSAMetadataStreamer.cpp --------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-/// \file
-/// \brief AMDGPU HSA Metadata Streamer.
-///
-//
-//===----------------------------------------------------------------------===//
-
-#include "AMDGPUHSAMetadataStreamer.h"
-#include "AMDGPU.h"
-#include "llvm/ADT/StringSwitch.h"
-#include "llvm/IR/Constants.h"
-#include "llvm/IR/Module.h"
-#include "llvm/Support/raw_ostream.h"
-
-namespace llvm {
-
-static cl::opt<bool> DumpHSAMetadata(
- "amdgpu-dump-hsa-metadata",
- cl::desc("Dump AMDGPU HSA Metadata"));
-static cl::opt<bool> VerifyHSAMetadata(
- "amdgpu-verify-hsa-metadata",
- cl::desc("Verify AMDGPU HSA Metadata"));
-
-namespace AMDGPU {
-namespace HSAMD {
-
-void MetadataStreamer::dump(StringRef HSAMetadataString) const {
- errs() << "AMDGPU HSA Metadata:\n" << HSAMetadataString << '\n';
-}
-
-void MetadataStreamer::verify(StringRef HSAMetadataString) const {
- errs() << "AMDGPU HSA Metadata Parser Test: ";
-
- HSAMD::Metadata FromHSAMetadataString;
- if (fromString(HSAMetadataString, FromHSAMetadataString)) {
- errs() << "FAIL\n";
- return;
- }
-
- std::string ToHSAMetadataString;
- if (toString(FromHSAMetadataString, ToHSAMetadataString)) {
- errs() << "FAIL\n";
- return;
- }
-
- errs() << (HSAMetadataString == ToHSAMetadataString ? "PASS" : "FAIL")
- << '\n';
- if (HSAMetadataString != ToHSAMetadataString) {
- errs() << "Original input: " << HSAMetadataString << '\n'
- << "Produced output: " << ToHSAMetadataString << '\n';
- }
-}
-
-AccessQualifier MetadataStreamer::getAccessQualifier(StringRef AccQual) const {
- if (AccQual.empty())
- return AccessQualifier::Unknown;
-
- return StringSwitch<AccessQualifier>(AccQual)
- .Case("read_only", AccessQualifier::ReadOnly)
- .Case("write_only", AccessQualifier::WriteOnly)
- .Case("read_write", AccessQualifier::ReadWrite)
- .Default(AccessQualifier::Default);
-}
-
-AddressSpaceQualifier MetadataStreamer::getAddressSpaceQualifer(
- unsigned AddressSpace) const {
- if (AddressSpace == AMDGPUASI.PRIVATE_ADDRESS)
- return AddressSpaceQualifier::Private;
- if (AddressSpace == AMDGPUASI.GLOBAL_ADDRESS)
- return AddressSpaceQualifier::Global;
- if (AddressSpace == AMDGPUASI.CONSTANT_ADDRESS)
- return AddressSpaceQualifier::Constant;
- if (AddressSpace == AMDGPUASI.LOCAL_ADDRESS)
- return AddressSpaceQualifier::Local;
- if (AddressSpace == AMDGPUASI.FLAT_ADDRESS)
- return AddressSpaceQualifier::Generic;
- if (AddressSpace == AMDGPUASI.REGION_ADDRESS)
- return AddressSpaceQualifier::Region;
-
- llvm_unreachable("Unknown address space qualifier");
-}
-
-ValueKind MetadataStreamer::getValueKind(Type *Ty, StringRef TypeQual,
- StringRef BaseTypeName) const {
- if (TypeQual.find("pipe") != StringRef::npos)
- return ValueKind::Pipe;
-
- return StringSwitch<ValueKind>(BaseTypeName)
- .Case("image1d_t", ValueKind::Image)
- .Case("image1d_array_t", ValueKind::Image)
- .Case("image1d_buffer_t", ValueKind::Image)
- .Case("image2d_t", ValueKind::Image)
- .Case("image2d_array_t", ValueKind::Image)
- .Case("image2d_array_depth_t", ValueKind::Image)
- .Case("image2d_array_msaa_t", ValueKind::Image)
- .Case("image2d_array_msaa_depth_t", ValueKind::Image)
- .Case("image2d_depth_t", ValueKind::Image)
- .Case("image2d_msaa_t", ValueKind::Image)
- .Case("image2d_msaa_depth_t", ValueKind::Image)
- .Case("image3d_t", ValueKind::Image)
- .Case("sampler_t", ValueKind::Sampler)
- .Case("queue_t", ValueKind::Queue)
- .Default(isa<PointerType>(Ty) ?
- (Ty->getPointerAddressSpace() ==
- AMDGPUASI.LOCAL_ADDRESS ?
- ValueKind::DynamicSharedPointer :
- ValueKind::GlobalBuffer) :
- ValueKind::ByValue);
-}
-
-ValueType MetadataStreamer::getValueType(Type *Ty, StringRef TypeName) const {
- switch (Ty->getTypeID()) {
- case Type::IntegerTyID: {
- auto Signed = !TypeName.startswith("u");
- switch (Ty->getIntegerBitWidth()) {
- case 8:
- return Signed ? ValueType::I8 : ValueType::U8;
- case 16:
- return Signed ? ValueType::I16 : ValueType::U16;
- case 32:
- return Signed ? ValueType::I32 : ValueType::U32;
- case 64:
- return Signed ? ValueType::I64 : ValueType::U64;
- default:
- return ValueType::Struct;
- }
- }
- case Type::HalfTyID:
- return ValueType::F16;
- case Type::FloatTyID:
- return ValueType::F32;
- case Type::DoubleTyID:
- return ValueType::F64;
- case Type::PointerTyID:
- return getValueType(Ty->getPointerElementType(), TypeName);
- case Type::VectorTyID:
- return getValueType(Ty->getVectorElementType(), TypeName);
- default:
- return ValueType::Struct;
- }
-}
-
-std::string MetadataStreamer::getTypeName(Type *Ty, bool Signed) const {
- switch (Ty->getTypeID()) {
- case Type::IntegerTyID: {
- if (!Signed)
- return (Twine('u') + getTypeName(Ty, true)).str();
-
- auto BitWidth = Ty->getIntegerBitWidth();
- switch (BitWidth) {
- case 8:
- return "char";
- case 16:
- return "short";
- case 32:
- return "int";
- case 64:
- return "long";
- default:
- return (Twine('i') + Twine(BitWidth)).str();
- }
- }
- case Type::HalfTyID:
- return "half";
- case Type::FloatTyID:
- return "float";
- case Type::DoubleTyID:
- return "double";
- case Type::VectorTyID: {
- auto VecTy = cast<VectorType>(Ty);
- auto ElTy = VecTy->getElementType();
- auto NumElements = VecTy->getVectorNumElements();
- return (Twine(getTypeName(ElTy, Signed)) + Twine(NumElements)).str();
- }
- default:
- return "unknown";
- }
-}
-
-std::vector<uint32_t> MetadataStreamer::getWorkGroupDimensions(
- MDNode *Node) const {
- std::vector<uint32_t> Dims;
- if (Node->getNumOperands() != 3)
- return Dims;
-
- for (auto &Op : Node->operands())
- Dims.push_back(mdconst::extract<ConstantInt>(Op)->getZExtValue());
- return Dims;
-}
-
-void MetadataStreamer::emitVersion() {
- auto &Version = HSAMetadata.mVersion;
-
- Version.push_back(VersionMajor);
- Version.push_back(VersionMinor);
-}
-
-void MetadataStreamer::emitPrintf(const Module &Mod) {
- auto &Printf = HSAMetadata.mPrintf;
-
- auto Node = Mod.getNamedMetadata("llvm.printf.fmts");
- if (!Node)
- return;
-
- for (auto Op : Node->operands())
- if (Op->getNumOperands())
- Printf.push_back(cast<MDString>(Op->getOperand(0))->getString());
-}
-
-void MetadataStreamer::emitKernelLanguage(const Function &Func) {
- auto &Kernel = HSAMetadata.mKernels.back();
-
- // TODO: What about other languages?
- auto Node = Func.getParent()->getNamedMetadata("opencl.ocl.version");
- if (!Node || !Node->getNumOperands())
- return;
- auto Op0 = Node->getOperand(0);
- if (Op0->getNumOperands() <= 1)
- return;
-
- Kernel.mLanguage = "OpenCL C";
- Kernel.mLanguageVersion.push_back(
- mdconst::extract<ConstantInt>(Op0->getOperand(0))->getZExtValue());
- Kernel.mLanguageVersion.push_back(
- mdconst::extract<ConstantInt>(Op0->getOperand(1))->getZExtValue());
-}
-
-void MetadataStreamer::emitKernelAttrs(const Function &Func) {
- auto &Attrs = HSAMetadata.mKernels.back().mAttrs;
-
- if (auto Node = Func.getMetadata("reqd_work_group_size"))
- Attrs.mReqdWorkGroupSize = getWorkGroupDimensions(Node);
- if (auto Node = Func.getMetadata("work_group_size_hint"))
- Attrs.mWorkGroupSizeHint = getWorkGroupDimensions(Node);
- if (auto Node = Func.getMetadata("vec_type_hint")) {
- Attrs.mVecTypeHint = getTypeName(
- cast<ValueAsMetadata>(Node->getOperand(0))->getType(),
- mdconst::extract<ConstantInt>(Node->getOperand(1))->getZExtValue());
- }
- if (Func.hasFnAttribute("runtime-handle")) {
- Attrs.mRuntimeHandle =
- Func.getFnAttribute("runtime-handle").getValueAsString().str();
- }
-}
-
-void MetadataStreamer::emitKernelArgs(const Function &Func) {
- for (auto &Arg : Func.args())
- emitKernelArg(Arg);
-
- // TODO: What about other languages?
- if (!Func.getParent()->getNamedMetadata("opencl.ocl.version"))
- return;
-
- auto &DL = Func.getParent()->getDataLayout();
- auto Int64Ty = Type::getInt64Ty(Func.getContext());
-
- emitKernelArg(DL, Int64Ty, ValueKind::HiddenGlobalOffsetX);
- emitKernelArg(DL, Int64Ty, ValueKind::HiddenGlobalOffsetY);
- emitKernelArg(DL, Int64Ty, ValueKind::HiddenGlobalOffsetZ);
-
- auto Int8PtrTy = Type::getInt8PtrTy(Func.getContext(),
- AMDGPUASI.GLOBAL_ADDRESS);
- auto CallsPrintf = Func.getParent()->getNamedMetadata("llvm.printf.fmts");
- if (CallsPrintf)
- emitKernelArg(DL, Int8PtrTy, ValueKind::HiddenPrintfBuffer);
- if (Func.hasFnAttribute("calls-enqueue-kernel")) {
- if (!CallsPrintf) {
- // Emit a dummy argument so that the remaining hidden arguments
- // have a fixed position relative to the first hidden argument.
- // This is to facilitate library code to access hidden arguments.
- emitKernelArg(DL, Int8PtrTy, ValueKind::HiddenNone);
- }
- emitKernelArg(DL, Int8PtrTy, ValueKind::HiddenDefaultQueue);
- emitKernelArg(DL, Int8PtrTy, ValueKind::HiddenCompletionAction);
- }
-}
-
-void MetadataStreamer::emitKernelArg(const Argument &Arg) {
- auto Func = Arg.getParent();
- auto ArgNo = Arg.getArgNo();
- const MDNode *Node;
-
- StringRef Name;
- Node = Func->getMetadata("kernel_arg_name");
- if (Node && ArgNo < Node->getNumOperands())
- Name = cast<MDString>(Node->getOperand(ArgNo))->getString();
- else if (Arg.hasName())
- Name = Arg.getName();
-
- StringRef TypeName;
- Node = Func->getMetadata("kernel_arg_type");
- if (Node && ArgNo < Node->getNumOperands())
- TypeName = cast<MDString>(Node->getOperand(ArgNo))->getString();
-
- StringRef BaseTypeName;
- Node = Func->getMetadata("kernel_arg_base_type");
- if (Node && ArgNo < Node->getNumOperands())
- BaseTypeName = cast<MDString>(Node->getOperand(ArgNo))->getString();
-
- StringRef AccQual;
- if (Arg.getType()->isPointerTy() && Arg.onlyReadsMemory() &&
- Arg.hasNoAliasAttr()) {
- AccQual = "read_only";
- } else {
- Node = Func->getMetadata("kernel_arg_access_qual");
- if (Node && ArgNo < Node->getNumOperands())
- AccQual = cast<MDString>(Node->getOperand(ArgNo))->getString();
- }
-
- StringRef TypeQual;
- Node = Func->getMetadata("kernel_arg_type_qual");
- if (Node && ArgNo < Node->getNumOperands())
- TypeQual = cast<MDString>(Node->getOperand(ArgNo))->getString();
-
- emitKernelArg(Func->getParent()->getDataLayout(), Arg.getType(),
- getValueKind(Arg.getType(), TypeQual, BaseTypeName), Name,
- TypeName, BaseTypeName, AccQual, TypeQual);
-}
-
-void MetadataStreamer::emitKernelArg(const DataLayout &DL, Type *Ty,
- ValueKind ValueKind, StringRef Name,
- StringRef TypeName, StringRef BaseTypeName,
- StringRef AccQual, StringRef TypeQual) {
- HSAMetadata.mKernels.back().mArgs.push_back(Kernel::Arg::Metadata());
- auto &Arg = HSAMetadata.mKernels.back().mArgs.back();
-
- Arg.mName = Name;
- Arg.mTypeName = TypeName;
- Arg.mSize = DL.getTypeAllocSize(Ty);
- Arg.mAlign = DL.getABITypeAlignment(Ty);
- Arg.mValueKind = ValueKind;
- Arg.mValueType = getValueType(Ty, BaseTypeName);
-
- if (auto PtrTy = dyn_cast<PointerType>(Ty)) {
- auto ElTy = PtrTy->getElementType();
- if (PtrTy->getAddressSpace() == AMDGPUASI.LOCAL_ADDRESS && ElTy->isSized())
- Arg.mPointeeAlign = DL.getABITypeAlignment(ElTy);
- }
-
- if (auto PtrTy = dyn_cast<PointerType>(Ty))
- Arg.mAddrSpaceQual = getAddressSpaceQualifer(PtrTy->getAddressSpace());
-
- Arg.mAccQual = getAccessQualifier(AccQual);
-
- // TODO: Emit Arg.mActualAccQual.
-
- SmallVector<StringRef, 1> SplitTypeQuals;
- TypeQual.split(SplitTypeQuals, " ", -1, false);
- for (StringRef Key : SplitTypeQuals) {
- auto P = StringSwitch<bool*>(Key)
- .Case("const", &Arg.mIsConst)
- .Case("restrict", &Arg.mIsRestrict)
- .Case("volatile", &Arg.mIsVolatile)
- .Case("pipe", &Arg.mIsPipe)
- .Default(nullptr);
- if (P)
- *P = true;
- }
-}
-
-void MetadataStreamer::begin(const Module &Mod) {
- AMDGPUASI = getAMDGPUAS(Mod);
- emitVersion();
- emitPrintf(Mod);
-}
-
-void MetadataStreamer::end() {
- std::string HSAMetadataString;
- if (toString(HSAMetadata, HSAMetadataString))
- return;
-
- if (DumpHSAMetadata)
- dump(HSAMetadataString);
- if (VerifyHSAMetadata)
- verify(HSAMetadataString);
-}
-
-void MetadataStreamer::emitKernel(
- const Function &Func,
- const Kernel::CodeProps::Metadata &CodeProps,
- const Kernel::DebugProps::Metadata &DebugProps) {
- if (Func.getCallingConv() != CallingConv::AMDGPU_KERNEL)
- return;
-
- HSAMetadata.mKernels.push_back(Kernel::Metadata());
- auto &Kernel = HSAMetadata.mKernels.back();
-
- Kernel.mName = Func.getName();
- Kernel.mSymbolName = (Twine(Func.getName()) + Twine("@kd")).str();
- emitKernelLanguage(Func);
- emitKernelAttrs(Func);
- emitKernelArgs(Func);
- HSAMetadata.mKernels.back().mCodeProps = CodeProps;
- HSAMetadata.mKernels.back().mDebugProps = DebugProps;
-}
-
-} // end namespace HSAMD
-} // end namespace AMDGPU
-} // end namespace llvm
diff --git a/lib/Target/AMDGPU/MCTargetDesc/AMDGPUHSAMetadataStreamer.h b/lib/Target/AMDGPU/MCTargetDesc/AMDGPUHSAMetadataStreamer.h
deleted file mode 100644
index bd6515521a74..000000000000
--- a/lib/Target/AMDGPU/MCTargetDesc/AMDGPUHSAMetadataStreamer.h
+++ /dev/null
@@ -1,96 +0,0 @@
-//===--- AMDGPUHSAMetadataStreamer.h ----------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-/// \file
-/// \brief AMDGPU HSA Metadata Streamer.
-///
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_LIB_TARGET_AMDGPU_MCTARGETDESC_AMDGPUHSAMETADATASTREAMER_H
-#define LLVM_LIB_TARGET_AMDGPU_MCTARGETDESC_AMDGPUHSAMETADATASTREAMER_H
-
-#include "AMDGPU.h"
-#include "AMDKernelCodeT.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/AMDGPUMetadata.h"
-
-namespace llvm {
-
-class Argument;
-class DataLayout;
-class Function;
-class MDNode;
-class Module;
-class Type;
-
-namespace AMDGPU {
-namespace HSAMD {
-
-class MetadataStreamer final {
-private:
- Metadata HSAMetadata;
- AMDGPUAS AMDGPUASI;
-
- void dump(StringRef HSAMetadataString) const;
-
- void verify(StringRef HSAMetadataString) const;
-
- AccessQualifier getAccessQualifier(StringRef AccQual) const;
-
- AddressSpaceQualifier getAddressSpaceQualifer(unsigned AddressSpace) const;
-
- ValueKind getValueKind(Type *Ty, StringRef TypeQual,
- StringRef BaseTypeName) const;
-
- ValueType getValueType(Type *Ty, StringRef TypeName) const;
-
- std::string getTypeName(Type *Ty, bool Signed) const;
-
- std::vector<uint32_t> getWorkGroupDimensions(MDNode *Node) const;
-
- void emitVersion();
-
- void emitPrintf(const Module &Mod);
-
- void emitKernelLanguage(const Function &Func);
-
- void emitKernelAttrs(const Function &Func);
-
- void emitKernelArgs(const Function &Func);
-
- void emitKernelArg(const Argument &Arg);
-
- void emitKernelArg(const DataLayout &DL, Type *Ty, ValueKind ValueKind,
- StringRef Name = "", StringRef TypeName = "",
- StringRef BaseTypeName = "", StringRef AccQual = "",
- StringRef TypeQual = "");
-
-public:
- MetadataStreamer() = default;
- ~MetadataStreamer() = default;
-
- const Metadata &getHSAMetadata() const {
- return HSAMetadata;
- }
-
- void begin(const Module &Mod);
-
- void end();
-
- void emitKernel(const Function &Func,
- const Kernel::CodeProps::Metadata &CodeProps,
- const Kernel::DebugProps::Metadata &DebugProps);
-};
-
-} // end namespace HSAMD
-} // end namespace AMDGPU
-} // end namespace llvm
-
-#endif // LLVM_LIB_TARGET_AMDGPU_MCTARGETDESC_AMDGPUHSAMETADATASTREAMER_H
diff --git a/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCCodeEmitter.cpp b/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCCodeEmitter.cpp
index 521b3b39bba2..cae7a7a6c7e7 100644
--- a/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCCodeEmitter.cpp
+++ b/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCCodeEmitter.cpp
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
//
/// \file
-/// \brief CodeEmitter interface for R600 and SI codegen.
+/// CodeEmitter interface for R600 and SI codegen.
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCCodeEmitter.h b/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCCodeEmitter.h
index 1b062064ace1..dcc10a032afe 100644
--- a/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCCodeEmitter.h
+++ b/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCCodeEmitter.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
//
/// \file
-/// \brief CodeEmitter interface for R600 and SI codegen.
+/// CodeEmitter interface for R600 and SI codegen.
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCTargetDesc.cpp b/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCTargetDesc.cpp
index 2b321c04fb30..c579c7d60e16 100644
--- a/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCTargetDesc.cpp
+++ b/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCTargetDesc.cpp
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
//
/// \file
-/// \brief This file provides AMDGPU specific target descriptions.
+/// This file provides AMDGPU specific target descriptions.
//
//===----------------------------------------------------------------------===//
@@ -22,6 +22,7 @@
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCInstrInfo.h"
+#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSubtargetInfo.h"
@@ -37,9 +38,17 @@ using namespace llvm;
#define GET_SUBTARGETINFO_MC_DESC
#include "AMDGPUGenSubtargetInfo.inc"
+#define NoSchedModel NoSchedModelR600
+#define GET_SUBTARGETINFO_MC_DESC
+#include "R600GenSubtargetInfo.inc"
+#undef NoSchedModelR600
+
#define GET_REGINFO_MC_DESC
#include "AMDGPUGenRegisterInfo.inc"
+#define GET_REGINFO_MC_DESC
+#include "R600GenRegisterInfo.inc"
+
static MCInstrInfo *createAMDGPUMCInstrInfo() {
MCInstrInfo *X = new MCInstrInfo();
InitAMDGPUMCInstrInfo(X);
@@ -48,12 +57,17 @@ static MCInstrInfo *createAMDGPUMCInstrInfo() {
static MCRegisterInfo *createAMDGPUMCRegisterInfo(const Triple &TT) {
MCRegisterInfo *X = new MCRegisterInfo();
- InitAMDGPUMCRegisterInfo(X, 0);
+ if (TT.getArch() == Triple::r600)
+ InitR600MCRegisterInfo(X, 0);
+ else
+ InitAMDGPUMCRegisterInfo(X, 0);
return X;
}
static MCSubtargetInfo *
createAMDGPUMCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS) {
+ if (TT.getArch() == Triple::r600)
+ return createR600MCSubtargetInfoImpl(TT, CPU, FS);
return createAMDGPUMCSubtargetInfoImpl(TT, CPU, FS);
}
@@ -62,8 +76,10 @@ static MCInstPrinter *createAMDGPUMCInstPrinter(const Triple &T,
const MCAsmInfo &MAI,
const MCInstrInfo &MII,
const MCRegisterInfo &MRI) {
- return T.getArch() == Triple::r600 ? new R600InstPrinter(MAI, MII, MRI) :
- new AMDGPUInstPrinter(MAI, MII, MRI);
+ if (T.getArch() == Triple::r600)
+ return new R600InstPrinter(MAI, MII, MRI);
+ else
+ return new AMDGPUInstPrinter(MAI, MII, MRI);
}
static MCTargetStreamer *createAMDGPUAsmTargetStreamer(MCStreamer &S,
@@ -76,23 +92,25 @@ static MCTargetStreamer *createAMDGPUAsmTargetStreamer(MCStreamer &S,
static MCTargetStreamer * createAMDGPUObjectTargetStreamer(
MCStreamer &S,
const MCSubtargetInfo &STI) {
- return new AMDGPUTargetELFStreamer(S);
+ return new AMDGPUTargetELFStreamer(S, STI);
}
static MCStreamer *createMCStreamer(const Triple &T, MCContext &Context,
std::unique_ptr<MCAsmBackend> &&MAB,
- raw_pwrite_stream &OS,
+ std::unique_ptr<MCObjectWriter> &&OW,
std::unique_ptr<MCCodeEmitter> &&Emitter,
bool RelaxAll) {
- return createAMDGPUELFStreamer(T, Context, std::move(MAB), OS,
+ return createAMDGPUELFStreamer(T, Context, std::move(MAB), std::move(OW),
std::move(Emitter), RelaxAll);
}
extern "C" void LLVMInitializeAMDGPUTargetMC() {
+
+ TargetRegistry::RegisterMCInstrInfo(getTheGCNTarget(), createAMDGPUMCInstrInfo);
+ TargetRegistry::RegisterMCInstrInfo(getTheAMDGPUTarget(), createR600MCInstrInfo);
for (Target *T : {&getTheAMDGPUTarget(), &getTheGCNTarget()}) {
RegisterMCAsmInfo<AMDGPUMCAsmInfo> X(*T);
- TargetRegistry::RegisterMCInstrInfo(*T, createAMDGPUMCInstrInfo);
TargetRegistry::RegisterMCRegInfo(*T, createAMDGPUMCRegisterInfo);
TargetRegistry::RegisterMCSubtargetInfo(*T, createAMDGPUMCSubtargetInfo);
TargetRegistry::RegisterMCInstPrinter(*T, createAMDGPUMCInstPrinter);
@@ -103,6 +121,8 @@ extern "C" void LLVMInitializeAMDGPUTargetMC() {
// R600 specific registration
TargetRegistry::RegisterMCCodeEmitter(getTheAMDGPUTarget(),
createR600MCCodeEmitter);
+ TargetRegistry::RegisterObjectTargetStreamer(
+ getTheAMDGPUTarget(), createAMDGPUObjectTargetStreamer);
// GCN specific registration
TargetRegistry::RegisterMCCodeEmitter(getTheGCNTarget(),
diff --git a/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCTargetDesc.h b/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCTargetDesc.h
index 0b3563303ad0..f3628d96d6e9 100644
--- a/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCTargetDesc.h
+++ b/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCTargetDesc.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
//
/// \file
-/// \brief Provides AMDGPU specific target descriptions.
+/// Provides AMDGPU specific target descriptions.
//
//===----------------------------------------------------------------------===//
//
@@ -25,7 +25,7 @@ class MCAsmBackend;
class MCCodeEmitter;
class MCContext;
class MCInstrInfo;
-class MCObjectWriter;
+class MCObjectTargetWriter;
class MCRegisterInfo;
class MCSubtargetInfo;
class MCTargetOptions;
@@ -40,24 +40,30 @@ Target &getTheGCNTarget();
MCCodeEmitter *createR600MCCodeEmitter(const MCInstrInfo &MCII,
const MCRegisterInfo &MRI,
MCContext &Ctx);
+MCInstrInfo *createR600MCInstrInfo();
MCCodeEmitter *createSIMCCodeEmitter(const MCInstrInfo &MCII,
const MCRegisterInfo &MRI,
MCContext &Ctx);
-MCAsmBackend *createAMDGPUAsmBackend(const Target &T, const MCRegisterInfo &MRI,
- const Triple &TT, StringRef CPU,
+MCAsmBackend *createAMDGPUAsmBackend(const Target &T,
+ const MCSubtargetInfo &STI,
+ const MCRegisterInfo &MRI,
const MCTargetOptions &Options);
-std::unique_ptr<MCObjectWriter>
+std::unique_ptr<MCObjectTargetWriter>
createAMDGPUELFObjectWriter(bool Is64Bit, uint8_t OSABI,
- bool HasRelocationAddend, raw_pwrite_stream &OS);
+ bool HasRelocationAddend);
} // End llvm namespace
#define GET_REGINFO_ENUM
#include "AMDGPUGenRegisterInfo.inc"
#undef GET_REGINFO_ENUM
+#define GET_REGINFO_ENUM
+#include "R600GenRegisterInfo.inc"
+#undef GET_REGINFO_ENUM
+
#define GET_INSTRINFO_ENUM
#define GET_INSTRINFO_OPERAND_ENUM
#define GET_INSTRINFO_SCHED_ENUM
@@ -66,9 +72,20 @@ createAMDGPUELFObjectWriter(bool Is64Bit, uint8_t OSABI,
#undef GET_INSTRINFO_OPERAND_ENUM
#undef GET_INSTRINFO_ENUM
+#define GET_INSTRINFO_ENUM
+#define GET_INSTRINFO_OPERAND_ENUM
+#define GET_INSTRINFO_SCHED_ENUM
+#include "R600GenInstrInfo.inc"
+#undef GET_INSTRINFO_SCHED_ENUM
+#undef GET_INSTRINFO_OPERAND_ENUM
+#undef GET_INSTRINFO_ENUM
#define GET_SUBTARGETINFO_ENUM
#include "AMDGPUGenSubtargetInfo.inc"
#undef GET_SUBTARGETINFO_ENUM
+#define GET_SUBTARGETINFO_ENUM
+#include "R600GenSubtargetInfo.inc"
+#undef GET_SUBTARGETINFO_ENUM
+
#endif
diff --git a/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.cpp b/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.cpp
index d897956daccf..6a41e3f650bc 100644
--- a/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.cpp
+++ b/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.cpp
@@ -39,6 +39,84 @@ using namespace llvm::AMDGPU;
// AMDGPUTargetStreamer
//===----------------------------------------------------------------------===//
+static const struct {
+ const char *Name;
+ unsigned Mach;
+} MachTable[] = {
+ // Radeon HD 2000/3000 Series (R600).
+ { "r600", ELF::EF_AMDGPU_MACH_R600_R600 },
+ { "r630", ELF::EF_AMDGPU_MACH_R600_R630 },
+ { "rs880", ELF::EF_AMDGPU_MACH_R600_RS880 },
+ { "rv670", ELF::EF_AMDGPU_MACH_R600_RV670 },
+ // Radeon HD 4000 Series (R700).
+ { "rv710", ELF::EF_AMDGPU_MACH_R600_RV710 },
+ { "rv730", ELF::EF_AMDGPU_MACH_R600_RV730 },
+ { "rv770", ELF::EF_AMDGPU_MACH_R600_RV770 },
+ // Radeon HD 5000 Series (Evergreen).
+ { "cedar", ELF::EF_AMDGPU_MACH_R600_CEDAR },
+ { "cypress", ELF::EF_AMDGPU_MACH_R600_CYPRESS },
+ { "juniper", ELF::EF_AMDGPU_MACH_R600_JUNIPER },
+ { "redwood", ELF::EF_AMDGPU_MACH_R600_REDWOOD },
+ { "sumo", ELF::EF_AMDGPU_MACH_R600_SUMO },
+ // Radeon HD 6000 Series (Northern Islands).
+ { "barts", ELF::EF_AMDGPU_MACH_R600_BARTS },
+ { "caicos", ELF::EF_AMDGPU_MACH_R600_CAICOS },
+ { "cayman", ELF::EF_AMDGPU_MACH_R600_CAYMAN },
+ { "turks", ELF::EF_AMDGPU_MACH_R600_TURKS },
+ // AMDGCN GFX6.
+ { "gfx600", ELF::EF_AMDGPU_MACH_AMDGCN_GFX600 },
+ { "tahiti", ELF::EF_AMDGPU_MACH_AMDGCN_GFX600 },
+ { "gfx601", ELF::EF_AMDGPU_MACH_AMDGCN_GFX601 },
+ { "hainan", ELF::EF_AMDGPU_MACH_AMDGCN_GFX601 },
+ { "oland", ELF::EF_AMDGPU_MACH_AMDGCN_GFX601 },
+ { "pitcairn", ELF::EF_AMDGPU_MACH_AMDGCN_GFX601 },
+ { "verde", ELF::EF_AMDGPU_MACH_AMDGCN_GFX601 },
+ // AMDGCN GFX7.
+ { "gfx700", ELF::EF_AMDGPU_MACH_AMDGCN_GFX700 },
+ { "kaveri", ELF::EF_AMDGPU_MACH_AMDGCN_GFX700 },
+ { "gfx701", ELF::EF_AMDGPU_MACH_AMDGCN_GFX701 },
+ { "hawaii", ELF::EF_AMDGPU_MACH_AMDGCN_GFX701 },
+ { "gfx702", ELF::EF_AMDGPU_MACH_AMDGCN_GFX702 },
+ { "gfx703", ELF::EF_AMDGPU_MACH_AMDGCN_GFX703 },
+ { "kabini", ELF::EF_AMDGPU_MACH_AMDGCN_GFX703 },
+ { "mullins", ELF::EF_AMDGPU_MACH_AMDGCN_GFX703 },
+ { "gfx704", ELF::EF_AMDGPU_MACH_AMDGCN_GFX704 },
+ { "bonaire", ELF::EF_AMDGPU_MACH_AMDGCN_GFX704 },
+ // AMDGCN GFX8.
+ { "gfx801", ELF::EF_AMDGPU_MACH_AMDGCN_GFX801 },
+ { "carrizo", ELF::EF_AMDGPU_MACH_AMDGCN_GFX801 },
+ { "gfx802", ELF::EF_AMDGPU_MACH_AMDGCN_GFX802 },
+ { "iceland", ELF::EF_AMDGPU_MACH_AMDGCN_GFX802 },
+ { "tonga", ELF::EF_AMDGPU_MACH_AMDGCN_GFX802 },
+ { "gfx803", ELF::EF_AMDGPU_MACH_AMDGCN_GFX803 },
+ { "fiji", ELF::EF_AMDGPU_MACH_AMDGCN_GFX803 },
+ { "polaris10", ELF::EF_AMDGPU_MACH_AMDGCN_GFX803 },
+ { "polaris11", ELF::EF_AMDGPU_MACH_AMDGCN_GFX803 },
+ { "gfx810", ELF::EF_AMDGPU_MACH_AMDGCN_GFX810 },
+ { "stoney", ELF::EF_AMDGPU_MACH_AMDGCN_GFX810 },
+ // AMDGCN GFX9.
+ { "gfx900", ELF::EF_AMDGPU_MACH_AMDGCN_GFX900 },
+ { "gfx902", ELF::EF_AMDGPU_MACH_AMDGCN_GFX902 },
+ { "gfx904", ELF::EF_AMDGPU_MACH_AMDGCN_GFX904 },
+ { "gfx906", ELF::EF_AMDGPU_MACH_AMDGCN_GFX906 },
+ // Not specified processor.
+ { nullptr, ELF::EF_AMDGPU_MACH_NONE }
+};
+
+unsigned AMDGPUTargetStreamer::getMACH(StringRef GPU) const {
+ auto Entry = MachTable;
+ for (; Entry->Name && GPU != Entry->Name; ++Entry)
+ ;
+ return Entry->Mach;
+}
+
+const char *AMDGPUTargetStreamer::getMachName(unsigned Mach) {
+ auto Entry = MachTable;
+ for (; Entry->Name && Mach != Entry->Mach; ++Entry)
+ ;
+ return Entry->Name;
+}
+
bool AMDGPUTargetStreamer::EmitHSAMetadata(StringRef HSAMetadataString) {
HSAMD::Metadata HSAMetadata;
if (HSAMD::fromString(HSAMetadataString, HSAMetadata))
@@ -55,9 +133,12 @@ AMDGPUTargetAsmStreamer::AMDGPUTargetAsmStreamer(MCStreamer &S,
formatted_raw_ostream &OS)
: AMDGPUTargetStreamer(S), OS(OS) { }
-void
-AMDGPUTargetAsmStreamer::EmitDirectiveHSACodeObjectVersion(uint32_t Major,
- uint32_t Minor) {
+void AMDGPUTargetAsmStreamer::EmitDirectiveAMDGCNTarget(StringRef Target) {
+ OS << "\t.amdgcn_target \"" << Target << "\"\n";
+}
+
+void AMDGPUTargetAsmStreamer::EmitDirectiveHSACodeObjectVersion(
+ uint32_t Major, uint32_t Minor) {
OS << "\t.hsa_code_object_version " <<
Twine(Major) << "," << Twine(Minor) << '\n';
}
@@ -118,12 +199,157 @@ bool AMDGPUTargetAsmStreamer::EmitPALMetadata(
return true;
}
+void AMDGPUTargetAsmStreamer::EmitAmdhsaKernelDescriptor(
+ const MCSubtargetInfo &STI, StringRef KernelName,
+ const amdhsa::kernel_descriptor_t &KD, uint64_t NextVGPR, uint64_t NextSGPR,
+ bool ReserveVCC, bool ReserveFlatScr, bool ReserveXNACK) {
+ amdhsa::kernel_descriptor_t DefaultKD = getDefaultAmdhsaKernelDescriptor();
+
+ IsaInfo::IsaVersion IVersion = IsaInfo::getIsaVersion(STI.getFeatureBits());
+
+ OS << "\t.amdhsa_kernel " << KernelName << '\n';
+
+#define PRINT_IF_NOT_DEFAULT(STREAM, DIRECTIVE, KERNEL_DESC, \
+ DEFAULT_KERNEL_DESC, MEMBER_NAME, FIELD_NAME) \
+ if (AMDHSA_BITS_GET(KERNEL_DESC.MEMBER_NAME, FIELD_NAME) != \
+ AMDHSA_BITS_GET(DEFAULT_KERNEL_DESC.MEMBER_NAME, FIELD_NAME)) \
+ STREAM << "\t\t" << DIRECTIVE << " " \
+ << AMDHSA_BITS_GET(KERNEL_DESC.MEMBER_NAME, FIELD_NAME) << '\n';
+
+ if (KD.group_segment_fixed_size != DefaultKD.group_segment_fixed_size)
+ OS << "\t\t.amdhsa_group_segment_fixed_size " << KD.group_segment_fixed_size
+ << '\n';
+ if (KD.private_segment_fixed_size != DefaultKD.private_segment_fixed_size)
+ OS << "\t\t.amdhsa_private_segment_fixed_size "
+ << KD.private_segment_fixed_size << '\n';
+
+ PRINT_IF_NOT_DEFAULT(
+ OS, ".amdhsa_user_sgpr_private_segment_buffer", KD, DefaultKD,
+ kernel_code_properties,
+ amdhsa::KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_BUFFER);
+ PRINT_IF_NOT_DEFAULT(OS, ".amdhsa_user_sgpr_dispatch_ptr", KD, DefaultKD,
+ kernel_code_properties,
+ amdhsa::KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_PTR);
+ PRINT_IF_NOT_DEFAULT(OS, ".amdhsa_user_sgpr_queue_ptr", KD, DefaultKD,
+ kernel_code_properties,
+ amdhsa::KERNEL_CODE_PROPERTY_ENABLE_SGPR_QUEUE_PTR);
+ PRINT_IF_NOT_DEFAULT(
+ OS, ".amdhsa_user_sgpr_kernarg_segment_ptr", KD, DefaultKD,
+ kernel_code_properties,
+ amdhsa::KERNEL_CODE_PROPERTY_ENABLE_SGPR_KERNARG_SEGMENT_PTR);
+ PRINT_IF_NOT_DEFAULT(OS, ".amdhsa_user_sgpr_dispatch_id", KD, DefaultKD,
+ kernel_code_properties,
+ amdhsa::KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_ID);
+ PRINT_IF_NOT_DEFAULT(
+ OS, ".amdhsa_user_sgpr_flat_scratch_init", KD, DefaultKD,
+ kernel_code_properties,
+ amdhsa::KERNEL_CODE_PROPERTY_ENABLE_SGPR_FLAT_SCRATCH_INIT);
+ PRINT_IF_NOT_DEFAULT(
+ OS, ".amdhsa_user_sgpr_private_segment_size", KD, DefaultKD,
+ kernel_code_properties,
+ amdhsa::KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_SIZE);
+ PRINT_IF_NOT_DEFAULT(
+ OS, ".amdhsa_system_sgpr_private_segment_wavefront_offset", KD, DefaultKD,
+ compute_pgm_rsrc2,
+ amdhsa::COMPUTE_PGM_RSRC2_ENABLE_SGPR_PRIVATE_SEGMENT_WAVEFRONT_OFFSET);
+ PRINT_IF_NOT_DEFAULT(OS, ".amdhsa_system_sgpr_workgroup_id_x", KD, DefaultKD,
+ compute_pgm_rsrc2,
+ amdhsa::COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_X);
+ PRINT_IF_NOT_DEFAULT(OS, ".amdhsa_system_sgpr_workgroup_id_y", KD, DefaultKD,
+ compute_pgm_rsrc2,
+ amdhsa::COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Y);
+ PRINT_IF_NOT_DEFAULT(OS, ".amdhsa_system_sgpr_workgroup_id_z", KD, DefaultKD,
+ compute_pgm_rsrc2,
+ amdhsa::COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Z);
+ PRINT_IF_NOT_DEFAULT(OS, ".amdhsa_system_sgpr_workgroup_info", KD, DefaultKD,
+ compute_pgm_rsrc2,
+ amdhsa::COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_INFO);
+ PRINT_IF_NOT_DEFAULT(OS, ".amdhsa_system_vgpr_workitem_id", KD, DefaultKD,
+ compute_pgm_rsrc2,
+ amdhsa::COMPUTE_PGM_RSRC2_ENABLE_VGPR_WORKITEM_ID);
+
+ // These directives are required.
+ OS << "\t\t.amdhsa_next_free_vgpr " << NextVGPR << '\n';
+ OS << "\t\t.amdhsa_next_free_sgpr " << NextSGPR << '\n';
+
+ if (!ReserveVCC)
+ OS << "\t\t.amdhsa_reserve_vcc " << ReserveVCC << '\n';
+ if (IVersion.Major >= 7 && !ReserveFlatScr)
+ OS << "\t\t.amdhsa_reserve_flat_scratch " << ReserveFlatScr << '\n';
+ if (IVersion.Major >= 8 && ReserveXNACK != hasXNACK(STI))
+ OS << "\t\t.amdhsa_reserve_xnack_mask " << ReserveXNACK << '\n';
+
+ PRINT_IF_NOT_DEFAULT(OS, ".amdhsa_float_round_mode_32", KD, DefaultKD,
+ compute_pgm_rsrc1,
+ amdhsa::COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_32);
+ PRINT_IF_NOT_DEFAULT(OS, ".amdhsa_float_round_mode_16_64", KD, DefaultKD,
+ compute_pgm_rsrc1,
+ amdhsa::COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_16_64);
+ PRINT_IF_NOT_DEFAULT(OS, ".amdhsa_float_denorm_mode_32", KD, DefaultKD,
+ compute_pgm_rsrc1,
+ amdhsa::COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_32);
+ PRINT_IF_NOT_DEFAULT(OS, ".amdhsa_float_denorm_mode_16_64", KD, DefaultKD,
+ compute_pgm_rsrc1,
+ amdhsa::COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_16_64);
+ PRINT_IF_NOT_DEFAULT(OS, ".amdhsa_dx10_clamp", KD, DefaultKD,
+ compute_pgm_rsrc1,
+ amdhsa::COMPUTE_PGM_RSRC1_ENABLE_DX10_CLAMP);
+ PRINT_IF_NOT_DEFAULT(OS, ".amdhsa_ieee_mode", KD, DefaultKD,
+ compute_pgm_rsrc1,
+ amdhsa::COMPUTE_PGM_RSRC1_ENABLE_IEEE_MODE);
+ if (IVersion.Major >= 9)
+ PRINT_IF_NOT_DEFAULT(OS, ".amdhsa_fp16_overflow", KD, DefaultKD,
+ compute_pgm_rsrc1,
+ amdhsa::COMPUTE_PGM_RSRC1_FP16_OVFL);
+ PRINT_IF_NOT_DEFAULT(
+ OS, ".amdhsa_exception_fp_ieee_invalid_op", KD, DefaultKD,
+ compute_pgm_rsrc2,
+ amdhsa::COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INVALID_OPERATION);
+ PRINT_IF_NOT_DEFAULT(
+ OS, ".amdhsa_exception_fp_denorm_src", KD, DefaultKD, compute_pgm_rsrc2,
+ amdhsa::COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_FP_DENORMAL_SOURCE);
+ PRINT_IF_NOT_DEFAULT(
+ OS, ".amdhsa_exception_fp_ieee_div_zero", KD, DefaultKD,
+ compute_pgm_rsrc2,
+ amdhsa::COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_DIVISION_BY_ZERO);
+ PRINT_IF_NOT_DEFAULT(
+ OS, ".amdhsa_exception_fp_ieee_overflow", KD, DefaultKD,
+ compute_pgm_rsrc2,
+ amdhsa::COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_OVERFLOW);
+ PRINT_IF_NOT_DEFAULT(
+ OS, ".amdhsa_exception_fp_ieee_underflow", KD, DefaultKD,
+ compute_pgm_rsrc2,
+ amdhsa::COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_UNDERFLOW);
+ PRINT_IF_NOT_DEFAULT(
+ OS, ".amdhsa_exception_fp_ieee_inexact", KD, DefaultKD, compute_pgm_rsrc2,
+ amdhsa::COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INEXACT);
+ PRINT_IF_NOT_DEFAULT(
+ OS, ".amdhsa_exception_int_div_zero", KD, DefaultKD, compute_pgm_rsrc2,
+ amdhsa::COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_INT_DIVIDE_BY_ZERO);
+#undef PRINT_IF_NOT_DEFAULT
+
+ OS << "\t.end_amdhsa_kernel\n";
+}
+
//===----------------------------------------------------------------------===//
// AMDGPUTargetELFStreamer
//===----------------------------------------------------------------------===//
-AMDGPUTargetELFStreamer::AMDGPUTargetELFStreamer(MCStreamer &S)
- : AMDGPUTargetStreamer(S), Streamer(S) {}
+AMDGPUTargetELFStreamer::AMDGPUTargetELFStreamer(
+ MCStreamer &S, const MCSubtargetInfo &STI)
+ : AMDGPUTargetStreamer(S), Streamer(S) {
+ MCAssembler &MCA = getStreamer().getAssembler();
+ unsigned EFlags = MCA.getELFHeaderEFlags();
+
+ EFlags &= ~ELF::EF_AMDGPU_MACH;
+ EFlags |= getMACH(STI.getCPU());
+
+ EFlags &= ~ELF::EF_AMDGPU_XNACK;
+ if (AMDGPU::hasXNACK(STI))
+ EFlags |= ELF::EF_AMDGPU_XNACK;
+
+ MCA.setELFHeaderEFlags(EFlags);
+}
MCELFStreamer &AMDGPUTargetELFStreamer::getStreamer() {
return static_cast<MCELFStreamer &>(Streamer);
@@ -150,9 +376,10 @@ void AMDGPUTargetELFStreamer::EmitAMDGPUNote(
S.PopSection();
}
-void
-AMDGPUTargetELFStreamer::EmitDirectiveHSACodeObjectVersion(uint32_t Major,
- uint32_t Minor) {
+void AMDGPUTargetELFStreamer::EmitDirectiveAMDGCNTarget(StringRef Target) {}
+
+void AMDGPUTargetELFStreamer::EmitDirectiveHSACodeObjectVersion(
+ uint32_t Major, uint32_t Minor) {
EmitAMDGPUNote(
MCConstantExpr::create(8, getContext()),
@@ -207,7 +434,7 @@ void AMDGPUTargetELFStreamer::EmitAMDGPUSymbolType(StringRef SymbolName,
unsigned Type) {
MCSymbolELF *Symbol = cast<MCSymbolELF>(
getStreamer().getContext().getOrCreateSymbol(SymbolName));
- Symbol->setType(ELF::STT_AMDGPU_HSA_KERNEL);
+ Symbol->setType(Type);
}
bool AMDGPUTargetELFStreamer::EmitISAVersion(StringRef IsaVersionString) {
@@ -271,3 +498,46 @@ bool AMDGPUTargetELFStreamer::EmitPALMetadata(
);
return true;
}
+
+void AMDGPUTargetELFStreamer::EmitAmdhsaKernelDescriptor(
+ const MCSubtargetInfo &STI, StringRef KernelName,
+ const amdhsa::kernel_descriptor_t &KernelDescriptor, uint64_t NextVGPR,
+ uint64_t NextSGPR, bool ReserveVCC, bool ReserveFlatScr,
+ bool ReserveXNACK) {
+ auto &Streamer = getStreamer();
+ auto &Context = Streamer.getContext();
+
+ MCSymbolELF *KernelDescriptorSymbol = cast<MCSymbolELF>(
+ Context.getOrCreateSymbol(Twine(KernelName) + Twine(".kd")));
+ KernelDescriptorSymbol->setBinding(ELF::STB_GLOBAL);
+ KernelDescriptorSymbol->setType(ELF::STT_OBJECT);
+ KernelDescriptorSymbol->setSize(
+ MCConstantExpr::create(sizeof(KernelDescriptor), Context));
+
+ MCSymbolELF *KernelCodeSymbol = cast<MCSymbolELF>(
+ Context.getOrCreateSymbol(Twine(KernelName)));
+ KernelCodeSymbol->setBinding(ELF::STB_LOCAL);
+
+ Streamer.EmitLabel(KernelDescriptorSymbol);
+ Streamer.EmitBytes(StringRef(
+ (const char*)&(KernelDescriptor),
+ offsetof(amdhsa::kernel_descriptor_t, kernel_code_entry_byte_offset)));
+ // FIXME: Remove the use of VK_AMDGPU_REL64 in the expression below. The
+ // expression being created is:
+ // (start of kernel code) - (start of kernel descriptor)
+ // It implies R_AMDGPU_REL64, but ends up being R_AMDGPU_ABS64.
+ Streamer.EmitValue(MCBinaryExpr::createSub(
+ MCSymbolRefExpr::create(
+ KernelCodeSymbol, MCSymbolRefExpr::VK_AMDGPU_REL64, Context),
+ MCSymbolRefExpr::create(
+ KernelDescriptorSymbol, MCSymbolRefExpr::VK_None, Context),
+ Context),
+ sizeof(KernelDescriptor.kernel_code_entry_byte_offset));
+ Streamer.EmitBytes(StringRef(
+ (const char*)&(KernelDescriptor) +
+ offsetof(amdhsa::kernel_descriptor_t, kernel_code_entry_byte_offset) +
+ sizeof(KernelDescriptor.kernel_code_entry_byte_offset),
+ sizeof(KernelDescriptor) -
+ offsetof(amdhsa::kernel_descriptor_t, kernel_code_entry_byte_offset) -
+ sizeof(KernelDescriptor.kernel_code_entry_byte_offset)));
+}
diff --git a/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.h b/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.h
index 0919b754480d..472da1b73593 100644
--- a/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.h
+++ b/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.h
@@ -14,6 +14,7 @@
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/AMDGPUMetadata.h"
+#include "llvm/Support/AMDHSAKernelDescriptor.h"
namespace llvm {
#include "AMDGPUPTNote.h"
@@ -30,9 +31,17 @@ class AMDGPUTargetStreamer : public MCTargetStreamer {
protected:
MCContext &getContext() const { return Streamer.getContext(); }
+ /// \returns Equivalent EF_AMDGPU_MACH_* value for given \p GPU name.
+ unsigned getMACH(StringRef GPU) const;
+
public:
+ /// \returns Equivalent GPU name for an EF_AMDGPU_MACH_* value.
+ static const char *getMachName(unsigned Mach);
+
AMDGPUTargetStreamer(MCStreamer &S) : MCTargetStreamer(S) {}
+ virtual void EmitDirectiveAMDGCNTarget(StringRef Target) = 0;
+
virtual void EmitDirectiveHSACodeObjectVersion(uint32_t Major,
uint32_t Minor) = 0;
@@ -56,12 +65,21 @@ public:
/// \returns True on success, false on failure.
virtual bool EmitPALMetadata(const AMDGPU::PALMD::Metadata &PALMetadata) = 0;
+
+ virtual void EmitAmdhsaKernelDescriptor(
+ const MCSubtargetInfo &STI, StringRef KernelName,
+ const amdhsa::kernel_descriptor_t &KernelDescriptor, uint64_t NextVGPR,
+ uint64_t NextSGPR, bool ReserveVCC, bool ReserveFlatScr,
+ bool ReserveXNACK) = 0;
};
class AMDGPUTargetAsmStreamer final : public AMDGPUTargetStreamer {
formatted_raw_ostream &OS;
public:
AMDGPUTargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS);
+
+ void EmitDirectiveAMDGCNTarget(StringRef Target) override;
+
void EmitDirectiveHSACodeObjectVersion(uint32_t Major,
uint32_t Minor) override;
@@ -81,6 +99,12 @@ public:
/// \returns True on success, false on failure.
bool EmitPALMetadata(const AMDGPU::PALMD::Metadata &PALMetadata) override;
+
+ void EmitAmdhsaKernelDescriptor(
+ const MCSubtargetInfo &STI, StringRef KernelName,
+ const amdhsa::kernel_descriptor_t &KernelDescriptor, uint64_t NextVGPR,
+ uint64_t NextSGPR, bool ReserveVCC, bool ReserveFlatScr,
+ bool ReserveXNACK) override;
};
class AMDGPUTargetELFStreamer final : public AMDGPUTargetStreamer {
@@ -90,10 +114,12 @@ class AMDGPUTargetELFStreamer final : public AMDGPUTargetStreamer {
function_ref<void(MCELFStreamer &)> EmitDesc);
public:
- AMDGPUTargetELFStreamer(MCStreamer &S);
+ AMDGPUTargetELFStreamer(MCStreamer &S, const MCSubtargetInfo &STI);
MCELFStreamer &getStreamer();
+ void EmitDirectiveAMDGCNTarget(StringRef Target) override;
+
void EmitDirectiveHSACodeObjectVersion(uint32_t Major,
uint32_t Minor) override;
@@ -113,6 +139,12 @@ public:
/// \returns True on success, false on failure.
bool EmitPALMetadata(const AMDGPU::PALMD::Metadata &PALMetadata) override;
+
+ void EmitAmdhsaKernelDescriptor(
+ const MCSubtargetInfo &STI, StringRef KernelName,
+ const amdhsa::kernel_descriptor_t &KernelDescriptor, uint64_t NextVGPR,
+ uint64_t NextSGPR, bool ReserveVCC, bool ReserveFlatScr,
+ bool ReserveXNACK) override;
};
}
diff --git a/lib/Target/AMDGPU/MCTargetDesc/CMakeLists.txt b/lib/Target/AMDGPU/MCTargetDesc/CMakeLists.txt
index f9cb4678dc51..2d201bbbd7b8 100644
--- a/lib/Target/AMDGPU/MCTargetDesc/CMakeLists.txt
+++ b/lib/Target/AMDGPU/MCTargetDesc/CMakeLists.txt
@@ -2,11 +2,11 @@ add_llvm_library(LLVMAMDGPUDesc
AMDGPUAsmBackend.cpp
AMDGPUELFObjectWriter.cpp
AMDGPUELFStreamer.cpp
- AMDGPUHSAMetadataStreamer.cpp
AMDGPUMCAsmInfo.cpp
AMDGPUMCCodeEmitter.cpp
AMDGPUMCTargetDesc.cpp
AMDGPUTargetStreamer.cpp
R600MCCodeEmitter.cpp
+ R600MCTargetDesc.cpp
SIMCCodeEmitter.cpp
)
diff --git a/lib/Target/AMDGPU/MCTargetDesc/R600MCCodeEmitter.cpp b/lib/Target/AMDGPU/MCTargetDesc/R600MCCodeEmitter.cpp
index eab90e1d344c..28d4bc1829e2 100644
--- a/lib/Target/AMDGPU/MCTargetDesc/R600MCCodeEmitter.cpp
+++ b/lib/Target/AMDGPU/MCTargetDesc/R600MCCodeEmitter.cpp
@@ -9,13 +9,12 @@
//
/// \file
///
-/// \brief The R600 code emitter produces machine code that can be executed
+/// The R600 code emitter produces machine code that can be executed
/// directly on the GPU device.
//
//===----------------------------------------------------------------------===//
#include "MCTargetDesc/AMDGPUFixupKinds.h"
-#include "MCTargetDesc/AMDGPUMCCodeEmitter.h"
#include "MCTargetDesc/AMDGPUMCTargetDesc.h"
#include "R600Defines.h"
#include "llvm/MC/MCCodeEmitter.h"
@@ -36,30 +35,40 @@ using namespace llvm;
namespace {
-class R600MCCodeEmitter : public AMDGPUMCCodeEmitter {
+class R600MCCodeEmitter : public MCCodeEmitter {
const MCRegisterInfo &MRI;
+ const MCInstrInfo &MCII;
public:
R600MCCodeEmitter(const MCInstrInfo &mcii, const MCRegisterInfo &mri)
- : AMDGPUMCCodeEmitter(mcii), MRI(mri) {}
+ : MRI(mri), MCII(mcii) {}
R600MCCodeEmitter(const R600MCCodeEmitter &) = delete;
R600MCCodeEmitter &operator=(const R600MCCodeEmitter &) = delete;
- /// \brief Encode the instruction and write it to the OS.
+ /// Encode the instruction and write it to the OS.
void encodeInstruction(const MCInst &MI, raw_ostream &OS,
SmallVectorImpl<MCFixup> &Fixups,
- const MCSubtargetInfo &STI) const override;
+ const MCSubtargetInfo &STI) const;
/// \returns the encoding for an MCOperand.
uint64_t getMachineOpValue(const MCInst &MI, const MCOperand &MO,
SmallVectorImpl<MCFixup> &Fixups,
- const MCSubtargetInfo &STI) const override;
+ const MCSubtargetInfo &STI) const;
private:
+
void Emit(uint32_t value, raw_ostream &OS) const;
void Emit(uint64_t value, raw_ostream &OS) const;
unsigned getHWReg(unsigned regNo) const;
+
+ uint64_t getBinaryCodeForInstr(const MCInst &MI,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const;
+ uint64_t computeAvailableFeatures(const FeatureBitset &FB) const;
+ void verifyInstructionPredicates(const MCInst &MI,
+ uint64_t AvailableFeatures) const;
+
};
} // end anonymous namespace
@@ -94,16 +103,16 @@ void R600MCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
computeAvailableFeatures(STI.getFeatureBits()));
const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
- if (MI.getOpcode() == AMDGPU::RETURN ||
- MI.getOpcode() == AMDGPU::FETCH_CLAUSE ||
- MI.getOpcode() == AMDGPU::ALU_CLAUSE ||
- MI.getOpcode() == AMDGPU::BUNDLE ||
- MI.getOpcode() == AMDGPU::KILL) {
+ if (MI.getOpcode() == R600::RETURN ||
+ MI.getOpcode() == R600::FETCH_CLAUSE ||
+ MI.getOpcode() == R600::ALU_CLAUSE ||
+ MI.getOpcode() == R600::BUNDLE ||
+ MI.getOpcode() == R600::KILL) {
return;
} else if (IS_VTX(Desc)) {
uint64_t InstWord01 = getBinaryCodeForInstr(MI, Fixups, STI);
uint32_t InstWord2 = MI.getOperand(2).getImm(); // Offset
- if (!(STI.getFeatureBits()[AMDGPU::FeatureCaymanISA])) {
+ if (!(STI.getFeatureBits()[R600::FeatureCaymanISA])) {
InstWord2 |= 1 << 19; // Mega-Fetch bit
}
@@ -136,7 +145,7 @@ void R600MCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
Emit((uint32_t) 0, OS);
} else {
uint64_t Inst = getBinaryCodeForInstr(MI, Fixups, STI);
- if ((STI.getFeatureBits()[AMDGPU::FeatureR600ALUInst]) &&
+ if ((STI.getFeatureBits()[R600::FeatureR600ALUInst]) &&
((Desc.TSFlags & R600_InstFlag::OP1) ||
Desc.TSFlags & R600_InstFlag::OP2)) {
uint64_t ISAOpCode = Inst & (0x3FFULL << 39);
@@ -148,11 +157,11 @@ void R600MCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
}
void R600MCCodeEmitter::Emit(uint32_t Value, raw_ostream &OS) const {
- support::endian::Writer<support::little>(OS).write(Value);
+ support::endian::write(OS, Value, support::little);
}
void R600MCCodeEmitter::Emit(uint64_t Value, raw_ostream &OS) const {
- support::endian::Writer<support::little>(OS).write(Value);
+ support::endian::write(OS, Value, support::little);
}
unsigned R600MCCodeEmitter::getHWReg(unsigned RegNo) const {
@@ -186,4 +195,4 @@ uint64_t R600MCCodeEmitter::getMachineOpValue(const MCInst &MI,
}
#define ENABLE_INSTR_PREDICATE_VERIFIER
-#include "AMDGPUGenMCCodeEmitter.inc"
+#include "R600GenMCCodeEmitter.inc"
diff --git a/lib/Target/AMDGPU/MCTargetDesc/R600MCTargetDesc.cpp b/lib/Target/AMDGPU/MCTargetDesc/R600MCTargetDesc.cpp
new file mode 100644
index 000000000000..1c99a708e5ac
--- /dev/null
+++ b/lib/Target/AMDGPU/MCTargetDesc/R600MCTargetDesc.cpp
@@ -0,0 +1,27 @@
+//===-- R600MCTargetDesc.cpp - R600 Target Descriptions -------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+/// \file
+/// \brief This file provides R600 specific target descriptions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "AMDGPUMCTargetDesc.h"
+#include "llvm/MC/MCInstrInfo.h"
+
+using namespace llvm;
+
+#define GET_INSTRINFO_MC_DESC
+#include "R600GenInstrInfo.inc"
+
+MCInstrInfo *llvm::createR600MCInstrInfo() {
+ MCInstrInfo *X = new MCInstrInfo();
+ InitR600MCInstrInfo(X);
+ return X;
+}
diff --git a/lib/Target/AMDGPU/MCTargetDesc/SIMCCodeEmitter.cpp b/lib/Target/AMDGPU/MCTargetDesc/SIMCCodeEmitter.cpp
index 94c0157edeb5..36913bd04274 100644
--- a/lib/Target/AMDGPU/MCTargetDesc/SIMCCodeEmitter.cpp
+++ b/lib/Target/AMDGPU/MCTargetDesc/SIMCCodeEmitter.cpp
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
//
/// \file
-/// \brief The SI code emitter produces machine code that can be executed
+/// The SI code emitter produces machine code that can be executed
/// directly on the GPU device.
//
//===----------------------------------------------------------------------===//
@@ -43,7 +43,7 @@ namespace {
class SIMCCodeEmitter : public AMDGPUMCCodeEmitter {
const MCRegisterInfo &MRI;
- /// \brief Encode an fp or int literal
+ /// Encode an fp or int literal
uint32_t getLitEncoding(const MCOperand &MO, const MCOperandInfo &OpInfo,
const MCSubtargetInfo &STI) const;
@@ -54,7 +54,7 @@ public:
SIMCCodeEmitter(const SIMCCodeEmitter &) = delete;
SIMCCodeEmitter &operator=(const SIMCCodeEmitter &) = delete;
- /// \brief Encode the instruction and write it to the OS.
+ /// Encode the instruction and write it to the OS.
void encodeInstruction(const MCInst &MI, raw_ostream &OS,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const override;
@@ -64,7 +64,7 @@ public:
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const override;
- /// \brief Use a fixup to encode the simm16 field for SOPP branch
+ /// Use a fixup to encode the simm16 field for SOPP branch
/// instructions.
unsigned getSOPPBrEncoding(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
@@ -335,13 +335,24 @@ SIMCCodeEmitter::getSDWASrcEncoding(const MCInst &MI, unsigned OpNo,
const MCOperand &MO = MI.getOperand(OpNo);
- unsigned Reg = MO.getReg();
- RegEnc |= MRI.getEncodingValue(Reg);
- RegEnc &= SDWA9EncValues::SRC_VGPR_MASK;
- if (AMDGPU::isSGPR(AMDGPU::mc2PseudoReg(Reg), &MRI)) {
- RegEnc |= SDWA9EncValues::SRC_SGPR_MASK;
+ if (MO.isReg()) {
+ unsigned Reg = MO.getReg();
+ RegEnc |= MRI.getEncodingValue(Reg);
+ RegEnc &= SDWA9EncValues::SRC_VGPR_MASK;
+ if (AMDGPU::isSGPR(AMDGPU::mc2PseudoReg(Reg), &MRI)) {
+ RegEnc |= SDWA9EncValues::SRC_SGPR_MASK;
+ }
+ return RegEnc;
+ } else {
+ const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
+ uint32_t Enc = getLitEncoding(MO, Desc.OpInfo[OpNo], STI);
+ if (Enc != ~0U && Enc != 255) {
+ return Enc | SDWA9EncValues::SRC_SGPR_MASK;
+ }
}
- return RegEnc;
+
+ llvm_unreachable("Unsupported operand kind");
+ return 0;
}
unsigned
@@ -427,3 +438,6 @@ uint64_t SIMCCodeEmitter::getMachineOpValue(const MCInst &MI,
llvm_unreachable("Encoding of this operand type is not supported yet.");
return 0;
}
+
+#define ENABLE_INSTR_PREDICATE_VERIFIER
+#include "AMDGPUGenMCCodeEmitter.inc"