From d199fc5aa5ba8ff892b5a4d003eee1bdd0113106 Mon Sep 17 00:00:00 2001 From: Teresa Johnson Date: Wed, 16 Sep 2015 20:41:43 +0000 Subject: [PATCH] Allow BackpatchWord to be called for non-32-bit aligned words, and from outside the BitstreamWriter. Split out of patch D12536 (Function bitcode index in Value Symbol Table and lazy reading support), which will use it to patch in the VST offset. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@247847 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Bitcode/BitstreamWriter.h | 27 ++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/include/llvm/Bitcode/BitstreamWriter.h b/include/llvm/Bitcode/BitstreamWriter.h index 490911f1ce1..df07204bc7c 100644 --- a/include/llvm/Bitcode/BitstreamWriter.h +++ b/include/llvm/Bitcode/BitstreamWriter.h @@ -63,12 +63,6 @@ class BitstreamWriter { }; std::vector BlockInfoRecords; - // BackpatchWord - Backpatch a 32-bit word in the output with the specified - // value. - void BackpatchWord(unsigned ByteNo, unsigned NewWord) { - support::endian::write32le(&Out[ByteNo], NewWord); - } - void WriteByte(unsigned char Value) { Out.push_back(Value); } @@ -105,6 +99,23 @@ public: // Basic Primitives for emitting bits to the stream. //===--------------------------------------------------------------------===// + /// Backpatch a 32-bit word in the output at the given bit offset + /// with the specified value. + void BackpatchWord(uint64_t BitNo, unsigned NewWord) { + unsigned ByteNo = BitNo / 8; + if ((BitNo & 7) == 0) { + // Already 8-bit aligned + support::endian::write32le(&Out[ByteNo], NewWord); + } else { + uint64_t CurDWord = support::endian::read64le(&Out[ByteNo]); + unsigned StartBit = BitNo & 7; + // Currently expect to backpatch 0-value placeholders. + assert(((CurDWord >> StartBit) & 0xffffffff) == 0); + CurDWord |= NewWord << StartBit; + support::endian::write64le(&Out[ByteNo], CurDWord); + } + } + void Emit(uint32_t Val, unsigned NumBits) { assert(NumBits && NumBits <= 32 && "Invalid value size!"); assert((Val & ~(~0U >> (32-NumBits))) == 0 && "High bits set!"); @@ -234,10 +245,10 @@ public: // Compute the size of the block, in words, not counting the size field. unsigned SizeInWords = GetWordIndex() - B.StartSizeWord - 1; - unsigned ByteNo = B.StartSizeWord*4; + uint64_t BitNo = B.StartSizeWord * 32; // Update the block size field in the header of this sub-block. - BackpatchWord(ByteNo, SizeInWords); + BackpatchWord(BitNo, SizeInWords); // Restore the inner block's code size and abbrev table. CurCodeSize = B.PrevCodeSize; -- 2.34.1