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