Implement RDTSCP on amd64, finally. This fixes #251569 and dups
311933, 313348 and 313354.
git-svn-id: svn://svn.valgrind.org/vex/trunk@2701 8f6e269a-dfd6-0310-a8e1-e2731360e62c
diff --git a/priv/main_main.c b/priv/main_main.c
index a4d4240..aa45d11 100644
--- a/priv/main_main.c
+++ b/priv/main_main.c
@@ -1205,37 +1205,48 @@
/* SSE3 and CX16 are orthogonal and > baseline, although we really
don't expect to come across anything which can do SSE3 but can't
do CX16. Still, we can handle that case. LZCNT is similarly
- orthogonal. AVX is technically orthogonal, but just add the
- cases we actually come across. (This scheme for printing is
- very stupid. We should add strings independently based on
- feature bits, but then it would be hard to return a string that
- didn't need deallocating by the caller.) */
- /* FIXME: show_hwcaps_s390x is a much better way to do this. */
- switch (hwcaps) {
- case 0:
- return "amd64-sse2";
- case VEX_HWCAPS_AMD64_SSE3:
- return "amd64-sse3";
- case VEX_HWCAPS_AMD64_CX16:
- return "amd64-sse2-cx16";
- case VEX_HWCAPS_AMD64_SSE3 | VEX_HWCAPS_AMD64_CX16:
- return "amd64-sse3-cx16";
- case VEX_HWCAPS_AMD64_SSE3 | VEX_HWCAPS_AMD64_LZCNT:
- return "amd64-sse3-lzcnt";
- case VEX_HWCAPS_AMD64_CX16 | VEX_HWCAPS_AMD64_LZCNT:
- return "amd64-sse2-cx16-lzcnt";
- case VEX_HWCAPS_AMD64_SSE3 | VEX_HWCAPS_AMD64_CX16
- | VEX_HWCAPS_AMD64_LZCNT:
- return "amd64-sse3-cx16-lzcnt";
- case VEX_HWCAPS_AMD64_SSE3 | VEX_HWCAPS_AMD64_CX16
- | VEX_HWCAPS_AMD64_AVX:
- return "amd64-sse3-cx16-avx";
- case VEX_HWCAPS_AMD64_SSE3 | VEX_HWCAPS_AMD64_CX16
- | VEX_HWCAPS_AMD64_LZCNT | VEX_HWCAPS_AMD64_AVX:
- return "amd64-sse3-cx16-lzcnt-avx";
- default:
- return NULL;
+ orthogonal. */
+
+ /* Throw out obviously stupid cases: */
+ /* AVX without SSE3 */
+ Bool have_sse3 = (hwcaps & VEX_HWCAPS_AMD64_SSE3) != 0;
+ Bool have_avx = (hwcaps & VEX_HWCAPS_AMD64_AVX) != 0;
+ if (have_avx && !have_sse3)
+ return NULL;
+
+ /* This isn't threadsafe. We might need to fix it at some point. */
+ static HChar buf[100] = { 0 };
+ if (buf[0] != 0) return buf; /* already constructed */
+
+ vex_bzero(buf, sizeof(buf));
+
+ HChar* p = &buf[0];
+
+ p = p + vex_sprintf(p, "%s", "amd64");
+ if (hwcaps == 0) {
+ /* special-case the baseline case */
+ p = p + vex_sprintf(p, "%s", "-sse2");
+ goto out;
}
+ if (hwcaps & VEX_HWCAPS_AMD64_CX16) {
+ p = p + vex_sprintf(p, "%s", "-cx16");
+ }
+ if (hwcaps & VEX_HWCAPS_AMD64_LZCNT) {
+ p = p + vex_sprintf(p, "%s", "-lzcnt");
+ }
+ if (hwcaps & VEX_HWCAPS_AMD64_RDTSCP) {
+ p = p + vex_sprintf(p, "%s", "-rdtscp");
+ }
+ if (hwcaps & VEX_HWCAPS_AMD64_SSE3) {
+ p = p + vex_sprintf(p, "%s", "-sse3");
+ }
+ if (hwcaps & VEX_HWCAPS_AMD64_AVX) {
+ p = p + vex_sprintf(p, "%s", "-avx");
+ }
+
+ out:
+ vassert(buf[sizeof(buf)-1] == 0);
+ return buf;
}
static const HChar* show_hwcaps_ppc32 ( UInt hwcaps )