6 /* ------------------------------------------------- */
8 typedef unsigned char UChar
;
9 typedef unsigned short UShort
;
10 typedef unsigned int UInt
;
11 typedef unsigned long long int ULong
;
13 typedef signed char Char
;
16 typedef long long int Long
;
25 /* Offsets, in 16-bit ints, into the FPU environment (env) area. */
29 #define FP_ENV_IP 6 /* and 7 */
31 #define FP_ENV_OPOFF 10 /* and 11 */
32 #define FP_ENV_OPSEL 12
33 #define FP_REG(ii) (10*(7-(ii)))
35 /* Bitfield offsets for exceptions in the FPU status and control words. */
43 /* More bitfield offsets, but for the status word only. */
45 #define FP_E_SUMMARY 7
50 /* top-of-stack ptr is bits 13,12,11 of the word */
51 #define FP_F_TOS_LO 11
52 #define FP_F_TOS_HI 13
55 #define FP_TAG_VALID 0
58 #define FP_TAG_EMPTY 3
61 = { "Valid", "Zero", "Spec", "Empty" };
63 char* fp_exception_names
[6]
64 = { "INVAL", "DENOR", "DIVZ", "OVERF", "UNDERF", "LOS" };
66 Fpu_State m_fpu_state
;
70 UInt
fp_get_tos ( void )
72 return (m_fpu_state
.env
[FP_ENV_STAT
] >> FP_F_TOS_LO
) & 7;
75 UInt
fp_get_tag ( UInt regno
)
77 assert(!(regno
< 0 || regno
> 7));
78 return (m_fpu_state
.env
[FP_ENV_TAG
] >> (2*regno
)) & 3;
81 UInt
fp_get_statusword_flag ( UInt flagno
)
83 assert(!(flagno
< 0 || flagno
> 15));
84 return (m_fpu_state
.env
[FP_ENV_STAT
] >> flagno
) & 0x1;
87 UInt
fp_get_controlword_flag ( UInt flagno
)
89 assert(!(flagno
< 0 || flagno
> 15));
90 return (m_fpu_state
.env
[FP_ENV_CTRL
] >> flagno
) & 0x1;
94 void printFpuState ( void )
97 assert(sizeof(Fpu_State
)==108);
98 for (i
= 7; i
>= 0; i
--) {
99 printf ( " %s fpreg%d: 0x",
100 (UInt
)i
== fp_get_tos() ? "**" : " ", i
);
101 for (k
= 0, j
= FP_REG(i
)+9; k
< 10; k
++,j
--)
102 printf ( "%02x", (UInt
)m_fpu_state
.reg
[j
]);
103 printf ( " %5s ", fp_tag_names
[fp_get_tag(i
)] );
105 //printf ( "%20.16e\n", fp_get_reg(i) );
107 printf(" fctrl: 0x%04x masked: ",
108 (UInt
)m_fpu_state
.env
[FP_ENV_CTRL
] );
109 for (i
= FP_E_INVAL
; i
<= FP_E_LOS
; i
++)
110 if (fp_get_controlword_flag(i
))
111 printf ( "%s ", fp_exception_names
[i
] );
114 printf(" fstat: 0x%04x except:",
115 (UInt
)m_fpu_state
.env
[FP_ENV_STAT
] );
116 for (i
= FP_E_INVAL
; i
<= FP_E_LOS
; i
++)
117 if (fp_get_statusword_flag(i
))
118 printf ( "%s ", fp_exception_names
[i
] );
119 printf ( " top: %d ", fp_get_tos() );
120 printf ( "c3210: %d%d%d%d",
121 fp_get_statusword_flag(FP_F_C3
),
122 fp_get_statusword_flag(FP_F_C2
),
123 fp_get_statusword_flag(FP_F_C1
),
124 fp_get_statusword_flag(FP_F_C0
) );
125 printf ( " STACKF: %d\n", fp_get_statusword_flag(FP_E_STACKF
) );
127 printf(" ftag: 0x%04x ", (UInt
)m_fpu_state
.env
[FP_ENV_TAG
] );
128 for (i
= 7; i
>= 0; i
--)
129 printf ( "%d:%s ", i
, fp_tag_names
[fp_get_tag(i
)] );
132 printf(" fip: 0x%08x\n",
133 (((UInt
)m_fpu_state
.env
[FP_ENV_IP
+1]) << 16) |
134 ((UInt
)m_fpu_state
.env
[FP_ENV_IP
]) );
135 printf(" fcs: 0x%04x\n",
136 ((UInt
)m_fpu_state
.env
[FP_ENV_CS
]) );
137 printf(" fopoff: 0x%08x\n",
138 (((UInt
)m_fpu_state
.env
[FP_ENV_OPOFF
+1]) << 16) |
139 ((UInt
)m_fpu_state
.env
[FP_ENV_OPOFF
]) );
140 printf(" fopsel: 0x%04x\n",
141 ((UInt
)m_fpu_state
.env
[FP_ENV_OPSEL
]) );
145 /* ------------------------------------------------- */
148 /* Initialise the FPU, dump its state, and print it. */
151 void show ( unsigned char* st
)
154 for (i
= 0; i
< 28; i
++) {
155 printf("%02x ", st
[i
]);
156 if (i
> 0 && ((i
& 3) == 3)) printf("\n");
158 for (i
= 0; i
< 80; i
++) {
159 printf("%02x ", st
[i
+28]);
160 if (i
> 0 && ((i
% 10) == 9)) printf("\n");
167 Fpu_State
* st
= &m_fpu_state
;
168 assert(sizeof(m_fpu_state
) == 108);
169 asm volatile ("finit ; fnsave %0"
176 asm volatile ("fildl 0(%%esp) ; pushl $17 ; fildl 0(%%esp) ; addl $4, %%esp ; fnsave %0"