mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-05-23 05:42:29 +00:00
Add x86_64-linux-gnu emulator
I wanted a tiny scriptable meltdown proof way to run userspace programs and visualize how program execution impacts memory. It helps to explain how things like Actually Portable Executable works. It can show you how the GCC generated code is going about manipulating matrices and more. I didn't feel fully comfortable with Qemu and Bochs because I'm not smart enough to understand them. I wanted something like gVisor but with much stronger levels of assurances. I wanted a single binary that'll run, on all major operating systems with an embedded GPL barrier ZIP filesystem that is tiny enough to transpile to JavaScript and run in browsers too. https://justine.storage.googleapis.com/emulator625.mp4
This commit is contained in:
parent
467504308a
commit
f4f4caab0e
1052 changed files with 65667 additions and 7825 deletions
|
@ -24,23 +24,22 @@
|
|||
STATIC_YOINK("realloc");
|
||||
|
||||
TEST(tarjan, empty_doesNothing) {
|
||||
uint32_t sorted_vertices[1] = {-1u};
|
||||
uint32_t edges[][2] = {{0, 0}};
|
||||
uint32_t vertex_count = 0;
|
||||
uint32_t edge_count = 0;
|
||||
int sorted_vertices[1] = {-1};
|
||||
int edges[][2] = {{0, 0}};
|
||||
int vertex_count = 0;
|
||||
int edge_count = 0;
|
||||
tarjan(vertex_count, (void *)edges, edge_count, sorted_vertices, NULL, NULL);
|
||||
ASSERT_EQ(-1u, sorted_vertices[0]);
|
||||
ASSERT_EQ(-1, sorted_vertices[0]);
|
||||
}
|
||||
|
||||
TEST(tarjan, topologicalSort_noCycles) {
|
||||
enum VertexIndex { A = 0, B = 1, C = 2, D = 3 };
|
||||
const char *const vertices[] = {[A] = "A", [B] = "B", [C] = "C", [D] = "D"};
|
||||
uint32_t edges[][2] = {
|
||||
{A /* depends on → */, B /* which must come before A */},
|
||||
{A /* depends on → */, C /* which must come before A */},
|
||||
{A /* depends on → */, D /* which must come before A */},
|
||||
{B /* depends on → */, C /* which must come before B */},
|
||||
{B /* depends on → */, D /* which must come before B */}};
|
||||
int edges[][2] = {{A /* depends on → */, B /* which must come before A */},
|
||||
{A /* depends on → */, C /* which must come before A */},
|
||||
{A /* depends on → */, D /* which must come before A */},
|
||||
{B /* depends on → */, C /* which must come before B */},
|
||||
{B /* depends on → */, D /* which must come before B */}};
|
||||
/*
|
||||
$ tsort <<EOF
|
||||
B A
|
||||
|
@ -54,7 +53,7 @@ TEST(tarjan, topologicalSort_noCycles) {
|
|||
B
|
||||
A
|
||||
*/
|
||||
uint32_t sorted[4], components[4], componentcount;
|
||||
int sorted[4], components[4], componentcount;
|
||||
ASSERT_EQ(0, tarjan(ARRAYLEN(vertices), (void *)edges, ARRAYLEN(edges),
|
||||
sorted, components, &componentcount));
|
||||
EXPECT_EQ(C, sorted[0]);
|
||||
|
@ -73,12 +72,11 @@ TEST(tarjan, testOneBigCycle_isDetected_weDontCareAboutOrderInsideTheCycle) {
|
|||
const char *const vertices[] = {[A] = "A", [B] = "B", [C] = "C", [D] = "D"};
|
||||
/* ┌─────────┐
|
||||
└→A→B→C→D─┘ */
|
||||
uint32_t edges[][2] = {
|
||||
{A /* depends on → */, B /* which must come before A */},
|
||||
{B /* depends on → */, C /* which must come before B */},
|
||||
{C /* depends on → */, D /* which must come before C */},
|
||||
{D /* depends on → */, A /* which must come before D */}};
|
||||
uint32_t sorted[4], components[4], componentcount;
|
||||
int edges[][2] = {{A /* depends on → */, B /* which must come before A */},
|
||||
{B /* depends on → */, C /* which must come before B */},
|
||||
{C /* depends on → */, D /* which must come before C */},
|
||||
{D /* depends on → */, A /* which must come before D */}};
|
||||
int sorted[4], components[4], componentcount;
|
||||
ASSERT_EQ(0, tarjan(ARRAYLEN(vertices), (void *)edges, ARRAYLEN(edges),
|
||||
sorted, components, &componentcount));
|
||||
ASSERT_EQ(1, componentcount);
|
||||
|
@ -104,15 +102,15 @@ TEST(tarjan, testHeaders) {
|
|||
[LIBC_MACROS] = "libc/macros.h",
|
||||
[LIBC_MACROS_CPP] = "libc/macros-cpp.inc",
|
||||
};
|
||||
uint32_t edges[][2] = {
|
||||
int edges[][2] = {
|
||||
{LIBC_STR_STR, LIBC_BITS_BITS}, {LIBC_STR_STR, LIBC_INTEGRAL},
|
||||
{LIBC_STR_STR, LIBC_KEYWORDS}, {LIBC_BITS_BITS, LIBC_DCE},
|
||||
{LIBC_BITS_BITS, LIBC_INTEGRAL}, {LIBC_BITS_BITS, LIBC_KEYWORDS},
|
||||
{LIBC_BITS_BITS, LIBC_MACROS}, {LIBC_MACROS, LIBC_MACROS_CPP},
|
||||
};
|
||||
uint32_t sorted[ARRAYLEN(vertices)];
|
||||
uint32_t components[ARRAYLEN(vertices)];
|
||||
uint32_t componentcount;
|
||||
int sorted[ARRAYLEN(vertices)];
|
||||
int components[ARRAYLEN(vertices)];
|
||||
int componentcount;
|
||||
ASSERT_EQ(0, tarjan(ARRAYLEN(vertices), (void *)edges, ARRAYLEN(edges),
|
||||
sorted, components, &componentcount));
|
||||
ASSERT_EQ(ARRAYLEN(vertices), componentcount);
|
||||
|
|
|
@ -5,13 +5,18 @@ PKGS += TEST_LIBC_ALG
|
|||
|
||||
TEST_LIBC_ALG_SRCS := $(wildcard test/libc/alg/*.c)
|
||||
TEST_LIBC_ALG_SRCS_TEST = $(filter %_test.c,$(TEST_LIBC_ALG_SRCS))
|
||||
TEST_LIBC_ALG_COMS = $(TEST_LIBC_ALG_OBJS:%.o=%.com)
|
||||
TEST_LIBC_ALG_BINS = $(TEST_LIBC_ALG_COMS) $(TEST_LIBC_ALG_COMS:%=%.dbg)
|
||||
|
||||
TEST_LIBC_ALG_OBJS = \
|
||||
$(TEST_LIBC_ALG_SRCS:%=o/$(MODE)/%.zip.o) \
|
||||
$(TEST_LIBC_ALG_SRCS:%.c=o/$(MODE)/%.o)
|
||||
|
||||
TEST_LIBC_ALG_COMS = \
|
||||
$(TEST_LIBC_ALG_SRCS:%.c=o/$(MODE)/%.com)
|
||||
|
||||
TEST_LIBC_ALG_BINS = \
|
||||
$(TEST_LIBC_ALG_COMS) \
|
||||
$(TEST_LIBC_ALG_COMS:%=%.dbg)
|
||||
|
||||
TEST_LIBC_ALG_TESTS = $(TEST_LIBC_ALG_SRCS_TEST:%.c=o/$(MODE)/%.com.ok)
|
||||
|
||||
TEST_LIBC_ALG_CHECKS = \
|
||||
|
@ -49,9 +54,7 @@ o/$(MODE)/test/libc/alg/%.com.dbg: \
|
|||
$(APE)
|
||||
@$(APELINK)
|
||||
|
||||
$(TEST_LIBC_ALG_OBJS): \
|
||||
$(BUILD_FILES) \
|
||||
test/libc/alg/test.mk
|
||||
$(TEST_LIBC_ALG_OBJS): test/libc/alg/test.mk
|
||||
|
||||
$(TEST_LIBC_ALG_OBJS): \
|
||||
DEFAULT_CCFLAGS += \
|
||||
|
|
|
@ -18,41 +18,51 @@
|
|||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/macros.h"
|
||||
#include "libc/runtime/mappings.h"
|
||||
#include "libc/bits/progn.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
#define ADDR
|
||||
#define L(x) ((int64_t)(x))
|
||||
#define S(x) ((int128_t)(x))
|
||||
#define U(x) ((uint128_t)(x))
|
||||
|
||||
struct MemoryCoord stack = ADDRSIZE_TO_COORD(0x7fffffff0000L, 0x00010000);
|
||||
struct MemoryCoord heap3 = ADDRSIZE_TO_COORD(0x200000020000L, 0x00010000);
|
||||
struct MemoryCoord heap2 = ADDRSIZE_TO_COORD(0x200000010000L, 0x00010000);
|
||||
struct MemoryCoord heap1 = ADDRSIZE_TO_COORD(0x200000000000L, 0x00010000);
|
||||
struct MemoryCoord heapa = ADDRSIZE_TO_COORD(0x200000000000L, 0x00030000);
|
||||
struct MemoryCoord progg = ADDRSIZE_TO_COORD(0x000000400000L, 0x00010000);
|
||||
struct MemoryCoord bane = ADDRSIZE_TO_COORD(0xffff800000080000L, 0x00010000);
|
||||
|
||||
TEST(isoverlapping, test) {
|
||||
EXPECT_FALSE(ISOVERLAPPING(stack, heap3));
|
||||
EXPECT_FALSE(ISOVERLAPPING(heap1, heap2));
|
||||
EXPECT_FALSE(ISOVERLAPPING(heap2, heap3));
|
||||
EXPECT_FALSE(ISOVERLAPPING(heap1, heap3));
|
||||
EXPECT_TRUE(ISOVERLAPPING(heapa, heap1));
|
||||
EXPECT_TRUE(ISOVERLAPPING(heapa, heap3));
|
||||
TEST(division, testUnsigned) {
|
||||
volatile uint128_t x;
|
||||
EXPECT_EQ(U(20769187431582143),
|
||||
PROGN(x = U(1000000000123123123), (U(1125899906842624) << 64) / x));
|
||||
EXPECT_EQ((U(26807140639110) << 64) | U(1756832768924719201),
|
||||
PROGN(x = U(42), (U(1125899906842624) << 64) / x));
|
||||
}
|
||||
|
||||
TEST(findmapping, limits) {
|
||||
ASSERT_EQ(INT_MAX, ADDR_TO_COORD(0x7fffffff0000L));
|
||||
ASSERT_EQ(INT_MIN, ADDR_TO_COORD(-0x800000000000L));
|
||||
TEST(division, testSigned) {
|
||||
volatile int128_t x;
|
||||
EXPECT_EQ(S(20769187431582143),
|
||||
PROGN(x = S(1000000000123123123), (S(1125899906842624) << 64) / x));
|
||||
EXPECT_EQ(S(26807140639110) << 64 | S(1756832768924719201),
|
||||
PROGN(x = S(42), (S(1125899906842624) << 64) / x));
|
||||
}
|
||||
|
||||
TEST(findmapping, test) {
|
||||
struct MemoryCoord c[] = {bane, progg, heap1, heap2, heap3, stack};
|
||||
EXPECT_EQ(6, ARRAYLEN(c));
|
||||
EXPECT_EQ(0, findmapping_(ADDR_TO_COORD(-0x800000000000UL), c, 6));
|
||||
EXPECT_EQ(1, findmapping_(ADDR_TO_COORD(-42), c, 6));
|
||||
EXPECT_EQ(1, findmapping_(ADDR_TO_COORD(0x000000300000L), c, 6));
|
||||
EXPECT_EQ(2, findmapping_(ADDR_TO_COORD(0x000000400000L), c, 6));
|
||||
EXPECT_EQ(6, findmapping_(ADDR_TO_COORD(0x7fffffffffffL), c, 6));
|
||||
BENCH(divmodti4, bench) {
|
||||
volatile int128_t x;
|
||||
EZBENCH2("divmodti4 small / small", donothing,
|
||||
PROGN(x = S(42), x = S(112589990684) / x));
|
||||
EZBENCH2("divmodti4 small / large", donothing,
|
||||
PROGN(x = U(123) << 64 | 123, x = S(112589990684) / x));
|
||||
EZBENCH2("divmodti4 large / small", donothing,
|
||||
PROGN(x = 123, x = (S(1125899906842624) << 64 | 334) / x));
|
||||
EZBENCH2(
|
||||
"divmodti4 large / large", donothing,
|
||||
PROGN(x = U(123) << 64 | 123, x = (S(1125899906842624) << 64 | 334) / x));
|
||||
}
|
||||
|
||||
BENCH(idiv32, bench) {
|
||||
volatile int32_t x;
|
||||
EZBENCH2("idiv32", donothing,
|
||||
PROGN(x = L(1000000000123123123), x = L(1125899906842624) / x));
|
||||
}
|
||||
|
||||
BENCH(idiv64, bench) {
|
||||
volatile int64_t x;
|
||||
EZBENCH2("idiv64", donothing,
|
||||
PROGN(x = L(1000000000123123123), x = L(1125899906842624) / x));
|
||||
}
|
|
@ -17,6 +17,7 @@
|
|||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/macros.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
|
|
@ -17,39 +17,19 @@
|
|||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/intrin/paddsw.h"
|
||||
#include "libc/intrin/paddw.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/bits/popcnt.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
TEST(paddw, test) {
|
||||
short A[8] = {7};
|
||||
short B[8] = {11};
|
||||
short C[8];
|
||||
paddw(C, A, B);
|
||||
EXPECT_EQ(18, C[0]);
|
||||
TEST(popcnt, test) {
|
||||
EXPECT_EQ(32, popcnt(0x5555555555555555));
|
||||
EXPECT_EQ(32, popcnt(VEIL("r", 0x5555555555555555)));
|
||||
EXPECT_EQ(32, (popcnt)(VEIL("r", 0x5555555555555555)));
|
||||
}
|
||||
|
||||
TEST(paddsw, test) {
|
||||
short A[8] = {7};
|
||||
short B[8] = {11};
|
||||
short C[8];
|
||||
paddsw(C, A, B);
|
||||
EXPECT_EQ(18, C[0]);
|
||||
}
|
||||
|
||||
TEST(paddw, testOverflow_wrapsAround) {
|
||||
short A[8] = {SHRT_MAX, SHRT_MIN};
|
||||
short B[8] = {1, -1};
|
||||
paddw(A, A, B);
|
||||
EXPECT_EQ(SHRT_MIN, A[0]);
|
||||
EXPECT_EQ(SHRT_MAX, A[1]);
|
||||
}
|
||||
|
||||
TEST(paddsw, testOverflow_saturates) {
|
||||
short A[8] = {SHRT_MAX, SHRT_MIN};
|
||||
short B[8] = {1, -1};
|
||||
paddsw(A, A, B);
|
||||
EXPECT_EQ(SHRT_MAX, A[0]);
|
||||
EXPECT_EQ(SHRT_MIN, A[1]);
|
||||
BENCH(popcnt, bench) {
|
||||
EZBENCH2("popcnt", donothing,
|
||||
EXPROPRIATE(popcnt(VEIL("r", 0x5555555555555555))));
|
||||
EZBENCH2("(popcnt)", donothing,
|
||||
EXPROPRIATE((popcnt)(VEIL("r", 0x5555555555555555))));
|
||||
}
|
|
@ -5,12 +5,14 @@ PKGS += TEST_LIBC_BITS
|
|||
|
||||
TEST_LIBC_BITS_SRCS := $(wildcard test/libc/bits/*.c)
|
||||
TEST_LIBC_BITS_SRCS_TEST = $(filter %_test.c,$(TEST_LIBC_BITS_SRCS))
|
||||
TEST_LIBC_BITS_COMS = $(TEST_LIBC_BITS_OBJS:%.o=%.com)
|
||||
|
||||
TEST_LIBC_BITS_OBJS = \
|
||||
$(TEST_LIBC_BITS_SRCS:%=o/$(MODE)/%.zip.o) \
|
||||
$(TEST_LIBC_BITS_SRCS:%.c=o/$(MODE)/%.o)
|
||||
|
||||
TEST_LIBC_BITS_COMS = \
|
||||
$(TEST_LIBC_BITS_SRCS:%.c=o/$(MODE)/%.com)
|
||||
|
||||
TEST_LIBC_BITS_BINS = \
|
||||
$(TEST_LIBC_BITS_COMS) \
|
||||
$(TEST_LIBC_BITS_COMS:%=%.dbg)
|
||||
|
@ -26,7 +28,8 @@ TEST_LIBC_BITS_DIRECTDEPS = \
|
|||
LIBC_BITS \
|
||||
LIBC_NEXGEN32E \
|
||||
LIBC_STUBS \
|
||||
LIBC_TESTLIB
|
||||
LIBC_TESTLIB \
|
||||
THIRD_PARTY_COMPILER_RT
|
||||
|
||||
TEST_LIBC_BITS_DEPS := \
|
||||
$(call uniq,$(foreach x,$(TEST_LIBC_BITS_DIRECTDEPS),$($(x))))
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/runtime/gc.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/runtime/gc.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
char16_t p[PATH_MAX];
|
||||
|
|
|
@ -7,12 +7,14 @@ TEST_LIBC_CALLS_SRCS := \
|
|||
$(wildcard test/libc/calls/*.c) \
|
||||
$(wildcard test/libc/calls/hefty/*.c)
|
||||
TEST_LIBC_CALLS_SRCS_TEST = $(filter %_test.c,$(TEST_LIBC_CALLS_SRCS))
|
||||
TEST_LIBC_CALLS_COMS = $(TEST_LIBC_CALLS_OBJS:%.o=%.com)
|
||||
|
||||
TEST_LIBC_CALLS_OBJS = \
|
||||
$(TEST_LIBC_CALLS_SRCS:%=o/$(MODE)/%.zip.o) \
|
||||
$(TEST_LIBC_CALLS_SRCS:%.c=o/$(MODE)/%.o)
|
||||
|
||||
TEST_LIBC_CALLS_COMS = \
|
||||
$(TEST_LIBC_CALLS_SRCS:%.c=o/$(MODE)/%.com)
|
||||
|
||||
TEST_LIBC_CALLS_BINS = \
|
||||
$(TEST_LIBC_CALLS_COMS) \
|
||||
$(TEST_LIBC_CALLS_COMS:%=%.dbg)
|
||||
|
|
63
test/libc/conv/itoa64radix10_test.c
Normal file
63
test/libc/conv/itoa64radix10_test.c
Normal file
|
@ -0,0 +1,63 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/conv/conv.h"
|
||||
#include "libc/conv/itoa.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
TEST(int64toarray_radix10, test) {
|
||||
char buf[21];
|
||||
EXPECT_EQ(1, int64toarray_radix10(0, buf));
|
||||
EXPECT_STREQ("0", buf);
|
||||
EXPECT_EQ(19, int64toarray_radix10(INT64_MAX, buf));
|
||||
EXPECT_STREQ("9223372036854775807", buf);
|
||||
EXPECT_EQ(20, int64toarray_radix10(INT64_MIN, buf));
|
||||
EXPECT_STREQ("-9223372036854775808", buf);
|
||||
}
|
||||
|
||||
TEST(uint64toarray_radix10, test) {
|
||||
char buf[21];
|
||||
EXPECT_EQ(1, uint64toarray_radix10(0, buf));
|
||||
EXPECT_STREQ("0", buf);
|
||||
EXPECT_EQ(20, uint64toarray_radix10(UINT64_MAX, buf));
|
||||
EXPECT_STREQ("18446744073709551615", buf);
|
||||
EXPECT_EQ(19, uint64toarray_radix10(INT64_MIN, buf));
|
||||
EXPECT_STREQ("9223372036854775808", buf);
|
||||
}
|
||||
|
||||
TEST(int128toarray_radix10, test) {
|
||||
char buf[41];
|
||||
EXPECT_EQ(1, int128toarray_radix10(0, buf));
|
||||
EXPECT_STREQ("0", buf);
|
||||
EXPECT_EQ(39, int128toarray_radix10(INT128_MAX, buf));
|
||||
EXPECT_STREQ("170141183460469231731687303715884105727", buf);
|
||||
EXPECT_EQ(40, int128toarray_radix10(INT128_MIN, buf));
|
||||
EXPECT_STREQ("-170141183460469231731687303715884105728", buf);
|
||||
}
|
||||
|
||||
TEST(uint128toarray_radix10, test) {
|
||||
char buf[40];
|
||||
EXPECT_EQ(1, uint128toarray_radix10(0, buf));
|
||||
EXPECT_STREQ("0", buf);
|
||||
EXPECT_EQ(39, uint128toarray_radix10(UINT128_MAX, buf));
|
||||
EXPECT_STREQ("340282366920938463463374607431768211455", buf);
|
||||
EXPECT_EQ(39, uint128toarray_radix10(INT128_MIN, buf));
|
||||
EXPECT_STREQ("170141183460469231731687303715884105728", buf);
|
||||
}
|
|
@ -17,22 +17,17 @@
|
|||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/intrin/psraw.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/conv/itoa.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
TEST(psraw, testPositive) {
|
||||
short A[8] = {1, 2, SHRT_MAX};
|
||||
psraw(A, A, 1);
|
||||
EXPECT_EQ(0, A[0]);
|
||||
EXPECT_EQ(1, A[1]);
|
||||
EXPECT_EQ(SHRT_MAX / 2, A[2]);
|
||||
TEST(itoa64radix16, test) {
|
||||
char buf[21];
|
||||
EXPECT_EQ(5, uint64toarray_radix16(0x31337, buf));
|
||||
EXPECT_STREQ("31337", buf);
|
||||
}
|
||||
|
||||
TEST(psraw, testNegative) {
|
||||
short A[8] = {-1, -2, SHRT_MIN};
|
||||
psraw(A, A, 1);
|
||||
EXPECT_EQ(-1, A[0]);
|
||||
EXPECT_EQ(-1, A[1]);
|
||||
EXPECT_EQ(SHRT_MIN / 2, A[2]);
|
||||
TEST(itoa64fixed16, test) {
|
||||
char buf[21];
|
||||
EXPECT_EQ(8, uint64toarray_fixed16(0x31337, buf, 32));
|
||||
EXPECT_STREQ("00031337", buf);
|
||||
}
|
|
@ -21,20 +21,10 @@
|
|||
#include "libc/conv/conv.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
/* todo(jart): work on this more */
|
||||
|
||||
TEST(strtoimax, testZero) {
|
||||
EXPECT_EQ(0, strtoimax("0", NULL, 0));
|
||||
}
|
||||
TEST(strtoimax, testDecimal) {
|
||||
EXPECT_EQ(-123, strtoimax("-123", NULL, 0));
|
||||
}
|
||||
TEST(strtoimax, testHex) {
|
||||
EXPECT_EQ(-255, strtoimax("-0xff", NULL, 0));
|
||||
}
|
||||
TEST(strtoimax, testOctal) {
|
||||
EXPECT_EQ(-123, strtoimax("-0173", NULL, 0));
|
||||
}
|
||||
TEST(strtoimax, testZero) { EXPECT_EQ(0, strtoimax("0", NULL, 0)); }
|
||||
TEST(strtoimax, testDecimal) { EXPECT_EQ(-123, strtoimax("-123", NULL, 0)); }
|
||||
TEST(strtoimax, testHex) { EXPECT_EQ(-255, strtoimax("-0xff", NULL, 0)); }
|
||||
TEST(strtoimax, testOctal) { EXPECT_EQ(-123, strtoimax("-0173", NULL, 0)); }
|
||||
|
||||
TEST(strtoimax, testLimits) {
|
||||
EXPECT_EQ(
|
||||
|
@ -50,3 +40,8 @@ TEST(strtoimax, testZeroExtend) {
|
|||
EXPECT_EQ(0xffffffff, strtoimax("-1u", NULL, 0));
|
||||
EXPECT_EQ(0xffffffffffffffff, strtoimax("-1ul", NULL, 0));
|
||||
}
|
||||
|
||||
TEST(strtoimax, testTwosBane) {
|
||||
EXPECT_EQ(((uintmax_t)0x8000000000000000) << 64 | 0x0000000000000000,
|
||||
strtoimax("0x80000000000000000000000000000000", NULL, 0));
|
||||
}
|
||||
|
|
|
@ -5,12 +5,14 @@ PKGS += TEST_LIBC_CONV
|
|||
|
||||
TEST_LIBC_CONV_SRCS := $(wildcard test/libc/conv/*.c)
|
||||
TEST_LIBC_CONV_SRCS_TEST = $(filter %_test.c,$(TEST_LIBC_CONV_SRCS))
|
||||
TEST_LIBC_CONV_COMS = $(TEST_LIBC_CONV_OBJS:%.o=%.com)
|
||||
|
||||
TEST_LIBC_CONV_OBJS = \
|
||||
$(TEST_LIBC_CONV_SRCS:%=o/$(MODE)/%.zip.o) \
|
||||
$(TEST_LIBC_CONV_SRCS:%.c=o/$(MODE)/%.o)
|
||||
|
||||
TEST_LIBC_CONV_COMS = \
|
||||
$(TEST_LIBC_CONV_SRCS:%.c=o/$(MODE)/%.com)
|
||||
|
||||
TEST_LIBC_CONV_BINS = \
|
||||
$(TEST_LIBC_CONV_COMS) \
|
||||
$(TEST_LIBC_CONV_COMS:%=%.dbg)
|
||||
|
@ -43,9 +45,7 @@ o/$(MODE)/test/libc/conv/%.com.dbg: \
|
|||
$(APE)
|
||||
@$(APELINK)
|
||||
|
||||
$(TEST_LIBC_CONV_OBJS): \
|
||||
$(BUILD_FILES) \
|
||||
test/libc/conv/test.mk
|
||||
$(TEST_LIBC_CONV_OBJS): test/libc/conv/test.mk
|
||||
|
||||
$(TEST_LIBC_CONV_OBJS): \
|
||||
DEFAULT_CCFLAGS += \
|
||||
|
|
|
@ -42,10 +42,9 @@ TEST(parseresolvconf, testEmpty) {
|
|||
}
|
||||
|
||||
TEST(parseresolvconf, testCorrectlyTokenizes) {
|
||||
const char kInput[] =
|
||||
"# this is a comment\n"
|
||||
"nameserver 203.0.113.2 \n"
|
||||
" nameserver 203.0.113.1\n";
|
||||
const char kInput[] = "# this is a comment\n"
|
||||
"nameserver 203.0.113.2 \n"
|
||||
" nameserver 203.0.113.1\n";
|
||||
struct ResolvConf *rv = calloc(1, sizeof(struct ResolvConf));
|
||||
FILE *f = fmemopen(NULL, BUFSIZ, "r+");
|
||||
ASSERT_EQ(strlen(kInput), fwrite(kInput, 1, strlen(kInput), f));
|
||||
|
@ -61,16 +60,13 @@ TEST(parseresolvconf, testCorrectlyTokenizes) {
|
|||
fclose(f);
|
||||
}
|
||||
|
||||
TEST(parseresolvconf, testSearchLocal_setsLoopback) {
|
||||
TEST(parseresolvconf, testMulticastDnsThing_getsIgnored) {
|
||||
const char kInput[] = "search local # boop\n";
|
||||
struct ResolvConf *rv = calloc(1, sizeof(struct ResolvConf));
|
||||
FILE *f = fmemopen(NULL, BUFSIZ, "r+");
|
||||
ASSERT_EQ(strlen(kInput), fwrite(kInput, 1, strlen(kInput), f));
|
||||
ASSERT_EQ(1, parseresolvconf(rv, f));
|
||||
ASSERT_EQ(1, rv->nameservers.i);
|
||||
EXPECT_EQ(AF_INET, rv->nameservers.p[0].sin_family);
|
||||
EXPECT_EQ(DNS_PORT, ntohs(rv->nameservers.p[0].sin_port));
|
||||
EXPECT_STREQ("127.0.0.1", FormatIp(&rv->nameservers.p[0]));
|
||||
ASSERT_EQ(0, parseresolvconf(rv, f));
|
||||
ASSERT_EQ(0, rv->nameservers.i);
|
||||
freeresolvconf(&rv);
|
||||
fclose(f);
|
||||
}
|
||||
|
|
|
@ -5,12 +5,14 @@ PKGS += TEST_LIBC_DNS
|
|||
|
||||
TEST_LIBC_DNS_SRCS := $(wildcard test/libc/dns/*.c)
|
||||
TEST_LIBC_DNS_SRCS_TEST = $(filter %_test.c,$(TEST_LIBC_DNS_SRCS))
|
||||
TEST_LIBC_DNS_COMS = $(TEST_LIBC_DNS_OBJS:%.o=%.com)
|
||||
|
||||
TEST_LIBC_DNS_OBJS = \
|
||||
$(TEST_LIBC_DNS_SRCS:%=o/$(MODE)/%.zip.o) \
|
||||
$(TEST_LIBC_DNS_SRCS:%.c=o/$(MODE)/%.o)
|
||||
|
||||
TEST_LIBC_DNS_COMS = \
|
||||
$(TEST_LIBC_DNS_SRCS:%.c=o/$(MODE)/%.com)
|
||||
|
||||
TEST_LIBC_DNS_BINS = \
|
||||
$(TEST_LIBC_DNS_COMS) \
|
||||
$(TEST_LIBC_DNS_COMS:%=%.dbg)
|
||||
|
|
|
@ -27,12 +27,15 @@
|
|||
#include "libc/bits/progn.h"
|
||||
#include "libc/bits/pushpop.h"
|
||||
#include "libc/bits/safemacros.h"
|
||||
#include "libc/conv/itoa.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/fmt/fmt.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/math.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/gc.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
#include "libc/x/x.h"
|
||||
|
||||
|
@ -479,10 +482,8 @@ TEST(sprintf, test_types) {
|
|||
TEST(sprintf, testOverflow_truncationNotSaturation) {
|
||||
errno = 0;
|
||||
EXPECT_STREQ("13398", Format("%hu", 0x123456UL));
|
||||
EXPECT_EQ(ERANGE, errno);
|
||||
errno = 0;
|
||||
EXPECT_STREQ("Test16 65535", Format("%s%hhi %hu", "Test", 10000, 0xFFFFFFFF));
|
||||
EXPECT_EQ(ERANGE, errno);
|
||||
}
|
||||
|
||||
TEST(sprintf, test_pointer) {
|
||||
|
@ -598,6 +599,10 @@ TEST(xasprintf, test) {
|
|||
free(pp);
|
||||
}
|
||||
|
||||
TEST(xasprintf, nullPointer) {
|
||||
ASSERT_STREQ("000000000000", gc(xasprintf("%p", NULL)));
|
||||
}
|
||||
|
||||
TEST(xasprintf, pointer_doesntShowNonCanonicalZeroes) {
|
||||
ASSERT_STREQ("100000000010", gc(xasprintf("%p", 0x0000100000000010)));
|
||||
ASSERT_STREQ("0x100000000010", gc(xasprintf("%#p", 0x0000100000000010)));
|
||||
|
@ -610,6 +615,19 @@ TEST(xasprintf, nonCanonicalPointer_discardsHighBits_ratherThanSaturate) {
|
|||
ASSERT_STREQ("0x7fffffffffff", gc(xasprintf("%#p", 0x7fffffffffff)));
|
||||
}
|
||||
|
||||
TEST(xasprintf, hugeNtoa) {
|
||||
ASSERT_STREQ(
|
||||
"0b1111111111111111111111111111111111111111111111111111111111111111111111"
|
||||
"1111111111111111111111111111111111111111111111111111111111",
|
||||
gc(xasprintf("%#jb", UINT128_MAX)));
|
||||
}
|
||||
|
||||
TEST(xasprintf, twosBane) {
|
||||
ASSERT_STREQ("-2147483648", gc(xasprintf("%d", 0x80000000)));
|
||||
ASSERT_STREQ("-9223372036854775808",
|
||||
gc(xasprintf("%ld", 0x8000000000000000)));
|
||||
}
|
||||
|
||||
TEST(snprintf, testFixedWidthString_wontOverrunInput) {
|
||||
const int N = 2;
|
||||
char *buf = tmalloc(N + 1);
|
||||
|
@ -651,3 +669,17 @@ TEST(snprintf, testFixedWidthStringIsNull_wontLeakMemory) {
|
|||
EXPECT_BINEQ(u"NULL ", buf);
|
||||
tfree(buf);
|
||||
}
|
||||
|
||||
TEST(snprintf, twosBaneWithTypePromotion) {
|
||||
int16_t x = 0x8000;
|
||||
EXPECT_STREQ("-32768", Format("%hd", x));
|
||||
}
|
||||
|
||||
BENCH(palandprintf, bench) {
|
||||
EZBENCH2("snprintf %x", donothing, Format("%x", VEIL("r", INT_MIN)));
|
||||
EZBENCH2("snprintf %d", donothing, Format("%d", VEIL("r", INT_MIN)));
|
||||
EZBENCH2("snprintf %s", donothing, Format("%s", VEIL("r", "hi (╯°□°)╯")));
|
||||
EZBENCH2("snprintf %hs", donothing, Format("%hs", VEIL("r", u"hi (╯°□°)╯")));
|
||||
EZBENCH2("snprintf %ls", donothing, Format("%ls", VEIL("r", L"hi (╯°□°)╯")));
|
||||
EZBENCH2("int64toarray", donothing, int64toarray_radix10(-3, buffer));
|
||||
}
|
||||
|
|
|
@ -40,10 +40,10 @@ TEST(SUITE(sprintf), testCharacterCounting) {
|
|||
|
||||
TEST(SUITE(snprintf), testTableFlip) {
|
||||
EXPECT_STREQ("Table flip ", Format("%-20ls", L"Table flip"));
|
||||
EXPECT_STREQ("(╯°□°)╯︵ ┻━┻ ", Format("%-20ls", L"(╯°□°)╯︵ ┻━┻"));
|
||||
EXPECT_STREQ("(╯°□°)╯︵ ┻━┻ ", Format("%-20hs", u"(╯°□°)╯︵ ┻━┻"));
|
||||
EXPECT_STREQ("(╯°□°)╯︵L┻━┻ ", Format("%-20ls", L"(╯°□°)╯︵L┻━┻"));
|
||||
EXPECT_STREQ("(╯°□°)╯︵u┻━┻ ", Format("%-20hs", u"(╯°□°)╯︵u┻━┻"));
|
||||
EXPECT_STREQ("ちゃぶ台返し ", Format("%-20ls", L"ちゃぶ台返し"));
|
||||
EXPECT_STREQ(" (╯°□°)╯︵ ┻━┻", Format("%20ls", L"(╯°□°)╯︵ ┻━┻"));
|
||||
EXPECT_STREQ(" (╯°□°)╯︵L┻━┻", Format("%20ls", L"(╯°□°)╯︵L┻━┻"));
|
||||
EXPECT_STREQ(" ちゃぶ台返し", Format("%20ls", L"ちゃぶ台返し"));
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,11 @@
|
|||
* libc/sysv/kErrnoNames.S needs updating.
|
||||
*/
|
||||
|
||||
TEST(strerror, e2big) {
|
||||
if (IsTiny()) return;
|
||||
EXPECT_STARTSWITH("E2BIG", strerror(E2BIG));
|
||||
}
|
||||
|
||||
TEST(strerror, enosys) {
|
||||
if (IsTiny()) return;
|
||||
EXPECT_STARTSWITH("ENOSYS", strerror(ENOSYS));
|
||||
|
|
|
@ -5,7 +5,6 @@ PKGS += TEST_LIBC_FMT
|
|||
|
||||
TEST_LIBC_FMT_SRCS := $(wildcard test/libc/fmt/*.c)
|
||||
TEST_LIBC_FMT_SRCS_TEST = $(filter %_test.c,$(TEST_LIBC_FMT_SRCS))
|
||||
TEST_LIBC_FMT_COMS = $(TEST_LIBC_FMT_OBJS:%.o=%.com)
|
||||
TEST_LIBC_FMT_BINS = $(TEST_LIBC_FMT_COMS) $(TEST_LIBC_FMT_COMS:%=%.dbg)
|
||||
TEST_LIBC_FMT_TESTS = $(TEST_LIBC_FMT_SRCS_TEST:%.c=o/$(MODE)/%.com.ok)
|
||||
|
||||
|
@ -13,11 +12,15 @@ TEST_LIBC_FMT_OBJS = \
|
|||
$(TEST_LIBC_FMT_SRCS:%=o/$(MODE)/%.zip.o) \
|
||||
$(TEST_LIBC_FMT_SRCS:%.c=o/$(MODE)/%.o)
|
||||
|
||||
TEST_LIBC_FMT_COMS = \
|
||||
$(TEST_LIBC_FMT_SRCS:%.c=o/$(MODE)/%.com)
|
||||
|
||||
TEST_LIBC_FMT_CHECKS = \
|
||||
$(TEST_LIBC_FMT_SRCS_TEST:%.c=o/$(MODE)/%.com.runs)
|
||||
|
||||
TEST_LIBC_FMT_DIRECTDEPS = \
|
||||
LIBC_CALLS_HEFTY \
|
||||
LIBC_CONV \
|
||||
LIBC_FMT \
|
||||
LIBC_MEM \
|
||||
LIBC_NEXGEN32E \
|
||||
|
@ -45,9 +48,7 @@ o/$(MODE)/test/libc/fmt/%.com.dbg: \
|
|||
$(APE)
|
||||
@$(APELINK)
|
||||
|
||||
$(TEST_LIBC_FMT_OBJS): \
|
||||
$(BUILD_FILES) \
|
||||
test/libc/fmt/test.mk
|
||||
$(TEST_LIBC_FMT_OBJS): test/libc/fmt/test.mk
|
||||
|
||||
.PHONY: o/$(MODE)/test/libc/fmt
|
||||
o/$(MODE)/test/libc/fmt: \
|
||||
|
|
2108
test/libc/intrin/intrin_test.c
Normal file
2108
test/libc/intrin/intrin_test.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -17,71 +17,216 @@
|
|||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/progn.h"
|
||||
#include "libc/intrin/palignr.h"
|
||||
#include "libc/rand/rand.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
const int A[4] = {1, 2, 3, 4};
|
||||
const int B[4] = {5, 6, 7, 8};
|
||||
|
||||
TEST(palignr, testLeftpad) {
|
||||
const int A[4] = {1, 2, 3, 4};
|
||||
const int B[4] = {5, 6, 7, 8};
|
||||
int C[4] = {0};
|
||||
palignr(C, B, A, 12);
|
||||
EXPECT_EQ(4, C[0]);
|
||||
EXPECT_EQ(5, C[1]);
|
||||
EXPECT_EQ(6, C[2]);
|
||||
EXPECT_EQ(7, C[3]);
|
||||
ASSERT_EQ(4, C[0]);
|
||||
ASSERT_EQ(5, C[1]);
|
||||
ASSERT_EQ(6, C[2]);
|
||||
ASSERT_EQ(7, C[3]);
|
||||
}
|
||||
|
||||
TEST(palignr, testLeftpad_variableImmediate) {
|
||||
const int A[4] = {1, 2, 3, 4};
|
||||
const int B[4] = {5, 6, 7, 8};
|
||||
int C[4] = {0};
|
||||
palignr(C, B, A, VEIL("r", 12));
|
||||
ASSERT_EQ(4, C[0]);
|
||||
ASSERT_EQ(5, C[1]);
|
||||
ASSERT_EQ(6, C[2]);
|
||||
ASSERT_EQ(7, C[3]);
|
||||
}
|
||||
|
||||
TEST(palignr, test0) {
|
||||
const int A[4] = {1, 2, 3, 4};
|
||||
const int B[4] = {5, 6, 7, 8};
|
||||
int C[4];
|
||||
palignr(C, B, A, 0);
|
||||
EXPECT_EQ(1, C[0]);
|
||||
EXPECT_EQ(2, C[1]);
|
||||
EXPECT_EQ(3, C[2]);
|
||||
EXPECT_EQ(4, C[3]);
|
||||
ASSERT_EQ(1, C[0]);
|
||||
ASSERT_EQ(2, C[1]);
|
||||
ASSERT_EQ(3, C[2]);
|
||||
ASSERT_EQ(4, C[3]);
|
||||
}
|
||||
|
||||
TEST(palignr, test4) {
|
||||
const int A[4] = {1, 2, 3, 4};
|
||||
const int B[4] = {5, 6, 7, 8};
|
||||
int C[4];
|
||||
palignr(C, B, A, 4);
|
||||
EXPECT_EQ(2, C[0]);
|
||||
EXPECT_EQ(3, C[1]);
|
||||
EXPECT_EQ(4, C[2]);
|
||||
EXPECT_EQ(5, C[3]);
|
||||
ASSERT_EQ(2, C[0]);
|
||||
ASSERT_EQ(3, C[1]);
|
||||
ASSERT_EQ(4, C[2]);
|
||||
ASSERT_EQ(5, C[3]);
|
||||
}
|
||||
|
||||
TEST(palignr, test12) {
|
||||
const int A[4] = {1, 2, 3, 4};
|
||||
const int B[4] = {5, 6, 7, 8};
|
||||
int C[4];
|
||||
palignr(C, B, A, 12);
|
||||
EXPECT_EQ(4, C[0]);
|
||||
EXPECT_EQ(5, C[1]);
|
||||
EXPECT_EQ(6, C[2]);
|
||||
EXPECT_EQ(7, C[3]);
|
||||
ASSERT_EQ(4, C[0]);
|
||||
ASSERT_EQ(5, C[1]);
|
||||
ASSERT_EQ(6, C[2]);
|
||||
ASSERT_EQ(7, C[3]);
|
||||
}
|
||||
|
||||
TEST(palignr, test16) {
|
||||
const int A[4] = {1, 2, 3, 4};
|
||||
const int B[4] = {5, 6, 7, 8};
|
||||
int C[4];
|
||||
palignr(C, B, A, 16);
|
||||
EXPECT_EQ(5, C[0]);
|
||||
EXPECT_EQ(6, C[1]);
|
||||
EXPECT_EQ(7, C[2]);
|
||||
EXPECT_EQ(8, C[3]);
|
||||
ASSERT_EQ(5, C[0]);
|
||||
ASSERT_EQ(6, C[1]);
|
||||
ASSERT_EQ(7, C[2]);
|
||||
ASSERT_EQ(8, C[3]);
|
||||
}
|
||||
|
||||
TEST(palignr, test20) {
|
||||
const int A[4] = {1, 2, 3, 4};
|
||||
const int B[4] = {5, 6, 7, 8};
|
||||
int C[4] = {-1, -1, -1, -1};
|
||||
palignr(C, B, A, 20);
|
||||
EXPECT_EQ(6, C[0]);
|
||||
EXPECT_EQ(7, C[1]);
|
||||
EXPECT_EQ(8, C[2]);
|
||||
EXPECT_EQ(0, C[3]);
|
||||
ASSERT_EQ(6, C[0]);
|
||||
ASSERT_EQ(7, C[1]);
|
||||
ASSERT_EQ(8, C[2]);
|
||||
ASSERT_EQ(0, C[3]);
|
||||
}
|
||||
|
||||
TEST(palignr, test32) {
|
||||
TEST(palignrc, testLeftpad) {
|
||||
const int A[4] = {1, 2, 3, 4};
|
||||
const int B[4] = {5, 6, 7, 8};
|
||||
int C[4] = {0};
|
||||
(palignr)(C, B, A, 12);
|
||||
ASSERT_EQ(4, C[0]);
|
||||
ASSERT_EQ(5, C[1]);
|
||||
ASSERT_EQ(6, C[2]);
|
||||
ASSERT_EQ(7, C[3]);
|
||||
}
|
||||
|
||||
TEST(palignrc, testLeftpad_variableImmediate) {
|
||||
const int A[4] = {1, 2, 3, 4};
|
||||
const int B[4] = {5, 6, 7, 8};
|
||||
int C[4] = {0};
|
||||
(palignr)(C, B, A, VEIL("r", 12));
|
||||
ASSERT_EQ(4, C[0]);
|
||||
ASSERT_EQ(5, C[1]);
|
||||
ASSERT_EQ(6, C[2]);
|
||||
ASSERT_EQ(7, C[3]);
|
||||
}
|
||||
|
||||
TEST(palignrc, test0) {
|
||||
const int A[4] = {1, 2, 3, 4};
|
||||
const int B[4] = {5, 6, 7, 8};
|
||||
int C[4];
|
||||
(palignr)(C, B, A, 0);
|
||||
ASSERT_EQ(1, C[0]);
|
||||
ASSERT_EQ(2, C[1]);
|
||||
ASSERT_EQ(3, C[2]);
|
||||
ASSERT_EQ(4, C[3]);
|
||||
}
|
||||
|
||||
TEST(palignrc, test4) {
|
||||
const int A[4] = {1, 2, 3, 4};
|
||||
const int B[4] = {5, 6, 7, 8};
|
||||
int C[4];
|
||||
(palignr)(C, B, A, 4);
|
||||
ASSERT_EQ(2, C[0]);
|
||||
ASSERT_EQ(3, C[1]);
|
||||
ASSERT_EQ(4, C[2]);
|
||||
ASSERT_EQ(5, C[3]);
|
||||
}
|
||||
|
||||
TEST(palignrc, test12) {
|
||||
const int A[4] = {1, 2, 3, 4};
|
||||
const int B[4] = {5, 6, 7, 8};
|
||||
int C[4];
|
||||
(palignr)(C, B, A, 12);
|
||||
ASSERT_EQ(4, C[0]);
|
||||
ASSERT_EQ(5, C[1]);
|
||||
ASSERT_EQ(6, C[2]);
|
||||
ASSERT_EQ(7, C[3]);
|
||||
}
|
||||
|
||||
TEST(palignrc, test16) {
|
||||
const int A[4] = {1, 2, 3, 4};
|
||||
const int B[4] = {5, 6, 7, 8};
|
||||
int C[4];
|
||||
(palignr)(C, B, A, 16);
|
||||
ASSERT_EQ(5, C[0]);
|
||||
ASSERT_EQ(6, C[1]);
|
||||
ASSERT_EQ(7, C[2]);
|
||||
ASSERT_EQ(8, C[3]);
|
||||
}
|
||||
|
||||
TEST(palignrc, test20) {
|
||||
const int A[4] = {1, 2, 3, 4};
|
||||
const int B[4] = {5, 6, 7, 8};
|
||||
int C[4] = {-1, -1, -1, -1};
|
||||
(palignr)(C, B, A, 20);
|
||||
ASSERT_EQ(6, C[0]);
|
||||
ASSERT_EQ(7, C[1]);
|
||||
ASSERT_EQ(8, C[2]);
|
||||
ASSERT_EQ(0, C[3]);
|
||||
}
|
||||
|
||||
TEST(palignr, test32orHigher_clearsOutput) {
|
||||
const int A[4] = {1, 2, 3, 4};
|
||||
const int B[4] = {5, 6, 7, 8};
|
||||
int C[4] = {-1, -1, -1, -1};
|
||||
palignr(C, B, A, 32);
|
||||
EXPECT_EQ(0, C[0]);
|
||||
EXPECT_EQ(0, C[1]);
|
||||
EXPECT_EQ(0, C[2]);
|
||||
EXPECT_EQ(0, C[3]);
|
||||
ASSERT_EQ(0, C[0]);
|
||||
ASSERT_EQ(0, C[1]);
|
||||
ASSERT_EQ(0, C[2]);
|
||||
ASSERT_EQ(0, C[3]);
|
||||
C[0] = 43;
|
||||
palignr(C, B, A, 123);
|
||||
ASSERT_EQ(0, C[0]);
|
||||
ASSERT_EQ(0, C[1]);
|
||||
ASSERT_EQ(0, C[2]);
|
||||
ASSERT_EQ(0, C[3]);
|
||||
}
|
||||
|
||||
TEST(palignrv, test32orHigher_clearsOutput) {
|
||||
const int A[4] = {1, 2, 3, 4};
|
||||
const int B[4] = {5, 6, 7, 8};
|
||||
int C[4] = {-1, -1, -1, -1};
|
||||
palignr(C, B, A, VEIL("r", 32));
|
||||
ASSERT_EQ(0, C[0]);
|
||||
ASSERT_EQ(0, C[1]);
|
||||
ASSERT_EQ(0, C[2]);
|
||||
ASSERT_EQ(0, C[3]);
|
||||
C[0] = 43;
|
||||
palignr(C, B, A, VEIL("r", 123));
|
||||
ASSERT_EQ(0, C[0]);
|
||||
ASSERT_EQ(0, C[1]);
|
||||
ASSERT_EQ(0, C[2]);
|
||||
ASSERT_EQ(0, C[3]);
|
||||
}
|
||||
|
||||
TEST(palignrc, test32orHigher_clearsOutput) {
|
||||
const int A[4] = {1, 2, 3, 4};
|
||||
const int B[4] = {5, 6, 7, 8};
|
||||
int C[4] = {-1, -1, -1, -1};
|
||||
(palignr)(C, B, A, 32);
|
||||
ASSERT_EQ(0, C[0]);
|
||||
ASSERT_EQ(0, C[1]);
|
||||
ASSERT_EQ(0, C[2]);
|
||||
ASSERT_EQ(0, C[3]);
|
||||
}
|
||||
|
||||
BENCH(palignr, bench) {
|
||||
volatile __intrin_xmm_t A;
|
||||
volatile __intrin_xmm_t B;
|
||||
EZBENCH2("palignr const 𝑖", donothing, PROGN(palignr(&A, &A, &B, 7)));
|
||||
EZBENCH2("palignr var 𝑖", donothing,
|
||||
PROGN(palignr(&A, &A, &B, VEIL("r", 7))));
|
||||
EZBENCH2("palignr ansi", donothing, PROGN((palignr)(&A, &A, &B, 7)));
|
||||
}
|
||||
|
|
162
test/libc/intrin/pshuf_test.c
Normal file
162
test/libc/intrin/pshuf_test.c
Normal file
|
@ -0,0 +1,162 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/intrin/pshufd.h"
|
||||
#include "libc/intrin/pshufhw.h"
|
||||
#include "libc/intrin/pshuflw.h"
|
||||
#include "libc/rand/rand.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
#define T(f, m) \
|
||||
f(a, x, m); \
|
||||
(f)(b, x, m); \
|
||||
EXPECT_EQ(0, memcmp(a, b, 16))
|
||||
|
||||
TEST(pshuflw, test) {
|
||||
int i, j;
|
||||
int16_t x[8], a[8], b[8];
|
||||
for (i = 0; i < 10; ++i) {
|
||||
for (j = 0; j < 8; ++j) x[j] = rand();
|
||||
T(pshuflw, 0b00000000);
|
||||
T(pshuflw, 0b00000001);
|
||||
T(pshuflw, 0b00000011);
|
||||
T(pshuflw, 0b00001100);
|
||||
T(pshuflw, 0b00001101);
|
||||
T(pshuflw, 0b00001111);
|
||||
T(pshuflw, 0b00110000);
|
||||
T(pshuflw, 0b00110001);
|
||||
T(pshuflw, 0b00110011);
|
||||
T(pshuflw, 0b00111100);
|
||||
T(pshuflw, 0b00111101);
|
||||
T(pshuflw, 0b00111111);
|
||||
T(pshuflw, 0b01000000);
|
||||
T(pshuflw, 0b01000001);
|
||||
T(pshuflw, 0b01000011);
|
||||
T(pshuflw, 0b01001100);
|
||||
T(pshuflw, 0b01001101);
|
||||
T(pshuflw, 0b01001111);
|
||||
T(pshuflw, 0b01110000);
|
||||
T(pshuflw, 0b01110001);
|
||||
T(pshuflw, 0b01110011);
|
||||
T(pshuflw, 0b01111100);
|
||||
T(pshuflw, 0b01111101);
|
||||
T(pshuflw, 0b01111111);
|
||||
T(pshuflw, 0b11000000);
|
||||
T(pshuflw, 0b11000001);
|
||||
T(pshuflw, 0b11000011);
|
||||
T(pshuflw, 0b11001100);
|
||||
T(pshuflw, 0b11001101);
|
||||
T(pshuflw, 0b11001111);
|
||||
T(pshuflw, 0b11110000);
|
||||
T(pshuflw, 0b11110001);
|
||||
T(pshuflw, 0b11110011);
|
||||
T(pshuflw, 0b11111100);
|
||||
T(pshuflw, 0b11111101);
|
||||
T(pshuflw, 0b11111111);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(pshufhw, test) {
|
||||
int i, j;
|
||||
int16_t x[8], a[8], b[8];
|
||||
for (i = 0; i < 10; ++i) {
|
||||
for (j = 0; j < 8; ++j) x[j] = rand();
|
||||
T(pshufhw, 0b00000000);
|
||||
T(pshufhw, 0b00000001);
|
||||
T(pshufhw, 0b00000011);
|
||||
T(pshufhw, 0b00001100);
|
||||
T(pshufhw, 0b00001101);
|
||||
T(pshufhw, 0b00001111);
|
||||
T(pshufhw, 0b00110000);
|
||||
T(pshufhw, 0b00110001);
|
||||
T(pshufhw, 0b00110011);
|
||||
T(pshufhw, 0b00111100);
|
||||
T(pshufhw, 0b00111101);
|
||||
T(pshufhw, 0b00111111);
|
||||
T(pshufhw, 0b01000000);
|
||||
T(pshufhw, 0b01000001);
|
||||
T(pshufhw, 0b01000011);
|
||||
T(pshufhw, 0b01001100);
|
||||
T(pshufhw, 0b01001101);
|
||||
T(pshufhw, 0b01001111);
|
||||
T(pshufhw, 0b01110000);
|
||||
T(pshufhw, 0b01110001);
|
||||
T(pshufhw, 0b01110011);
|
||||
T(pshufhw, 0b01111100);
|
||||
T(pshufhw, 0b01111101);
|
||||
T(pshufhw, 0b01111111);
|
||||
T(pshufhw, 0b11000000);
|
||||
T(pshufhw, 0b11000001);
|
||||
T(pshufhw, 0b11000011);
|
||||
T(pshufhw, 0b11001100);
|
||||
T(pshufhw, 0b11001101);
|
||||
T(pshufhw, 0b11001111);
|
||||
T(pshufhw, 0b11110000);
|
||||
T(pshufhw, 0b11110001);
|
||||
T(pshufhw, 0b11110011);
|
||||
T(pshufhw, 0b11111100);
|
||||
T(pshufhw, 0b11111101);
|
||||
T(pshufhw, 0b11111111);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(pshufd, test) {
|
||||
int i, j;
|
||||
int32_t x[4], a[4], b[4];
|
||||
for (i = 0; i < 10; ++i) {
|
||||
for (j = 0; j < 4; ++j) x[j] = rand();
|
||||
T(pshufd, 0b00000000);
|
||||
T(pshufd, 0b00000001);
|
||||
T(pshufd, 0b00000011);
|
||||
T(pshufd, 0b00001100);
|
||||
T(pshufd, 0b00001101);
|
||||
T(pshufd, 0b00001111);
|
||||
T(pshufd, 0b00110000);
|
||||
T(pshufd, 0b00110001);
|
||||
T(pshufd, 0b00110011);
|
||||
T(pshufd, 0b00111100);
|
||||
T(pshufd, 0b00111101);
|
||||
T(pshufd, 0b00111111);
|
||||
T(pshufd, 0b01000000);
|
||||
T(pshufd, 0b01000001);
|
||||
T(pshufd, 0b01000011);
|
||||
T(pshufd, 0b01001100);
|
||||
T(pshufd, 0b01001101);
|
||||
T(pshufd, 0b01001111);
|
||||
T(pshufd, 0b01110000);
|
||||
T(pshufd, 0b01110001);
|
||||
T(pshufd, 0b01110011);
|
||||
T(pshufd, 0b01111100);
|
||||
T(pshufd, 0b01111101);
|
||||
T(pshufd, 0b01111111);
|
||||
T(pshufd, 0b11000000);
|
||||
T(pshufd, 0b11000001);
|
||||
T(pshufd, 0b11000011);
|
||||
T(pshufd, 0b11001100);
|
||||
T(pshufd, 0b11001101);
|
||||
T(pshufd, 0b11001111);
|
||||
T(pshufd, 0b11110000);
|
||||
T(pshufd, 0b11110001);
|
||||
T(pshufd, 0b11110011);
|
||||
T(pshufd, 0b11111100);
|
||||
T(pshufd, 0b11111101);
|
||||
T(pshufd, 0b11111111);
|
||||
}
|
||||
}
|
|
@ -5,12 +5,14 @@ PKGS += TEST_LIBC_INTRIN
|
|||
|
||||
TEST_LIBC_INTRIN_SRCS := $(wildcard test/libc/intrin/*.c)
|
||||
TEST_LIBC_INTRIN_SRCS_TEST = $(filter %_test.c,$(TEST_LIBC_INTRIN_SRCS))
|
||||
TEST_LIBC_INTRIN_COMS = $(TEST_LIBC_INTRIN_OBJS:%.o=%.com)
|
||||
|
||||
TEST_LIBC_INTRIN_OBJS = \
|
||||
$(TEST_LIBC_INTRIN_SRCS:%=o/$(MODE)/%.zip.o) \
|
||||
$(TEST_LIBC_INTRIN_SRCS:%.c=o/$(MODE)/%.o)
|
||||
|
||||
TEST_LIBC_INTRIN_COMS = \
|
||||
$(TEST_LIBC_INTRIN_SRCS:%.c=o/$(MODE)/%.com)
|
||||
|
||||
TEST_LIBC_INTRIN_BINS = \
|
||||
$(TEST_LIBC_INTRIN_COMS) \
|
||||
$(TEST_LIBC_INTRIN_COMS:%=%.dbg)
|
||||
|
@ -22,12 +24,17 @@ TEST_LIBC_INTRIN_CHECKS = \
|
|||
$(TEST_LIBC_INTRIN_SRCS_TEST:%.c=o/$(MODE)/%.com.runs)
|
||||
|
||||
TEST_LIBC_INTRIN_DIRECTDEPS = \
|
||||
LIBC_FMT \
|
||||
LIBC_INTRIN \
|
||||
LIBC_NEXGEN32E \
|
||||
LIBC_RAND \
|
||||
LIBC_LOG \
|
||||
LIBC_STUBS \
|
||||
LIBC_TESTLIB \
|
||||
LIBC_TINYMATH \
|
||||
TOOL_VIZ_LIB \
|
||||
LIBC_TESTLIB
|
||||
LIBC_RUNTIME \
|
||||
LIBC_X \
|
||||
TOOL_VIZ_LIB
|
||||
|
||||
TEST_LIBC_INTRIN_DEPS := \
|
||||
$(call uniq,$(foreach x,$(TEST_LIBC_INTRIN_DIRECTDEPS),$($(x))))
|
||||
|
|
29
test/libc/math/ilogb_test.c
Normal file
29
test/libc/math/ilogb_test.c
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/math.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
TEST(ilogb, test) {
|
||||
EXPECT_EQ(0x7fffffff, ilogb(INFINITY));
|
||||
EXPECT_EQ(0, ilogb(1));
|
||||
EXPECT_EQ(1, ilogb(2));
|
||||
EXPECT_EQ(2, ilogb(4));
|
||||
EXPECT_EQ(63, ilogb(1e19));
|
||||
}
|
|
@ -5,12 +5,14 @@ PKGS += TEST_LIBC_MATH
|
|||
|
||||
TEST_LIBC_MATH_SRCS := $(wildcard test/libc/math/*.c)
|
||||
TEST_LIBC_MATH_SRCS_TEST = $(filter %_test.c,$(TEST_LIBC_MATH_SRCS))
|
||||
TEST_LIBC_MATH_COMS = $(TEST_LIBC_MATH_OBJS:%.o=%.com)
|
||||
|
||||
TEST_LIBC_MATH_OBJS = \
|
||||
$(TEST_LIBC_MATH_SRCS:%=o/$(MODE)/%.zip.o) \
|
||||
$(TEST_LIBC_MATH_SRCS:%.c=o/$(MODE)/%.o)
|
||||
|
||||
TEST_LIBC_MATH_COMS = \
|
||||
$(TEST_LIBC_MATH_SRCS:%.c=o/$(MODE)/%.com)
|
||||
|
||||
TEST_LIBC_MATH_BINS = \
|
||||
$(TEST_LIBC_MATH_COMS) \
|
||||
$(TEST_LIBC_MATH_COMS:%=%.dbg)
|
||||
|
@ -23,7 +25,7 @@ TEST_LIBC_MATH_CHECKS = \
|
|||
TEST_LIBC_MATH_DIRECTDEPS = \
|
||||
LIBC_CALLS_HEFTY \
|
||||
LIBC_FMT \
|
||||
LIBC_TINYMATH \
|
||||
LIBC_MATH \
|
||||
LIBC_MEM \
|
||||
LIBC_RUNTIME \
|
||||
LIBC_STUBS \
|
||||
|
|
|
@ -18,7 +18,59 @@
|
|||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/bits/safemacros.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/stat.h"
|
||||
#include "libc/macros.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/rand/rand.h"
|
||||
#include "libc/runtime/memtrack.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/map.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
#include "libc/sysv/consts/prot.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
TEST(malloc, test) { free(malloc(123)); }
|
||||
#define N 1024
|
||||
#define M 20
|
||||
|
||||
TEST(malloc, test) {
|
||||
static struct stat st;
|
||||
static volatile int i, j, k, *A[4096], fds[M], *maps[M], mapsizes[M];
|
||||
memset(fds, -1, sizeof(fds));
|
||||
memset(maps, -1, sizeof(maps));
|
||||
for (i = 0; i < N * M; ++i) {
|
||||
j = rand() % ARRAYLEN(A);
|
||||
if (A[j]) {
|
||||
ASSERT_EQ(j, A[j][0]);
|
||||
A[j] = realloc(A[j], max(sizeof(int), rand() % N));
|
||||
ASSERT_NE(NULL, A[j]);
|
||||
ASSERT_EQ(j, A[j][0]);
|
||||
free(A[j]);
|
||||
A[j] = NULL;
|
||||
} else {
|
||||
A[j] = malloc(max(sizeof(int), rand() % N));
|
||||
ASSERT_NE(NULL, A[j]);
|
||||
A[j][0] = j;
|
||||
}
|
||||
if (i % M == 0) {
|
||||
k = rand() % M;
|
||||
if (fds[k] == -1) {
|
||||
ASSERT_NE(-1, (fds[k] = open(program_invocation_name, O_RDONLY)));
|
||||
ASSERT_NE(-1, fstat(fds[k], &st));
|
||||
ASSERT_NE(MAP_FAILED,
|
||||
(maps[k] = mmap(NULL, (mapsizes[k] = st.st_size), PROT_READ,
|
||||
MAP_SHARED, fds[k], 0)));
|
||||
} else {
|
||||
ASSERT_NE(-1, munmap(maps[k], mapsizes[k]));
|
||||
ASSERT_NE(-1, close(fds[k]));
|
||||
fds[k] = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i = 0; i < ARRAYLEN(A); ++i) free(A[i]);
|
||||
for (i = 0; i < ARRAYLEN(maps); ++i) munmap(maps[i], mapsizes[i]);
|
||||
for (i = 0; i < ARRAYLEN(fds); ++i) close(fds[i]);
|
||||
}
|
||||
|
|
|
@ -5,12 +5,14 @@ PKGS += TEST_LIBC_MEM
|
|||
|
||||
TEST_LIBC_MEM_SRCS := $(wildcard test/libc/mem/*.c)
|
||||
TEST_LIBC_MEM_SRCS_TEST = $(filter %_test.c,$(TEST_LIBC_MEM_SRCS))
|
||||
TEST_LIBC_MEM_COMS = $(TEST_LIBC_MEM_OBJS:%.o=%.com)
|
||||
|
||||
TEST_LIBC_MEM_OBJS = \
|
||||
$(TEST_LIBC_MEM_SRCS:%=o/$(MODE)/%.zip.o) \
|
||||
$(TEST_LIBC_MEM_SRCS:%.c=o/$(MODE)/%.o)
|
||||
|
||||
TEST_LIBC_MEM_COMS = \
|
||||
$(TEST_LIBC_MEM_SRCS:%.c=o/$(MODE)/%.com)
|
||||
|
||||
TEST_LIBC_MEM_BINS = \
|
||||
$(TEST_LIBC_MEM_COMS) \
|
||||
$(TEST_LIBC_MEM_COMS:%=%.dbg)
|
||||
|
@ -22,7 +24,14 @@ TEST_LIBC_MEM_CHECKS = \
|
|||
|
||||
TEST_LIBC_MEM_DIRECTDEPS = \
|
||||
LIBC_MEM \
|
||||
LIBC_CALLS \
|
||||
LIBC_STUBS \
|
||||
LIBC_NEXGEN32E \
|
||||
LIBC_SYSV \
|
||||
LIBC_FMT \
|
||||
LIBC_RUNTIME \
|
||||
LIBC_STDIO \
|
||||
LIBC_RAND \
|
||||
LIBC_TESTLIB
|
||||
|
||||
TEST_LIBC_MEM_DEPS := \
|
||||
|
|
|
@ -18,25 +18,40 @@
|
|||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.h"
|
||||
#include "libc/nexgen32e/crc32.h"
|
||||
#include "libc/nexgen32e/x86feature.h"
|
||||
#include "libc/str/knuthmultiplicativehash.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
#include "libc/testlib/hyperion.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
uint32_t crc32(uint32_t, const void *, int);
|
||||
uint32_t crc32$pclmul(uint32_t, const void *, size_t);
|
||||
uint32_t crc32$pclmul2(uint32_t, const void *, size_t);
|
||||
#include "third_party/zlib/zlib.h"
|
||||
|
||||
TEST(crc32, testBigText) {
|
||||
size_t size;
|
||||
void *hyperion;
|
||||
size = kHyperionSize;
|
||||
EXPECT_EQ(0xe9ded8e6, crc32(0, kHyperion, size));
|
||||
EXPECT_EQ(0xe9ded8e6, crc32_z(0, kHyperion, size));
|
||||
hyperion = kHyperion;
|
||||
EXPECT_EQ(0xe9ded8e6, crc32(0, hyperion, size));
|
||||
EXPECT_EQ(0xe9ded8e6, crc32_z(0, hyperion, size));
|
||||
if (X86_HAVE(PCLMUL)) {
|
||||
size = ROUNDDOWN(size, 64);
|
||||
EXPECT_EQ(0xc7adc04f, crc32(0, kHyperion, size));
|
||||
EXPECT_EQ(0xc7adc04f, crc32_z(0, kHyperion, size));
|
||||
EXPECT_EQ(0xc7adc04f, crc32(0, hyperion, size));
|
||||
EXPECT_EQ(0xc7adc04f, crc32_z(0, hyperion, size));
|
||||
EXPECT_EQ(0xc7adc04f,
|
||||
0xffffffffu ^ crc32$pclmul(0 ^ 0xffffffffu, kHyperion, size));
|
||||
0xffffffffu ^ crc32$pclmul(0 ^ 0xffffffffu, hyperion, size));
|
||||
}
|
||||
}
|
||||
|
||||
#define TESTSTR "libc/calls/typedef/sighandler_t.h"
|
||||
|
||||
BENCH(crc32c, bench) {
|
||||
EZBENCH2("crc32c", donothing,
|
||||
EXPROPRIATE(crc32c(0, VEIL("r", TESTSTR), sizeof(TESTSTR) - 1)));
|
||||
}
|
||||
|
||||
BENCH(KnuthMultiplicativeHash32, bench) {
|
||||
EZBENCH2("KMP", donothing,
|
||||
EXPROPRIATE(KnuthMultiplicativeHash32(VEIL("r", TESTSTR),
|
||||
sizeof(TESTSTR) - 1)));
|
||||
}
|
||||
|
|
|
@ -17,19 +17,14 @@
|
|||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/alg/alg.h"
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/macros.h"
|
||||
#include "libc/nexgen32e/nexgen32e.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
#include "libc/unicode/unicode.h"
|
||||
|
||||
TEST(heapsortcar, test) {
|
||||
int32_t A[][2] = {{4, 'a'}, {65, 'b'}, {2, 'c'}, {-31, 'd'}, {0, 'e'},
|
||||
{99, 'f'}, {2, 'g'}, {83, 'h'}, {782, 'i'}, {1, 'j'}};
|
||||
const int32_t B[][2] = {{-31, 'd'}, {0, 'e'}, {1, 'j'}, {2, 'c'},
|
||||
{2, 'g'}, {4, 'a'}, {65, 'b'}, {83, 'h'},
|
||||
{99, 'f'}, {782, 'i'}};
|
||||
unsigned n = ARRAYLEN(A);
|
||||
heapsortcar(A, n);
|
||||
ASSERT_EQ(0, memcmp(&A[0], &B[0], sizeof(A)));
|
||||
TEST(kcp437, test) {
|
||||
long i;
|
||||
for (i = 0; i < 256; ++i) {
|
||||
EXPECT_EQ(1, wcwidth(kCp437[i]), "%lc", kCp437[i]);
|
||||
}
|
||||
}
|
|
@ -20,7 +20,6 @@
|
|||
#include "libc/bits/bits.h"
|
||||
#include "libc/runtime/buffer.h"
|
||||
#include "libc/runtime/gc.h"
|
||||
#include "libc/runtime/mappings.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
|
|
@ -25,12 +25,15 @@
|
|||
#define N 256
|
||||
#define S 7
|
||||
|
||||
long i, j, n;
|
||||
char *b1, *b2;
|
||||
|
||||
TEST(memmove, overlapping) {
|
||||
for (size_t i = 0; i < N; i += S) {
|
||||
for (size_t j = 10; j < N; j += S) {
|
||||
char *b1 = tmalloc(N);
|
||||
char *b2 = tmalloc(N);
|
||||
size_t n = min(N - i, N - j);
|
||||
for (i = 0; i < N; i += S) {
|
||||
for (j = 10; j < N; j += S) {
|
||||
b1 = tmalloc(N);
|
||||
b2 = tmalloc(N);
|
||||
n = min(N - i, N - j);
|
||||
memcpy(b2, b1 + i, n);
|
||||
ASSERT_EQ(b1 + j, memmove(b1 + j, b1 + i, n));
|
||||
ASSERT_EQ(0, memcmp(b1 + j, b2, n));
|
||||
|
@ -41,11 +44,11 @@ TEST(memmove, overlapping) {
|
|||
}
|
||||
|
||||
TEST(memmove, overlappingDirect) {
|
||||
for (size_t i = 0; i < N; i += S) {
|
||||
for (size_t j = 10; j < N; j += S) {
|
||||
char *b1 = tmalloc(N);
|
||||
char *b2 = tmalloc(N);
|
||||
size_t n = min(N - i, N - j);
|
||||
for (i = 0; i < N; i += S) {
|
||||
for (j = 10; j < N; j += S) {
|
||||
b1 = tmalloc(N);
|
||||
b2 = tmalloc(N);
|
||||
n = min(N - i, N - j);
|
||||
memcpy(b2, b1 + i, n);
|
||||
ASSERT_EQ(b1 + j, (memmove)(b1 + j, b1 + i, n));
|
||||
ASSERT_EQ(0, memcmp(b1 + j, b2, n));
|
|
@ -17,54 +17,55 @@
|
|||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/intrin/packsswb.h"
|
||||
#include "libc/intrin/packuswb.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/nexgen32e/kcpuids.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/nexgen32e/nexgen32e.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
const short S[8] = {0, 128, -128, 255, SHRT_MAX, SHRT_MIN, 0, 0};
|
||||
|
||||
TEST(packuswb, test) {
|
||||
unsigned char B[16] = {0};
|
||||
packuswb(B, S, S);
|
||||
EXPECT_EQ(0, B[0]);
|
||||
EXPECT_EQ(128, B[1]);
|
||||
EXPECT_EQ(0, B[2]);
|
||||
EXPECT_EQ(255, B[3]);
|
||||
EXPECT_EQ(255, B[4]);
|
||||
EXPECT_EQ(0, B[5]);
|
||||
EXPECT_EQ(0, B[6]);
|
||||
EXPECT_EQ(0, B[7]);
|
||||
EXPECT_EQ(0, B[8]);
|
||||
EXPECT_EQ(128, B[9]);
|
||||
EXPECT_EQ(0, B[10]);
|
||||
EXPECT_EQ(255, B[11]);
|
||||
EXPECT_EQ(255, B[12]);
|
||||
EXPECT_EQ(0, B[13]);
|
||||
EXPECT_EQ(0, B[14]);
|
||||
EXPECT_EQ(0, B[15]);
|
||||
TEST(memset, testMulTrick4) {
|
||||
long i, j;
|
||||
unsigned long x;
|
||||
long di, si, dx, ax;
|
||||
volatile uint8_t *b;
|
||||
b = tgc(tmalloc(4));
|
||||
for (i = 0; i < 255; ++i) {
|
||||
for (j = -1; j < 1; ++j) {
|
||||
x = j;
|
||||
x &= ~0xff;
|
||||
x |= i;
|
||||
asm volatile("call\tmemset"
|
||||
: "=D"(di), "=S"(si), "=d"(dx), "=a"(ax)
|
||||
: "0"(b), "1"(x), "2"(4)
|
||||
: "rcx", "memory", "cc");
|
||||
ASSERT_EQ(x & 0xff, b[0]);
|
||||
ASSERT_EQ(x & 0xff, b[1]);
|
||||
ASSERT_EQ(x & 0xff, b[2]);
|
||||
ASSERT_EQ(x & 0xff, b[3]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(packsswb, test) {
|
||||
const short S[8] = {0, 128, -128, 255, SHRT_MAX, SHRT_MIN, 0, 0};
|
||||
signed char B[16] = {0};
|
||||
packsswb(B, S, S);
|
||||
EXPECT_EQ(0, B[0]);
|
||||
EXPECT_EQ(127, B[1]);
|
||||
EXPECT_EQ(-128, B[2]);
|
||||
EXPECT_EQ(127, B[3]);
|
||||
EXPECT_EQ(127, B[4]);
|
||||
EXPECT_EQ(-128, B[5]);
|
||||
EXPECT_EQ(0, B[6]);
|
||||
EXPECT_EQ(0, B[7]);
|
||||
EXPECT_EQ(0, B[8]);
|
||||
EXPECT_EQ(127, B[9]);
|
||||
EXPECT_EQ(-128, B[10]);
|
||||
EXPECT_EQ(127, B[11]);
|
||||
EXPECT_EQ(127, B[12]);
|
||||
EXPECT_EQ(-128, B[13]);
|
||||
EXPECT_EQ(0, B[14]);
|
||||
EXPECT_EQ(0, B[15]);
|
||||
TEST(memset, testMulTrick8) {
|
||||
long i, j;
|
||||
unsigned long x;
|
||||
long di, si, dx, ax;
|
||||
volatile uint8_t *b;
|
||||
b = tgc(tmalloc(8));
|
||||
for (i = 0; i < 255; ++i) {
|
||||
for (j = -1; j < 1; ++j) {
|
||||
x = j;
|
||||
x &= ~0xff;
|
||||
x |= i;
|
||||
asm volatile("call\tmemset"
|
||||
: "=D"(di), "=S"(si), "=d"(dx), "=a"(ax)
|
||||
: "0"(b), "1"(x), "2"(8)
|
||||
: "rcx", "memory", "cc");
|
||||
ASSERT_EQ(x & 0xff, b[0]);
|
||||
ASSERT_EQ(x & 0xff, b[1]);
|
||||
ASSERT_EQ(x & 0xff, b[2]);
|
||||
ASSERT_EQ(x & 0xff, b[3]);
|
||||
ASSERT_EQ(x & 0xff, b[4]);
|
||||
ASSERT_EQ(x & 0xff, b[5]);
|
||||
ASSERT_EQ(x & 0xff, b[6]);
|
||||
ASSERT_EQ(x & 0xff, b[7]);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -17,32 +17,32 @@
|
|||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/intrin/phaddw.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/nexgen32e/nexgen32e.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
#include "tool/viz/lib/formatstringtable-testlib.h"
|
||||
/* clang-format off */
|
||||
|
||||
FIXTURE(phaddw, disableHardwareExtensions) {
|
||||
memset((/*unconst*/ void *)kCpuids, 0, sizeof(kCpuids));
|
||||
TEST(sidiv, smoke) {
|
||||
EXPECT_EQ(13373133731337 / 10, div10int64(13373133731337));
|
||||
EXPECT_EQ(13373133731337 / 100, div100int64(13373133731337));
|
||||
EXPECT_EQ(13373133731337 / 1000, div1000int64(13373133731337));
|
||||
EXPECT_EQ(13373133731337 / 10000, div10000int64(13373133731337));
|
||||
EXPECT_EQ(13373133731337 / 1000000, div1000000int64(13373133731337));
|
||||
EXPECT_EQ(13373133731337 / 1000000000, div1000000000int64(13373133731337));
|
||||
}
|
||||
|
||||
TEST(phaddw, testOverflow_wrapsAround) {
|
||||
short M[2][8] = {
|
||||
{0x7fff, 0, 0x7fff, 1, 13004, -30425, 20777, -16389},
|
||||
{-28040, 13318, -1336, -24798, -13876, 3599, -7346, -23575},
|
||||
};
|
||||
phaddw(M[0], M[0], M[1]);
|
||||
EXPECT_SHRTMATRIXEQ(2, 8, M, "\n\
|
||||
32767 -32768 -17421 4388 -14722 -26134 -10277 -30921\n\
|
||||
-28040 13318 -1336 -24798 -13876 3599 -7346 -23575");
|
||||
TEST(sirem, smoke) {
|
||||
EXPECT_EQ(13373133731337 % 10, rem10int64(13373133731337));
|
||||
EXPECT_EQ(13373133731337 % 100, rem100int64(13373133731337));
|
||||
EXPECT_EQ(13373133731337 % 1000, rem1000int64(13373133731337));
|
||||
EXPECT_EQ(13373133731337 % 10000, rem10000int64(13373133731337));
|
||||
EXPECT_EQ(13373133731337 % 1000000, rem1000000int64(13373133731337));
|
||||
EXPECT_EQ(13373133731337 % 1000000000, rem1000000000int64(13373133731337));
|
||||
}
|
||||
|
||||
TEST(phaddw, testAliasing_isOk) {
|
||||
short M[1][8] = {
|
||||
{0,1, 2,3, 4,5, 6,7},
|
||||
};
|
||||
phaddw(M[0],M[0],M[0]);
|
||||
EXPECT_SHRTMATRIXEQ(1, 8, M, "\n\
|
||||
1 5 9 13 1 5 9 13");
|
||||
TEST(rem, euclid) {
|
||||
ASSERT_EQ(-2, rem10int64(-12));
|
||||
ASSERT_EQ(-1, rem10int64(-1));
|
||||
ASSERT_EQ(0, rem10int64(0));
|
||||
ASSERT_EQ(1, rem10int64(1));
|
||||
ASSERT_EQ(9, rem10int64(9));
|
||||
ASSERT_EQ(1, rem10int64(11));
|
||||
}
|
|
@ -24,25 +24,31 @@
|
|||
#include "libc/testlib/testlib.h"
|
||||
|
||||
TEST(strtolower, testAligned) {
|
||||
char s[128] = "AZCDabcdABCDabcdABCDabcdABCDabcdABCDabcd";
|
||||
EXPECT_STREQ("azcdabcdabcdabcdabcdabcdabcdabcdabcdabcd", strtolower(s));
|
||||
EXPECT_STREQ("azcdabcdabcdabcd",
|
||||
strtolower(tgc(tstrdup("AZCDabcdABCDabcd"))));
|
||||
EXPECT_STREQ("azcdabcdabcdabcdabcdabcdabcdabcd",
|
||||
strtolower(tgc(tstrdup("AZCDabcdABCDabcdABCDabcdABCDabcd"))));
|
||||
}
|
||||
|
||||
TEST(strtolower, testUnaligned) {
|
||||
char s[128] = "AZCDabcdABCDabcdABCDabcdABCDabcdABCDabcd";
|
||||
strtolower(s + 1);
|
||||
EXPECT_STREQ("Azcdabcdabcdabcdabcdabcdabcdabcdabcdabcd", s);
|
||||
EXPECT_STREQ("1", strtolower(tgc(tstrdup("1"))));
|
||||
EXPECT_STREQ(
|
||||
"zcdabcdabcdabcdabcdabcdabcdabc",
|
||||
strtolower((char *)tgc(tstrdup("AZCDabcdABCDabcdABCDabcdABCDabc")) + 1));
|
||||
}
|
||||
|
||||
TEST(strtoupper, testAligned) {
|
||||
char s[128] = "AZCDabcdABCDabcdA0CDabcdABCDabcdABCDabcd";
|
||||
EXPECT_STREQ("AZCDABCDABCDABCDA0CDABCDABCDABCDABCDABCD", strtoupper(s));
|
||||
EXPECT_STREQ("AZCDABCDABCDABCD",
|
||||
strtoupper(tgc(tstrdup("AZCDabcdABCDabcd"))));
|
||||
EXPECT_STREQ("AZCDABCDABCDABCDABCDABCDABCDABCD",
|
||||
strtoupper(tgc(tstrdup("AZCDabcdABCDabcdABCDabcdABCDabcd"))));
|
||||
}
|
||||
|
||||
TEST(strtoupper, testUnaligned) {
|
||||
char s[128] = "aZCDabcdABCDabcdABCDabcdABCDabcdABCDabcd";
|
||||
strtoupper(s + 1);
|
||||
EXPECT_STREQ("aZCDABCDABCDABCDABCDABCDABCDABCDABCDABCD", s);
|
||||
EXPECT_STREQ("1", strtoupper(tgc(tstrdup("1"))));
|
||||
EXPECT_STREQ(
|
||||
"ZCDABCDABCDABCDABCDABCDABCDABC",
|
||||
strtoupper((char *)tgc(tstrdup("AZCDabcdABCDabcdABCDabcdABCDabc")) + 1));
|
||||
}
|
||||
|
||||
BENCH(strtolower, bench) {
|
|
@ -13,7 +13,7 @@ TEST_LIBC_NEXGEN32E_OBJS = \
|
|||
$(TEST_LIBC_NEXGEN32E_SRCS:%.c=o/$(MODE)/%.o)
|
||||
|
||||
TEST_LIBC_NEXGEN32E_COMS = \
|
||||
$(TEST_LIBC_NEXGEN32E_OBJS:%.o=%.com)
|
||||
$(TEST_LIBC_NEXGEN32E_SRCS:%.c=o/$(MODE)/%.com)
|
||||
|
||||
TEST_LIBC_NEXGEN32E_BINS = \
|
||||
$(TEST_LIBC_NEXGEN32E_COMS) \
|
||||
|
@ -38,6 +38,7 @@ TEST_LIBC_NEXGEN32E_DIRECTDEPS = \
|
|||
LIBC_RUNTIME \
|
||||
LIBC_STUBS \
|
||||
LIBC_STR \
|
||||
LIBC_UNICODE \
|
||||
LIBC_TESTLIB \
|
||||
LIBC_X \
|
||||
TOOL_VIZ_LIB
|
||||
|
|
|
@ -5,13 +5,15 @@ PKGS += TEST_LIBC_RAND
|
|||
|
||||
TEST_LIBC_RAND_SRCS := $(wildcard test/libc/rand/*.c)
|
||||
TEST_LIBC_RAND_SRCS_TEST = $(filter %_test.c,$(TEST_LIBC_RAND_SRCS))
|
||||
TEST_LIBC_RAND_COMS = $(TEST_LIBC_RAND_OBJS:%.o=%.com)
|
||||
TEST_LIBC_RAND_BINS = $(TEST_LIBC_RAND_COMS) $(TEST_LIBC_RAND_COMS:%=%.dbg)
|
||||
|
||||
TEST_LIBC_RAND_OBJS = \
|
||||
$(TEST_LIBC_RAND_SRCS:%=o/$(MODE)/%.zip.o) \
|
||||
$(TEST_LIBC_RAND_SRCS:%.c=o/$(MODE)/%.o)
|
||||
|
||||
TEST_LIBC_RAND_COMS = \
|
||||
$(TEST_LIBC_RAND_SRCS:%.c=o/$(MODE)/%.com)
|
||||
|
||||
TEST_LIBC_RAND_TESTS = $(TEST_LIBC_RAND_SRCS_TEST:%.c=o/$(MODE)/%.com.ok)
|
||||
|
||||
TEST_LIBC_RAND_CHECKS = \
|
||||
|
@ -45,9 +47,7 @@ o/$(MODE)/test/libc/rand/%.com.dbg: \
|
|||
$(APE)
|
||||
@$(APELINK)
|
||||
|
||||
$(TEST_LIBC_RAND_OBJS): \
|
||||
$(BUILD_FILES) \
|
||||
test/libc/rand/test.mk
|
||||
$(TEST_LIBC_RAND_OBJS): test/libc/rand/test.mk
|
||||
|
||||
$(TEST_LIBC_RAND_OBJS): \
|
||||
DEFAULT_CCFLAGS += \
|
||||
|
|
|
@ -17,8 +17,9 @@
|
|||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/dce.h"
|
||||
#include "libc/bits/segmentation.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
TEST(arch_prctl, fs) {
|
||||
|
|
|
@ -1,105 +0,0 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/safemacros.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/sigaction.h"
|
||||
#include "libc/calls/ucontext.h"
|
||||
#include "libc/runtime/buffer.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/fileno.h"
|
||||
#include "libc/sysv/consts/prot.h"
|
||||
#include "libc/sysv/consts/sa.h"
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
#include "libc/x/x.h"
|
||||
#include "third_party/xed/x86.h"
|
||||
|
||||
char *p;
|
||||
bool segfaulted_;
|
||||
struct GuardedBuffer b_;
|
||||
struct sigaction oldsegv_;
|
||||
struct XedDecodedInst xedd_;
|
||||
|
||||
void RestrictPage(void *addr, unsigned flags) {
|
||||
addr = (void *)rounddown((intptr_t)addr, PAGESIZE);
|
||||
EXPECT_NE(-1, mprotect(addr, PAGESIZE, flags));
|
||||
}
|
||||
|
||||
void OnSegLol(int sig, struct siginfo *si, struct ucontext *uc) {
|
||||
size_t i;
|
||||
uint8_t *rip;
|
||||
segfaulted_ = true;
|
||||
rip = (uint8_t *)uc->uc_mcontext.rip;
|
||||
RestrictPage(rip, PROT_READ | PROT_WRITE | PROT_EXEC);
|
||||
ASSERT_EQ(XED_ERROR_NONE,
|
||||
xed_instruction_length_decode(xed_decoded_inst_zero_set_mode(
|
||||
&xedd_, XED_MACHINE_MODE_LONG_64),
|
||||
rip, XED_MAX_INSTRUCTION_BYTES));
|
||||
for (i = 0; i < xedd_.decoded_length; ++i) rip[i] = 0x90; /* NOP */
|
||||
RestrictPage(rip, PROT_READ | PROT_EXEC);
|
||||
}
|
||||
|
||||
void SetUp(void) {
|
||||
segfaulted_ = false;
|
||||
memset(&b_, 0, sizeof(b_));
|
||||
ASSERT_NE(-1, xsigaction(SIGSEGV, OnSegLol, SA_RESETHAND | SA_RESTART, 0,
|
||||
&oldsegv_));
|
||||
}
|
||||
|
||||
void TearDown(void) {
|
||||
EXPECT_NE(-1, sigaction(SIGSEGV, &oldsegv_, NULL));
|
||||
bfree(&b_);
|
||||
EXPECT_EQ(NULL, b_.p);
|
||||
}
|
||||
|
||||
TEST(balloc, createsGuardPage) {
|
||||
ASSERT_NE(NULL, (p = balloc(&b_, 1, 1)));
|
||||
EXPECT_EQ(p, b_.p);
|
||||
p[0] = '.';
|
||||
ASSERT_FALSE(segfaulted_);
|
||||
/* TODO(jart): fix me!!! */
|
||||
/* p[1 + __BIGGEST_ALIGNMENT__] = '!'; */
|
||||
/* EXPECT_TRUE(segfaulted_); */
|
||||
}
|
||||
|
||||
TEST(balloc, aligned_roundsUp) {
|
||||
ASSERT_NE(NULL, (p = balloc(&b_, 128, 1)));
|
||||
EXPECT_EQ(0, (intptr_t)b_.p & 127);
|
||||
p[127] = '.';
|
||||
ASSERT_FALSE(segfaulted_);
|
||||
/* TODO(jart): fix me!!! */
|
||||
/* p[128 + __BIGGEST_ALIGNMENT__] = '!'; */
|
||||
/* EXPECT_TRUE(segfaulted_); */
|
||||
}
|
||||
|
||||
TEST(balloc, multipleCalls_avoidsNeedlessSyscalls) {
|
||||
size_t c;
|
||||
c = g_syscount;
|
||||
ASSERT_NE(NULL, (p = balloc(&b_, 1, 31337)));
|
||||
EXPECT_GT(g_syscount, c);
|
||||
c = g_syscount;
|
||||
ASSERT_NE(NULL, (p = balloc(&b_, 1, 31337 / 2)));
|
||||
EXPECT_EQ(g_syscount, c);
|
||||
c = g_syscount;
|
||||
ASSERT_NE(NULL, (p = balloc(&b_, 1, 31337 * 2)));
|
||||
EXPECT_GT(g_syscount, c);
|
||||
}
|
75
test/libc/runtime/carsort_test.c
Normal file
75
test/libc/runtime/carsort_test.c
Normal file
|
@ -0,0 +1,75 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/alg/alg.h"
|
||||
#include "libc/macros.h"
|
||||
#include "libc/rand/rand.h"
|
||||
#include "libc/runtime/carsort.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
const int32_t kUnsorted[][2] = {
|
||||
{4, 'a'}, {65, 'b'}, {2, 'c'}, {-1, 'G'}, {-31, 'd'}, {0, 'e'},
|
||||
{99, 'f'}, {2, 'g'}, {83, 'h'}, {782, 'i'}, {1, 'j'},
|
||||
};
|
||||
|
||||
const int32_t kGolden[][2] = {
|
||||
{-31, 'd'}, {-1, 'G'}, {0, 'e'}, {1, 'j'}, {2, 'c'}, {2, 'g'},
|
||||
{4, 'a'}, {65, 'b'}, {83, 'h'}, {99, 'f'}, {782, 'i'},
|
||||
};
|
||||
|
||||
int32_t A[ARRAYLEN(kUnsorted)][2];
|
||||
int32_t B[2100][2];
|
||||
|
||||
TEST(carsort100, test) {
|
||||
memcpy(A, kUnsorted, sizeof(A));
|
||||
carsort100(ARRAYLEN(A), A);
|
||||
ASSERT_EQ(0, memcmp(&A[0], &kGolden[0], sizeof(kUnsorted)));
|
||||
}
|
||||
|
||||
TEST(carsort1000, test) {
|
||||
memcpy(A, kUnsorted, sizeof(A));
|
||||
carsort1000(ARRAYLEN(A), A);
|
||||
ASSERT_EQ(0, memcmp(&A[0], &kGolden[0], sizeof(kUnsorted)));
|
||||
}
|
||||
|
||||
TEST(qsort, test) {
|
||||
memcpy(A, kUnsorted, sizeof(A));
|
||||
qsort(A, ARRAYLEN(A), 8, cmpsl);
|
||||
ASSERT_EQ(0, memcmp(&A[0], &kGolden[0], sizeof(kUnsorted)));
|
||||
}
|
||||
|
||||
BENCH(carsort, benchMedium) {
|
||||
EZBENCH2("medium carsort100", rngset(B, sizeof(B), rand64, -1),
|
||||
carsort100(ARRAYLEN(B), B));
|
||||
EZBENCH2("medium carsort1000", rngset(B, sizeof(B), rand64, -1),
|
||||
carsort1000(ARRAYLEN(B), B));
|
||||
EZBENCH2("medium qsort", rngset(B, sizeof(B), rand64, -1),
|
||||
qsort(B, ARRAYLEN(B), 8, cmpsl));
|
||||
}
|
||||
|
||||
BENCH(carsort, benchSmall) {
|
||||
EZBENCH2("small carsort100", memcpy(A, kUnsorted, sizeof(A)),
|
||||
carsort100(ARRAYLEN(A), A));
|
||||
EZBENCH2("small carsort1000", memcpy(A, kUnsorted, sizeof(A)),
|
||||
carsort1000(ARRAYLEN(A), A));
|
||||
EZBENCH2("small qsort", memcpy(A, kUnsorted, sizeof(A)),
|
||||
qsort(A, ARRAYLEN(A), 8, cmpsl));
|
||||
}
|
|
@ -21,7 +21,6 @@
|
|||
#include "libc/limits.h"
|
||||
#include "libc/macros.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/mappings.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
* @see __addvsi3, __mulvsi3, etc.
|
||||
*/
|
||||
|
||||
bool overflowed_;
|
||||
volatile bool overflowed_;
|
||||
|
||||
void __on_arithmetic_overflow(void) {
|
||||
overflowed_ = true;
|
||||
|
@ -174,6 +174,16 @@ TEST(__mulvdi3, standAndDeliver_aNegativeTimesANegativeEqualsAPositive) {
|
|||
EXPECT_FALSE(overflowed_);
|
||||
}
|
||||
|
||||
TEST(__mulvdi3, testOverflow) {
|
||||
volatile int64_t x;
|
||||
x = 3037000500;
|
||||
x *= 3037000499;
|
||||
EXPECT_FALSE(overflowed_);
|
||||
x = 3037000500;
|
||||
x *= 3037000500;
|
||||
EXPECT_TRUE(overflowed_);
|
||||
}
|
||||
|
||||
/* 32-BIT SIGNED ADDITION */
|
||||
|
||||
TEST(__addvsi3, testMin1) {
|
||||
|
@ -246,3 +256,99 @@ TEST(__subvdi3, testMax1) {
|
|||
EXPECT_EQ(LONG_MAX - 1, VEIL("r", LONG_MAX) - 1);
|
||||
EXPECT_FALSE(overflowed_);
|
||||
}
|
||||
|
||||
/* 128-BIT SIGNED ADDITION */
|
||||
|
||||
TEST(__addvti3, testMath) {
|
||||
volatile int128_t x;
|
||||
x = 2;
|
||||
x += 2;
|
||||
EXPECT_EQ(4, x);
|
||||
x = -2;
|
||||
x += -2;
|
||||
EXPECT_EQ(-4, x);
|
||||
x = UINT64_MAX;
|
||||
x += 1;
|
||||
EXPECT_EQ((int128_t)UINT64_MAX + 1, x);
|
||||
EXPECT_FALSE(overflowed_);
|
||||
}
|
||||
|
||||
TEST(__addvti3, testOverflow) {
|
||||
volatile int128_t x;
|
||||
x = INT128_MAX;
|
||||
x += 1;
|
||||
EXPECT_TRUE(overflowed_);
|
||||
}
|
||||
|
||||
/* 128-BIT SIGNED SUBTRACTION */
|
||||
|
||||
TEST(__subvti3, testMath) {
|
||||
volatile int128_t x;
|
||||
x = -2;
|
||||
x -= 2;
|
||||
EXPECT_EQ(-4, x);
|
||||
x = UINT64_MIN;
|
||||
x -= 1;
|
||||
EXPECT_EQ((int128_t)UINT64_MIN - 1, x);
|
||||
EXPECT_FALSE(overflowed_);
|
||||
}
|
||||
|
||||
TEST(__subvti3, testOverflow) {
|
||||
volatile int128_t x;
|
||||
x = INT128_MIN;
|
||||
x -= 1;
|
||||
EXPECT_TRUE(overflowed_);
|
||||
}
|
||||
|
||||
/* 128-BIT SIGNED NEGATION */
|
||||
|
||||
TEST(__negvti3, testMath) {
|
||||
volatile int128_t x;
|
||||
x = -2;
|
||||
x = -x;
|
||||
EXPECT_EQ(2, x);
|
||||
EXPECT_FALSE(overflowed_);
|
||||
x = INT128_MAX;
|
||||
x = -x;
|
||||
EXPECT_EQ(INT128_MIN + 1, x);
|
||||
EXPECT_FALSE(overflowed_);
|
||||
x = (uint128_t)0x8000000000000000 << 64 | 0x8000000000000000;
|
||||
x = -x;
|
||||
EXPECT_EQ((uint128_t)0x7fffffffffffffff << 64 | 0x8000000000000000, x);
|
||||
EXPECT_FALSE(overflowed_);
|
||||
}
|
||||
|
||||
TEST(__negvti3, testOverflow) {
|
||||
volatile int128_t x;
|
||||
x = INT128_MIN;
|
||||
x = -x;
|
||||
EXPECT_TRUE(overflowed_);
|
||||
}
|
||||
|
||||
/* 128-BIT SIGNED MULTIPLICATION */
|
||||
|
||||
TEST(__mulvti3, testMath) {
|
||||
volatile int128_t x;
|
||||
x = 7;
|
||||
x *= 11;
|
||||
EXPECT_EQ(77, x);
|
||||
EXPECT_FALSE(overflowed_);
|
||||
x = 0x1fffffffffffffff;
|
||||
x *= 0x1fffffffffffffff;
|
||||
EXPECT_EQ((uint128_t)0x3ffffffffffffff << 64 | 0xc000000000000001, x);
|
||||
EXPECT_FALSE(overflowed_);
|
||||
x = -0x1fffffffffffffff;
|
||||
x *= 0x1fffffffffffffff;
|
||||
EXPECT_EQ((uint128_t)0xfc00000000000000 << 64 | 0x3fffffffffffffff, x);
|
||||
EXPECT_FALSE(overflowed_);
|
||||
}
|
||||
|
||||
TEST(__mulvti3, testOverflow) {
|
||||
volatile int128_t x;
|
||||
x = 0xb504f333f9de5be0;
|
||||
x *= 0xb504f333f9de6d28;
|
||||
EXPECT_FALSE(overflowed_);
|
||||
x = 0xb504f333f9de5be0;
|
||||
x *= 0xb504f333f9de6d29;
|
||||
EXPECT_TRUE(overflowed_);
|
||||
}
|
||||
|
|
289
test/libc/runtime/memtrack_test.c
Normal file
289
test/libc/runtime/memtrack_test.c
Normal file
|
@ -0,0 +1,289 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/errno.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/memtrack.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
static bool AreMemoryIntervalsEqual(const struct MemoryIntervals *mm1,
|
||||
const struct MemoryIntervals *mm2) {
|
||||
if (mm1->i != mm2->i) return false;
|
||||
if (memcmp(mm1->p, mm2->p, mm1->i * sizeof(*mm2->p)) != 0) return false;
|
||||
if (memcmp(mm1->h, mm2->h, mm1->i * sizeof(*mm2->h)) != 0) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void PrintMemoryInterval(const struct MemoryIntervals *mm) {
|
||||
int i;
|
||||
for (i = 0; i < mm->i; ++i) {
|
||||
if (i) fprintf(stderr, ",");
|
||||
fprintf(stderr, "{%d,%d}", mm->p[i].x, mm->p[i].y);
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
static void CheckMemoryIntervalsEqual(const struct MemoryIntervals *mm1,
|
||||
const struct MemoryIntervals *mm2) {
|
||||
if (!AreMemoryIntervalsEqual(mm1, mm2)) {
|
||||
PrintMemoryInterval(mm1);
|
||||
PrintMemoryInterval(mm2);
|
||||
CHECK(!"memory intervals not equal");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
static void CheckMemoryIntervalsAreOk(const struct MemoryIntervals *mm) {
|
||||
if (!AreMemoryIntervalsOk(mm)) {
|
||||
PrintMemoryInterval(mm);
|
||||
CHECK(!"memory intervals not ok");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
static void RunTrackMemoryIntervalTest(const struct MemoryIntervals t[2], int x,
|
||||
int y, long h) {
|
||||
struct MemoryIntervals *mm;
|
||||
mm = memcpy(memalign(alignof(*t), sizeof(*t)), t, sizeof(*t));
|
||||
CheckMemoryIntervalsAreOk(mm);
|
||||
CHECK_NE(-1, TrackMemoryInterval(mm, x, y, h));
|
||||
CheckMemoryIntervalsAreOk(mm);
|
||||
CheckMemoryIntervalsEqual(mm, t + 1);
|
||||
free(mm);
|
||||
}
|
||||
|
||||
static void RunReleaseMemoryIntervalsTest(const struct MemoryIntervals t[2],
|
||||
int x, int y) {
|
||||
struct MemoryIntervals *mm;
|
||||
mm = memcpy(memalign(alignof(*t), sizeof(*t)), t, sizeof(*t));
|
||||
CheckMemoryIntervalsAreOk(mm);
|
||||
CHECK_NE(-1, ReleaseMemoryIntervals(mm, x, y, NULL));
|
||||
CheckMemoryIntervalsAreOk(mm);
|
||||
CheckMemoryIntervalsEqual(t + 1, mm);
|
||||
free(mm);
|
||||
}
|
||||
|
||||
TEST(TrackMemoryInterval, TestEmpty) {
|
||||
static const struct MemoryIntervals mm[2] = {
|
||||
{0, {}, {}},
|
||||
{1, {{2, 2}}, {0}},
|
||||
};
|
||||
RunTrackMemoryIntervalTest(mm, 2, 2, 0);
|
||||
}
|
||||
|
||||
TEST(TrackMemoryInterval, TestFull) {
|
||||
int i;
|
||||
struct MemoryIntervals *mm;
|
||||
mm = calloc(1, sizeof(struct MemoryIntervals));
|
||||
for (i = 0; i < ARRAYLEN(mm->p); ++i) {
|
||||
CheckMemoryIntervalsAreOk(mm);
|
||||
CHECK_NE(-1, TrackMemoryInterval(mm, i, i, i));
|
||||
CheckMemoryIntervalsAreOk(mm);
|
||||
}
|
||||
CHECK_EQ(-1, TrackMemoryInterval(mm, i, i, i));
|
||||
CHECK_EQ(ENOMEM, errno);
|
||||
CheckMemoryIntervalsAreOk(mm);
|
||||
free(mm);
|
||||
}
|
||||
|
||||
TEST(TrackMemoryInterval, TestAppend) {
|
||||
static const struct MemoryIntervals mm[2] = {
|
||||
{1, {{2, 2}}, {0}},
|
||||
{1, {{2, 3}}, {0}},
|
||||
};
|
||||
RunTrackMemoryIntervalTest(mm, 3, 3, 0);
|
||||
}
|
||||
|
||||
TEST(TrackMemoryInterval, TestPrepend) {
|
||||
static const struct MemoryIntervals mm[2] = {
|
||||
{1, {{2, 2}}, {0}},
|
||||
{1, {{1, 2}}, {0}},
|
||||
};
|
||||
RunTrackMemoryIntervalTest(mm, 1, 1, 0);
|
||||
}
|
||||
|
||||
TEST(TrackMemoryInterval, TestFillHole) {
|
||||
static const struct MemoryIntervals mm[2] = {
|
||||
{4, {{1, 1}, {3, 4}, {5, 5}, {6, 8}}, {0, 0, 1, 0}},
|
||||
{3, {{1, 4}, {5, 5}, {6, 8}}, {0, 1, 0}},
|
||||
};
|
||||
RunTrackMemoryIntervalTest(mm, 2, 2, 0);
|
||||
}
|
||||
|
||||
TEST(TrackMemoryInterval, TestAppend2) {
|
||||
static const struct MemoryIntervals mm[2] = {
|
||||
{1, {{2, 2}}, {0}},
|
||||
{2, {{2, 2}, {3, 3}}, {0, 1}},
|
||||
};
|
||||
RunTrackMemoryIntervalTest(mm, 3, 3, 1);
|
||||
}
|
||||
|
||||
TEST(TrackMemoryInterval, TestPrepend2) {
|
||||
static const struct MemoryIntervals mm[2] = {
|
||||
{1, {{2, 2}}, {0}},
|
||||
{2, {{1, 1}, {2, 2}}, {1, 0}},
|
||||
};
|
||||
RunTrackMemoryIntervalTest(mm, 1, 1, 1);
|
||||
}
|
||||
|
||||
TEST(TrackMemoryInterval, TestFillHole2) {
|
||||
static const struct MemoryIntervals mm[2] = {
|
||||
{4, {{1, 1}, {3, 4}, {5, 5}, {6, 8}}, {0, 0, 1, 0}},
|
||||
{5, {{1, 1}, {2, 2}, {3, 4}, {5, 5}, {6, 8}}, {0, 1, 0, 1, 0}},
|
||||
};
|
||||
RunTrackMemoryIntervalTest(mm, 2, 2, 1);
|
||||
}
|
||||
|
||||
TEST(FindMemoryInterval, Test) {
|
||||
static const struct MemoryIntervals mm[1] = {
|
||||
{4,
|
||||
{
|
||||
[0] = {1, 1},
|
||||
[1] = {3, 4},
|
||||
[2] = {5, 5},
|
||||
[3] = {6, 8},
|
||||
},
|
||||
{0, 0, 1, 0}},
|
||||
};
|
||||
EXPECT_EQ(0, FindMemoryInterval(mm, 0));
|
||||
EXPECT_EQ(0, FindMemoryInterval(mm, 1));
|
||||
EXPECT_EQ(1, FindMemoryInterval(mm, 2));
|
||||
EXPECT_EQ(1, FindMemoryInterval(mm, 3));
|
||||
EXPECT_EQ(1, FindMemoryInterval(mm, 4));
|
||||
EXPECT_EQ(2, FindMemoryInterval(mm, 5));
|
||||
EXPECT_EQ(3, FindMemoryInterval(mm, 6));
|
||||
EXPECT_EQ(3, FindMemoryInterval(mm, 7));
|
||||
EXPECT_EQ(3, FindMemoryInterval(mm, 8));
|
||||
EXPECT_EQ(4, FindMemoryInterval(mm, 9));
|
||||
}
|
||||
|
||||
TEST(ReleaseMemoryIntervals, TestEmpty) {
|
||||
static const struct MemoryIntervals mm[2] = {
|
||||
{0, {}, {}},
|
||||
{0, {}, {}},
|
||||
};
|
||||
RunReleaseMemoryIntervalsTest(mm, 2, 2);
|
||||
}
|
||||
|
||||
TEST(ReleaseMemoryIntervals, TestRemoveElement_UsesInclusiveRange) {
|
||||
static const struct MemoryIntervals mm[2] = {
|
||||
{3, {{0, 0}, {2, 2}, {4, 4}}, {}},
|
||||
{2, {{0, 0}, {4, 4}}, {}},
|
||||
};
|
||||
RunReleaseMemoryIntervalsTest(mm, 2, 2);
|
||||
}
|
||||
|
||||
TEST(ReleaseMemoryIntervals, TestPunchHole) {
|
||||
static const struct MemoryIntervals mm[2] = {
|
||||
{1, {{0, 9}}, {}},
|
||||
{2, {{0, 3}, {6, 9}}, {}},
|
||||
};
|
||||
RunReleaseMemoryIntervalsTest(mm, 4, 5);
|
||||
}
|
||||
|
||||
TEST(ReleaseMemoryIntervals, TestShortenLeft) {
|
||||
static const struct MemoryIntervals mm[2] = {
|
||||
{1, {{0, 9}}, {}},
|
||||
{1, {{0, 7}}, {}},
|
||||
};
|
||||
RunReleaseMemoryIntervalsTest(mm, 8, 9);
|
||||
}
|
||||
|
||||
TEST(ReleaseMemoryIntervals, TestShortenRight) {
|
||||
static const struct MemoryIntervals mm[2] = {
|
||||
{1, {{0, 9}}, {}},
|
||||
{1, {{3, 9}}, {}},
|
||||
};
|
||||
RunReleaseMemoryIntervalsTest(mm, 0, 2);
|
||||
}
|
||||
|
||||
TEST(ReleaseMemoryIntervals, TestShortenLeft2) {
|
||||
static const struct MemoryIntervals mm[2] = {
|
||||
{1, {{0, 9}}, {}},
|
||||
{1, {{0, 7}}, {}},
|
||||
};
|
||||
RunReleaseMemoryIntervalsTest(mm, 8, 11);
|
||||
}
|
||||
|
||||
TEST(ReleaseMemoryIntervals, TestShortenRight2) {
|
||||
static const struct MemoryIntervals mm[2] = {
|
||||
{1, {{0, 9}}, {}},
|
||||
{1, {{3, 9}}, {}},
|
||||
};
|
||||
RunReleaseMemoryIntervalsTest(mm, -3, 2);
|
||||
}
|
||||
|
||||
TEST(ReleaseMemoryIntervals, TestZeroZero) {
|
||||
static const struct MemoryIntervals mm[2] = {
|
||||
{1, {{3, 9}}, {}},
|
||||
{1, {{3, 9}}, {}},
|
||||
};
|
||||
RunReleaseMemoryIntervalsTest(mm, 0, 0);
|
||||
}
|
||||
|
||||
TEST(ReleaseMemoryIntervals, TestNoopLeft) {
|
||||
static const struct MemoryIntervals mm[2] = {
|
||||
{1, {{3, 9}}, {}},
|
||||
{1, {{3, 9}}, {}},
|
||||
};
|
||||
RunReleaseMemoryIntervalsTest(mm, 1, 2);
|
||||
}
|
||||
|
||||
TEST(ReleaseMemoryIntervals, TestNoopRight) {
|
||||
static const struct MemoryIntervals mm[2] = {
|
||||
{1, {{3, 9}}, {}},
|
||||
{1, {{3, 9}}, {}},
|
||||
};
|
||||
RunReleaseMemoryIntervalsTest(mm, 10, 10);
|
||||
}
|
||||
|
||||
TEST(ReleaseMemoryIntervals, TestBigFree) {
|
||||
static const struct MemoryIntervals mm[2] = {
|
||||
{2, {{0, 3}, {6, 9}}, {}},
|
||||
{0, {}, {}},
|
||||
};
|
||||
RunReleaseMemoryIntervalsTest(mm, INT_MIN, INT_MAX);
|
||||
}
|
||||
|
||||
TEST(ReleaseMemoryIntervals, TestWeirdGap) {
|
||||
static const struct MemoryIntervals mm[2] = {
|
||||
{3, {{10, 10}, {20, 20}, {30, 30}}, {}},
|
||||
{2, {{10, 10}, {30, 30}}, {}},
|
||||
};
|
||||
RunReleaseMemoryIntervalsTest(mm, 15, 25);
|
||||
}
|
||||
|
||||
TEST(ReleaseMemoryIntervals, TestOutOfMemory) {
|
||||
int i;
|
||||
struct MemoryIntervals *mm;
|
||||
mm = calloc(1, sizeof(struct MemoryIntervals));
|
||||
for (i = 0; i < ARRAYLEN(mm->p); ++i) {
|
||||
CHECK_NE(-1, TrackMemoryInterval(mm, i * 10, i * 10 + 8, 0));
|
||||
}
|
||||
CheckMemoryIntervalsAreOk(mm);
|
||||
CHECK_EQ(-1, ReleaseMemoryIntervals(mm, 4, 4, NULL));
|
||||
CHECK_EQ(ENOMEM, errno);
|
||||
CheckMemoryIntervalsAreOk(mm);
|
||||
free(mm);
|
||||
}
|
|
@ -21,8 +21,9 @@
|
|||
#include "libc/bits/xchg.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/fmt/fmt.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/gc.h"
|
||||
#include "libc/runtime/mappings.h"
|
||||
#include "libc/runtime/memtrack.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
|
@ -33,71 +34,17 @@
|
|||
#include "libc/testlib/testlib.h"
|
||||
#include "libc/x/x.h"
|
||||
|
||||
unsigned m1;
|
||||
|
||||
TEST(mmap, testMapUnmapAnonAnyAddr) {
|
||||
void *p;
|
||||
m1 = _mm.i;
|
||||
EXPECT_NE(MAP_FAILED, (p = mmap(NULL, FRAMESIZE, PROT_READ | PROT_WRITE,
|
||||
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)));
|
||||
EXPECT_EQ(m1 + 1, _mm.i);
|
||||
EXPECT_NE(-1, munmap(p, FRAMESIZE));
|
||||
EXPECT_EQ(m1 + 0, _mm.i);
|
||||
}
|
||||
|
||||
TEST(mmap, testMunmapUnmapsMultiple) {
|
||||
void *p1, *p2;
|
||||
m1 = _mm.i;
|
||||
EXPECT_NE(MAP_FAILED, (p1 = mmap(NULL, FRAMESIZE, PROT_READ | PROT_WRITE,
|
||||
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)));
|
||||
EXPECT_NE(MAP_FAILED, (p2 = mmap(NULL, FRAMESIZE, PROT_READ | PROT_WRITE,
|
||||
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)));
|
||||
if ((intptr_t)p1 > (intptr_t)p2) xchg(&p1, &p2);
|
||||
EXPECT_EQ(m1 + 2, _mm.i);
|
||||
EXPECT_NE(-1, munmap(p1, (intptr_t)p2 + (intptr_t)FRAMESIZE - (intptr_t)p1));
|
||||
EXPECT_EQ(m1 + 0, _mm.i);
|
||||
}
|
||||
|
||||
TEST(mmap, testPartialUnmapRight) {
|
||||
if (1) return; /* naaah */
|
||||
char *p;
|
||||
m1 = _mm.i;
|
||||
EXPECT_NE(MAP_FAILED, (p = mmap(NULL, FRAMESIZE * 2, PROT_READ | PROT_WRITE,
|
||||
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)));
|
||||
EXPECT_EQ(m1 + 1, _mm.i);
|
||||
EXPECT_NE(-1, munmap(p + FRAMESIZE, FRAMESIZE));
|
||||
EXPECT_EQ(m1 + 1, _mm.i);
|
||||
EXPECT_NE(-1, munmap(p, FRAMESIZE));
|
||||
EXPECT_EQ(m1 + 0, _mm.i);
|
||||
}
|
||||
|
||||
TEST(mmap, testPartialUnmapLeft) {
|
||||
if (1) return; /* naaah */
|
||||
char *p;
|
||||
m1 = _mm.i;
|
||||
EXPECT_NE(MAP_FAILED, (p = mmap(NULL, FRAMESIZE * 2, PROT_READ | PROT_WRITE,
|
||||
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)));
|
||||
EXPECT_EQ(m1 + 1, _mm.i);
|
||||
EXPECT_NE(-1, munmap(p, FRAMESIZE));
|
||||
EXPECT_EQ(m1 + 1, _mm.i);
|
||||
EXPECT_NE(-1, munmap(p + FRAMESIZE, FRAMESIZE));
|
||||
EXPECT_EQ(m1 + 0, _mm.i);
|
||||
}
|
||||
|
||||
TEST(mmap, testMapFile) {
|
||||
int fd;
|
||||
char *p;
|
||||
char path[PATH_MAX];
|
||||
sprintf(path, "%s%s.%d", kTmpPath, program_invocation_short_name, getpid());
|
||||
m1 = _mm.i;
|
||||
ASSERT_NE(-1, (fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0644)));
|
||||
EXPECT_EQ(5, write(fd, "hello", 5));
|
||||
EXPECT_NE(-1, fdatasync(fd));
|
||||
EXPECT_NE(MAP_FAILED, (p = mmap(NULL, 5, PROT_READ, MAP_PRIVATE, fd, 0)));
|
||||
EXPECT_EQ(m1 + 1, _mm.i);
|
||||
EXPECT_STREQ("hello", p);
|
||||
EXPECT_NE(-1, munmap(p, 5));
|
||||
EXPECT_EQ(m1 + 0, _mm.i);
|
||||
EXPECT_NE(-1, close(fd));
|
||||
EXPECT_NE(-1, unlink(path));
|
||||
}
|
||||
|
@ -106,14 +53,12 @@ TEST(mmap, testMapFile_fdGetsClosed_makesNoDifference) {
|
|||
int fd;
|
||||
char *p, buf[16], path[PATH_MAX];
|
||||
sprintf(path, "%s%s.%d", kTmpPath, program_invocation_short_name, getpid());
|
||||
m1 = _mm.i;
|
||||
ASSERT_NE(-1, (fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0644)));
|
||||
EXPECT_EQ(5, write(fd, "hello", 5));
|
||||
EXPECT_NE(-1, fdatasync(fd));
|
||||
EXPECT_NE(MAP_FAILED,
|
||||
(p = mmap(NULL, 5, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)));
|
||||
EXPECT_NE(-1, close(fd));
|
||||
EXPECT_EQ(m1 + 1, _mm.i);
|
||||
EXPECT_STREQ("hello", p);
|
||||
p[1] = 'a';
|
||||
EXPECT_NE(-1, msync(p, PAGESIZE, MS_SYNC));
|
||||
|
@ -122,12 +67,11 @@ TEST(mmap, testMapFile_fdGetsClosed_makesNoDifference) {
|
|||
EXPECT_STREQN("hallo", buf, 5);
|
||||
EXPECT_NE(-1, close(fd));
|
||||
EXPECT_NE(-1, munmap(p, 5));
|
||||
EXPECT_EQ(m1 + 0, _mm.i);
|
||||
EXPECT_NE(-1, unlink(path));
|
||||
}
|
||||
|
||||
TEST(mmap, testMapFixed_destroysEverythingInItsPath) {
|
||||
m1 = _mm.i;
|
||||
unsigned m1 = _mmi.i;
|
||||
EXPECT_NE(MAP_FAILED, mmap((void *)(kFixedMappingsStart + FRAMESIZE * 0),
|
||||
FRAMESIZE, PROT_READ | PROT_WRITE,
|
||||
MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
|
||||
|
@ -137,10 +81,31 @@ TEST(mmap, testMapFixed_destroysEverythingInItsPath) {
|
|||
EXPECT_NE(MAP_FAILED, mmap((void *)(kFixedMappingsStart + FRAMESIZE * 2),
|
||||
FRAMESIZE, PROT_READ | PROT_WRITE,
|
||||
MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
|
||||
ASSERT_EQ(m1 + 3, _mm.i);
|
||||
EXPECT_NE(MAP_FAILED, mmap((void *)(kFixedMappingsStart + FRAMESIZE * 0),
|
||||
FRAMESIZE * 3, PROT_READ | PROT_WRITE,
|
||||
MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
|
||||
ASSERT_EQ(m1 + 1, _mm.i);
|
||||
ASSERT_GT(_mmi.i, m1);
|
||||
EXPECT_NE(-1, munmap((void *)kFixedMappingsStart, FRAMESIZE * 3));
|
||||
ASSERT_EQ(m1, _mmi.i);
|
||||
}
|
||||
|
||||
TEST(isheap, nullPtr) {
|
||||
ASSERT_FALSE(isheap(NULL));
|
||||
}
|
||||
|
||||
TEST(isheap, stackMemory) {
|
||||
int boop;
|
||||
ASSERT_FALSE(isheap(&boop));
|
||||
}
|
||||
|
||||
TEST(isheap, malloc) {
|
||||
ASSERT_TRUE(isheap(gc(malloc(1))));
|
||||
}
|
||||
|
||||
TEST(isheap, emptyMalloc) {
|
||||
ASSERT_TRUE(isheap(gc(malloc(0))));
|
||||
}
|
||||
|
||||
TEST(isheap, mallocOffset) {
|
||||
ASSERT_TRUE(isheap((char *)gc(malloc(131072)) + 100000));
|
||||
}
|
||||
|
|
|
@ -5,12 +5,14 @@ PKGS += TEST_LIBC_RUNTIME
|
|||
|
||||
TEST_LIBC_RUNTIME_SRCS := $(wildcard test/libc/runtime/*.c)
|
||||
TEST_LIBC_RUNTIME_SRCS_TEST = $(filter %_test.c,$(TEST_LIBC_RUNTIME_SRCS))
|
||||
TEST_LIBC_RUNTIME_COMS = $(TEST_LIBC_RUNTIME_OBJS:%.o=%.com)
|
||||
|
||||
TEST_LIBC_RUNTIME_OBJS = \
|
||||
$(TEST_LIBC_RUNTIME_SRCS:%=o/$(MODE)/%.zip.o) \
|
||||
$(TEST_LIBC_RUNTIME_SRCS:%.c=o/$(MODE)/%.o)
|
||||
|
||||
TEST_LIBC_RUNTIME_COMS = \
|
||||
$(TEST_LIBC_RUNTIME_SRCS:%.c=o/$(MODE)/%.com)
|
||||
|
||||
TEST_LIBC_RUNTIME_BINS = \
|
||||
$(TEST_LIBC_RUNTIME_COMS) \
|
||||
$(TEST_LIBC_RUNTIME_COMS:%=%.dbg)
|
||||
|
@ -22,13 +24,16 @@ TEST_LIBC_RUNTIME_CHECKS = \
|
|||
$(TEST_LIBC_RUNTIME_SRCS_TEST:%.c=o/$(MODE)/%.com.runs)
|
||||
|
||||
TEST_LIBC_RUNTIME_DIRECTDEPS = \
|
||||
LIBC_ALG \
|
||||
LIBC_CALLS \
|
||||
LIBC_CALLS_HEFTY \
|
||||
LIBC_FMT \
|
||||
LIBC_MEM \
|
||||
LIBC_NEXGEN32E \
|
||||
LIBC_RAND \
|
||||
LIBC_RUNTIME \
|
||||
LIBC_STDIO \
|
||||
LIBC_LOG \
|
||||
LIBC_STR \
|
||||
LIBC_STUBS \
|
||||
LIBC_SYSV \
|
||||
|
@ -60,6 +65,7 @@ o/$(MODE)/test/libc/runtime/getenv_test.com.runs: \
|
|||
o/$(MODE)/test/libc/runtime/getenv_test.com
|
||||
@HELLO=THERE build/runit $@ $<
|
||||
|
||||
o/$(MODE)/test/libc/runtime/fun_test.o \
|
||||
o/$(MODE)/test/libc/runtime/itsatrap_test.o: \
|
||||
OVERRIDE_CFLAGS += \
|
||||
-fno-sanitize=all \
|
||||
|
|
|
@ -5,12 +5,14 @@ PKGS += TEST_LIBC_SOCK
|
|||
|
||||
TEST_LIBC_SOCK_SRCS := $(wildcard test/libc/sock/*.c)
|
||||
TEST_LIBC_SOCK_SRCS_TEST = $(filter %_test.c,$(TEST_LIBC_SOCK_SRCS))
|
||||
TEST_LIBC_SOCK_COMS = $(TEST_LIBC_SOCK_OBJS:%.o=%.com)
|
||||
|
||||
TEST_LIBC_SOCK_OBJS = \
|
||||
$(TEST_LIBC_SOCK_SRCS:%=o/$(MODE)/%.zip.o) \
|
||||
$(TEST_LIBC_SOCK_SRCS:%.c=o/$(MODE)/%.o)
|
||||
|
||||
TEST_LIBC_SOCK_COMS = \
|
||||
$(TEST_LIBC_SOCK_SRCS:%.c=o/$(MODE)/%.com)
|
||||
|
||||
TEST_LIBC_SOCK_BINS = \
|
||||
$(TEST_LIBC_SOCK_COMS) \
|
||||
$(TEST_LIBC_SOCK_COMS:%=%.dbg)
|
||||
|
@ -51,9 +53,7 @@ o/$(MODE)/test/libc/sock/%.com.dbg: \
|
|||
$(APE)
|
||||
@$(APELINK)
|
||||
|
||||
$(TEST_LIBC_SOCK_OBJS): \
|
||||
$(BUILD_FILES) \
|
||||
test/libc/sock/test.mk
|
||||
$(TEST_LIBC_SOCK_OBJS): test/libc/sock/test.mk
|
||||
|
||||
.PHONY: o/$(MODE)/test/libc/sock
|
||||
o/$(MODE)/test/libc/sock: \
|
||||
|
|
|
@ -5,12 +5,14 @@ PKGS += TEST_LIBC_STDIO
|
|||
|
||||
TEST_LIBC_STDIO_SRCS := $(wildcard test/libc/stdio/*.c)
|
||||
TEST_LIBC_STDIO_SRCS_TEST = $(filter %_test.c,$(TEST_LIBC_STDIO_SRCS))
|
||||
TEST_LIBC_STDIO_COMS = $(TEST_LIBC_STDIO_OBJS:%.o=%.com)
|
||||
|
||||
TEST_LIBC_STDIO_OBJS = \
|
||||
$(TEST_LIBC_STDIO_SRCS:%=o/$(MODE)/%.zip.o) \
|
||||
$(TEST_LIBC_STDIO_SRCS:%.c=o/$(MODE)/%.o)
|
||||
|
||||
TEST_LIBC_STDIO_COMS = \
|
||||
$(TEST_LIBC_STDIO_SRCS:%.c=o/$(MODE)/%.com)
|
||||
|
||||
TEST_LIBC_STDIO_BINS = \
|
||||
$(TEST_LIBC_STDIO_COMS) \
|
||||
$(TEST_LIBC_STDIO_COMS:%=%.dbg)
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/dce.h"
|
||||
#include "libc/nexgen32e/crc32.h"
|
||||
#include "libc/nexgen32e/x86feature.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
@ -40,9 +41,10 @@ TEST(crc32c, test) {
|
|||
strlen(hyperion) - strlen(FANATICS)));
|
||||
}
|
||||
|
||||
uint32_t crc32c$pure(uint32_t, const char *, size_t) hidden;
|
||||
uint32_t crc32c$sse42(uint32_t, const char *, size_t) hidden;
|
||||
FIXTURE(crc32c, pure) { *(void **)(&crc32c) = (void *)crc32c$pure; }
|
||||
FIXTURE(crc32c, pure) {
|
||||
*(void **)(&crc32c) = (void *)crc32c$pure;
|
||||
}
|
||||
|
||||
FIXTURE(crc32c, sse42) {
|
||||
if (X86_HAVE(SSE4_2)) {
|
||||
*(void **)(&crc32c) = (void *)crc32c$sse42;
|
||||
|
|
|
@ -17,9 +17,14 @@
|
|||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/str/tinymemccpy.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
void *memccpy2(void *, const void *, int, size_t);
|
||||
|
||||
TEST(memccpy, testStringCopy) {
|
||||
char buf[16];
|
||||
EXPECT_EQ(buf + 3, memccpy(buf, "hi", '\0', sizeof(buf)));
|
||||
|
@ -35,3 +40,21 @@ TEST(memccpy, testZeroLength_doesNothing) {
|
|||
char buf[1];
|
||||
EXPECT_EQ(NULL, memccpy(buf, "hi", '\0', 0));
|
||||
}
|
||||
|
||||
TEST(memccpy, memcpy) {
|
||||
unsigned n, n2;
|
||||
char *b1, *b2, *b3, *e1, *e2;
|
||||
for (n = 0; n < 1026; ++n) {
|
||||
b1 = tmalloc(n);
|
||||
b2 = tmalloc(n);
|
||||
b3 = tmalloc(n);
|
||||
e1 = tinymemccpy(b2, b1, 31337, n);
|
||||
e2 = memccpy(b3, b1, 31337, n);
|
||||
n2 = e1 ? e1 - b1 : n;
|
||||
ASSERT_EQ(e1, e2);
|
||||
ASSERT_EQ(0, memcmp(b2, b3, n2));
|
||||
tfree(b3);
|
||||
tfree(b2);
|
||||
tfree(b1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,30 +17,17 @@
|
|||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/intrin/phaddsw.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
#include "tool/viz/lib/formatstringtable-testlib.h"
|
||||
/* clang-format off */
|
||||
#include "third_party/regex/regex.h"
|
||||
|
||||
FIXTURE(phaddsw, disableHardwareExtensions) {
|
||||
memset((/*unconst*/ void *)kCpuids, 0, sizeof(kCpuids));
|
||||
}
|
||||
|
||||
TEST(phaddsw, testOverflow_saturates) {
|
||||
short M[2][8] = {
|
||||
{0x7fff, 0, 0x7fff, 1, 0x7fff, 0x7fff, 20777, -16389},
|
||||
{-28040, 13318, -1336, -24798, -13876, 3599, -7346, -23575},
|
||||
};
|
||||
phaddsw(M[0], M[0], M[1]);
|
||||
EXPECT_SHRTMATRIXEQ(2, 8, M, "\n\
|
||||
32767 32767 32767 4388 -14722 -26134 -10277 -30921\n\
|
||||
-28040 13318 -1336 -24798 -13876 3599 -7346 -23575");
|
||||
}
|
||||
|
||||
TEST(phaddsw, testAliasing_isOk) {
|
||||
short M[1][8] = {{0,1,2,3,4,5,6,7}};
|
||||
phaddsw(M[0],M[0],M[0]);
|
||||
EXPECT_SHRTMATRIXEQ(1, 8, M, "\n\
|
||||
1 5 9 13 1 5 9 13");
|
||||
TEST(regex, test) {
|
||||
regex_t rx;
|
||||
EXPECT_EQ(REG_OK, regcomp(&rx, "^[A-Za-z\x7f-\uffff]{2}$", REG_EXTENDED));
|
||||
EXPECT_EQ(REG_OK, regexec(&rx, "AZ", 0, NULL, 0));
|
||||
EXPECT_EQ(REG_OK, regexec(&rx, "→→", 0, NULL, 0));
|
||||
EXPECT_EQ(REG_NOMATCH, regexec(&rx, "A", 0, NULL, 0));
|
||||
EXPECT_EQ(REG_NOMATCH, regexec(&rx, "→", 0, NULL, 0));
|
||||
EXPECT_EQ(REG_NOMATCH, regexec(&rx, "0", 0, NULL, 0));
|
||||
regfree(&rx);
|
||||
}
|
|
@ -18,6 +18,7 @@
|
|||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
#include "libc/testlib/hyperion.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
|
@ -30,8 +31,16 @@ uint8_t *sha256(const char *s) {
|
|||
return hash;
|
||||
}
|
||||
|
||||
TEST(sha256, testEmpty) {
|
||||
EXPECT_BINEQ(
|
||||
"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
||||
sha256(""));
|
||||
}
|
||||
|
||||
TEST(sha256, test) {
|
||||
EXPECT_BINEQ(u",≥M║_░ú♫&Φ;*┼╣Γ€←▬▲╲▼ºB^s♦3bôïÿ$", sha256("hello"));
|
||||
EXPECT_BINEQ(u",≥M║_░ú♫&Φ;*┼╣Γ€←▬▲\\▼ºB^s♦3bôïÿ$", sha256("hello"));
|
||||
EXPECT_BINEQ("2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b98",
|
||||
sha256("hello"));
|
||||
}
|
||||
|
||||
TEST(sha256, testNontrivialSize) {
|
||||
|
|
|
@ -551,7 +551,8 @@ void longstringislong_dupe(size_t size, char data[size], char dupe[size]) {
|
|||
BENCH(bench_00_strcmp, bench) {
|
||||
size_t size;
|
||||
char *dupe, *data;
|
||||
size = ROUNDDOWN(getcachesize(kCpuCacheTypeData, 1) / 2, PAGESIZE);
|
||||
size = ROUNDDOWN(MAX(FRAMESIZE, getcachesize(kCpuCacheTypeData, 1)) / 2,
|
||||
PAGESIZE);
|
||||
data = tgc(tmalloc(size));
|
||||
dupe = tgc(tmalloc(size));
|
||||
EZBENCH2("strcmp [identity]", longstringislong(size, data),
|
||||
|
@ -569,7 +570,8 @@ BENCH(bench_00_strcmp, bench) {
|
|||
BENCH(bench_01_strcasecmp, bench) {
|
||||
size_t size;
|
||||
char *dupe, *data;
|
||||
size = ROUNDDOWN(getcachesize(kCpuCacheTypeData, 1) / 2, PAGESIZE);
|
||||
size = ROUNDDOWN(MAX(FRAMESIZE, getcachesize(kCpuCacheTypeData, 1)) / 2,
|
||||
PAGESIZE);
|
||||
data = tgc(tmalloc(size));
|
||||
dupe = tgc(tmalloc(size));
|
||||
EZBENCH2("strcasecmp [identity]", longstringislong(size, data),
|
||||
|
|
|
@ -86,7 +86,7 @@ TEST(strnlen, nulNotFound_ReturnsSize) {
|
|||
for (unsigned i = 0; i < ARRAYLEN(sizes); ++i) {
|
||||
char *buf = tmalloc(sizes[i]);
|
||||
memset(buf, ' ', sizes[i]);
|
||||
ASSERT_EQ(sizes[i], strnlen(buf, sizes[i]));
|
||||
ASSERT_EQ(sizes[i], strnlen(buf, sizes[i]), "%d", sizes[i]);
|
||||
tfree(buf);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,25 +21,29 @@
|
|||
#include "libc/testlib/testlib.h"
|
||||
|
||||
#define T(NAME) NAME
|
||||
#define S(S) S
|
||||
#define C(C) C
|
||||
#define S(S) S
|
||||
#define C(C) C
|
||||
#include "test/libc/str/strrchr_test.inc"
|
||||
#undef C
|
||||
#undef S
|
||||
#undef T
|
||||
|
||||
#define T(NAME) NAME##16
|
||||
#define S(S) u##S
|
||||
#define C(C) u##C
|
||||
#define T(NAME) NAME##16
|
||||
#define S(S) u##S
|
||||
#define C(C) u##C
|
||||
#define strchr(x, y) strchr16(x, y)
|
||||
#include "test/libc/str/strrchr_test.inc"
|
||||
#undef strchr
|
||||
#undef C
|
||||
#undef S
|
||||
#undef T
|
||||
|
||||
#define T(NAME) NAME##32
|
||||
#define S(S) L##S
|
||||
#define C(C) L##C
|
||||
#define T(NAME) NAME##32
|
||||
#define S(S) L##S
|
||||
#define C(C) L##C
|
||||
#define strchr(x, y) wcschr(x, y)
|
||||
#include "test/libc/str/strrchr_test.inc"
|
||||
#undef strchr
|
||||
#undef C
|
||||
#undef S
|
||||
#undef T
|
||||
|
|
|
@ -5,12 +5,14 @@ PKGS += TEST_LIBC_STR
|
|||
|
||||
TEST_LIBC_STR_SRCS := $(wildcard test/libc/str/*.c)
|
||||
TEST_LIBC_STR_SRCS_TEST = $(filter %_test.c,$(TEST_LIBC_STR_SRCS))
|
||||
TEST_LIBC_STR_COMS = $(TEST_LIBC_STR_OBJS:%.o=%.com)
|
||||
|
||||
TEST_LIBC_STR_OBJS = \
|
||||
$(TEST_LIBC_STR_SRCS:%=o/$(MODE)/%.zip.o) \
|
||||
$(TEST_LIBC_STR_SRCS:%.c=o/$(MODE)/%.o)
|
||||
|
||||
TEST_LIBC_STR_COMS = \
|
||||
$(TEST_LIBC_STR_SRCS:%.c=o/$(MODE)/%.com)
|
||||
|
||||
TEST_LIBC_STR_BINS = \
|
||||
$(TEST_LIBC_STR_COMS) \
|
||||
$(TEST_LIBC_STR_COMS:%=%.dbg)
|
||||
|
@ -38,6 +40,7 @@ TEST_LIBC_STR_DIRECTDEPS = \
|
|||
LIBC_LOG \
|
||||
LIBC_X \
|
||||
LIBC_ZIPOS \
|
||||
THIRD_PARTY_REGEX \
|
||||
THIRD_PARTY_ZLIB
|
||||
|
||||
TEST_LIBC_STR_DEPS := \
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "libc/log/check.h"
|
||||
#include "libc/macros.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/nexgen32e/crc32.h"
|
||||
#include "libc/runtime/gc.h"
|
||||
#include "libc/runtime/rbx.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
|
@ -50,6 +51,7 @@ TEST(undeflate, testEmbeddedPlaintextConstant) {
|
|||
TEST(undeflate, testStatCentralDirectory_notFound_noSysCalls) {
|
||||
uint64_t c;
|
||||
struct stat st;
|
||||
stat("zip:doge.txt", &st); /* warmup */
|
||||
c = g_syscount;
|
||||
ASSERT_EQ(-1, stat("zip:doge.txt", &st));
|
||||
ASSERT_EQ(0, g_syscount - c);
|
||||
|
|
|
@ -1,301 +0,0 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/fmt/bing.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/macros.h"
|
||||
#include "libc/runtime/gc.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/str/varint.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
#include "libc/x/x.h"
|
||||
|
||||
#define TV(X, B, I) __FILE__, __LINE__, #X, X, #B, B, #I, I
|
||||
|
||||
static const struct VarintTestVectors {
|
||||
const char *file;
|
||||
int line;
|
||||
const char *xcode;
|
||||
uint64_t x;
|
||||
const char *bcode;
|
||||
uint16_t b[11];
|
||||
const char *icode;
|
||||
uint8_t i;
|
||||
} kv[] = {
|
||||
{TV(0x0000000000000000ul, u" ", 1)},
|
||||
{TV(0x0000000000000001ul, u"☺ ", 1)},
|
||||
{TV(0x0000000000000003ul, u"♥ ", 1)},
|
||||
{TV(0x0000000000000007ul, u"• ", 1)},
|
||||
{TV(0x000000000000000ful, u"☼ ", 1)},
|
||||
{TV(0x000000000000001ful, u"▼ ", 1)},
|
||||
{TV(0x000000000000003ful, u"⁇ ", 1)},
|
||||
{TV(0x000000000000007ful, u"⌂ ", 1)},
|
||||
{TV(0x00000000000000fful, u"λ☺ ", 2)},
|
||||
{TV(0x00000000000001fful, u"λ♥ ", 2)},
|
||||
{TV(0x00000000000003fful, u"λ• ", 2)},
|
||||
{TV(0x00000000000007fful, u"λ☼ ", 2)},
|
||||
{TV(0x0000000000000ffful, u"λ▼ ", 2)},
|
||||
{TV(0x0000000000001ffful, u"λ⁇ ", 2)},
|
||||
{TV(0x0000000000003ffful, u"λ⌂ ", 2)},
|
||||
{TV(0x0000000000007ffful, u"λλ☺ ", 3)},
|
||||
{TV(0x000000000000fffful, u"λλ♥ ", 3)},
|
||||
{TV(0x000000000001fffful, u"λλ• ", 3)},
|
||||
{TV(0x000000000003fffful, u"λλ☼ ", 3)},
|
||||
{TV(0x000000000007fffful, u"λλ▼ ", 3)},
|
||||
{TV(0x00000000000ffffful, u"λλ⁇ ", 3)},
|
||||
{TV(0x00000000001ffffful, u"λλ⌂ ", 3)},
|
||||
{TV(0x00000000003ffffful, u"λλλ☺ ", 4)},
|
||||
{TV(0x00000000007ffffful, u"λλλ♥ ", 4)},
|
||||
{TV(0x0000000000fffffful, u"λλλ• ", 4)},
|
||||
{TV(0x0000000001fffffful, u"λλλ☼ ", 4)},
|
||||
{TV(0x0000000003fffffful, u"λλλ▼ ", 4)},
|
||||
{TV(0x0000000007fffffful, u"λλλ⁇ ", 4)},
|
||||
{TV(0x000000000ffffffful, u"λλλ⌂ ", 4)},
|
||||
{TV(0x000000001ffffffful, u"λλλλ☺ ", 5)},
|
||||
{TV(0x000000003ffffffful, u"λλλλ♥ ", 5)},
|
||||
{TV(0x000000007ffffffful, u"λλλλ• ", 5)},
|
||||
{TV(0x00000000fffffffful, u"λλλλ☼ ", 5)},
|
||||
{TV(0x00000001fffffffful, u"λλλλ▼ ", 5)},
|
||||
{TV(0x00000003fffffffful, u"λλλλ⁇ ", 5)},
|
||||
{TV(0x00000007fffffffful, u"λλλλ⌂ ", 5)},
|
||||
{TV(0x0000000ffffffffful, u"λλλλλ☺ ", 6)},
|
||||
{TV(0x0000001ffffffffful, u"λλλλλ♥ ", 6)},
|
||||
{TV(0x0000003ffffffffful, u"λλλλλ• ", 6)},
|
||||
{TV(0x0000007ffffffffful, u"λλλλλ☼ ", 6)},
|
||||
{TV(0x000000fffffffffful, u"λλλλλ▼ ", 6)},
|
||||
{TV(0x000001fffffffffful, u"λλλλλ⁇ ", 6)},
|
||||
{TV(0x000003fffffffffful, u"λλλλλ⌂ ", 6)},
|
||||
{TV(0x000007fffffffffful, u"λλλλλλ☺ ", 7)},
|
||||
{TV(0x00000ffffffffffful, u"λλλλλλ♥ ", 7)},
|
||||
{TV(0x00001ffffffffffful, u"λλλλλλ• ", 7)},
|
||||
{TV(0x00003ffffffffffful, u"λλλλλλ☼ ", 7)},
|
||||
{TV(0x00007ffffffffffful, u"λλλλλλ▼ ", 7)},
|
||||
{TV(0x0000fffffffffffful, u"λλλλλλ⁇ ", 7)},
|
||||
{TV(0x0001fffffffffffful, u"λλλλλλ⌂ ", 7)},
|
||||
{TV(0x0003fffffffffffful, u"λλλλλλλ☺ ", 8)},
|
||||
{TV(0x0007fffffffffffful, u"λλλλλλλ♥ ", 8)},
|
||||
{TV(0x000ffffffffffffful, u"λλλλλλλ• ", 8)},
|
||||
{TV(0x001ffffffffffffful, u"λλλλλλλ☼ ", 8)},
|
||||
{TV(0x003ffffffffffffful, u"λλλλλλλ▼ ", 8)},
|
||||
{TV(0x007ffffffffffffful, u"λλλλλλλ⁇ ", 8)},
|
||||
{TV(0x00fffffffffffffful, u"λλλλλλλ⌂ ", 8)},
|
||||
{TV(0x01fffffffffffffful, u"λλλλλλλλ☺ ", 9)},
|
||||
{TV(0x03fffffffffffffful, u"λλλλλλλλ♥ ", 9)},
|
||||
{TV(0x07fffffffffffffful, u"λλλλλλλλ• ", 9)},
|
||||
{TV(0x0ffffffffffffffful, u"λλλλλλλλ☼ ", 9)},
|
||||
{TV(0x1ffffffffffffffful, u"λλλλλλλλ▼ ", 9)},
|
||||
{TV(0x3ffffffffffffffful, u"λλλλλλλλ⁇ ", 9)},
|
||||
{TV(0x7ffffffffffffffful, u"λλλλλλλλ⌂ ", 9)},
|
||||
{TV(0xfffffffffffffffful, u"λλλλλλλλλ☺", 10)},
|
||||
};
|
||||
|
||||
const struct ZigzagTestVectors {
|
||||
const char *file;
|
||||
int line;
|
||||
const char *xcode;
|
||||
int64_t x;
|
||||
const char *bcode;
|
||||
uint16_t b[11];
|
||||
const char *icode;
|
||||
uint8_t i;
|
||||
} kz[] = {
|
||||
{TV(0, u" ", 1)},
|
||||
{TV(1, u"☻", 1)},
|
||||
{TV(-1, u"☺", 1)},
|
||||
{TV(2, u"♦", 1)},
|
||||
{TV(-2, u"♥", 1)},
|
||||
{TV(4, u"◘", 1)},
|
||||
{TV(-4, u"•", 1)},
|
||||
{TV(8, u"►", 1)},
|
||||
{TV(-8, u"☼", 1)},
|
||||
{TV(16, u" ", 1)},
|
||||
{TV(-16, u"▼", 1)},
|
||||
{TV(32, u"@", 1)},
|
||||
{TV(-32, u"⁇", 1)},
|
||||
{TV(64, u"Ç☺", 2)},
|
||||
{TV(-64, u"⌂", 1)},
|
||||
{TV(128, u"Ç☻", 2)},
|
||||
{TV(-128, u"λ☺", 2)},
|
||||
{TV(256, u"Ç♦", 2)},
|
||||
{TV(-256, u"λ♥", 2)},
|
||||
{TV(512, u"Ç◘", 2)},
|
||||
{TV(-512, u"λ•", 2)},
|
||||
{TV(1024, u"Ç►", 2)},
|
||||
{TV(-1024, u"λ☼", 2)},
|
||||
{TV(2048, u"Ç ", 2)},
|
||||
{TV(-2048, u"λ▼", 2)},
|
||||
{TV(4096, u"Ç@", 2)},
|
||||
{TV(-4096, u"λ⁇", 2)},
|
||||
{TV(8192, u"ÇÇ☺", 3)},
|
||||
{TV(-8192, u"λ⌂", 2)},
|
||||
{TV(16384, u"ÇÇ☻", 3)},
|
||||
{TV(-16384, u"λλ☺", 3)},
|
||||
{TV(32768, u"ÇÇ♦", 3)},
|
||||
{TV(-32768, u"λλ♥", 3)},
|
||||
{TV(65536, u"ÇÇ◘", 3)},
|
||||
{TV(-65536, u"λλ•", 3)},
|
||||
{TV(131072, u"ÇÇ►", 3)},
|
||||
{TV(-131072, u"λλ☼", 3)},
|
||||
{TV(262144, u"ÇÇ ", 3)},
|
||||
{TV(-262144, u"λλ▼", 3)},
|
||||
{TV(524288, u"ÇÇ@", 3)},
|
||||
{TV(-524288, u"λλ⁇", 3)},
|
||||
{TV(1048576, u"ÇÇÇ☺", 4)},
|
||||
{TV(-1048576, u"λλ⌂", 3)},
|
||||
{TV(2097152, u"ÇÇÇ☻", 4)},
|
||||
{TV(-2097152, u"λλλ☺", 4)},
|
||||
{TV(4194304, u"ÇÇÇ♦", 4)},
|
||||
{TV(-4194304, u"λλλ♥", 4)},
|
||||
{TV(8388608, u"ÇÇÇ◘", 4)},
|
||||
{TV(-8388608, u"λλλ•", 4)},
|
||||
{TV(16777216, u"ÇÇÇ►", 4)},
|
||||
{TV(-16777216, u"λλλ☼", 4)},
|
||||
{TV(33554432, u"ÇÇÇ ", 4)},
|
||||
{TV(-33554432, u"λλλ▼", 4)},
|
||||
{TV(67108864, u"ÇÇÇ@", 4)},
|
||||
{TV(-67108864, u"λλλ⁇", 4)},
|
||||
{TV(134217728, u"ÇÇÇÇ☺", 5)},
|
||||
{TV(-134217728, u"λλλ⌂", 4)},
|
||||
{TV(268435456, u"ÇÇÇÇ☻", 5)},
|
||||
{TV(-268435456, u"λλλλ☺", 5)},
|
||||
{TV(536870912, u"ÇÇÇÇ♦", 5)},
|
||||
{TV(-536870912, u"λλλλ♥", 5)},
|
||||
{TV(1073741824, u"ÇÇÇÇ◘", 5)},
|
||||
{TV(-1073741824, u"λλλλ•", 5)},
|
||||
{TV(2147483648, u"ÇÇÇÇ►", 5)},
|
||||
{TV(-2147483648, u"λλλλ☼", 5)},
|
||||
{TV(4294967296, u"ÇÇÇÇ ", 5)},
|
||||
{TV(-4294967296, u"λλλλ▼", 5)},
|
||||
{TV(8589934592, u"ÇÇÇÇ@", 5)},
|
||||
{TV(-8589934592, u"λλλλ⁇", 5)},
|
||||
{TV(17179869184, u"ÇÇÇÇÇ☺", 6)},
|
||||
{TV(-17179869184, u"λλλλ⌂", 5)},
|
||||
{TV(34359738368, u"ÇÇÇÇÇ☻", 6)},
|
||||
{TV(-34359738368, u"λλλλλ☺", 6)},
|
||||
{TV(68719476736, u"ÇÇÇÇÇ♦", 6)},
|
||||
{TV(-68719476736, u"λλλλλ♥", 6)},
|
||||
{TV(137438953472, u"ÇÇÇÇÇ◘", 6)},
|
||||
{TV(-137438953472, u"λλλλλ•", 6)},
|
||||
{TV(274877906944, u"ÇÇÇÇÇ►", 6)},
|
||||
{TV(-274877906944, u"λλλλλ☼", 6)},
|
||||
{TV(549755813888, u"ÇÇÇÇÇ ", 6)},
|
||||
{TV(-549755813888, u"λλλλλ▼", 6)},
|
||||
{TV(1099511627776, u"ÇÇÇÇÇ@", 6)},
|
||||
{TV(-1099511627776, u"λλλλλ⁇", 6)},
|
||||
{TV(2199023255552, u"ÇÇÇÇÇÇ☺", 7)},
|
||||
{TV(-2199023255552, u"λλλλλ⌂", 6)},
|
||||
{TV(4398046511104, u"ÇÇÇÇÇÇ☻", 7)},
|
||||
{TV(-4398046511104, u"λλλλλλ☺", 7)},
|
||||
{TV(8796093022208, u"ÇÇÇÇÇÇ♦", 7)},
|
||||
{TV(-8796093022208, u"λλλλλλ♥", 7)},
|
||||
{TV(17592186044416, u"ÇÇÇÇÇÇ◘", 7)},
|
||||
{TV(-17592186044416, u"λλλλλλ•", 7)},
|
||||
{TV(35184372088832, u"ÇÇÇÇÇÇ►", 7)},
|
||||
{TV(-35184372088832, u"λλλλλλ☼", 7)},
|
||||
{TV(70368744177664, u"ÇÇÇÇÇÇ ", 7)},
|
||||
{TV(-70368744177664, u"λλλλλλ▼", 7)},
|
||||
{TV(140737488355328, u"ÇÇÇÇÇÇ@", 7)},
|
||||
{TV(-140737488355328, u"λλλλλλ⁇", 7)},
|
||||
{TV(281474976710656, u"ÇÇÇÇÇÇÇ☺", 8)},
|
||||
{TV(-281474976710656, u"λλλλλλ⌂", 7)},
|
||||
{TV(562949953421312, u"ÇÇÇÇÇÇÇ☻", 8)},
|
||||
{TV(-562949953421312, u"λλλλλλλ☺", 8)},
|
||||
{TV(1125899906842624, u"ÇÇÇÇÇÇÇ♦", 8)},
|
||||
{TV(-1125899906842624, u"λλλλλλλ♥", 8)},
|
||||
{TV(2251799813685248, u"ÇÇÇÇÇÇÇ◘", 8)},
|
||||
{TV(-2251799813685248, u"λλλλλλλ•", 8)},
|
||||
{TV(4503599627370496, u"ÇÇÇÇÇÇÇ►", 8)},
|
||||
{TV(-4503599627370496, u"λλλλλλλ☼", 8)},
|
||||
{TV(9007199254740992, u"ÇÇÇÇÇÇÇ ", 8)},
|
||||
{TV(-9007199254740992, u"λλλλλλλ▼", 8)},
|
||||
{TV(18014398509481984, u"ÇÇÇÇÇÇÇ@", 8)},
|
||||
{TV(-18014398509481984, u"λλλλλλλ⁇", 8)},
|
||||
{TV(36028797018963968, u"ÇÇÇÇÇÇÇÇ☺", 9)},
|
||||
{TV(-36028797018963968, u"λλλλλλλ⌂", 8)},
|
||||
{TV(72057594037927936, u"ÇÇÇÇÇÇÇÇ☻", 9)},
|
||||
{TV(-72057594037927936, u"λλλλλλλλ☺", 9)},
|
||||
{TV(144115188075855872, u"ÇÇÇÇÇÇÇÇ♦", 9)},
|
||||
{TV(-144115188075855872, u"λλλλλλλλ♥", 9)},
|
||||
{TV(288230376151711744, u"ÇÇÇÇÇÇÇÇ◘", 9)},
|
||||
{TV(-288230376151711744, u"λλλλλλλλ•", 9)},
|
||||
{TV(576460752303423488, u"ÇÇÇÇÇÇÇÇ►", 9)},
|
||||
{TV(-576460752303423488, u"λλλλλλλλ☼", 9)},
|
||||
{TV(1152921504606846976, u"ÇÇÇÇÇÇÇÇ ", 9)},
|
||||
{TV(-1152921504606846976, u"λλλλλλλλ▼", 9)},
|
||||
{TV(2305843009213693952, u"ÇÇÇÇÇÇÇÇ@", 9)},
|
||||
{TV(-2305843009213693952, u"λλλλλλλλ⁇", 9)},
|
||||
{TV(4611686018427387904, u"ÇÇÇÇÇÇÇÇÇ☺", 10)},
|
||||
{TV(-4611686018427387904, u"λλλλλλλλ⌂", 9)},
|
||||
{TV(INT64_MIN, u"λλλλλλλλλ☺", 10)},
|
||||
{TV(INT64_MAX, u"■λλλλλλλλ☺", 10)}, /* wut */
|
||||
};
|
||||
|
||||
TEST(writevint, test) {
|
||||
size_t i;
|
||||
uint8_t b[10], *p;
|
||||
for (i = 0; i < ARRAYLEN(kv); ++i) {
|
||||
memset(b, 0, sizeof(b));
|
||||
p = writevint(b, kv[i].x);
|
||||
__TEST_EQ(assert, kz[i].file, kz[i].line, __FUNCTION__, kz[i].icode,
|
||||
kz[i].xcode, kv[i].i, p - b);
|
||||
assertBinaryEquals$cp437(kz[i].file, kz[i].line, __FUNCTION__, kv[i].b, b,
|
||||
strlen(kv[i].b), "", false);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(readvint, test) {
|
||||
size_t i;
|
||||
uint64_t x;
|
||||
uint8_t *b, *p;
|
||||
for (i = 0; i < ARRAYLEN(kv); ++i) {
|
||||
b = gc(unbingstr(kv[i].b));
|
||||
p = readvint(b, b + strlen(kv[i].b), &x);
|
||||
__TEST_EQ(assert, kv[i].file, kv[i].line, __FUNCTION__, kv[i].icode,
|
||||
kv[i].xcode, kv[i].i, (intptr_t)(p - b));
|
||||
assertBinaryEquals$cp437(kv[i].file, kv[i].line, __FUNCTION__, kv[i].b, b,
|
||||
strlen(kv[i].b), "", false);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(writesint, test) {
|
||||
size_t i;
|
||||
uint8_t b[10], *p;
|
||||
for (i = 0; i < ARRAYLEN(kz); ++i) {
|
||||
memset(b, 0, sizeof(b));
|
||||
p = writesint(b, kz[i].x);
|
||||
__TEST_EQ(assert, kz[i].file, kz[i].line, __FUNCTION__, kz[i].icode,
|
||||
kz[i].xcode, kz[i].i, (intptr_t)(p - b));
|
||||
assertBinaryEquals$cp437(kz[i].file, kz[i].line, __FUNCTION__, kz[i].b, b,
|
||||
strlen(kz[i].b), "", false);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(readsint, test) {
|
||||
size_t i;
|
||||
int64_t x;
|
||||
uint8_t *b, *p;
|
||||
for (i = 0; i < ARRAYLEN(kz); ++i) {
|
||||
b = gc(unbingstr(kz[i].b));
|
||||
p = readsint(b, b + strlen(kz[i].b), &x);
|
||||
__TEST_EQ(assert, kz[i].file, kz[i].line, __FUNCTION__, kz[i].icode,
|
||||
kz[i].xcode, kz[i].i, (intptr_t)(p - b));
|
||||
assertBinaryEquals$cp437(kz[i].file, kz[i].line, __FUNCTION__, kz[i].b, b,
|
||||
strlen(kz[i].b), "", false);
|
||||
}
|
||||
}
|
|
@ -30,7 +30,7 @@
|
|||
TEST(fastdiv, test) {
|
||||
long x = 123000000321;
|
||||
EXPECT_EQ(123, div1000000000int64(x));
|
||||
EXPECT_EQ(321, mod1000000000int64(x));
|
||||
EXPECT_EQ(321, rem1000000000int64(x));
|
||||
}
|
||||
|
||||
TEST(dsleep, test) {
|
||||
|
|
|
@ -5,13 +5,15 @@ PKGS += TEST_LIBC_TIME
|
|||
|
||||
TEST_LIBC_TIME_SRCS := $(wildcard test/libc/time/*.c)
|
||||
TEST_LIBC_TIME_SRCS_TEST = $(filter %_test.c,$(TEST_LIBC_TIME_SRCS))
|
||||
TEST_LIBC_TIME_COMS = $(TEST_LIBC_TIME_OBJS:%.o=%.com)
|
||||
TEST_LIBC_TIME_BINS = $(TEST_LIBC_TIME_COMS) $(TEST_LIBC_TIME_COMS:%=%.dbg)
|
||||
|
||||
TEST_LIBC_TIME_OBJS = \
|
||||
$(TEST_LIBC_TIME_SRCS:%=o/$(MODE)/%.zip.o) \
|
||||
$(TEST_LIBC_TIME_SRCS:%.c=o/$(MODE)/%.o)
|
||||
|
||||
TEST_LIBC_TIME_COMS = \
|
||||
$(TEST_LIBC_TIME_SRCS:%.c=o/$(MODE)/%.com)
|
||||
|
||||
TEST_LIBC_TIME_TESTS = $(TEST_LIBC_TIME_SRCS_TEST:%.c=o/$(MODE)/%.com.ok)
|
||||
TEST_LIBC_TIME_CHECKS = \
|
||||
$(TEST_LIBC_TIME_SRCS_TEST:%.c=o/$(MODE)/%.com.runs)
|
||||
|
|
|
@ -17,34 +17,37 @@
|
|||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/conv/conv.h"
|
||||
#include "libc/conv/sizemultiply.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/math.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
#include "libc/tinymath/tinymath.h"
|
||||
|
||||
size_t out;
|
||||
|
||||
TEST(sizemultiply, testMultiplication) {
|
||||
EXPECT_TRUE(sizemultiply(&out, 7, 11));
|
||||
EXPECT_EQ(7 * 11, out);
|
||||
EXPECT_TRUE(sizemultiply(&out, 11, 7));
|
||||
EXPECT_EQ(7 * 11, out);
|
||||
EXPECT_TRUE(sizemultiply(&out, 0, 11));
|
||||
EXPECT_EQ(0 * 11, out);
|
||||
EXPECT_TRUE(sizemultiply(&out, 11, 0));
|
||||
EXPECT_EQ(0 * 11, out);
|
||||
TEST(ilogb, yolo) {
|
||||
EXPECT_EQ(0, ilogb(1));
|
||||
EXPECT_EQ(1, ilogb(2));
|
||||
EXPECT_EQ(2, ilogb(4));
|
||||
EXPECT_EQ(63, ilogb(1e19));
|
||||
EXPECT_EQ(0, ilogbf(1));
|
||||
EXPECT_EQ(1, ilogbf(2));
|
||||
EXPECT_EQ(2, ilogbf(4));
|
||||
EXPECT_EQ(63, ilogb(1e19));
|
||||
EXPECT_EQ(0, ilogbl(1));
|
||||
EXPECT_EQ(1, ilogbl(2));
|
||||
EXPECT_EQ(2, ilogbl(4));
|
||||
EXPECT_EQ(63, ilogbl(1e19));
|
||||
}
|
||||
|
||||
TEST(sizemultiply, testOverflow_alwaysReturnsSizeMax) {
|
||||
EXPECT_FALSE(sizemultiply(&out, 7, SIZE_MAX));
|
||||
EXPECT_EQ(SIZE_MAX, out);
|
||||
EXPECT_FALSE(sizemultiply(&out, SIZE_MAX, 7));
|
||||
EXPECT_EQ(SIZE_MAX, out);
|
||||
}
|
||||
|
||||
TEST(sizemultiply, testOverflow_closeButNoCigar) {
|
||||
EXPECT_TRUE(sizemultiply(&out, SIZE_MAX, 1));
|
||||
EXPECT_EQ(SIZE_MAX, out);
|
||||
EXPECT_TRUE(sizemultiply(&out, 1, SIZE_MAX));
|
||||
EXPECT_EQ(SIZE_MAX, out);
|
||||
TEST(logb, yolo) {
|
||||
EXPECT_EQ(0, (int)logb(1));
|
||||
EXPECT_EQ(1, (int)logb(2));
|
||||
EXPECT_EQ(2, (int)logb(4));
|
||||
EXPECT_EQ(63, (int)logb(1e19));
|
||||
EXPECT_EQ(0, (int)logbf(1));
|
||||
EXPECT_EQ(1, (int)logbf(2));
|
||||
EXPECT_EQ(2, (int)logbf(4));
|
||||
EXPECT_EQ(63, (int)logb(1e19));
|
||||
EXPECT_EQ(0, (int)logbl(1));
|
||||
EXPECT_EQ(1, (int)logbl(2));
|
||||
EXPECT_EQ(2, (int)logbl(4));
|
||||
EXPECT_EQ(63, (int)logbl(1e19));
|
||||
}
|
|
@ -27,15 +27,6 @@
|
|||
float tinymath_roundf$k8(float);
|
||||
double tinymath_round$k8(double);
|
||||
|
||||
TEST(round, test) {
|
||||
EXPECT_STREQ("-3", gc(xdtoa(tinymath_round(-2.5))));
|
||||
EXPECT_STREQ("-2", gc(xdtoa(tinymath_round(-1.5))));
|
||||
EXPECT_STREQ("-1", gc(xdtoa(tinymath_round(-.5))));
|
||||
EXPECT_STREQ("1", gc(xdtoa(tinymath_round(.5))));
|
||||
EXPECT_STREQ("2", gc(xdtoa(tinymath_round(1.5))));
|
||||
EXPECT_STREQ("3", gc(xdtoa(tinymath_round(2.5))));
|
||||
}
|
||||
|
||||
TEST(round, testCornerCases) {
|
||||
EXPECT_STREQ("-0", gc(xdtoa(tinymath_round(-0.0))));
|
||||
EXPECT_STREQ("nan", gc(xdtoa(tinymath_round(NAN))));
|
||||
|
@ -44,6 +35,105 @@ TEST(round, testCornerCases) {
|
|||
EXPECT_STREQ("-inf", gc(xdtoa(tinymath_round(-INFINITY))));
|
||||
}
|
||||
|
||||
TEST(round, test) {
|
||||
EXPECT_STREQ("-3", gc(xdtoa(tinymath_round(-2.5))));
|
||||
EXPECT_STREQ("-2", gc(xdtoa(tinymath_round(-1.5))));
|
||||
EXPECT_STREQ("-1", gc(xdtoa(tinymath_round(-.5))));
|
||||
EXPECT_STREQ("-0", gc(xdtoa(tinymath_round(-.4))));
|
||||
EXPECT_STREQ("0", gc(xdtoa(tinymath_round(.4))));
|
||||
EXPECT_STREQ("1", gc(xdtoa(tinymath_round(.5))));
|
||||
EXPECT_STREQ("2", gc(xdtoa(tinymath_round(1.5))));
|
||||
EXPECT_STREQ("3", gc(xdtoa(tinymath_round(2.5))));
|
||||
}
|
||||
|
||||
TEST(roundf, test) {
|
||||
EXPECT_STREQ("-3", gc(xdtoa(tinymath_roundf(-2.5))));
|
||||
EXPECT_STREQ("-2", gc(xdtoa(tinymath_roundf(-1.5))));
|
||||
EXPECT_STREQ("-1", gc(xdtoa(tinymath_roundf(-.5))));
|
||||
EXPECT_STREQ("-0", gc(xdtoa(tinymath_roundf(-.4))));
|
||||
EXPECT_STREQ("0", gc(xdtoa(tinymath_roundf(.4))));
|
||||
EXPECT_STREQ("1", gc(xdtoa(tinymath_roundf(.5))));
|
||||
EXPECT_STREQ("2", gc(xdtoa(tinymath_roundf(1.5))));
|
||||
EXPECT_STREQ("3", gc(xdtoa(tinymath_roundf(2.5))));
|
||||
}
|
||||
|
||||
TEST(roundl, test) {
|
||||
EXPECT_STREQ("-3", gc(xdtoa(tinymath_roundl(-2.5))));
|
||||
EXPECT_STREQ("-2", gc(xdtoa(tinymath_roundl(-1.5))));
|
||||
EXPECT_STREQ("-1", gc(xdtoa(tinymath_roundl(-.5))));
|
||||
EXPECT_STREQ("-0", gc(xdtoa(tinymath_roundl(-.4))));
|
||||
EXPECT_STREQ("0", gc(xdtoa(tinymath_roundl(.4))));
|
||||
EXPECT_STREQ("1", gc(xdtoa(tinymath_roundl(.5))));
|
||||
EXPECT_STREQ("2", gc(xdtoa(tinymath_roundl(1.5))));
|
||||
EXPECT_STREQ("3", gc(xdtoa(tinymath_roundl(2.5))));
|
||||
}
|
||||
|
||||
TEST(nearbyint, test) {
|
||||
EXPECT_STREQ("-2", gc(xdtoa(tinymath_nearbyint(-2.5))));
|
||||
EXPECT_STREQ("-2", gc(xdtoa(tinymath_nearbyint(-1.5))));
|
||||
EXPECT_STREQ("-0", gc(xdtoa(tinymath_nearbyint(-.5))));
|
||||
EXPECT_STREQ("-0", gc(xdtoa(tinymath_nearbyint(-.4))));
|
||||
EXPECT_STREQ("0", gc(xdtoa(tinymath_nearbyint(.4))));
|
||||
EXPECT_STREQ("0", gc(xdtoa(tinymath_nearbyint(.5))));
|
||||
EXPECT_STREQ("2", gc(xdtoa(tinymath_nearbyint(1.5))));
|
||||
EXPECT_STREQ("2", gc(xdtoa(tinymath_nearbyint(2.5))));
|
||||
}
|
||||
|
||||
TEST(nearbyintf, test) {
|
||||
EXPECT_STREQ("-2", gc(xdtoa(tinymath_nearbyintf(-2.5))));
|
||||
EXPECT_STREQ("-2", gc(xdtoa(tinymath_nearbyintf(-1.5))));
|
||||
EXPECT_STREQ("-0", gc(xdtoa(tinymath_nearbyintf(-.5))));
|
||||
EXPECT_STREQ("-0", gc(xdtoa(tinymath_nearbyintf(-.4))));
|
||||
EXPECT_STREQ("0", gc(xdtoa(tinymath_nearbyintf(.4))));
|
||||
EXPECT_STREQ("0", gc(xdtoa(tinymath_nearbyintf(.5))));
|
||||
EXPECT_STREQ("2", gc(xdtoa(tinymath_nearbyintf(1.5))));
|
||||
EXPECT_STREQ("2", gc(xdtoa(tinymath_nearbyintf(2.5))));
|
||||
}
|
||||
|
||||
TEST(nearbyintl, test) {
|
||||
EXPECT_STREQ("-2", gc(xdtoa(tinymath_nearbyintl(-2.5))));
|
||||
EXPECT_STREQ("-2", gc(xdtoa(tinymath_nearbyintl(-1.5))));
|
||||
EXPECT_STREQ("-0", gc(xdtoa(tinymath_nearbyintl(-.5))));
|
||||
EXPECT_STREQ("-0", gc(xdtoa(tinymath_nearbyintl(-.4))));
|
||||
EXPECT_STREQ("0", gc(xdtoa(tinymath_nearbyintl(.4))));
|
||||
EXPECT_STREQ("0", gc(xdtoa(tinymath_nearbyintl(.5))));
|
||||
EXPECT_STREQ("2", gc(xdtoa(tinymath_nearbyintl(1.5))));
|
||||
EXPECT_STREQ("2", gc(xdtoa(tinymath_nearbyintl(2.5))));
|
||||
}
|
||||
|
||||
TEST(rint, test) {
|
||||
EXPECT_STREQ("-2", gc(xdtoa(tinymath_rint(-2.5))));
|
||||
EXPECT_STREQ("-2", gc(xdtoa(tinymath_rint(-1.5))));
|
||||
EXPECT_STREQ("-0", gc(xdtoa(tinymath_rint(-.5))));
|
||||
EXPECT_STREQ("-0", gc(xdtoa(tinymath_rint(-.4))));
|
||||
EXPECT_STREQ("0", gc(xdtoa(tinymath_rint(.4))));
|
||||
EXPECT_STREQ("0", gc(xdtoa(tinymath_rint(.5))));
|
||||
EXPECT_STREQ("2", gc(xdtoa(tinymath_rint(1.5))));
|
||||
EXPECT_STREQ("2", gc(xdtoa(tinymath_rint(2.5))));
|
||||
}
|
||||
|
||||
TEST(rintf, test) {
|
||||
EXPECT_STREQ("-2", gc(xdtoa(tinymath_rintf(-2.5))));
|
||||
EXPECT_STREQ("-2", gc(xdtoa(tinymath_rintf(-1.5))));
|
||||
EXPECT_STREQ("-0", gc(xdtoa(tinymath_rintf(-.5))));
|
||||
EXPECT_STREQ("-0", gc(xdtoa(tinymath_rintf(-.4))));
|
||||
EXPECT_STREQ("0", gc(xdtoa(tinymath_rintf(.4))));
|
||||
EXPECT_STREQ("0", gc(xdtoa(tinymath_rintf(.5))));
|
||||
EXPECT_STREQ("2", gc(xdtoa(tinymath_rintf(1.5))));
|
||||
EXPECT_STREQ("2", gc(xdtoa(tinymath_rintf(2.5))));
|
||||
}
|
||||
|
||||
TEST(rintl, test) {
|
||||
EXPECT_STREQ("-2", gc(xdtoa(tinymath_rintl(-2.5))));
|
||||
EXPECT_STREQ("-2", gc(xdtoa(tinymath_rintl(-1.5))));
|
||||
EXPECT_STREQ("-0", gc(xdtoa(tinymath_rintl(-.5))));
|
||||
EXPECT_STREQ("-0", gc(xdtoa(tinymath_rintl(-.4))));
|
||||
EXPECT_STREQ("0", gc(xdtoa(tinymath_rintl(.4))));
|
||||
EXPECT_STREQ("0", gc(xdtoa(tinymath_rintl(.5))));
|
||||
EXPECT_STREQ("2", gc(xdtoa(tinymath_rintl(1.5))));
|
||||
EXPECT_STREQ("2", gc(xdtoa(tinymath_rintl(2.5))));
|
||||
}
|
||||
|
||||
TEST(lround, test) {
|
||||
EXPECT_EQ(-3, tinymath_lround(-2.5));
|
||||
EXPECT_EQ(-2, tinymath_lround(-1.5));
|
||||
|
@ -54,15 +144,6 @@ TEST(lround, test) {
|
|||
EXPECT_EQ(3, tinymath_lround(2.5));
|
||||
}
|
||||
|
||||
TEST(roundf, test) {
|
||||
EXPECT_STREQ("-3", gc(xdtoa(tinymath_roundf(-2.5))));
|
||||
EXPECT_STREQ("-2", gc(xdtoa(tinymath_roundf(-1.5))));
|
||||
EXPECT_STREQ("-1", gc(xdtoa(tinymath_roundf(-.5))));
|
||||
EXPECT_STREQ("1", gc(xdtoa(tinymath_roundf(.5))));
|
||||
EXPECT_STREQ("2", gc(xdtoa(tinymath_roundf(1.5))));
|
||||
EXPECT_STREQ("3", gc(xdtoa(tinymath_roundf(2.5))));
|
||||
}
|
||||
|
||||
TEST(roundf, testCornerCases) {
|
||||
EXPECT_STREQ("-0", gc(xdtoa(tinymath_roundf(-0.0))));
|
||||
EXPECT_STREQ("nan", gc(xdtoa(tinymath_roundf(NAN))));
|
||||
|
|
|
@ -5,17 +5,20 @@ PKGS += TEST_LIBC_TINYMATH
|
|||
|
||||
TEST_LIBC_TINYMATH_SRCS := $(wildcard test/libc/tinymath/*.c)
|
||||
TEST_LIBC_TINYMATH_SRCS_TEST = $(filter %_test.c,$(TEST_LIBC_TINYMATH_SRCS))
|
||||
TEST_LIBC_TINYMATH_COMS = $(TEST_LIBC_TINYMATH_OBJS:%.o=%.com)
|
||||
|
||||
TEST_LIBC_TINYMATH_OBJS = \
|
||||
$(TEST_LIBC_TINYMATH_SRCS:%=o/$(MODE)/%.zip.o) \
|
||||
$(TEST_LIBC_TINYMATH_SRCS:%.c=o/$(MODE)/%.o)
|
||||
|
||||
TEST_LIBC_TINYMATH_COMS = \
|
||||
$(TEST_LIBC_TINYMATH_SRCS:%.c=o/$(MODE)/%.com)
|
||||
|
||||
TEST_LIBC_TINYMATH_BINS = \
|
||||
$(TEST_LIBC_TINYMATH_COMS) \
|
||||
$(TEST_LIBC_TINYMATH_COMS:%=%.dbg)
|
||||
|
||||
TEST_LIBC_TINYMATH_TESTS = $(TEST_LIBC_TINYMATH_SRCS_TEST:%.c=o/$(MODE)/%.com.ok)
|
||||
TEST_LIBC_TINYMATH_TESTS = \
|
||||
$(TEST_LIBC_TINYMATH_SRCS_TEST:%.c=o/$(MODE)/%.com.ok)
|
||||
|
||||
TEST_LIBC_TINYMATH_CHECKS = \
|
||||
$(TEST_LIBC_TINYMATH_SRCS_TEST:%.c=o/$(MODE)/%.com.runs)
|
||||
|
|
|
@ -5,12 +5,14 @@ PKGS += TEST_LIBC_UNICODE
|
|||
|
||||
TEST_LIBC_UNICODE_SRCS := $(wildcard test/libc/unicode/*.c)
|
||||
TEST_LIBC_UNICODE_SRCS_TEST = $(filter %_test.c,$(TEST_LIBC_UNICODE_SRCS))
|
||||
TEST_LIBC_UNICODE_COMS = $(TEST_LIBC_UNICODE_OBJS:%.o=%.com)
|
||||
|
||||
TEST_LIBC_UNICODE_OBJS = \
|
||||
$(TEST_LIBC_UNICODE_SRCS:%=o/$(MODE)/%.zip.o) \
|
||||
$(TEST_LIBC_UNICODE_SRCS:%.c=o/$(MODE)/%.o)
|
||||
|
||||
TEST_LIBC_UNICODE_COMS = \
|
||||
$(TEST_LIBC_UNICODE_SRCS:%.c=o/$(MODE)/%.com)
|
||||
|
||||
TEST_LIBC_UNICODE_BINS = \
|
||||
$(TEST_LIBC_UNICODE_COMS) \
|
||||
$(TEST_LIBC_UNICODE_COMS:%=%.dbg)
|
||||
|
|
|
@ -61,21 +61,6 @@ TEST(wcwidth, testCjkWidesAndCombiningLowLines_widthIsNotLength) {
|
|||
/*────────────────────────────────────────────────────┴─*/
|
||||
}
|
||||
|
||||
TEST(strwidth, testEmoji_cosmoHelpsYouBuildInclusiveProductsEasily) {
|
||||
/* ┌─If this line is solid your terminal
|
||||
│ is respectful and inclusive towards
|
||||
│ our friends w/ rich and interesting
|
||||
│ backgrounds that aren't Anglo-Saxon
|
||||
│
|
||||
│ ┌─This line being solid, means your
|
||||
│ │ terminal needs a patch to address
|
||||
│ │ issues concerning racism
|
||||
│ │
|
||||
──────────────────────────────────────┼─┼─*/
|
||||
EXPECT_EQ(02, wcswidth(/**/ L"👦🏿" /*- │ - */));
|
||||
/*────────────────────────────────────┼─┼─*/
|
||||
}
|
||||
|
||||
TEST(strwidth, tab) {
|
||||
EXPECT_EQ(32, strwidth("mov 0x0(%rip),%rcx \t"));
|
||||
}
|
||||
|
|
|
@ -5,12 +5,14 @@ PKGS += TEST_LIBC_X
|
|||
|
||||
TEST_LIBC_X_SRCS := $(wildcard test/libc/x/*.c)
|
||||
TEST_LIBC_X_SRCS_TEST = $(filter %_test.c,$(TEST_LIBC_X_SRCS))
|
||||
TEST_LIBC_X_COMS = $(TEST_LIBC_X_OBJS:%.o=%.com)
|
||||
|
||||
TEST_LIBC_X_OBJS = \
|
||||
$(TEST_LIBC_X_SRCS:%=o/$(MODE)/%.zip.o) \
|
||||
$(TEST_LIBC_X_SRCS:%.c=o/$(MODE)/%.o)
|
||||
|
||||
TEST_LIBC_X_COMS = \
|
||||
$(TEST_LIBC_X_SRCS:%.c=o/$(MODE)/%.com)
|
||||
|
||||
TEST_LIBC_X_BINS = \
|
||||
$(TEST_LIBC_X_COMS) \
|
||||
$(TEST_LIBC_X_COMS:%=%.dbg)
|
||||
|
@ -29,7 +31,8 @@ TEST_LIBC_X_DIRECTDEPS = \
|
|||
LIBC_RUNTIME \
|
||||
LIBC_X \
|
||||
LIBC_STUBS \
|
||||
LIBC_TESTLIB
|
||||
LIBC_TESTLIB \
|
||||
THIRD_PARTY_DTOA
|
||||
|
||||
TEST_LIBC_X_DEPS := \
|
||||
$(call uniq,$(foreach x,$(TEST_LIBC_X_DIRECTDEPS),$($(x))))
|
||||
|
|
|
@ -51,12 +51,14 @@ $(TEST_LIBC_XED_TESTLIB_A): \
|
|||
PKGS += TEST_LIBC_XED
|
||||
|
||||
TEST_LIBC_XED_SRCS = $(filter %_test.c,$(TEST_LIBC_XED_FILES))
|
||||
TEST_LIBC_XED_COMS = $(TEST_LIBC_XED_OBJS:%.o=%.com)
|
||||
|
||||
TEST_LIBC_XED_OBJS = \
|
||||
$(TEST_LIBC_XED_SRCS:%=o/$(MODE)/%.zip.o) \
|
||||
$(TEST_LIBC_XED_SRCS:%.c=o/$(MODE)/%.o)
|
||||
|
||||
TEST_LIBC_XED_COMS = \
|
||||
$(TEST_LIBC_XED_SRCS:%.c=o/$(MODE)/%.com)
|
||||
|
||||
TEST_LIBC_XED_BINS = \
|
||||
$(TEST_LIBC_XED_COMS) \
|
||||
$(TEST_LIBC_XED_COMS:%=%.dbg)
|
||||
|
|
|
@ -41,7 +41,7 @@ testonly int ild(const char16_t *codez) {
|
|||
error = xed_instruction_length_decode(
|
||||
xed_decoded_inst_zero_set_mode(&xedd, XED_MACHINE_MODE_LONG_64),
|
||||
gc(unbingx86op(codez)), strlen16(codez) + 16);
|
||||
return error == XED_ERROR_NONE ? xedd.decoded_length : -error;
|
||||
return error == XED_ERROR_NONE ? xedd.length : -error;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -53,7 +53,7 @@ testonly int ildreal(const char16_t *codez) {
|
|||
error = xed_instruction_length_decode(
|
||||
xed_decoded_inst_zero_set_mode(&xedd, XED_MACHINE_MODE_REAL),
|
||||
gc(unbingx86op(codez)), strlen16(codez) + 16);
|
||||
return error == XED_ERROR_NONE ? xedd.decoded_length : -error;
|
||||
return error == XED_ERROR_NONE ? xedd.length : -error;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -65,5 +65,5 @@ testonly int ildlegacy(const char16_t *codez) {
|
|||
error = xed_instruction_length_decode(
|
||||
xed_decoded_inst_zero_set_mode(&xedd, XED_MACHINE_MODE_LEGACY_32),
|
||||
gc(unbingx86op(codez)), strlen16(codez) + 16);
|
||||
return error == XED_ERROR_NONE ? xedd.decoded_length : -error;
|
||||
return error == XED_ERROR_NONE ? xedd.length : -error;
|
||||
}
|
||||
|
|
|
@ -1416,7 +1416,7 @@ TEST(x86ild, test_415C) {
|
|||
ISA_SET: I86
|
||||
SHORT: pop r12
|
||||
*/
|
||||
EXPECT_EQ(2, ild(u"A╲"));
|
||||
EXPECT_EQ(2, ild(u"A\\"));
|
||||
}
|
||||
|
||||
TEST(x86ild, test_488B04C500000000) {
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/runtime/gc.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
#include "test/libc/xed/lib.h"
|
||||
#include "third_party/xed/x86.h"
|
||||
|
@ -94,6 +95,24 @@ TEST(x86ild, testAmd3dnow) {
|
|||
0, xed_instruction_length_decode(
|
||||
xed_decoded_inst_zero_set_mode(&xedd, XED_MACHINE_MODE_LEGACY_32),
|
||||
gc(unbingx86op(u"☼☼╚ª")), 4));
|
||||
ASSERT_EQ(true, xedd.operands.amd3dnow);
|
||||
ASSERT_EQ(0xa6, xedd.operands.nominal_opcode);
|
||||
ASSERT_EQ(true, (int)xedd.op.amd3dnow);
|
||||
ASSERT_EQ(0xa6, xedd.op.opcode);
|
||||
}
|
||||
|
||||
TEST(x86ild, testPopToMemory) {
|
||||
ASSERT_EQ(3, ild(u"ÅF◘")); /* 8f 46 08 */
|
||||
}
|
||||
|
||||
TEST(x86ild, testFinit) {
|
||||
ASSERT_EQ(1, ild(u"¢█π")); /* 9B DB E3: fwait */
|
||||
ASSERT_EQ(2, ild(u"█π")); /* DB E3: fninit */
|
||||
}
|
||||
|
||||
BENCH(x86ild, bench) {
|
||||
uint8_t *x = gc(unbingx86op(u"b▓m◘Pî± ►"));
|
||||
struct XedDecodedInst xedd;
|
||||
EZBENCH2("x86ild", donothing,
|
||||
xed_instruction_length_decode(
|
||||
xed_decoded_inst_zero_set_mode(&xedd, XED_MACHINE_MODE_LONG_64),
|
||||
x, XED_MAX_INSTRUCTION_BYTES));
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue