MCAsmInfo: replace AIX-specific variables with IsAIX

AIX assembly is very different from the gas syntax. We don't expect
other targets to share these differences. Unify the numerous,
essentially AIX-specific variables.
This commit is contained in:
Fangrui Song 2024-12-24 22:46:12 -08:00
parent 5d81b14900
commit 25bb6592c9
5 changed files with 48 additions and 146 deletions

View File

@ -94,9 +94,7 @@ protected:
/// constants into comdat sections.
bool HasCOFFComdatConstants = false;
/// True if this is an XCOFF target that supports visibility attributes as
/// part of .global, .weak, .extern, and .comm. Default is false.
bool HasVisibilityOnlyWithLinkage = false;
bool IsAIX = false;
// True if using the HLASM dialect on z/OS.
bool IsHLASM = false;
@ -202,10 +200,6 @@ protected:
/// instead.
bool UseDataRegionDirectives = false;
/// True if .align is to be used for alignment. Only power-of-two
/// alignment is supported.
bool UseDotAlignForAlignment = false;
/// True if the target supports LEB128 directives.
bool HasLEB128Directives = true;
@ -220,11 +214,6 @@ protected:
/// "\t.zero\t"
const char *ZeroDirective;
/// This should be set to true if the zero directive supports a value to emit
/// other than zero. If this is set to false, the Data*bitsDirective's will be
/// used to emit these bytes. Defaults to true.
bool ZeroDirectiveSupportsNonZeroValue = true;
/// This directive allows emission of an ascii string with the standard C
/// escape characters embedded into it. If a target doesn't support this, it
/// can be set to null. Defaults to "\t.ascii\t"
@ -235,16 +224,6 @@ protected:
/// doesn't support this, it can be set to null. Defaults to "\t.asciz\t"
const char *AscizDirective;
/// This directive accepts a comma-separated list of bytes for emission as a
/// string of bytes. For targets that do not support this, it shall be set to
/// null. Defaults to null.
const char *ByteListDirective = nullptr;
/// This directive allows emission of a zero-terminated ascii string without
/// the standard C escape characters embedded into it. If a target doesn't
/// support this, it can be set to null. Defaults to null.
const char *PlainStringDirective = nullptr;
/// Form used for character literals in the assembly syntax. Useful for
/// producing strings as byte lists. If a target does not use or support
/// this, it shall be set to ACLS_Unknown. Defaults to ACLS_Unknown.
@ -325,16 +304,6 @@ protected:
/// argument and how it is interpreted. Defaults to NoAlignment.
LCOMM::LCOMMType LCOMMDirectiveAlignmentType = LCOMM::NoAlignment;
/// True if the target only has basename for .file directive. False if the
/// target also needs the directory along with the basename. Defaults to true.
bool HasBasenameOnlyForFileDirective = true;
/// True if the target represents string constants as mostly raw characters in
/// paired double quotation with paired double quotation marks as the escape
/// mechanism to represent a double quotation mark within the string. Defaults
/// to false.
bool HasPairedDoubleQuoteStringConstants = false;
// True if the target allows .align directives on functions. This is true for
// most targets, so defaults to true.
bool HasFunctionAlignment = true;
@ -347,10 +316,6 @@ protected:
/// for ELF targets. Defaults to true.
bool HasSingleParameterDotFile = true;
/// True if the target has a four strings .file directive, strings separated
/// by comma. Defaults to false.
bool HasFourStringsDotFile = false;
/// True if the target has a .ident directive, this is true for ELF targets.
/// Defaults to false.
bool HasIdentDirective = false;
@ -417,10 +382,6 @@ protected:
/// absolute difference.
bool DwarfFDESymbolsUseAbsDiff = false;
/// True if the target supports generating the DWARF line table through using
/// the .loc/.file directives. Defaults to true.
bool UsesDwarfFileAndLocDirectives = true;
/// True if DWARF `.file directory' directive syntax is used by
/// default.
bool EnableDwarfFileDirectoryDefault = true;
@ -484,9 +445,6 @@ protected:
// If true, use Motorola-style integers in Assembly (ex. $0ac).
bool UseMotorolaIntegers = false;
// If true, emit function descriptor symbol on AIX.
bool NeedsFunctionDescriptors = false;
public:
explicit MCAsmInfo();
virtual ~MCAsmInfo();
@ -567,13 +525,11 @@ public:
// Accessors.
bool isAIX() const { return IsAIX; }
bool isHLASM() const { return IsHLASM; }
bool isMachO() const { return HasSubsectionsViaSymbols; }
bool hasCOFFAssociativeComdats() const { return HasCOFFAssociativeComdats; }
bool hasCOFFComdatConstants() const { return HasCOFFComdatConstants; }
bool hasVisibilityOnlyWithLinkage() const {
return HasVisibilityOnlyWithLinkage;
}
/// Returns the maximum possible encoded instruction size in bytes. If \p STI
/// is null, this should be the maximum size for any subtarget.
@ -630,23 +586,14 @@ public:
return UseDataRegionDirectives;
}
bool useDotAlignForAlignment() const {
return UseDotAlignForAlignment;
}
bool hasLEB128Directives() const { return HasLEB128Directives; }
bool useFullRegisterNames() const { return PPCUseFullRegisterNames; }
void setFullRegisterNames(bool V) { PPCUseFullRegisterNames = V; }
const char *getZeroDirective() const { return ZeroDirective; }
bool doesZeroDirectiveSupportNonZeroValue() const {
return ZeroDirectiveSupportsNonZeroValue;
}
const char *getAsciiDirective() const { return AsciiDirective; }
const char *getAscizDirective() const { return AscizDirective; }
const char *getByteListDirective() const { return ByteListDirective; }
const char *getPlainStringDirective() const { return PlainStringDirective; }
AsmCharLiteralSyntax characterLiteralSyntax() const {
return CharacterLiteralSyntax;
}
@ -666,16 +613,9 @@ public:
return LCOMMDirectiveAlignmentType;
}
bool hasBasenameOnlyForFileDirective() const {
return HasBasenameOnlyForFileDirective;
}
bool hasPairedDoubleQuoteStringConstants() const {
return HasPairedDoubleQuoteStringConstants;
}
bool hasFunctionAlignment() const { return HasFunctionAlignment; }
bool hasDotTypeDotSizeDirective() const { return HasDotTypeDotSizeDirective; }
bool hasSingleParameterDotFile() const { return HasSingleParameterDotFile; }
bool hasFourStringsDotFile() const { return HasFourStringsDotFile; }
bool hasIdentDirective() const { return HasIdentDirective; }
bool hasNoDeadStrip() const { return HasNoDeadStrip; }
const char *getWeakDirective() const { return WeakDirective; }
@ -742,13 +682,7 @@ public:
return SupportsExtendedDwarfLocDirective;
}
bool usesDwarfFileAndLocDirectives() const {
return UsesDwarfFileAndLocDirectives;
}
bool needsDwarfSectionSizeInHeader() const {
return DwarfSectionSizeRequired;
}
bool usesDwarfFileAndLocDirectives() const { return !IsAIX; }
bool enableDwarfFileDirectoryDefault() const {
return EnableDwarfFileDirectoryDefault;
@ -798,7 +732,6 @@ public:
bool shouldUseLogicalShr() const { return UseLogicalShr; }
bool hasMipsExpressions() const { return HasMipsExpressions; }
bool needsFunctionDescriptors() const { return NeedsFunctionDescriptors; }
bool shouldUseMotorolaIntegers() const { return UseMotorolaIntegers; }
};

