diff options
-rw-r--r-- | tools/testing/selftests/powerpc/stringloops/Makefile | 4 | ||||
-rw-r--r-- | tools/testing/selftests/powerpc/stringloops/string.c | 21 | ||||
-rw-r--r-- | tools/testing/selftests/powerpc/stringloops/strlen.c | 127 |
3 files changed, 151 insertions, 1 deletions
diff --git a/tools/testing/selftests/powerpc/stringloops/Makefile b/tools/testing/selftests/powerpc/stringloops/Makefile index b682be18dc66..31499587b483 100644 --- a/tools/testing/selftests/powerpc/stringloops/Makefile +++ b/tools/testing/selftests/powerpc/stringloops/Makefile | |||
@@ -6,7 +6,7 @@ EXTRA_SOURCES := ../harness.c | |||
6 | 6 | ||
7 | build_32bit = $(shell if ($(CC) $(CFLAGS) -m32 -o /dev/null memcmp.c >/dev/null 2>&1) then echo "1"; fi) | 7 | build_32bit = $(shell if ($(CC) $(CFLAGS) -m32 -o /dev/null memcmp.c >/dev/null 2>&1) then echo "1"; fi) |
8 | 8 | ||
9 | TEST_GEN_PROGS := memcmp_64 | 9 | TEST_GEN_PROGS := memcmp_64 strlen |
10 | 10 | ||
11 | $(OUTPUT)/memcmp_64: memcmp.c | 11 | $(OUTPUT)/memcmp_64: memcmp.c |
12 | $(OUTPUT)/memcmp_64: CFLAGS += -m64 -maltivec | 12 | $(OUTPUT)/memcmp_64: CFLAGS += -m64 -maltivec |
@@ -18,6 +18,8 @@ $(OUTPUT)/memcmp_32: CFLAGS += -m32 | |||
18 | TEST_GEN_PROGS += memcmp_32 | 18 | TEST_GEN_PROGS += memcmp_32 |
19 | endif | 19 | endif |
20 | 20 | ||
21 | $(OUTPUT)/strlen: strlen.c string.c | ||
22 | |||
21 | ASFLAGS = $(CFLAGS) | 23 | ASFLAGS = $(CFLAGS) |
22 | 24 | ||
23 | include ../../lib.mk | 25 | include ../../lib.mk |
diff --git a/tools/testing/selftests/powerpc/stringloops/string.c b/tools/testing/selftests/powerpc/stringloops/string.c new file mode 100644 index 000000000000..45e7775415c7 --- /dev/null +++ b/tools/testing/selftests/powerpc/stringloops/string.c | |||
@@ -0,0 +1,21 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * Copied from linux/lib/string.c | ||
4 | * | ||
5 | * Copyright (C) 1991, 1992 Linus Torvalds | ||
6 | */ | ||
7 | |||
8 | #include <stddef.h> | ||
9 | |||
10 | /** | ||
11 | * strlen - Find the length of a string | ||
12 | * @s: The string to be sized | ||
13 | */ | ||
14 | size_t test_strlen(const char *s) | ||
15 | { | ||
16 | const char *sc; | ||
17 | |||
18 | for (sc = s; *sc != '\0'; ++sc) | ||
19 | /* nothing */; | ||
20 | return sc - s; | ||
21 | } | ||
diff --git a/tools/testing/selftests/powerpc/stringloops/strlen.c b/tools/testing/selftests/powerpc/stringloops/strlen.c new file mode 100644 index 000000000000..9055ebc484d0 --- /dev/null +++ b/tools/testing/selftests/powerpc/stringloops/strlen.c | |||
@@ -0,0 +1,127 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | #include <malloc.h> | ||
3 | #include <stdlib.h> | ||
4 | #include <string.h> | ||
5 | #include <time.h> | ||
6 | #include "utils.h" | ||
7 | |||
8 | #define SIZE 256 | ||
9 | #define ITERATIONS 1000 | ||
10 | #define ITERATIONS_BENCH 100000 | ||
11 | |||
12 | int test_strlen(const void *s); | ||
13 | |||
14 | /* test all offsets and lengths */ | ||
15 | static void test_one(char *s) | ||
16 | { | ||
17 | unsigned long offset; | ||
18 | |||
19 | for (offset = 0; offset < SIZE; offset++) { | ||
20 | int x, y; | ||
21 | unsigned long i; | ||
22 | |||
23 | y = strlen(s + offset); | ||
24 | x = test_strlen(s + offset); | ||
25 | |||
26 | if (x != y) { | ||
27 | printf("strlen() returned %d, should have returned %d (%p offset %ld)\n", x, y, s, offset); | ||
28 | |||
29 | for (i = offset; i < SIZE; i++) | ||
30 | printf("%02x ", s[i]); | ||
31 | printf("\n"); | ||
32 | } | ||
33 | } | ||
34 | } | ||
35 | |||
36 | static void bench_test(char *s) | ||
37 | { | ||
38 | struct timespec ts_start, ts_end; | ||
39 | int i; | ||
40 | |||
41 | clock_gettime(CLOCK_MONOTONIC, &ts_start); | ||
42 | |||
43 | for (i = 0; i < ITERATIONS_BENCH; i++) | ||
44 | test_strlen(s); | ||
45 | |||
46 | clock_gettime(CLOCK_MONOTONIC, &ts_end); | ||
47 | |||
48 | printf("len %3.3d : time = %.6f\n", test_strlen(s), ts_end.tv_sec - ts_start.tv_sec + (ts_end.tv_nsec - ts_start.tv_nsec) / 1e9); | ||
49 | } | ||
50 | |||
51 | static int testcase(void) | ||
52 | { | ||
53 | char *s; | ||
54 | unsigned long i; | ||
55 | |||
56 | s = memalign(128, SIZE); | ||
57 | if (!s) { | ||
58 | perror("memalign"); | ||
59 | exit(1); | ||
60 | } | ||
61 | |||
62 | srandom(1); | ||
63 | |||
64 | memset(s, 0, SIZE); | ||
65 | for (i = 0; i < SIZE; i++) { | ||
66 | char c; | ||
67 | |||
68 | do { | ||
69 | c = random() & 0x7f; | ||
70 | } while (!c); | ||
71 | s[i] = c; | ||
72 | test_one(s); | ||
73 | } | ||
74 | |||
75 | for (i = 0; i < ITERATIONS; i++) { | ||
76 | unsigned long j; | ||
77 | |||
78 | for (j = 0; j < SIZE; j++) { | ||
79 | char c; | ||
80 | |||
81 | do { | ||
82 | c = random() & 0x7f; | ||
83 | } while (!c); | ||
84 | s[j] = c; | ||
85 | } | ||
86 | for (j = 0; j < sizeof(long); j++) { | ||
87 | s[SIZE - 1 - j] = 0; | ||
88 | test_one(s); | ||
89 | } | ||
90 | } | ||
91 | |||
92 | for (i = 0; i < SIZE; i++) { | ||
93 | char c; | ||
94 | |||
95 | do { | ||
96 | c = random() & 0x7f; | ||
97 | } while (!c); | ||
98 | s[i] = c; | ||
99 | } | ||
100 | |||
101 | bench_test(s); | ||
102 | |||
103 | s[16] = 0; | ||
104 | bench_test(s); | ||
105 | |||
106 | s[8] = 0; | ||
107 | bench_test(s); | ||
108 | |||
109 | s[4] = 0; | ||
110 | bench_test(s); | ||
111 | |||
112 | s[3] = 0; | ||
113 | bench_test(s); | ||
114 | |||
115 | s[2] = 0; | ||
116 | bench_test(s); | ||
117 | |||
118 | s[1] = 0; | ||
119 | bench_test(s); | ||
120 | |||
121 | return 0; | ||
122 | } | ||
123 | |||
124 | int main(void) | ||
125 | { | ||
126 | return test_harness(testcase, "strlen"); | ||
127 | } | ||