From 80668d18e8064560bb6c227cde4e2a01d32e683e Mon Sep 17 00:00:00 2001 From: Logan Chien Date: Sat, 22 Feb 2014 14:00:39 +0000 Subject: [PATCH] Move get[S|U]LEB128Size() to LEB128.h. This commit moves getSLEB128Size() and getULEB128Size() from MCAsmInfo to LEB128.h and removes some copy-and-paste code. Besides, this commit also adds some unit tests for the LEB128 functions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@201937 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/MC/MCAsmInfo.h | 4 - include/llvm/Support/LEB128.h | 25 ++ lib/CodeGen/AsmPrinter/DIE.cpp | 13 +- lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 3 +- lib/CodeGen/AsmPrinter/DwarfException.cpp | 24 +- lib/MC/MCAsmInfo.cpp | 24 -- lib/MC/MCDwarf.cpp | 3 +- .../ARM/MCTargetDesc/ARMELFStreamer.cpp | 22 +- unittests/Support/CMakeLists.txt | 1 + unittests/Support/LEB128Test.cpp | 311 ++++++++++++++++++ 10 files changed, 364 insertions(+), 66 deletions(-) create mode 100644 unittests/Support/LEB128Test.cpp diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h index f039ba0db15..4e5322fe6af 100644 --- a/include/llvm/MC/MCAsmInfo.h +++ b/include/llvm/MC/MCAsmInfo.h @@ -311,10 +311,6 @@ namespace llvm { explicit MCAsmInfo(); virtual ~MCAsmInfo(); - // FIXME: move these methods to DwarfPrinter when the JIT stops using them. - static unsigned getSLEB128Size(int64_t Value); - static unsigned getULEB128Size(uint64_t Value); - /// getPointerSize - Get the pointer size in bytes. unsigned getPointerSize() const { return PointerSize; diff --git a/include/llvm/Support/LEB128.h b/include/llvm/Support/LEB128.h index 3d7379250af..6eb34eec8a6 100644 --- a/include/llvm/Support/LEB128.h +++ b/include/llvm/Support/LEB128.h @@ -90,6 +90,31 @@ inline uint64_t decodeULEB128(const uint8_t *p, unsigned *n = 0) { return Value; } +/// Utility function to get the size of the ULEB128-encoded value. +inline unsigned getULEB128Size(uint64_t Value) { + unsigned Size = 0; + do { + Value >>= 7; + Size += sizeof(int8_t); + } while (Value); + return Size; +} + +/// Utility function to get the size of the SLEB128-encoded value. +inline unsigned getSLEB128Size(int64_t Value) { + unsigned Size = 0; + int Sign = Value >> (8 * sizeof(Value) - 1); + bool IsMore; + + do { + unsigned Byte = Value & 0x7f; + Value >>= 7; + IsMore = Value != Sign || ((Byte ^ Sign) & 0x40) != 0; + Size += sizeof(int8_t); + } while (IsMore); + return Size; +} + } // namespace llvm #endif // LLVM_SYSTEM_LEB128_H diff --git a/lib/CodeGen/AsmPrinter/DIE.cpp b/lib/CodeGen/AsmPrinter/DIE.cpp index 845bb4610a2..cf8cbd5b7ea 100644 --- a/lib/CodeGen/AsmPrinter/DIE.cpp +++ b/lib/CodeGen/AsmPrinter/DIE.cpp @@ -24,6 +24,7 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Format.h" #include "llvm/Support/FormattedStream.h" +#include "llvm/Support/LEB128.h" #include "llvm/Support/MD5.h" using namespace llvm; @@ -256,10 +257,10 @@ unsigned DIEInteger::SizeOf(AsmPrinter *AP, dwarf::Form Form) const { case dwarf::DW_FORM_ref8: // Fall thru case dwarf::DW_FORM_ref_sig8: // Fall thru case dwarf::DW_FORM_data8: return sizeof(int64_t); - case dwarf::DW_FORM_GNU_str_index: return MCAsmInfo::getULEB128Size(Integer); - case dwarf::DW_FORM_GNU_addr_index: return MCAsmInfo::getULEB128Size(Integer); - case dwarf::DW_FORM_udata: return MCAsmInfo::getULEB128Size(Integer); - case dwarf::DW_FORM_sdata: return MCAsmInfo::getSLEB128Size(Integer); + case dwarf::DW_FORM_GNU_str_index: return getULEB128Size(Integer); + case dwarf::DW_FORM_GNU_addr_index: return getULEB128Size(Integer); + case dwarf::DW_FORM_udata: return getULEB128Size(Integer); + case dwarf::DW_FORM_sdata: return getSLEB128Size(Integer); case dwarf::DW_FORM_addr: return AP->getDataLayout().getPointerSize(); default: llvm_unreachable("DIE Value form not supported yet"); } @@ -463,7 +464,7 @@ unsigned DIELoc::SizeOf(AsmPrinter *AP, dwarf::Form Form) const { case dwarf::DW_FORM_block4: return Size + sizeof(int32_t); case dwarf::DW_FORM_block: case dwarf::DW_FORM_exprloc: - return Size + MCAsmInfo::getULEB128Size(Size); + return Size + getULEB128Size(Size); default: llvm_unreachable("Improper form for block"); } } @@ -516,7 +517,7 @@ unsigned DIEBlock::SizeOf(AsmPrinter *AP, dwarf::Form Form) const { case dwarf::DW_FORM_block1: return Size + sizeof(int8_t); case dwarf::DW_FORM_block2: return Size + sizeof(int16_t); case dwarf::DW_FORM_block4: return Size + sizeof(int32_t); - case dwarf::DW_FORM_block: return Size + MCAsmInfo::getULEB128Size(Size); + case dwarf::DW_FORM_block: return Size + getULEB128Size(Size); default: llvm_unreachable("Improper form for block"); } } diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 05006b33bc3..2425948ae9a 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -38,6 +38,7 @@ #include "llvm/Support/Dwarf.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FormattedStream.h" +#include "llvm/Support/LEB128.h" #include "llvm/Support/MD5.h" #include "llvm/Support/Path.h" #include "llvm/Support/Timer.h" @@ -1876,7 +1877,7 @@ unsigned DwarfFile::computeSizeAndOffset(DIE *Die, unsigned Offset) { Die->setOffset(Offset); // Start the size with the size of abbreviation code. - Offset += MCAsmInfo::getULEB128Size(Die->getAbbrevNumber()); + Offset += getULEB128Size(Die->getAbbrevNumber()); const SmallVectorImpl &Values = Die->getValues(); const SmallVectorImpl &AbbrevData = Abbrev.getData(); diff --git a/lib/CodeGen/AsmPrinter/DwarfException.cpp b/lib/CodeGen/AsmPrinter/DwarfException.cpp index f72bc81499d..dd4cad683de 100644 --- a/lib/CodeGen/AsmPrinter/DwarfException.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfException.cpp @@ -31,6 +31,7 @@ #include "llvm/Support/Dwarf.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FormattedStream.h" +#include "llvm/Support/LEB128.h" #include "llvm/Target/TargetFrameLowering.h" #include "llvm/Target/TargetLoweringObjectFile.h" #include "llvm/Target/TargetOptions.h" @@ -108,7 +109,7 @@ ComputeActionsTable(const SmallVectorImpl &LandingPads, for (std::vector::const_iterator I = FilterIds.begin(), E = FilterIds.end(); I != E; ++I) { FilterOffsets.push_back(Offset); - Offset -= MCAsmInfo::getULEB128Size(*I); + Offset -= getULEB128Size(*I); } FirstActions.reserve(LandingPads.size()); @@ -132,14 +133,12 @@ ComputeActionsTable(const SmallVectorImpl &LandingPads, unsigned SizePrevIds = PrevLPI->TypeIds.size(); assert(Actions.size()); PrevAction = Actions.size() - 1; - SizeAction = - MCAsmInfo::getSLEB128Size(Actions[PrevAction].NextAction) + - MCAsmInfo::getSLEB128Size(Actions[PrevAction].ValueForTypeID); + SizeAction = getSLEB128Size(Actions[PrevAction].NextAction) + + getSLEB128Size(Actions[PrevAction].ValueForTypeID); for (unsigned j = NumShared; j != SizePrevIds; ++j) { assert(PrevAction != (unsigned)-1 && "PrevAction is invalid!"); - SizeAction -= - MCAsmInfo::getSLEB128Size(Actions[PrevAction].ValueForTypeID); + SizeAction -= getSLEB128Size(Actions[PrevAction].ValueForTypeID); SizeAction += -Actions[PrevAction].NextAction; PrevAction = Actions[PrevAction].Previous; } @@ -150,10 +149,10 @@ ComputeActionsTable(const SmallVectorImpl &LandingPads, int TypeID = TypeIds[J]; assert(-1 - TypeID < (int)FilterOffsets.size() && "Unknown filter id!"); int ValueForTypeID = TypeID < 0 ? FilterOffsets[-1 - TypeID] : TypeID; - unsigned SizeTypeID = MCAsmInfo::getSLEB128Size(ValueForTypeID); + unsigned SizeTypeID = getSLEB128Size(ValueForTypeID); int NextAction = SizeAction ? -(SizeAction + SizeTypeID) : 0; - SizeAction = SizeTypeID + MCAsmInfo::getSLEB128Size(NextAction); + SizeAction = SizeTypeID + getSLEB128Size(NextAction); SizeSiteActions += SizeAction; ActionEntry Action = { ValueForTypeID, NextAction, PrevAction }; @@ -401,9 +400,9 @@ void DwarfException::EmitExceptionTable() { } for (unsigned i = 0, e = CallSites.size(); i < e; ++i) { - CallSiteTableLength += MCAsmInfo::getULEB128Size(CallSites[i].Action); + CallSiteTableLength += getULEB128Size(CallSites[i].Action); if (IsSJLJ) - CallSiteTableLength += MCAsmInfo::getULEB128Size(i); + CallSiteTableLength += getULEB128Size(i); } // Type infos. @@ -488,15 +487,14 @@ void DwarfException::EmitExceptionTable() { // We chose another solution: don't output padding inside the table like GCC // does, instead output it before the table. unsigned SizeTypes = TypeInfos.size() * TypeFormatSize; - unsigned CallSiteTableLengthSize = - MCAsmInfo::getULEB128Size(CallSiteTableLength); + unsigned CallSiteTableLengthSize = getULEB128Size(CallSiteTableLength); unsigned TTypeBaseOffset = sizeof(int8_t) + // Call site format CallSiteTableLengthSize + // Call site table length size CallSiteTableLength + // Call site table length SizeActions + // Actions size SizeTypes; - unsigned TTypeBaseOffsetSize = MCAsmInfo::getULEB128Size(TTypeBaseOffset); + unsigned TTypeBaseOffsetSize = getULEB128Size(TTypeBaseOffset); unsigned TotalSize = sizeof(int8_t) + // LPStart format sizeof(int8_t) + // TType format diff --git a/lib/MC/MCAsmInfo.cpp b/lib/MC/MCAsmInfo.cpp index 0243f008fc9..f09bbd1a660 100644 --- a/lib/MC/MCAsmInfo.cpp +++ b/lib/MC/MCAsmInfo.cpp @@ -105,30 +105,6 @@ MCAsmInfo::MCAsmInfo() { MCAsmInfo::~MCAsmInfo() { } - -unsigned MCAsmInfo::getULEB128Size(uint64_t Value) { - unsigned Size = 0; - do { - Value >>= 7; - Size += sizeof(int8_t); - } while (Value); - return Size; -} - -unsigned MCAsmInfo::getSLEB128Size(int64_t Value) { - unsigned Size = 0; - int Sign = Value >> (8 * sizeof(Value) - 1); - bool IsMore; - - do { - unsigned Byte = Value & 0x7f; - Value >>= 7; - IsMore = Value != Sign || ((Byte ^ Sign) & 0x40) != 0; - Size += sizeof(int8_t); - } while (IsMore); - return Size; -} - const MCExpr * MCAsmInfo::getExprForPersonalitySymbol(const MCSymbol *Sym, unsigned Encoding, diff --git a/lib/MC/MCDwarf.cpp b/lib/MC/MCDwarf.cpp index d52c7a76928..98d78737cc6 100644 --- a/lib/MC/MCDwarf.cpp +++ b/lib/MC/MCDwarf.cpp @@ -157,8 +157,7 @@ static inline void EmitDwarfLineTable(MCStreamer *MCOS, } if (Discriminator != it->getDiscriminator()) { Discriminator = it->getDiscriminator(); - unsigned Size = - MCOS->getContext().getAsmInfo()->getULEB128Size(Discriminator); + unsigned Size = getULEB128Size(Discriminator); MCOS->EmitIntValue(dwarf::DW_LNS_extended_op, 1); MCOS->EmitULEB128IntValue(Size + 1); MCOS->EmitIntValue(dwarf::DW_LNE_set_discriminator, 1); diff --git a/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp b/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp index 0c6c17bf051..2945f09992c 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp @@ -43,6 +43,7 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/ELF.h" #include "llvm/Support/FormattedStream.h" +#include "llvm/Support/LEB128.h" #include "llvm/Support/raw_ostream.h" #include @@ -306,17 +307,6 @@ private: const MCSection *AttributeSection; - // FIXME: this should be in a more generic place, but - // getULEBSize() is in MCAsmInfo and will be moved to MCDwarf - static size_t getULEBSize(int Value) { - size_t Size = 0; - do { - Value >>= 7; - Size += sizeof(int8_t); // Is this really necessary? - } while (Value); - return Size; - } - AttributeItem *getAttributeItem(unsigned Attribute) { for (size_t i = 0; i < Contents.size(); ++i) if (Contents[i].Tag == Attribute) @@ -897,16 +887,16 @@ size_t ARMTargetELFStreamer::calculateContentSize() const { case AttributeItem::HiddenAttribute: break; case AttributeItem::NumericAttribute: - Result += getULEBSize(item.Tag); - Result += getULEBSize(item.IntValue); + Result += getULEB128Size(item.Tag); + Result += getULEB128Size(item.IntValue); break; case AttributeItem::TextAttribute: - Result += getULEBSize(item.Tag); + Result += getULEB128Size(item.Tag); Result += item.StringValue.size() + 1; // string + '\0' break; case AttributeItem::NumericAndTextAttributes: - Result += getULEBSize(item.Tag); - Result += getULEBSize(item.IntValue); + Result += getULEB128Size(item.Tag); + Result += getULEB128Size(item.IntValue); Result += item.StringValue.size() + 1; // string + '\0'; break; } diff --git a/unittests/Support/CMakeLists.txt b/unittests/Support/CMakeLists.txt index b3f0622e34b..bfbef982e2e 100644 --- a/unittests/Support/CMakeLists.txt +++ b/unittests/Support/CMakeLists.txt @@ -17,6 +17,7 @@ add_llvm_unittest(SupportTests EndianTest.cpp ErrorOrTest.cpp FileOutputBufferTest.cpp + LEB128Test.cpp LeakDetectorTest.cpp LineIteratorTest.cpp LockFileManagerTest.cpp diff --git a/unittests/Support/LEB128Test.cpp b/unittests/Support/LEB128Test.cpp new file mode 100644 index 00000000000..b1ca13ef241 --- /dev/null +++ b/unittests/Support/LEB128Test.cpp @@ -0,0 +1,311 @@ +//===- llvm/unittest/Support/LEB128Test.cpp - LEB128 function tests -------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "gtest/gtest.h" +#include "llvm/Support/DataTypes.h" +#include "llvm/Support/LEB128.h" +#include "llvm/Support/raw_ostream.h" +#include +using namespace llvm; + +namespace { + +TEST(LEB128Test, EncodeSLEB128) { +#define EXPECT_SLEB128_EQ(EXPECTED, VALUE) \ + do { \ + /* encodeSLEB128(uint64_t, raw_ostream &) */ \ + std::string Expected(EXPECTED, sizeof(EXPECTED) - 1); \ + std::string Actual; \ + raw_string_ostream Stream(Actual); \ + encodeSLEB128(VALUE, Stream); \ + Stream.flush(); \ + EXPECT_EQ(Expected, Actual); \ + } while (0) + + // Encode SLEB128 + EXPECT_SLEB128_EQ("\x00", 0); + EXPECT_SLEB128_EQ("\x01", 1); + EXPECT_SLEB128_EQ("\x7f", -1); + EXPECT_SLEB128_EQ("\x3f", 63); + EXPECT_SLEB128_EQ("\x41", -63); + EXPECT_SLEB128_EQ("\x40", -64); + EXPECT_SLEB128_EQ("\xbf\x7f", -65); + EXPECT_SLEB128_EQ("\xc0\x00", 64); + +#undef EXPECT_SLEB128_EQ +} + +TEST(LEB128Test, EncodeULEB128) { +#define EXPECT_ULEB128_EQ(EXPECTED, VALUE, PAD) \ + do { \ + std::string Expected(EXPECTED, sizeof(EXPECTED) - 1); \ + \ + /* encodeULEB128(uint64_t, raw_ostream &, unsigned) */ \ + std::string Actual1; \ + raw_string_ostream Stream(Actual1); \ + encodeULEB128(VALUE, Stream, PAD); \ + Stream.flush(); \ + EXPECT_EQ(Expected, Actual1); \ + \ + /* encodeULEB128(uint64_t, uint8_t *, unsigned) */ \ + uint8_t Buffer[32]; \ + unsigned Size = encodeULEB128(VALUE, Buffer, PAD); \ + std::string Actual2(reinterpret_cast(Buffer), Size); \ + EXPECT_EQ(Expected, Actual2); \ + } while (0) + + // Encode ULEB128 + EXPECT_ULEB128_EQ("\x00", 0, 0); + EXPECT_ULEB128_EQ("\x01", 1, 0); + EXPECT_ULEB128_EQ("\x3f", 63, 0); + EXPECT_ULEB128_EQ("\x40", 64, 0); + EXPECT_ULEB128_EQ("\x7f", 0x7f, 0); + EXPECT_ULEB128_EQ("\x80\x01", 0x80, 0); + EXPECT_ULEB128_EQ("\x81\x01", 0x81, 0); + EXPECT_ULEB128_EQ("\x90\x01", 0x90, 0); + EXPECT_ULEB128_EQ("\xff\x01", 0xff, 0); + EXPECT_ULEB128_EQ("\x80\x02", 0x100, 0); + EXPECT_ULEB128_EQ("\x81\x02", 0x101, 0); + + // Encode ULEB128 with some extra padding bytes + EXPECT_ULEB128_EQ("\x80\x00", 0, 1); + EXPECT_ULEB128_EQ("\x80\x80\x00", 0, 2); + EXPECT_ULEB128_EQ("\xff\x00", 0x7f, 1); + EXPECT_ULEB128_EQ("\xff\x80\x00", 0x7f, 2); + EXPECT_ULEB128_EQ("\x80\x81\x00", 0x80, 1); + EXPECT_ULEB128_EQ("\x80\x81\x80\x00", 0x80, 2); + +#undef EXPECT_ULEB128_EQ +} + +TEST(LEB128Test, DecodeULEB128) { +#define EXPECT_DECODE_ULEB128_EQ(EXPECTED, VALUE) \ + do { \ + unsigned ActualSize = 0; \ + uint64_t Actual = decodeULEB128(reinterpret_cast(VALUE), \ + &ActualSize); \ + EXPECT_EQ(sizeof(VALUE) - 1, ActualSize); \ + EXPECT_EQ(EXPECTED, Actual); \ + } while (0) + + // Decode ULEB128 + EXPECT_DECODE_ULEB128_EQ(0u, "\x00"); + EXPECT_DECODE_ULEB128_EQ(1u, "\x01"); + EXPECT_DECODE_ULEB128_EQ(63u, "\x3f"); + EXPECT_DECODE_ULEB128_EQ(64u, "\x40"); + EXPECT_DECODE_ULEB128_EQ(0x7fu, "\x7f"); + EXPECT_DECODE_ULEB128_EQ(0x80u, "\x80\x01"); + EXPECT_DECODE_ULEB128_EQ(0x81u, "\x81\x01"); + EXPECT_DECODE_ULEB128_EQ(0x90u, "\x90\x01"); + EXPECT_DECODE_ULEB128_EQ(0xffu, "\xff\x01"); + EXPECT_DECODE_ULEB128_EQ(0x100u, "\x80\x02"); + EXPECT_DECODE_ULEB128_EQ(0x101u, "\x81\x02"); + + // Decode ULEB128 with extra padding bytes + EXPECT_DECODE_ULEB128_EQ(0u, "\x80\x00"); + EXPECT_DECODE_ULEB128_EQ(0u, "\x80\x80\x00"); + EXPECT_DECODE_ULEB128_EQ(0x7fu, "\xff\x00"); + EXPECT_DECODE_ULEB128_EQ(0x7fu, "\xff\x80\x00"); + EXPECT_DECODE_ULEB128_EQ(0x80u, "\x80\x81\x00"); + EXPECT_DECODE_ULEB128_EQ(0x80u, "\x80\x81\x80\x00"); + +#undef EXPECT_DECODE_ULEB128_EQ +} + +TEST(LEB128Test, SLEB128Size) { + // Positive Value Testing Plan: + // (1) 128 ^ n - 1 ........ need (n+1) bytes + // (2) 128 ^ n ............ need (n+1) bytes + // (3) 128 ^ n * 63 ....... need (n+1) bytes + // (4) 128 ^ n * 64 - 1 ... need (n+1) bytes + // (5) 128 ^ n * 64 ....... need (n+2) bytes + + EXPECT_EQ(1u, getSLEB128Size(0x0LL)); + EXPECT_EQ(1u, getSLEB128Size(0x1LL)); + EXPECT_EQ(1u, getSLEB128Size(0x3fLL)); + EXPECT_EQ(1u, getSLEB128Size(0x3fLL)); + EXPECT_EQ(2u, getSLEB128Size(0x40LL)); + + EXPECT_EQ(2u, getSLEB128Size(0x7fLL)); + EXPECT_EQ(2u, getSLEB128Size(0x80LL)); + EXPECT_EQ(2u, getSLEB128Size(0x1f80LL)); + EXPECT_EQ(2u, getSLEB128Size(0x1fffLL)); + EXPECT_EQ(3u, getSLEB128Size(0x2000LL)); + + EXPECT_EQ(3u, getSLEB128Size(0x3fffLL)); + EXPECT_EQ(3u, getSLEB128Size(0x4000LL)); + EXPECT_EQ(3u, getSLEB128Size(0xfc000LL)); + EXPECT_EQ(3u, getSLEB128Size(0xfffffLL)); + EXPECT_EQ(4u, getSLEB128Size(0x100000LL)); + + EXPECT_EQ(4u, getSLEB128Size(0x1fffffLL)); + EXPECT_EQ(4u, getSLEB128Size(0x200000LL)); + EXPECT_EQ(4u, getSLEB128Size(0x7e00000LL)); + EXPECT_EQ(4u, getSLEB128Size(0x7ffffffLL)); + EXPECT_EQ(5u, getSLEB128Size(0x8000000LL)); + + EXPECT_EQ(5u, getSLEB128Size(0xfffffffLL)); + EXPECT_EQ(5u, getSLEB128Size(0x10000000LL)); + EXPECT_EQ(5u, getSLEB128Size(0x3f0000000LL)); + EXPECT_EQ(5u, getSLEB128Size(0x3ffffffffLL)); + EXPECT_EQ(6u, getSLEB128Size(0x400000000LL)); + + EXPECT_EQ(6u, getSLEB128Size(0x7ffffffffLL)); + EXPECT_EQ(6u, getSLEB128Size(0x800000000LL)); + EXPECT_EQ(6u, getSLEB128Size(0x1f800000000LL)); + EXPECT_EQ(6u, getSLEB128Size(0x1ffffffffffLL)); + EXPECT_EQ(7u, getSLEB128Size(0x20000000000LL)); + + EXPECT_EQ(7u, getSLEB128Size(0x3ffffffffffLL)); + EXPECT_EQ(7u, getSLEB128Size(0x40000000000LL)); + EXPECT_EQ(7u, getSLEB128Size(0xfc0000000000LL)); + EXPECT_EQ(7u, getSLEB128Size(0xffffffffffffLL)); + EXPECT_EQ(8u, getSLEB128Size(0x1000000000000LL)); + + EXPECT_EQ(8u, getSLEB128Size(0x1ffffffffffffLL)); + EXPECT_EQ(8u, getSLEB128Size(0x2000000000000LL)); + EXPECT_EQ(8u, getSLEB128Size(0x7e000000000000LL)); + EXPECT_EQ(8u, getSLEB128Size(0x7fffffffffffffLL)); + EXPECT_EQ(9u, getSLEB128Size(0x80000000000000LL)); + + EXPECT_EQ(9u, getSLEB128Size(0xffffffffffffffLL)); + EXPECT_EQ(9u, getSLEB128Size(0x100000000000000LL)); + EXPECT_EQ(9u, getSLEB128Size(0x3f00000000000000LL)); + EXPECT_EQ(9u, getSLEB128Size(0x3fffffffffffffffLL)); + EXPECT_EQ(10u, getSLEB128Size(0x4000000000000000LL)); + + EXPECT_EQ(10u, getSLEB128Size(0x7fffffffffffffffLL)); + EXPECT_EQ(10u, getSLEB128Size(INT64_MAX)); + + // Negative Value Testing Plan: + // (1) - 128 ^ n - 1 ........ need (n+1) bytes + // (2) - 128 ^ n ............ need (n+1) bytes + // (3) - 128 ^ n * 63 ....... need (n+1) bytes + // (4) - 128 ^ n * 64 ....... need (n+1) bytes (different from positive one) + // (5) - 128 ^ n * 65 - 1 ... need (n+2) bytes (if n > 0) + // (6) - 128 ^ n * 65 ....... need (n+2) bytes + + EXPECT_EQ(1u, getSLEB128Size(0x0LL)); + EXPECT_EQ(1u, getSLEB128Size(-0x1LL)); + EXPECT_EQ(1u, getSLEB128Size(-0x3fLL)); + EXPECT_EQ(1u, getSLEB128Size(-0x40LL)); + EXPECT_EQ(1u, getSLEB128Size(-0x40LL)); // special case + EXPECT_EQ(2u, getSLEB128Size(-0x41LL)); + + EXPECT_EQ(2u, getSLEB128Size(-0x7fLL)); + EXPECT_EQ(2u, getSLEB128Size(-0x80LL)); + EXPECT_EQ(2u, getSLEB128Size(-0x1f80LL)); + EXPECT_EQ(2u, getSLEB128Size(-0x2000LL)); + EXPECT_EQ(3u, getSLEB128Size(-0x207fLL)); + EXPECT_EQ(3u, getSLEB128Size(-0x2080LL)); + + EXPECT_EQ(3u, getSLEB128Size(-0x3fffLL)); + EXPECT_EQ(3u, getSLEB128Size(-0x4000LL)); + EXPECT_EQ(3u, getSLEB128Size(-0xfc000LL)); + EXPECT_EQ(3u, getSLEB128Size(-0x100000LL)); + EXPECT_EQ(4u, getSLEB128Size(-0x103fffLL)); + EXPECT_EQ(4u, getSLEB128Size(-0x104000LL)); + + EXPECT_EQ(4u, getSLEB128Size(-0x1fffffLL)); + EXPECT_EQ(4u, getSLEB128Size(-0x200000LL)); + EXPECT_EQ(4u, getSLEB128Size(-0x7e00000LL)); + EXPECT_EQ(4u, getSLEB128Size(-0x8000000LL)); + EXPECT_EQ(5u, getSLEB128Size(-0x81fffffLL)); + EXPECT_EQ(5u, getSLEB128Size(-0x8200000LL)); + + EXPECT_EQ(5u, getSLEB128Size(-0xfffffffLL)); + EXPECT_EQ(5u, getSLEB128Size(-0x10000000LL)); + EXPECT_EQ(5u, getSLEB128Size(-0x3f0000000LL)); + EXPECT_EQ(5u, getSLEB128Size(-0x400000000LL)); + EXPECT_EQ(6u, getSLEB128Size(-0x40fffffffLL)); + EXPECT_EQ(6u, getSLEB128Size(-0x410000000LL)); + + EXPECT_EQ(6u, getSLEB128Size(-0x7ffffffffLL)); + EXPECT_EQ(6u, getSLEB128Size(-0x800000000LL)); + EXPECT_EQ(6u, getSLEB128Size(-0x1f800000000LL)); + EXPECT_EQ(6u, getSLEB128Size(-0x20000000000LL)); + EXPECT_EQ(7u, getSLEB128Size(-0x207ffffffffLL)); + EXPECT_EQ(7u, getSLEB128Size(-0x20800000000LL)); + + EXPECT_EQ(7u, getSLEB128Size(-0x3ffffffffffLL)); + EXPECT_EQ(7u, getSLEB128Size(-0x40000000000LL)); + EXPECT_EQ(7u, getSLEB128Size(-0xfc0000000000LL)); + EXPECT_EQ(7u, getSLEB128Size(-0x1000000000000LL)); + EXPECT_EQ(8u, getSLEB128Size(-0x103ffffffffffLL)); + EXPECT_EQ(8u, getSLEB128Size(-0x1040000000000LL)); + + EXPECT_EQ(8u, getSLEB128Size(-0x1ffffffffffffLL)); + EXPECT_EQ(8u, getSLEB128Size(-0x2000000000000LL)); + EXPECT_EQ(8u, getSLEB128Size(-0x7e000000000000LL)); + EXPECT_EQ(8u, getSLEB128Size(-0x80000000000000LL)); + EXPECT_EQ(9u, getSLEB128Size(-0x81ffffffffffffLL)); + EXPECT_EQ(9u, getSLEB128Size(-0x82000000000000LL)); + + EXPECT_EQ(9u, getSLEB128Size(-0xffffffffffffffLL)); + EXPECT_EQ(9u, getSLEB128Size(-0x100000000000000LL)); + EXPECT_EQ(9u, getSLEB128Size(-0x3f00000000000000LL)); + EXPECT_EQ(9u, getSLEB128Size(-0x4000000000000000LL)); + EXPECT_EQ(10u, getSLEB128Size(-0x40ffffffffffffffLL)); + EXPECT_EQ(10u, getSLEB128Size(-0x4100000000000000LL)); + + EXPECT_EQ(10u, getSLEB128Size(-0x7fffffffffffffffLL)); + EXPECT_EQ(10u, getSLEB128Size(-0x8000000000000000LL)); + EXPECT_EQ(10u, getSLEB128Size(INT64_MIN)); +} + +TEST(LEB128Test, ULEB128Size) { + // Testing Plan: + // (1) 128 ^ n ............ need (n+1) bytes + // (2) 128 ^ n * 64 ....... need (n+1) bytes + // (3) 128 ^ (n+1) - 1 .... need (n+1) bytes + + EXPECT_EQ(1u, getULEB128Size(0)); // special case + + EXPECT_EQ(1u, getULEB128Size(0x1ULL)); + EXPECT_EQ(1u, getULEB128Size(0x40ULL)); + EXPECT_EQ(1u, getULEB128Size(0x7fULL)); + + EXPECT_EQ(2u, getULEB128Size(0x80ULL)); + EXPECT_EQ(2u, getULEB128Size(0x2000ULL)); + EXPECT_EQ(2u, getULEB128Size(0x3fffULL)); + + EXPECT_EQ(3u, getULEB128Size(0x4000ULL)); + EXPECT_EQ(3u, getULEB128Size(0x100000ULL)); + EXPECT_EQ(3u, getULEB128Size(0x1fffffULL)); + + EXPECT_EQ(4u, getULEB128Size(0x200000ULL)); + EXPECT_EQ(4u, getULEB128Size(0x8000000ULL)); + EXPECT_EQ(4u, getULEB128Size(0xfffffffULL)); + + EXPECT_EQ(5u, getULEB128Size(0x10000000ULL)); + EXPECT_EQ(5u, getULEB128Size(0x400000000ULL)); + EXPECT_EQ(5u, getULEB128Size(0x7ffffffffULL)); + + EXPECT_EQ(6u, getULEB128Size(0x800000000ULL)); + EXPECT_EQ(6u, getULEB128Size(0x20000000000ULL)); + EXPECT_EQ(6u, getULEB128Size(0x3ffffffffffULL)); + + EXPECT_EQ(7u, getULEB128Size(0x40000000000ULL)); + EXPECT_EQ(7u, getULEB128Size(0x1000000000000ULL)); + EXPECT_EQ(7u, getULEB128Size(0x1ffffffffffffULL)); + + EXPECT_EQ(8u, getULEB128Size(0x2000000000000ULL)); + EXPECT_EQ(8u, getULEB128Size(0x80000000000000ULL)); + EXPECT_EQ(8u, getULEB128Size(0xffffffffffffffULL)); + + EXPECT_EQ(9u, getULEB128Size(0x100000000000000ULL)); + EXPECT_EQ(9u, getULEB128Size(0x4000000000000000ULL)); + EXPECT_EQ(9u, getULEB128Size(0x7fffffffffffffffULL)); + + EXPECT_EQ(10u, getULEB128Size(0x8000000000000000ULL)); + + EXPECT_EQ(10u, getULEB128Size(UINT64_MAX)); +} + +} // anonymous namespace -- 2.34.1