diff --git a/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp b/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp index f0a85645b8628..b8469a6ba70ea 100644 --- a/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp +++ b/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include "MCTargetDesc/SystemZInstPrinter.h" +#include "MCTargetDesc/SystemZGNUInstPrinter.h" #include "MCTargetDesc/SystemZMCAsmInfo.h" #include "MCTargetDesc/SystemZMCTargetDesc.h" #include "SystemZTargetStreamer.h" @@ -721,7 +721,7 @@ void SystemZOperand::print(raw_ostream &OS) const { OS << "Token:" << getToken(); break; case KindReg: - OS << "Reg:" << SystemZInstPrinter::getRegisterName(getReg()); + OS << "Reg:" << SystemZGNUInstPrinter::getRegisterName(getReg()); break; case KindImm: OS << "Imm:"; @@ -743,10 +743,10 @@ void SystemZOperand::print(raw_ostream &OS) const { if (Op.MemKind == BDLMem) OS << *cast(Op.Length.Imm) << ","; else if (Op.MemKind == BDRMem) - OS << SystemZInstPrinter::getRegisterName(Op.Length.Reg) << ","; + OS << SystemZGNUInstPrinter::getRegisterName(Op.Length.Reg) << ","; if (Op.Index) - OS << SystemZInstPrinter::getRegisterName(Op.Index) << ","; - OS << SystemZInstPrinter::getRegisterName(Op.Base); + OS << SystemZGNUInstPrinter::getRegisterName(Op.Index) << ","; + OS << SystemZGNUInstPrinter::getRegisterName(Op.Base); OS << ")"; } break; diff --git a/llvm/lib/Target/SystemZ/CMakeLists.txt b/llvm/lib/Target/SystemZ/CMakeLists.txt index 063e5bcd44171..0d8f3eac6ee4f 100644 --- a/llvm/lib/Target/SystemZ/CMakeLists.txt +++ b/llvm/lib/Target/SystemZ/CMakeLists.txt @@ -3,7 +3,8 @@ add_llvm_component_group(SystemZ HAS_JIT) set(LLVM_TARGET_DEFINITIONS SystemZ.td) tablegen(LLVM SystemZGenAsmMatcher.inc -gen-asm-matcher) -tablegen(LLVM SystemZGenAsmWriter.inc -gen-asm-writer) +tablegen(LLVM SystemZGenGNUAsmWriter.inc -gen-asm-writer) +tablegen(LLVM SystemZGenHLASMAsmWriter.inc -gen-asm-writer -asmwriternum=1) tablegen(LLVM SystemZGenCallingConv.inc -gen-callingconv) tablegen(LLVM SystemZGenDAGISel.inc -gen-dag-isel) tablegen(LLVM SystemZGenDisassemblerTables.inc -gen-disassembler) diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/CMakeLists.txt b/llvm/lib/Target/SystemZ/MCTargetDesc/CMakeLists.txt index 6700d79369708..9c00706531b88 100644 --- a/llvm/lib/Target/SystemZ/MCTargetDesc/CMakeLists.txt +++ b/llvm/lib/Target/SystemZ/MCTargetDesc/CMakeLists.txt @@ -1,7 +1,9 @@ add_llvm_component_library(LLVMSystemZDesc SystemZELFObjectWriter.cpp + SystemZGNUInstPrinter.cpp SystemZGOFFObjectWriter.cpp - SystemZInstPrinter.cpp + SystemZHLASMInstPrinter.cpp + SystemZInstPrinterCommon.cpp SystemZMCAsmBackend.cpp SystemZMCAsmInfo.cpp SystemZMCCodeEmitter.cpp diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZGNUInstPrinter.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZGNUInstPrinter.cpp new file mode 100644 index 0000000000000..05113010794e0 --- /dev/null +++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZGNUInstPrinter.cpp @@ -0,0 +1,33 @@ +//===- SystemZGNUInstPrinter.cpp - Convert SystemZ MCInst to GNU assembly -===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "SystemZGNUInstPrinter.h" +#include "llvm/MC/MCInst.h" +#include "llvm/MC/MCRegister.h" +#include "llvm/Support/raw_ostream.h" + +using namespace llvm; + +#define DEBUG_TYPE "asm-printer" + +#include "SystemZGenGNUAsmWriter.inc" + +void SystemZGNUInstPrinter::printFormattedRegName(const MCAsmInfo *MAI, + MCRegister Reg, + raw_ostream &O) const { + const char *RegName = getRegisterName(Reg); + markup(O, Markup::Register) << '%' << RegName; +} + +void SystemZGNUInstPrinter::printInst(const MCInst *MI, uint64_t Address, + StringRef Annot, + const MCSubtargetInfo &STI, + raw_ostream &O) { + printInstruction(MI, Address, O); + printAnnotation(O, Annot); +} diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZGNUInstPrinter.h b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZGNUInstPrinter.h new file mode 100644 index 0000000000000..8f62ae0e16c00 --- /dev/null +++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZGNUInstPrinter.h @@ -0,0 +1,46 @@ +//=- SystemZGNUInstPrinter.h - Convert SystemZ MCInst to assembly -*- C++ -*-=// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// This class prints a SystemZ MCInst to a .s file in GNU assembly format. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_SYSTEMZ_MCTARGETDESC_SYSTEMZGNUINSTPRINTER_H +#define LLVM_LIB_TARGET_SYSTEMZ_MCTARGETDESC_SYSTEMZGNUINSTPRINTER_H + +#include "SystemZInstPrinterCommon.h" +#include "llvm/MC/MCInstPrinter.h" +#include + +namespace llvm { + +class MCOperand; + +class SystemZGNUInstPrinter : public SystemZInstPrinterCommon { +public: + SystemZGNUInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII, + const MCRegisterInfo &MRI) + : SystemZInstPrinterCommon(MAI, MII, MRI) {} + + // Automatically generated by tblgen. + std::pair getMnemonic(const MCInst *MI) override; + void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &O); + static const char *getRegisterName(MCRegister Reg); + + // Override MCInstPrinter. + void printInst(const MCInst *MI, uint64_t Address, StringRef Annot, + const MCSubtargetInfo &STI, raw_ostream &O) override; + +private: + void printFormattedRegName(const MCAsmInfo *MAI, MCRegister Reg, + raw_ostream &O) const override; +}; + +} // end namespace llvm + +#endif // LLVM_LIB_TARGET_SYSTEMZ_MCTARGETDESC_SYSTEMZGNUINSTPRINTER_H diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMInstPrinter.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMInstPrinter.cpp new file mode 100644 index 0000000000000..ed7ff83a3c6df --- /dev/null +++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMInstPrinter.cpp @@ -0,0 +1,35 @@ +//=- SystemZHLASMInstPrinter.cpp - Convert SystemZ MCInst to HLASM assembly -=// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "SystemZHLASMInstPrinter.h" +#include "llvm/MC/MCInst.h" +#include "llvm/MC/MCRegister.h" +#include "llvm/Support/raw_ostream.h" + +using namespace llvm; + +#define DEBUG_TYPE "asm-printer" + +#include "SystemZGenHLASMAsmWriter.inc" + +void SystemZHLASMInstPrinter::printFormattedRegName(const MCAsmInfo *MAI, + MCRegister Reg, + raw_ostream &O) const { + const char *RegName = getRegisterName(Reg); + // Skip register prefix so that only register number is left + assert(isalpha(RegName[0]) && isdigit(RegName[1])); + markup(O, Markup::Register) << (RegName + 1); +} + +void SystemZHLASMInstPrinter::printInst(const MCInst *MI, uint64_t Address, + StringRef Annot, + const MCSubtargetInfo &STI, + raw_ostream &O) { + printInstruction(MI, Address, O); + printAnnotation(O, Annot); +} diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMInstPrinter.h b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMInstPrinter.h new file mode 100644 index 0000000000000..9a69e012c7294 --- /dev/null +++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZHLASMInstPrinter.h @@ -0,0 +1,45 @@ +//- SystemZHLASMInstPrinter.h - Convert SystemZ MCInst to assembly -*- C++ -*-// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// This class prints a SystemZ MCInst to a .s file in HLASM assembly format. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_SYSTEMZ_MCTARGETDESC_SYSTEMZHLASMINSTPRINTER_H +#define LLVM_LIB_TARGET_SYSTEMZ_MCTARGETDESC_SYSTEMZHLASMINSTPRINTER_H + +#include "SystemZInstPrinterCommon.h" +#include "llvm/MC/MCInstPrinter.h" +#include + +namespace llvm { + +class MCOperand; + +class SystemZHLASMInstPrinter : public SystemZInstPrinterCommon { +public: + SystemZHLASMInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII, + const MCRegisterInfo &MRI) + : SystemZInstPrinterCommon(MAI, MII, MRI) {} + + // Automatically generated by tblgen. + std::pair getMnemonic(const MCInst *MI) override; + void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &O); + static const char *getRegisterName(MCRegister Reg); + + void printInst(const MCInst *MI, uint64_t Address, StringRef Annot, + const MCSubtargetInfo &STI, raw_ostream &O) override; + +private: + void printFormattedRegName(const MCAsmInfo *MAI, MCRegister Reg, + raw_ostream &O) const override; +}; + +} // end namespace llvm + +#endif // LLVM_LIB_TARGET_SYSTEMZ_MCTARGETDESC_SYSTEMZHLASMINSTPRINTER_H diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZInstPrinter.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZInstPrinter.cpp deleted file mode 100644 index fa534fadc3230..0000000000000 --- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZInstPrinter.cpp +++ /dev/null @@ -1,266 +0,0 @@ -//===- SystemZInstPrinter.cpp - Convert SystemZ MCInst to assembly syntax -===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -#include "SystemZInstPrinter.h" -#include "llvm/MC/MCExpr.h" -#include "llvm/MC/MCInst.h" -#include "llvm/MC/MCRegister.h" -#include "llvm/MC/MCSymbol.h" -#include "llvm/Support/Casting.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/MathExtras.h" -#include "llvm/Support/raw_ostream.h" -#include -#include - -using namespace llvm; - -#define DEBUG_TYPE "asm-printer" - -#include "SystemZGenAsmWriter.inc" - -void SystemZInstPrinter::printAddress(const MCAsmInfo *MAI, MCRegister Base, - const MCOperand &DispMO, MCRegister Index, - raw_ostream &O) { - printOperand(DispMO, MAI, O); - if (Base || Index) { - O << '('; - if (Index) { - printFormattedRegName(MAI, Index, O); - O << ','; - } - if (Base) - printFormattedRegName(MAI, Base, O); - else - O << '0'; - O << ')'; - } -} - -void SystemZInstPrinter::printOperand(const MCOperand &MO, const MCAsmInfo *MAI, - raw_ostream &O) { - if (MO.isReg()) { - if (!MO.getReg()) - O << '0'; - else - printFormattedRegName(MAI, MO.getReg(), O); - } - else if (MO.isImm()) - markup(O, Markup::Immediate) << MO.getImm(); - else if (MO.isExpr()) - MO.getExpr()->print(O, MAI); - else - llvm_unreachable("Invalid operand"); -} - -void SystemZInstPrinter::printFormattedRegName(const MCAsmInfo *MAI, - MCRegister Reg, - raw_ostream &O) const { - const char *RegName = getRegisterName(Reg); - if (MAI->getAssemblerDialect() == AD_HLASM) { - // Skip register prefix so that only register number is left - assert(isalpha(RegName[0]) && isdigit(RegName[1])); - markup(O, Markup::Register) << (RegName + 1); - } else - markup(O, Markup::Register) << '%' << RegName; -} - -void SystemZInstPrinter::printRegName(raw_ostream &O, MCRegister Reg) const { - printFormattedRegName(&MAI, Reg, O); -} - -void SystemZInstPrinter::printInst(const MCInst *MI, uint64_t Address, - StringRef Annot, const MCSubtargetInfo &STI, - raw_ostream &O) { - printInstruction(MI, Address, O); - printAnnotation(O, Annot); -} - -template -void SystemZInstPrinter::printUImmOperand(const MCInst *MI, int OpNum, - raw_ostream &O) { - const MCOperand &MO = MI->getOperand(OpNum); - if (MO.isExpr()) { - O << *MO.getExpr(); - return; - } - uint64_t Value = static_cast(MO.getImm()); - assert(isUInt(Value) && "Invalid uimm argument"); - markup(O, Markup::Immediate) << Value; -} - -template -void SystemZInstPrinter::printSImmOperand(const MCInst *MI, int OpNum, - raw_ostream &O) { - const MCOperand &MO = MI->getOperand(OpNum); - if (MO.isExpr()) { - O << *MO.getExpr(); - return; - } - int64_t Value = MI->getOperand(OpNum).getImm(); - assert(isInt(Value) && "Invalid simm argument"); - markup(O, Markup::Immediate) << Value; -} - -void SystemZInstPrinter::printU1ImmOperand(const MCInst *MI, int OpNum, - raw_ostream &O) { - printUImmOperand<1>(MI, OpNum, O); -} - -void SystemZInstPrinter::printU2ImmOperand(const MCInst *MI, int OpNum, - raw_ostream &O) { - printUImmOperand<2>(MI, OpNum, O); -} - -void SystemZInstPrinter::printU3ImmOperand(const MCInst *MI, int OpNum, - raw_ostream &O) { - printUImmOperand<3>(MI, OpNum, O); -} - -void SystemZInstPrinter::printU4ImmOperand(const MCInst *MI, int OpNum, - raw_ostream &O) { - printUImmOperand<4>(MI, OpNum, O); -} - -void SystemZInstPrinter::printS8ImmOperand(const MCInst *MI, int OpNum, - raw_ostream &O) { - printSImmOperand<8>(MI, OpNum, O); -} - -void SystemZInstPrinter::printU8ImmOperand(const MCInst *MI, int OpNum, - raw_ostream &O) { - printUImmOperand<8>(MI, OpNum, O); -} - -void SystemZInstPrinter::printU12ImmOperand(const MCInst *MI, int OpNum, - raw_ostream &O) { - printUImmOperand<12>(MI, OpNum, O); -} - -void SystemZInstPrinter::printS16ImmOperand(const MCInst *MI, int OpNum, - raw_ostream &O) { - printSImmOperand<16>(MI, OpNum, O); -} - -void SystemZInstPrinter::printU16ImmOperand(const MCInst *MI, int OpNum, - raw_ostream &O) { - printUImmOperand<16>(MI, OpNum, O); -} - -void SystemZInstPrinter::printS32ImmOperand(const MCInst *MI, int OpNum, - raw_ostream &O) { - printSImmOperand<32>(MI, OpNum, O); -} - -void SystemZInstPrinter::printU32ImmOperand(const MCInst *MI, int OpNum, - raw_ostream &O) { - printUImmOperand<32>(MI, OpNum, O); -} - -void SystemZInstPrinter::printU48ImmOperand(const MCInst *MI, int OpNum, - raw_ostream &O) { - printUImmOperand<48>(MI, OpNum, O); -} - -void SystemZInstPrinter::printPCRelOperand(const MCInst *MI, int OpNum, - raw_ostream &O) { - const MCOperand &MO = MI->getOperand(OpNum); - if (MO.isImm()) { - WithMarkup M = markup(O, Markup::Immediate); - O << "0x"; - O.write_hex(MO.getImm()); - } else - MO.getExpr()->print(O, &MAI); -} - -void SystemZInstPrinter::printPCRelTLSOperand(const MCInst *MI, - uint64_t Address, int OpNum, - raw_ostream &O) { - // Output the PC-relative operand. - printPCRelOperand(MI, OpNum, O); - - // Output the TLS marker if present. - if ((unsigned)OpNum + 1 < MI->getNumOperands()) { - const MCOperand &MO = MI->getOperand(OpNum + 1); - const MCSymbolRefExpr &refExp = cast(*MO.getExpr()); - switch (refExp.getKind()) { - case MCSymbolRefExpr::VK_TLSGD: - O << ":tls_gdcall:"; - break; - case MCSymbolRefExpr::VK_TLSLDM: - O << ":tls_ldcall:"; - break; - default: - llvm_unreachable("Unexpected symbol kind"); - } - O << refExp.getSymbol().getName(); - } -} - -void SystemZInstPrinter::printOperand(const MCInst *MI, int OpNum, - raw_ostream &O) { - printOperand(MI->getOperand(OpNum), &MAI, O); -} - -void SystemZInstPrinter::printBDAddrOperand(const MCInst *MI, int OpNum, - raw_ostream &O) { - printAddress(&MAI, MI->getOperand(OpNum).getReg(), MI->getOperand(OpNum + 1), - 0, O); -} - -void SystemZInstPrinter::printBDXAddrOperand(const MCInst *MI, int OpNum, - raw_ostream &O) { - printAddress(&MAI, MI->getOperand(OpNum).getReg(), MI->getOperand(OpNum + 1), - MI->getOperand(OpNum + 2).getReg(), O); -} - -void SystemZInstPrinter::printBDLAddrOperand(const MCInst *MI, int OpNum, - raw_ostream &O) { - unsigned Base = MI->getOperand(OpNum).getReg(); - const MCOperand &DispMO = MI->getOperand(OpNum + 1); - uint64_t Length = MI->getOperand(OpNum + 2).getImm(); - printOperand(DispMO, &MAI, O); - O << '(' << Length; - if (Base) { - O << ","; - printRegName(O, Base); - } - O << ')'; -} - -void SystemZInstPrinter::printBDRAddrOperand(const MCInst *MI, int OpNum, - raw_ostream &O) { - unsigned Base = MI->getOperand(OpNum).getReg(); - const MCOperand &DispMO = MI->getOperand(OpNum + 1); - unsigned Length = MI->getOperand(OpNum + 2).getReg(); - printOperand(DispMO, &MAI, O); - O << "("; - printRegName(O, Length); - if (Base) { - O << ","; - printRegName(O, Base); - } - O << ')'; -} - -void SystemZInstPrinter::printBDVAddrOperand(const MCInst *MI, int OpNum, - raw_ostream &O) { - printAddress(&MAI, MI->getOperand(OpNum).getReg(), MI->getOperand(OpNum + 1), - MI->getOperand(OpNum + 2).getReg(), O); -} - -void SystemZInstPrinter::printCond4Operand(const MCInst *MI, int OpNum, - raw_ostream &O) { - static const char *const CondNames[] = { - "o", "h", "nle", "l", "nhe", "lh", "ne", - "e", "nlh", "he", "nl", "le", "nh", "no" - }; - uint64_t Imm = MI->getOperand(OpNum).getImm(); - assert(Imm > 0 && Imm < 15 && "Invalid condition"); - O << CondNames[Imm - 1]; -} diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZInstPrinterCommon.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZInstPrinterCommon.cpp new file mode 100644 index 0000000000000..00560ab1f4b18 --- /dev/null +++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZInstPrinterCommon.cpp @@ -0,0 +1,246 @@ +//=- SystemZInstPrinterCommon.cpp - Common SystemZ MCInst to assembly funcs -=// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "SystemZInstPrinterCommon.h" +#include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCInst.h" +#include "llvm/MC/MCRegister.h" +#include "llvm/MC/MCSymbol.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/MathExtras.h" +#include "llvm/Support/raw_ostream.h" +#include +#include + +using namespace llvm; + +#define DEBUG_TYPE "asm-printer" + +void SystemZInstPrinterCommon::printAddress(const MCAsmInfo *MAI, + MCRegister Base, + const MCOperand &DispMO, + MCRegister Index, raw_ostream &O) { + printOperand(DispMO, MAI, O); + if (Base || Index) { + O << '('; + if (Index) { + printRegName(O, Index); + O << ','; + } + if (Base) + printRegName(O, Base); + else + O << '0'; + O << ')'; + } +} + +void SystemZInstPrinterCommon::printOperand(const MCOperand &MO, + const MCAsmInfo *MAI, + raw_ostream &O) { + if (MO.isReg()) { + if (!MO.getReg()) + O << '0'; + else + printRegName(O, MO.getReg()); + } else if (MO.isImm()) + markup(O, Markup::Immediate) << MO.getImm(); + else if (MO.isExpr()) + MO.getExpr()->print(O, MAI); + else + llvm_unreachable("Invalid operand"); +} + +void SystemZInstPrinterCommon::printRegName(raw_ostream &O, + MCRegister Reg) const { + printFormattedRegName(&MAI, Reg, O); +} + +template +void SystemZInstPrinterCommon::printUImmOperand(const MCInst *MI, int OpNum, + raw_ostream &O) { + const MCOperand &MO = MI->getOperand(OpNum); + if (MO.isExpr()) { + O << *MO.getExpr(); + return; + } + uint64_t Value = static_cast(MO.getImm()); + assert(isUInt(Value) && "Invalid uimm argument"); + markup(O, Markup::Immediate) << Value; +} + +template +void SystemZInstPrinterCommon::printSImmOperand(const MCInst *MI, int OpNum, + raw_ostream &O) { + const MCOperand &MO = MI->getOperand(OpNum); + if (MO.isExpr()) { + O << *MO.getExpr(); + return; + } + int64_t Value = MI->getOperand(OpNum).getImm(); + assert(isInt(Value) && "Invalid simm argument"); + markup(O, Markup::Immediate) << Value; +} + +void SystemZInstPrinterCommon::printU1ImmOperand(const MCInst *MI, int OpNum, + raw_ostream &O) { + printUImmOperand<1>(MI, OpNum, O); +} + +void SystemZInstPrinterCommon::printU2ImmOperand(const MCInst *MI, int OpNum, + raw_ostream &O) { + printUImmOperand<2>(MI, OpNum, O); +} + +void SystemZInstPrinterCommon::printU3ImmOperand(const MCInst *MI, int OpNum, + raw_ostream &O) { + printUImmOperand<3>(MI, OpNum, O); +} + +void SystemZInstPrinterCommon::printU4ImmOperand(const MCInst *MI, int OpNum, + raw_ostream &O) { + printUImmOperand<4>(MI, OpNum, O); +} + +void SystemZInstPrinterCommon::printS8ImmOperand(const MCInst *MI, int OpNum, + raw_ostream &O) { + printSImmOperand<8>(MI, OpNum, O); +} + +void SystemZInstPrinterCommon::printU8ImmOperand(const MCInst *MI, int OpNum, + raw_ostream &O) { + printUImmOperand<8>(MI, OpNum, O); +} + +void SystemZInstPrinterCommon::printU12ImmOperand(const MCInst *MI, int OpNum, + raw_ostream &O) { + printUImmOperand<12>(MI, OpNum, O); +} + +void SystemZInstPrinterCommon::printS16ImmOperand(const MCInst *MI, int OpNum, + raw_ostream &O) { + printSImmOperand<16>(MI, OpNum, O); +} + +void SystemZInstPrinterCommon::printU16ImmOperand(const MCInst *MI, int OpNum, + raw_ostream &O) { + printUImmOperand<16>(MI, OpNum, O); +} + +void SystemZInstPrinterCommon::printS32ImmOperand(const MCInst *MI, int OpNum, + raw_ostream &O) { + printSImmOperand<32>(MI, OpNum, O); +} + +void SystemZInstPrinterCommon::printU32ImmOperand(const MCInst *MI, int OpNum, + raw_ostream &O) { + printUImmOperand<32>(MI, OpNum, O); +} + +void SystemZInstPrinterCommon::printU48ImmOperand(const MCInst *MI, int OpNum, + raw_ostream &O) { + printUImmOperand<48>(MI, OpNum, O); +} + +void SystemZInstPrinterCommon::printPCRelOperand(const MCInst *MI, int OpNum, + raw_ostream &O) { + const MCOperand &MO = MI->getOperand(OpNum); + if (MO.isImm()) { + WithMarkup M = markup(O, Markup::Immediate); + O << "0x"; + O.write_hex(MO.getImm()); + } else + MO.getExpr()->print(O, &MAI); +} + +void SystemZInstPrinterCommon::printPCRelTLSOperand(const MCInst *MI, + uint64_t Address, int OpNum, + raw_ostream &O) { + // Output the PC-relative operand. + printPCRelOperand(MI, OpNum, O); + + // Output the TLS marker if present. + if ((unsigned)OpNum + 1 < MI->getNumOperands()) { + const MCOperand &MO = MI->getOperand(OpNum + 1); + const MCSymbolRefExpr &refExp = cast(*MO.getExpr()); + switch (refExp.getKind()) { + case MCSymbolRefExpr::VK_TLSGD: + O << ":tls_gdcall:"; + break; + case MCSymbolRefExpr::VK_TLSLDM: + O << ":tls_ldcall:"; + break; + default: + llvm_unreachable("Unexpected symbol kind"); + } + O << refExp.getSymbol().getName(); + } +} + +void SystemZInstPrinterCommon::printOperand(const MCInst *MI, int OpNum, + raw_ostream &O) { + printOperand(MI->getOperand(OpNum), &MAI, O); +} + +void SystemZInstPrinterCommon::printBDAddrOperand(const MCInst *MI, int OpNum, + raw_ostream &O) { + printAddress(&MAI, MI->getOperand(OpNum).getReg(), MI->getOperand(OpNum + 1), + 0, O); +} + +void SystemZInstPrinterCommon::printBDXAddrOperand(const MCInst *MI, int OpNum, + raw_ostream &O) { + printAddress(&MAI, MI->getOperand(OpNum).getReg(), MI->getOperand(OpNum + 1), + MI->getOperand(OpNum + 2).getReg(), O); +} + +void SystemZInstPrinterCommon::printBDLAddrOperand(const MCInst *MI, int OpNum, + raw_ostream &O) { + unsigned Base = MI->getOperand(OpNum).getReg(); + const MCOperand &DispMO = MI->getOperand(OpNum + 1); + uint64_t Length = MI->getOperand(OpNum + 2).getImm(); + printOperand(DispMO, &MAI, O); + O << '(' << Length; + if (Base) { + O << ","; + printRegName(O, Base); + } + O << ')'; +} + +void SystemZInstPrinterCommon::printBDRAddrOperand(const MCInst *MI, int OpNum, + raw_ostream &O) { + unsigned Base = MI->getOperand(OpNum).getReg(); + const MCOperand &DispMO = MI->getOperand(OpNum + 1); + unsigned Length = MI->getOperand(OpNum + 2).getReg(); + printOperand(DispMO, &MAI, O); + O << "("; + printRegName(O, Length); + if (Base) { + O << ","; + printRegName(O, Base); + } + O << ')'; +} + +void SystemZInstPrinterCommon::printBDVAddrOperand(const MCInst *MI, int OpNum, + raw_ostream &O) { + printAddress(&MAI, MI->getOperand(OpNum).getReg(), MI->getOperand(OpNum + 1), + MI->getOperand(OpNum + 2).getReg(), O); +} + +void SystemZInstPrinterCommon::printCond4Operand(const MCInst *MI, int OpNum, + raw_ostream &O) { + static const char *const CondNames[] = {"o", "h", "nle", "l", "nhe", + "lh", "ne", "e", "nlh", "he", + "nl", "le", "nh", "no"}; + uint64_t Imm = MI->getOperand(OpNum).getImm(); + assert(Imm > 0 && Imm < 15 && "Invalid condition"); + O << CondNames[Imm - 1]; +} diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZInstPrinter.h b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZInstPrinterCommon.h similarity index 77% rename from llvm/lib/Target/SystemZ/MCTargetDesc/SystemZInstPrinter.h rename to llvm/lib/Target/SystemZ/MCTargetDesc/SystemZInstPrinterCommon.h index 4e7490dad2996..9a972824f7ffb 100644 --- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZInstPrinter.h +++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZInstPrinterCommon.h @@ -1,4 +1,4 @@ -//==- SystemZInstPrinter.h - Convert SystemZ MCInst to assembly --*- C++ -*-==// +//== SystemZInstPrinterCommon.h - Common SystemZ InstPrinter funcs *- C++ -*==// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -10,27 +10,23 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIB_TARGET_SYSTEMZ_MCTARGETDESC_SYSTEMZINSTPRINTER_H -#define LLVM_LIB_TARGET_SYSTEMZ_MCTARGETDESC_SYSTEMZINSTPRINTER_H +#ifndef LLVM_LIB_TARGET_SYSTEMZ_MCTARGETDESC_SYSTEMZINSTPRINTERCOMMON_H +#define LLVM_LIB_TARGET_SYSTEMZ_MCTARGETDESC_SYSTEMZINSTPRINTERCOMMON_H #include "SystemZMCAsmInfo.h" #include "llvm/MC/MCInstPrinter.h" +#include "llvm/MC/MCRegister.h" #include namespace llvm { class MCOperand; -class SystemZInstPrinter : public MCInstPrinter { +class SystemZInstPrinterCommon : public MCInstPrinter { public: - SystemZInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII, - const MCRegisterInfo &MRI) - : MCInstPrinter(MAI, MII, MRI) {} - - // Automatically generated by tblgen. - std::pair getMnemonic(const MCInst *MI) override; - void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &O); - static const char *getRegisterName(MCRegister Reg); + SystemZInstPrinterCommon(const MCAsmInfo &MAI, const MCInstrInfo &MII, + const MCRegisterInfo &MRI) + : MCInstPrinter(MAI, MII, MRI) {} // Print an address with the given base, displacement and index. void printAddress(const MCAsmInfo *MAI, MCRegister Base, @@ -39,16 +35,13 @@ class SystemZInstPrinter : public MCInstPrinter { // Print the given operand. void printOperand(const MCOperand &MO, const MCAsmInfo *MAI, raw_ostream &O); - void printFormattedRegName(const MCAsmInfo *MAI, MCRegister Reg, - raw_ostream &O) const; + virtual void printFormattedRegName(const MCAsmInfo *MAI, MCRegister Reg, + raw_ostream &O) const {} // Override MCInstPrinter. void printRegName(raw_ostream &O, MCRegister Reg) const override; - void printInst(const MCInst *MI, uint64_t Address, StringRef Annot, - const MCSubtargetInfo &STI, raw_ostream &O) override; - -private: +protected: template void printUImmOperand(const MCInst *MI, int OpNum, raw_ostream &O); template @@ -92,4 +85,4 @@ class SystemZInstPrinter : public MCInstPrinter { } // end namespace llvm -#endif // LLVM_LIB_TARGET_SYSTEMZ_MCTARGETDESC_SYSTEMZINSTPRINTER_H +#endif // LLVM_LIB_TARGET_SYSTEMZ_MCTARGETDESC_SYSTEMZINSTPRINTERCOMMON_H diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCTargetDesc.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCTargetDesc.cpp index f58674ee118ee..333221c46ebb8 100644 --- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCTargetDesc.cpp +++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCTargetDesc.cpp @@ -7,7 +7,8 @@ //===----------------------------------------------------------------------===// #include "SystemZMCTargetDesc.h" -#include "SystemZInstPrinter.h" +#include "SystemZGNUInstPrinter.h" +#include "SystemZHLASMInstPrinter.h" #include "SystemZMCAsmInfo.h" #include "SystemZTargetStreamer.h" #include "TargetInfo/SystemZTargetInfo.h" @@ -186,7 +187,10 @@ static MCInstPrinter *createSystemZMCInstPrinter(const Triple &T, const MCAsmInfo &MAI, const MCInstrInfo &MII, const MCRegisterInfo &MRI) { - return new SystemZInstPrinter(MAI, MII, MRI); + if (SyntaxVariant == AD_HLASM) + return new SystemZHLASMInstPrinter(MAI, MII, MRI); + + return new SystemZGNUInstPrinter(MAI, MII, MRI); } void SystemZTargetStreamer::emitConstantPools() { diff --git a/llvm/lib/Target/SystemZ/SystemZ.td b/llvm/lib/Target/SystemZ/SystemZ.td index 9d0c77eafa2e2..ec110645c62dd 100644 --- a/llvm/lib/Target/SystemZ/SystemZ.td +++ b/llvm/lib/Target/SystemZ/SystemZ.td @@ -81,6 +81,20 @@ def HLASMAsmParserVariant : AsmParserVariant { string Name = "hlasm"; } +//===----------------------------------------------------------------------===// +// Assembly writer +//===----------------------------------------------------------------------===// + +// The SystemZ target supports two different syntaxes for emitting machine code. +def GNUAsmWriter : AsmWriter { + string AsmWriterClassName = "GNUInstPrinter"; + int Variant = 0; +} +def HLASMAsmWriter : AsmWriter { + string AsmWriterClassName = "HLASMInstPrinter"; + int Variant = 1; +} + //===----------------------------------------------------------------------===// // Top-level target declaration //===----------------------------------------------------------------------===// @@ -89,5 +103,6 @@ def SystemZ : Target { let InstructionSet = SystemZInstrInfo; let AssemblyParsers = [SystemZAsmParser]; let AssemblyParserVariants = [GNUAsmParserVariant, HLASMAsmParserVariant]; + let AssemblyWriters = [GNUAsmWriter, HLASMAsmWriter]; let AllowRegisterRenaming = 1; } diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp index ed400e9eceb9c..050a482c69d52 100644 --- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp +++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp @@ -12,7 +12,8 @@ //===----------------------------------------------------------------------===// #include "SystemZAsmPrinter.h" -#include "MCTargetDesc/SystemZInstPrinter.h" +#include "MCTargetDesc/SystemZGNUInstPrinter.h" +#include "MCTargetDesc/SystemZHLASMInstPrinter.h" #include "MCTargetDesc/SystemZMCExpr.h" #include "SystemZConstantPoolValue.h" #include "SystemZMCInstLower.h" @@ -882,13 +883,16 @@ void SystemZAsmPrinter::emitMachineConstantPoolValue( static void printFormattedRegName(const MCAsmInfo *MAI, unsigned RegNo, raw_ostream &OS) { - const char *RegName = SystemZInstPrinter::getRegisterName(RegNo); + const char *RegName; if (MAI->getAssemblerDialect() == AD_HLASM) { + RegName = SystemZHLASMInstPrinter::getRegisterName(RegNo); // Skip register prefix so that only register number is left assert(isalpha(RegName[0]) && isdigit(RegName[1])); OS << (RegName + 1); - } else + } else { + RegName = SystemZGNUInstPrinter::getRegisterName(RegNo); OS << '%' << RegName; + } } static void printReg(unsigned Reg, const MCAsmInfo *MAI, raw_ostream &OS) {