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