fxsave.c revision e739ac0589b4fb43561f801c4faba8c1b89f8680
1 2#include <stdio.h> 3#include <stdlib.h> 4#include "tests/asm.h" 5#include "tests/malloc.h" 6#include <string.h> 7 8const unsigned int vec0[4] 9 = { 0x12345678, 0x11223344, 0x55667788, 0x87654321 }; 10 11const unsigned int vec1[4] 12 = { 0xABCDEF01, 0xAABBCCDD, 0xEEFF0011, 0x10FEDCBA }; 13 14const unsigned int vecZ[4] 15 = { 0, 0, 0, 0 }; 16 17void do_fxsave ( void* p ) { 18 asm __volatile__("fxsave (%0)" : : "r" (p) : "memory" ); 19} 20 21void do_fxrstor ( void* p ) { 22 asm __volatile__("fxrstor (%0)" : : "r" (p) : "memory" ); 23} 24 25void 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. */ 53void 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 74int 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 88void 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 104int 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