16be2ff7dSConrad Meyer /* 26be2ff7dSConrad Meyer * Copyright (c) 2017 Conrad Meyer <cem@FreeBSD.org> 36be2ff7dSConrad Meyer * All rights reserved. 46be2ff7dSConrad Meyer * 56be2ff7dSConrad Meyer * Redistribution and use in source and binary forms, with or without 66be2ff7dSConrad Meyer * modification, are permitted provided that the following conditions 76be2ff7dSConrad Meyer * are met: 86be2ff7dSConrad Meyer * 1. Redistributions of source code must retain the above copyright 96be2ff7dSConrad Meyer * notice, this list of conditions and the following disclaimer. 106be2ff7dSConrad Meyer * 2. Redistributions in binary form must reproduce the above copyright 116be2ff7dSConrad Meyer * notice, this list of conditions and the following disclaimer in the 126be2ff7dSConrad Meyer * documentation and/or other materials provided with the distribution. 136be2ff7dSConrad Meyer * 146be2ff7dSConrad Meyer * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 156be2ff7dSConrad Meyer * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 166be2ff7dSConrad Meyer * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 176be2ff7dSConrad Meyer * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 186be2ff7dSConrad Meyer * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 196be2ff7dSConrad Meyer * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 206be2ff7dSConrad Meyer * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 216be2ff7dSConrad Meyer * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 226be2ff7dSConrad Meyer * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 236be2ff7dSConrad Meyer * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 246be2ff7dSConrad Meyer * SUCH DAMAGE. 256be2ff7dSConrad Meyer * 266be2ff7dSConrad Meyer * $FreeBSD$ 276be2ff7dSConrad Meyer */ 286be2ff7dSConrad Meyer 296be2ff7dSConrad Meyer #include <sys/param.h> 306be2ff7dSConrad Meyer 316be2ff7dSConrad Meyer #include <stdint.h> 326be2ff7dSConrad Meyer 336be2ff7dSConrad Meyer #include <atf-c.h> 346be2ff7dSConrad Meyer 35*d7f27102SMichael Tuexen #if defined(__amd64__) || defined(__i386__) 366be2ff7dSConrad Meyer extern uint32_t sse42_crc32c(uint32_t, const unsigned char *, unsigned); 37*d7f27102SMichael Tuexen #elif defined(__aarch64__) 38*d7f27102SMichael Tuexen extern uint32_t armv8_crc32c(uint32_t, const unsigned char *, unsigned); 39*d7f27102SMichael Tuexen #else 40*d7f27102SMichael Tuexen #error These tests are not supported on this platform 41*d7f27102SMichael Tuexen #endif 426be2ff7dSConrad Meyer 436be2ff7dSConrad Meyer ATF_TC_WITHOUT_HEAD(crc32c_basic_correctness); 446be2ff7dSConrad Meyer ATF_TC_BODY(crc32c_basic_correctness, tc) 456be2ff7dSConrad Meyer { 466be2ff7dSConrad Meyer const uint64_t inputs[] = { 476be2ff7dSConrad Meyer 0xf408c634b3a9142, 486be2ff7dSConrad Meyer 0x80539e8c7c352e2b, 496be2ff7dSConrad Meyer 0x62e9121db6e4d649, 506be2ff7dSConrad Meyer 0x899345850ed0a286, 516be2ff7dSConrad Meyer 0x2302df11b4a43b15, 526be2ff7dSConrad Meyer 0xe943de7b3d35d70, 536be2ff7dSConrad Meyer 0xdf1ff2bf41abf56b, 546be2ff7dSConrad Meyer 0x9bc138abae315de2, 556be2ff7dSConrad Meyer 0x31cc82e56234f0ff, 566be2ff7dSConrad Meyer 0xce63c0cd6988e847, 576be2ff7dSConrad Meyer 0x3e42f6b78ee352fa, 586be2ff7dSConrad Meyer 0xfa4085436078cfa6, 596be2ff7dSConrad Meyer 0x53349558bf670a4b, 606be2ff7dSConrad Meyer 0x2714e10e7d722c61, 616be2ff7dSConrad Meyer 0xc0d3261addfc6908, 626be2ff7dSConrad Meyer 0xd1567c3181d3a1bf, 636be2ff7dSConrad Meyer }; 646be2ff7dSConrad Meyer const uint32_t results[] = { 656be2ff7dSConrad Meyer 0x2ce33ede, 666be2ff7dSConrad Meyer 0xc49cc573, 676be2ff7dSConrad Meyer 0xb8683c96, 686be2ff7dSConrad Meyer 0x6918660d, 696be2ff7dSConrad Meyer 0xa904e522, 706be2ff7dSConrad Meyer 0x52dbc42c, 716be2ff7dSConrad Meyer 0x98863c22, 726be2ff7dSConrad Meyer 0x894d5d2c, 736be2ff7dSConrad Meyer 0xb003745d, 746be2ff7dSConrad Meyer 0xfc496dbd, 756be2ff7dSConrad Meyer 0x97d2fbb5, 766be2ff7dSConrad Meyer 0x3c062ef1, 776be2ff7dSConrad Meyer 0xcc2eff18, 786be2ff7dSConrad Meyer 0x6a9b09f6, 796be2ff7dSConrad Meyer 0x420242c1, 806be2ff7dSConrad Meyer 0xfd562dc3, 816be2ff7dSConrad Meyer }; 826be2ff7dSConrad Meyer size_t i; 836be2ff7dSConrad Meyer uint32_t act; 846be2ff7dSConrad Meyer 856be2ff7dSConrad Meyer ATF_REQUIRE(nitems(inputs) == nitems(results)); 866be2ff7dSConrad Meyer 876be2ff7dSConrad Meyer for (i = 0; i < nitems(inputs); i++) { 88*d7f27102SMichael Tuexen #if defined(__amd64__) || defined(__i386__) 896be2ff7dSConrad Meyer act = sse42_crc32c(~0, (const void *)&inputs[i], 906be2ff7dSConrad Meyer sizeof(inputs[0])); 91*d7f27102SMichael Tuexen #else 92*d7f27102SMichael Tuexen act = armv8_crc32c(~0, (const void *)&inputs[i], 93*d7f27102SMichael Tuexen sizeof(inputs[0])); 94*d7f27102SMichael Tuexen #endif 956be2ff7dSConrad Meyer ATF_REQUIRE_MSG(act == results[i], 966be2ff7dSConrad Meyer "crc32c(0x%jx) = 0x%08x, got 0x%08x", (uintmax_t)inputs[i], 976be2ff7dSConrad Meyer results[i], act); 986be2ff7dSConrad Meyer } 996be2ff7dSConrad Meyer } 1006be2ff7dSConrad Meyer 1016be2ff7dSConrad Meyer ATF_TC_WITHOUT_HEAD(crc32c_alignment); 1026be2ff7dSConrad Meyer ATF_TC_BODY(crc32c_alignment, tc) 1036be2ff7dSConrad Meyer { 1046be2ff7dSConrad Meyer const uint64_t input = 0xf408c634b3a9142; 1056be2ff7dSConrad Meyer const uint32_t result = 0x2ce33ede; 1066be2ff7dSConrad Meyer unsigned char buf[15]; 1076be2ff7dSConrad Meyer size_t i; 1086be2ff7dSConrad Meyer uint32_t act; 1096be2ff7dSConrad Meyer 1106be2ff7dSConrad Meyer 1116be2ff7dSConrad Meyer for (i = 1; i < 8; i++) { 1126be2ff7dSConrad Meyer memcpy(&buf[i], &input, sizeof(input)); 1136be2ff7dSConrad Meyer 114*d7f27102SMichael Tuexen #if defined(__amd64__) || defined(__i386__) 1156be2ff7dSConrad Meyer act = sse42_crc32c(~0, (const void *)&buf[i], sizeof(input)); 116*d7f27102SMichael Tuexen #else 117*d7f27102SMichael Tuexen act = armv8_crc32c(~0, (const void *)&buf[i], sizeof(input)); 118*d7f27102SMichael Tuexen #endif 1196be2ff7dSConrad Meyer ATF_REQUIRE_MSG(act == result, 1206be2ff7dSConrad Meyer "crc32c(0x%jx) = 0x%08x, got 0x%08x", (uintmax_t)input, 1216be2ff7dSConrad Meyer result, act); 1226be2ff7dSConrad Meyer } 1236be2ff7dSConrad Meyer } 1246be2ff7dSConrad Meyer 1256be2ff7dSConrad Meyer ATF_TC_WITHOUT_HEAD(crc32c_trailing_bytes); 1266be2ff7dSConrad Meyer ATF_TC_BODY(crc32c_trailing_bytes, tc) 1276be2ff7dSConrad Meyer { 1286be2ff7dSConrad Meyer const unsigned char input[] = { 1296be2ff7dSConrad Meyer 0x87, 0x54, 0x74, 0xd2, 0xb, 0x9b, 0xdd, 0xf6, 0x68, 0x37, 1306be2ff7dSConrad Meyer 0xd4, 0x4, 0x5e, 0xa9, 0xb3 1316be2ff7dSConrad Meyer }; 1326be2ff7dSConrad Meyer const uint32_t result = 0xec638d62; 1336be2ff7dSConrad Meyer uint32_t act; 1346be2ff7dSConrad Meyer 135*d7f27102SMichael Tuexen #if defined(__amd64__) || defined(__i386__) 1366be2ff7dSConrad Meyer act = sse42_crc32c(~0, input, sizeof(input)); 137*d7f27102SMichael Tuexen #else 138*d7f27102SMichael Tuexen act = armv8_crc32c(~0, input, sizeof(input)); 139*d7f27102SMichael Tuexen #endif 1406be2ff7dSConrad Meyer ATF_REQUIRE_MSG(act == result, "expected 0x%08x, got 0x%08x", result, 1416be2ff7dSConrad Meyer act); 1426be2ff7dSConrad Meyer } 1436be2ff7dSConrad Meyer 1446be2ff7dSConrad Meyer ATF_TP_ADD_TCS(tp) 1456be2ff7dSConrad Meyer { 1466be2ff7dSConrad Meyer 1476be2ff7dSConrad Meyer ATF_TP_ADD_TC(tp, crc32c_basic_correctness); 1486be2ff7dSConrad Meyer ATF_TP_ADD_TC(tp, crc32c_alignment); 1496be2ff7dSConrad Meyer ATF_TP_ADD_TC(tp, crc32c_trailing_bytes); 1506be2ff7dSConrad Meyer return (atf_no_error()); 1516be2ff7dSConrad Meyer } 152