gem5  v22.1.0.0
bitunion.test.cc
Go to the documentation of this file.
1 /*
2  * Copyright 2014 Google, Inc.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met: redistributions of source code must retain the above copyright
7  * notice, this list of conditions and the following disclaimer;
8  * redistributions in binary form must reproduce the above copyright
9  * notice, this list of conditions and the following disclaimer in the
10  * documentation and/or other materials provided with the distribution;
11  * neither the name of the copyright holders nor the names of its
12  * contributors may be used to endorse or promote products derived from
13  * this software without specific prior written permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #include <gtest/gtest.h>
29 
30 #include <cassert>
31 #include <iostream>
32 #include <type_traits>
33 
34 #include "base/bitunion.hh"
35 #include "base/cprintf.hh"
36 
37 using namespace gem5;
38 
39 namespace {
40 
41 BitUnion64(SixtyFour)
42  Bitfield<39, 32> byte5;
43  Bitfield<2> bit2;
44  BitfieldRO<39, 32> byte5RO;
45  BitfieldWO<39, 32> byte5WO;
46  SubBitUnion(byte6, 47, 40)
47  Bitfield<43, 42> bits43To42;
48  Bitfield<41> bit41;
49  SignedBitfield<41> bit41Signed;
50  EndSubBitUnion(byte6)
51  SignedBitfield<47, 40> byte6Signed;
52  SignedBitfieldRO<47, 40> byte6SignedRO;
53  SignedBitfieldWO<47, 40> byte6SignedWO;
54 EndBitUnion(SixtyFour)
55 
56 BitUnion64(EmptySixtyFour)
57 EndBitUnion(EmptySixtyFour)
58 
59 BitUnion32(EmptyThirtyTwo)
60 EndBitUnion(EmptyThirtyTwo)
61 
62 BitUnion16(EmptySixteen)
63 EndBitUnion(EmptySixteen)
64 
65 BitUnion8(EmptyEight)
66 EndBitUnion(EmptyEight)
67 
68 class SplitField
69 {
70  protected:
71  BitUnion64(In)
72  Bitfield<15, 12> high;
73  Bitfield<7, 4> low;
74  EndBitUnion(In)
75 
76  BitUnion64(Out)
77  Bitfield<7, 4> high;
78  Bitfield<3, 0> low;
79  EndBitUnion(Out)
80  public:
81  uint64_t
82  getter(const uint64_t &storage) const
83  {
84  Out out = 0;
85  In in = storage;
86  out.high = in.high;
87  out.low = in.low;
88  return out;
89  }
90 
91  void
92  setter(uint64_t &storage, uint64_t val)
93  {
94  Out out = val;
95  In in = 0;
96  in.high = out.high;
97  in.low = out.low;
98  storage = in;
99  }
100 };
101 
102 BitUnion64(Split)
104 EndBitUnion(Split)
105 
106 struct ContainingStruct
107 {
108  BitUnion64(Contained)
109  Bitfield<63, 60> topNibble;
110  EndBitUnion(Contained)
111 
112  Contained contained;
113 };
114 
115 uint64_t
116 containingFunc(uint64_t init_val, uint64_t fieldVal)
117 {
118  BitUnion32(Contained)
119  Bitfield<16, 15> field;
120  EndBitUnion(Contained)
121 
122  Contained contained = init_val;
123  contained.field = fieldVal;
124  return contained;
125 }
126 
127 } // anonymous namespace
128 
129 // Declare these as global so g++ doesn't ignore them. Initialize them in
130 // various ways.
131 EmptySixtyFour emptySixtyFour = 0;
132 EmptyThirtyTwo emptyThirtyTwo{};
133 [[maybe_unused]] EmptySixteen emptySixteen;
134 EmptyEight emptyEight(0);
135 
136 class BitUnionData : public testing::Test
137 {
138  protected:
139  SixtyFour sixtyFour;
140  Split split;
141 
142  void SetUp() override { sixtyFour = 0; split = 0; }
143 
144  template <typename T>
145  uint64_t templatedFunction(T) { return 0; }
146 
147  template <typename T>
148  uint64_t
150  {
152  return b;
153  }
154 };
155 
156 TEST_F(BitUnionData, NormalBitfield)
157 {
158  EXPECT_EQ(sixtyFour.byte5, 0);
159  sixtyFour.byte5 = 0xff;
160  EXPECT_EQ(sixtyFour, 0xff00000000);
161  sixtyFour.byte5 = 0xfff;
162  EXPECT_EQ(sixtyFour, 0xff00000000);
163  EXPECT_EQ(sixtyFour.byte5, 0xff);
164 }
165 
166 TEST_F(BitUnionData, SingleBitfield)
167 {
168  EXPECT_EQ(sixtyFour.bit2, 0);
169  sixtyFour.bit2 = 0x1;
170  EXPECT_EQ(sixtyFour, 0x4);
171  EXPECT_EQ(sixtyFour.bit2, 0x1);
172 }
173 
174 TEST_F(BitUnionData, ReadOnlyBitfield)
175 {
176  EXPECT_EQ(sixtyFour.byte5RO, 0);
177  sixtyFour.byte5 = 0xff;
178  EXPECT_EQ(sixtyFour.byte5RO, 0xff);
179 }
180 
181 TEST_F(BitUnionData, WriteOnlyBitfield)
182 {
183  sixtyFour.byte5WO = 0xff;
184  EXPECT_EQ(sixtyFour, 0xff00000000);
185 }
186 
187 TEST_F(BitUnionData, SubBitUnions)
188 {
189  EXPECT_EQ(sixtyFour.byte6.bit41, 0);
190  sixtyFour.byte6 = 0x2;
191  EXPECT_EQ(sixtyFour.byte6.bit41, 1);
192  sixtyFour.byte6.bits43To42 = 0x3;
193  EXPECT_EQ(sixtyFour.byte6, 0xe);
194  sixtyFour.byte6 = 0xff;
195  sixtyFour.byte6.bit41 = 0;
196  EXPECT_EQ(sixtyFour, 0xfd0000000000);
197 }
198 
199 TEST_F(BitUnionData, SignedBitfields)
200 {
201  sixtyFour.byte6 = 0xff;
202  EXPECT_EQ(sixtyFour.byte6Signed, -1);
203  EXPECT_EQ(sixtyFour.byte6SignedRO, -1);
204  sixtyFour.byte6SignedWO = 0;
205  EXPECT_EQ(sixtyFour.byte6Signed, 0);
206  EXPECT_EQ(sixtyFour.byte6SignedRO, 0);
207  EXPECT_EQ(sixtyFour.byte6, 0);
208 }
209 
210 TEST_F(BitUnionData, InsideStruct)
211 {
212  ContainingStruct containing;
213  containing.contained = 0;
214  containing.contained.topNibble = 0xd;
215  EXPECT_EQ(containing.contained, 0xd000000000000000);
216 }
217 
218 TEST_F(BitUnionData, InsideFunction)
219 {
220  EXPECT_EQ(containingFunc(0xfffff, 0), 0xe7fff);
221 }
222 
223 TEST_F(BitUnionData, BitfieldToBitfieldAssignment)
224 {
225  SixtyFour otherSixtyFour = 0;
226  sixtyFour.bit2 = 1;
227  otherSixtyFour.byte6.bit41 = sixtyFour.bit2;
228  EXPECT_EQ(otherSixtyFour, 0x20000000000);
229  otherSixtyFour.bit2 = sixtyFour.bit2;
230  EXPECT_EQ(otherSixtyFour, 0x20000000004);
231 }
232 
233 TEST_F(BitUnionData, Operators)
234 {
235  SixtyFour otherSixtyFour = 0x4;
236  sixtyFour = otherSixtyFour;
237  EXPECT_EQ(sixtyFour, 0x4);
238  sixtyFour = 0;
239  EXPECT_TRUE(sixtyFour < otherSixtyFour);
240  EXPECT_TRUE(otherSixtyFour > sixtyFour);
241  EXPECT_TRUE(sixtyFour != otherSixtyFour);
242  sixtyFour = otherSixtyFour;
243  EXPECT_TRUE(sixtyFour == otherSixtyFour);
244 }
245 
247 {
248  EXPECT_EQ(split, 0);
249  split.split = 0xfff;
250  EXPECT_EQ(split, 0xf0f0);
251  EXPECT_EQ((uint64_t)split.split, 0xff);
252 }
253 
254 TEST_F(BitUnionData, Templating)
255 {
256  sixtyFour = 0xff;
257  EXPECT_EQ(templatedFunction(sixtyFour), 0xff);
258  EXPECT_EQ(templatedFunction((uint64_t)sixtyFour), 0);
259 
260  BitUnion(uint64_t, Dummy64)
261  EndBitUnion(Dummy64);
262 
263  BitUnion(uint32_t, Dummy32)
264  EndBitUnion(Dummy32);
265 
266  bool is64;
267  is64 = std::is_same_v<BitUnionBaseType<Dummy64>, uint64_t>;
268  EXPECT_TRUE(is64);
269  is64 = std::is_same_v<BitUnionBaseType<Dummy32>, uint64_t>;
270  EXPECT_FALSE(is64);
271 }
272 
274 {
275  sixtyFour = 1234567812345678;
276  std::stringstream ss;
277  ss << sixtyFour;
278  EXPECT_EQ(ss.str(), "1234567812345678");
279  ss.str("");
280 
281  EmptyEight eight = 65;
282  ss << eight;
283  EXPECT_EQ(ss.str(), "65");
284  ss.str("");
285 }
#define BitUnion32(name)
Definition: bitunion.hh:495
#define BitUnion8(name)
Definition: bitunion.hh:497
EmptyThirtyTwo emptyThirtyTwo
EmptySixteen emptySixteen
EmptyEight emptyEight(0)
EmptySixtyFour emptySixtyFour
TEST_F(BitUnionData, NormalBitfield)
uint64_t templatedFunction(BitUnionType< T > u)
void SetUp() override
uint64_t templatedFunction(T)
SixtyFour sixtyFour
#define BitUnion64(name)
Use this to define conveniently sized values overlayed with bitfields.
Definition: bitunion.hh:494
#define SubBitUnion(name, first, last)
Regular bitfields These define macros for read/write regular bitfield based subbitfields.
Definition: bitunion.hh:470
#define EndSubBitUnion(name)
This closes off the union created above and gives it a name.
Definition: bitunion.hh:455
#define BitUnion(type, name)
Use this to define an arbitrary type overlayed with bitfields.
Definition: bitunion.hh:487
typename bitfield_backend::BitUnionBaseType< T >::Type BitUnionBaseType
Definition: bitunion.hh:540
Bitfield< 7 > b
Definition: misc_types.hh:388
Bitfield< 22 > u
Definition: misc_types.hh:359
Bitfield< 63 > val
Definition: misc.hh:776
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
high
Definition: intmath.hh:176
EndBitUnion(PciCommandRegister) union PCIConfig
Definition: pcireg.h:65
BitUnion16(PciCommandRegister) Bitfield< 15
std::stringstream ss
Definition: trace.test.cc:45

Generated on Wed Dec 21 2022 10:22:28 for gem5 by doxygen 1.9.1