diff options
-rw-r--r-- | include/llvm/MC/MCSection.h | 4 | ||||
-rw-r--r-- | include/llvm/MC/MCSectionCOFF.h | 1 | ||||
-rw-r--r-- | include/llvm/MC/MCSectionELF.h | 3 | ||||
-rw-r--r-- | include/llvm/MC/MCSectionMachO.h | 1 | ||||
-rw-r--r-- | lib/MC/MCParser/AsmParser.cpp | 7 | ||||
-rw-r--r-- | lib/MC/MCSectionCOFF.cpp | 4 | ||||
-rw-r--r-- | lib/MC/MCSectionELF.cpp | 4 | ||||
-rw-r--r-- | lib/MC/MCSectionMachO.cpp | 5 | ||||
-rw-r--r-- | lib/Target/PIC16/PIC16Section.cpp | 4 | ||||
-rw-r--r-- | lib/Target/PIC16/PIC16Section.h | 2 | ||||
-rw-r--r-- | test/MC/COFF/align-nops.s | 45 | ||||
-rw-r--r-- | test/MC/COFF/dg.exp | 2 | ||||
-rw-r--r-- | test/MC/ELF/align-nops.s | 40 |
13 files changed, 113 insertions, 9 deletions
diff --git a/include/llvm/MC/MCSection.h b/include/llvm/MC/MCSection.h index 5c99735..3e5b5f1 100644 --- a/include/llvm/MC/MCSection.h +++ b/include/llvm/MC/MCSection.h @@ -61,6 +61,10 @@ namespace llvm { return false; } + // UseCodeAlign - Return true if a .align directive should use + // "optimized nops" to fill instead of 0s. + virtual bool UseCodeAlign() const = 0; + static bool classof(const MCSection *) { return true; } }; diff --git a/include/llvm/MC/MCSectionCOFF.h b/include/llvm/MC/MCSectionCOFF.h index f828e10..62d07cf 100644 --- a/include/llvm/MC/MCSectionCOFF.h +++ b/include/llvm/MC/MCSectionCOFF.h @@ -55,6 +55,7 @@ namespace llvm { virtual void PrintSwitchToSection(const MCAsmInfo &MAI, raw_ostream &OS) const; + virtual bool UseCodeAlign() const; static bool classof(const MCSection *S) { return S->getVariant() == SV_COFF; diff --git a/include/llvm/MC/MCSectionELF.h b/include/llvm/MC/MCSectionELF.h index f97ab16..a92d0f2 100644 --- a/include/llvm/MC/MCSectionELF.h +++ b/include/llvm/MC/MCSectionELF.h @@ -178,7 +178,8 @@ public: void PrintSwitchToSection(const MCAsmInfo &MAI, raw_ostream &OS) const; - + virtual bool UseCodeAlign() const; + /// isBaseAddressKnownZero - We know that non-allocatable sections (like /// debug info) have a base of zero. virtual bool isBaseAddressKnownZero() const { diff --git a/include/llvm/MC/MCSectionMachO.h b/include/llvm/MC/MCSectionMachO.h index 2d9d133..19d003a 100644 --- a/include/llvm/MC/MCSectionMachO.h +++ b/include/llvm/MC/MCSectionMachO.h @@ -165,6 +165,7 @@ public: virtual void PrintSwitchToSection(const MCAsmInfo &MAI, raw_ostream &OS) const; + virtual bool UseCodeAlign() const; static bool classof(const MCSection *S) { return S->getVariant() == SV_MachO; diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp index fbac34a..688827d 100644 --- a/lib/MC/MCParser/AsmParser.cpp +++ b/lib/MC/MCParser/AsmParser.cpp @@ -1654,12 +1654,7 @@ bool AsmParser::ParseDirectiveAlign(bool IsPow2, unsigned ValueSize) { // Check whether we should use optimal code alignment for this .align // directive. - // - // FIXME: This should be using a target hook. - bool UseCodeAlign = false; - if (const MCSectionMachO *S = dyn_cast<MCSectionMachO>( - getStreamer().getCurrentSection())) - UseCodeAlign = S->hasAttribute(MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS); + bool UseCodeAlign = getStreamer().getCurrentSection()->UseCodeAlign(); if ((!HasFillExpr || Lexer.getMAI().getTextAlignFillValue() == FillExpr) && ValueSize == 1 && UseCodeAlign) { getStreamer().EmitCodeAlignment(Alignment, MaxBytesToFill); diff --git a/lib/MC/MCSectionCOFF.cpp b/lib/MC/MCSectionCOFF.cpp index eb53160..0909df4 100644 --- a/lib/MC/MCSectionCOFF.cpp +++ b/lib/MC/MCSectionCOFF.cpp @@ -74,3 +74,7 @@ void MCSectionCOFF::PrintSwitchToSection(const MCAsmInfo &MAI, } } } + +bool MCSectionCOFF::UseCodeAlign() const { + return getKind().isText(); +} diff --git a/lib/MC/MCSectionELF.cpp b/lib/MC/MCSectionELF.cpp index ef935d0..133cad1 100644 --- a/lib/MC/MCSectionELF.cpp +++ b/lib/MC/MCSectionELF.cpp @@ -112,6 +112,10 @@ void MCSectionELF::PrintSwitchToSection(const MCAsmInfo &MAI, OS << '\n'; } +bool MCSectionELF::UseCodeAlign() const { + return getFlags() & MCSectionELF::SHF_EXECINSTR; +} + // HasCommonSymbols - True if this section holds common symbols, this is // indicated on the ELF object file by a symbol with SHN_COMMON section // header index. diff --git a/lib/MC/MCSectionMachO.cpp b/lib/MC/MCSectionMachO.cpp index ded3b20..12b3efe 100644 --- a/lib/MC/MCSectionMachO.cpp +++ b/lib/MC/MCSectionMachO.cpp @@ -148,6 +148,10 @@ void MCSectionMachO::PrintSwitchToSection(const MCAsmInfo &MAI, OS << '\n'; } +bool MCSectionMachO::UseCodeAlign() const { + return hasAttribute(MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS); +} + /// StripSpaces - This removes leading and trailing spaces from the StringRef. static void StripSpaces(StringRef &Str) { while (!Str.empty() && isspace(Str[0])) @@ -283,4 +287,3 @@ std::string MCSectionMachO::ParseSectionSpecifier(StringRef Spec, // In. return ""; } - diff --git a/lib/Target/PIC16/PIC16Section.cpp b/lib/Target/PIC16/PIC16Section.cpp index 2505b11..7664fbb 100644 --- a/lib/Target/PIC16/PIC16Section.cpp +++ b/lib/Target/PIC16/PIC16Section.cpp @@ -102,3 +102,7 @@ void PIC16Section::PrintSwitchToSection(const MCAsmInfo &MAI, OS << '\n'; } + +bool PIC16Section::UseCodeAlign() const { + return isCODE_Type(); +} diff --git a/lib/Target/PIC16/PIC16Section.h b/lib/Target/PIC16/PIC16Section.h index 5b33b51..98e5902 100644 --- a/lib/Target/PIC16/PIC16Section.h +++ b/lib/Target/PIC16/PIC16Section.h @@ -88,6 +88,8 @@ namespace llvm { virtual void PrintSwitchToSection(const MCAsmInfo &MAI, raw_ostream &OS) const; + virtual bool UseCodeAlign() const; + static bool classof(const MCSection *S) { return S->getVariant() == SV_PIC16; } diff --git a/test/MC/COFF/align-nops.s b/test/MC/COFF/align-nops.s new file mode 100644 index 0000000..f190fdb --- /dev/null +++ b/test/MC/COFF/align-nops.s @@ -0,0 +1,45 @@ +// RUN: llvm-mc -filetype=obj -triple i686-pc-win32 %s -o %t +// RUN: coff-dump.py %abs_tmp | FileCheck %s + +// Test that we get optimal nops in text + .text +f0: + .long 0 + .align 8, 0x90 + .long 0 + .align 8 + +// But not in another section + .data + .long 0 + .align 8, 0x90 + .long 0 + .align 8 + +//CHECK: Name = .text +//CHECK-NEXT: VirtualSize +//CHECK-NEXT: VirtualAddress +//CHECK-NEXT: SizeOfRawData = 16 +//CHECK-NEXT: PointerToRawData +//CHECK-NEXT: PointerToRelocations +//CHECK-NEXT: PointerToLineNumbers +//CHECK-NEXT: NumberOfRelocations +//CHECK-NEXT: NumberOfLineNumbers +//CHECK-NEXT: Charateristics = 0x400001 +//CHECK-NEXT: IMAGE_SCN_ALIGN_8BYTES +//CHECK-NEXT: SectionData = +//CHECK-NEXT: 00 00 00 00 0F 1F 40 00 - 00 00 00 00 0F 1F 40 00 + +//CHECK: Name = .data +//CHECK-NEXT: VirtualSize +//CHECK-NEXT: VirtualAddress +//CHECK-NEXT: SizeOfRawData = 16 +//CHECK-NEXT: PointerToRawData +//CHECK-NEXT: PointerToRelocations +//CHECK-NEXT: PointerToLineNumbers +//CHECK-NEXT: NumberOfRelocations +//CHECK-NEXT: NumberOfLineNumbers +//CHECK-NEXT: Charateristics = 0x400001 +//CHECK-NEXT: IMAGE_SCN_ALIGN_8BYTES +//CHECK-NEXT: SectionData = +//CHECK-NEXT: 00 00 00 00 90 90 90 90 - 00 00 00 00 00 00 00 00 diff --git a/test/MC/COFF/dg.exp b/test/MC/COFF/dg.exp index 7b7bd4e..d46d700 100644 --- a/test/MC/COFF/dg.exp +++ b/test/MC/COFF/dg.exp @@ -1,5 +1,5 @@ load_lib llvm.exp if { [llvm_supports_target X86] } { - RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll}]] + RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,s}]] } diff --git a/test/MC/ELF/align-nops.s b/test/MC/ELF/align-nops.s new file mode 100644 index 0000000..b6793ec --- /dev/null +++ b/test/MC/ELF/align-nops.s @@ -0,0 +1,40 @@ +// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - | elf-dump --dump-section-data | FileCheck %s + +// Test that we get optimal nops in text + .text +f0: + .long 0 + .align 8, 0x90 + .long 0 + .align 8 + +// But not in another section + .data + .long 0 + .align 8, 0x90 + .long 0 + .align 8 + +// CHECK: (('sh_name', 1) # '.text' +// CHECK-NEXT: ('sh_type', 1) +// CHECK-NEXT: ('sh_flags', 6) +// CHECK-NEXT: ('sh_addr', +// CHECK-NEXT: ('sh_offset', +// CHECK-NEXT: ('sh_size', 16) +// CHECK-NEXT: ('sh_link', 0) +// CHECK-NEXT: ('sh_info', 0) +// CHECK-NEXT: ('sh_addralign', 8) +// CHECK-NEXT: ('sh_entsize', 0) +// CHECK-NEXT: ('_section_data', '00000000 0f1f4000 00000000 0f1f4000') + +// CHECK: (('sh_name', 7) # '.data' +// CHECK-NEXT: ('sh_type', 1) +// CHECK-NEXT: ('sh_flags', 3) +// CHECK-NEXT: ('sh_addr', +// CHECK-NEXT: ('sh_offset', +// CHECK-NEXT: ('sh_size', 16) +// CHECK-NEXT: ('sh_link', 0) +// CHECK-NEXT: ('sh_info', 0) +// CHECK-NEXT: ('sh_addralign', 8) +// CHECK-NEXT: ('sh_entsize', 0) +// CHECK-NEXT: ('_section_data', '00000000 90909090 00000000 00000000') |