[SystemZ] Split SystemZInstPrinter to two classes based on Asm dialect (#112975)

In preparation for future work on separating the output of the GNU/HLASM
ASM dialects, we first separate the SystemZInstPrinter classes to two
versions, one for each ASM dialect.

The common code remains in a SystemZInstPrinterCommon class instead.

---------

Co-authored-by: Tony Tao <tonytao@ca.ibm.com>
This commit is contained in:
tltao
2024-10-22 10:28:57 -04:00
committed by GitHub
parent 6761b24ae2
commit 6512a8dd8c
13 changed files with 455 additions and 297 deletions

View File

@@ -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<MCConstantExpr>(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;

View File

@@ -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)

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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 <cstdint>
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<const char *, uint64_t> 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

View File

@@ -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);
}

View File

@@ -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 <cstdint>
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<const char *, uint64_t> 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

View File

@@ -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 <cassert>
#include <cstdint>
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 <unsigned N>
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<uint64_t>(MO.getImm());
assert(isUInt<N>(Value) && "Invalid uimm argument");
markup(O, Markup::Immediate) << Value;
}
template <unsigned N>
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<N>(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<MCSymbolRefExpr>(*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];
}

View File

@@ -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 <cassert>
#include <cstdint>
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 <unsigned N>
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<uint64_t>(MO.getImm());
assert(isUInt<N>(Value) && "Invalid uimm argument");
markup(O, Markup::Immediate) << Value;
}
template <unsigned N>
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<N>(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<MCSymbolRefExpr>(*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];
}

View File

@@ -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 <cstdint>
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<const char *, uint64_t> 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 @@ public:
// 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 <unsigned N>
void printUImmOperand(const MCInst *MI, int OpNum, raw_ostream &O);
template <unsigned N>
@@ -92,4 +85,4 @@ private:
} // end namespace llvm
#endif // LLVM_LIB_TARGET_SYSTEMZ_MCTARGETDESC_SYSTEMZINSTPRINTER_H
#endif // LLVM_LIB_TARGET_SYSTEMZ_MCTARGETDESC_SYSTEMZINSTPRINTERCOMMON_H

View File

@@ -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() {

View File

@@ -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;
}

View File

@@ -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) {