diff --git a/llvm/include/llvm/MC/MCAsmInfo.h b/llvm/include/llvm/MC/MCAsmInfo.h --- a/llvm/include/llvm/MC/MCAsmInfo.h +++ b/llvm/include/llvm/MC/MCAsmInfo.h @@ -18,6 +18,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/MC/MCDirectives.h" #include "llvm/MC/MCTargetOptions.h" +#include #include namespace llvm { @@ -855,6 +856,9 @@ bool hasMipsExpressions() const { return HasMipsExpressions; } bool needsFunctionDescriptors() const { return NeedsFunctionDescriptors; } bool shouldUseMotorolaIntegers() const { return UseMotorolaIntegers; } + + /// .align 0 may have architecture specific meaning. + virtual void handleAlignmentZero(int64_t *Alignment) const; }; } // end namespace llvm diff --git a/llvm/lib/MC/MCAsmInfo.cpp b/llvm/lib/MC/MCAsmInfo.cpp --- a/llvm/lib/MC/MCAsmInfo.cpp +++ b/llvm/lib/MC/MCAsmInfo.cpp @@ -136,3 +136,8 @@ return SectionName == ".text" || SectionName == ".data" || (SectionName == ".bss" && !usesELFSectionDirectiveForBSS()); } + +void MCAsmInfo::handleAlignmentZero(int64_t *Alignment) const { + assert(*Alignment == 0 && "caller should check that alignment is zero"); + *Alignment = 1; +} diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp --- a/llvm/lib/MC/MCParser/AsmParser.cpp +++ b/llvm/lib/MC/MCParser/AsmParser.cpp @@ -3411,7 +3411,9 @@ bool ReturnVal = false; // Compute alignment in bytes. - if (IsPow2) { + if (Alignment == 0) { + Lexer.getMAI().handleAlignmentZero(&Alignment); + } else if (IsPow2) { // FIXME: Diagnose overflow. if (Alignment >= 32) { ReturnVal |= Error(AlignmentLoc, "invalid alignment value"); @@ -3420,11 +3422,8 @@ Alignment = 1ULL << Alignment; } else { - // Reject alignments that aren't either a power of two or zero, - // for gas compatibility. Alignment of zero is silently rounded - // up to one. - if (Alignment == 0) - Alignment = 1; + // Reject alignments that aren't either a power of two or > 2**32 + // for gas compatibility. if (!isPowerOf2_64(Alignment)) ReturnVal |= Error(AlignmentLoc, "alignment must be a power of 2"); if (!isUInt<32>(Alignment)) diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.h b/llvm/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.h --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.h +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.h @@ -34,6 +34,7 @@ explicit ARMELFMCAsmInfo(const Triple &TT); void setUseIntegratedAssembler(bool Value) override; + void handleAlignmentZero(int64_t *Alignment) const override; }; class ARMCOFFMCAsmInfoMicrosoft : public MCAsmInfoMicrosoft { diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp @@ -83,6 +83,10 @@ } } +void ARMELFMCAsmInfo::handleAlignmentZero(int64_t *Alignment) const { + *Alignment = 4; +} + void ARMCOFFMCAsmInfoMicrosoft::anchor() { } ARMCOFFMCAsmInfoMicrosoft::ARMCOFFMCAsmInfoMicrosoft() { diff --git a/llvm/test/MC/ARM/thumb-text-align0.s b/llvm/test/MC/ARM/thumb-text-align0.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/ARM/thumb-text-align0.s @@ -0,0 +1,21 @@ +@@ Test the default alignment for text sections + +@ RUN: llvm-mc %s -triple=thumbv7-linux-gnueabi -filetype=obj \ +@ RUN: | llvm-readobj -S - | FileCheck %s +@ RUN: llvm-mc %s -triple=armv7-linux-gnueabi -filetype=obj \ +@ RUN: | llvm-readobj -S - | FileCheck %s +.align 0 +mov pc, lr + +@ CHECK: Name: .text (1) +@ CHECK-NEXT: Type: SHT_PROGBITS (0x1) +@ CHECK-NEXT: Flags [ (0x6) +@ CHECK-NEXT: SHF_ALLOC (0x2) +@ CHECK-NEXT: SHF_EXECINSTR (0x4) +@ CHECK-NEXT: ] +@ CHECK-NEXT: Address: 0x0 +@ CHECK-NEXT: Offset: 0x34 +@ CHECK-NEXT: Size: 4 +@ CHECK-NEXT: Link: 0 +@ CHECK-NEXT: Info: 0 +@ CHECK-NEXT: AddressAlignment: 4