1b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 2b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include <stdio.h> 3b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include <assert.h> 4b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 5b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 6b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* ------------------------------------------------- */ 7b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 8b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovtypedef unsigned char UChar; 9b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovtypedef unsigned short UShort; 10b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovtypedef unsigned int UInt; 11b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovtypedef unsigned long long int ULong; 12b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 13b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovtypedef signed char Char; 14b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovtypedef short Short; 15b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovtypedef int Int; 16b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovtypedef long long int Long; 17b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 18b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovtypedef 19b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov struct { 20b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UShort env[14]; 21b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UChar reg[80]; 22b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 23b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Fpu_State; 24b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 25b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Offsets, in 16-bit ints, into the FPU environment (env) area. */ 26b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define FP_ENV_CTRL 0 27b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define FP_ENV_STAT 2 28b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define FP_ENV_TAG 4 29b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define FP_ENV_IP 6 /* and 7 */ 30b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define FP_ENV_CS 8 31b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define FP_ENV_OPOFF 10 /* and 11 */ 32b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define FP_ENV_OPSEL 12 33b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define FP_REG(ii) (10*(7-(ii))) 34b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 35b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Bitfield offsets for exceptions in the FPU status and control words. */ 36b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define FP_E_INVAL 0 37b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define FP_E_DENOR 1 38b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define FP_E_DIVZ 2 39b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define FP_E_OVERF 3 40b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define FP_E_UNDER 4 41b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define FP_E_LOS 5 42b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 43b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* More bitfield offsets, but for the status word only. */ 44b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define FP_E_STACKF 6 45b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define FP_E_SUMMARY 7 46b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define FP_F_C0 8 47b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define FP_F_C1 9 48b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define FP_F_C2 10 49b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define FP_F_C3 14 50b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* top-of-stack ptr is bits 13,12,11 of the word */ 51b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define FP_F_TOS_LO 11 52b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define FP_F_TOS_HI 13 53b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 54b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Register tags. */ 55b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define FP_TAG_VALID 0 56b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define FP_TAG_ZERO 1 57b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define FP_TAG_SPEC 2 58b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define FP_TAG_EMPTY 3 59b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 60b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovchar* fp_tag_names[4] 61b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov = { "Valid", "Zero", "Spec", "Empty" }; 62b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 63b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovchar* fp_exception_names[6] 64b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov = { "INVAL", "DENOR", "DIVZ", "OVERF", "UNDERF", "LOS" }; 65b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 66b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovFpu_State m_fpu_state; 67b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 68b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 69b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 70b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovUInt fp_get_tos ( void ) 71b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 72b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return (m_fpu_state.env[FP_ENV_STAT] >> FP_F_TOS_LO) & 7; 73b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 74b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 75b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovUInt fp_get_tag ( UInt regno ) 76b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 77b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov assert(!(regno < 0 || regno > 7)); 78b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return (m_fpu_state.env[FP_ENV_TAG] >> (2*regno)) & 3; 79b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 80b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 81b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovUInt fp_get_statusword_flag ( UInt flagno ) 82b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 83b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov assert(!(flagno < 0 || flagno > 15)); 84b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return (m_fpu_state.env[FP_ENV_STAT] >> flagno) & 0x1; 85b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 86b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 87b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovUInt fp_get_controlword_flag ( UInt flagno ) 88b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 89b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov assert(!(flagno < 0 || flagno > 15)); 90b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return (m_fpu_state.env[FP_ENV_CTRL] >> flagno) & 0x1; 91b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 92b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 93b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic 94b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid printFpuState ( void ) 95b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 96b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Int i, j, k; 97b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov assert(sizeof(Fpu_State)==108); 98b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for (i = 7; i >= 0; i--) { 99b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf ( " %s fpreg%d: 0x", 100b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (UInt)i == fp_get_tos() ? "**" : " ", i ); 101b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for (k = 0, j = FP_REG(i)+9; k < 10; k++,j--) 102b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf ( "%02x", (UInt)m_fpu_state.reg[j]); 103b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf ( " %5s ", fp_tag_names[fp_get_tag(i)] ); 104b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("\n"); 105b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov //printf ( "%20.16e\n", fp_get_reg(i) ); 106b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 107b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf(" fctrl: 0x%04x masked: ", 108b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (UInt)m_fpu_state.env[FP_ENV_CTRL] ); 109b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for (i = FP_E_INVAL; i <= FP_E_LOS; i++) 110b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (fp_get_controlword_flag(i)) 111b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf ( "%s ", fp_exception_names[i] ); 112b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf ( "\n" ); 113b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 114b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf(" fstat: 0x%04x except:", 115b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (UInt)m_fpu_state.env[FP_ENV_STAT] ); 116b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for (i = FP_E_INVAL; i <= FP_E_LOS; i++) 117b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (fp_get_statusword_flag(i)) 118b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf ( "%s ", fp_exception_names[i] ); 119b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf ( " top: %d ", fp_get_tos() ); 120b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf ( "c3210: %d%d%d%d", 121b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fp_get_statusword_flag(FP_F_C3), 122b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fp_get_statusword_flag(FP_F_C2), 123b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fp_get_statusword_flag(FP_F_C1), 124b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fp_get_statusword_flag(FP_F_C0) ); 125b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf ( " STACKF: %d\n", fp_get_statusword_flag(FP_E_STACKF) ); 126b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 127b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf(" ftag: 0x%04x ", (UInt)m_fpu_state.env[FP_ENV_TAG] ); 128b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for (i = 7; i >= 0; i--) 129b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf ( "%d:%s ", i, fp_tag_names[fp_get_tag(i)] ); 130b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("\n"); 131b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 132b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf(" fip: 0x%08x\n", 133b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (((UInt)m_fpu_state.env[FP_ENV_IP+1]) << 16) | 134b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ((UInt)m_fpu_state.env[FP_ENV_IP]) ); 135b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf(" fcs: 0x%04x\n", 136b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ((UInt)m_fpu_state.env[FP_ENV_CS]) ); 137b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf(" fopoff: 0x%08x\n", 138b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (((UInt)m_fpu_state.env[FP_ENV_OPOFF+1]) << 16) | 139b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ((UInt)m_fpu_state.env[FP_ENV_OPOFF]) ); 140b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf(" fopsel: 0x%04x\n", 141b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ((UInt)m_fpu_state.env[FP_ENV_OPSEL]) ); 142b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 143b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 144b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 145b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* ------------------------------------------------- */ 146b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 147b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 148b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Initialise the FPU, dump its state, and print it. */ 149b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 150b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 151b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid show ( unsigned char* st ) 152b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 153b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int i; 154b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for (i = 0; i < 28; i++) { 155b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("%02x ", st[i]); 156b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (i > 0 && ((i & 3) == 3)) printf("\n"); 157b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 158b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for (i = 0; i < 80; i++) { 159b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("%02x ", st[i+28]); 160b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (i > 0 && ((i % 10) == 9)) printf("\n"); 161b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 162b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("\n"); 163b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 164b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 165b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovint main ( void ) 166b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 167b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Fpu_State* st = &m_fpu_state; 168b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov assert(sizeof(m_fpu_state) == 108); 169b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm volatile ("finit ; fnsave %0" 170b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "=m" (m_fpu_state) 171b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : 172b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "memory" ); 173b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printFpuState(); 174b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("\n\n"); 175b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 176b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm volatile ("fildl 0(%%esp) ; pushl $17 ; fildl 0(%%esp) ; addl $4, %%esp ; fnsave %0" 177b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "=m" (m_fpu_state) 178b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : 179b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "memory" ); 180b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printFpuState(); 181b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("\n"); 182b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov show(st); 183b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return 0; 184b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 185