gem5  v21.0.0.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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 namespace {
38 
39 BitUnion64(SixtyFour)
40  Bitfield<39, 32> byte5;
41  Bitfield<2> bit2;
42  BitfieldRO<39, 32> byte5RO;
43  BitfieldWO<39, 32> byte5WO;
44  SubBitUnion(byte6, 47, 40)
45  Bitfield<43, 42> bits43To42;
46  Bitfield<41> bit41;
47  SignedBitfield<41> bit41Signed;
48  EndSubBitUnion(byte6)
49  SignedBitfield<47, 40> byte6Signed;
50  SignedBitfieldRO<47, 40> byte6SignedRO;
51  SignedBitfieldWO<47, 40> byte6SignedWO;
52 EndBitUnion(SixtyFour)
53 
54 BitUnion64(EmptySixtyFour)
55 EndBitUnion(EmptySixtyFour)
56 
57 BitUnion32(EmptyThirtyTwo)
58 EndBitUnion(EmptyThirtyTwo)
59 
60 BitUnion16(EmptySixteen)
61 EndBitUnion(EmptySixteen)
62 
63 BitUnion8(EmptyEight)
64 EndBitUnion(EmptyEight)
65 
66 class SplitField
67 {
68  protected:
69  BitUnion64(In)
70  Bitfield<15, 12> high;
71  Bitfield<7, 4> low;
72  EndBitUnion(In)
73 
74  BitUnion64(Out)
75  Bitfield<7, 4> high;
76  Bitfield<3, 0> low;
77  EndBitUnion(Out)
78  public:
79  uint64_t
80  getter(const uint64_t &storage) const
81  {
82  Out out = 0;
83  In in = storage;
84  out.high = in.high;
85  out.low = in.low;
86  return out;
87  }
88 
89  void
90  setter(uint64_t &storage, uint64_t val)
91  {
92  Out out = val;
93  In in = 0;
94  in.high = out.high;
95  in.low = out.low;
96  storage = in;
97  }
98 };
99 
100 BitUnion64(Split)
102 EndBitUnion(Split)
103 
104 struct ContainingStruct
105 {
106  BitUnion64(Contained)
107  Bitfield<63, 60> topNibble;
108  EndBitUnion(Contained)
109 
110  Contained contained;
111 };
112 
113 uint64_t
114 containingFunc(uint64_t init_val, uint64_t fieldVal)
115 {
116  BitUnion32(Contained)
117  Bitfield<16, 15> field;
118  EndBitUnion(Contained)
119 
120  Contained contained = init_val;
121  contained.field = fieldVal;
122  return contained;
123 }
124 
125 } // anonymous namespace
126 
127 // Declare these as global so g++ doesn't ignore them. Initialize them in
128 // various ways.
129 EmptySixtyFour emptySixtyFour = 0;
130 EmptyThirtyTwo emptyThirtyTwo;
131 EmptySixteen emptySixteen;
132 EmptyEight emptyEight(0);
133 
134 class BitUnionData : public testing::Test {
135  protected:
136  SixtyFour sixtyFour;
137  Split split;
138 
139  void SetUp() override { sixtyFour = 0; split = 0; }
140 
141  template <typename T>
142  uint64_t templatedFunction(T) { return 0; }
143 
144  template <typename T>
145  uint64_t
147  {
149  return b;
150  }
151 };
152 
153 TEST_F(BitUnionData, NormalBitfield)
154 {
155  EXPECT_EQ(sixtyFour.byte5, 0);
156  sixtyFour.byte5 = 0xff;
157  EXPECT_EQ(sixtyFour, 0xff00000000);
158  sixtyFour.byte5 = 0xfff;
159  EXPECT_EQ(sixtyFour, 0xff00000000);
160  EXPECT_EQ(sixtyFour.byte5, 0xff);
161 }
162 
163 TEST_F(BitUnionData, SingleBitfield)
164 {
165  EXPECT_EQ(sixtyFour.bit2, 0);
166  sixtyFour.bit2 = 0x1;
167  EXPECT_EQ(sixtyFour, 0x4);
168  EXPECT_EQ(sixtyFour.bit2, 0x1);
169 }
170 
171 TEST_F(BitUnionData, ReadOnlyBitfield)
172 {
173  EXPECT_EQ(sixtyFour.byte5RO, 0);
174  sixtyFour.byte5 = 0xff;
175  EXPECT_EQ(sixtyFour.byte5RO, 0xff);
176 }
177 
178 TEST_F(BitUnionData, WriteOnlyBitfield)
179 {
180  sixtyFour.byte5WO = 0xff;
181  EXPECT_EQ(sixtyFour, 0xff00000000);
182 }
183 
184 TEST_F(BitUnionData, SubBitUnions)
185 {
186  EXPECT_EQ(sixtyFour.byte6.bit41, 0);
187  sixtyFour.byte6 = 0x2;
188  EXPECT_EQ(sixtyFour.byte6.bit41, 1);
189  sixtyFour.byte6.bits43To42 = 0x3;
190  EXPECT_EQ(sixtyFour.byte6, 0xe);
191  sixtyFour.byte6 = 0xff;
192  sixtyFour.byte6.bit41 = 0;
193  EXPECT_EQ(sixtyFour, 0xfd0000000000);
194 }
195 
196 TEST_F(BitUnionData, SignedBitfields)
197 {
198  sixtyFour.byte6 = 0xff;
199  EXPECT_EQ(sixtyFour.byte6Signed, -1);
200  EXPECT_EQ(sixtyFour.byte6SignedRO, -1);
201  sixtyFour.byte6SignedWO = 0;
202  EXPECT_EQ(sixtyFour.byte6Signed, 0);
203  EXPECT_EQ(sixtyFour.byte6SignedRO, 0);
204  EXPECT_EQ(sixtyFour.byte6, 0);
205 }
206 
207 TEST_F(BitUnionData, InsideStruct)
208 {
209  ContainingStruct containing;
210  containing.contained = 0;
211  containing.contained.topNibble = 0xd;
212  EXPECT_EQ(containing.contained, 0xd000000000000000);
213 }
214 
215 TEST_F(BitUnionData, InsideFunction)
216 {
217  EXPECT_EQ(containingFunc(0xfffff, 0), 0xe7fff);
218 }
219 
220 TEST_F(BitUnionData, BitfieldToBitfieldAssignment)
221 {
222  SixtyFour otherSixtyFour = 0;
223  sixtyFour.bit2 = 1;
224  otherSixtyFour.byte6.bit41 = sixtyFour.bit2;
225  EXPECT_EQ(otherSixtyFour, 0x20000000000);
226  otherSixtyFour.bit2 = sixtyFour.bit2;
227  EXPECT_EQ(otherSixtyFour, 0x20000000004);
228 }
229 
230 TEST_F(BitUnionData, Operators)
231 {
232  SixtyFour otherSixtyFour = 0x4;
233  sixtyFour = otherSixtyFour;
234  EXPECT_EQ(sixtyFour, 0x4);
235  sixtyFour = 0;
236  EXPECT_TRUE(sixtyFour < otherSixtyFour);
237  EXPECT_TRUE(otherSixtyFour > sixtyFour);
238  EXPECT_TRUE(sixtyFour != otherSixtyFour);
239  sixtyFour = otherSixtyFour;
240  EXPECT_TRUE(sixtyFour == otherSixtyFour);
241 }
242 
244 {
245  EXPECT_EQ(split, 0);
246  split.split = 0xfff;
247  EXPECT_EQ(split, 0xf0f0);
248  EXPECT_EQ((uint64_t)split.split, 0xff);
249 }
250 
251 TEST_F(BitUnionData, Templating)
252 {
253  sixtyFour = 0xff;
254  EXPECT_EQ(templatedFunction(sixtyFour), 0xff);
255  EXPECT_EQ(templatedFunction((uint64_t)sixtyFour), 0);
256 
257  BitUnion(uint64_t, Dummy64)
258  EndBitUnion(Dummy64);
259 
260  BitUnion(uint32_t, Dummy32)
261  EndBitUnion(Dummy32);
262 
263  bool is64;
264  is64 = std::is_same<BitUnionBaseType<Dummy64>, uint64_t>::value;
265  EXPECT_TRUE(is64);
266  is64 = std::is_same<BitUnionBaseType<Dummy32>, uint64_t>::value;
267  EXPECT_FALSE(is64);
268 }
269 
271 {
272  sixtyFour = 1234567812345678;
273  std::stringstream ss;
274  ss << sixtyFour;
275  EXPECT_EQ(ss.str(), "1234567812345678");
276  ss.str("");
277 
278  EmptyEight eight = 65;
279  ss << eight;
280  EXPECT_EQ(ss.str(), "65");
281  ss.str("");
282 }
BitUnion
#define BitUnion(type, name)
Use this to define an arbitrary type overlayed with bitfields.
Definition: bitunion.hh:484
BitUnionData
Definition: bitunion.test.cc:134
PowerISA::xe
Bitfield< 4 > xe
Definition: miscregs.hh:91
emptySixteen
EmptySixteen emptySixteen
Definition: bitunion.test.cc:131
TEST_F
TEST_F(BitUnionData, NormalBitfield)
Definition: bitunion.test.cc:153
BitUnion32
#define BitUnion32(name)
Definition: bitunion.hh:492
emptySixtyFour
EmptySixtyFour emptySixtyFour
Definition: bitunion.test.cc:129
BitUnion64
#define BitUnion64(name)
Use this to define conveniently sized values overlayed with bitfields.
Definition: bitunion.hh:491
BitUnionData::split
Split split
Definition: bitunion.test.cc:137
ArmISA::ss
Bitfield< 21 > ss
Definition: miscregs_types.hh:56
EndSubBitUnion
#define EndSubBitUnion(name)
This closes off the union created above and gives it a name.
Definition: bitunion.hh:452
EndBitUnion
EndBitUnion(PciCommandRegister) union PCIConfig
Definition: pcireg.h:65
SubBitUnion
#define SubBitUnion(name, first, last)
Regular bitfields These define macros for read/write regular bitfield based subbitfields.
Definition: bitunion.hh:467
bitunion.hh
BitUnionData::sixtyFour
SixtyFour sixtyFour
Definition: bitunion.test.cc:136
BitUnion8
#define BitUnion8(name)
Definition: bitunion.hh:494
cprintf.hh
emptyThirtyTwo
EmptyThirtyTwo emptyThirtyTwo
Definition: bitunion.test.cc:130
BitfieldType
Definition: bitunion.hh:114
BitfieldBackend::BitUnionOperators
Definition: bitunion.hh:248
X86ISA::val
Bitfield< 63 > val
Definition: misc.hh:769
ArmISA::u
Bitfield< 22 > u
Definition: miscregs_types.hh:348
BitUnion16
BitUnion16(PciCommandRegister) Bitfield< 15
ArmISA::b
Bitfield< 7 > b
Definition: miscregs_types.hh:376
BitUnionData::SetUp
void SetUp() override
Definition: bitunion.test.cc:139
BitUnionData::templatedFunction
uint64_t templatedFunction(BitUnionType< T > u)
Definition: bitunion.test.cc:146
BitUnionData::templatedFunction
uint64_t templatedFunction(T)
Definition: bitunion.test.cc:142
emptyEight
EmptyEight emptyEight(0)
BitUnionBaseType
typename BitfieldBackend::BitUnionBaseType< T >::Type BitUnionBaseType
Definition: bitunion.hh:537

Generated on Tue Mar 23 2021 19:41:23 for gem5 by doxygen 1.8.17