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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions llvm/lib/Target/AMDGPU/AMDGPU.td
Original file line number Diff line number Diff line change
Expand Up @@ -2488,6 +2488,10 @@ def HasFmaakFmamkF32Insts :
Predicate<"Subtarget->hasFmaakFmamkF32Insts()">,
AssemblerPredicate<(any_of FeatureGFX10Insts, FeatureGFX940Insts)>;

def HasFmaakFmamkF64Insts :
Predicate<"Subtarget->hasFmaakFmamkF64Insts()">,
AssemblerPredicate<(any_of FeatureGFX1250Insts)>;

def HasImageInsts : Predicate<"Subtarget->hasImageInsts()">,
AssemblerPredicate<(all_of FeatureImageInsts)>;

Expand Down
28 changes: 24 additions & 4 deletions llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -951,6 +951,8 @@ class AMDGPUOperand : public MCParsedAsmOperand {
return isLiteralImm(MVT::f16);
}

bool isKImmFP64() const { return isLiteralImm(MVT::f64); }

bool isMem() const override {
return false;
}
Expand Down Expand Up @@ -2003,6 +2005,7 @@ static const fltSemantics *getOpFltSemantics(uint8_t OperandType) {
case AMDGPU::OPERAND_REG_INLINE_C_INT64:
case AMDGPU::OPERAND_REG_INLINE_C_FP64:
case AMDGPU::OPERAND_REG_INLINE_AC_FP64:
case AMDGPU::OPERAND_KIMM64:
return &APFloat::IEEEdouble();
case AMDGPU::OPERAND_REG_IMM_FP16:
case AMDGPU::OPERAND_REG_INLINE_C_FP16:
Expand Down Expand Up @@ -2343,6 +2346,11 @@ void AMDGPUOperand::addLiteralImmOperand(MCInst &Inst, int64_t Val, bool ApplyMo
// in predicate methods (isLiteralImm())
llvm_unreachable("fp literal in 64-bit integer instruction.");

case AMDGPU::OPERAND_KIMM64:
Inst.addOperand(MCOperand::createImm(Val));
setImmKindMandatoryLiteral();
return;

case AMDGPU::OPERAND_REG_IMM_BF16:
case AMDGPU::OPERAND_REG_INLINE_C_BF16:
case AMDGPU::OPERAND_REG_INLINE_C_V2BF16:
Expand Down Expand Up @@ -2548,6 +2556,13 @@ void AMDGPUOperand::addLiteralImmOperand(MCInst &Inst, int64_t Val, bool ApplyMo
Inst.addOperand(MCOperand::createImm(Literal.getLoBits(16).getZExtValue()));
setImmKindMandatoryLiteral();
return;
case AMDGPU::OPERAND_KIMM64:
if ((isInt<32>(Val) || isUInt<32>(Val)) && !getModifiers().Lit64)
Val <<= 32;

Inst.addOperand(MCOperand::createImm(Val));
setImmKindMandatoryLiteral();
return;
default:
llvm_unreachable("invalid operand size");
}
Expand Down Expand Up @@ -4992,7 +5007,7 @@ bool AMDGPUAsmParser::validateVOPLiteral(const MCInst &Inst,

unsigned NumExprs = 0;
unsigned NumLiterals = 0;
uint32_t LiteralValue;
uint64_t LiteralValue;

for (int OpIdx : OpIndices) {
if (OpIdx == -1)
Expand All @@ -5006,16 +5021,21 @@ bool AMDGPUAsmParser::validateVOPLiteral(const MCInst &Inst,

if (MO.isImm() && !isInlineConstant(Inst, OpIdx)) {
uint64_t Value = static_cast<uint64_t>(MO.getImm());
bool IsFP64 = AMDGPU::isSISrcFPOperand(Desc, OpIdx) &&
bool IsForcedFP64 =
Desc.operands()[OpIdx].OperandType == AMDGPU::OPERAND_KIMM64 ||
(Desc.operands()[OpIdx].OperandType == AMDGPU::OPERAND_REG_IMM_FP64 &&
HasMandatoryLiteral);
bool IsFP64 = (IsForcedFP64 || AMDGPU::isSISrcFPOperand(Desc, OpIdx)) &&
AMDGPU::getOperandSize(Desc.operands()[OpIdx]) == 8;
bool IsValid32Op = AMDGPU::isValid32BitLiteral(Value, IsFP64);

if (!IsValid32Op && !isInt<32>(Value) && !isUInt<32>(Value)) {
if (!IsValid32Op && !isInt<32>(Value) && !isUInt<32>(Value) &&
!IsForcedFP64 && (!has64BitLiterals() || Desc.getSize() != 4)) {
Error(getLitLoc(Operands), "invalid operand for instruction");
return false;
}

if (IsFP64 && IsValid32Op)
if (IsFP64 && IsValid32Op && !IsForcedFP64)
Value = Hi_32(Value);

if (NumLiterals == 0 || LiteralValue != Value) {
Expand Down
27 changes: 27 additions & 0 deletions llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,13 @@ static DecodeStatus decodeOperand_KImmFP(MCInst &Inst, unsigned Imm,
return addOperand(Inst, DAsm->decodeMandatoryLiteralConstant(Imm));
}

static DecodeStatus decodeOperand_KImmFP64(MCInst &Inst, uint64_t Imm,
uint64_t Addr,
const MCDisassembler *Decoder) {
const auto *DAsm = static_cast<const AMDGPUDisassembler *>(Decoder);
return addOperand(Inst, DAsm->decodeMandatoryLiteral64Constant(Imm));
}

static DecodeStatus decodeOperandVOPDDstY(MCInst &Inst, unsigned Val,
uint64_t Addr, const void *Decoder) {
const auto *DAsm = static_cast<const AMDGPUDisassembler *>(Decoder);
Expand Down Expand Up @@ -613,6 +620,15 @@ DecodeStatus AMDGPUDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
tryDecodeInst(DecoderTableGFX12W6496, MI, DecW, Address, CS))
break;

if (STI.hasFeature(AMDGPU::Feature64BitLiterals)) {
// Return 8 bytes for a potential literal.
Bytes = Bytes_.slice(4, MaxInstBytesNum - 4);

if (isGFX1250() &&
tryDecodeInst(DecoderTableGFX125096, MI, DecW, Address, CS))
break;
}

// Reinitialize Bytes
Bytes = Bytes_.slice(0, MaxInstBytesNum);

Expand Down Expand Up @@ -1467,6 +1483,17 @@ AMDGPUDisassembler::decodeMandatoryLiteralConstant(unsigned Val) const {
return MCOperand::createImm(Literal);
}

MCOperand
AMDGPUDisassembler::decodeMandatoryLiteral64Constant(uint64_t Val) const {
if (HasLiteral) {
if (Literal64 != Val)
return errOperand(Val, "More than one unique literal is illegal");
}
HasLiteral = true;
Literal = Literal64 = Val;
return MCOperand::createImm(Literal64);
}

MCOperand AMDGPUDisassembler::decodeLiteralConstant(bool ExtendFP64) const {
// For now all literal constants are supposed to be unsigned integer
// ToDo: deal with signed/unsigned 64-bit integer constants
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.h
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ class AMDGPUDisassembler : public MCDisassembler {
static MCOperand decodeIntImmed(unsigned Imm);

MCOperand decodeMandatoryLiteralConstant(unsigned Imm) const;
MCOperand decodeMandatoryLiteral64Constant(uint64_t Imm) const;
MCOperand decodeLiteralConstant(bool ExtendFP64) const;
MCOperand decodeLiteral64Constant() const;

Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/AMDGPU/GCNSubtarget.h
Original file line number Diff line number Diff line change
Expand Up @@ -1100,6 +1100,8 @@ class GCNSubtarget final : public AMDGPUGenSubtargetInfo,
return getGeneration() >= GFX10 || hasGFX940Insts();
}

bool hasFmaakFmamkF64Insts() const { return hasGFX1250Insts(); }

bool hasImageInsts() const {
return HasImageInsts;
}
Expand Down
12 changes: 12 additions & 0 deletions llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,18 @@ void AMDGPUInstPrinter::printU32ImmOperand(const MCInst *MI, unsigned OpNo,
O << formatHex(MI->getOperand(OpNo).getImm() & 0xffffffff);
}

void AMDGPUInstPrinter::printFP64ImmOperand(const MCInst *MI, unsigned OpNo,
const MCSubtargetInfo &STI,
raw_ostream &O) {
// KIMM64
// This part needs to align with AMDGPUInstPrinter::printImmediate64.
uint64_t Imm = MI->getOperand(OpNo).getImm();
if (STI.hasFeature(AMDGPU::Feature64BitLiterals) && Lo_32(Imm))
O << "lit64(" << formatHex(static_cast<uint64_t>(Imm)) << ')';
else
O << formatHex(static_cast<uint64_t>(Hi_32(Imm)));
}

void AMDGPUInstPrinter::printNamedBit(const MCInst *MI, unsigned OpNo,
raw_ostream &O, StringRef BitName) {
if (MI->getOperand(OpNo).getImm()) {
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ class AMDGPUInstPrinter : public MCInstPrinter {
void printU16ImmDecOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
void printU32ImmOperand(const MCInst *MI, unsigned OpNo,
const MCSubtargetInfo &STI, raw_ostream &O);
void printFP64ImmOperand(const MCInst *MI, unsigned OpNo,
const MCSubtargetInfo &STI, raw_ostream &O);
void printNamedBit(const MCInst *MI, unsigned OpNo, raw_ostream &O,
StringRef BitName);
void printOffset(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI,
Expand Down
26 changes: 17 additions & 9 deletions llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCCodeEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,10 @@ class AMDGPUMCCodeEmitter : public MCCodeEmitter {
const MCSubtargetInfo &STI) const;

/// Encode an fp or int literal.
std::optional<uint32_t> getLitEncoding(const MCOperand &MO,
const MCOperandInfo &OpInfo,
const MCSubtargetInfo &STI) const;
std::optional<uint64_t>
getLitEncoding(const MCOperand &MO, const MCOperandInfo &OpInfo,
const MCSubtargetInfo &STI,
bool HasMandatoryLiteral = false) const;

void getBinaryCodeForInstr(const MCInst &MI, SmallVectorImpl<MCFixup> &Fixups,
APInt &Inst, APInt &Scratch,
Expand Down Expand Up @@ -265,10 +266,9 @@ static uint32_t getLit64Encoding(uint64_t Val, const MCSubtargetInfo &STI,
: 255;
}

std::optional<uint32_t>
AMDGPUMCCodeEmitter::getLitEncoding(const MCOperand &MO,
const MCOperandInfo &OpInfo,
const MCSubtargetInfo &STI) const {
std::optional<uint64_t> AMDGPUMCCodeEmitter::getLitEncoding(
const MCOperand &MO, const MCOperandInfo &OpInfo,
const MCSubtargetInfo &STI, bool HasMandatoryLiteral) const {
int64_t Imm;
if (MO.isExpr()) {
if (!MO.getExpr()->evaluateAsAbsolute(Imm))
Expand Down Expand Up @@ -303,9 +303,13 @@ AMDGPUMCCodeEmitter::getLitEncoding(const MCOperand &MO,

case AMDGPU::OPERAND_REG_INLINE_C_FP64:
case AMDGPU::OPERAND_REG_INLINE_AC_FP64:
case AMDGPU::OPERAND_REG_IMM_FP64:
return getLit64Encoding(static_cast<uint64_t>(Imm), STI, true);

case AMDGPU::OPERAND_REG_IMM_FP64: {
auto Enc = getLit64Encoding(static_cast<uint64_t>(Imm), STI, true);
return (HasMandatoryLiteral && Enc == 255) ? 254 : Enc;
}

case AMDGPU::OPERAND_REG_IMM_INT16:
case AMDGPU::OPERAND_REG_INLINE_C_INT16:
return getLit16IntEncoding(static_cast<uint32_t>(Imm), STI);
Expand Down Expand Up @@ -339,6 +343,7 @@ AMDGPUMCCodeEmitter::getLitEncoding(const MCOperand &MO,

case AMDGPU::OPERAND_KIMM32:
case AMDGPU::OPERAND_KIMM16:
case AMDGPU::OPERAND_KIMM64:
return MO.getImm();
default:
llvm_unreachable("invalid operand size");
Expand Down Expand Up @@ -685,7 +690,10 @@ void AMDGPUMCCodeEmitter::getMachineOpValueCommon(

const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
if (AMDGPU::isSISrcOperand(Desc, OpNo)) {
if (auto Enc = getLitEncoding(MO, Desc.operands()[OpNo], STI)) {
bool HasMandatoryLiteral =
AMDGPU::hasNamedOperand(MI.getOpcode(), AMDGPU::OpName::imm);
if (auto Enc = getLitEncoding(MO, Desc.operands()[OpNo], STI,
HasMandatoryLiteral)) {
Op = *Enc;
return;
}
Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/Target/AMDGPU/SIDefines.h
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ enum OperandType : unsigned {
/// Operand with 32-bit immediate that uses the constant bus.
OPERAND_KIMM32,
OPERAND_KIMM16,
OPERAND_KIMM64,

/// Operands with an AccVGPR register or inline constant
OPERAND_REG_INLINE_AC_INT32,
Expand All @@ -254,7 +255,7 @@ enum OperandType : unsigned {
OPERAND_SRC_LAST = OPERAND_REG_INLINE_C_LAST,

OPERAND_KIMM_FIRST = OPERAND_KIMM32,
OPERAND_KIMM_LAST = OPERAND_KIMM16
OPERAND_KIMM_LAST = OPERAND_KIMM64

};
}
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4442,6 +4442,7 @@ bool SIInstrInfo::isInlineConstant(int64_t Imm, uint8_t OperandType) const {
}
case AMDGPU::OPERAND_KIMM32:
case AMDGPU::OPERAND_KIMM16:
case AMDGPU::OPERAND_KIMM64:
return false;
case AMDGPU::OPERAND_INPUT_MODS:
case MCOI::OPERAND_IMMEDIATE:
Expand Down Expand Up @@ -4867,6 +4868,7 @@ bool SIInstrInfo::verifyInstruction(const MachineInstr &MI,
break;
case MCOI::OPERAND_IMMEDIATE:
case AMDGPU::OPERAND_KIMM32:
case AMDGPU::OPERAND_KIMM64:
// Check if this operand is an immediate.
// FrameIndex operands will be replaced by immediates, so they are
// allowed.
Expand Down
6 changes: 6 additions & 0 deletions llvm/lib/Target/AMDGPU/SIInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -1316,6 +1316,12 @@ def KImmFP32 : KImmFPOperand<i32>;
// constant bus.
def KImmFP16 : KImmFPOperand<i16>;

// 64-bit VALU immediate operand that uses the constant bus.
def KImmFP64 : KImmFPOperand<i64> {
let DecoderMethod = "decodeOperand_KImmFP64";
let PrintMethod = "printFP64ImmOperand";
}

class FPInputModsMatchClass <int opSize> : AsmOperandClass {
let Name = "RegOrImmWithFP"#opSize#"InputMods";
let ParserMethod = "parseRegOrImmWithFPInputMods";
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -1603,6 +1603,7 @@ inline unsigned getOperandSize(const MCOperandInfo &OpInfo) {
case AMDGPU::OPERAND_REG_INLINE_C_INT64:
case AMDGPU::OPERAND_REG_INLINE_C_FP64:
case AMDGPU::OPERAND_REG_INLINE_AC_FP64:
case AMDGPU::OPERAND_KIMM64:
return 8;

case AMDGPU::OPERAND_REG_IMM_INT16:
Expand Down
Loading
Loading