@@ -83,39 +83,33 @@ static void swapBytes(std::byte *M, size_t N) {
83
83
// / have indeterminate value.
84
84
// / All offsets are in bits.
85
85
struct BitcastBuffer {
86
- llvm::BitVector Data;
86
+ size_t SizeInBits = 0 ;
87
+ llvm::SmallVector<std::byte> Data;
87
88
88
89
BitcastBuffer () = default ;
89
90
90
- size_t size () const { return Data. size () ; }
91
+ size_t size () const { return SizeInBits ; }
91
92
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 (); }
109
94
110
95
bool allInitialized () const {
111
96
// FIXME: Implement.
112
97
return true ;
113
98
}
114
99
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
+
115
111
void pushData (const std::byte *data, size_t BitOffset, size_t BitWidth,
116
112
bool BigEndianTarget) {
117
- Data.reserve (BitOffset + BitWidth);
118
-
119
113
bool OnlyFullBytes = BitWidth % 8 == 0 ;
120
114
unsigned NBytes = BitWidth / 8 ;
121
115
@@ -125,7 +119,7 @@ struct BitcastBuffer {
125
119
std::byte B =
126
120
BigEndianTarget ? data[NBytes - OnlyFullBytes - I] : data[I];
127
121
for (unsigned X = 0 ; X != 8 ; ++X) {
128
- Data. push_back (bitof (B, X));
122
+ pushBit (bitof (B, X));
129
123
++BitsHandled;
130
124
}
131
125
}
@@ -137,7 +131,7 @@ struct BitcastBuffer {
137
131
assert ((BitWidth - BitsHandled) < 8 );
138
132
std::byte B = BigEndianTarget ? data[0 ] : data[NBytes];
139
133
for (size_t I = 0 , E = (BitWidth - BitsHandled); I != E; ++I) {
140
- Data. push_back (bitof (B, I));
134
+ pushBit (bitof (B, I));
141
135
++BitsHandled;
142
136
}
143
137
@@ -363,5 +357,8 @@ bool clang::interp::DoBitCast(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
363
357
HasIndeterminateBits = !Buffer.allInitialized ();
364
358
std::memcpy (Buff, Buffer.data (), BuffSize);
365
359
360
+ if (llvm::sys::IsBigEndianHost)
361
+ swapBytes (Buff, BuffSize);
362
+
366
363
return Success;
367
364
}
0 commit comments