mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-26 10:29:36 +00:00
Fix alignment of .comm and .lcomm on mingw32.
For some reason .lcomm uses byte alignment and .comm log2 alignment so we can't use the same setting for both. Fix this by reintroducing the LCOMM enum. I verified this against mingw's gcc. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163420 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
b72a90e05b
commit
a9e37c5eaf
@ -32,6 +32,10 @@ namespace llvm {
|
||||
enum ExceptionsType { None, DwarfCFI, SjLj, ARM, Win64 };
|
||||
}
|
||||
|
||||
namespace LCOMM {
|
||||
enum LCOMMType { NoAlignment, ByteAlignment, Log2Alignment };
|
||||
}
|
||||
|
||||
/// MCAsmInfo - This class is intended to be used as a base class for asm
|
||||
/// properties and features specific to the target.
|
||||
class MCAsmInfo {
|
||||
@ -247,9 +251,9 @@ namespace llvm {
|
||||
/// 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.
|
||||
/// LCOMMDirectiveAlignment - Describes if the .lcomm directive for the
|
||||
/// target supports an alignment argument and how it is interpreted.
|
||||
LCOMM::LCOMMType LCOMMDirectiveAlignmentType; // Defaults to NoAlignment.
|
||||
|
||||
/// HasDotTypeDotSizeDirective - True if the target has .type and .size
|
||||
/// directives, this is true for most ELF targets.
|
||||
@ -495,8 +499,8 @@ namespace llvm {
|
||||
bool getCOMMDirectiveAlignmentIsInBytes() const {
|
||||
return COMMDirectiveAlignmentIsInBytes;
|
||||
}
|
||||
bool getLCOMMDirectiveSupportsAlignment() const {
|
||||
return LCOMMDirectiveSupportsAlignment;
|
||||
LCOMM::LCOMMType getLCOMMDirectiveAlignmentType() const {
|
||||
return LCOMMDirectiveAlignmentType;
|
||||
}
|
||||
bool hasDotTypeDotSizeDirective() const {return HasDotTypeDotSizeDirective;}
|
||||
bool hasSingleParameterDotFile() const { return HasSingleParameterDotFile; }
|
||||
|
@ -312,7 +312,8 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Align == 1 || MAI->getLCOMMDirectiveSupportsAlignment()) {
|
||||
if (Align == 1 ||
|
||||
MAI->getLCOMMDirectiveAlignmentType() != LCOMM::NoAlignment) {
|
||||
// .lcomm _foo, 42
|
||||
OutStreamer.EmitLocalCommonSymbol(GVSym, Size, Align);
|
||||
return;
|
||||
|
@ -69,7 +69,7 @@ MCAsmInfo::MCAsmInfo() {
|
||||
HasSetDirective = true;
|
||||
HasAggressiveSymbolFolding = true;
|
||||
COMMDirectiveAlignmentIsInBytes = true;
|
||||
LCOMMDirectiveSupportsAlignment = false;
|
||||
LCOMMDirectiveAlignmentType = LCOMM::NoAlignment;
|
||||
HasDotTypeDotSizeDirective = true;
|
||||
HasSingleParameterDotFile = true;
|
||||
HasNoDeadStrip = false;
|
||||
|
@ -19,8 +19,10 @@ void MCAsmInfoCOFF::anchor() { }
|
||||
|
||||
MCAsmInfoCOFF::MCAsmInfoCOFF() {
|
||||
GlobalPrefix = "_";
|
||||
COMMDirectiveAlignmentIsInBytes = true;
|
||||
LCOMMDirectiveSupportsAlignment = true;
|
||||
// MingW 4.5 and later support .comm with log2 alignment, but .lcomm uses byte
|
||||
// alignment.
|
||||
COMMDirectiveAlignmentIsInBytes = false;
|
||||
LCOMMDirectiveAlignmentType = LCOMM::ByteAlignment;
|
||||
HasDotTypeDotSizeDirective = false;
|
||||
HasSingleParameterDotFile = false;
|
||||
PrivateGlobalPrefix = "L"; // Prefix for private global symbols
|
||||
|
@ -32,7 +32,7 @@ MCAsmInfoDarwin::MCAsmInfoDarwin() {
|
||||
|
||||
AlignmentIsInBytes = false;
|
||||
COMMDirectiveAlignmentIsInBytes = false;
|
||||
LCOMMDirectiveSupportsAlignment = true;
|
||||
LCOMMDirectiveAlignmentType = LCOMM::Log2Alignment;
|
||||
InlineAsmStart = " InlineAsm Start";
|
||||
InlineAsmEnd = " InlineAsm End";
|
||||
|
||||
|
@ -519,13 +519,16 @@ void MCAsmStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
|
||||
unsigned ByteAlign) {
|
||||
OS << "\t.lcomm\t" << *Symbol << ',' << Size;
|
||||
if (ByteAlign > 1) {
|
||||
assert(MAI.getLCOMMDirectiveSupportsAlignment() &&
|
||||
"alignment not supported on .lcomm!");
|
||||
if (MAI.getCOMMDirectiveAlignmentIsInBytes()) {
|
||||
switch (MAI.getLCOMMDirectiveAlignmentType()) {
|
||||
case LCOMM::NoAlignment:
|
||||
llvm_unreachable("alignment not supported on .lcomm!");
|
||||
case LCOMM::ByteAlignment:
|
||||
OS << ',' << ByteAlign;
|
||||
} else {
|
||||
break;
|
||||
case LCOMM::Log2Alignment:
|
||||
assert(isPowerOf2_32(ByteAlign) && "alignment must be a power of 2");
|
||||
OS << ',' << Log2_32(ByteAlign);
|
||||
break;
|
||||
}
|
||||
}
|
||||
EmitEOL();
|
||||
|
@ -2280,11 +2280,13 @@ bool AsmParser::ParseDirectiveComm(bool IsLocal) {
|
||||
if (ParseAbsoluteExpression(Pow2Alignment))
|
||||
return true;
|
||||
|
||||
if (IsLocal && !Lexer.getMAI().getLCOMMDirectiveSupportsAlignment())
|
||||
LCOMM::LCOMMType LCOMM = Lexer.getMAI().getLCOMMDirectiveAlignmentType();
|
||||
if (IsLocal && LCOMM == LCOMM::NoAlignment)
|
||||
return Error(Pow2AlignmentLoc, "alignment not supported on this target");
|
||||
|
||||
// If this target takes alignments in bytes (not log) validate and convert.
|
||||
if (Lexer.getMAI().getCOMMDirectiveAlignmentIsInBytes()) {
|
||||
if ((!IsLocal && Lexer.getMAI().getCOMMDirectiveAlignmentIsInBytes()) ||
|
||||
(IsLocal && LCOMM == LCOMM::ByteAlignment)) {
|
||||
if (!isPowerOf2_64(Pow2Alignment))
|
||||
return Error(Pow2AlignmentLoc, "alignment must be a power of 2");
|
||||
Pow2Alignment = Log2_64(Pow2Alignment);
|
||||
|
@ -24,7 +24,7 @@ HexagonMCAsmInfo::HexagonMCAsmInfo(const Target &T, StringRef TT) {
|
||||
HasLEB128 = true;
|
||||
|
||||
PrivateGlobalPrefix = ".L";
|
||||
LCOMMDirectiveSupportsAlignment = true;
|
||||
LCOMMDirectiveAlignmentType = LCOMM::ByteAlignment;
|
||||
InlineAsmStart = "# InlineAsm Start";
|
||||
InlineAsmEnd = "# InlineAsm End";
|
||||
ZeroDirective = "\t.space\t";
|
||||
|
13
test/MC/COFF/comm.ll
Normal file
13
test/MC/COFF/comm.ll
Normal file
@ -0,0 +1,13 @@
|
||||
; RUN: llc -mtriple i386-pc-mingw32 < %s | FileCheck %s
|
||||
|
||||
@a = internal global i8 0, align 1
|
||||
@b = internal global double 0.000000e+00, align 8
|
||||
@c = common global i8 0, align 1
|
||||
@d = common global double 0.000000e+00, align 8
|
||||
|
||||
; .lcomm uses byte alignment
|
||||
; CHECK: .lcomm _a,1
|
||||
; CHECK: .lcomm _b,8,8
|
||||
; .comm uses log2 alignment
|
||||
; CHECK: .comm _c,1,0
|
||||
; CHECK: .comm _d,8,3
|
Loading…
x
Reference in New Issue
Block a user