diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2010-09-11 16:45:15 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2010-09-11 16:45:15 +0000 |
commit | b98ac2a71e55e685efa0fdbebdffb5228f7a512d (patch) | |
tree | f465f442732805a1655aa054451bd778d9105e29 | |
parent | dfa3c9d98260f899297c11cda2b15dc44fc4f91e (diff) |
Add support for leb128 of absolute expressions.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@113691 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/MC/MCParser/AsmParser.cpp | 49 | ||||
-rw-r--r-- | lib/MC/MCParser/ELFAsmParser.cpp | 23 | ||||
-rw-r--r-- | test/MC/ELF/dg.exp | 2 | ||||
-rw-r--r-- | test/MC/ELF/sleb.s | 29 | ||||
-rw-r--r-- | test/MC/ELF/uleb.s | 22 |
5 files changed, 101 insertions, 24 deletions
diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp index 0a664fd876..5ef6f682bf 100644 --- a/lib/MC/MCParser/AsmParser.cpp +++ b/lib/MC/MCParser/AsmParser.cpp @@ -238,6 +238,9 @@ public: AddDirectiveHandler<&GenericAsmParser::ParseDirectiveMacro>(".macro"); AddDirectiveHandler<&GenericAsmParser::ParseDirectiveEndMacro>(".endm"); AddDirectiveHandler<&GenericAsmParser::ParseDirectiveEndMacro>(".endmacro"); + + AddDirectiveHandler<&GenericAsmParser::ParseDirectiveLEB128>(".sleb128"); + AddDirectiveHandler<&GenericAsmParser::ParseDirectiveLEB128>(".uleb128"); } bool ParseDirectiveFile(StringRef, SMLoc DirectiveLoc); @@ -247,6 +250,10 @@ public: bool ParseDirectiveMacrosOnOff(StringRef, SMLoc DirectiveLoc); bool ParseDirectiveMacro(StringRef, SMLoc DirectiveLoc); bool ParseDirectiveEndMacro(StringRef, SMLoc DirectiveLoc); + + void ParseUleb128(uint64_t Value); + void ParseSleb128(int64_t Value); + bool ParseDirectiveLEB128(StringRef, SMLoc); }; } @@ -2049,6 +2056,48 @@ bool GenericAsmParser::ParseDirectiveEndMacro(StringRef Directive, "no current macro definition"); } +void GenericAsmParser::ParseUleb128(uint64_t Value) { + const uint64_t Mask = (1 << 7) - 1; + do { + unsigned Byte = Value & Mask; + Value >>= 7; + if (Value) // Not the last one + Byte |= (1 << 7); + getStreamer().EmitIntValue(Byte, 1, DEFAULT_ADDRSPACE); + } while (Value); +} + +void GenericAsmParser::ParseSleb128(int64_t Value) { + const int64_t Mask = (1 << 7) - 1; + for(;;) { + unsigned Byte = Value & Mask; + Value >>= 7; + bool Done = ((Value == 0 && (Byte & 0x40) == 0) || + (Value == -1 && (Byte & 0x40) != 0)); + if (!Done) + Byte |= (1 << 7); + getStreamer().EmitIntValue(Byte, 1, DEFAULT_ADDRSPACE); + if (Done) + break; + } +} + +bool GenericAsmParser::ParseDirectiveLEB128(StringRef DirName, SMLoc) { + int64_t Value; + if (getParser().ParseAbsoluteExpression(Value)) + return true; + + if (getLexer().isNot(AsmToken::EndOfStatement)) + return TokError("unexpected token in directive"); + + if (DirName[1] == 's') + ParseSleb128(Value); + else + ParseUleb128(Value); + return false; +} + + /// \brief Create an MCAsmParser instance. MCAsmParser *llvm::createMCAsmParser(const Target &T, SourceMgr &SM, MCContext &C, MCStreamer &Out, diff --git a/lib/MC/MCParser/ELFAsmParser.cpp b/lib/MC/MCParser/ELFAsmParser.cpp index f982fdaecb..38288d78b0 100644 --- a/lib/MC/MCParser/ELFAsmParser.cpp +++ b/lib/MC/MCParser/ELFAsmParser.cpp @@ -48,8 +48,6 @@ public: AddDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveEhFrame>(".eh_frame"); AddDirectiveHandler<&ELFAsmParser::ParseDirectiveSection>(".section"); AddDirectiveHandler<&ELFAsmParser::ParseDirectiveSize>(".size"); - AddDirectiveHandler<&ELFAsmParser::ParseDirectiveLEB128>(".sleb128"); - AddDirectiveHandler<&ELFAsmParser::ParseDirectiveLEB128>(".uleb128"); AddDirectiveHandler<&ELFAsmParser::ParseDirectivePrevious>(".previous"); } @@ -109,7 +107,6 @@ public: MCSectionELF::SHF_WRITE, SectionKind::getDataRel()); } - bool ParseDirectiveLEB128(StringRef, SMLoc); bool ParseDirectiveSection(StringRef, SMLoc); bool ParseDirectiveSize(StringRef, SMLoc); bool ParseDirectivePrevious(StringRef, SMLoc); @@ -254,26 +251,6 @@ bool ELFAsmParser::ParseDirectiveSection(StringRef, SMLoc) { return false; } -bool ELFAsmParser::ParseDirectiveLEB128(StringRef DirName, SMLoc) { - int64_t Value; - if (getParser().ParseAbsoluteExpression(Value)) - return true; - - if (getLexer().isNot(AsmToken::EndOfStatement)) - return TokError("unexpected token in directive"); - - // FIXME: Add proper MC support. - if (getContext().getAsmInfo().hasLEB128()) { - if (DirName[1] == 's') - getStreamer().EmitRawText("\t.sleb128\t" + Twine(Value)); - else - getStreamer().EmitRawText("\t.uleb128\t" + Twine(Value)); - return false; - } - // FIXME: This shouldn't be an error! - return TokError("LEB128 not supported yet"); -} - bool ELFAsmParser::ParseDirectivePrevious(StringRef DirName, SMLoc) { const MCSection *PreviousSection = getStreamer().getPreviousSection(); if (PreviousSection != NULL) diff --git a/test/MC/ELF/dg.exp b/test/MC/ELF/dg.exp index 7b7bd4e738..d46d700975 100644 --- a/test/MC/ELF/dg.exp +++ b/test/MC/ELF/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/sleb.s b/test/MC/ELF/sleb.s new file mode 100644 index 0000000000..ed656b6755 --- /dev/null +++ b/test/MC/ELF/sleb.s @@ -0,0 +1,29 @@ +// RUN: llvm-mc -filetype=obj -triple i686-pc-linux-gnu -n %s -o - | elf-dump --dump-section-data | FileCheck -check-prefix=ELF_32 %s +// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu -n %s -o - | elf-dump --dump-section-data | FileCheck -check-prefix=ELF_64 %s +// RUN: llvm-mc -filetype=obj -triple i386-apple-darwin9 %s -o - | macho-dump --dump-section-data | FileCheck -check-prefix=MACHO_32 %s +// RUN: llvm-mc -filetype=obj -triple x86_64-apple-darwin9 %s -o - | macho-dump --dump-section-data | FileCheck -check-prefix=MACHO_64 %s + + .text +foo: + .sleb128 0 + .sleb128 1 + .sleb128 -1 + .sleb128 63 + .sleb128 -64 + + .sleb128 64 + .sleb128 -65 + + .sleb128 8191 + .sleb128 -8192 + + .sleb128 8193 + +// ELF_32: ('sh_name', 1) # '.text' +// ELF_32: ('_section_data', '00017f3f 40c000bf 7fff3f80 4081c000') +// ELF_64: ('sh_name', 1) # '.text' +// ELF_64: ('_section_data', '00017f3f 40c000bf 7fff3f80 4081c000') +// MACHO_32: ('section_name', '__text\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') +// MACHO_32: ('_section_data', '00017f3f 40c000bf 7fff3f80 4081c000') +// MACHO_64: ('section_name', '__text\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') +// MACHO_64: ('_section_data', '00017f3f 40c000bf 7fff3f80 4081c000') diff --git a/test/MC/ELF/uleb.s b/test/MC/ELF/uleb.s new file mode 100644 index 0000000000..1fb2a2347a --- /dev/null +++ b/test/MC/ELF/uleb.s @@ -0,0 +1,22 @@ +// RUN: llvm-mc -filetype=obj -triple i686-pc-linux-gnu -n %s -o - | elf-dump --dump-section-data | FileCheck -check-prefix=ELF_32 %s +// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu -n %s -o - | elf-dump --dump-section-data | FileCheck -check-prefix=ELF_64 %s +// RUN: llvm-mc -filetype=obj -triple i386-apple-darwin9 %s -o - | macho-dump --dump-section-data | FileCheck -check-prefix=MACHO_32 %s +// RUN: llvm-mc -filetype=obj -triple x86_64-apple-darwin9 %s -o - | macho-dump --dump-section-data | FileCheck -check-prefix=MACHO_64 %s + + .text +foo: + .uleb128 0 + .uleb128 1 + .uleb128 127 + .uleb128 128 + .uleb128 16383 + .uleb128 16384 + +// ELF_32: ('sh_name', 1) # '.text' +// ELF_32: ('_section_data', '00017f80 01ff7f80 8001') +// ELF_64: ('sh_name', 1) # '.text' +// ELF_64: ('_section_data', '00017f80 01ff7f80 8001') +// MACHO_32: ('section_name', '__text\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') +// MACHO_32: ('_section_data', '00017f80 01ff7f80 8001') +// MACHO_64: ('section_name', '__text\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') +// MACHO_64: ('_section_data', '00017f80 01ff7f80 8001') |