blob: 87b10e995828acb2abeaece7f8433fdf36661a9c [file] [log] [blame]
Elliott Hughesa0664b92017-04-18 17:46:52 -07001#if defined(__mips_hard_float)
2
3#include <elf.h>
4#include <stdio.h>
5#include <stdlib.h>
6#include <sys/prctl.h>
7
8#if !defined(PR_SET_FP_MODE)
9# define PR_SET_FP_MODE 45
10#endif
11
12#if !defined(PR_GET_FP_MODE)
13# define PR_GET_FP_MODE 46
14#endif
15
16/* Determine FP mode based on sdc1 behavior
17 returns 1 if FR = 1 mode is detected. */
18static int get_fp_mode(void) {
19 unsigned long long result = 0;
20 __asm__ volatile(
21 ".set push\n\t"
22 ".set noreorder\n\t"
23 ".set oddspreg\n\t"
24 "lui $t0, 0x3FF0\n\t"
25 "ldc1 $f0, %0\n\t"
26 "mtc1 $t0, $f1\n\t"
27 "sdc1 $f0, %0\n\t"
28 ".set pop\n\t"
29 : "+m"(result)
30 :
31 : "t0", "$f0", "$f1", "memory");
32
33 return (result != 0x3FF0000000000000ull);
34}
35
36static void fatal_error(const char* msg) {
37 fprintf(stderr, "Error: %s\n", msg);
38 exit(1);
39}
40
41static void test(int* fr_prctl, int* fr_detected) {
42 *fr_prctl = prctl(PR_GET_FP_MODE);
43 *fr_detected = get_fp_mode();
44
45 if (*fr_prctl < 0) {
46 fatal_error("prctl(PR_GET_FP_MODE) fails.");
47 }
48
49 printf("fr_prctl: %d, fr_detected: %d\n", *fr_prctl, *fr_detected);
50
51 if (*fr_prctl != *fr_detected) {
52 fatal_error("fr_prctl != fr_detected");
53 }
54}
55
56int main() {
57 int fr_prctl, fr_detected;
58
59 test(&fr_prctl, &fr_detected);
60
61 /* FP64 */
62 if (fr_prctl == 1) {
63
64 /* Change mode to FP32 */
65 if (prctl(PR_SET_FP_MODE, 0) != 0) {
66 fatal_error("prctl(PR_SET_FP_MODE, 0) fails.");
67 }
68
69 test(&fr_prctl, &fr_detected);
70
71 /* Change back FP mode */
72 if (prctl(PR_SET_FP_MODE, 1) != 0) {
73 fatal_error("prctl(PR_SET_FP_MODE, 1) fails.");
74 }
75
76 test(&fr_prctl, &fr_detected);
77 }
78
79 return 0;
80}
81#else
82int main() {
83 return 0;
84}
85#endif