sewardj | 0bb9285 | 2005-01-06 10:57:16 +0000 | [diff] [blame] | 1 | |
| 2 | #include <stdio.h> |
| 3 | #include <stdlib.h> |
sewardj | d86b6bb | 2008-05-09 13:27:47 +0000 | [diff] [blame] | 4 | #include <malloc.h> |
| 5 | #include <string.h> |
sewardj | 0bb9285 | 2005-01-06 10:57:16 +0000 | [diff] [blame] | 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 | |
sewardj | d86b6bb | 2008-05-09 13:27:47 +0000 | [diff] [blame] | 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 | |
sewardj | 0bb9285 | 2005-01-06 10:57:16 +0000 | [diff] [blame] | 51 | /* set up the FP and SSE state, and then dump it. */ |
sewardj | d86b6bb | 2008-05-09 13:27:47 +0000 | [diff] [blame] | 52 | void do_setup_then_fxsave ( void* p ) |
sewardj | 0bb9285 | 2005-01-06 10:57:16 +0000 | [diff] [blame] | 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"); |
sewardj | d86b6bb | 2008-05-09 13:27:47 +0000 | [diff] [blame] | 70 | do_fxsave (p); |
sewardj | 0bb9285 | 2005-01-06 10:57:16 +0000 | [diff] [blame] | 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 | |
sewardj | d86b6bb | 2008-05-09 13:27:47 +0000 | [diff] [blame] | 87 | void show ( unsigned char* buf, int xx ) |
sewardj | 0bb9285 | 2005-01-06 10:57:16 +0000 | [diff] [blame] | 88 | { |
| 89 | int i; |
sewardj | 0bb9285 | 2005-01-06 10:57:16 +0000 | [diff] [blame] | 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 | } |
sewardj | d86b6bb | 2008-05-09 13:27:47 +0000 | [diff] [blame] | 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 | |
sewardj | 0bb9285 | 2005-01-06 10:57:16 +0000 | [diff] [blame] | 135 | return 0; |
| 136 | } |