From: Petar Jovanovic Date: Tue, 4 Oct 2016 13:07:36 +0000 (+0000) Subject: mips32: test for syscalls prctl(GET/SET_FP_MODE) X-Git-Tag: svn/VALGRIND_3_13_0~365 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a1d8c2ac15bbc9cca793144504d8ad542064fe03;p=thirdparty%2Fvalgrind.git mips32: test for syscalls prctl(GET/SET_FP_MODE) 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 --- diff --git a/none/tests/mips32/Makefile.am b/none/tests/mips32/Makefile.am index d554d8ccad..6983f8510e 100644 --- a/none/tests/mips32/Makefile.am +++ b/none/tests/mips32/Makefile.am @@ -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 index 0000000000..73350b150b --- /dev/null +++ b/none/tests/mips32/change_fp_mode.c @@ -0,0 +1,78 @@ +#include +#include +#include +#include + +#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 index 0000000000..e69de29bb2 diff --git a/none/tests/mips32/change_fp_mode.stdout.exp b/none/tests/mips32/change_fp_mode.stdout.exp new file mode 100644 index 0000000000..61640e3f3f --- /dev/null +++ b/none/tests/mips32/change_fp_mode.stdout.exp @@ -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 index 0000000000..2525770104 --- /dev/null +++ b/none/tests/mips32/change_fp_mode.stdout.exp-fpu32 @@ -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 index 0000000000..68fa456d9e --- /dev/null +++ b/none/tests/mips32/change_fp_mode.vgtest @@ -0,0 +1,2 @@ +prog: change_fp_mode +vgopts: -q