Index: llvm/trunk/lib/Target/AMDGPU/AMDGPUAsmPrinter.h =================================================================== --- llvm/trunk/lib/Target/AMDGPU/AMDGPUAsmPrinter.h +++ llvm/trunk/lib/Target/AMDGPU/AMDGPUAsmPrinter.h @@ -137,7 +137,6 @@ /// Emit register usage information so that the GPU driver /// can correctly setup the GPU state. - void EmitProgramInfoR600(const MachineFunction &MF); void EmitProgramInfoSI(const MachineFunction &MF, const SIProgramInfo &KernelInfo); void EmitPALMetadata(const MachineFunction &MF, Index: llvm/trunk/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp =================================================================== --- llvm/trunk/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp +++ llvm/trunk/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp @@ -23,6 +23,7 @@ #include "InstPrinter/AMDGPUInstPrinter.h" #include "MCTargetDesc/AMDGPUMCTargetDesc.h" #include "MCTargetDesc/AMDGPUTargetStreamer.h" +#include "R600AsmPrinter.h" #include "R600Defines.h" #include "R600MachineFunctionInfo.h" #include "R600RegisterInfo.h" @@ -89,7 +90,7 @@ extern "C" void LLVMInitializeAMDGPUAsmPrinter() { TargetRegistry::RegisterAsmPrinter(getTheAMDGPUTarget(), - createAMDGPUAsmPrinterPass); + llvm::createR600AsmPrinterPass); TargetRegistry::RegisterAsmPrinter(getTheGCNTarget(), createAMDGPUAsmPrinterPass); } @@ -115,9 +116,6 @@ } void AMDGPUAsmPrinter::EmitStartOfAsmFile(Module &M) { - if (TM.getTargetTriple().getArch() != Triple::amdgcn) - return; - if (TM.getTargetTriple().getOS() != Triple::AMDHSA && TM.getTargetTriple().getOS() != Triple::AMDPAL) return; @@ -143,8 +141,6 @@ } void AMDGPUAsmPrinter::EmitEndOfAsmFile(Module &M) { - if (TM.getTargetTriple().getArch() != Triple::amdgcn) - return; // Following code requires TargetStreamer to be present. if (!getTargetStreamer()) @@ -309,24 +305,20 @@ OutStreamer->SwitchSection(ConfigSection); } - if (STM.getGeneration() >= AMDGPUSubtarget::SOUTHERN_ISLANDS) { - if (MFI->isEntryFunction()) { - getSIProgramInfo(CurrentProgramInfo, MF); - } else { - auto I = CallGraphResourceInfo.insert( - std::make_pair(&MF.getFunction(), SIFunctionResourceInfo())); - SIFunctionResourceInfo &Info = I.first->second; - assert(I.second && "should only be called once per function"); - Info = analyzeResourceUsage(MF); - } - - if (STM.isAmdPalOS()) - EmitPALMetadata(MF, CurrentProgramInfo); - else if (!STM.isAmdHsaOS()) { - EmitProgramInfoSI(MF, CurrentProgramInfo); - } + if (MFI->isEntryFunction()) { + getSIProgramInfo(CurrentProgramInfo, MF); } else { - EmitProgramInfoR600(MF); + auto I = CallGraphResourceInfo.insert( + std::make_pair(&MF.getFunction(), SIFunctionResourceInfo())); + SIFunctionResourceInfo &Info = I.first->second; + assert(I.second && "should only be called once per function"); + Info = analyzeResourceUsage(MF); + } + + if (STM.isAmdPalOS()) + EmitPALMetadata(MF, CurrentProgramInfo); + else if (!STM.isAmdHsaOS()) { + EmitProgramInfoSI(MF, CurrentProgramInfo); } DisasmLines.clear(); @@ -340,84 +332,78 @@ Context.getELFSection(".AMDGPU.csdata", ELF::SHT_PROGBITS, 0); OutStreamer->SwitchSection(CommentSection); - if (STM.getGeneration() >= AMDGPUSubtarget::SOUTHERN_ISLANDS) { - if (!MFI->isEntryFunction()) { - OutStreamer->emitRawComment(" Function info:", false); - SIFunctionResourceInfo &Info = CallGraphResourceInfo[&MF.getFunction()]; - emitCommonFunctionComments( - Info.NumVGPR, - Info.getTotalNumSGPRs(MF.getSubtarget()), - Info.PrivateSegmentSize, - getFunctionCodeSize(MF)); - return false; - } - - OutStreamer->emitRawComment(" Kernel info:", false); - emitCommonFunctionComments(CurrentProgramInfo.NumVGPR, - CurrentProgramInfo.NumSGPR, - CurrentProgramInfo.ScratchSize, - getFunctionCodeSize(MF)); - - OutStreamer->emitRawComment( - " FloatMode: " + Twine(CurrentProgramInfo.FloatMode), false); - OutStreamer->emitRawComment( - " IeeeMode: " + Twine(CurrentProgramInfo.IEEEMode), false); - OutStreamer->emitRawComment( - " LDSByteSize: " + Twine(CurrentProgramInfo.LDSSize) + - " bytes/workgroup (compile time only)", false); - - OutStreamer->emitRawComment( - " SGPRBlocks: " + Twine(CurrentProgramInfo.SGPRBlocks), false); - OutStreamer->emitRawComment( - " VGPRBlocks: " + Twine(CurrentProgramInfo.VGPRBlocks), false); - - OutStreamer->emitRawComment( - " NumSGPRsForWavesPerEU: " + - Twine(CurrentProgramInfo.NumSGPRsForWavesPerEU), false); - OutStreamer->emitRawComment( - " NumVGPRsForWavesPerEU: " + - Twine(CurrentProgramInfo.NumVGPRsForWavesPerEU), false); - - OutStreamer->emitRawComment( - " ReservedVGPRFirst: " + Twine(CurrentProgramInfo.ReservedVGPRFirst), - false); - OutStreamer->emitRawComment( - " ReservedVGPRCount: " + Twine(CurrentProgramInfo.ReservedVGPRCount), - false); + if (!MFI->isEntryFunction()) { + OutStreamer->emitRawComment(" Function info:", false); + SIFunctionResourceInfo &Info = CallGraphResourceInfo[&MF.getFunction()]; + emitCommonFunctionComments( + Info.NumVGPR, + Info.getTotalNumSGPRs(MF.getSubtarget()), + Info.PrivateSegmentSize, + getFunctionCodeSize(MF)); + return false; + } - if (MF.getSubtarget().debuggerEmitPrologue()) { - OutStreamer->emitRawComment( - " DebuggerWavefrontPrivateSegmentOffsetSGPR: s" + - Twine(CurrentProgramInfo.DebuggerWavefrontPrivateSegmentOffsetSGPR), false); - OutStreamer->emitRawComment( - " DebuggerPrivateSegmentBufferSGPR: s" + - Twine(CurrentProgramInfo.DebuggerPrivateSegmentBufferSGPR), false); - } + OutStreamer->emitRawComment(" Kernel info:", false); + emitCommonFunctionComments(CurrentProgramInfo.NumVGPR, + CurrentProgramInfo.NumSGPR, + CurrentProgramInfo.ScratchSize, + getFunctionCodeSize(MF)); + + OutStreamer->emitRawComment( + " FloatMode: " + Twine(CurrentProgramInfo.FloatMode), false); + OutStreamer->emitRawComment( + " IeeeMode: " + Twine(CurrentProgramInfo.IEEEMode), false); + OutStreamer->emitRawComment( + " LDSByteSize: " + Twine(CurrentProgramInfo.LDSSize) + + " bytes/workgroup (compile time only)", false); + + OutStreamer->emitRawComment( + " SGPRBlocks: " + Twine(CurrentProgramInfo.SGPRBlocks), false); + OutStreamer->emitRawComment( + " VGPRBlocks: " + Twine(CurrentProgramInfo.VGPRBlocks), false); + + OutStreamer->emitRawComment( + " NumSGPRsForWavesPerEU: " + + Twine(CurrentProgramInfo.NumSGPRsForWavesPerEU), false); + OutStreamer->emitRawComment( + " NumVGPRsForWavesPerEU: " + + Twine(CurrentProgramInfo.NumVGPRsForWavesPerEU), false); + + OutStreamer->emitRawComment( + " ReservedVGPRFirst: " + Twine(CurrentProgramInfo.ReservedVGPRFirst), + false); + OutStreamer->emitRawComment( + " ReservedVGPRCount: " + Twine(CurrentProgramInfo.ReservedVGPRCount), + false); + if (MF.getSubtarget().debuggerEmitPrologue()) { OutStreamer->emitRawComment( - " COMPUTE_PGM_RSRC2:USER_SGPR: " + - Twine(G_00B84C_USER_SGPR(CurrentProgramInfo.ComputePGMRSrc2)), false); - OutStreamer->emitRawComment( - " COMPUTE_PGM_RSRC2:TRAP_HANDLER: " + - Twine(G_00B84C_TRAP_HANDLER(CurrentProgramInfo.ComputePGMRSrc2)), false); + " DebuggerWavefrontPrivateSegmentOffsetSGPR: s" + + Twine(CurrentProgramInfo.DebuggerWavefrontPrivateSegmentOffsetSGPR), false); OutStreamer->emitRawComment( - " COMPUTE_PGM_RSRC2:TGID_X_EN: " + - Twine(G_00B84C_TGID_X_EN(CurrentProgramInfo.ComputePGMRSrc2)), false); - OutStreamer->emitRawComment( - " COMPUTE_PGM_RSRC2:TGID_Y_EN: " + - Twine(G_00B84C_TGID_Y_EN(CurrentProgramInfo.ComputePGMRSrc2)), false); - OutStreamer->emitRawComment( - " COMPUTE_PGM_RSRC2:TGID_Z_EN: " + - Twine(G_00B84C_TGID_Z_EN(CurrentProgramInfo.ComputePGMRSrc2)), false); - OutStreamer->emitRawComment( - " COMPUTE_PGM_RSRC2:TIDIG_COMP_CNT: " + - Twine(G_00B84C_TIDIG_COMP_CNT(CurrentProgramInfo.ComputePGMRSrc2)), - false); - } else { - R600MachineFunctionInfo *MFI = MF.getInfo(); - OutStreamer->emitRawComment( - Twine("SQ_PGM_RESOURCES:STACK_SIZE = " + Twine(MFI->CFStackSize))); + " DebuggerPrivateSegmentBufferSGPR: s" + + Twine(CurrentProgramInfo.DebuggerPrivateSegmentBufferSGPR), false); } + + OutStreamer->emitRawComment( + " COMPUTE_PGM_RSRC2:USER_SGPR: " + + Twine(G_00B84C_USER_SGPR(CurrentProgramInfo.ComputePGMRSrc2)), false); + OutStreamer->emitRawComment( + " COMPUTE_PGM_RSRC2:TRAP_HANDLER: " + + Twine(G_00B84C_TRAP_HANDLER(CurrentProgramInfo.ComputePGMRSrc2)), false); + OutStreamer->emitRawComment( + " COMPUTE_PGM_RSRC2:TGID_X_EN: " + + Twine(G_00B84C_TGID_X_EN(CurrentProgramInfo.ComputePGMRSrc2)), false); + OutStreamer->emitRawComment( + " COMPUTE_PGM_RSRC2:TGID_Y_EN: " + + Twine(G_00B84C_TGID_Y_EN(CurrentProgramInfo.ComputePGMRSrc2)), false); + OutStreamer->emitRawComment( + " COMPUTE_PGM_RSRC2:TGID_Z_EN: " + + Twine(G_00B84C_TGID_Z_EN(CurrentProgramInfo.ComputePGMRSrc2)), false); + OutStreamer->emitRawComment( + " COMPUTE_PGM_RSRC2:TIDIG_COMP_CNT: " + + Twine(G_00B84C_TIDIG_COMP_CNT(CurrentProgramInfo.ComputePGMRSrc2)), + false); } if (STM.dumpCode()) { @@ -440,65 +426,6 @@ return false; } -void AMDGPUAsmPrinter::EmitProgramInfoR600(const MachineFunction &MF) { - unsigned MaxGPR = 0; - bool killPixel = false; - const R600Subtarget &STM = MF.getSubtarget(); - const R600RegisterInfo *RI = STM.getRegisterInfo(); - const R600MachineFunctionInfo *MFI = MF.getInfo(); - - for (const MachineBasicBlock &MBB : MF) { - for (const MachineInstr &MI : MBB) { - if (MI.getOpcode() == AMDGPU::KILLGT) - killPixel = true; - unsigned numOperands = MI.getNumOperands(); - for (unsigned op_idx = 0; op_idx < numOperands; op_idx++) { - const MachineOperand &MO = MI.getOperand(op_idx); - if (!MO.isReg()) - continue; - unsigned HWReg = RI->getHWRegIndex(MO.getReg()); - - // Register with value > 127 aren't GPR - if (HWReg > 127) - continue; - MaxGPR = std::max(MaxGPR, HWReg); - } - } - } - - unsigned RsrcReg; - if (STM.getGeneration() >= R600Subtarget::EVERGREEN) { - // Evergreen / Northern Islands - switch (MF.getFunction().getCallingConv()) { - default: LLVM_FALLTHROUGH; - case CallingConv::AMDGPU_CS: RsrcReg = R_0288D4_SQ_PGM_RESOURCES_LS; break; - case CallingConv::AMDGPU_GS: RsrcReg = R_028878_SQ_PGM_RESOURCES_GS; break; - case CallingConv::AMDGPU_PS: RsrcReg = R_028844_SQ_PGM_RESOURCES_PS; break; - case CallingConv::AMDGPU_VS: RsrcReg = R_028860_SQ_PGM_RESOURCES_VS; break; - } - } else { - // R600 / R700 - switch (MF.getFunction().getCallingConv()) { - default: LLVM_FALLTHROUGH; - case CallingConv::AMDGPU_GS: LLVM_FALLTHROUGH; - case CallingConv::AMDGPU_CS: LLVM_FALLTHROUGH; - case CallingConv::AMDGPU_VS: RsrcReg = R_028868_SQ_PGM_RESOURCES_VS; break; - case CallingConv::AMDGPU_PS: RsrcReg = R_028850_SQ_PGM_RESOURCES_PS; break; - } - } - - OutStreamer->EmitIntValue(RsrcReg, 4); - OutStreamer->EmitIntValue(S_NUM_GPRS(MaxGPR + 1) | - S_STACK_SIZE(MFI->CFStackSize), 4); - OutStreamer->EmitIntValue(R_02880C_DB_SHADER_CONTROL, 4); - OutStreamer->EmitIntValue(S_02880C_KILL_ENABLE(killPixel), 4); - - if (AMDGPU::isCompute(MF.getFunction().getCallingConv())) { - OutStreamer->EmitIntValue(R_0288E8_SQ_LDS_ALLOC, 4); - OutStreamer->EmitIntValue(alignTo(MFI->getLDSSize(), 4) >> 2, 4); - } -} - uint64_t AMDGPUAsmPrinter::getFunctionCodeSize(const MachineFunction &MF) const { const SISubtarget &STM = MF.getSubtarget(); const SIInstrInfo *TII = STM.getInstrInfo(); Index: llvm/trunk/lib/Target/AMDGPU/AMDGPUMCInstLower.cpp =================================================================== --- llvm/trunk/lib/Target/AMDGPU/AMDGPUMCInstLower.cpp +++ llvm/trunk/lib/Target/AMDGPU/AMDGPUMCInstLower.cpp @@ -19,6 +19,7 @@ #include "AMDGPUTargetMachine.h" #include "InstPrinter/AMDGPUInstPrinter.h" #include "MCTargetDesc/AMDGPUMCTargetDesc.h" +#include "R600AsmPrinter.h" #include "SIInstrInfo.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineInstr.h" @@ -175,11 +176,13 @@ return MCInstLowering.lowerOperand(MO, MCOp); } -const MCExpr *AMDGPUAsmPrinter::lowerConstant(const Constant *CV) { +static const MCExpr *lowerAddrSpaceCast(const TargetMachine &TM, + const Constant *CV, + MCContext &OutContext) { // TargetMachine does not support llvm-style cast. Use C++-style cast. // This is safe since TM is always of type AMDGPUTargetMachine or its // derived class. - auto *AT = static_cast(&TM); + auto &AT = static_cast(TM); auto *CE = dyn_cast(CV); // Lower null pointers in private and local address space. @@ -188,12 +191,18 @@ if (CE && CE->getOpcode() == Instruction::AddrSpaceCast) { auto Op = CE->getOperand(0); auto SrcAddr = Op->getType()->getPointerAddressSpace(); - if (Op->isNullValue() && AT->getNullPointerValue(SrcAddr) == 0) { + if (Op->isNullValue() && AT.getNullPointerValue(SrcAddr) == 0) { auto DstAddr = CE->getType()->getPointerAddressSpace(); - return MCConstantExpr::create(AT->getNullPointerValue(DstAddr), + return MCConstantExpr::create(AT.getNullPointerValue(DstAddr), OutContext); } } + return nullptr; +} + +const MCExpr *AMDGPUAsmPrinter::lowerConstant(const Constant *CV) { + if (const MCExpr *E = lowerAddrSpaceCast(TM, CV, OutContext)) + return E; return AsmPrinter::lowerConstant(CV); } @@ -293,3 +302,34 @@ } } } + +void R600AsmPrinter::EmitInstruction(const MachineInstr *MI) { + const R600Subtarget &STI = MF->getSubtarget(); + AMDGPUMCInstLower MCInstLowering(OutContext, STI, *this); + + StringRef Err; + if (!STI.getInstrInfo()->verifyInstruction(*MI, Err)) { + LLVMContext &C = MI->getParent()->getParent()->getFunction().getContext(); + C.emitError("Illegal instruction detected: " + Err); + MI->print(errs()); + } + + if (MI->isBundle()) { + const MachineBasicBlock *MBB = MI->getParent(); + MachineBasicBlock::const_instr_iterator I = ++MI->getIterator(); + while (I != MBB->instr_end() && I->isInsideBundle()) { + EmitInstruction(&*I); + ++I; + } + } else { + MCInst TmpInst; + MCInstLowering.lower(MI, TmpInst); + EmitToStreamer(*OutStreamer, TmpInst); + } +} + +const MCExpr *R600AsmPrinter::lowerConstant(const Constant *CV) { + if (const MCExpr *E = lowerAddrSpaceCast(TM, CV, OutContext)) + return E; + return AsmPrinter::lowerConstant(CV); +} Index: llvm/trunk/lib/Target/AMDGPU/CMakeLists.txt =================================================================== --- llvm/trunk/lib/Target/AMDGPU/CMakeLists.txt +++ llvm/trunk/lib/Target/AMDGPU/CMakeLists.txt @@ -64,6 +64,7 @@ GCNMinRegStrategy.cpp GCNRegPressure.cpp GCNSchedStrategy.cpp + R600AsmPrinter.cpp R600ClauseMergePass.cpp R600ControlFlowFinalizer.cpp R600EmitClauseMarkers.cpp Index: llvm/trunk/lib/Target/AMDGPU/R600AsmPrinter.h =================================================================== --- llvm/trunk/lib/Target/AMDGPU/R600AsmPrinter.h +++ llvm/trunk/lib/Target/AMDGPU/R600AsmPrinter.h @@ -0,0 +1,46 @@ +//===-- R600AsmPrinter.h - Print R600 assembly code -------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +/// \file +/// R600 Assembly printer class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_AMDGPU_R600ASMPRINTER_H +#define LLVM_LIB_TARGET_AMDGPU_R600ASMPRINTER_H + +#include "llvm/CodeGen/AsmPrinter.h" + +namespace llvm { + +class R600AsmPrinter final : public AsmPrinter { + +public: + explicit R600AsmPrinter(TargetMachine &TM, + std::unique_ptr Streamer); + StringRef getPassName() const override; + bool runOnMachineFunction(MachineFunction &MF) override; + /// Implemented in AMDGPUMCInstLower.cpp + void EmitInstruction(const MachineInstr *MI) override; + /// Lower the specified LLVM Constant to an MCExpr. + /// The AsmPrinter::lowerConstantof does not know how to lower + /// addrspacecast, therefore they should be lowered by this function. + const MCExpr *lowerConstant(const Constant *CV) override; + +private: + void EmitProgramInfoR600(const MachineFunction &MF); +}; + +AsmPrinter * +createR600AsmPrinterPass(TargetMachine &TM, + std::unique_ptr &&Streamer); + +} // namespace llvm + +#endif // LLVM_LIB_TARGET_AMDGPU_R600ASMPRINTER_H Index: llvm/trunk/lib/Target/AMDGPU/R600AsmPrinter.cpp =================================================================== --- llvm/trunk/lib/Target/AMDGPU/R600AsmPrinter.cpp +++ llvm/trunk/lib/Target/AMDGPU/R600AsmPrinter.cpp @@ -0,0 +1,129 @@ +//===-- R600AsmPrinter.cpp - R600 Assebly printer ------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +/// \file +/// +/// The R600AsmPrinter is used to print both assembly string and also binary +/// code. When passed an MCAsmStreamer it prints assembly and when passed +/// an MCObjectStreamer it outputs binary code. +// +//===----------------------------------------------------------------------===// + +#include "R600AsmPrinter.h" +#include "AMDGPUSubtarget.h" +#include "R600Defines.h" +#include "R600MachineFunctionInfo.h" +#include "MCTargetDesc/AMDGPUMCTargetDesc.h" +#include "llvm/BinaryFormat/ELF.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCSectionELF.h" +#include "llvm/MC/MCStreamer.h" +#include "llvm/Target/TargetLoweringObjectFile.h" + +using namespace llvm; + +AsmPrinter * +llvm::createR600AsmPrinterPass(TargetMachine &TM, + std::unique_ptr &&Streamer) { + return new R600AsmPrinter(TM, std::move(Streamer)); +} + +R600AsmPrinter::R600AsmPrinter(TargetMachine &TM, + std::unique_ptr Streamer) + : AsmPrinter(TM, std::move(Streamer)) { } + +StringRef R600AsmPrinter::getPassName() const { + return "R600 Assembly Printer"; +} + +void R600AsmPrinter::EmitProgramInfoR600(const MachineFunction &MF) { + unsigned MaxGPR = 0; + bool killPixel = false; + const R600Subtarget &STM = MF.getSubtarget(); + const R600RegisterInfo *RI = STM.getRegisterInfo(); + const R600MachineFunctionInfo *MFI = MF.getInfo(); + + for (const MachineBasicBlock &MBB : MF) { + for (const MachineInstr &MI : MBB) { + if (MI.getOpcode() == AMDGPU::KILLGT) + killPixel = true; + unsigned numOperands = MI.getNumOperands(); + for (unsigned op_idx = 0; op_idx < numOperands; op_idx++) { + const MachineOperand &MO = MI.getOperand(op_idx); + if (!MO.isReg()) + continue; + unsigned HWReg = RI->getHWRegIndex(MO.getReg()); + + // Register with value > 127 aren't GPR + if (HWReg > 127) + continue; + MaxGPR = std::max(MaxGPR, HWReg); + } + } + } + + unsigned RsrcReg; + if (STM.getGeneration() >= R600Subtarget::EVERGREEN) { + // Evergreen / Northern Islands + switch (MF.getFunction().getCallingConv()) { + default: LLVM_FALLTHROUGH; + case CallingConv::AMDGPU_CS: RsrcReg = R_0288D4_SQ_PGM_RESOURCES_LS; break; + case CallingConv::AMDGPU_GS: RsrcReg = R_028878_SQ_PGM_RESOURCES_GS; break; + case CallingConv::AMDGPU_PS: RsrcReg = R_028844_SQ_PGM_RESOURCES_PS; break; + case CallingConv::AMDGPU_VS: RsrcReg = R_028860_SQ_PGM_RESOURCES_VS; break; + } + } else { + // R600 / R700 + switch (MF.getFunction().getCallingConv()) { + default: LLVM_FALLTHROUGH; + case CallingConv::AMDGPU_GS: LLVM_FALLTHROUGH; + case CallingConv::AMDGPU_CS: LLVM_FALLTHROUGH; + case CallingConv::AMDGPU_VS: RsrcReg = R_028868_SQ_PGM_RESOURCES_VS; break; + case CallingConv::AMDGPU_PS: RsrcReg = R_028850_SQ_PGM_RESOURCES_PS; break; + } + } + + OutStreamer->EmitIntValue(RsrcReg, 4); + OutStreamer->EmitIntValue(S_NUM_GPRS(MaxGPR + 1) | + S_STACK_SIZE(MFI->CFStackSize), 4); + OutStreamer->EmitIntValue(R_02880C_DB_SHADER_CONTROL, 4); + OutStreamer->EmitIntValue(S_02880C_KILL_ENABLE(killPixel), 4); + + if (AMDGPU::isCompute(MF.getFunction().getCallingConv())) { + OutStreamer->EmitIntValue(R_0288E8_SQ_LDS_ALLOC, 4); + OutStreamer->EmitIntValue(alignTo(MFI->getLDSSize(), 4) >> 2, 4); + } +} + +bool R600AsmPrinter::runOnMachineFunction(MachineFunction &MF) { + + SetupMachineFunction(MF); + + MCContext &Context = getObjFileLowering().getContext(); + MCSectionELF *ConfigSection = + Context.getELFSection(".AMDGPU.config", ELF::SHT_PROGBITS, 0); + OutStreamer->SwitchSection(ConfigSection); + + EmitProgramInfoR600(MF); + + EmitFunctionBody(); + + if (isVerbose()) { + MCSectionELF *CommentSection = + Context.getELFSection(".AMDGPU.csdata", ELF::SHT_PROGBITS, 0); + OutStreamer->SwitchSection(CommentSection); + + R600MachineFunctionInfo *MFI = MF.getInfo(); + OutStreamer->emitRawComment( + Twine("SQ_PGM_RESOURCES:STACK_SIZE = " + Twine(MFI->CFStackSize))); + } + + return false; +} +