252 lines · cpp
1//===- unittests/Support/EndianTest.cpp - Endian.h tests ------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/Support/Endian.h"10#include "llvm/Support/DataTypes.h"11#include "gtest/gtest.h"12#include <cstdlib>13#include <ctime>14using namespace llvm;15using namespace support;16 17#undef max18 19namespace {20 21TEST(Endian, Read) {22 // These are 5 bytes so we can be sure at least one of the reads is unaligned.23 unsigned char bigval[] = {0x00, 0x01, 0x02, 0x03, 0x04};24 unsigned char littleval[] = {0x00, 0x04, 0x03, 0x02, 0x01};25 int32_t BigAsHost = 0x00010203;26 EXPECT_EQ(BigAsHost,27 (endian::read<int32_t, unaligned>(bigval, llvm::endianness::big)));28 int32_t LittleAsHost = 0x02030400;29 EXPECT_EQ(LittleAsHost, (endian::read<int32_t, unaligned>(30 littleval, llvm::endianness::little)));31 32 EXPECT_EQ(33 (endian::read<int32_t, unaligned>(bigval + 1, llvm::endianness::big)),34 (endian::read<int32_t, unaligned>(littleval + 1,35 llvm::endianness::little)));36}37 38TEST(Endian, WriteNext) {39 unsigned char bigval[] = {0x00, 0x00}, *p = bigval;40 endian::writeNext<int16_t, llvm::endianness::big>(p, short(0xaabb));41 EXPECT_EQ(bigval[0], 0xaa);42 EXPECT_EQ(bigval[1], 0xbb);43 EXPECT_EQ(p, bigval + 2);44 45 char littleval[8] = {}, *q = littleval;46 endian::writeNext<uint32_t, llvm::endianness::little>(q, 0x44556677);47 EXPECT_EQ(littleval[0], 0x77);48 EXPECT_EQ(littleval[1], 0x66);49 EXPECT_EQ(littleval[2], 0x55);50 EXPECT_EQ(littleval[3], 0x44);51 EXPECT_EQ(q, littleval + 4);52 53 endian::writeNext<uint32_t>(q, 0x11223344, llvm::endianness::little);54 EXPECT_EQ(littleval[4], 0x44);55 EXPECT_EQ(littleval[5], 0x33);56 EXPECT_EQ(littleval[6], 0x22);57 EXPECT_EQ(littleval[7], 0x11);58 EXPECT_EQ(q, littleval + 8);59}60 61TEST(Endian, ReadBitAligned) {62 // Simple test to make sure we properly pull out the 0x0 word.63 unsigned char littleval[] = {0x3f, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff};64 unsigned char bigval[] = {0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0};65 EXPECT_EQ(66 (endian::readAtBitAlignment<int, llvm::endianness::little, unaligned>(67 &littleval[0], 6)),68 0x0);69 EXPECT_EQ((endian::readAtBitAlignment<int, llvm::endianness::big, unaligned>(70 &bigval[0], 6)),71 0x0);72 // Test to make sure that signed right shift of 0xf0000000 is masked73 // properly.74 unsigned char littleval2[] = {0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00};75 unsigned char bigval2[] = {0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};76 EXPECT_EQ(77 (endian::readAtBitAlignment<int, llvm::endianness::little, unaligned>(78 &littleval2[0], 4)),79 0x0f000000);80 EXPECT_EQ((endian::readAtBitAlignment<int, llvm::endianness::big, unaligned>(81 &bigval2[0], 4)),82 0x0f000000);83 // Test to make sure left shift of start bit doesn't overflow.84 EXPECT_EQ(85 (endian::readAtBitAlignment<int, llvm::endianness::little, unaligned>(86 &littleval2[0], 1)),87 0x78000000);88 EXPECT_EQ((endian::readAtBitAlignment<int, llvm::endianness::big, unaligned>(89 &bigval2[0], 1)),90 0x78000000);91 // Test to make sure 64-bit int doesn't overflow.92 unsigned char littleval3[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,93 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};94 unsigned char bigval3[] = {0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,95 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};96 EXPECT_EQ(97 (endian::readAtBitAlignment<int64_t, llvm::endianness::little, unaligned>(98 &littleval3[0], 4)),99 0x0f00000000000000);100 EXPECT_EQ(101 (endian::readAtBitAlignment<int64_t, llvm::endianness::big, unaligned>(102 &bigval3[0], 4)),103 0x0f00000000000000);104}105 106TEST(Endian, WriteBitAligned) {107 // This test ensures that signed right shift of 0xffffaa is masked108 // properly.109 unsigned char bigval[8] = {0x00};110 endian::writeAtBitAlignment<int32_t, llvm::endianness::big, unaligned>(111 bigval, (int)0xffffaaaa, 4);112 EXPECT_EQ(bigval[0], 0xff);113 EXPECT_EQ(bigval[1], 0xfa);114 EXPECT_EQ(bigval[2], 0xaa);115 EXPECT_EQ(bigval[3], 0xa0);116 EXPECT_EQ(bigval[4], 0x00);117 EXPECT_EQ(bigval[5], 0x00);118 EXPECT_EQ(bigval[6], 0x00);119 EXPECT_EQ(bigval[7], 0x0f);120 121 unsigned char littleval[8] = {0x00};122 endian::writeAtBitAlignment<int32_t, llvm::endianness::little, unaligned>(123 littleval, (int)0xffffaaaa, 4);124 EXPECT_EQ(littleval[0], 0xa0);125 EXPECT_EQ(littleval[1], 0xaa);126 EXPECT_EQ(littleval[2], 0xfa);127 EXPECT_EQ(littleval[3], 0xff);128 EXPECT_EQ(littleval[4], 0x0f);129 EXPECT_EQ(littleval[5], 0x00);130 EXPECT_EQ(littleval[6], 0x00);131 EXPECT_EQ(littleval[7], 0x00);132 133 // This test makes sure 1<<31 doesn't overflow.134 // Test to make sure left shift of start bit doesn't overflow.135 unsigned char bigval2[8] = {0x00};136 endian::writeAtBitAlignment<int32_t, llvm::endianness::big, unaligned>(137 bigval2, (int)0xffffffff, 1);138 EXPECT_EQ(bigval2[0], 0xff);139 EXPECT_EQ(bigval2[1], 0xff);140 EXPECT_EQ(bigval2[2], 0xff);141 EXPECT_EQ(bigval2[3], 0xfe);142 EXPECT_EQ(bigval2[4], 0x00);143 EXPECT_EQ(bigval2[5], 0x00);144 EXPECT_EQ(bigval2[6], 0x00);145 EXPECT_EQ(bigval2[7], 0x01);146 147 unsigned char littleval2[8] = {0x00};148 endian::writeAtBitAlignment<int32_t, llvm::endianness::little, unaligned>(149 littleval2, (int)0xffffffff, 1);150 EXPECT_EQ(littleval2[0], 0xfe);151 EXPECT_EQ(littleval2[1], 0xff);152 EXPECT_EQ(littleval2[2], 0xff);153 EXPECT_EQ(littleval2[3], 0xff);154 EXPECT_EQ(littleval2[4], 0x01);155 EXPECT_EQ(littleval2[5], 0x00);156 EXPECT_EQ(littleval2[6], 0x00);157 EXPECT_EQ(littleval2[7], 0x00);158 159 // Test to make sure 64-bit int doesn't overflow.160 unsigned char bigval64[16] = {0x00};161 endian::writeAtBitAlignment<int64_t, llvm::endianness::big, unaligned>(162 bigval64, (int64_t)0xffffffffffffffff, 1);163 EXPECT_EQ(bigval64[0], 0xff);164 EXPECT_EQ(bigval64[1], 0xff);165 EXPECT_EQ(bigval64[2], 0xff);166 EXPECT_EQ(bigval64[3], 0xff);167 EXPECT_EQ(bigval64[4], 0xff);168 EXPECT_EQ(bigval64[5], 0xff);169 EXPECT_EQ(bigval64[6], 0xff);170 EXPECT_EQ(bigval64[7], 0xfe);171 EXPECT_EQ(bigval64[8], 0x00);172 EXPECT_EQ(bigval64[9], 0x00);173 EXPECT_EQ(bigval64[10], 0x00);174 EXPECT_EQ(bigval64[11], 0x00);175 EXPECT_EQ(bigval64[12], 0x00);176 EXPECT_EQ(bigval64[13], 0x00);177 EXPECT_EQ(bigval64[14], 0x00);178 EXPECT_EQ(bigval64[15], 0x01);179 180 unsigned char littleval64[16] = {0x00};181 endian::writeAtBitAlignment<int64_t, llvm::endianness::little, unaligned>(182 littleval64, (int64_t)0xffffffffffffffff, 1);183 EXPECT_EQ(littleval64[0], 0xfe);184 EXPECT_EQ(littleval64[1], 0xff);185 EXPECT_EQ(littleval64[2], 0xff);186 EXPECT_EQ(littleval64[3], 0xff);187 EXPECT_EQ(littleval64[4], 0xff);188 EXPECT_EQ(littleval64[5], 0xff);189 EXPECT_EQ(littleval64[6], 0xff);190 EXPECT_EQ(littleval64[7], 0xff);191 EXPECT_EQ(littleval64[8], 0x01);192 EXPECT_EQ(littleval64[9], 0x00);193 EXPECT_EQ(littleval64[10], 0x00);194 EXPECT_EQ(littleval64[11], 0x00);195 EXPECT_EQ(littleval64[12], 0x00);196 EXPECT_EQ(littleval64[13], 0x00);197 EXPECT_EQ(littleval64[14], 0x00);198 EXPECT_EQ(littleval64[15], 0x00);199}200 201TEST(Endian, Write) {202 unsigned char data[5];203 endian::write<int32_t, unaligned>(data, -1362446643, llvm::endianness::big);204 EXPECT_EQ(data[0], 0xAE);205 EXPECT_EQ(data[1], 0xCA);206 EXPECT_EQ(data[2], 0xB6);207 EXPECT_EQ(data[3], 0xCD);208 endian::write<int32_t, unaligned>(data + 1, -1362446643,209 llvm::endianness::big);210 EXPECT_EQ(data[1], 0xAE);211 EXPECT_EQ(data[2], 0xCA);212 EXPECT_EQ(data[3], 0xB6);213 EXPECT_EQ(data[4], 0xCD);214 215 endian::write<int32_t, unaligned>(data, -1362446643,216 llvm::endianness::little);217 EXPECT_EQ(data[0], 0xCD);218 EXPECT_EQ(data[1], 0xB6);219 EXPECT_EQ(data[2], 0xCA);220 EXPECT_EQ(data[3], 0xAE);221 endian::write<int32_t, unaligned>(data + 1, -1362446643,222 llvm::endianness::little);223 EXPECT_EQ(data[1], 0xCD);224 EXPECT_EQ(data[2], 0xB6);225 EXPECT_EQ(data[3], 0xCA);226 EXPECT_EQ(data[4], 0xAE);227}228 229TEST(Endian, PackedEndianSpecificIntegral) {230 // These are 5 bytes so we can be sure at least one of the reads is unaligned.231 unsigned char big[] = {0x00, 0x01, 0x02, 0x03, 0x04};232 unsigned char little[] = {0x00, 0x04, 0x03, 0x02, 0x01};233 big32_t *big_val =234 reinterpret_cast<big32_t *>(big + 1);235 little32_t *little_val =236 reinterpret_cast<little32_t *>(little + 1);237 238 EXPECT_EQ(*big_val, *little_val);239 EXPECT_EQ(big_val->value(), little_val->value());240}241 242TEST(Endian, PacketEndianSpecificIntegralAsEnum) {243 enum class Test : uint16_t { ONETWO = 0x0102, TWOONE = 0x0201 };244 unsigned char bytes[] = {0x01, 0x02};245 using LittleTest = little_t<Test>;246 using BigTest = big_t<Test>;247 EXPECT_EQ(Test::TWOONE, *reinterpret_cast<LittleTest *>(bytes));248 EXPECT_EQ(Test::ONETWO, *reinterpret_cast<BigTest *>(bytes));249}250 251} // end anon namespace252