1 #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. */ 18 static 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 36 static void fatal_error(const char* msg) { 37 fprintf(stderr, "Error: %s\n", msg); 38 exit(1); 39 } 40 41 static 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 56 int 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 82 int main() { 83 return 0; 84 } 85 #endif 86