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