@@ -83,39 +83,33 @@ static void swapBytes(std::byte *M, size_t N) {
8383// / have indeterminate value.
8484// / All offsets are in bits.
8585struct BitcastBuffer {
86- llvm::BitVector Data;
86+ size_t SizeInBits = 0 ;
87+ llvm::SmallVector<std::byte> Data;
8788
8889 BitcastBuffer () = default ;
8990
90- size_t size () const { return Data. size () ; }
91+ size_t size () const { return SizeInBits ; }
9192
92- const std::byte *data () const {
93- unsigned NBytes = Data.size () / 8 ;
94- unsigned BitVectorWordSize = sizeof (uintptr_t );
95- bool FullWord = (NBytes % BitVectorWordSize == 0 );
96-
97- // llvm::BitVector uses 64-bit fields internally, so when we have
98- // fewer bytes than that, we need to compensate for that on
99- // big endian hosts.
100- unsigned DataPlus;
101- if (llvm::sys::IsBigEndianHost)
102- DataPlus = BitVectorWordSize - (NBytes % BitVectorWordSize);
103- else
104- DataPlus = 0 ;
105-
106- return reinterpret_cast <const std::byte *>(Data.getData ().data ()) +
107- (FullWord ? 0 : DataPlus);
108- }
93+ const std::byte *data () const { return Data.data (); }
10994
11095 bool allInitialized () const {
11196 // FIXME: Implement.
11297 return true ;
11398 }
11499
100+ bool atByteBoundary () const { return (Data.size () * 8 ) == SizeInBits; }
101+
102+ void pushBit (bool Value) {
103+ if (atByteBoundary ())
104+ Data.push_back (std::byte{0 });
105+
106+ if (Value)
107+ Data.back () |= (std::byte{1 } << (SizeInBits % 8 ));
108+ ++SizeInBits;
109+ }
110+
115111 void pushData (const std::byte *data, size_t BitOffset, size_t BitWidth,
116112 bool BigEndianTarget) {
117- Data.reserve (BitOffset + BitWidth);
118-
119113 bool OnlyFullBytes = BitWidth % 8 == 0 ;
120114 unsigned NBytes = BitWidth / 8 ;
121115
@@ -125,7 +119,7 @@ struct BitcastBuffer {
125119 std::byte B =
126120 BigEndianTarget ? data[NBytes - OnlyFullBytes - I] : data[I];
127121 for (unsigned X = 0 ; X != 8 ; ++X) {
128- Data. push_back (bitof (B, X));
122+ pushBit (bitof (B, X));
129123 ++BitsHandled;
130124 }
131125 }
@@ -137,7 +131,7 @@ struct BitcastBuffer {
137131 assert ((BitWidth - BitsHandled) < 8 );
138132 std::byte B = BigEndianTarget ? data[0 ] : data[NBytes];
139133 for (size_t I = 0 , E = (BitWidth - BitsHandled); I != E; ++I) {
140- Data. push_back (bitof (B, I));
134+ pushBit (bitof (B, I));
141135 ++BitsHandled;
142136 }
143137
@@ -363,5 +357,8 @@ bool clang::interp::DoBitCast(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
363357 HasIndeterminateBits = !Buffer.allInitialized ();
364358 std::memcpy (Buff, Buffer.data (), BuffSize);
365359
360+ if (llvm::sys::IsBigEndianHost)
361+ swapBytes (Buff, BuffSize);
362+
366363 return Success;
367364}
0 commit comments