View File

@ -503,13 +503,7 @@ bool AsmPrinter::doInitialization(Module &M) {
// don't, this at least helps the user find where a global came from.
if (MAI->hasSingleParameterDotFile()) {
// .file "foo.c"
SmallString<128> FileName;
if (MAI->hasBasenameOnlyForFileDirective())
FileName = llvm::sys::path::filename(M.getSourceFileName());
else
FileName = M.getSourceFileName();
if (MAI->hasFourStringsDotFile()) {
if (MAI->isAIX()) {
const char VerStr[] =
#ifdef PACKAGE_VENDOR
PACKAGE_VENDOR " "
@ -520,9 +514,10 @@ bool AsmPrinter::doInitialization(Module &M) {
#endif
;
// TODO: Add timestamp and description.
OutStreamer->emitFileDirective(FileName, VerStr, "", "");
OutStreamer->emitFileDirective(M.getSourceFileName(), VerStr, "", "");
} else {
OutStreamer->emitFileDirective(FileName);
OutStreamer->emitFileDirective(
llvm::sys::path::filename(M.getSourceFileName()));
}
}
@ -967,11 +962,10 @@ void AsmPrinter::emitFunctionHeader() {
MF->setSection(getObjFileLowering().SectionForGlobal(&F, TM));
OutStreamer->switchSection(MF->getSection());
if (!MAI->hasVisibilityOnlyWithLinkage())
emitVisibility(CurrentFnSym, F.getVisibility());
if (MAI->needsFunctionDescriptors())
if (MAI->isAIX())
emitLinkage(&F, CurrentFnDescSym);
else
emitVisibility(CurrentFnSym, F.getVisibility());
emitLinkage(&F, CurrentFnSym);
if (MAI->hasFunctionAlignment())
@ -1031,7 +1025,7 @@ void AsmPrinter::emitFunctionHeader() {
// to emit their specific function descriptor. Right now it is only used by
// the AIX target. The PowerPC 64-bit V1 ELF target also uses function
// descriptors and should be converted to use this hook as well.
if (MAI->needsFunctionDescriptors())
if (MAI->isAIX())
emitFunctionDescriptor();
// Emit the CurrentFnSym. This is a virtual function to allow targets to do
@ -2234,9 +2228,6 @@ void AsmPrinter::emitGlobalAlias(const Module &M, const GlobalAlias &GA) {
// point, all the extra label is emitted, we just have to emit linkage for
// those labels.
if (TM.getTargetTriple().isOSBinFormatXCOFF()) {
assert(MAI->hasVisibilityOnlyWithLinkage() &&
"Visibility should be handled with emitLinkage() on AIX.");
// Linkage for alias of global variable has been emitted.
if (isa<GlobalVariable>(GA.getAliaseeObject()))
return;
@ -2730,7 +2721,7 @@ void AsmPrinter::SetupMachineFunction(MachineFunction &MF) {
HasNoSplitStack = true;
// Get the function symbol.
if (!MAI->needsFunctionDescriptors()) {
if (!MAI->isAIX()) {
CurrentFnSym = getSymbol(&MF.getFunction());
} else {
assert(TM.getTargetTriple().isOSAIX() &&

View File

@ -19,29 +19,17 @@ extern cl::opt<cl::boolOrDefault> UseLEB128Directives;
void MCAsmInfoXCOFF::anchor() {}
MCAsmInfoXCOFF::MCAsmInfoXCOFF() {
IsAIX = true;
IsLittleEndian = false;
HasVisibilityOnlyWithLinkage = true;
HasBasenameOnlyForFileDirective = false;
HasFourStringsDotFile = true;
// For XCOFF, string constant consists of any number of characters enclosed in
// "" (double quotation marks).
HasPairedDoubleQuoteStringConstants = true;
PrivateGlobalPrefix = "L..";
PrivateLabelPrefix = "L..";
SupportsQuotedNames = false;
UseDotAlignForAlignment = true;
UsesDwarfFileAndLocDirectives = false;
DwarfSectionSizeRequired = false;
if (UseLEB128Directives == cl::BOU_UNSET)
HasLEB128Directives = false;
ZeroDirective = "\t.space\t";
ZeroDirectiveSupportsNonZeroValue = false;
AsciiDirective = nullptr; // not supported
AscizDirective = nullptr; // not supported
ByteListDirective = "\t.byte\t";
PlainStringDirective = "\t.string\t";
CharacterLiteralSyntax = ACLS_SingleQuotePrefix;
// Use .vbyte for data definition to avoid directives that apply an implicit
@ -53,7 +41,6 @@ MCAsmInfoXCOFF::MCAsmInfoXCOFF() {
LCOMMDirectiveAlignmentType = LCOMM::Log2Alignment;
HasDotTypeDotSizeDirective = false;
ParseInlineAsmUsingAsmParser = true;
NeedsFunctionDescriptors = true;
ExceptionsType = ExceptionHandling::AIX;
}

View File

@ -1219,7 +1219,7 @@ static void PrintByteList(StringRef Data, raw_ostream &OS,
void MCAsmStreamer::PrintQuotedString(StringRef Data, raw_ostream &OS) const {
OS << '"';
if (MAI->hasPairedDoubleQuoteStringConstants()) {
if (MAI->isAIX()) {
for (unsigned char C : Data) {
if (C == '"')
OS << "\"\"";
@ -1273,6 +1273,25 @@ void MCAsmStreamer::emitBytes(StringRef Data) {
if (Data.empty()) return;
const auto emitAsString = [this](StringRef Data) {
if (MAI->isAIX()) {
if (isPrintableString(Data)) {
// For target with DoubleQuoteString constants, .string and .byte are
// used as replacement of .asciz and .ascii.
if (Data.back() == 0) {
OS << "\t.string\t";
Data = Data.substr(0, Data.size() - 1);
} else {
OS << "\t.byte\t";
}
PrintQuotedString(Data, OS);
} else {
OS << "\t.byte\t";
PrintByteList(Data, OS, MAI->characterLiteralSyntax());
}
EmitEOL();
return true;
}
// If the data ends with 0 and the target supports .asciz, use it, otherwise
// use .ascii or a byte-list directive
if (MAI->getAscizDirective() && Data.back() == 0) {
@ -1280,27 +1299,6 @@ void MCAsmStreamer::emitBytes(StringRef Data) {
Data = Data.substr(0, Data.size() - 1);
} else if (LLVM_LIKELY(MAI->getAsciiDirective())) {
OS << MAI->getAsciiDirective();
} else if (MAI->hasPairedDoubleQuoteStringConstants() &&
isPrintableString(Data)) {
// For target with DoubleQuoteString constants, .string and .byte are used
// as replacement of .asciz and .ascii.
assert(MAI->getPlainStringDirective() &&
"hasPairedDoubleQuoteStringConstants target must support "
"PlainString Directive");
assert(MAI->getByteListDirective() &&
"hasPairedDoubleQuoteStringConstants target must support ByteList "
"Directive");
if (Data.back() == 0) {
OS << MAI->getPlainStringDirective();
Data = Data.substr(0, Data.size() - 1);
} else {
OS << MAI->getByteListDirective();
}
} else if (MAI->getByteListDirective()) {
OS << MAI->getByteListDirective();
PrintByteList(Data, OS, MAI->characterLiteralSyntax());
EmitEOL();
return true;
} else {
return false;
}
@ -1483,7 +1481,7 @@ void MCAsmStreamer::emitFill(const MCExpr &NumBytes, uint64_t FillValue,
return;
if (const char *ZeroDirective = MAI->getZeroDirective()) {
if (MAI->doesZeroDirectiveSupportNonZeroValue() || FillValue == 0) {
if (!MAI->isAIX() || FillValue == 0) {
// FIXME: Emit location directives
OS << ZeroDirective;
NumBytes.print(OS, MAI);
@ -1519,7 +1517,7 @@ void MCAsmStreamer::emitAlignmentDirective(uint64_t ByteAlignment,
std::optional<int64_t> Value,
unsigned ValueSize,
unsigned MaxBytesToEmit) {
if (MAI->useDotAlignForAlignment()) {
if (MAI->isAIX()) {
if (!isPowerOf2_64(ByteAlignment))
report_fatal_error("Only power-of-two alignments are supported "
"with .align.");
@ -1623,7 +1621,7 @@ void MCAsmStreamer::emitFileDirective(StringRef Filename,
StringRef CompilerVersion,
StringRef TimeStamp,
StringRef Description) {
assert(MAI->hasFourStringsDotFile());
assert(MAI->isAIX());
OS << "\t.file\t";
PrintQuotedString(Filename, OS);
bool useTimeStamp = !TimeStamp.empty();
@ -1694,8 +1692,7 @@ Expected<unsigned> MCAsmStreamer::tryEmitDwarfFileDirective(
// Return early if this file is already emitted before or if target doesn't
// support .file directive.
if (NumFiles == Table.getMCDwarfFiles().size() ||
!MAI->usesDwarfFileAndLocDirectives())
if (NumFiles == Table.getMCDwarfFiles().size() || MAI->isAIX())
return FileNo;
SmallString<128> Str;
@ -1724,7 +1721,7 @@ void MCAsmStreamer::emitDwarfFile0Directive(
Source);
// Target doesn't support .loc/.file directives, return early.
if (!MAI->usesDwarfFileAndLocDirectives())
if (MAI->isAIX())
return;
SmallString<128> Str;
@ -1744,7 +1741,7 @@ void MCAsmStreamer::emitDwarfLocDirective(unsigned FileNo, unsigned Line,
StringRef FileName) {
// If target doesn't support .loc/.file directive, we need to record the lines
// same way like we do in object mode.
if (!MAI->usesDwarfFileAndLocDirectives()) {
if (MAI->isAIX()) {
// In case we see two .loc directives in a row, make sure the
// first one gets a line entry.
MCDwarfLineEntry::make(this, getCurrentSectionOnly());
@ -2444,7 +2441,7 @@ void MCAsmStreamer::AddEncodingComment(const MCInst &Inst,
void MCAsmStreamer::emitInstruction(const MCInst &Inst,
const MCSubtargetInfo &STI) {
if (!MAI->usesDwarfFileAndLocDirectives() && CurFrag)
if (MAI->isAIX() && CurFrag)
// Now that a machine instruction has been assembled into this section, make
// a line entry for any .loc directive that has been seen.
MCDwarfLineEntry::make(this, getCurrentSectionOnly());
@ -2547,7 +2544,7 @@ void MCAsmStreamer::finishImpl() {
// Now it is time to emit debug line sections if target doesn't support .loc
// and .line directives.
if (!MAI->usesDwarfFileAndLocDirectives()) {
if (MAI->isAIX()) {
MCDwarfLineTable::emit(this, getAssembler().getDWARFLinetableParams());
return;
}
@ -2572,7 +2569,7 @@ void MCAsmStreamer::emitDwarfUnitLength(uint64_t Length, const Twine &Comment) {
// the debug section headers. In such cases, any label we placed occurs
// after the implied length field. We need to adjust the reference here
// to account for the offset introduced by the inserted length field.
if (!MAI->needsDwarfSectionSizeInHeader())
if (MAI->isAIX())
return;
MCStreamer::emitDwarfUnitLength(Length, Comment);
}
@ -2585,7 +2582,7 @@ MCSymbol *MCAsmStreamer::emitDwarfUnitLength(const Twine &Prefix,
// the debug section headers. In such cases, any label we placed occurs
// after the implied length field. We need to adjust the reference here
// to account for the offset introduced by the inserted length field.
if (!MAI->needsDwarfSectionSizeInHeader())
if (MAI->isAIX())
return getContext().createTempSymbol(Prefix + "_end");
return MCStreamer::emitDwarfUnitLength(Prefix, Comment);
}
@ -2598,7 +2595,7 @@ void MCAsmStreamer::emitDwarfLineStartLabel(MCSymbol *StartSym) {
// after the implied length field. We need to adjust the reference here
// to account for the offset introduced by the inserted length field.
MCContext &Ctx = getContext();
if (!MAI->needsDwarfSectionSizeInHeader()) {
if (MAI->isAIX()) {
MCSymbol *DebugLineSymTmp = Ctx.createTempSymbol("debug_line_");
// Emit the symbol which does not contain the unit length field.
emitLabel(DebugLineSymTmp);
@ -2625,7 +2622,7 @@ void MCAsmStreamer::emitDwarfLineEndEntry(MCSection *Section,
// we currently use the .text end label as any section end. This will not
// impact the debugability as we will jump to the caller of the last function
// in the section before we come into the .text end address.
assert(!MAI->usesDwarfFileAndLocDirectives() &&
assert(MAI->isAIX() &&
".loc should not be generated together with raw data!");
MCContext &Ctx = getContext();
@ -2648,7 +2645,7 @@ void MCAsmStreamer::emitDwarfAdvanceLineAddr(int64_t LineDelta,
const MCSymbol *LastLabel,
const MCSymbol *Label,
unsigned PointerSize) {
assert(!MAI->usesDwarfFileAndLocDirectives() &&
assert(MAI->isAIX() &&
".loc/.file don't need raw data in debug line section!");
// Set to new address.
@ -2685,9 +2682,7 @@ void MCAsmStreamer::emitDwarfAdvanceLineAddr(int64_t LineDelta,
void MCAsmStreamer::doFinalizationAtSectionEnd(MCSection *Section) {
// Emit section end. This is used to tell the debug line section where the end
// is for a text section if we don't use .loc to represent the debug line.
if (MAI->usesDwarfFileAndLocDirectives())
return;
assert(MAI->isAIX());
switchSectionNoPrint(Section);
MCSymbol *Sym = getCurrentSectionOnly()->getEndSymbol(getContext());

View File

@ -2230,10 +2230,6 @@ void PPCLinuxAsmPrinter::emitFunctionBodyEnd() {
void PPCAIXAsmPrinter::emitLinkage(const GlobalValue *GV,
MCSymbol *GVSym) const {
assert(MAI->hasVisibilityOnlyWithLinkage() &&
"AIX's linkage directives take a visibility setting.");
MCSymbolAttr LinkageAttr = MCSA_Invalid;
switch (GV->getLinkage()) {
case GlobalValue::ExternalLinkage:
@ -3251,7 +3247,7 @@ void PPCAIXAsmPrinter::emitInstruction(const MachineInstr *MI) {
bool PPCAIXAsmPrinter::doFinalization(Module &M) {
// Do streamer related finalization for DWARF.
if (!MAI->usesDwarfFileAndLocDirectives() && hasDebugInfo())
if (hasDebugInfo())
OutStreamer->doFinalizationAtSectionEnd(
OutStreamer->getContext().getObjectFileInfo()->getTextSection());