diff options
-rw-r--r-- | include/llvm/MC/MCAsmInfo.h | 22 | ||||
-rw-r--r-- | lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 3 | ||||
-rw-r--r-- | lib/MC/MCAsmInfo.cpp | 2 | ||||
-rw-r--r-- | lib/MC/MCAsmInfoCOFF.cpp | 2 | ||||
-rw-r--r-- | lib/MC/MCAsmInfoDarwin.cpp | 1 | ||||
-rw-r--r-- | lib/MC/MCAsmStreamer.cpp | 13 | ||||
-rw-r--r-- | lib/MC/MCMachOStreamer.cpp | 13 | ||||
-rw-r--r-- | lib/MC/MCParser/AsmParser.cpp | 11 | ||||
-rw-r--r-- | lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp | 1 | ||||
-rw-r--r-- | lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.cpp | 2 | ||||
-rw-r--r-- | lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp | 1 | ||||
-rw-r--r-- | test/MC/AsmParser/directive_lcomm.s | 11 | ||||
-rw-r--r-- | test/MC/AsmParser/labels.s | 2 | ||||
-rw-r--r-- | test/MC/ELF/lcomm.s | 21 |
14 files changed, 67 insertions, 38 deletions
diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h index 9f5230b..7370936 100644 --- a/include/llvm/MC/MCAsmInfo.h +++ b/include/llvm/MC/MCAsmInfo.h @@ -32,10 +32,6 @@ namespace llvm { enum ExceptionsType { None, DwarfCFI, SjLj, ARM, Win64 }; } - namespace LCOMM { - enum LCOMMType { None, NoAlignment, ByteAlignment }; - } - /// MCAsmInfo - This class is intended to be used as a base class for asm /// properties and features specific to the target. class MCAsmInfo { @@ -247,14 +243,14 @@ namespace llvm { /// .long a - b bool HasAggressiveSymbolFolding; // Defaults to true. - /// LCOMMDirectiveType - Describes if the target supports the .lcomm - /// directive and whether it has an alignment parameter. - LCOMM::LCOMMType LCOMMDirectiveType; // Defaults to LCOMM::None. - - /// COMMDirectiveAlignmentIsInBytes - True is COMMDirective's optional + /// COMMDirectiveAlignmentIsInBytes - True is .comm's and .lcomms optional /// alignment is to be specified in bytes instead of log2(n). bool COMMDirectiveAlignmentIsInBytes; // Defaults to true; + /// LCOMMDirectiveSupportsAlignment - True if .lcomm supports an optional + /// alignment argument on this target. + bool LCOMMDirectiveSupportsAlignment; // Defaults to false. + /// HasDotTypeDotSizeDirective - True if the target has .type and .size /// directives, this is true for most ELF targets. bool HasDotTypeDotSizeDirective; // Defaults to true. @@ -496,13 +492,13 @@ namespace llvm { bool hasAggressiveSymbolFolding() const { return HasAggressiveSymbolFolding; } - LCOMM::LCOMMType getLCOMMDirectiveType() const { - return LCOMMDirectiveType; - } - bool hasDotTypeDotSizeDirective() const {return HasDotTypeDotSizeDirective;} bool getCOMMDirectiveAlignmentIsInBytes() const { return COMMDirectiveAlignmentIsInBytes; } + bool getLCOMMDirectiveSupportsAlignment() const { + return LCOMMDirectiveSupportsAlignment; + } + bool hasDotTypeDotSizeDirective() const {return HasDotTypeDotSizeDirective;} bool hasSingleParameterDotFile() const { return HasSingleParameterDotFile; } bool hasNoDeadStrip() const { return HasNoDeadStrip; } bool hasSymbolResolver() const { return HasSymbolResolver; } diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index aa5d140..80017c5 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -312,8 +312,7 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) { return; } - if (MAI->getLCOMMDirectiveType() != LCOMM::None && - (MAI->getLCOMMDirectiveType() != LCOMM::NoAlignment || Align == 1)) { + if (Align == 1 || MAI->getLCOMMDirectiveSupportsAlignment()) { // .lcomm _foo, 42 OutStreamer.EmitLocalCommonSymbol(GVSym, Size, Align); return; diff --git a/lib/MC/MCAsmInfo.cpp b/lib/MC/MCAsmInfo.cpp index 8da2e0e..11e368c 100644 --- a/lib/MC/MCAsmInfo.cpp +++ b/lib/MC/MCAsmInfo.cpp @@ -68,8 +68,8 @@ MCAsmInfo::MCAsmInfo() { GlobalDirective = "\t.globl\t"; HasSetDirective = true; HasAggressiveSymbolFolding = true; - LCOMMDirectiveType = LCOMM::None; COMMDirectiveAlignmentIsInBytes = true; + LCOMMDirectiveSupportsAlignment = false; HasDotTypeDotSizeDirective = true; HasSingleParameterDotFile = true; HasNoDeadStrip = false; diff --git a/lib/MC/MCAsmInfoCOFF.cpp b/lib/MC/MCAsmInfoCOFF.cpp index 678e75a..2637be7 100644 --- a/lib/MC/MCAsmInfoCOFF.cpp +++ b/lib/MC/MCAsmInfoCOFF.cpp @@ -20,7 +20,7 @@ void MCAsmInfoCOFF::anchor() { } MCAsmInfoCOFF::MCAsmInfoCOFF() { GlobalPrefix = "_"; COMMDirectiveAlignmentIsInBytes = false; - LCOMMDirectiveType = LCOMM::ByteAlignment; + LCOMMDirectiveSupportsAlignment = true; HasDotTypeDotSizeDirective = false; HasSingleParameterDotFile = false; PrivateGlobalPrefix = "L"; // Prefix for private global symbols diff --git a/lib/MC/MCAsmInfoDarwin.cpp b/lib/MC/MCAsmInfoDarwin.cpp index 8e0ac23..99520d4 100644 --- a/lib/MC/MCAsmInfoDarwin.cpp +++ b/lib/MC/MCAsmInfoDarwin.cpp @@ -32,6 +32,7 @@ MCAsmInfoDarwin::MCAsmInfoDarwin() { AlignmentIsInBytes = false; COMMDirectiveAlignmentIsInBytes = false; + LCOMMDirectiveSupportsAlignment = true; InlineAsmStart = " InlineAsm Start"; InlineAsmEnd = " InlineAsm End"; diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp index 394f049..804e38e 100644 --- a/lib/MC/MCAsmStreamer.cpp +++ b/lib/MC/MCAsmStreamer.cpp @@ -517,13 +517,16 @@ void MCAsmStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, /// @param Size - The size of the common symbol. void MCAsmStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlign) { - assert(MAI.getLCOMMDirectiveType() != LCOMM::None && - "Doesn't have .lcomm, can't emit it!"); OS << "\t.lcomm\t" << *Symbol << ',' << Size; if (ByteAlign > 1) { - assert(MAI.getLCOMMDirectiveType() == LCOMM::ByteAlignment && - "Alignment not supported on .lcomm!"); - OS << ',' << ByteAlign; + assert(MAI.getLCOMMDirectiveSupportsAlignment() && + "alignment not supported on .lcomm!"); + if (MAI.getCOMMDirectiveAlignmentIsInBytes()) { + OS << ',' << ByteAlign; + } else { + assert(isPowerOf2_32(ByteAlign) && "alignment must be a power of 2"); + OS << ',' << Log2_32(ByteAlign); + } } EmitEOL(); } diff --git a/lib/MC/MCMachOStreamer.cpp b/lib/MC/MCMachOStreamer.cpp index b75fe2c..74f6dc6 100644 --- a/lib/MC/MCMachOStreamer.cpp +++ b/lib/MC/MCMachOStreamer.cpp @@ -70,9 +70,7 @@ public: llvm_unreachable("macho doesn't support this directive"); } virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, - unsigned ByteAlignment) { - llvm_unreachable("macho doesn't support this directive"); - } + unsigned ByteAlignment); virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0, uint64_t Size = 0, unsigned ByteAlignment = 0); virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, @@ -325,6 +323,15 @@ void MCMachOStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, SD.setCommon(Size, ByteAlignment); } +void MCMachOStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, + unsigned ByteAlignment) { + // '.lcomm' is equivalent to '.zerofill'. + return EmitZerofill(getContext().getMachOSection("__DATA", "__bss", + MCSectionMachO::S_ZEROFILL, + 0, SectionKind::getBSS()), + Symbol, Size, ByteAlignment); +} + void MCMachOStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment) { MCSectionData &SectData = getAssembler().getOrCreateSectionData(*Section); diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp index d60a270..271fee0 100644 --- a/lib/MC/MCParser/AsmParser.cpp +++ b/lib/MC/MCParser/AsmParser.cpp @@ -2280,8 +2280,11 @@ bool AsmParser::ParseDirectiveComm(bool IsLocal) { if (ParseAbsoluteExpression(Pow2Alignment)) return true; + if (IsLocal && !Lexer.getMAI().getLCOMMDirectiveSupportsAlignment()) + return Error(Pow2AlignmentLoc, "alignment not supported on this target"); + // If this target takes alignments in bytes (not log) validate and convert. - if (Lexer.getMAI().getAlignmentIsInBytes()) { + if (Lexer.getMAI().getCOMMDirectiveAlignmentIsInBytes()) { if (!isPowerOf2_64(Pow2Alignment)) return Error(Pow2AlignmentLoc, "alignment must be a power of 2"); Pow2Alignment = Log2_64(Pow2Alignment); @@ -2309,13 +2312,9 @@ bool AsmParser::ParseDirectiveComm(bool IsLocal) { if (!Sym->isUndefined()) return Error(IDLoc, "invalid symbol redefinition"); - // '.lcomm' is equivalent to '.zerofill'. // Create the Symbol as a common or local common with Size and Pow2Alignment if (IsLocal) { - getStreamer().EmitZerofill(Ctx.getMachOSection( - "__DATA", "__bss", MCSectionMachO::S_ZEROFILL, - 0, SectionKind::getBSS()), - Sym, Size, 1 << Pow2Alignment); + getStreamer().EmitLocalCommonSymbol(Sym, Size, 1 << Pow2Alignment); return false; } diff --git a/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp b/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp index d32805e..c1aab9c 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp @@ -50,7 +50,6 @@ ARMELFMCAsmInfo::ARMELFMCAsmInfo() { Code32Directive = ".code\t32"; WeakRefDirective = "\t.weak\t"; - LCOMMDirectiveType = LCOMM::NoAlignment; HasLEB128 = true; SupportsDebugInformation = true; diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.cpp b/lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.cpp index d6e6c36..ec6b721 100644 --- a/lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.cpp +++ b/lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.cpp @@ -24,7 +24,7 @@ HexagonMCAsmInfo::HexagonMCAsmInfo(const Target &T, StringRef TT) { HasLEB128 = true; PrivateGlobalPrefix = ".L"; - LCOMMDirectiveType = LCOMM::ByteAlignment; + LCOMMDirectiveSupportsAlignment = true; InlineAsmStart = "# InlineAsm Start"; InlineAsmEnd = "# InlineAsm End"; ZeroDirective = "\t.space\t"; diff --git a/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp b/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp index 245b457..b9ea8b5 100644 --- a/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp +++ b/lib/Target/PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp @@ -64,7 +64,6 @@ PPCLinuxMCAsmInfo::PPCLinuxMCAsmInfo(bool is64Bit) { ZeroDirective = "\t.space\t"; Data64bitsDirective = is64Bit ? "\t.quad\t" : 0; - LCOMMDirectiveType = LCOMM::NoAlignment; AssemblerDialect = 0; // Old-Style mnemonics. } diff --git a/test/MC/AsmParser/directive_lcomm.s b/test/MC/AsmParser/directive_lcomm.s index 0a0add5..37a350c 100644 --- a/test/MC/AsmParser/directive_lcomm.s +++ b/test/MC/AsmParser/directive_lcomm.s @@ -1,9 +1,14 @@ # RUN: llvm-mc -triple i386-apple-darwin10 %s | FileCheck %s +# RUN: llvm-mc -triple i386-pc-mingw32 %s | FileCheck %s +# RUN: not llvm-mc -triple i386-linux-gnu %s 2>&1 | FileCheck %s -check-prefix=ERROR # CHECK: TEST0: -# CHECK: .zerofill __DATA,__bss,a,7,4 -# CHECK: .zerofill __DATA,__bss,b,8 -# CHECK: .zerofill __DATA,__bss,c,0 +# CHECK: .lcomm a,7,4 +# CHECK: .lcomm b,8 +# CHECK: .lcomm c,0 + +# ELF doesn't like alignment on .lcomm. +# ERROR: alignment not supported on this target TEST0: .lcomm a, 8-1, 4 .lcomm b,8 diff --git a/test/MC/AsmParser/labels.s b/test/MC/AsmParser/labels.s index 5609175..6a9870b 100644 --- a/test/MC/AsmParser/labels.s +++ b/test/MC/AsmParser/labels.s @@ -41,7 +41,7 @@ foo: // CHECK: .comm "a 6",1 .comm "a 6", 1 -// CHECK: .zerofill __DATA,__bss,"a 7",1,0 +// CHECK: .lcomm "a 7",1 .lcomm "a 7", 1 // FIXME: We don't bother to support .lsym. diff --git a/test/MC/ELF/lcomm.s b/test/MC/ELF/lcomm.s new file mode 100644 index 0000000..ae8d0ba --- /dev/null +++ b/test/MC/ELF/lcomm.s @@ -0,0 +1,21 @@ +// RUN: llvm-mc -triple i386-pc-linux-gnu %s -filetype=obj -o - | elf-dump | FileCheck %s + +.lcomm A, 5 +.lcomm B, 32 << 20 + +// CHECK: (('st_name', 0x00000001) # 'A' +// CHECK: ('st_value', 0x00000000) +// CHECK: ('st_size', 0x00000005) +// CHECK: ('st_bind', 0x0) +// CHECK: ('st_type', 0x1) +// CHECK: ('st_other', 0x00) +// CHECK: ('st_shndx', 0x0003) +// CHECK: ), +// CHECK: (('st_name', 0x00000003) # 'B' +// CHECK: ('st_value', 0x00000005) +// CHECK: ('st_size', 0x02000000) +// CHECK: ('st_bind', 0x0) +// CHECK: ('st_type', 0x1) +// CHECK: ('st_other', 0x00) +// CHECK: ('st_shndx', 0x0003) +// CHECK: ), |