Home | History | Annotate | Download | only in mips32
      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