]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
mips32: test for syscalls prctl(GET/SET_FP_MODE)
authorPetar Jovanovic <mips32r2@gmail.com>
Tue, 4 Oct 2016 13:07:36 +0000 (13:07 +0000)
committerPetar Jovanovic <mips32r2@gmail.com>
Tue, 4 Oct 2016 13:07:36 +0000 (13:07 +0000)
MIPS32 test for syscalls prctl(GET/SET_FP_MODE).
Patch by Aleksandar Rikalo.

Related Bugzilla issue #366079.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@16001

none/tests/mips32/Makefile.am
none/tests/mips32/change_fp_mode.c [new file with mode: 0644]
none/tests/mips32/change_fp_mode.stderr.exp [new file with mode: 0644]
none/tests/mips32/change_fp_mode.stdout.exp [new file with mode: 0644]
none/tests/mips32/change_fp_mode.stdout.exp-fpu32 [new file with mode: 0644]
none/tests/mips32/change_fp_mode.vgtest [new file with mode: 0644]

index d554d8ccada9581e55d8efbc70a2897bf875b686..6983f8510e553cd8f34e1e67529965789cfde7c6 100644 (file)
@@ -6,6 +6,8 @@ dist_noinst_SCRIPTS = filter_stderr
 EXTRA_DIST = \
        block_size.stdout.exp block_size.stderr.exp block_size.vgtest \
        branches.stdout.exp branches.stderr.exp branches.vgtest \
+       change_fp_mode.stdout.exp change_fp_mode.stdout.exp-fpu32 \
+       change_fp_mode.stderr.exp change_fp_mode.vgtest  \
        FPUarithmetic.stdout.exp FPUarithmetic.stdout.exp-mips32 \
        FPUarithmetic.stderr.exp FPUarithmetic.vgtest \
        LoadStore.stdout.exp LoadStore.stdout.exp-BE LoadStore.stderr.exp \
@@ -42,6 +44,7 @@ check_PROGRAMS = \
        allexec \
        block_size \
        branches \
+       change_fp_mode \
        FPUarithmetic \
        LoadStore \
        LoadStore1 \
diff --git a/none/tests/mips32/change_fp_mode.c b/none/tests/mips32/change_fp_mode.c
new file mode 100644 (file)
index 0000000..73350b1
--- /dev/null
@@ -0,0 +1,78 @@
+#include <elf.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/prctl.h>
+
+#if !defined(PR_SET_FP_MODE)
+#   define PR_SET_FP_MODE 45
+#endif
+
+#if !defined(PR_GET_FP_MODE)
+#   define PR_GET_FP_MODE 46
+#endif
+
+/* Determine FP mode based on sdc1 behavior
+   returns 1 if FR = 1 mode is detected. */
+static int get_fp_mode(void) {
+   unsigned long long result = 0;
+   __asm__ volatile(
+      ".set push\n\t"
+      ".set noreorder\n\t"
+      ".set oddspreg\n\t"
+      "lui $t0, 0x3FF0\n\t"
+      "ldc1 $f0, %0\n\t"
+      "mtc1 $t0, $f1\n\t"
+      "sdc1 $f0, %0\n\t"
+      ".set pop\n\t"
+      : "+m"(result)
+      :
+      : "t0", "$f0", "$f1", "memory");
+
+   return (result != 0x3FF0000000000000ull);
+}
+
+static void fatal_error(const char* msg) {
+   fprintf(stderr, "Error: %s\n", msg);
+   exit(1);
+}
+
+static void test(int* fr_prctl, int* fr_detected) {
+   *fr_prctl = prctl(PR_GET_FP_MODE);
+   *fr_detected = get_fp_mode();
+
+   if (*fr_prctl < 0) {
+      fatal_error("prctl(PR_GET_FP_MODE) fails.");
+   }
+
+   printf("fr_prctl: %d, fr_detected: %d\n", *fr_prctl, *fr_detected);
+
+   if (*fr_prctl != *fr_detected) {
+      fatal_error("fr_prctl != fr_detected");
+   }
+}
+
+int main() {
+   int fr_prctl, fr_detected;
+
+   test(&fr_prctl, &fr_detected);
+
+   /* FP64 */
+   if (fr_prctl == 1) {
+
+      /* Change mode to FP32 */
+      if (prctl(PR_SET_FP_MODE, 0) != 0) {
+         fatal_error("prctl(PR_SET_FP_MODE, 0) fails.");
+      }
+
+      test(&fr_prctl, &fr_detected);
+
+      /* Change back FP mode */
+      if (prctl(PR_SET_FP_MODE, 1) != 0) {
+         fatal_error("prctl(PR_SET_FP_MODE, 1) fails.");
+      }
+
+      test(&fr_prctl, &fr_detected);
+   }
+
+   return 0;
+}
diff --git a/none/tests/mips32/change_fp_mode.stderr.exp b/none/tests/mips32/change_fp_mode.stderr.exp
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/none/tests/mips32/change_fp_mode.stdout.exp b/none/tests/mips32/change_fp_mode.stdout.exp
new file mode 100644 (file)
index 0000000..61640e3
--- /dev/null
@@ -0,0 +1,3 @@
+fr_prctl: 1, fr_detected: 1
+fr_prctl: 0, fr_detected: 0
+fr_prctl: 1, fr_detected: 1
diff --git a/none/tests/mips32/change_fp_mode.stdout.exp-fpu32 b/none/tests/mips32/change_fp_mode.stdout.exp-fpu32
new file mode 100644 (file)
index 0000000..2525770
--- /dev/null
@@ -0,0 +1 @@
+fr_prctl: 0, fr_detected: 0
diff --git a/none/tests/mips32/change_fp_mode.vgtest b/none/tests/mips32/change_fp_mode.vgtest
new file mode 100644 (file)
index 0000000..68fa456
--- /dev/null
@@ -0,0 +1,2 @@
+prog: change_fp_mode
+vgopts: -q