diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-08-21 18:13:02 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-08-21 18:13:02 +0000 |
commit | 54db30ce18663e6c2991958f3b5d18362e8e93c4 (patch) | |
tree | 4aa6442802570767398cc83ba484e97b1309bdc2 /contrib/llvm/lib/Target/AMDGPU/MCTargetDesc/SIMCCodeEmitter.cpp | |
parent | 35284c22e9c8348159b7ce032ea45f2cdeb65298 (diff) | |
parent | e6d1592492a3a379186bfb02bd0f4eda0669c0d5 (diff) |
Merge llvm trunk r366426, resolve conflicts, and update FREEBSD-Xlist.
Notes
Notes:
svn path=/projects/clang900-import/; revision=351344
Diffstat (limited to 'contrib/llvm/lib/Target/AMDGPU/MCTargetDesc/SIMCCodeEmitter.cpp')
-rw-r--r-- | contrib/llvm/lib/Target/AMDGPU/MCTargetDesc/SIMCCodeEmitter.cpp | 84 |
1 files changed, 73 insertions, 11 deletions
diff --git a/contrib/llvm/lib/Target/AMDGPU/MCTargetDesc/SIMCCodeEmitter.cpp b/contrib/llvm/lib/Target/AMDGPU/MCTargetDesc/SIMCCodeEmitter.cpp index 36913bd04274..f8ec3c36f019 100644 --- a/contrib/llvm/lib/Target/AMDGPU/MCTargetDesc/SIMCCodeEmitter.cpp +++ b/contrib/llvm/lib/Target/AMDGPU/MCTargetDesc/SIMCCodeEmitter.cpp @@ -1,9 +1,8 @@ //===-- SIMCCodeEmitter.cpp - SI Code Emitter -----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -14,9 +13,11 @@ //===----------------------------------------------------------------------===// #include "AMDGPU.h" +#include "AMDGPURegisterInfo.h" #include "MCTargetDesc/AMDGPUFixupKinds.h" #include "MCTargetDesc/AMDGPUMCCodeEmitter.h" #include "MCTargetDesc/AMDGPUMCTargetDesc.h" +#include "SIDefines.h" #include "Utils/AMDGPUBaseInfo.h" #include "llvm/MC/MCCodeEmitter.h" #include "llvm/MC/MCContext.h" @@ -77,6 +78,10 @@ public: unsigned getSDWAVopcDstEncoding(const MCInst &MI, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const override; + + unsigned getAVOperandEncoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const override; }; } // end anonymous namespace @@ -233,6 +238,8 @@ uint32_t SIMCCodeEmitter::getLitEncoding(const MCOperand &MO, case AMDGPU::OPERAND_REG_IMM_FP32: case AMDGPU::OPERAND_REG_INLINE_C_INT32: case AMDGPU::OPERAND_REG_INLINE_C_FP32: + case AMDGPU::OPERAND_REG_INLINE_AC_INT32: + case AMDGPU::OPERAND_REG_INLINE_AC_FP32: return getLit32Encoding(static_cast<uint32_t>(Imm), STI); case AMDGPU::OPERAND_REG_IMM_INT64: @@ -245,12 +252,21 @@ uint32_t SIMCCodeEmitter::getLitEncoding(const MCOperand &MO, case AMDGPU::OPERAND_REG_IMM_FP16: case AMDGPU::OPERAND_REG_INLINE_C_INT16: case AMDGPU::OPERAND_REG_INLINE_C_FP16: + case AMDGPU::OPERAND_REG_INLINE_AC_INT16: + case AMDGPU::OPERAND_REG_INLINE_AC_FP16: // FIXME Is this correct? What do inline immediates do on SI for f16 src // which does not have f16 support? return getLit16Encoding(static_cast<uint16_t>(Imm), STI); + case AMDGPU::OPERAND_REG_IMM_V2INT16: + case AMDGPU::OPERAND_REG_IMM_V2FP16: + if (!isUInt<16>(Imm) && STI.getFeatureBits()[AMDGPU::FeatureVOP3Literal]) + return getLit32Encoding(static_cast<uint32_t>(Imm), STI); + LLVM_FALLTHROUGH; case AMDGPU::OPERAND_REG_INLINE_C_V2INT16: - case AMDGPU::OPERAND_REG_INLINE_C_V2FP16: { + case AMDGPU::OPERAND_REG_INLINE_C_V2FP16: + case AMDGPU::OPERAND_REG_INLINE_AC_V2INT16: + case AMDGPU::OPERAND_REG_INLINE_AC_V2FP16: { uint16_t Lo16 = static_cast<uint16_t>(Imm); uint32_t Encoding = getLit16Encoding(Lo16, STI); return Encoding; @@ -274,7 +290,25 @@ void SIMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS, OS.write((uint8_t) ((Encoding >> (8 * i)) & 0xff)); } - if (bytes > 4) + // NSA encoding. + if (AMDGPU::isGFX10(STI) && Desc.TSFlags & SIInstrFlags::MIMG) { + int vaddr0 = AMDGPU::getNamedOperandIdx(MI.getOpcode(), + AMDGPU::OpName::vaddr0); + int srsrc = AMDGPU::getNamedOperandIdx(MI.getOpcode(), + AMDGPU::OpName::srsrc); + assert(vaddr0 >= 0 && srsrc > vaddr0); + unsigned NumExtraAddrs = srsrc - vaddr0 - 1; + unsigned NumPadding = (-NumExtraAddrs) & 3; + + for (unsigned i = 0; i < NumExtraAddrs; ++i) + OS.write((uint8_t)getMachineOpValue(MI, MI.getOperand(vaddr0 + 1 + i), + Fixups, STI)); + for (unsigned i = 0; i < NumPadding; ++i) + OS.write(0); + } + + if ((bytes > 8 && STI.getFeatureBits()[AMDGPU::FeatureVOP3Literal]) || + (bytes > 4 && !STI.getFeatureBits()[AMDGPU::FeatureVOP3Literal])) return; // Check for additional literals in SRC0/1/2 (Op 1/2/3) @@ -366,7 +400,7 @@ SIMCCodeEmitter::getSDWAVopcDstEncoding(const MCInst &MI, unsigned OpNo, const MCOperand &MO = MI.getOperand(OpNo); unsigned Reg = MO.getReg(); - if (Reg != AMDGPU::VCC) { + if (Reg != AMDGPU::VCC && Reg != AMDGPU::VCC_LO) { RegEnc |= MRI.getEncodingValue(Reg); RegEnc &= SDWA9EncValues::VOPC_DST_SGPR_MASK; RegEnc |= SDWA9EncValues::VOPC_DST_VCC_MASK; @@ -374,10 +408,31 @@ SIMCCodeEmitter::getSDWAVopcDstEncoding(const MCInst &MI, unsigned OpNo, return RegEnc; } +unsigned +SIMCCodeEmitter::getAVOperandEncoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const { + unsigned Reg = MI.getOperand(OpNo).getReg(); + uint64_t Enc = MRI.getEncodingValue(Reg); + + // VGPR and AGPR have the same encoding, but SrcA and SrcB operands of mfma + // instructions use acc[0:1] modifier bits to distinguish. These bits are + // encoded as a virtual 9th bit of the register for these operands. + if (MRI.getRegClass(AMDGPU::AGPR_32RegClassID).contains(Reg) || + MRI.getRegClass(AMDGPU::AReg_64RegClassID).contains(Reg)) + Enc |= 512; + + return Enc; +} + static bool needsPCRel(const MCExpr *Expr) { switch (Expr->getKind()) { - case MCExpr::SymbolRef: - return true; + case MCExpr::SymbolRef: { + auto *SE = cast<MCSymbolRefExpr>(Expr); + MCSymbolRefExpr::VariantKind Kind = SE->getKind(); + return Kind != MCSymbolRefExpr::VK_AMDGPU_ABS32_LO && + Kind != MCSymbolRefExpr::VK_AMDGPU_ABS32_HI; + } case MCExpr::Binary: { auto *BE = cast<MCBinaryExpr>(Expr); if (BE->getOpcode() == MCBinaryExpr::Sub) @@ -416,7 +471,13 @@ uint64_t SIMCCodeEmitter::getMachineOpValue(const MCInst &MI, Kind = FK_PCRel_4; else Kind = FK_Data_4; - Fixups.push_back(MCFixup::create(4, MO.getExpr(), Kind, MI.getLoc())); + + const MCInstrDesc &Desc = MCII.get(MI.getOpcode()); + uint32_t Offset = Desc.getSize(); + assert(Offset == 4 || Offset == 8); + + Fixups.push_back( + MCFixup::create(Offset, MO.getExpr(), Kind, MI.getLoc())); } // Figure out the operand number, needed for isSrcOperand check @@ -429,7 +490,8 @@ uint64_t SIMCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCInstrDesc &Desc = MCII.get(MI.getOpcode()); if (AMDGPU::isSISrcOperand(Desc, OpNo)) { uint32_t Enc = getLitEncoding(MO, Desc.OpInfo[OpNo], STI); - if (Enc != ~0U && (Enc != 255 || Desc.getSize() == 4)) + if (Enc != ~0U && + (Enc != 255 || Desc.getSize() == 4 || Desc.getSize() == 8)) return Enc; } else if (MO.isImm()) |