/* * Copyright 2014 Google, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer; * redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution; * neither the name of the copyright holders nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Authors: Gabe Black */ #include #include #include #include "base/bitunion.hh" #include "base/cprintf.hh" using namespace std; namespace { BitUnion64(SixtyFour) Bitfield<39, 32> byte5; Bitfield<2> bit2; BitfieldRO<39, 32> byte5RO; BitfieldWO<39, 32> byte5WO; SubBitUnion(byte6, 47, 40) Bitfield<43, 42> bits43To42; Bitfield<41> bit41; SignedBitfield<41> bit41Signed; EndSubBitUnion(byte6) SignedBitfield<47, 40> byte6Signed; SignedBitfieldRO<47, 40> byte6SignedRO; SignedBitfieldWO<47, 40> byte6SignedWO; EndBitUnion(SixtyFour) BitUnion64(EmptySixtyFour) EndBitUnion(EmptySixtyFour) BitUnion32(EmptyThirtyTwo) EndBitUnion(EmptyThirtyTwo) BitUnion16(EmptySixteen) EndBitUnion(EmptySixteen) BitUnion8(EmptyEight) EndBitUnion(EmptyEight) struct ContainingStruct { BitUnion64(Contained) Bitfield<63, 60> topNibble; EndBitUnion(Contained) Contained contained; }; uint64_t containingFunc(uint64_t init_val, uint64_t fieldVal) { BitUnion32(Contained) Bitfield<16, 15> field; EndBitUnion(Contained) Contained contained = init_val; contained.field = fieldVal; return contained; } } // anonymous namespace // Declare these as global so g++ doesn't ignore them. Initialize them in // various ways. EmptySixtyFour emptySixtyFour = 0; EmptyThirtyTwo emptyThirtyTwo; EmptySixteen emptySixteen; EmptyEight emptyEight(0); class BitUnionData : public testing::Test { protected: SixtyFour sixtyFour; void SetUp() override { sixtyFour = 0; } }; TEST_F(BitUnionData, NormalBitfield) { EXPECT_EQ(sixtyFour.byte5, 0); sixtyFour.byte5 = 0xff; EXPECT_EQ(sixtyFour, 0xff00000000); sixtyFour.byte5 = 0xfff; EXPECT_EQ(sixtyFour, 0xff00000000); EXPECT_EQ(sixtyFour.byte5, 0xff); } TEST_F(BitUnionData, SingleBitfield) { EXPECT_EQ(sixtyFour.bit2, 0); sixtyFour.bit2 = 0x1; EXPECT_EQ(sixtyFour, 0x4); EXPECT_EQ(sixtyFour.bit2, 0x1); } TEST_F(BitUnionData, ReadOnlyBitfield) { EXPECT_EQ(sixtyFour.byte5RO, 0); sixtyFour.byte5 = 0xff; EXPECT_EQ(sixtyFour.byte5RO, 0xff); } TEST_F(BitUnionData, WriteOnlyBitfield) { sixtyFour.byte5WO = 0xff; EXPECT_EQ(sixtyFour, 0xff00000000); } TEST_F(BitUnionData, SubBitUnions) { EXPECT_EQ(sixtyFour.byte6.bit41, 0); sixtyFour.byte6 = 0x2; EXPECT_EQ(sixtyFour.byte6.bit41, 1); sixtyFour.byte6.bits43To42 = 0x3; EXPECT_EQ(sixtyFour.byte6, 0xe); sixtyFour.byte6 = 0xff; sixtyFour.byte6.bit41 = 0; EXPECT_EQ(sixtyFour, 0xfd0000000000); } TEST_F(BitUnionData, SignedBitfields) { sixtyFour.byte6 = 0xff; EXPECT_EQ(sixtyFour.byte6Signed, -1); EXPECT_EQ(sixtyFour.byte6SignedRO, -1); sixtyFour.byte6SignedWO = 0; EXPECT_EQ(sixtyFour.byte6Signed, 0); EXPECT_EQ(sixtyFour.byte6SignedRO, 0); EXPECT_EQ(sixtyFour.byte6, 0); } TEST_F(BitUnionData, InsideStruct) { ContainingStruct containing; containing.contained = 0; containing.contained.topNibble = 0xd; EXPECT_EQ(containing.contained, 0xd000000000000000); } TEST_F(BitUnionData, InsideFunction) { EXPECT_EQ(containingFunc(0xfffff, 0), 0xe7fff); } TEST_F(BitUnionData, BitfieldToBitfieldAssignment) { SixtyFour otherSixtyFour = 0; sixtyFour.bit2 = 1; otherSixtyFour.byte6.bit41 = sixtyFour.bit2; EXPECT_EQ(otherSixtyFour, 0x20000000000); otherSixtyFour.bit2 = sixtyFour.bit2; EXPECT_EQ(otherSixtyFour, 0x20000000004); } TEST_F(BitUnionData, Operators) { SixtyFour otherSixtyFour = 0x4; sixtyFour = otherSixtyFour; EXPECT_EQ(sixtyFour, 0x4); sixtyFour = 0; EXPECT_TRUE(sixtyFour < otherSixtyFour); EXPECT_TRUE(otherSixtyFour > sixtyFour); EXPECT_TRUE(sixtyFour != otherSixtyFour); sixtyFour = otherSixtyFour; EXPECT_TRUE(sixtyFour == otherSixtyFour); }