diff options
Diffstat (limited to 'contrib/llvm/lib/Target/AMDGPU/MCTargetDesc')
15 files changed, 476 insertions, 603 deletions
diff --git a/contrib/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUAsmBackend.cpp b/contrib/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUAsmBackend.cpp index d700acc34bc9..abc88c02adca 100644 --- a/contrib/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUAsmBackend.cpp +++ b/contrib/llvm/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,9 +193,9 @@ 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); } }; diff --git a/contrib/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUELFObjectWriter.cpp b/contrib/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUELFObjectWriter.cpp index e443b0729606..07bef9103c0d 100644 --- a/contrib/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUELFObjectWriter.cpp +++ b/contrib/llvm/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/contrib/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUELFStreamer.cpp b/contrib/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUELFStreamer.cpp index 1497edc7a054..c627a08e7463 100644 --- a/contrib/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUELFStreamer.cpp +++ b/contrib/llvm/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/contrib/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUELFStreamer.h b/contrib/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUELFStreamer.h index 0cc0a4c5cd5d..41e9063a759e 100644 --- a/contrib/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUELFStreamer.h +++ b/contrib/llvm/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/contrib/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUHSAMetadataStreamer.cpp b/contrib/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUHSAMetadataStreamer.cpp deleted file mode 100644 index 463e700f13b7..000000000000 --- a/contrib/llvm/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/contrib/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUHSAMetadataStreamer.h b/contrib/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUHSAMetadataStreamer.h deleted file mode 100644 index bd6515521a74..000000000000 --- a/contrib/llvm/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/contrib/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCCodeEmitter.cpp b/contrib/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCCodeEmitter.cpp index 521b3b39bba2..cae7a7a6c7e7 100644 --- a/contrib/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCCodeEmitter.cpp +++ b/contrib/llvm/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/contrib/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCCodeEmitter.h b/contrib/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCCodeEmitter.h index 1b062064ace1..dcc10a032afe 100644 --- a/contrib/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCCodeEmitter.h +++ b/contrib/llvm/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/contrib/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCTargetDesc.cpp b/contrib/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCTargetDesc.cpp index 2b321c04fb30..c579c7d60e16 100644 --- a/contrib/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCTargetDesc.cpp +++ b/contrib/llvm/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/contrib/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCTargetDesc.h b/contrib/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCTargetDesc.h index 1173dfd437ca..f3628d96d6e9 100644 --- a/contrib/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCTargetDesc.h +++ b/contrib/llvm/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,6 +40,7 @@ Target &getTheGCNTarget(); MCCodeEmitter *createR600MCCodeEmitter(const MCInstrInfo &MCII, const MCRegisterInfo &MRI, MCContext &Ctx); +MCInstrInfo *createR600MCInstrInfo(); MCCodeEmitter *createSIMCCodeEmitter(const MCInstrInfo &MCII, const MCRegisterInfo &MRI, @@ -50,15 +51,19 @@ MCAsmBackend *createAMDGPUAsmBackend(const Target &T, 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 @@ -67,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/contrib/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.cpp b/contrib/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.cpp index d897956daccf..6a41e3f650bc 100644 --- a/contrib/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.cpp +++ b/contrib/llvm/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/contrib/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.h b/contrib/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.h index 0919b754480d..472da1b73593 100644 --- a/contrib/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.h +++ b/contrib/llvm/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/contrib/llvm/lib/Target/AMDGPU/MCTargetDesc/R600MCCodeEmitter.cpp b/contrib/llvm/lib/Target/AMDGPU/MCTargetDesc/R600MCCodeEmitter.cpp index eab90e1d344c..28d4bc1829e2 100644 --- a/contrib/llvm/lib/Target/AMDGPU/MCTargetDesc/R600MCCodeEmitter.cpp +++ b/contrib/llvm/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/contrib/llvm/lib/Target/AMDGPU/MCTargetDesc/R600MCTargetDesc.cpp b/contrib/llvm/lib/Target/AMDGPU/MCTargetDesc/R600MCTargetDesc.cpp new file mode 100644 index 000000000000..1c99a708e5ac --- /dev/null +++ b/contrib/llvm/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/contrib/llvm/lib/Target/AMDGPU/MCTargetDesc/SIMCCodeEmitter.cpp b/contrib/llvm/lib/Target/AMDGPU/MCTargetDesc/SIMCCodeEmitter.cpp index 94c0157edeb5..36913bd04274 100644 --- a/contrib/llvm/lib/Target/AMDGPU/MCTargetDesc/SIMCCodeEmitter.cpp +++ b/contrib/llvm/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" |