33
33
34
34
#define pop_0 () { FPU_settag0(TAG_Empty); top++; }
35
35
36
+ /* index is a 5-bit value: (3-bit FPU_modrm.reg field | opcode[2,1]) */
36
37
static u_char const type_table [32 ] = {
37
- _PUSH_ , _PUSH_ , _PUSH_ , _PUSH_ ,
38
- _null_ , _null_ , _null_ , _null_ ,
39
- _REG0_ , _REG0_ , _REG0_ , _REG0_ ,
40
- _REG0_ , _REG0_ , _REG0_ , _REG0_ ,
38
+ _PUSH_ , _PUSH_ , _PUSH_ , _PUSH_ , /* /0: d9:fld f32, db:fild m32, dd:fld f64, df:fild m16 */
39
+ _null_ , _REG0_ , _REG0_ , _REG0_ , /* /1: d9:undef, db,dd,df:fisttp m32/64/16 */
40
+ _REG0_ , _REG0_ , _REG0_ , _REG0_ , /* /2: d9:fst f32, db:fist m32, dd:fst f64, df:fist m16 */
41
+ _REG0_ , _REG0_ , _REG0_ , _REG0_ , /* /3: d9:fstp f32, db:fistp m32, dd:fstp f64, df:fistp m16 */
41
42
_NONE_ , _null_ , _NONE_ , _PUSH_ ,
42
43
_NONE_ , _PUSH_ , _null_ , _PUSH_ ,
43
44
_NONE_ , _null_ , _NONE_ , _REG0_ ,
44
45
_NONE_ , _REG0_ , _NONE_ , _REG0_
45
46
};
46
47
47
48
u_char const data_sizes_16 [32 ] = {
48
- 4 , 4 , 8 , 2 , 0 , 0 , 0 , 0 ,
49
- 4 , 4 , 8 , 2 , 4 , 4 , 8 , 2 ,
49
+ 4 , 4 , 8 , 2 ,
50
+ 0 , 4 , 8 , 2 , /* /1: d9:undef, db,dd,df:fisttp */
51
+ 4 , 4 , 8 , 2 ,
52
+ 4 , 4 , 8 , 2 ,
50
53
14 , 0 , 94 , 10 , 2 , 10 , 0 , 8 ,
51
54
14 , 0 , 94 , 10 , 2 , 10 , 2 , 8
52
55
};
53
56
54
57
static u_char const data_sizes_32 [32 ] = {
55
- 4 , 4 , 8 , 2 , 0 , 0 , 0 , 0 ,
56
- 4 , 4 , 8 , 2 , 4 , 4 , 8 , 2 ,
58
+ 4 , 4 , 8 , 2 ,
59
+ 0 , 4 , 8 , 2 , /* /1: d9:undef, db,dd,df:fisttp */
60
+ 4 , 4 , 8 , 2 ,
61
+ 4 , 4 , 8 , 2 ,
57
62
28 , 0 , 108 , 10 , 2 , 10 , 0 , 8 ,
58
63
28 , 0 , 108 , 10 , 2 , 10 , 2 , 8
59
64
};
@@ -65,6 +70,7 @@ int FPU_load_store(u_char type, fpu_addr_modes addr_modes,
65
70
FPU_REG * st0_ptr ;
66
71
u_char st0_tag = TAG_Empty ; /* This is just to stop a gcc warning. */
67
72
u_char loaded_tag ;
73
+ int sv_cw ;
68
74
69
75
st0_ptr = NULL ; /* Initialized just to stop compiler warnings. */
70
76
@@ -111,7 +117,8 @@ int FPU_load_store(u_char type, fpu_addr_modes addr_modes,
111
117
}
112
118
113
119
switch (type ) {
114
- case 000 : /* fld m32real */
120
+ /* type is a 5-bit value: (3-bit FPU_modrm.reg field | opcode[2,1]) */
121
+ case 000 : /* fld m32real (d9 /0) */
115
122
clear_C1 ();
116
123
loaded_tag =
117
124
FPU_load_single ((float __user * )data_address , & loaded_data );
@@ -123,13 +130,13 @@ int FPU_load_store(u_char type, fpu_addr_modes addr_modes,
123
130
}
124
131
FPU_copy_to_reg0 (& loaded_data , loaded_tag );
125
132
break ;
126
- case 001 : /* fild m32int */
133
+ case 001 : /* fild m32int (db /0) */
127
134
clear_C1 ();
128
135
loaded_tag =
129
136
FPU_load_int32 ((long __user * )data_address , & loaded_data );
130
137
FPU_copy_to_reg0 (& loaded_data , loaded_tag );
131
138
break ;
132
- case 002 : /* fld m64real */
139
+ case 002 : /* fld m64real (dd /0) */
133
140
clear_C1 ();
134
141
loaded_tag =
135
142
FPU_load_double ((double __user * )data_address ,
@@ -142,12 +149,44 @@ int FPU_load_store(u_char type, fpu_addr_modes addr_modes,
142
149
}
143
150
FPU_copy_to_reg0 (& loaded_data , loaded_tag );
144
151
break ;
145
- case 003 : /* fild m16int */
152
+ case 003 : /* fild m16int (df /0) */
146
153
clear_C1 ();
147
154
loaded_tag =
148
155
FPU_load_int16 ((short __user * )data_address , & loaded_data );
149
156
FPU_copy_to_reg0 (& loaded_data , loaded_tag );
150
157
break ;
158
+ /* case 004: undefined (d9 /1) */
159
+ /* fisttp are enabled if CPUID(1).ECX(0) "sse3" is set */
160
+ case 005 : /* fisttp m32int (db /1) */
161
+ clear_C1 ();
162
+ sv_cw = control_word ;
163
+ control_word |= RC_CHOP ;
164
+ if (FPU_store_int32
165
+ (st0_ptr , st0_tag , (long __user * )data_address ))
166
+ pop_0 (); /* pop only if the number was actually stored
167
+ (see the 80486 manual p16-28) */
168
+ control_word = sv_cw ;
169
+ break ;
170
+ case 006 : /* fisttp m64int (dd /1) */
171
+ clear_C1 ();
172
+ sv_cw = control_word ;
173
+ control_word |= RC_CHOP ;
174
+ if (FPU_store_int64
175
+ (st0_ptr , st0_tag , (long long __user * )data_address ))
176
+ pop_0 (); /* pop only if the number was actually stored
177
+ (see the 80486 manual p16-28) */
178
+ control_word = sv_cw ;
179
+ break ;
180
+ case 007 : /* fisttp m16int (df /1) */
181
+ clear_C1 ();
182
+ sv_cw = control_word ;
183
+ control_word |= RC_CHOP ;
184
+ if (FPU_store_int16
185
+ (st0_ptr , st0_tag , (short __user * )data_address ))
186
+ pop_0 (); /* pop only if the number was actually stored
187
+ (see the 80486 manual p16-28) */
188
+ control_word = sv_cw ;
189
+ break ;
151
190
case 010 : /* fst m32real */
152
191
clear_C1 ();
153
192
FPU_store_single (st0_ptr , st0_tag ,
0 commit comments