root/tools/testing/selftests/x86/test_FCMOV.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. TEST
  2. sighandler
  3. main

   1 // SPDX-License-Identifier: GPL-2.0
   2 #undef _GNU_SOURCE
   3 #define _GNU_SOURCE 1
   4 #undef __USE_GNU
   5 #define __USE_GNU 1
   6 #include <unistd.h>
   7 #include <stdlib.h>
   8 #include <string.h>
   9 #include <stdio.h>
  10 #include <signal.h>
  11 #include <sys/types.h>
  12 #include <sys/select.h>
  13 #include <sys/time.h>
  14 #include <sys/wait.h>
  15 
  16 #define TEST(insn) \
  17 long double __attribute__((noinline)) insn(long flags) \
  18 {                                               \
  19         long double out;                        \
  20         asm ("\n"                               \
  21         "       push    %1""\n"                 \
  22         "       popf""\n"                       \
  23         "       fldpi""\n"                      \
  24         "       fld1""\n"                       \
  25         "       " #insn " %%st(1), %%st" "\n"   \
  26         "       ffree   %%st(1)" "\n"           \
  27         : "=t" (out)                            \
  28         : "r" (flags)                           \
  29         );                                      \
  30         return out;                             \
  31 }
  32 
  33 TEST(fcmovb)
  34 TEST(fcmove)
  35 TEST(fcmovbe)
  36 TEST(fcmovu)
  37 TEST(fcmovnb)
  38 TEST(fcmovne)
  39 TEST(fcmovnbe)
  40 TEST(fcmovnu)
  41 
  42 enum {
  43         CF = 1 << 0,
  44         PF = 1 << 2,
  45         ZF = 1 << 6,
  46 };
  47 
  48 void sighandler(int sig)
  49 {
  50         printf("[FAIL]\tGot signal %d, exiting\n", sig);
  51         exit(1);
  52 }
  53 
  54 int main(int argc, char **argv, char **envp)
  55 {
  56         int err = 0;
  57 
  58         /* SIGILL triggers on 32-bit kernels w/o fcomi emulation
  59          * when run with "no387 nofxsr". Other signals are caught
  60          * just in case.
  61          */
  62         signal(SIGILL, sighandler);
  63         signal(SIGFPE, sighandler);
  64         signal(SIGSEGV, sighandler);
  65 
  66         printf("[RUN]\tTesting fcmovCC instructions\n");
  67         /* If fcmovCC() returns 1.0, the move wasn't done */
  68         err |= !(fcmovb(0)   == 1.0); err |= !(fcmovnb(0)  != 1.0);
  69         err |= !(fcmove(0)   == 1.0); err |= !(fcmovne(0)  != 1.0);
  70         err |= !(fcmovbe(0)  == 1.0); err |= !(fcmovnbe(0) != 1.0);
  71         err |= !(fcmovu(0)   == 1.0); err |= !(fcmovnu(0)  != 1.0);
  72 
  73         err |= !(fcmovb(CF)  != 1.0); err |= !(fcmovnb(CF)  == 1.0);
  74         err |= !(fcmove(CF)  == 1.0); err |= !(fcmovne(CF)  != 1.0);
  75         err |= !(fcmovbe(CF) != 1.0); err |= !(fcmovnbe(CF) == 1.0);
  76         err |= !(fcmovu(CF)  == 1.0); err |= !(fcmovnu(CF)  != 1.0);
  77 
  78         err |= !(fcmovb(ZF)  == 1.0); err |= !(fcmovnb(ZF)  != 1.0);
  79         err |= !(fcmove(ZF)  != 1.0); err |= !(fcmovne(ZF)  == 1.0);
  80         err |= !(fcmovbe(ZF) != 1.0); err |= !(fcmovnbe(ZF) == 1.0);
  81         err |= !(fcmovu(ZF)  == 1.0); err |= !(fcmovnu(ZF)  != 1.0);
  82 
  83         err |= !(fcmovb(PF)  == 1.0); err |= !(fcmovnb(PF)  != 1.0);
  84         err |= !(fcmove(PF)  == 1.0); err |= !(fcmovne(PF)  != 1.0);
  85         err |= !(fcmovbe(PF) == 1.0); err |= !(fcmovnbe(PF) != 1.0);
  86         err |= !(fcmovu(PF)  != 1.0); err |= !(fcmovnu(PF)  == 1.0);
  87 
  88         if (!err)
  89                 printf("[OK]\tfcmovCC\n");
  90         else
  91                 printf("[FAIL]\tfcmovCC errors: %d\n", err);
  92 
  93         return err;
  94 }

/* [<][>][^][v][top][bottom][index][help] */