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 {
/// 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.
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; }
return;
}
- if (Align == 1 || MAI->getLCOMMDirectiveSupportsAlignment()) {
+ if (Align == 1 ||
+ MAI->getLCOMMDirectiveAlignmentType() != LCOMM::NoAlignment) {
// .lcomm _foo, 42
OutStreamer.EmitLocalCommonSymbol(GVSym, Size, Align);
return;
HasSetDirective = true;
HasAggressiveSymbolFolding = true;
COMMDirectiveAlignmentIsInBytes = true;
- LCOMMDirectiveSupportsAlignment = false;
+ LCOMMDirectiveAlignmentType = LCOMM::NoAlignment;
HasDotTypeDotSizeDirective = true;
HasSingleParameterDotFile = true;
HasNoDeadStrip = false;
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
AlignmentIsInBytes = false;
COMMDirectiveAlignmentIsInBytes = false;
- LCOMMDirectiveSupportsAlignment = true;
+ LCOMMDirectiveAlignmentType = LCOMM::Log2Alignment;
InlineAsmStart = " InlineAsm Start";
InlineAsmEnd = " InlineAsm End";
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();
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);
HasLEB128 = true;
PrivateGlobalPrefix = ".L";
- LCOMMDirectiveSupportsAlignment = true;
+ LCOMMDirectiveAlignmentType = LCOMM::ByteAlignment;
InlineAsmStart = "# InlineAsm Start";
InlineAsmEnd = "# InlineAsm End";
ZeroDirective = "\t.space\t";
--- /dev/null
+; 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