Home | History | Annotate | Download | only in test
      1 
      2 #include <stdio.h>
      3 #include <stdlib.h>
      4 #include <malloc.h>
      5 #include <string.h>
      6 
      7 const unsigned int vec0[4]
      8    = { 0x12345678, 0x11223344, 0x55667788, 0x87654321 };
      9 
     10 const unsigned int vec1[4]
     11    = { 0xABCDEF01, 0xAABBCCDD, 0xEEFF0011, 0x10FEDCBA };
     12 
     13 const unsigned int vecZ[4]
     14    = { 0, 0, 0, 0 };
     15 
     16 void do_fxsave ( void* p ) {
     17    asm __volatile__("fxsave (%0)" : : "r" (p) : "memory" );
     18 }
     19 
     20 void do_fxrstor ( void* p ) {
     21    asm __volatile__("fxrstor (%0)" : : "r" (p) : "memory" );
     22 }
     23 
     24 void do_zeroise ( void )
     25 {
     26    asm __volatile__("finit");
     27    asm __volatile__(
     28     "fldz\n\t"
     29     "fldz\n\t"
     30     "fldz\n\t"
     31     "fldz\n\t"
     32     "fldz\n\t"
     33     "fldz\n\t"
     34     "fldz\n\t"
     35     "fldz\n\t"
     36     "finit\n");
     37    asm __volatile__("movups vecZ, %xmm0");
     38    asm __volatile__("movups vecZ, %xmm1");
     39    asm __volatile__("movups vecZ, %xmm2");
     40    asm __volatile__("movups vecZ, %xmm3");
     41    asm __volatile__("movups vecZ, %xmm4");
     42    asm __volatile__("movups vecZ, %xmm5");
     43    asm __volatile__("movups vecZ, %xmm6");
     44    asm __volatile__("movups vecZ, %xmm7");
     45    asm __volatile__(
     46       "pushl $0\n\t"
     47       "ldmxcsr 0(%esp)\n\t"
     48       "addl $4,%esp\n");
     49 }
     50 
     51 /* set up the FP and SSE state, and then dump it. */
     52 void do_setup_then_fxsave ( void* p )
     53 {
     54    asm __volatile__("finit");
     55    asm __volatile__("fldpi");
     56    asm __volatile__("fld1");
     57    asm __volatile__("fldln2");
     58    asm __volatile__("fldlg2");
     59    asm __volatile__("fld %st(3)");
     60    asm __volatile__("fld %st(3)");
     61    asm __volatile__("movups vec0, %xmm0");
     62    asm __volatile__("movups vec1, %xmm1");
     63    asm __volatile__("xorps %xmm2, %xmm2");
     64    asm __volatile__("movaps %xmm2, %xmm3");
     65    asm __volatile__("movaps %xmm2, %xmm4");
     66    asm __volatile__("movaps %xmm2, %xmm5");
     67    asm __volatile__("movaps %xmm2, %xmm6");
     68    asm __volatile__("movaps %xmm1, %xmm7");
     69    asm __volatile__("xorps %xmm0, %xmm7");
     70    do_fxsave (p);
     71 }
     72 
     73 int isFPLsbs ( int i )
     74 {
     75    int q;
     76    q = 32; if (i == q || i == q+1) return 1;
     77    q = 48; if (i == q || i == q+1) return 1;
     78    q = 64; if (i == q || i == q+1) return 1;
     79    q = 80; if (i == q || i == q+1) return 1;
     80    q = 96; if (i == q || i == q+1) return 1;
     81    q = 112; if (i == q || i == q+1) return 1;
     82    q = 128; if (i == q || i == q+1) return 1;
     83    q = 144; if (i == q || i == q+1) return 1;
     84    return 0;
     85 }
     86 
     87 void show ( unsigned char* buf, int xx )
     88 {
     89    int i;
     90    for (i = 0; i < 512; i++) {
     91       if ((i % 16) == 0)
     92          printf("%3d   ", i);
     93       if (xx && isFPLsbs(i))
     94 	 printf("xx ");
     95       else
     96          printf("%02x ", buf[i]);
     97       if (i > 0 && ((i % 16) == 15))
     98           printf("\n");
     99    }
    100 }
    101 
    102 
    103 int main ( int argc, char** argv )
    104 {
    105    unsigned char* buf1 = memalign(16,512);
    106    unsigned char* buf2 = memalign(16,512);
    107    unsigned char* buf3 = memalign(16,512);
    108    int xx = argc > 1;
    109    printf("Re-run with any arg to suppress least-significant\n"
    110           "   16 bits of FP numbers\n");
    111    memset(buf1, 0x55, 512);
    112    memset(buf2, 0x55, 512);
    113    memset(buf3, 0x55, 512);
    114 
    115    /* Load up x87/xmm state and dump it. */
    116    do_setup_then_fxsave(buf1);
    117    printf("\nBEFORE\n");
    118    show(buf1, xx);
    119 
    120    /* Zeroise x87/xmm state and dump it, to show that the
    121       regs have been cleared out. */
    122    do_zeroise();
    123    do_fxsave(buf2);
    124    printf("\nZEROED\n");
    125    show(buf2, xx);
    126 
    127    /* Reload x87/xmm state from buf1 and dump it in buf3. */
    128    do_fxrstor(buf1);
    129    do_fxsave(buf3);
    130    printf("\nRESTORED\n");
    131    show(buf3, xx);
    132 
    133    free(buf1); free(buf2); free(buf3);
    134 
    135    return 0;
    136 }
    137