diff options
Diffstat (limited to 'llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp')
| -rw-r--r-- | llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp | 126 |
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"; } |
