aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/math-emu/fpu_etc.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/math-emu/fpu_etc.c')
-rw-r--r--arch/x86/math-emu/fpu_etc.c193
1 files changed, 90 insertions, 103 deletions
diff --git a/arch/x86/math-emu/fpu_etc.c b/arch/x86/math-emu/fpu_etc.c
index e3b5d465587f..e73631e0cde9 100644
--- a/arch/x86/math-emu/fpu_etc.c
+++ b/arch/x86/math-emu/fpu_etc.c
@@ -16,128 +16,115 @@
16#include "status_w.h" 16#include "status_w.h"
17#include "reg_constant.h" 17#include "reg_constant.h"
18 18
19 19static void fchs(FPU_REG * st0_ptr, u_char st0tag)
20static void fchs(FPU_REG *st0_ptr, u_char st0tag)
21{ 20{
22 if ( st0tag ^ TAG_Empty ) 21 if (st0tag ^ TAG_Empty) {
23 { 22 signbyte(st0_ptr) ^= SIGN_NEG;
24 signbyte(st0_ptr) ^= SIGN_NEG; 23 clear_C1();
25 clear_C1(); 24 } else
26 } 25 FPU_stack_underflow();
27 else
28 FPU_stack_underflow();
29} 26}
30 27
31 28static void fabs(FPU_REG * st0_ptr, u_char st0tag)
32static void fabs(FPU_REG *st0_ptr, u_char st0tag)
33{ 29{
34 if ( st0tag ^ TAG_Empty ) 30 if (st0tag ^ TAG_Empty) {
35 { 31 setpositive(st0_ptr);
36 setpositive(st0_ptr); 32 clear_C1();
37 clear_C1(); 33 } else
38 } 34 FPU_stack_underflow();
39 else
40 FPU_stack_underflow();
41} 35}
42 36
43 37static void ftst_(FPU_REG * st0_ptr, u_char st0tag)
44static void ftst_(FPU_REG *st0_ptr, u_char st0tag)
45{ 38{
46 switch (st0tag) 39 switch (st0tag) {
47 { 40 case TAG_Zero:
48 case TAG_Zero:
49 setcc(SW_C3);
50 break;
51 case TAG_Valid:
52 if (getsign(st0_ptr) == SIGN_POS)
53 setcc(0);
54 else
55 setcc(SW_C0);
56 break;
57 case TAG_Special:
58 switch ( FPU_Special(st0_ptr) )
59 {
60 case TW_Denormal:
61 if (getsign(st0_ptr) == SIGN_POS)
62 setcc(0);
63 else
64 setcc(SW_C0);
65 if ( denormal_operand() < 0 )
66 {
67#ifdef PECULIAR_486
68 /* This is weird! */
69 if (getsign(st0_ptr) == SIGN_POS)
70 setcc(SW_C3); 41 setcc(SW_C3);
42 break;
43 case TAG_Valid:
44 if (getsign(st0_ptr) == SIGN_POS)
45 setcc(0);
46 else
47 setcc(SW_C0);
48 break;
49 case TAG_Special:
50 switch (FPU_Special(st0_ptr)) {
51 case TW_Denormal:
52 if (getsign(st0_ptr) == SIGN_POS)
53 setcc(0);
54 else
55 setcc(SW_C0);
56 if (denormal_operand() < 0) {
57#ifdef PECULIAR_486
58 /* This is weird! */
59 if (getsign(st0_ptr) == SIGN_POS)
60 setcc(SW_C3);
71#endif /* PECULIAR_486 */ 61#endif /* PECULIAR_486 */
72 return; 62 return;
73 } 63 }
74 break; 64 break;
75 case TW_NaN: 65 case TW_NaN:
76 setcc(SW_C0|SW_C2|SW_C3); /* Operand is not comparable */ 66 setcc(SW_C0 | SW_C2 | SW_C3); /* Operand is not comparable */
77 EXCEPTION(EX_Invalid); 67 EXCEPTION(EX_Invalid);
78 break; 68 break;
79 case TW_Infinity: 69 case TW_Infinity:
80 if (getsign(st0_ptr) == SIGN_POS) 70 if (getsign(st0_ptr) == SIGN_POS)
81 setcc(0); 71 setcc(0);
82 else 72 else
83 setcc(SW_C0); 73 setcc(SW_C0);
84 break; 74 break;
85 default: 75 default:
86 setcc(SW_C0|SW_C2|SW_C3); /* Operand is not comparable */ 76 setcc(SW_C0 | SW_C2 | SW_C3); /* Operand is not comparable */
87 EXCEPTION(EX_INTERNAL|0x14); 77 EXCEPTION(EX_INTERNAL | 0x14);
88 break; 78 break;
79 }
80 break;
81 case TAG_Empty:
82 setcc(SW_C0 | SW_C2 | SW_C3);
83 EXCEPTION(EX_StackUnder);
84 break;
89 } 85 }
90 break;
91 case TAG_Empty:
92 setcc(SW_C0|SW_C2|SW_C3);
93 EXCEPTION(EX_StackUnder);
94 break;
95 }
96} 86}
97 87
98 88static void fxam(FPU_REG * st0_ptr, u_char st0tag)
99static void fxam(FPU_REG *st0_ptr, u_char st0tag)
100{ 89{
101 int c = 0; 90 int c = 0;
102 switch (st0tag) 91 switch (st0tag) {
103 { 92 case TAG_Empty:
104 case TAG_Empty: 93 c = SW_C3 | SW_C0;
105 c = SW_C3|SW_C0; 94 break;
106 break; 95 case TAG_Zero:
107 case TAG_Zero: 96 c = SW_C3;
108 c = SW_C3; 97 break;
109 break; 98 case TAG_Valid:
110 case TAG_Valid: 99 c = SW_C2;
111 c = SW_C2; 100 break;
112 break; 101 case TAG_Special:
113 case TAG_Special: 102 switch (FPU_Special(st0_ptr)) {
114 switch ( FPU_Special(st0_ptr) ) 103 case TW_Denormal:
115 { 104 c = SW_C2 | SW_C3; /* Denormal */
116 case TW_Denormal: 105 break;
117 c = SW_C2|SW_C3; /* Denormal */ 106 case TW_NaN:
118 break; 107 /* We also use NaN for unsupported types. */
119 case TW_NaN: 108 if ((st0_ptr->sigh & 0x80000000)
120 /* We also use NaN for unsupported types. */ 109 && (exponent(st0_ptr) == EXP_OVER))
121 if ( (st0_ptr->sigh & 0x80000000) && (exponent(st0_ptr) == EXP_OVER) ) 110 c = SW_C0;
122 c = SW_C0; 111 break;
123 break; 112 case TW_Infinity:
124 case TW_Infinity: 113 c = SW_C2 | SW_C0;
125 c = SW_C2|SW_C0; 114 break;
126 break; 115 }
127 } 116 }
128 } 117 if (getsign(st0_ptr) == SIGN_NEG)
129 if ( getsign(st0_ptr) == SIGN_NEG ) 118 c |= SW_C1;
130 c |= SW_C1; 119 setcc(c);
131 setcc(c);
132} 120}
133 121
134
135static FUNC_ST0 const fp_etc_table[] = { 122static FUNC_ST0 const fp_etc_table[] = {
136 fchs, fabs, (FUNC_ST0)FPU_illegal, (FUNC_ST0)FPU_illegal, 123 fchs, fabs, (FUNC_ST0) FPU_illegal, (FUNC_ST0) FPU_illegal,
137 ftst_, fxam, (FUNC_ST0)FPU_illegal, (FUNC_ST0)FPU_illegal 124 ftst_, fxam, (FUNC_ST0) FPU_illegal, (FUNC_ST0) FPU_illegal
138}; 125};
139 126
140void FPU_etc(void) 127void FPU_etc(void)
141{ 128{
142 (fp_etc_table[FPU_rm])(&st(0), FPU_gettag0()); 129 (fp_etc_table[FPU_rm]) (&st(0), FPU_gettag0());
143} 130}