xref: /aosp_15_r20/art/libartbase/base/bit_struct_test.cc (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2017 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker #include "bit_struct.h"
18*795d594fSAndroid Build Coastguard Worker 
19*795d594fSAndroid Build Coastguard Worker #include "gtest/gtest.h"
20*795d594fSAndroid Build Coastguard Worker 
21*795d594fSAndroid Build Coastguard Worker namespace art {
22*795d594fSAndroid Build Coastguard Worker 
23*795d594fSAndroid Build Coastguard Worker // A copy of detail::ValidateBitStructSize that uses EXPECT for a more
24*795d594fSAndroid Build Coastguard Worker // human-readable message.
25*795d594fSAndroid Build Coastguard Worker template <typename T>
ValidateBitStructSize(const char * name)26*795d594fSAndroid Build Coastguard Worker static constexpr bool ValidateBitStructSize(const char* name) {
27*795d594fSAndroid Build Coastguard Worker   const size_t kBitStructSizeOf = BitStructSizeOf<T>();
28*795d594fSAndroid Build Coastguard Worker   const size_t kExpectedSize = (BitStructSizeOf<T>() < kBitsPerByte)
29*795d594fSAndroid Build Coastguard Worker                                    ? kBitsPerByte
30*795d594fSAndroid Build Coastguard Worker                                    : RoundUpToPowerOfTwo(kBitStructSizeOf);
31*795d594fSAndroid Build Coastguard Worker 
32*795d594fSAndroid Build Coastguard Worker   // Ensure no extra fields were added in between START/END.
33*795d594fSAndroid Build Coastguard Worker   const size_t kActualSize = sizeof(T) * kBitsPerByte;
34*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(kExpectedSize, kActualSize) << name;
35*795d594fSAndroid Build Coastguard Worker   return true;
36*795d594fSAndroid Build Coastguard Worker }
37*795d594fSAndroid Build Coastguard Worker 
38*795d594fSAndroid Build Coastguard Worker #define VALIDATE_BITSTRUCT_SIZE(type) ValidateBitStructSize<type>(#type)
39*795d594fSAndroid Build Coastguard Worker 
TEST(BitStructs,MinimumType)40*795d594fSAndroid Build Coastguard Worker TEST(BitStructs, MinimumType) {
41*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(1u, sizeof(typename detail::MinimumTypeUnsignedHelper<1>::type));
42*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(1u, sizeof(typename detail::MinimumTypeUnsignedHelper<2>::type));
43*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(1u, sizeof(typename detail::MinimumTypeUnsignedHelper<3>::type));
44*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(1u, sizeof(typename detail::MinimumTypeUnsignedHelper<8>::type));
45*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(2u, sizeof(typename detail::MinimumTypeUnsignedHelper<9>::type));
46*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(2u, sizeof(typename detail::MinimumTypeUnsignedHelper<10>::type));
47*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(2u, sizeof(typename detail::MinimumTypeUnsignedHelper<15>::type));
48*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(2u, sizeof(typename detail::MinimumTypeUnsignedHelper<16>::type));
49*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(4u, sizeof(typename detail::MinimumTypeUnsignedHelper<17>::type));
50*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(4u, sizeof(typename detail::MinimumTypeUnsignedHelper<32>::type));
51*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(8u, sizeof(typename detail::MinimumTypeUnsignedHelper<33>::type));
52*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(8u, sizeof(typename detail::MinimumTypeUnsignedHelper<64>::type));
53*795d594fSAndroid Build Coastguard Worker }
54*795d594fSAndroid Build Coastguard Worker 
55*795d594fSAndroid Build Coastguard Worker template <typename T>
AsUint(const T & value)56*795d594fSAndroid Build Coastguard Worker size_t AsUint(const T& value) {
57*795d594fSAndroid Build Coastguard Worker   size_t uint_value = 0;
58*795d594fSAndroid Build Coastguard Worker   memcpy(&uint_value, &value, sizeof(value));
59*795d594fSAndroid Build Coastguard Worker   return uint_value;
60*795d594fSAndroid Build Coastguard Worker }
61*795d594fSAndroid Build Coastguard Worker 
62*795d594fSAndroid Build Coastguard Worker struct CustomBitStruct {
63*795d594fSAndroid Build Coastguard Worker   CustomBitStruct() = default;
CustomBitStructart::CustomBitStruct64*795d594fSAndroid Build Coastguard Worker   explicit CustomBitStruct(uint8_t data) : data(data) {}
65*795d594fSAndroid Build Coastguard Worker 
BitStructSizeOfart::CustomBitStruct66*795d594fSAndroid Build Coastguard Worker   static constexpr size_t BitStructSizeOf() {
67*795d594fSAndroid Build Coastguard Worker     return 4;
68*795d594fSAndroid Build Coastguard Worker   }
69*795d594fSAndroid Build Coastguard Worker 
70*795d594fSAndroid Build Coastguard Worker   uint8_t data;
71*795d594fSAndroid Build Coastguard Worker };
72*795d594fSAndroid Build Coastguard Worker 
TEST(BitStructs,Custom)73*795d594fSAndroid Build Coastguard Worker TEST(BitStructs, Custom) {
74*795d594fSAndroid Build Coastguard Worker   CustomBitStruct expected(0b1111u);
75*795d594fSAndroid Build Coastguard Worker 
76*795d594fSAndroid Build Coastguard Worker   BitStructField<CustomBitStruct, /*lsb=*/4, /*width=*/4, uint8_t> f{};
77*795d594fSAndroid Build Coastguard Worker 
78*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(1u, sizeof(f));
79*795d594fSAndroid Build Coastguard Worker 
80*795d594fSAndroid Build Coastguard Worker   f = CustomBitStruct(0b1111u);
81*795d594fSAndroid Build Coastguard Worker 
82*795d594fSAndroid Build Coastguard Worker   CustomBitStruct read_out = f;
83*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(read_out.data, 0b1111u);
84*795d594fSAndroid Build Coastguard Worker 
85*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(AsUint(f), 0b11110000u);
86*795d594fSAndroid Build Coastguard Worker }
87*795d594fSAndroid Build Coastguard Worker 
88*795d594fSAndroid Build Coastguard Worker BITSTRUCT_DEFINE_START(TestTwoCustom, /* size= */ 8)
89*795d594fSAndroid Build Coastguard Worker   BITSTRUCT_FIELD(CustomBitStruct, /*lsb=*/0, /*width=*/4) f4_a;
90*795d594fSAndroid Build Coastguard Worker   BITSTRUCT_FIELD(CustomBitStruct, /*lsb=*/4, /*width=*/4) f4_b;
91*795d594fSAndroid Build Coastguard Worker BITSTRUCT_DEFINE_END(TestTwoCustom);
92*795d594fSAndroid Build Coastguard Worker 
TEST(BitStructs,TwoCustom)93*795d594fSAndroid Build Coastguard Worker TEST(BitStructs, TwoCustom) {
94*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(sizeof(TestTwoCustom), 1u);
95*795d594fSAndroid Build Coastguard Worker 
96*795d594fSAndroid Build Coastguard Worker   VALIDATE_BITSTRUCT_SIZE(TestTwoCustom);
97*795d594fSAndroid Build Coastguard Worker 
98*795d594fSAndroid Build Coastguard Worker   TestTwoCustom cst{};
99*795d594fSAndroid Build Coastguard Worker 
100*795d594fSAndroid Build Coastguard Worker   // Test the write to most-significant field doesn't clobber least-significant.
101*795d594fSAndroid Build Coastguard Worker   cst.f4_a = CustomBitStruct(0b0110);
102*795d594fSAndroid Build Coastguard Worker   cst.f4_b = CustomBitStruct(0b0101);
103*795d594fSAndroid Build Coastguard Worker 
104*795d594fSAndroid Build Coastguard Worker   int8_t read_out = static_cast<CustomBitStruct>(cst.f4_a).data;
105*795d594fSAndroid Build Coastguard Worker   int8_t read_out_b = static_cast<CustomBitStruct>(cst.f4_b).data;
106*795d594fSAndroid Build Coastguard Worker 
107*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(0b0110, static_cast<int>(read_out));
108*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(0b0101, static_cast<int>(read_out_b));
109*795d594fSAndroid Build Coastguard Worker 
110*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(AsUint(cst), 0b01010110u);
111*795d594fSAndroid Build Coastguard Worker 
112*795d594fSAndroid Build Coastguard Worker   // Test write to least-significant field doesn't clobber most-significant.
113*795d594fSAndroid Build Coastguard Worker   cst.f4_a = CustomBitStruct(0);
114*795d594fSAndroid Build Coastguard Worker 
115*795d594fSAndroid Build Coastguard Worker   read_out = static_cast<CustomBitStruct>(cst.f4_a).data;
116*795d594fSAndroid Build Coastguard Worker   read_out_b = static_cast<CustomBitStruct>(cst.f4_b).data;
117*795d594fSAndroid Build Coastguard Worker 
118*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(0b0, static_cast<int>(read_out));
119*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(0b0101, static_cast<int>(read_out_b));
120*795d594fSAndroid Build Coastguard Worker 
121*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(AsUint(cst), 0b01010000u);
122*795d594fSAndroid Build Coastguard Worker }
123*795d594fSAndroid Build Coastguard Worker 
TEST(BitStructs,Number)124*795d594fSAndroid Build Coastguard Worker TEST(BitStructs, Number) {
125*795d594fSAndroid Build Coastguard Worker   BitStructNumber<uint16_t, /*lsb=*/4, /*width=*/4, uint16_t> bsn{};
126*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(2u, sizeof(bsn));
127*795d594fSAndroid Build Coastguard Worker 
128*795d594fSAndroid Build Coastguard Worker   bsn = 0b1111;
129*795d594fSAndroid Build Coastguard Worker 
130*795d594fSAndroid Build Coastguard Worker   uint32_t read_out = static_cast<uint32_t>(bsn);
131*795d594fSAndroid Build Coastguard Worker   uint32_t read_out_impl = bsn;
132*795d594fSAndroid Build Coastguard Worker 
133*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(read_out, read_out_impl);
134*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(read_out, 0b1111u);
135*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(AsUint(bsn), 0b11110000u);
136*795d594fSAndroid Build Coastguard Worker }
137*795d594fSAndroid Build Coastguard Worker 
TEST(BitStructs,NumberNarrowStorage)138*795d594fSAndroid Build Coastguard Worker TEST(BitStructs, NumberNarrowStorage) {
139*795d594fSAndroid Build Coastguard Worker   BitStructNumber<uint16_t, /*lsb=*/4, /*width=*/4, uint8_t> bsn{};
140*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(1u, sizeof(bsn));
141*795d594fSAndroid Build Coastguard Worker 
142*795d594fSAndroid Build Coastguard Worker   bsn = 0b1111;
143*795d594fSAndroid Build Coastguard Worker 
144*795d594fSAndroid Build Coastguard Worker   uint32_t read_out = static_cast<uint32_t>(bsn);
145*795d594fSAndroid Build Coastguard Worker   uint32_t read_out_impl = bsn;
146*795d594fSAndroid Build Coastguard Worker 
147*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(read_out, read_out_impl);
148*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(read_out, 0b1111u);
149*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(AsUint(bsn), 0b11110000u);
150*795d594fSAndroid Build Coastguard Worker }
151*795d594fSAndroid Build Coastguard Worker 
152*795d594fSAndroid Build Coastguard Worker BITSTRUCT_DEFINE_START(TestBitStruct, /* size= */ 8)
153*795d594fSAndroid Build Coastguard Worker   BITSTRUCT_INT(/*lsb=*/0, /*width=*/3) i3;
154*795d594fSAndroid Build Coastguard Worker   BITSTRUCT_UINT(/*lsb=*/3, /*width=*/4) u4;
155*795d594fSAndroid Build Coastguard Worker 
156*795d594fSAndroid Build Coastguard Worker   BITSTRUCT_UINT(/*lsb=*/0, /*width=*/7) alias_all;
157*795d594fSAndroid Build Coastguard Worker BITSTRUCT_DEFINE_END(TestBitStruct);
158*795d594fSAndroid Build Coastguard Worker 
TEST(BitStructs,Test1)159*795d594fSAndroid Build Coastguard Worker TEST(BitStructs, Test1) {
160*795d594fSAndroid Build Coastguard Worker   TestBitStruct tst{};
161*795d594fSAndroid Build Coastguard Worker 
162*795d594fSAndroid Build Coastguard Worker   // Check minimal size selection is correct.
163*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(1u, sizeof(TestBitStruct));
164*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(1u, sizeof(tst._));
165*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(1u, sizeof(tst.i3));
166*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(1u, sizeof(tst.u4));
167*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(1u, sizeof(tst.alias_all));
168*795d594fSAndroid Build Coastguard Worker 
169*795d594fSAndroid Build Coastguard Worker   // Check operator assignment.
170*795d594fSAndroid Build Coastguard Worker   tst.i3 = -1;
171*795d594fSAndroid Build Coastguard Worker   tst.u4 = 0b1010;
172*795d594fSAndroid Build Coastguard Worker 
173*795d594fSAndroid Build Coastguard Worker   // Check implicit operator conversion.
174*795d594fSAndroid Build Coastguard Worker   int8_t read_i3 = tst.i3;
175*795d594fSAndroid Build Coastguard Worker   uint8_t read_u4 = tst.u4;
176*795d594fSAndroid Build Coastguard Worker 
177*795d594fSAndroid Build Coastguard Worker   // Ensure read-out values were correct.
178*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(static_cast<int8_t>(-1), read_i3);
179*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(0b1010, read_u4);
180*795d594fSAndroid Build Coastguard Worker 
181*795d594fSAndroid Build Coastguard Worker   // Ensure aliasing is working.
182*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(0b1010111, static_cast<uint8_t>(tst.alias_all));
183*795d594fSAndroid Build Coastguard Worker 
184*795d594fSAndroid Build Coastguard Worker   // Ensure the bit pattern is correct.
185*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(0b1010111u, AsUint(tst));
186*795d594fSAndroid Build Coastguard Worker 
187*795d594fSAndroid Build Coastguard Worker   // Math operator checks
188*795d594fSAndroid Build Coastguard Worker   {
189*795d594fSAndroid Build Coastguard Worker     // In-place
190*795d594fSAndroid Build Coastguard Worker     ++tst.u4;
191*795d594fSAndroid Build Coastguard Worker     EXPECT_EQ(static_cast<uint8_t>(0b1011), static_cast<uint8_t>(tst.u4));
192*795d594fSAndroid Build Coastguard Worker     --tst.u4;
193*795d594fSAndroid Build Coastguard Worker     EXPECT_EQ(static_cast<uint8_t>(0b1010), static_cast<uint8_t>(tst.u4));
194*795d594fSAndroid Build Coastguard Worker 
195*795d594fSAndroid Build Coastguard Worker     // Copy
196*795d594fSAndroid Build Coastguard Worker     uint8_t read_and_convert = tst.u4++;
197*795d594fSAndroid Build Coastguard Worker     EXPECT_EQ(static_cast<uint8_t>(0b1011), read_and_convert);
198*795d594fSAndroid Build Coastguard Worker     EXPECT_EQ(static_cast<uint8_t>(0b1010), static_cast<uint8_t>(tst.u4));
199*795d594fSAndroid Build Coastguard Worker     read_and_convert = tst.u4--;
200*795d594fSAndroid Build Coastguard Worker     EXPECT_EQ(static_cast<uint8_t>(0b1001), read_and_convert);
201*795d594fSAndroid Build Coastguard Worker     EXPECT_EQ(static_cast<uint8_t>(0b1010), static_cast<uint8_t>(tst.u4));
202*795d594fSAndroid Build Coastguard Worker 
203*795d594fSAndroid Build Coastguard Worker     // Check boolean operator conversion.
204*795d594fSAndroid Build Coastguard Worker     tst.u4 = 0b1010;
205*795d594fSAndroid Build Coastguard Worker     EXPECT_TRUE(static_cast<bool>(tst.u4));
206*795d594fSAndroid Build Coastguard Worker     bool succ = tst.u4 ? true : false;
207*795d594fSAndroid Build Coastguard Worker     EXPECT_TRUE(succ);
208*795d594fSAndroid Build Coastguard Worker 
209*795d594fSAndroid Build Coastguard Worker     tst.u4 = 0;
210*795d594fSAndroid Build Coastguard Worker     EXPECT_FALSE(static_cast<bool>(tst.u4));
211*795d594fSAndroid Build Coastguard Worker 
212*795d594fSAndroid Build Coastguard Worker /*
213*795d594fSAndroid Build Coastguard Worker     // Disabled: Overflow is caught by the BitFieldInsert DCHECKs.
214*795d594fSAndroid Build Coastguard Worker     // Check overflow for uint.
215*795d594fSAndroid Build Coastguard Worker     tst.u4 = 0b1111;
216*795d594fSAndroid Build Coastguard Worker     ++tst.u4;
217*795d594fSAndroid Build Coastguard Worker     EXPECT_EQ(static_cast<uint8_t>(0), static_cast<uint8_t>(tst.u4));
218*795d594fSAndroid Build Coastguard Worker */
219*795d594fSAndroid Build Coastguard Worker   }
220*795d594fSAndroid Build Coastguard Worker }
221*795d594fSAndroid Build Coastguard Worker 
222*795d594fSAndroid Build Coastguard Worker BITSTRUCT_DEFINE_START(MixedSizeBitStruct, /* size= */ 32)
223*795d594fSAndroid Build Coastguard Worker   BITSTRUCT_UINT(/*lsb=*/0, /*width=*/3) u3;
224*795d594fSAndroid Build Coastguard Worker   BITSTRUCT_UINT(/*lsb=*/3, /*width=*/10) u10;
225*795d594fSAndroid Build Coastguard Worker   BITSTRUCT_UINT(/*lsb=*/13, /*width=*/19) u19;
226*795d594fSAndroid Build Coastguard Worker 
227*795d594fSAndroid Build Coastguard Worker   BITSTRUCT_UINT(/*lsb=*/0, /*width=*/32) alias_all;
228*795d594fSAndroid Build Coastguard Worker BITSTRUCT_DEFINE_END(MixedSizeBitStruct);
229*795d594fSAndroid Build Coastguard Worker 
230*795d594fSAndroid Build Coastguard Worker // static_assert(sizeof(MixedSizeBitStruct) == sizeof(uint32_t), "TestBitStructs#MixedSize");
231*795d594fSAndroid Build Coastguard Worker 
TEST(BitStructs,Mixed)232*795d594fSAndroid Build Coastguard Worker TEST(BitStructs, Mixed) {
233*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(4u, sizeof(MixedSizeBitStruct));
234*795d594fSAndroid Build Coastguard Worker 
235*795d594fSAndroid Build Coastguard Worker   MixedSizeBitStruct tst{};
236*795d594fSAndroid Build Coastguard Worker 
237*795d594fSAndroid Build Coastguard Worker   // Check operator assignment.
238*795d594fSAndroid Build Coastguard Worker   tst.u3 = 0b111u;
239*795d594fSAndroid Build Coastguard Worker   tst.u10 = 0b1111010100u;
240*795d594fSAndroid Build Coastguard Worker   tst.u19 = 0b1010101010101010101u;
241*795d594fSAndroid Build Coastguard Worker 
242*795d594fSAndroid Build Coastguard Worker   // Check implicit operator conversion.
243*795d594fSAndroid Build Coastguard Worker   uint8_t read_u3 = tst.u3;
244*795d594fSAndroid Build Coastguard Worker   uint16_t read_u10 = tst.u10;
245*795d594fSAndroid Build Coastguard Worker   uint32_t read_u19 = tst.u19;
246*795d594fSAndroid Build Coastguard Worker 
247*795d594fSAndroid Build Coastguard Worker   // Ensure read-out values were correct.
248*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(0b111u, read_u3);
249*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(0b1111010100u, read_u10);
250*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(0b1010101010101010101u, read_u19);
251*795d594fSAndroid Build Coastguard Worker 
252*795d594fSAndroid Build Coastguard Worker   uint32_t read_all = tst.alias_all;
253*795d594fSAndroid Build Coastguard Worker 
254*795d594fSAndroid Build Coastguard Worker   // Ensure aliasing is working.
255*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(0b10101010101010101011111010100111u, read_all);
256*795d594fSAndroid Build Coastguard Worker 
257*795d594fSAndroid Build Coastguard Worker   // Ensure the bit pattern is correct.
258*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(0b10101010101010101011111010100111u, AsUint(tst));
259*795d594fSAndroid Build Coastguard Worker }
260*795d594fSAndroid Build Coastguard Worker 
261*795d594fSAndroid Build Coastguard Worker BITSTRUCT_DEFINE_START(TestBitStruct_u8, /* size= */ 8)
262*795d594fSAndroid Build Coastguard Worker   BITSTRUCT_INT(/*lsb=*/0, /*width=*/3) i3;
263*795d594fSAndroid Build Coastguard Worker   BITSTRUCT_UINT(/*lsb=*/3, /*width=*/4) u4;
264*795d594fSAndroid Build Coastguard Worker 
265*795d594fSAndroid Build Coastguard Worker   BITSTRUCT_UINT(/*lsb=*/0, /*width=*/8) alias_all;
266*795d594fSAndroid Build Coastguard Worker BITSTRUCT_DEFINE_END(TestBitStruct_u8);
267*795d594fSAndroid Build Coastguard Worker 
TEST(BitStructs,FieldAssignment)268*795d594fSAndroid Build Coastguard Worker TEST(BitStructs, FieldAssignment) {
269*795d594fSAndroid Build Coastguard Worker   TestBitStruct_u8 all_1s{};
270*795d594fSAndroid Build Coastguard Worker   all_1s.alias_all = 0xffu;
271*795d594fSAndroid Build Coastguard Worker 
272*795d594fSAndroid Build Coastguard Worker   {
273*795d594fSAndroid Build Coastguard Worker     TestBitStruct_u8 tst{};
274*795d594fSAndroid Build Coastguard Worker     tst.i3 = all_1s.i3;
275*795d594fSAndroid Build Coastguard Worker 
276*795d594fSAndroid Build Coastguard Worker     // Copying a single bitfield does not copy all bitfields.
277*795d594fSAndroid Build Coastguard Worker     EXPECT_EQ(0b111, tst.alias_all);
278*795d594fSAndroid Build Coastguard Worker   }
279*795d594fSAndroid Build Coastguard Worker 
280*795d594fSAndroid Build Coastguard Worker   {
281*795d594fSAndroid Build Coastguard Worker     TestBitStruct_u8 tst{};
282*795d594fSAndroid Build Coastguard Worker     tst.u4 = all_1s.u4;
283*795d594fSAndroid Build Coastguard Worker 
284*795d594fSAndroid Build Coastguard Worker     // Copying a single bitfield does not copy all bitfields.
285*795d594fSAndroid Build Coastguard Worker     EXPECT_EQ(0b1111000, tst.alias_all);
286*795d594fSAndroid Build Coastguard Worker   }
287*795d594fSAndroid Build Coastguard Worker }
288*795d594fSAndroid Build Coastguard Worker 
289*795d594fSAndroid Build Coastguard Worker BITSTRUCT_DEFINE_START(NestedStruct, /* size= */ 2 * MixedSizeBitStruct::BitStructSizeOf())
290*795d594fSAndroid Build Coastguard Worker   BITSTRUCT_FIELD(MixedSizeBitStruct,
291*795d594fSAndroid Build Coastguard Worker                   /*lsb=*/0,
292*795d594fSAndroid Build Coastguard Worker                   /*width=*/MixedSizeBitStruct::BitStructSizeOf()) mixed_lower;
293*795d594fSAndroid Build Coastguard Worker   BITSTRUCT_FIELD(MixedSizeBitStruct,
294*795d594fSAndroid Build Coastguard Worker                   /*lsb=*/MixedSizeBitStruct::BitStructSizeOf(),
295*795d594fSAndroid Build Coastguard Worker                   /*width=*/MixedSizeBitStruct::BitStructSizeOf()) mixed_upper;
296*795d594fSAndroid Build Coastguard Worker 
297*795d594fSAndroid Build Coastguard Worker   BITSTRUCT_UINT(/*lsb=*/0, /*width=*/ 2 * MixedSizeBitStruct::BitStructSizeOf()) alias_all;
298*795d594fSAndroid Build Coastguard Worker BITSTRUCT_DEFINE_END(NestedStruct);
299*795d594fSAndroid Build Coastguard Worker 
TEST(BitStructs,NestedFieldAssignment)300*795d594fSAndroid Build Coastguard Worker TEST(BitStructs, NestedFieldAssignment) {
301*795d594fSAndroid Build Coastguard Worker   MixedSizeBitStruct mixed_all_1s{};
302*795d594fSAndroid Build Coastguard Worker   mixed_all_1s.alias_all = 0xFFFFFFFFu;
303*795d594fSAndroid Build Coastguard Worker 
304*795d594fSAndroid Build Coastguard Worker   {
305*795d594fSAndroid Build Coastguard Worker     NestedStruct xyz{};
306*795d594fSAndroid Build Coastguard Worker 
307*795d594fSAndroid Build Coastguard Worker     NestedStruct other{};
308*795d594fSAndroid Build Coastguard Worker     other.mixed_upper = mixed_all_1s;
309*795d594fSAndroid Build Coastguard Worker     other.mixed_lower = mixed_all_1s;
310*795d594fSAndroid Build Coastguard Worker 
311*795d594fSAndroid Build Coastguard Worker     // Copying a single bitfield does not copy all bitfields.
312*795d594fSAndroid Build Coastguard Worker     xyz.mixed_lower = other.mixed_lower;
313*795d594fSAndroid Build Coastguard Worker     EXPECT_EQ(0xFFFFFFFFu, xyz.alias_all);
314*795d594fSAndroid Build Coastguard Worker   }
315*795d594fSAndroid Build Coastguard Worker 
316*795d594fSAndroid Build Coastguard Worker   {
317*795d594fSAndroid Build Coastguard Worker     NestedStruct xyz{};
318*795d594fSAndroid Build Coastguard Worker 
319*795d594fSAndroid Build Coastguard Worker     NestedStruct other{};
320*795d594fSAndroid Build Coastguard Worker     other.mixed_upper = mixed_all_1s;
321*795d594fSAndroid Build Coastguard Worker     other.mixed_lower = mixed_all_1s;
322*795d594fSAndroid Build Coastguard Worker 
323*795d594fSAndroid Build Coastguard Worker     // Copying a single bitfield does not copy all bitfields.
324*795d594fSAndroid Build Coastguard Worker     xyz.mixed_upper = other.mixed_upper;
325*795d594fSAndroid Build Coastguard Worker     EXPECT_EQ(0xFFFFFFFF00000000u, xyz.alias_all);
326*795d594fSAndroid Build Coastguard Worker   }
327*795d594fSAndroid Build Coastguard Worker }
328*795d594fSAndroid Build Coastguard Worker 
329*795d594fSAndroid Build Coastguard Worker }  // namespace art
330