diff options
Diffstat (limited to 'lib/MC/MCParser/AsmParser.cpp')
-rw-r--r-- | lib/MC/MCParser/AsmParser.cpp | 49 |
1 files changed, 49 insertions, 0 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, |