summaryrefslogtreecommitdiff
path: root/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp')
-rw-r--r--llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp126
1 files changed, 87 insertions, 39 deletions
diff --git a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp
index aafbdc2e86a9..f098e7a3c6c6 100644
--- a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp
+++ b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp
@@ -80,12 +80,9 @@ void AMDGPUInstPrinter::printFP64ImmOperand(const MCInst *MI, unsigned OpNo,
const MCSubtargetInfo &STI,
raw_ostream &O) {
// KIMM64
- // This part needs to align with AMDGPUInstPrinter::printImmediate64.
+ const MCInstrDesc &Desc = MII.get(MI->getOpcode());
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)));
+ printLiteral64(Desc, Imm, STI, O, /*IsFP=*/true);
}
void AMDGPUInstPrinter::printNamedBit(const MCInst *MI, unsigned OpNo,
@@ -327,6 +324,54 @@ void AMDGPUInstPrinter::printSymbolicFormat(const MCInst *MI,
}
}
+// \returns a low 256 vgpr representing a high vgpr \p Reg [v256..v1023] or
+// \p Reg itself otherwise.
+static MCPhysReg getRegForPrinting(MCPhysReg Reg, const MCRegisterInfo &MRI) {
+ unsigned Enc = MRI.getEncodingValue(Reg);
+ unsigned Idx = Enc & AMDGPU::HWEncoding::REG_IDX_MASK;
+ if (Idx < 0x100)
+ return Reg;
+
+ const MCRegisterClass *RC = getVGPRPhysRegClass(Reg, MRI);
+ return RC->getRegister(Idx % 0x100);
+}
+
+// Restore MSBs of a VGPR above 255 from the MCInstrAnalysis.
+static MCPhysReg getRegFromMIA(MCPhysReg Reg, unsigned OpNo,
+ const MCInstrDesc &Desc,
+ const MCRegisterInfo &MRI,
+ const AMDGPUMCInstrAnalysis &MIA) {
+ unsigned VgprMSBs = MIA.getVgprMSBs();
+ if (!VgprMSBs)
+ return Reg;
+
+ unsigned Enc = MRI.getEncodingValue(Reg);
+ if (!(Enc & AMDGPU::HWEncoding::IS_VGPR))
+ return Reg;
+
+ auto Ops = AMDGPU::getVGPRLoweringOperandTables(Desc);
+ if (!Ops.first)
+ return Reg;
+ unsigned Opc = Desc.getOpcode();
+ unsigned I;
+ for (I = 0; I < 4; ++I) {
+ if (Ops.first[I] != AMDGPU::OpName::NUM_OPERAND_NAMES &&
+ (unsigned)AMDGPU::getNamedOperandIdx(Opc, Ops.first[I]) == OpNo)
+ break;
+ if (Ops.second && Ops.second[I] != AMDGPU::OpName::NUM_OPERAND_NAMES &&
+ (unsigned)AMDGPU::getNamedOperandIdx(Opc, Ops.second[I]) == OpNo)
+ break;
+ }
+ if (I == 4)
+ return Reg;
+ unsigned OpMSBs = (VgprMSBs >> (I * 2)) & 3;
+ if (!OpMSBs)
+ return Reg;
+ if (MCRegister NewReg = AMDGPU::getVGPRWithMSBs(Reg, OpMSBs, MRI))
+ return NewReg;
+ return Reg;
+}
+
void AMDGPUInstPrinter::printRegOperand(MCRegister Reg, raw_ostream &O,
const MCRegisterInfo &MRI) {
#if !defined(NDEBUG)
@@ -340,7 +385,20 @@ void AMDGPUInstPrinter::printRegOperand(MCRegister Reg, raw_ostream &O,
}
#endif
- O << getRegisterName(Reg);
+ unsigned PrintReg = getRegForPrinting(Reg, MRI);
+ O << getRegisterName(PrintReg);
+
+ if (PrintReg != Reg.id())
+ O << " /*" << getRegisterName(Reg) << "*/";
+}
+
+void AMDGPUInstPrinter::printRegOperand(MCRegister Reg, unsigned Opc,
+ unsigned OpNo, raw_ostream &O,
+ const MCRegisterInfo &MRI) {
+ if (MIA)
+ Reg = getRegFromMIA(Reg, OpNo, MII.get(Opc), MRI,
+ *static_cast<const AMDGPUMCInstrAnalysis *>(MIA));
+ printRegOperand(Reg, O, MRI);
}
void AMDGPUInstPrinter::printVOPDst(const MCInst *MI, unsigned OpNo,
@@ -594,7 +652,7 @@ void AMDGPUInstPrinter::printImmediate32(uint32_t Imm,
O << formatHex(static_cast<uint64_t>(Imm));
}
-void AMDGPUInstPrinter::printImmediate64(uint64_t Imm,
+void AMDGPUInstPrinter::printImmediate64(const MCInstrDesc &Desc, uint64_t Imm,
const MCSubtargetInfo &STI,
raw_ostream &O, bool IsFP) {
int64_t SImm = static_cast<int64_t>(Imm);
@@ -624,18 +682,24 @@ void AMDGPUInstPrinter::printImmediate64(uint64_t Imm,
else if (Imm == 0x3fc45f306dc9c882 &&
STI.hasFeature(AMDGPU::FeatureInv2PiInlineImm))
O << "0.15915494309189532";
- else {
- // This part needs to align with AMDGPUOperand::addLiteralImmOperand.
- if (IsFP) {
- 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)));
- return;
- }
+ else
+ printLiteral64(Desc, Imm, STI, O, IsFP);
+}
- if (STI.hasFeature(AMDGPU::Feature64BitLiterals) &&
- (!isInt<32>(Imm) || !isUInt<32>(Imm)))
+void AMDGPUInstPrinter::printLiteral64(const MCInstrDesc &Desc, uint64_t Imm,
+ const MCSubtargetInfo &STI,
+ raw_ostream &O, bool IsFP) {
+ // This part needs to align with AMDGPUOperand::addLiteralImmOperand.
+ bool CanUse64BitLiterals =
+ STI.hasFeature(AMDGPU::Feature64BitLiterals) &&
+ !(Desc.TSFlags & (SIInstrFlags::VOP3 | SIInstrFlags::VOP3P));
+ if (IsFP) {
+ if (CanUse64BitLiterals && Lo_32(Imm))
+ O << "lit64(" << formatHex(static_cast<uint64_t>(Imm)) << ')';
+ else
+ O << formatHex(static_cast<uint64_t>(Hi_32(Imm)));
+ } else {
+ if (CanUse64BitLiterals && (!isInt<32>(Imm) || !isUInt<32>(Imm)))
O << "lit64(" << formatHex(static_cast<uint64_t>(Imm)) << ')';
else
O << formatHex(static_cast<uint64_t>(Imm));
@@ -719,7 +783,7 @@ void AMDGPUInstPrinter::printRegularOperand(const MCInst *MI, unsigned OpNo,
const MCOperand &Op = MI->getOperand(OpNo);
if (Op.isReg()) {
- printRegOperand(Op.getReg(), O, MRI);
+ printRegOperand(Op.getReg(), MI->getOpcode(), OpNo, O, MRI);
// Check if operand register class contains register used.
// Intention: print disassembler message when invalid code is decoded,
@@ -750,12 +814,12 @@ void AMDGPUInstPrinter::printRegularOperand(const MCInst *MI, unsigned OpNo,
break;
case AMDGPU::OPERAND_REG_IMM_INT64:
case AMDGPU::OPERAND_REG_INLINE_C_INT64:
- printImmediate64(Op.getImm(), STI, O, false);
+ printImmediate64(Desc, Op.getImm(), STI, O, false);
break;
case AMDGPU::OPERAND_REG_IMM_FP64:
case AMDGPU::OPERAND_REG_INLINE_C_FP64:
case AMDGPU::OPERAND_REG_INLINE_AC_FP64:
- printImmediate64(Op.getImm(), STI, O, true);
+ printImmediate64(Desc, Op.getImm(), STI, O, true);
break;
case AMDGPU::OPERAND_REG_INLINE_C_INT16:
case AMDGPU::OPERAND_REG_IMM_INT16:
@@ -793,22 +857,6 @@ void AMDGPUInstPrinter::printRegularOperand(const MCInst *MI, unsigned OpNo,
// custom printer.
llvm_unreachable("unexpected immediate operand type");
}
- } else if (Op.isDFPImm()) {
- double Value = bit_cast<double>(Op.getDFPImm());
- // We special case 0.0 because otherwise it will be printed as an integer.
- if (Value == 0.0)
- O << "0.0";
- else {
- const MCInstrDesc &Desc = MII.get(MI->getOpcode());
- int RCID = Desc.operands()[OpNo].RegClass;
- unsigned RCBits = AMDGPU::getRegBitWidth(MRI.getRegClass(RCID));
- if (RCBits == 32)
- printImmediate32(llvm::bit_cast<uint32_t>((float)Value), STI, O);
- else if (RCBits == 64)
- printImmediate64(llvm::bit_cast<uint64_t>(Value), STI, O, true);
- else
- llvm_unreachable("Invalid register class size");
- }
} else if (Op.isExpr()) {
const MCExpr *Exp = Op.getExpr();
MAI.printExpr(O, *Exp);
@@ -891,7 +939,7 @@ void AMDGPUInstPrinter::printOperandAndFPInputMods(const MCInst *MI,
if (OpNo + 1 < MI->getNumOperands() &&
(InputModifiers & SISrcMods::ABS) == 0) {
const MCOperand &Op = MI->getOperand(OpNo + 1);
- NegMnemo = Op.isImm() || Op.isDFPImm();
+ NegMnemo = Op.isImm();
}
if (NegMnemo) {
O << "neg(";
@@ -1146,7 +1194,7 @@ void AMDGPUInstPrinter::printExpSrcN(const MCInst *MI, unsigned OpNo,
OpNo = OpNo - N + N / 2;
if (En & (1 << N))
- printRegOperand(MI->getOperand(OpNo).getReg(), O, MRI);
+ printRegOperand(MI->getOperand(OpNo).getReg(), Opc, OpNo, O, MRI);
else
O << "off";
}