1 /* Tests for powerpc GLIBC_TUNABLES=glibc.cpu.hwcaps filter.
2 Copyright (C) 2023 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
19 #include <array_length.h>
21 #include <ifunc-impl-list.h>
26 #include <support/check.h>
27 #include <support/support.h>
28 #include <support/xunistd.h>
32 /* Nonzero if the program gets called via `exec'. */
33 #define CMDLINE_OPTIONS \
34 { "restart", no_argument, &restart, 1 },
37 /* Hold the four initial argument used to respawn the process, plus the extra
38 '--direct', '--restart', and the function to check */
39 static char *spargs
[8];
42 /* Called on process re-execution. */
44 handle_restart (int argc
, char *argv
[])
46 TEST_VERIFY_EXIT (argc
== 1);
47 const char *funcname
= argv
[0];
49 struct libc_ifunc_impl impls
[32];
50 int cnt
= __libc_ifunc_impl_list ("memcpy", impls
, array_length (impls
));
53 TEST_VERIFY_EXIT (cnt
>= 1);
54 for (int i
= 0; i
< cnt
; i
++) {
55 if (strcmp (impls
[i
].name
, funcname
) == 0)
57 TEST_COMPARE (impls
[i
].usable
, false);
66 run_test (const char *filter
, const char *funcname
)
68 printf ("info: checking filter %s (expect %s ifunc selection to be removed)\n",
70 char *tunable
= xasprintf ("GLIBC_TUNABLES=glibc.cpu.hwcaps=%s", filter
);
71 char *const newenvs
[] = { (char*) tunable
, NULL
};
72 spargs
[fc
] = (char *) funcname
;
75 TEST_COMPARE (posix_spawn (&pid
, spargs
[0], NULL
, NULL
, spargs
, newenvs
), 0);
77 TEST_COMPARE (xwaitpid (pid
, &status
, 0), pid
);
78 TEST_VERIFY (WIFEXITED (status
));
79 TEST_VERIFY (!WIFSIGNALED (status
));
80 TEST_COMPARE (WEXITSTATUS (status
), 0);
86 do_test (int argc
, char *argv
[])
89 handle_restart (argc
- 1, &argv
[1]);
91 TEST_VERIFY_EXIT (argc
== 2 || argc
== 5);
94 for (i
= 0; i
< argc
- 1; i
++)
95 spargs
[i
] = argv
[i
+ 1];
96 spargs
[i
++] = (char *) "--direct";
97 spargs
[i
++] = (char *) "--restart";
101 unsigned long int hwcap
= getauxval (AT_HWCAP
);
102 unsigned long int hwcap2
= getauxval (AT_HWCAP2
);
103 if (__WORDSIZE
== 64)
105 if (hwcap2
& PPC_FEATURE2_ARCH_3_1
)
106 run_test ("-arch_3_1", "__memcpy_power10");
107 if (hwcap2
& PPC_FEATURE2_ARCH_2_07
)
108 run_test ("-arch_2_07", "__memcpy_power8_cached");
109 if (hwcap
& PPC_FEATURE_ARCH_2_06
)
110 run_test ("-arch_2_06", "__memcpy_power7");
111 if (hwcap
& PPC_FEATURE_ARCH_2_05
)
112 run_test ("-arch_2_06,-arch_2_05","__memcpy_power6");
113 run_test ("-arch_2_06,-arch_2_05,-power5+,-power5,-power4", "__memcpy_power4");
117 if (hwcap
& PPC_FEATURE_HAS_VSX
)
118 run_test ("-vsx", "__memcpy_power7");
119 if (hwcap
& PPC_FEATURE_ARCH_2_06
)
120 run_test ("-arch_2_06", "__memcpy_a2");
121 if (hwcap
& PPC_FEATURE_ARCH_2_05
)
122 run_test ("-arch_2_05", "__memcpy_power6");
127 #define TEST_FUNCTION_ARGV do_test
128 #include <support/test-driver.c>