Statistics
| Branch: | Revision:

root / op-i386.c @ 3ef693a0

History | View | Annotate | Download (42.8 kB)

1 7d13299d bellard
/*
2 7d13299d bellard
 *  i386 micro operations
3 7d13299d bellard
 * 
4 7d13299d bellard
 *  Copyright (c) 2003 Fabrice Bellard
5 7d13299d bellard
 *
6 3ef693a0 bellard
 * This library is free software; you can redistribute it and/or
7 3ef693a0 bellard
 * modify it under the terms of the GNU Lesser General Public
8 3ef693a0 bellard
 * License as published by the Free Software Foundation; either
9 3ef693a0 bellard
 * version 2 of the License, or (at your option) any later version.
10 7d13299d bellard
 *
11 3ef693a0 bellard
 * This library is distributed in the hope that it will be useful,
12 3ef693a0 bellard
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 3ef693a0 bellard
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 3ef693a0 bellard
 * Lesser General Public License for more details.
15 7d13299d bellard
 *
16 3ef693a0 bellard
 * You should have received a copy of the GNU Lesser General Public
17 3ef693a0 bellard
 * License along with this library; if not, write to the Free Software
18 3ef693a0 bellard
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 7d13299d bellard
 */
20 7d13299d bellard
#include "exec-i386.h"
21 7bfdb6d1 bellard
22 0ecfa993 bellard
/* NOTE: data are not static to force relocation generation by GCC */
23 367e86e8 bellard
24 7bfdb6d1 bellard
uint8_t parity_table[256] = {
25 7bfdb6d1 bellard
    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
26 7bfdb6d1 bellard
    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
27 7bfdb6d1 bellard
    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
28 7bfdb6d1 bellard
    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
29 7bfdb6d1 bellard
    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
30 7bfdb6d1 bellard
    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
31 7bfdb6d1 bellard
    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
32 7bfdb6d1 bellard
    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
33 7bfdb6d1 bellard
    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
34 7bfdb6d1 bellard
    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
35 7bfdb6d1 bellard
    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
36 7bfdb6d1 bellard
    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
37 7bfdb6d1 bellard
    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
38 7bfdb6d1 bellard
    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
39 7bfdb6d1 bellard
    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
40 7bfdb6d1 bellard
    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
41 7bfdb6d1 bellard
    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
42 7bfdb6d1 bellard
    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
43 7bfdb6d1 bellard
    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
44 7bfdb6d1 bellard
    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
45 7bfdb6d1 bellard
    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
46 7bfdb6d1 bellard
    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
47 7bfdb6d1 bellard
    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
48 7bfdb6d1 bellard
    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
49 7bfdb6d1 bellard
    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
50 7bfdb6d1 bellard
    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
51 7bfdb6d1 bellard
    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
52 7bfdb6d1 bellard
    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
53 7bfdb6d1 bellard
    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
54 7bfdb6d1 bellard
    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
55 7bfdb6d1 bellard
    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
56 7bfdb6d1 bellard
    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
57 7bfdb6d1 bellard
};
58 7bfdb6d1 bellard
59 367e86e8 bellard
/* modulo 17 table */
60 367e86e8 bellard
const uint8_t rclw_table[32] = {
61 367e86e8 bellard
    0, 1, 2, 3, 4, 5, 6, 7, 
62 367e86e8 bellard
    8, 9,10,11,12,13,14,15,
63 367e86e8 bellard
   16, 0, 1, 2, 3, 4, 5, 6,
64 367e86e8 bellard
    7, 8, 9,10,11,12,13,14,
65 367e86e8 bellard
};
66 7bfdb6d1 bellard
67 367e86e8 bellard
/* modulo 9 table */
68 367e86e8 bellard
const uint8_t rclb_table[32] = {
69 367e86e8 bellard
    0, 1, 2, 3, 4, 5, 6, 7, 
70 367e86e8 bellard
    8, 0, 1, 2, 3, 4, 5, 6,
71 367e86e8 bellard
    7, 8, 0, 1, 2, 3, 4, 5, 
72 367e86e8 bellard
    6, 7, 8, 0, 1, 2, 3, 4,
73 367e86e8 bellard
};
74 7bfdb6d1 bellard
75 927f621e bellard
#ifdef USE_X86LDOUBLE
76 927f621e bellard
/* an array of Intel 80-bit FP constants, to be loaded via integer ops */
77 927f621e bellard
typedef unsigned short f15ld[5];
78 927f621e bellard
const f15ld f15rk[] =
79 927f621e bellard
{
80 927f621e bellard
/*0*/        {0x0000,0x0000,0x0000,0x0000,0x0000},
81 927f621e bellard
/*1*/        {0x0000,0x0000,0x0000,0x8000,0x3fff},
82 927f621e bellard
/*pi*/        {0xc235,0x2168,0xdaa2,0xc90f,0x4000},
83 927f621e bellard
/*lg2*/        {0xf799,0xfbcf,0x9a84,0x9a20,0x3ffd},
84 927f621e bellard
/*ln2*/        {0x79ac,0xd1cf,0x17f7,0xb172,0x3ffe},
85 927f621e bellard
/*l2e*/        {0xf0bc,0x5c17,0x3b29,0xb8aa,0x3fff},
86 927f621e bellard
/*l2t*/        {0x8afe,0xcd1b,0x784b,0xd49a,0x4000}
87 927f621e bellard
};
88 927f621e bellard
#else
89 927f621e bellard
/* the same, 64-bit version */
90 927f621e bellard
typedef unsigned short f15ld[4];
91 927f621e bellard
const f15ld f15rk[] =
92 927f621e bellard
{
93 927f621e bellard
#ifndef WORDS_BIGENDIAN
94 927f621e bellard
/*0*/        {0x0000,0x0000,0x0000,0x0000},
95 927f621e bellard
/*1*/        {0x0000,0x0000,0x0000,0x3ff0},
96 927f621e bellard
/*pi*/        {0x2d18,0x5444,0x21fb,0x4009},
97 927f621e bellard
/*lg2*/        {0x79ff,0x509f,0x4413,0x3fd3},
98 927f621e bellard
/*ln2*/        {0x39ef,0xfefa,0x2e42,0x3fe6},
99 927f621e bellard
/*l2e*/        {0x82fe,0x652b,0x1547,0x3ff7},
100 927f621e bellard
/*l2t*/        {0xa371,0x0979,0x934f,0x400a}
101 927f621e bellard
#else
102 927f621e bellard
/*0*/   {0x0000,0x0000,0x0000,0x0000},
103 927f621e bellard
/*1*/   {0x3ff0,0x0000,0x0000,0x0000},
104 927f621e bellard
/*pi*/  {0x4009,0x21fb,0x5444,0x2d18},
105 927f621e bellard
/*lg2*/        {0x3fd3,0x4413,0x509f,0x79ff},
106 927f621e bellard
/*ln2*/        {0x3fe6,0x2e42,0xfefa,0x39ef},
107 927f621e bellard
/*l2e*/        {0x3ff7,0x1547,0x652b,0x82fe},
108 927f621e bellard
/*l2t*/        {0x400a,0x934f,0x0979,0xa371}
109 927f621e bellard
#endif
110 927f621e bellard
};
111 927f621e bellard
#endif
112 927f621e bellard
    
113 367e86e8 bellard
/* n must be a constant to be efficient */
114 367e86e8 bellard
static inline int lshift(int x, int n)
115 7bfdb6d1 bellard
{
116 367e86e8 bellard
    if (n >= 0)
117 367e86e8 bellard
        return x << n;
118 367e86e8 bellard
    else
119 367e86e8 bellard
        return x >> (-n);
120 7bfdb6d1 bellard
}
121 7bfdb6d1 bellard
122 7bfdb6d1 bellard
/* we define the various pieces of code used by the JIT */
123 7bfdb6d1 bellard
124 7bfdb6d1 bellard
#define REG EAX
125 7bfdb6d1 bellard
#define REGNAME _EAX
126 7bfdb6d1 bellard
#include "opreg_template.h"
127 7bfdb6d1 bellard
#undef REG
128 7bfdb6d1 bellard
#undef REGNAME
129 7bfdb6d1 bellard
130 7bfdb6d1 bellard
#define REG ECX
131 7bfdb6d1 bellard
#define REGNAME _ECX
132 7bfdb6d1 bellard
#include "opreg_template.h"
133 7bfdb6d1 bellard
#undef REG
134 7bfdb6d1 bellard
#undef REGNAME
135 7bfdb6d1 bellard
136 7bfdb6d1 bellard
#define REG EDX
137 7bfdb6d1 bellard
#define REGNAME _EDX
138 7bfdb6d1 bellard
#include "opreg_template.h"
139 7bfdb6d1 bellard
#undef REG
140 7bfdb6d1 bellard
#undef REGNAME
141 7bfdb6d1 bellard
142 7bfdb6d1 bellard
#define REG EBX
143 7bfdb6d1 bellard
#define REGNAME _EBX
144 7bfdb6d1 bellard
#include "opreg_template.h"
145 7bfdb6d1 bellard
#undef REG
146 7bfdb6d1 bellard
#undef REGNAME
147 7bfdb6d1 bellard
148 7bfdb6d1 bellard
#define REG ESP
149 7bfdb6d1 bellard
#define REGNAME _ESP
150 7bfdb6d1 bellard
#include "opreg_template.h"
151 7bfdb6d1 bellard
#undef REG
152 7bfdb6d1 bellard
#undef REGNAME
153 7bfdb6d1 bellard
154 7bfdb6d1 bellard
#define REG EBP
155 7bfdb6d1 bellard
#define REGNAME _EBP
156 7bfdb6d1 bellard
#include "opreg_template.h"
157 7bfdb6d1 bellard
#undef REG
158 7bfdb6d1 bellard
#undef REGNAME
159 7bfdb6d1 bellard
160 7bfdb6d1 bellard
#define REG ESI
161 7bfdb6d1 bellard
#define REGNAME _ESI
162 7bfdb6d1 bellard
#include "opreg_template.h"
163 7bfdb6d1 bellard
#undef REG
164 7bfdb6d1 bellard
#undef REGNAME
165 7bfdb6d1 bellard
166 7bfdb6d1 bellard
#define REG EDI
167 7bfdb6d1 bellard
#define REGNAME _EDI
168 7bfdb6d1 bellard
#include "opreg_template.h"
169 7bfdb6d1 bellard
#undef REG
170 7bfdb6d1 bellard
#undef REGNAME
171 7bfdb6d1 bellard
172 dc99065b bellard
/* operations with flags */
173 7bfdb6d1 bellard
174 7bfdb6d1 bellard
void OPPROTO op_addl_T0_T1_cc(void)
175 7bfdb6d1 bellard
{
176 7bfdb6d1 bellard
    CC_SRC = T0;
177 7bfdb6d1 bellard
    T0 += T1;
178 7bfdb6d1 bellard
    CC_DST = T0;
179 7bfdb6d1 bellard
}
180 7bfdb6d1 bellard
181 7bfdb6d1 bellard
void OPPROTO op_orl_T0_T1_cc(void)
182 7bfdb6d1 bellard
{
183 7bfdb6d1 bellard
    T0 |= T1;
184 7bfdb6d1 bellard
    CC_DST = T0;
185 7bfdb6d1 bellard
}
186 7bfdb6d1 bellard
187 7bfdb6d1 bellard
void OPPROTO op_andl_T0_T1_cc(void)
188 7bfdb6d1 bellard
{
189 7bfdb6d1 bellard
    T0 &= T1;
190 7bfdb6d1 bellard
    CC_DST = T0;
191 7bfdb6d1 bellard
}
192 7bfdb6d1 bellard
193 7bfdb6d1 bellard
void OPPROTO op_subl_T0_T1_cc(void)
194 7bfdb6d1 bellard
{
195 7bfdb6d1 bellard
    CC_SRC = T0;
196 7bfdb6d1 bellard
    T0 -= T1;
197 7bfdb6d1 bellard
    CC_DST = T0;
198 7bfdb6d1 bellard
}
199 7bfdb6d1 bellard
200 7bfdb6d1 bellard
void OPPROTO op_xorl_T0_T1_cc(void)
201 7bfdb6d1 bellard
{
202 7bfdb6d1 bellard
    T0 ^= T1;
203 7bfdb6d1 bellard
    CC_DST = T0;
204 7bfdb6d1 bellard
}
205 7bfdb6d1 bellard
206 7bfdb6d1 bellard
void OPPROTO op_cmpl_T0_T1_cc(void)
207 7bfdb6d1 bellard
{
208 7bfdb6d1 bellard
    CC_SRC = T0;
209 7bfdb6d1 bellard
    CC_DST = T0 - T1;
210 7bfdb6d1 bellard
}
211 7bfdb6d1 bellard
212 7bfdb6d1 bellard
void OPPROTO op_negl_T0_cc(void)
213 7bfdb6d1 bellard
{
214 7bfdb6d1 bellard
    CC_SRC = 0;
215 7bfdb6d1 bellard
    T0 = -T0;
216 7bfdb6d1 bellard
    CC_DST = T0;
217 7bfdb6d1 bellard
}
218 7bfdb6d1 bellard
219 7bfdb6d1 bellard
void OPPROTO op_incl_T0_cc(void)
220 7bfdb6d1 bellard
{
221 4b74fe1f bellard
    CC_SRC = cc_table[CC_OP].compute_c();
222 7bfdb6d1 bellard
    T0++;
223 7bfdb6d1 bellard
    CC_DST = T0;
224 7bfdb6d1 bellard
}
225 7bfdb6d1 bellard
226 7bfdb6d1 bellard
void OPPROTO op_decl_T0_cc(void)
227 7bfdb6d1 bellard
{
228 4b74fe1f bellard
    CC_SRC = cc_table[CC_OP].compute_c();
229 7bfdb6d1 bellard
    T0--;
230 7bfdb6d1 bellard
    CC_DST = T0;
231 7bfdb6d1 bellard
}
232 7bfdb6d1 bellard
233 7bfdb6d1 bellard
void OPPROTO op_testl_T0_T1_cc(void)
234 7bfdb6d1 bellard
{
235 7bfdb6d1 bellard
    CC_DST = T0 & T1;
236 7bfdb6d1 bellard
}
237 7bfdb6d1 bellard
238 dc99065b bellard
/* operations without flags */
239 dc99065b bellard
240 dc99065b bellard
void OPPROTO op_addl_T0_T1(void)
241 dc99065b bellard
{
242 dc99065b bellard
    T0 += T1;
243 dc99065b bellard
}
244 dc99065b bellard
245 dc99065b bellard
void OPPROTO op_orl_T0_T1(void)
246 dc99065b bellard
{
247 dc99065b bellard
    T0 |= T1;
248 dc99065b bellard
}
249 dc99065b bellard
250 dc99065b bellard
void OPPROTO op_andl_T0_T1(void)
251 dc99065b bellard
{
252 dc99065b bellard
    T0 &= T1;
253 dc99065b bellard
}
254 dc99065b bellard
255 dc99065b bellard
void OPPROTO op_subl_T0_T1(void)
256 dc99065b bellard
{
257 dc99065b bellard
    T0 -= T1;
258 dc99065b bellard
}
259 dc99065b bellard
260 dc99065b bellard
void OPPROTO op_xorl_T0_T1(void)
261 dc99065b bellard
{
262 dc99065b bellard
    T0 ^= T1;
263 dc99065b bellard
}
264 dc99065b bellard
265 dc99065b bellard
void OPPROTO op_negl_T0(void)
266 dc99065b bellard
{
267 dc99065b bellard
    T0 = -T0;
268 dc99065b bellard
}
269 dc99065b bellard
270 dc99065b bellard
void OPPROTO op_incl_T0(void)
271 dc99065b bellard
{
272 dc99065b bellard
    T0++;
273 dc99065b bellard
}
274 dc99065b bellard
275 dc99065b bellard
void OPPROTO op_decl_T0(void)
276 dc99065b bellard
{
277 dc99065b bellard
    T0--;
278 dc99065b bellard
}
279 dc99065b bellard
280 dc99065b bellard
void OPPROTO op_notl_T0(void)
281 dc99065b bellard
{
282 dc99065b bellard
    T0 = ~T0;
283 dc99065b bellard
}
284 dc99065b bellard
285 4b74fe1f bellard
void OPPROTO op_bswapl_T0(void)
286 4b74fe1f bellard
{
287 4b74fe1f bellard
    T0 = bswap32(T0);
288 4b74fe1f bellard
}
289 4b74fe1f bellard
290 7bfdb6d1 bellard
/* multiply/divide */
291 7bfdb6d1 bellard
void OPPROTO op_mulb_AL_T0(void)
292 7bfdb6d1 bellard
{
293 7bfdb6d1 bellard
    unsigned int res;
294 7bfdb6d1 bellard
    res = (uint8_t)EAX * (uint8_t)T0;
295 7bfdb6d1 bellard
    EAX = (EAX & 0xffff0000) | res;
296 7bfdb6d1 bellard
    CC_SRC = (res & 0xff00);
297 7bfdb6d1 bellard
}
298 7bfdb6d1 bellard
299 7bfdb6d1 bellard
void OPPROTO op_imulb_AL_T0(void)
300 7bfdb6d1 bellard
{
301 7bfdb6d1 bellard
    int res;
302 7bfdb6d1 bellard
    res = (int8_t)EAX * (int8_t)T0;
303 7bfdb6d1 bellard
    EAX = (EAX & 0xffff0000) | (res & 0xffff);
304 7bfdb6d1 bellard
    CC_SRC = (res != (int8_t)res);
305 7bfdb6d1 bellard
}
306 7bfdb6d1 bellard
307 7bfdb6d1 bellard
void OPPROTO op_mulw_AX_T0(void)
308 7bfdb6d1 bellard
{
309 7bfdb6d1 bellard
    unsigned int res;
310 7bfdb6d1 bellard
    res = (uint16_t)EAX * (uint16_t)T0;
311 7bfdb6d1 bellard
    EAX = (EAX & 0xffff0000) | (res & 0xffff);
312 7bfdb6d1 bellard
    EDX = (EDX & 0xffff0000) | ((res >> 16) & 0xffff);
313 7bfdb6d1 bellard
    CC_SRC = res >> 16;
314 7bfdb6d1 bellard
}
315 7bfdb6d1 bellard
316 7bfdb6d1 bellard
void OPPROTO op_imulw_AX_T0(void)
317 7bfdb6d1 bellard
{
318 7bfdb6d1 bellard
    int res;
319 7bfdb6d1 bellard
    res = (int16_t)EAX * (int16_t)T0;
320 7bfdb6d1 bellard
    EAX = (EAX & 0xffff0000) | (res & 0xffff);
321 7bfdb6d1 bellard
    EDX = (EDX & 0xffff0000) | ((res >> 16) & 0xffff);
322 7bfdb6d1 bellard
    CC_SRC = (res != (int16_t)res);
323 7bfdb6d1 bellard
}
324 7bfdb6d1 bellard
325 7bfdb6d1 bellard
void OPPROTO op_mull_EAX_T0(void)
326 7bfdb6d1 bellard
{
327 7bfdb6d1 bellard
    uint64_t res;
328 7bfdb6d1 bellard
    res = (uint64_t)((uint32_t)EAX) * (uint64_t)((uint32_t)T0);
329 7bfdb6d1 bellard
    EAX = res;
330 7bfdb6d1 bellard
    EDX = res >> 32;
331 7bfdb6d1 bellard
    CC_SRC = res >> 32;
332 7bfdb6d1 bellard
}
333 7bfdb6d1 bellard
334 7bfdb6d1 bellard
void OPPROTO op_imull_EAX_T0(void)
335 7bfdb6d1 bellard
{
336 7bfdb6d1 bellard
    int64_t res;
337 7bfdb6d1 bellard
    res = (int64_t)((int32_t)EAX) * (int64_t)((int32_t)T0);
338 7bfdb6d1 bellard
    EAX = res;
339 7bfdb6d1 bellard
    EDX = res >> 32;
340 7bfdb6d1 bellard
    CC_SRC = (res != (int32_t)res);
341 7bfdb6d1 bellard
}
342 7bfdb6d1 bellard
343 7bfdb6d1 bellard
void OPPROTO op_imulw_T0_T1(void)
344 7bfdb6d1 bellard
{
345 7bfdb6d1 bellard
    int res;
346 7bfdb6d1 bellard
    res = (int16_t)T0 * (int16_t)T1;
347 7bfdb6d1 bellard
    T0 = res;
348 7bfdb6d1 bellard
    CC_SRC = (res != (int16_t)res);
349 7bfdb6d1 bellard
}
350 7bfdb6d1 bellard
351 7bfdb6d1 bellard
void OPPROTO op_imull_T0_T1(void)
352 7bfdb6d1 bellard
{
353 7bfdb6d1 bellard
    int64_t res;
354 4b74fe1f bellard
    res = (int64_t)((int32_t)T0) * (int64_t)((int32_t)T1);
355 7bfdb6d1 bellard
    T0 = res;
356 7bfdb6d1 bellard
    CC_SRC = (res != (int32_t)res);
357 7bfdb6d1 bellard
}
358 7bfdb6d1 bellard
359 7bfdb6d1 bellard
/* division, flags are undefined */
360 9de5e440 bellard
/* XXX: add exceptions for overflow */
361 7bfdb6d1 bellard
void OPPROTO op_divb_AL_T0(void)
362 7bfdb6d1 bellard
{
363 7bfdb6d1 bellard
    unsigned int num, den, q, r;
364 7bfdb6d1 bellard
365 7bfdb6d1 bellard
    num = (EAX & 0xffff);
366 7bfdb6d1 bellard
    den = (T0 & 0xff);
367 9de5e440 bellard
    if (den == 0)
368 9de5e440 bellard
        raise_exception(EXCP00_DIVZ);
369 7bfdb6d1 bellard
    q = (num / den) & 0xff;
370 7bfdb6d1 bellard
    r = (num % den) & 0xff;
371 7bfdb6d1 bellard
    EAX = (EAX & 0xffff0000) | (r << 8) | q;
372 7bfdb6d1 bellard
}
373 7bfdb6d1 bellard
374 7bfdb6d1 bellard
void OPPROTO op_idivb_AL_T0(void)
375 7bfdb6d1 bellard
{
376 7bfdb6d1 bellard
    int num, den, q, r;
377 7bfdb6d1 bellard
378 7bfdb6d1 bellard
    num = (int16_t)EAX;
379 7bfdb6d1 bellard
    den = (int8_t)T0;
380 9de5e440 bellard
    if (den == 0)
381 9de5e440 bellard
        raise_exception(EXCP00_DIVZ);
382 7bfdb6d1 bellard
    q = (num / den) & 0xff;
383 7bfdb6d1 bellard
    r = (num % den) & 0xff;
384 7bfdb6d1 bellard
    EAX = (EAX & 0xffff0000) | (r << 8) | q;
385 7bfdb6d1 bellard
}
386 7bfdb6d1 bellard
387 7bfdb6d1 bellard
void OPPROTO op_divw_AX_T0(void)
388 7bfdb6d1 bellard
{
389 7bfdb6d1 bellard
    unsigned int num, den, q, r;
390 7bfdb6d1 bellard
391 7bfdb6d1 bellard
    num = (EAX & 0xffff) | ((EDX & 0xffff) << 16);
392 7bfdb6d1 bellard
    den = (T0 & 0xffff);
393 9de5e440 bellard
    if (den == 0)
394 9de5e440 bellard
        raise_exception(EXCP00_DIVZ);
395 7bfdb6d1 bellard
    q = (num / den) & 0xffff;
396 7bfdb6d1 bellard
    r = (num % den) & 0xffff;
397 7bfdb6d1 bellard
    EAX = (EAX & 0xffff0000) | q;
398 7bfdb6d1 bellard
    EDX = (EDX & 0xffff0000) | r;
399 7bfdb6d1 bellard
}
400 7bfdb6d1 bellard
401 7bfdb6d1 bellard
void OPPROTO op_idivw_AX_T0(void)
402 7bfdb6d1 bellard
{
403 7bfdb6d1 bellard
    int num, den, q, r;
404 7bfdb6d1 bellard
405 7bfdb6d1 bellard
    num = (EAX & 0xffff) | ((EDX & 0xffff) << 16);
406 7bfdb6d1 bellard
    den = (int16_t)T0;
407 9de5e440 bellard
    if (den == 0)
408 9de5e440 bellard
        raise_exception(EXCP00_DIVZ);
409 7bfdb6d1 bellard
    q = (num / den) & 0xffff;
410 7bfdb6d1 bellard
    r = (num % den) & 0xffff;
411 7bfdb6d1 bellard
    EAX = (EAX & 0xffff0000) | q;
412 7bfdb6d1 bellard
    EDX = (EDX & 0xffff0000) | r;
413 7bfdb6d1 bellard
}
414 7bfdb6d1 bellard
415 7bfdb6d1 bellard
void OPPROTO op_divl_EAX_T0(void)
416 7bfdb6d1 bellard
{
417 7bfdb6d1 bellard
    unsigned int den, q, r;
418 7bfdb6d1 bellard
    uint64_t num;
419 7bfdb6d1 bellard
    
420 7bfdb6d1 bellard
    num = EAX | ((uint64_t)EDX << 32);
421 7bfdb6d1 bellard
    den = T0;
422 9de5e440 bellard
    if (den == 0)
423 9de5e440 bellard
        raise_exception(EXCP00_DIVZ);
424 7bfdb6d1 bellard
    q = (num / den);
425 7bfdb6d1 bellard
    r = (num % den);
426 7bfdb6d1 bellard
    EAX = q;
427 7bfdb6d1 bellard
    EDX = r;
428 7bfdb6d1 bellard
}
429 7bfdb6d1 bellard
430 7bfdb6d1 bellard
void OPPROTO op_idivl_EAX_T0(void)
431 7bfdb6d1 bellard
{
432 7bfdb6d1 bellard
    int den, q, r;
433 4b74fe1f bellard
    int64_t num;
434 7bfdb6d1 bellard
    
435 7bfdb6d1 bellard
    num = EAX | ((uint64_t)EDX << 32);
436 4b74fe1f bellard
    den = T0;
437 9de5e440 bellard
    if (den == 0)
438 9de5e440 bellard
        raise_exception(EXCP00_DIVZ);
439 7bfdb6d1 bellard
    q = (num / den);
440 7bfdb6d1 bellard
    r = (num % den);
441 7bfdb6d1 bellard
    EAX = q;
442 7bfdb6d1 bellard
    EDX = r;
443 7bfdb6d1 bellard
}
444 7bfdb6d1 bellard
445 dab2ed99 bellard
/* constant load & misc op */
446 7bfdb6d1 bellard
447 ba1c6e37 bellard
void OPPROTO op_movl_T0_im(void)
448 7bfdb6d1 bellard
{
449 7bfdb6d1 bellard
    T0 = PARAM1;
450 7bfdb6d1 bellard
}
451 7bfdb6d1 bellard
452 dab2ed99 bellard
void OPPROTO op_addl_T0_im(void)
453 dab2ed99 bellard
{
454 dab2ed99 bellard
    T0 += PARAM1;
455 dab2ed99 bellard
}
456 dab2ed99 bellard
457 dab2ed99 bellard
void OPPROTO op_andl_T0_ffff(void)
458 dab2ed99 bellard
{
459 dab2ed99 bellard
    T0 = T0 & 0xffff;
460 dab2ed99 bellard
}
461 dab2ed99 bellard
462 dab2ed99 bellard
void OPPROTO op_movl_T0_T1(void)
463 dab2ed99 bellard
{
464 dab2ed99 bellard
    T0 = T1;
465 dab2ed99 bellard
}
466 dab2ed99 bellard
467 ba1c6e37 bellard
void OPPROTO op_movl_T1_im(void)
468 7bfdb6d1 bellard
{
469 7bfdb6d1 bellard
    T1 = PARAM1;
470 7bfdb6d1 bellard
}
471 7bfdb6d1 bellard
472 dab2ed99 bellard
void OPPROTO op_addl_T1_im(void)
473 dab2ed99 bellard
{
474 dab2ed99 bellard
    T1 += PARAM1;
475 dab2ed99 bellard
}
476 dab2ed99 bellard
477 dab2ed99 bellard
void OPPROTO op_movl_T1_A0(void)
478 dab2ed99 bellard
{
479 dab2ed99 bellard
    T1 = A0;
480 dab2ed99 bellard
}
481 dab2ed99 bellard
482 ba1c6e37 bellard
void OPPROTO op_movl_A0_im(void)
483 7bfdb6d1 bellard
{
484 7bfdb6d1 bellard
    A0 = PARAM1;
485 7bfdb6d1 bellard
}
486 7bfdb6d1 bellard
487 4b74fe1f bellard
void OPPROTO op_addl_A0_im(void)
488 4b74fe1f bellard
{
489 4b74fe1f bellard
    A0 += PARAM1;
490 4b74fe1f bellard
}
491 4b74fe1f bellard
492 4b74fe1f bellard
void OPPROTO op_andl_A0_ffff(void)
493 4b74fe1f bellard
{
494 4b74fe1f bellard
    A0 = A0 & 0xffff;
495 4b74fe1f bellard
}
496 4b74fe1f bellard
497 7bfdb6d1 bellard
/* memory access */
498 7bfdb6d1 bellard
499 7bfdb6d1 bellard
void OPPROTO op_ldub_T0_A0(void)
500 7bfdb6d1 bellard
{
501 7bfdb6d1 bellard
    T0 = ldub((uint8_t *)A0);
502 7bfdb6d1 bellard
}
503 7bfdb6d1 bellard
504 7bfdb6d1 bellard
void OPPROTO op_ldsb_T0_A0(void)
505 7bfdb6d1 bellard
{
506 7bfdb6d1 bellard
    T0 = ldsb((int8_t *)A0);
507 7bfdb6d1 bellard
}
508 7bfdb6d1 bellard
509 7bfdb6d1 bellard
void OPPROTO op_lduw_T0_A0(void)
510 7bfdb6d1 bellard
{
511 7bfdb6d1 bellard
    T0 = lduw((uint8_t *)A0);
512 7bfdb6d1 bellard
}
513 7bfdb6d1 bellard
514 7bfdb6d1 bellard
void OPPROTO op_ldsw_T0_A0(void)
515 7bfdb6d1 bellard
{
516 7bfdb6d1 bellard
    T0 = ldsw((int8_t *)A0);
517 7bfdb6d1 bellard
}
518 7bfdb6d1 bellard
519 7bfdb6d1 bellard
void OPPROTO op_ldl_T0_A0(void)
520 7bfdb6d1 bellard
{
521 7bfdb6d1 bellard
    T0 = ldl((uint8_t *)A0);
522 7bfdb6d1 bellard
}
523 7bfdb6d1 bellard
524 7bfdb6d1 bellard
void OPPROTO op_ldub_T1_A0(void)
525 7bfdb6d1 bellard
{
526 7bfdb6d1 bellard
    T1 = ldub((uint8_t *)A0);
527 7bfdb6d1 bellard
}
528 7bfdb6d1 bellard
529 7bfdb6d1 bellard
void OPPROTO op_ldsb_T1_A0(void)
530 7bfdb6d1 bellard
{
531 7bfdb6d1 bellard
    T1 = ldsb((int8_t *)A0);
532 7bfdb6d1 bellard
}
533 7bfdb6d1 bellard
534 7bfdb6d1 bellard
void OPPROTO op_lduw_T1_A0(void)
535 7bfdb6d1 bellard
{
536 7bfdb6d1 bellard
    T1 = lduw((uint8_t *)A0);
537 7bfdb6d1 bellard
}
538 7bfdb6d1 bellard
539 7bfdb6d1 bellard
void OPPROTO op_ldsw_T1_A0(void)
540 7bfdb6d1 bellard
{
541 7bfdb6d1 bellard
    T1 = ldsw((int8_t *)A0);
542 7bfdb6d1 bellard
}
543 7bfdb6d1 bellard
544 7bfdb6d1 bellard
void OPPROTO op_ldl_T1_A0(void)
545 7bfdb6d1 bellard
{
546 7bfdb6d1 bellard
    T1 = ldl((uint8_t *)A0);
547 7bfdb6d1 bellard
}
548 7bfdb6d1 bellard
549 7bfdb6d1 bellard
void OPPROTO op_stb_T0_A0(void)
550 7bfdb6d1 bellard
{
551 7bfdb6d1 bellard
    stb((uint8_t *)A0, T0);
552 7bfdb6d1 bellard
}
553 7bfdb6d1 bellard
554 7bfdb6d1 bellard
void OPPROTO op_stw_T0_A0(void)
555 7bfdb6d1 bellard
{
556 7bfdb6d1 bellard
    stw((uint8_t *)A0, T0);
557 7bfdb6d1 bellard
}
558 7bfdb6d1 bellard
559 7bfdb6d1 bellard
void OPPROTO op_stl_T0_A0(void)
560 7bfdb6d1 bellard
{
561 7bfdb6d1 bellard
    stl((uint8_t *)A0, T0);
562 7bfdb6d1 bellard
}
563 7bfdb6d1 bellard
564 4b74fe1f bellard
/* used for bit operations */
565 4b74fe1f bellard
566 4b74fe1f bellard
void OPPROTO op_add_bitw_A0_T1(void)
567 4b74fe1f bellard
{
568 4b74fe1f bellard
    A0 += ((int32_t)T1 >> 4) << 1;
569 4b74fe1f bellard
}
570 4b74fe1f bellard
571 4b74fe1f bellard
void OPPROTO op_add_bitl_A0_T1(void)
572 4b74fe1f bellard
{
573 4b74fe1f bellard
    A0 += ((int32_t)T1 >> 5) << 2;
574 4b74fe1f bellard
}
575 7bfdb6d1 bellard
576 7bfdb6d1 bellard
/* indirect jump */
577 0ecfa993 bellard
578 7bfdb6d1 bellard
void OPPROTO op_jmp_T0(void)
579 7bfdb6d1 bellard
{
580 dab2ed99 bellard
    EIP = T0;
581 7bfdb6d1 bellard
}
582 7bfdb6d1 bellard
583 7bfdb6d1 bellard
void OPPROTO op_jmp_im(void)
584 7bfdb6d1 bellard
{
585 dab2ed99 bellard
    EIP = PARAM1;
586 7bfdb6d1 bellard
}
587 7bfdb6d1 bellard
588 0ecfa993 bellard
void OPPROTO op_int_im(void)
589 0ecfa993 bellard
{
590 dab2ed99 bellard
    EIP = PARAM1;
591 0ecfa993 bellard
    raise_exception(EXCP0D_GPF);
592 0ecfa993 bellard
}
593 0ecfa993 bellard
594 0ecfa993 bellard
void OPPROTO op_int3(void)
595 0ecfa993 bellard
{
596 dab2ed99 bellard
    EIP = PARAM1;
597 0ecfa993 bellard
    raise_exception(EXCP03_INT3);
598 0ecfa993 bellard
}
599 0ecfa993 bellard
600 0ecfa993 bellard
void OPPROTO op_into(void)
601 0ecfa993 bellard
{
602 0ecfa993 bellard
    int eflags;
603 0ecfa993 bellard
    eflags = cc_table[CC_OP].compute_all();
604 0ecfa993 bellard
    if (eflags & CC_O) {
605 dab2ed99 bellard
        EIP = PARAM1;
606 0ecfa993 bellard
        raise_exception(EXCP04_INTO);
607 0ecfa993 bellard
    } else {
608 dab2ed99 bellard
        EIP = PARAM2;
609 0ecfa993 bellard
    }
610 0ecfa993 bellard
}
611 0ecfa993 bellard
612 7bfdb6d1 bellard
/* string ops */
613 7bfdb6d1 bellard
614 7bfdb6d1 bellard
#define ldul ldl
615 7bfdb6d1 bellard
616 7bfdb6d1 bellard
#define SHIFT 0
617 367e86e8 bellard
#include "ops_template.h"
618 7bfdb6d1 bellard
#undef SHIFT
619 7bfdb6d1 bellard
620 7bfdb6d1 bellard
#define SHIFT 1
621 367e86e8 bellard
#include "ops_template.h"
622 7bfdb6d1 bellard
#undef SHIFT
623 7bfdb6d1 bellard
624 7bfdb6d1 bellard
#define SHIFT 2
625 367e86e8 bellard
#include "ops_template.h"
626 7bfdb6d1 bellard
#undef SHIFT
627 7bfdb6d1 bellard
628 7bfdb6d1 bellard
/* sign extend */
629 7bfdb6d1 bellard
630 7bfdb6d1 bellard
void OPPROTO op_movsbl_T0_T0(void)
631 7bfdb6d1 bellard
{
632 7bfdb6d1 bellard
    T0 = (int8_t)T0;
633 7bfdb6d1 bellard
}
634 7bfdb6d1 bellard
635 7bfdb6d1 bellard
void OPPROTO op_movzbl_T0_T0(void)
636 7bfdb6d1 bellard
{
637 7bfdb6d1 bellard
    T0 = (uint8_t)T0;
638 7bfdb6d1 bellard
}
639 7bfdb6d1 bellard
640 7bfdb6d1 bellard
void OPPROTO op_movswl_T0_T0(void)
641 7bfdb6d1 bellard
{
642 7bfdb6d1 bellard
    T0 = (int16_t)T0;
643 7bfdb6d1 bellard
}
644 7bfdb6d1 bellard
645 7bfdb6d1 bellard
void OPPROTO op_movzwl_T0_T0(void)
646 7bfdb6d1 bellard
{
647 7bfdb6d1 bellard
    T0 = (uint16_t)T0;
648 7bfdb6d1 bellard
}
649 7bfdb6d1 bellard
650 7bfdb6d1 bellard
void OPPROTO op_movswl_EAX_AX(void)
651 7bfdb6d1 bellard
{
652 7bfdb6d1 bellard
    EAX = (int16_t)EAX;
653 7bfdb6d1 bellard
}
654 7bfdb6d1 bellard
655 7bfdb6d1 bellard
void OPPROTO op_movsbw_AX_AL(void)
656 7bfdb6d1 bellard
{
657 7bfdb6d1 bellard
    EAX = (EAX & 0xffff0000) | ((int8_t)EAX & 0xffff);
658 7bfdb6d1 bellard
}
659 7bfdb6d1 bellard
660 7bfdb6d1 bellard
void OPPROTO op_movslq_EDX_EAX(void)
661 7bfdb6d1 bellard
{
662 7bfdb6d1 bellard
    EDX = (int32_t)EAX >> 31;
663 7bfdb6d1 bellard
}
664 7bfdb6d1 bellard
665 7bfdb6d1 bellard
void OPPROTO op_movswl_DX_AX(void)
666 7bfdb6d1 bellard
{
667 7bfdb6d1 bellard
    EDX = (EDX & 0xffff0000) | (((int16_t)EAX >> 15) & 0xffff);
668 7bfdb6d1 bellard
}
669 7bfdb6d1 bellard
670 7bfdb6d1 bellard
/* push/pop */
671 7bfdb6d1 bellard
672 7bfdb6d1 bellard
void op_pushl_T0(void)
673 7bfdb6d1 bellard
{
674 7bfdb6d1 bellard
    uint32_t offset;
675 7bfdb6d1 bellard
    offset = ESP - 4;
676 7bfdb6d1 bellard
    stl((void *)offset, T0);
677 7bfdb6d1 bellard
    /* modify ESP after to handle exceptions correctly */
678 7bfdb6d1 bellard
    ESP = offset;
679 7bfdb6d1 bellard
}
680 7bfdb6d1 bellard
681 dab2ed99 bellard
void op_pushw_T0(void)
682 dab2ed99 bellard
{
683 dab2ed99 bellard
    uint32_t offset;
684 dab2ed99 bellard
    offset = ESP - 2;
685 dab2ed99 bellard
    stw((void *)offset, T0);
686 dab2ed99 bellard
    /* modify ESP after to handle exceptions correctly */
687 dab2ed99 bellard
    ESP = offset;
688 dab2ed99 bellard
}
689 dab2ed99 bellard
690 dab2ed99 bellard
void op_pushl_ss32_T0(void)
691 7bfdb6d1 bellard
{
692 7bfdb6d1 bellard
    uint32_t offset;
693 7bfdb6d1 bellard
    offset = ESP - 4;
694 dab2ed99 bellard
    stl(env->seg_cache[R_SS].base + offset, T0);
695 dab2ed99 bellard
    /* modify ESP after to handle exceptions correctly */
696 dab2ed99 bellard
    ESP = offset;
697 dab2ed99 bellard
}
698 dab2ed99 bellard
699 dab2ed99 bellard
void op_pushw_ss32_T0(void)
700 dab2ed99 bellard
{
701 dab2ed99 bellard
    uint32_t offset;
702 dab2ed99 bellard
    offset = ESP - 2;
703 dab2ed99 bellard
    stw(env->seg_cache[R_SS].base + offset, T0);
704 7bfdb6d1 bellard
    /* modify ESP after to handle exceptions correctly */
705 7bfdb6d1 bellard
    ESP = offset;
706 7bfdb6d1 bellard
}
707 7bfdb6d1 bellard
708 dab2ed99 bellard
void op_pushl_ss16_T0(void)
709 dab2ed99 bellard
{
710 dab2ed99 bellard
    uint32_t offset;
711 dab2ed99 bellard
    offset = (ESP - 4) & 0xffff;
712 dab2ed99 bellard
    stl(env->seg_cache[R_SS].base + offset, T0);
713 dab2ed99 bellard
    /* modify ESP after to handle exceptions correctly */
714 dab2ed99 bellard
    ESP = (ESP & ~0xffff) | offset;
715 dab2ed99 bellard
}
716 dab2ed99 bellard
717 dab2ed99 bellard
void op_pushw_ss16_T0(void)
718 dab2ed99 bellard
{
719 dab2ed99 bellard
    uint32_t offset;
720 dab2ed99 bellard
    offset = (ESP - 2) & 0xffff;
721 dab2ed99 bellard
    stw(env->seg_cache[R_SS].base + offset, T0);
722 dab2ed99 bellard
    /* modify ESP after to handle exceptions correctly */
723 dab2ed99 bellard
    ESP = (ESP & ~0xffff) | offset;
724 dab2ed99 bellard
}
725 dab2ed99 bellard
726 dab2ed99 bellard
/* NOTE: ESP update is done after */
727 7bfdb6d1 bellard
void op_popl_T0(void)
728 7bfdb6d1 bellard
{
729 7bfdb6d1 bellard
    T0 = ldl((void *)ESP);
730 dab2ed99 bellard
}
731 dab2ed99 bellard
732 dab2ed99 bellard
void op_popw_T0(void)
733 dab2ed99 bellard
{
734 dab2ed99 bellard
    T0 = lduw((void *)ESP);
735 dab2ed99 bellard
}
736 dab2ed99 bellard
737 dab2ed99 bellard
void op_popl_ss32_T0(void)
738 dab2ed99 bellard
{
739 dab2ed99 bellard
    T0 = ldl(env->seg_cache[R_SS].base + ESP);
740 dab2ed99 bellard
}
741 dab2ed99 bellard
742 dab2ed99 bellard
void op_popw_ss32_T0(void)
743 dab2ed99 bellard
{
744 dab2ed99 bellard
    T0 = lduw(env->seg_cache[R_SS].base + ESP);
745 dab2ed99 bellard
}
746 dab2ed99 bellard
747 dab2ed99 bellard
void op_popl_ss16_T0(void)
748 dab2ed99 bellard
{
749 dab2ed99 bellard
    T0 = ldl(env->seg_cache[R_SS].base + (ESP & 0xffff));
750 dab2ed99 bellard
}
751 dab2ed99 bellard
752 dab2ed99 bellard
void op_popw_ss16_T0(void)
753 dab2ed99 bellard
{
754 dab2ed99 bellard
    T0 = lduw(env->seg_cache[R_SS].base + (ESP & 0xffff));
755 dab2ed99 bellard
}
756 dab2ed99 bellard
757 dab2ed99 bellard
void op_addl_ESP_4(void)
758 dab2ed99 bellard
{
759 7bfdb6d1 bellard
    ESP += 4;
760 7bfdb6d1 bellard
}
761 7bfdb6d1 bellard
762 dab2ed99 bellard
void op_addl_ESP_2(void)
763 dab2ed99 bellard
{
764 dab2ed99 bellard
    ESP += 2;
765 dab2ed99 bellard
}
766 dab2ed99 bellard
767 dab2ed99 bellard
void op_addw_ESP_4(void)
768 dab2ed99 bellard
{
769 dab2ed99 bellard
    ESP = (ESP & ~0xffff) | ((ESP + 4) & 0xffff);
770 dab2ed99 bellard
}
771 dab2ed99 bellard
772 dab2ed99 bellard
void op_addw_ESP_2(void)
773 dab2ed99 bellard
{
774 dab2ed99 bellard
    ESP = (ESP & ~0xffff) | ((ESP + 2) & 0xffff);
775 dab2ed99 bellard
}
776 dab2ed99 bellard
777 7bfdb6d1 bellard
void op_addl_ESP_im(void)
778 7bfdb6d1 bellard
{
779 7bfdb6d1 bellard
    ESP += PARAM1;
780 7bfdb6d1 bellard
}
781 367e86e8 bellard
782 dab2ed99 bellard
void op_addw_ESP_im(void)
783 dab2ed99 bellard
{
784 dab2ed99 bellard
    ESP = (ESP & ~0xffff) | ((ESP + PARAM1) & 0xffff);
785 27362c82 bellard
}
786 27362c82 bellard
787 27362c82 bellard
/* rdtsc */
788 27362c82 bellard
#ifndef __i386__
789 27362c82 bellard
uint64_t emu_time;
790 27362c82 bellard
#endif
791 27362c82 bellard
void op_rdtsc(void)
792 27362c82 bellard
{
793 27362c82 bellard
    uint64_t val;
794 27362c82 bellard
#ifdef __i386__
795 27362c82 bellard
    asm("rdtsc" : "=A" (val));
796 27362c82 bellard
#else
797 27362c82 bellard
    /* better than nothing: the time increases */
798 27362c82 bellard
    val = emu_time++;
799 27362c82 bellard
#endif
800 27362c82 bellard
    EAX = val;
801 27362c82 bellard
    EDX = val >> 32;
802 27362c82 bellard
}
803 27362c82 bellard
804 27362c82 bellard
/* bcd */
805 27362c82 bellard
806 27362c82 bellard
/* XXX: exception */
807 27362c82 bellard
void OPPROTO op_aam(void)
808 27362c82 bellard
{
809 27362c82 bellard
    int base = PARAM1;
810 27362c82 bellard
    int al, ah;
811 27362c82 bellard
    al = EAX & 0xff;
812 27362c82 bellard
    ah = al / base;
813 27362c82 bellard
    al = al % base;
814 27362c82 bellard
    EAX = (EAX & ~0xffff) | al | (ah << 8);
815 27362c82 bellard
    CC_DST = al;
816 27362c82 bellard
}
817 27362c82 bellard
818 27362c82 bellard
void OPPROTO op_aad(void)
819 27362c82 bellard
{
820 27362c82 bellard
    int base = PARAM1;
821 27362c82 bellard
    int al, ah;
822 27362c82 bellard
    al = EAX & 0xff;
823 27362c82 bellard
    ah = (EAX >> 8) & 0xff;
824 27362c82 bellard
    al = ((ah * base) + al) & 0xff;
825 27362c82 bellard
    EAX = (EAX & ~0xffff) | al;
826 27362c82 bellard
    CC_DST = al;
827 27362c82 bellard
}
828 27362c82 bellard
829 27362c82 bellard
void OPPROTO op_aaa(void)
830 27362c82 bellard
{
831 27362c82 bellard
    int icarry;
832 27362c82 bellard
    int al, ah, af;
833 27362c82 bellard
    int eflags;
834 27362c82 bellard
835 27362c82 bellard
    eflags = cc_table[CC_OP].compute_all();
836 27362c82 bellard
    af = eflags & CC_A;
837 27362c82 bellard
    al = EAX & 0xff;
838 27362c82 bellard
    ah = (EAX >> 8) & 0xff;
839 27362c82 bellard
840 27362c82 bellard
    icarry = (al > 0xf9);
841 27362c82 bellard
    if (((al & 0x0f) > 9 ) || af) {
842 27362c82 bellard
        al = (al + 6) & 0x0f;
843 27362c82 bellard
        ah = (ah + 1 + icarry) & 0xff;
844 27362c82 bellard
        eflags |= CC_C | CC_A;
845 27362c82 bellard
    } else {
846 27362c82 bellard
        eflags &= ~(CC_C | CC_A);
847 27362c82 bellard
        al &= 0x0f;
848 27362c82 bellard
    }
849 27362c82 bellard
    EAX = (EAX & ~0xffff) | al | (ah << 8);
850 27362c82 bellard
    CC_SRC = eflags;
851 27362c82 bellard
}
852 27362c82 bellard
853 27362c82 bellard
void OPPROTO op_aas(void)
854 27362c82 bellard
{
855 27362c82 bellard
    int icarry;
856 27362c82 bellard
    int al, ah, af;
857 27362c82 bellard
    int eflags;
858 27362c82 bellard
859 27362c82 bellard
    eflags = cc_table[CC_OP].compute_all();
860 27362c82 bellard
    af = eflags & CC_A;
861 27362c82 bellard
    al = EAX & 0xff;
862 27362c82 bellard
    ah = (EAX >> 8) & 0xff;
863 27362c82 bellard
864 27362c82 bellard
    icarry = (al < 6);
865 27362c82 bellard
    if (((al & 0x0f) > 9 ) || af) {
866 27362c82 bellard
        al = (al - 6) & 0x0f;
867 27362c82 bellard
        ah = (ah - 1 - icarry) & 0xff;
868 27362c82 bellard
        eflags |= CC_C | CC_A;
869 27362c82 bellard
    } else {
870 27362c82 bellard
        eflags &= ~(CC_C | CC_A);
871 27362c82 bellard
        al &= 0x0f;
872 27362c82 bellard
    }
873 27362c82 bellard
    EAX = (EAX & ~0xffff) | al | (ah << 8);
874 27362c82 bellard
    CC_SRC = eflags;
875 27362c82 bellard
}
876 27362c82 bellard
877 27362c82 bellard
void OPPROTO op_daa(void)
878 27362c82 bellard
{
879 27362c82 bellard
    int al, af, cf;
880 27362c82 bellard
    int eflags;
881 27362c82 bellard
882 27362c82 bellard
    eflags = cc_table[CC_OP].compute_all();
883 27362c82 bellard
    cf = eflags & CC_C;
884 27362c82 bellard
    af = eflags & CC_A;
885 27362c82 bellard
    al = EAX & 0xff;
886 27362c82 bellard
887 27362c82 bellard
    eflags = 0;
888 27362c82 bellard
    if (((al & 0x0f) > 9 ) || af) {
889 27362c82 bellard
        al = (al + 6) & 0xff;
890 27362c82 bellard
        eflags |= CC_A;
891 27362c82 bellard
    }
892 27362c82 bellard
    if ((al > 0x9f) || cf) {
893 27362c82 bellard
        al = (al + 0x60) & 0xff;
894 27362c82 bellard
        eflags |= CC_C;
895 27362c82 bellard
    }
896 27362c82 bellard
    EAX = (EAX & ~0xff) | al;
897 27362c82 bellard
    /* well, speed is not an issue here, so we compute the flags by hand */
898 27362c82 bellard
    eflags |= (al == 0) << 6; /* zf */
899 27362c82 bellard
    eflags |= parity_table[al]; /* pf */
900 27362c82 bellard
    eflags |= (al & 0x80); /* sf */
901 27362c82 bellard
    CC_SRC = eflags;
902 27362c82 bellard
}
903 27362c82 bellard
904 27362c82 bellard
void OPPROTO op_das(void)
905 27362c82 bellard
{
906 27362c82 bellard
    int al, al1, af, cf;
907 27362c82 bellard
    int eflags;
908 27362c82 bellard
909 27362c82 bellard
    eflags = cc_table[CC_OP].compute_all();
910 27362c82 bellard
    cf = eflags & CC_C;
911 27362c82 bellard
    af = eflags & CC_A;
912 27362c82 bellard
    al = EAX & 0xff;
913 27362c82 bellard
914 27362c82 bellard
    eflags = 0;
915 27362c82 bellard
    al1 = al;
916 27362c82 bellard
    if (((al & 0x0f) > 9 ) || af) {
917 27362c82 bellard
        eflags |= CC_A;
918 27362c82 bellard
        if (al < 6 || cf)
919 27362c82 bellard
            eflags |= CC_C;
920 27362c82 bellard
        al = (al - 6) & 0xff;
921 27362c82 bellard
    }
922 27362c82 bellard
    if ((al1 > 0x99) || cf) {
923 27362c82 bellard
        al = (al - 0x60) & 0xff;
924 27362c82 bellard
        eflags |= CC_C;
925 27362c82 bellard
    }
926 27362c82 bellard
    EAX = (EAX & ~0xff) | al;
927 27362c82 bellard
    /* well, speed is not an issue here, so we compute the flags by hand */
928 27362c82 bellard
    eflags |= (al == 0) << 6; /* zf */
929 27362c82 bellard
    eflags |= parity_table[al]; /* pf */
930 27362c82 bellard
    eflags |= (al & 0x80); /* sf */
931 27362c82 bellard
    CC_SRC = eflags;
932 27362c82 bellard
}
933 27362c82 bellard
934 6dbad63e bellard
/* segment handling */
935 6dbad63e bellard
936 6dbad63e bellard
void load_seg(int seg_reg, int selector)
937 6dbad63e bellard
{
938 6dbad63e bellard
    SegmentCache *sc;
939 6dbad63e bellard
    SegmentDescriptorTable *dt;
940 6dbad63e bellard
    int index;
941 6dbad63e bellard
    uint32_t e1, e2;
942 6dbad63e bellard
    uint8_t *ptr;
943 6dbad63e bellard
944 6dbad63e bellard
    env->segs[seg_reg] = selector;
945 6dbad63e bellard
    sc = &env->seg_cache[seg_reg];
946 6dbad63e bellard
    if (env->vm86) {
947 6dbad63e bellard
        sc->base = (void *)(selector << 4);
948 6dbad63e bellard
        sc->limit = 0xffff;
949 6dbad63e bellard
        sc->seg_32bit = 0;
950 6dbad63e bellard
    } else {
951 6dbad63e bellard
        if (selector & 0x4)
952 6dbad63e bellard
            dt = &env->ldt;
953 6dbad63e bellard
        else
954 6dbad63e bellard
            dt = &env->gdt;
955 6dbad63e bellard
        index = selector & ~7;
956 6dbad63e bellard
        if ((index + 7) > dt->limit)
957 6dbad63e bellard
            raise_exception(EXCP0D_GPF);
958 6dbad63e bellard
        ptr = dt->base + index;
959 6dbad63e bellard
        e1 = ldl(ptr);
960 6dbad63e bellard
        e2 = ldl(ptr + 4);
961 6dbad63e bellard
        sc->base = (void *)((e1 >> 16) | ((e2 & 0xff) << 16) | (e2 & 0xff000000));
962 6dbad63e bellard
        sc->limit = (e1 & 0xffff) | (e2 & 0x000f0000);
963 6dbad63e bellard
        if (e2 & (1 << 23))
964 6dbad63e bellard
            sc->limit = (sc->limit << 12) | 0xfff;
965 6dbad63e bellard
        sc->seg_32bit = (e2 >> 22) & 1;
966 6dbad63e bellard
#if 0
967 6dbad63e bellard
        fprintf(logfile, "load_seg: sel=0x%04x base=0x%08lx limit=0x%08lx seg_32bit=%d\n", 
968 6dbad63e bellard
                selector, (unsigned long)sc->base, sc->limit, sc->seg_32bit);
969 6dbad63e bellard
#endif
970 6dbad63e bellard
    }
971 6dbad63e bellard
}
972 6dbad63e bellard
973 6dbad63e bellard
void OPPROTO op_movl_seg_T0(void)
974 6dbad63e bellard
{
975 6dbad63e bellard
    load_seg(PARAM1, T0 & 0xffff);
976 6dbad63e bellard
}
977 6dbad63e bellard
978 6dbad63e bellard
void OPPROTO op_movl_T0_seg(void)
979 6dbad63e bellard
{
980 6dbad63e bellard
    T0 = env->segs[PARAM1];
981 6dbad63e bellard
}
982 6dbad63e bellard
983 6dbad63e bellard
void OPPROTO op_addl_A0_seg(void)
984 6dbad63e bellard
{
985 6dbad63e bellard
    A0 += *(unsigned long *)((char *)env + PARAM1);
986 6dbad63e bellard
}
987 6dbad63e bellard
988 367e86e8 bellard
/* flags handling */
989 367e86e8 bellard
990 367e86e8 bellard
/* slow jumps cases (compute x86 flags) */
991 367e86e8 bellard
void OPPROTO op_jo_cc(void)
992 367e86e8 bellard
{
993 367e86e8 bellard
    int eflags;
994 367e86e8 bellard
    eflags = cc_table[CC_OP].compute_all();
995 367e86e8 bellard
    if (eflags & CC_O)
996 dab2ed99 bellard
        EIP = PARAM1;
997 367e86e8 bellard
    else
998 dab2ed99 bellard
        EIP = PARAM2;
999 0ecfa993 bellard
    FORCE_RET();
1000 367e86e8 bellard
}
1001 367e86e8 bellard
1002 367e86e8 bellard
void OPPROTO op_jb_cc(void)
1003 367e86e8 bellard
{
1004 367e86e8 bellard
    if (cc_table[CC_OP].compute_c())
1005 dab2ed99 bellard
        EIP = PARAM1;
1006 367e86e8 bellard
    else
1007 dab2ed99 bellard
        EIP = PARAM2;
1008 0ecfa993 bellard
    FORCE_RET();
1009 367e86e8 bellard
}
1010 367e86e8 bellard
1011 367e86e8 bellard
void OPPROTO op_jz_cc(void)
1012 367e86e8 bellard
{
1013 367e86e8 bellard
    int eflags;
1014 367e86e8 bellard
    eflags = cc_table[CC_OP].compute_all();
1015 367e86e8 bellard
    if (eflags & CC_Z)
1016 dab2ed99 bellard
        EIP = PARAM1;
1017 367e86e8 bellard
    else
1018 dab2ed99 bellard
        EIP = PARAM2;
1019 0ecfa993 bellard
    FORCE_RET();
1020 367e86e8 bellard
}
1021 367e86e8 bellard
1022 367e86e8 bellard
void OPPROTO op_jbe_cc(void)
1023 367e86e8 bellard
{
1024 367e86e8 bellard
    int eflags;
1025 367e86e8 bellard
    eflags = cc_table[CC_OP].compute_all();
1026 367e86e8 bellard
    if (eflags & (CC_Z | CC_C))
1027 dab2ed99 bellard
        EIP = PARAM1;
1028 367e86e8 bellard
    else
1029 dab2ed99 bellard
        EIP = PARAM2;
1030 0ecfa993 bellard
    FORCE_RET();
1031 367e86e8 bellard
}
1032 367e86e8 bellard
1033 367e86e8 bellard
void OPPROTO op_js_cc(void)
1034 367e86e8 bellard
{
1035 367e86e8 bellard
    int eflags;
1036 367e86e8 bellard
    eflags = cc_table[CC_OP].compute_all();
1037 367e86e8 bellard
    if (eflags & CC_S)
1038 dab2ed99 bellard
        EIP = PARAM1;
1039 367e86e8 bellard
    else
1040 dab2ed99 bellard
        EIP = PARAM2;
1041 0ecfa993 bellard
    FORCE_RET();
1042 367e86e8 bellard
}
1043 367e86e8 bellard
1044 367e86e8 bellard
void OPPROTO op_jp_cc(void)
1045 367e86e8 bellard
{
1046 367e86e8 bellard
    int eflags;
1047 367e86e8 bellard
    eflags = cc_table[CC_OP].compute_all();
1048 367e86e8 bellard
    if (eflags & CC_P)
1049 dab2ed99 bellard
        EIP = PARAM1;
1050 367e86e8 bellard
    else
1051 dab2ed99 bellard
        EIP = PARAM2;
1052 0ecfa993 bellard
    FORCE_RET();
1053 367e86e8 bellard
}
1054 367e86e8 bellard
1055 367e86e8 bellard
void OPPROTO op_jl_cc(void)
1056 367e86e8 bellard
{
1057 367e86e8 bellard
    int eflags;
1058 367e86e8 bellard
    eflags = cc_table[CC_OP].compute_all();
1059 367e86e8 bellard
    if ((eflags ^ (eflags >> 4)) & 0x80)
1060 dab2ed99 bellard
        EIP = PARAM1;
1061 367e86e8 bellard
    else
1062 dab2ed99 bellard
        EIP = PARAM2;
1063 0ecfa993 bellard
    FORCE_RET();
1064 367e86e8 bellard
}
1065 367e86e8 bellard
1066 367e86e8 bellard
void OPPROTO op_jle_cc(void)
1067 367e86e8 bellard
{
1068 367e86e8 bellard
    int eflags;
1069 367e86e8 bellard
    eflags = cc_table[CC_OP].compute_all();
1070 367e86e8 bellard
    if (((eflags ^ (eflags >> 4)) & 0x80) || (eflags & CC_Z))
1071 dab2ed99 bellard
        EIP = PARAM1;
1072 367e86e8 bellard
    else
1073 dab2ed99 bellard
        EIP = PARAM2;
1074 0ecfa993 bellard
    FORCE_RET();
1075 367e86e8 bellard
}
1076 367e86e8 bellard
1077 367e86e8 bellard
/* slow set cases (compute x86 flags) */
1078 367e86e8 bellard
void OPPROTO op_seto_T0_cc(void)
1079 367e86e8 bellard
{
1080 367e86e8 bellard
    int eflags;
1081 367e86e8 bellard
    eflags = cc_table[CC_OP].compute_all();
1082 367e86e8 bellard
    T0 = (eflags >> 11) & 1;
1083 367e86e8 bellard
}
1084 367e86e8 bellard
1085 367e86e8 bellard
void OPPROTO op_setb_T0_cc(void)
1086 367e86e8 bellard
{
1087 367e86e8 bellard
    T0 = cc_table[CC_OP].compute_c();
1088 367e86e8 bellard
}
1089 367e86e8 bellard
1090 367e86e8 bellard
void OPPROTO op_setz_T0_cc(void)
1091 367e86e8 bellard
{
1092 367e86e8 bellard
    int eflags;
1093 367e86e8 bellard
    eflags = cc_table[CC_OP].compute_all();
1094 367e86e8 bellard
    T0 = (eflags >> 6) & 1;
1095 367e86e8 bellard
}
1096 367e86e8 bellard
1097 367e86e8 bellard
void OPPROTO op_setbe_T0_cc(void)
1098 367e86e8 bellard
{
1099 367e86e8 bellard
    int eflags;
1100 367e86e8 bellard
    eflags = cc_table[CC_OP].compute_all();
1101 367e86e8 bellard
    T0 = (eflags & (CC_Z | CC_C)) != 0;
1102 367e86e8 bellard
}
1103 367e86e8 bellard
1104 367e86e8 bellard
void OPPROTO op_sets_T0_cc(void)
1105 367e86e8 bellard
{
1106 367e86e8 bellard
    int eflags;
1107 367e86e8 bellard
    eflags = cc_table[CC_OP].compute_all();
1108 367e86e8 bellard
    T0 = (eflags >> 7) & 1;
1109 367e86e8 bellard
}
1110 367e86e8 bellard
1111 367e86e8 bellard
void OPPROTO op_setp_T0_cc(void)
1112 367e86e8 bellard
{
1113 367e86e8 bellard
    int eflags;
1114 367e86e8 bellard
    eflags = cc_table[CC_OP].compute_all();
1115 367e86e8 bellard
    T0 = (eflags >> 2) & 1;
1116 367e86e8 bellard
}
1117 367e86e8 bellard
1118 367e86e8 bellard
void OPPROTO op_setl_T0_cc(void)
1119 367e86e8 bellard
{
1120 367e86e8 bellard
    int eflags;
1121 367e86e8 bellard
    eflags = cc_table[CC_OP].compute_all();
1122 367e86e8 bellard
    T0 = ((eflags ^ (eflags >> 4)) >> 7) & 1;
1123 367e86e8 bellard
}
1124 367e86e8 bellard
1125 367e86e8 bellard
void OPPROTO op_setle_T0_cc(void)
1126 367e86e8 bellard
{
1127 367e86e8 bellard
    int eflags;
1128 367e86e8 bellard
    eflags = cc_table[CC_OP].compute_all();
1129 367e86e8 bellard
    T0 = (((eflags ^ (eflags >> 4)) & 0x80) || (eflags & CC_Z)) != 0;
1130 367e86e8 bellard
}
1131 367e86e8 bellard
1132 367e86e8 bellard
void OPPROTO op_xor_T0_1(void)
1133 367e86e8 bellard
{
1134 367e86e8 bellard
    T0 ^= 1;
1135 367e86e8 bellard
}
1136 367e86e8 bellard
1137 367e86e8 bellard
void OPPROTO op_set_cc_op(void)
1138 367e86e8 bellard
{
1139 367e86e8 bellard
    CC_OP = PARAM1;
1140 367e86e8 bellard
}
1141 367e86e8 bellard
1142 367e86e8 bellard
void OPPROTO op_movl_eflags_T0(void)
1143 367e86e8 bellard
{
1144 367e86e8 bellard
    CC_SRC = T0;
1145 367e86e8 bellard
    DF = 1 - (2 * ((T0 >> 10) & 1));
1146 367e86e8 bellard
}
1147 367e86e8 bellard
1148 367e86e8 bellard
/* XXX: compute only O flag */
1149 367e86e8 bellard
void OPPROTO op_movb_eflags_T0(void)
1150 367e86e8 bellard
{
1151 367e86e8 bellard
    int of;
1152 367e86e8 bellard
    of = cc_table[CC_OP].compute_all() & CC_O;
1153 367e86e8 bellard
    CC_SRC = T0 | of;
1154 367e86e8 bellard
}
1155 367e86e8 bellard
1156 367e86e8 bellard
void OPPROTO op_movl_T0_eflags(void)
1157 367e86e8 bellard
{
1158 367e86e8 bellard
    T0 = cc_table[CC_OP].compute_all();
1159 367e86e8 bellard
    T0 |= (DF & DIRECTION_FLAG);
1160 367e86e8 bellard
}
1161 367e86e8 bellard
1162 367e86e8 bellard
void OPPROTO op_cld(void)
1163 367e86e8 bellard
{
1164 367e86e8 bellard
    DF = 1;
1165 367e86e8 bellard
}
1166 367e86e8 bellard
1167 367e86e8 bellard
void OPPROTO op_std(void)
1168 367e86e8 bellard
{
1169 367e86e8 bellard
    DF = -1;
1170 367e86e8 bellard
}
1171 367e86e8 bellard
1172 367e86e8 bellard
void OPPROTO op_clc(void)
1173 367e86e8 bellard
{
1174 367e86e8 bellard
    int eflags;
1175 367e86e8 bellard
    eflags = cc_table[CC_OP].compute_all();
1176 367e86e8 bellard
    eflags &= ~CC_C;
1177 367e86e8 bellard
    CC_SRC = eflags;
1178 367e86e8 bellard
}
1179 367e86e8 bellard
1180 367e86e8 bellard
void OPPROTO op_stc(void)
1181 367e86e8 bellard
{
1182 367e86e8 bellard
    int eflags;
1183 367e86e8 bellard
    eflags = cc_table[CC_OP].compute_all();
1184 367e86e8 bellard
    eflags |= CC_C;
1185 367e86e8 bellard
    CC_SRC = eflags;
1186 367e86e8 bellard
}
1187 367e86e8 bellard
1188 367e86e8 bellard
void OPPROTO op_cmc(void)
1189 367e86e8 bellard
{
1190 367e86e8 bellard
    int eflags;
1191 367e86e8 bellard
    eflags = cc_table[CC_OP].compute_all();
1192 367e86e8 bellard
    eflags ^= CC_C;
1193 367e86e8 bellard
    CC_SRC = eflags;
1194 367e86e8 bellard
}
1195 367e86e8 bellard
1196 27362c82 bellard
void OPPROTO op_salc(void)
1197 27362c82 bellard
{
1198 27362c82 bellard
    int cf;
1199 27362c82 bellard
    cf = cc_table[CC_OP].compute_c();
1200 27362c82 bellard
    EAX = (EAX & ~0xff) | ((-cf) & 0xff);
1201 27362c82 bellard
}
1202 27362c82 bellard
1203 367e86e8 bellard
static int compute_all_eflags(void)
1204 367e86e8 bellard
{
1205 367e86e8 bellard
    return CC_SRC;
1206 367e86e8 bellard
}
1207 367e86e8 bellard
1208 367e86e8 bellard
static int compute_c_eflags(void)
1209 367e86e8 bellard
{
1210 367e86e8 bellard
    return CC_SRC & CC_C;
1211 367e86e8 bellard
}
1212 367e86e8 bellard
1213 367e86e8 bellard
static int compute_c_mul(void)
1214 367e86e8 bellard
{
1215 367e86e8 bellard
    int cf;
1216 367e86e8 bellard
    cf = (CC_SRC != 0);
1217 367e86e8 bellard
    return cf;
1218 367e86e8 bellard
}
1219 367e86e8 bellard
1220 367e86e8 bellard
static int compute_all_mul(void)
1221 367e86e8 bellard
{
1222 367e86e8 bellard
    int cf, pf, af, zf, sf, of;
1223 367e86e8 bellard
    cf = (CC_SRC != 0);
1224 367e86e8 bellard
    pf = 0; /* undefined */
1225 367e86e8 bellard
    af = 0; /* undefined */
1226 367e86e8 bellard
    zf = 0; /* undefined */
1227 367e86e8 bellard
    sf = 0; /* undefined */
1228 367e86e8 bellard
    of = cf << 11;
1229 367e86e8 bellard
    return cf | pf | af | zf | sf | of;
1230 367e86e8 bellard
}
1231 367e86e8 bellard
    
1232 367e86e8 bellard
CCTable cc_table[CC_OP_NB] = {
1233 367e86e8 bellard
    [CC_OP_DYNAMIC] = { /* should never happen */ },
1234 367e86e8 bellard
1235 367e86e8 bellard
    [CC_OP_EFLAGS] = { compute_all_eflags, compute_c_eflags },
1236 367e86e8 bellard
1237 367e86e8 bellard
    [CC_OP_MUL] = { compute_all_mul, compute_c_mul },
1238 367e86e8 bellard
1239 367e86e8 bellard
    [CC_OP_ADDB] = { compute_all_addb, compute_c_addb },
1240 367e86e8 bellard
    [CC_OP_ADDW] = { compute_all_addw, compute_c_addw  },
1241 367e86e8 bellard
    [CC_OP_ADDL] = { compute_all_addl, compute_c_addl  },
1242 367e86e8 bellard
1243 4b74fe1f bellard
    [CC_OP_ADCB] = { compute_all_adcb, compute_c_adcb },
1244 4b74fe1f bellard
    [CC_OP_ADCW] = { compute_all_adcw, compute_c_adcw  },
1245 4b74fe1f bellard
    [CC_OP_ADCL] = { compute_all_adcl, compute_c_adcl  },
1246 4b74fe1f bellard
1247 367e86e8 bellard
    [CC_OP_SUBB] = { compute_all_subb, compute_c_subb  },
1248 367e86e8 bellard
    [CC_OP_SUBW] = { compute_all_subw, compute_c_subw  },
1249 367e86e8 bellard
    [CC_OP_SUBL] = { compute_all_subl, compute_c_subl  },
1250 367e86e8 bellard
    
1251 4b74fe1f bellard
    [CC_OP_SBBB] = { compute_all_sbbb, compute_c_sbbb  },
1252 4b74fe1f bellard
    [CC_OP_SBBW] = { compute_all_sbbw, compute_c_sbbw  },
1253 4b74fe1f bellard
    [CC_OP_SBBL] = { compute_all_sbbl, compute_c_sbbl  },
1254 4b74fe1f bellard
    
1255 367e86e8 bellard
    [CC_OP_LOGICB] = { compute_all_logicb, compute_c_logicb },
1256 367e86e8 bellard
    [CC_OP_LOGICW] = { compute_all_logicw, compute_c_logicw },
1257 367e86e8 bellard
    [CC_OP_LOGICL] = { compute_all_logicl, compute_c_logicl },
1258 367e86e8 bellard
    
1259 4b74fe1f bellard
    [CC_OP_INCB] = { compute_all_incb, compute_c_incl },
1260 4b74fe1f bellard
    [CC_OP_INCW] = { compute_all_incw, compute_c_incl },
1261 367e86e8 bellard
    [CC_OP_INCL] = { compute_all_incl, compute_c_incl },
1262 367e86e8 bellard
    
1263 4b74fe1f bellard
    [CC_OP_DECB] = { compute_all_decb, compute_c_incl },
1264 4b74fe1f bellard
    [CC_OP_DECW] = { compute_all_decw, compute_c_incl },
1265 367e86e8 bellard
    [CC_OP_DECL] = { compute_all_decl, compute_c_incl },
1266 367e86e8 bellard
    
1267 4b74fe1f bellard
    [CC_OP_SHLB] = { compute_all_shlb, compute_c_shll },
1268 4b74fe1f bellard
    [CC_OP_SHLW] = { compute_all_shlw, compute_c_shll },
1269 367e86e8 bellard
    [CC_OP_SHLL] = { compute_all_shll, compute_c_shll },
1270 4b74fe1f bellard
1271 4b74fe1f bellard
    [CC_OP_SARB] = { compute_all_sarb, compute_c_shll },
1272 4b74fe1f bellard
    [CC_OP_SARW] = { compute_all_sarw, compute_c_shll },
1273 4b74fe1f bellard
    [CC_OP_SARL] = { compute_all_sarl, compute_c_shll },
1274 367e86e8 bellard
};
1275 927f621e bellard
1276 927f621e bellard
/* floating point support */
1277 927f621e bellard
1278 927f621e bellard
#ifdef USE_X86LDOUBLE
1279 927f621e bellard
/* use long double functions */
1280 927f621e bellard
#define lrint lrintl
1281 927f621e bellard
#define llrint llrintl
1282 927f621e bellard
#define fabs fabsl
1283 927f621e bellard
#define sin sinl
1284 927f621e bellard
#define cos cosl
1285 927f621e bellard
#define sqrt sqrtl
1286 927f621e bellard
#define pow powl
1287 927f621e bellard
#define log logl
1288 927f621e bellard
#define tan tanl
1289 927f621e bellard
#define atan2 atan2l
1290 927f621e bellard
#define floor floorl
1291 927f621e bellard
#define ceil ceill
1292 927f621e bellard
#define rint rintl
1293 927f621e bellard
#endif
1294 927f621e bellard
1295 927f621e bellard
extern int lrint(CPU86_LDouble x);
1296 927f621e bellard
extern int64_t llrint(CPU86_LDouble x);
1297 927f621e bellard
extern CPU86_LDouble fabs(CPU86_LDouble x);
1298 927f621e bellard
extern CPU86_LDouble sin(CPU86_LDouble x);
1299 927f621e bellard
extern CPU86_LDouble cos(CPU86_LDouble x);
1300 927f621e bellard
extern CPU86_LDouble sqrt(CPU86_LDouble x);
1301 927f621e bellard
extern CPU86_LDouble pow(CPU86_LDouble, CPU86_LDouble);
1302 927f621e bellard
extern CPU86_LDouble log(CPU86_LDouble x);
1303 927f621e bellard
extern CPU86_LDouble tan(CPU86_LDouble x);
1304 927f621e bellard
extern CPU86_LDouble atan2(CPU86_LDouble, CPU86_LDouble);
1305 927f621e bellard
extern CPU86_LDouble floor(CPU86_LDouble x);
1306 927f621e bellard
extern CPU86_LDouble ceil(CPU86_LDouble x);
1307 927f621e bellard
extern CPU86_LDouble rint(CPU86_LDouble x);
1308 927f621e bellard
1309 927f621e bellard
#define RC_MASK         0xc00
1310 927f621e bellard
#define RC_NEAR                0x000
1311 927f621e bellard
#define RC_DOWN                0x400
1312 927f621e bellard
#define RC_UP                0x800
1313 927f621e bellard
#define RC_CHOP                0xc00
1314 927f621e bellard
1315 927f621e bellard
#define MAXTAN 9223372036854775808.0
1316 927f621e bellard
1317 927f621e bellard
#ifdef USE_X86LDOUBLE
1318 927f621e bellard
1319 927f621e bellard
/* only for x86 */
1320 927f621e bellard
typedef union {
1321 927f621e bellard
    long double d;
1322 927f621e bellard
    struct {
1323 927f621e bellard
        unsigned long long lower;
1324 927f621e bellard
        unsigned short upper;
1325 927f621e bellard
    } l;
1326 927f621e bellard
} CPU86_LDoubleU;
1327 927f621e bellard
1328 927f621e bellard
/* the following deal with x86 long double-precision numbers */
1329 927f621e bellard
#define MAXEXPD 0x7fff
1330 927f621e bellard
#define EXPBIAS 16383
1331 927f621e bellard
#define EXPD(fp)        (fp.l.upper & 0x7fff)
1332 927f621e bellard
#define SIGND(fp)        ((fp.l.upper) & 0x8000)
1333 927f621e bellard
#define MANTD(fp)       (fp.l.lower)
1334 927f621e bellard
#define BIASEXPONENT(fp) fp.l.upper = (fp.l.upper & ~(0x7fff)) | EXPBIAS
1335 927f621e bellard
1336 927f621e bellard
#else
1337 927f621e bellard
1338 77f8dd5a bellard
typedef union {
1339 927f621e bellard
    double d;
1340 927f621e bellard
#ifndef WORDS_BIGENDIAN
1341 927f621e bellard
    struct {
1342 927f621e bellard
        unsigned long lower;
1343 927f621e bellard
        long upper;
1344 927f621e bellard
    } l;
1345 927f621e bellard
#else
1346 927f621e bellard
    struct {
1347 927f621e bellard
        long upper;
1348 927f621e bellard
        unsigned long lower;
1349 927f621e bellard
    } l;
1350 927f621e bellard
#endif
1351 927f621e bellard
    long long ll;
1352 927f621e bellard
} CPU86_LDoubleU;
1353 927f621e bellard
1354 927f621e bellard
/* the following deal with IEEE double-precision numbers */
1355 927f621e bellard
#define MAXEXPD 0x7ff
1356 927f621e bellard
#define EXPBIAS 1023
1357 927f621e bellard
#define EXPD(fp)        (((fp.l.upper) >> 20) & 0x7FF)
1358 927f621e bellard
#define SIGND(fp)        ((fp.l.upper) & 0x80000000)
1359 927f621e bellard
#define MANTD(fp)        (fp.ll & ((1LL << 52) - 1))
1360 927f621e bellard
#define BIASEXPONENT(fp) fp.l.upper = (fp.l.upper & ~(0x7ff << 20)) | (EXPBIAS << 20)
1361 927f621e bellard
#endif
1362 927f621e bellard
1363 927f621e bellard
/* fp load FT0 */
1364 927f621e bellard
1365 927f621e bellard
void OPPROTO op_flds_FT0_A0(void)
1366 927f621e bellard
{
1367 927f621e bellard
    FT0 = ldfl((void *)A0);
1368 927f621e bellard
}
1369 927f621e bellard
1370 927f621e bellard
void OPPROTO op_fldl_FT0_A0(void)
1371 927f621e bellard
{
1372 927f621e bellard
    FT0 = ldfq((void *)A0);
1373 927f621e bellard
}
1374 927f621e bellard
1375 04369ff2 bellard
/* helpers are needed to avoid static constant reference. XXX: find a better way */
1376 04369ff2 bellard
#ifdef USE_INT_TO_FLOAT_HELPERS
1377 04369ff2 bellard
1378 04369ff2 bellard
void helper_fild_FT0_A0(void)
1379 04369ff2 bellard
{
1380 04369ff2 bellard
    FT0 = (CPU86_LDouble)ldsw((void *)A0);
1381 04369ff2 bellard
}
1382 04369ff2 bellard
1383 04369ff2 bellard
void helper_fildl_FT0_A0(void)
1384 04369ff2 bellard
{
1385 04369ff2 bellard
    FT0 = (CPU86_LDouble)((int32_t)ldl((void *)A0));
1386 04369ff2 bellard
}
1387 04369ff2 bellard
1388 04369ff2 bellard
void helper_fildll_FT0_A0(void)
1389 04369ff2 bellard
{
1390 04369ff2 bellard
    FT0 = (CPU86_LDouble)((int64_t)ldq((void *)A0));
1391 04369ff2 bellard
}
1392 04369ff2 bellard
1393 04369ff2 bellard
void OPPROTO op_fild_FT0_A0(void)
1394 04369ff2 bellard
{
1395 04369ff2 bellard
    helper_fild_FT0_A0();
1396 04369ff2 bellard
}
1397 04369ff2 bellard
1398 04369ff2 bellard
void OPPROTO op_fildl_FT0_A0(void)
1399 04369ff2 bellard
{
1400 04369ff2 bellard
    helper_fildl_FT0_A0();
1401 04369ff2 bellard
}
1402 04369ff2 bellard
1403 04369ff2 bellard
void OPPROTO op_fildll_FT0_A0(void)
1404 04369ff2 bellard
{
1405 04369ff2 bellard
    helper_fildll_FT0_A0();
1406 04369ff2 bellard
}
1407 04369ff2 bellard
1408 04369ff2 bellard
#else
1409 04369ff2 bellard
1410 927f621e bellard
void OPPROTO op_fild_FT0_A0(void)
1411 927f621e bellard
{
1412 927f621e bellard
    FT0 = (CPU86_LDouble)ldsw((void *)A0);
1413 927f621e bellard
}
1414 927f621e bellard
1415 927f621e bellard
void OPPROTO op_fildl_FT0_A0(void)
1416 927f621e bellard
{
1417 927f621e bellard
    FT0 = (CPU86_LDouble)((int32_t)ldl((void *)A0));
1418 927f621e bellard
}
1419 927f621e bellard
1420 927f621e bellard
void OPPROTO op_fildll_FT0_A0(void)
1421 927f621e bellard
{
1422 927f621e bellard
    FT0 = (CPU86_LDouble)((int64_t)ldq((void *)A0));
1423 927f621e bellard
}
1424 04369ff2 bellard
#endif
1425 927f621e bellard
1426 927f621e bellard
/* fp load ST0 */
1427 927f621e bellard
1428 927f621e bellard
void OPPROTO op_flds_ST0_A0(void)
1429 927f621e bellard
{
1430 927f621e bellard
    ST0 = ldfl((void *)A0);
1431 927f621e bellard
}
1432 927f621e bellard
1433 927f621e bellard
void OPPROTO op_fldl_ST0_A0(void)
1434 927f621e bellard
{
1435 927f621e bellard
    ST0 = ldfq((void *)A0);
1436 927f621e bellard
}
1437 927f621e bellard
1438 77f8dd5a bellard
#ifdef USE_X86LDOUBLE
1439 77f8dd5a bellard
void OPPROTO op_fldt_ST0_A0(void)
1440 77f8dd5a bellard
{
1441 77f8dd5a bellard
    ST0 = *(long double *)A0;
1442 77f8dd5a bellard
}
1443 77f8dd5a bellard
#else
1444 77f8dd5a bellard
void helper_fldt_ST0_A0(void)
1445 77f8dd5a bellard
{
1446 77f8dd5a bellard
    CPU86_LDoubleU temp;
1447 77f8dd5a bellard
    int upper, e;
1448 77f8dd5a bellard
    /* mantissa */
1449 77f8dd5a bellard
    upper = lduw((uint8_t *)A0 + 8);
1450 77f8dd5a bellard
    /* XXX: handle overflow ? */
1451 77f8dd5a bellard
    e = (upper & 0x7fff) - 16383 + EXPBIAS; /* exponent */
1452 77f8dd5a bellard
    e |= (upper >> 4) & 0x800; /* sign */
1453 77f8dd5a bellard
    temp.ll = ((ldq((void *)A0) >> 11) & ((1LL << 52) - 1)) | ((uint64_t)e << 52);
1454 77f8dd5a bellard
    ST0 = temp.d;
1455 77f8dd5a bellard
}
1456 77f8dd5a bellard
1457 77f8dd5a bellard
void OPPROTO op_fldt_ST0_A0(void)
1458 77f8dd5a bellard
{
1459 77f8dd5a bellard
    helper_fldt_ST0_A0();
1460 77f8dd5a bellard
}
1461 77f8dd5a bellard
#endif
1462 77f8dd5a bellard
1463 04369ff2 bellard
/* helpers are needed to avoid static constant reference. XXX: find a better way */
1464 04369ff2 bellard
#ifdef USE_INT_TO_FLOAT_HELPERS
1465 04369ff2 bellard
1466 04369ff2 bellard
void helper_fild_ST0_A0(void)
1467 04369ff2 bellard
{
1468 04369ff2 bellard
    ST0 = (CPU86_LDouble)ldsw((void *)A0);
1469 04369ff2 bellard
}
1470 04369ff2 bellard
1471 04369ff2 bellard
void helper_fildl_ST0_A0(void)
1472 04369ff2 bellard
{
1473 04369ff2 bellard
    ST0 = (CPU86_LDouble)((int32_t)ldl((void *)A0));
1474 04369ff2 bellard
}
1475 04369ff2 bellard
1476 04369ff2 bellard
void helper_fildll_ST0_A0(void)
1477 04369ff2 bellard
{
1478 04369ff2 bellard
    ST0 = (CPU86_LDouble)((int64_t)ldq((void *)A0));
1479 04369ff2 bellard
}
1480 04369ff2 bellard
1481 04369ff2 bellard
void OPPROTO op_fild_ST0_A0(void)
1482 04369ff2 bellard
{
1483 04369ff2 bellard
    helper_fild_ST0_A0();
1484 04369ff2 bellard
}
1485 04369ff2 bellard
1486 04369ff2 bellard
void OPPROTO op_fildl_ST0_A0(void)
1487 04369ff2 bellard
{
1488 04369ff2 bellard
    helper_fildl_ST0_A0();
1489 04369ff2 bellard
}
1490 04369ff2 bellard
1491 04369ff2 bellard
void OPPROTO op_fildll_ST0_A0(void)
1492 04369ff2 bellard
{
1493 04369ff2 bellard
    helper_fildll_ST0_A0();
1494 04369ff2 bellard
}
1495 04369ff2 bellard
1496 04369ff2 bellard
#else
1497 04369ff2 bellard
1498 927f621e bellard
void OPPROTO op_fild_ST0_A0(void)
1499 927f621e bellard
{
1500 927f621e bellard
    ST0 = (CPU86_LDouble)ldsw((void *)A0);
1501 927f621e bellard
}
1502 927f621e bellard
1503 927f621e bellard
void OPPROTO op_fildl_ST0_A0(void)
1504 927f621e bellard
{
1505 927f621e bellard
    ST0 = (CPU86_LDouble)((int32_t)ldl((void *)A0));
1506 927f621e bellard
}
1507 927f621e bellard
1508 927f621e bellard
void OPPROTO op_fildll_ST0_A0(void)
1509 927f621e bellard
{
1510 927f621e bellard
    ST0 = (CPU86_LDouble)((int64_t)ldq((void *)A0));
1511 927f621e bellard
}
1512 927f621e bellard
1513 04369ff2 bellard
#endif
1514 04369ff2 bellard
1515 927f621e bellard
/* fp store */
1516 927f621e bellard
1517 927f621e bellard
void OPPROTO op_fsts_ST0_A0(void)
1518 927f621e bellard
{
1519 927f621e bellard
    stfl((void *)A0, (float)ST0);
1520 927f621e bellard
}
1521 927f621e bellard
1522 927f621e bellard
void OPPROTO op_fstl_ST0_A0(void)
1523 927f621e bellard
{
1524 77f8dd5a bellard
    stfq((void *)A0, (double)ST0);
1525 927f621e bellard
}
1526 927f621e bellard
1527 77f8dd5a bellard
#ifdef USE_X86LDOUBLE
1528 77f8dd5a bellard
void OPPROTO op_fstt_ST0_A0(void)
1529 77f8dd5a bellard
{
1530 77f8dd5a bellard
    *(long double *)A0 = ST0;
1531 77f8dd5a bellard
}
1532 77f8dd5a bellard
#else
1533 77f8dd5a bellard
void helper_fstt_ST0_A0(void)
1534 77f8dd5a bellard
{
1535 77f8dd5a bellard
    CPU86_LDoubleU temp;
1536 77f8dd5a bellard
    int e;
1537 77f8dd5a bellard
    temp.d = ST0;
1538 77f8dd5a bellard
    /* mantissa */
1539 77f8dd5a bellard
    stq((void *)A0, (MANTD(temp) << 11) | (1LL << 63));
1540 77f8dd5a bellard
    /* exponent + sign */
1541 77f8dd5a bellard
    e = EXPD(temp) - EXPBIAS + 16383;
1542 77f8dd5a bellard
    e |= SIGND(temp) >> 16;
1543 77f8dd5a bellard
    stw((uint8_t *)A0 + 8, e);
1544 77f8dd5a bellard
}
1545 77f8dd5a bellard
1546 77f8dd5a bellard
void OPPROTO op_fstt_ST0_A0(void)
1547 77f8dd5a bellard
{
1548 77f8dd5a bellard
    helper_fstt_ST0_A0();
1549 77f8dd5a bellard
}
1550 77f8dd5a bellard
#endif
1551 77f8dd5a bellard
1552 927f621e bellard
void OPPROTO op_fist_ST0_A0(void)
1553 927f621e bellard
{
1554 927f621e bellard
    int val;
1555 927f621e bellard
    val = lrint(ST0);
1556 927f621e bellard
    stw((void *)A0, val);
1557 927f621e bellard
}
1558 927f621e bellard
1559 927f621e bellard
void OPPROTO op_fistl_ST0_A0(void)
1560 927f621e bellard
{
1561 927f621e bellard
    int val;
1562 927f621e bellard
    val = lrint(ST0);
1563 927f621e bellard
    stl((void *)A0, val);
1564 927f621e bellard
}
1565 927f621e bellard
1566 927f621e bellard
void OPPROTO op_fistll_ST0_A0(void)
1567 927f621e bellard
{
1568 927f621e bellard
    int64_t val;
1569 927f621e bellard
    val = llrint(ST0);
1570 927f621e bellard
    stq((void *)A0, val);
1571 927f621e bellard
}
1572 927f621e bellard
1573 77f8dd5a bellard
/* BCD ops */
1574 77f8dd5a bellard
1575 77f8dd5a bellard
#define MUL10(iv) ( iv + iv + (iv << 3) )
1576 77f8dd5a bellard
1577 77f8dd5a bellard
void helper_fbld_ST0_A0(void)
1578 77f8dd5a bellard
{
1579 77f8dd5a bellard
    uint8_t *seg;
1580 77f8dd5a bellard
    CPU86_LDouble fpsrcop;
1581 77f8dd5a bellard
    int m32i;
1582 77f8dd5a bellard
    unsigned int v;
1583 77f8dd5a bellard
1584 77f8dd5a bellard
    /* in this code, seg/m32i will be used as temporary ptr/int */
1585 77f8dd5a bellard
    seg = (uint8_t *)A0 + 8;
1586 77f8dd5a bellard
    v = ldub(seg--);
1587 77f8dd5a bellard
    /* XXX: raise exception */
1588 77f8dd5a bellard
    if (v != 0)
1589 77f8dd5a bellard
        return;
1590 77f8dd5a bellard
    v = ldub(seg--);
1591 77f8dd5a bellard
    /* XXX: raise exception */
1592 77f8dd5a bellard
    if ((v & 0xf0) != 0)
1593 77f8dd5a bellard
        return;
1594 77f8dd5a bellard
    m32i = v;  /* <-- d14 */
1595 77f8dd5a bellard
    v = ldub(seg--);
1596 77f8dd5a bellard
    m32i = MUL10(m32i) + (v >> 4);  /* <-- val * 10 + d13 */
1597 77f8dd5a bellard
    m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d12 */
1598 77f8dd5a bellard
    v = ldub(seg--);
1599 77f8dd5a bellard
    m32i = MUL10(m32i) + (v >> 4);  /* <-- val * 10 + d11 */
1600 77f8dd5a bellard
    m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d10 */
1601 77f8dd5a bellard
    v = ldub(seg--);
1602 77f8dd5a bellard
    m32i = MUL10(m32i) + (v >> 4);  /* <-- val * 10 + d9 */
1603 77f8dd5a bellard
    m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d8 */
1604 77f8dd5a bellard
    fpsrcop = ((CPU86_LDouble)m32i) * 100000000.0;
1605 77f8dd5a bellard
1606 77f8dd5a bellard
    v = ldub(seg--);
1607 77f8dd5a bellard
    m32i = (v >> 4);  /* <-- d7 */
1608 77f8dd5a bellard
    m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d6 */
1609 77f8dd5a bellard
    v = ldub(seg--);
1610 77f8dd5a bellard
    m32i = MUL10(m32i) + (v >> 4);  /* <-- val * 10 + d5 */
1611 77f8dd5a bellard
    m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d4 */
1612 77f8dd5a bellard
    v = ldub(seg--);
1613 77f8dd5a bellard
    m32i = MUL10(m32i) + (v >> 4);  /* <-- val * 10 + d3 */
1614 77f8dd5a bellard
    m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d2 */
1615 77f8dd5a bellard
    v = ldub(seg);
1616 77f8dd5a bellard
    m32i = MUL10(m32i) + (v >> 4);  /* <-- val * 10 + d1 */
1617 77f8dd5a bellard
    m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d0 */
1618 77f8dd5a bellard
    fpsrcop += ((CPU86_LDouble)m32i);
1619 77f8dd5a bellard
    if ( ldub(seg+9) & 0x80 )
1620 77f8dd5a bellard
        fpsrcop = -fpsrcop;
1621 77f8dd5a bellard
    ST0 = fpsrcop;
1622 77f8dd5a bellard
}
1623 77f8dd5a bellard
1624 77f8dd5a bellard
void OPPROTO op_fbld_ST0_A0(void)
1625 77f8dd5a bellard
{
1626 77f8dd5a bellard
    helper_fbld_ST0_A0();
1627 77f8dd5a bellard
}
1628 77f8dd5a bellard
1629 77f8dd5a bellard
void helper_fbst_ST0_A0(void)
1630 77f8dd5a bellard
{
1631 77f8dd5a bellard
    CPU86_LDouble fptemp;
1632 77f8dd5a bellard
    CPU86_LDouble fpsrcop;
1633 77f8dd5a bellard
    int v;
1634 77f8dd5a bellard
    uint8_t *mem_ref, *mem_end;
1635 77f8dd5a bellard
1636 77f8dd5a bellard
    fpsrcop = rint(ST0);
1637 77f8dd5a bellard
    mem_ref = (uint8_t *)A0;
1638 77f8dd5a bellard
    mem_end = mem_ref + 8;
1639 77f8dd5a bellard
    if ( fpsrcop < 0.0 ) {
1640 77f8dd5a bellard
        stw(mem_end, 0x8000);
1641 77f8dd5a bellard
        fpsrcop = -fpsrcop;
1642 77f8dd5a bellard
    } else {
1643 77f8dd5a bellard
        stw(mem_end, 0x0000);
1644 77f8dd5a bellard
    }
1645 77f8dd5a bellard
    while (mem_ref < mem_end) {
1646 77f8dd5a bellard
        if (fpsrcop == 0.0)
1647 77f8dd5a bellard
            break;
1648 77f8dd5a bellard
        fptemp = floor(fpsrcop/10.0);
1649 77f8dd5a bellard
        v = ((int)(fpsrcop - fptemp*10.0));
1650 77f8dd5a bellard
        if  (fptemp == 0.0)  { 
1651 77f8dd5a bellard
            stb(mem_ref++, v); 
1652 77f8dd5a bellard
            break; 
1653 77f8dd5a bellard
        }
1654 77f8dd5a bellard
        fpsrcop = fptemp;
1655 77f8dd5a bellard
        fptemp = floor(fpsrcop/10.0);
1656 77f8dd5a bellard
        v |= (((int)(fpsrcop - fptemp*10.0)) << 4);
1657 77f8dd5a bellard
        stb(mem_ref++, v);
1658 77f8dd5a bellard
        fpsrcop = fptemp;
1659 77f8dd5a bellard
    }
1660 77f8dd5a bellard
    while (mem_ref < mem_end) {
1661 77f8dd5a bellard
        stb(mem_ref++, 0);
1662 77f8dd5a bellard
    }
1663 77f8dd5a bellard
}
1664 77f8dd5a bellard
1665 77f8dd5a bellard
void OPPROTO op_fbst_ST0_A0(void)
1666 77f8dd5a bellard
{
1667 77f8dd5a bellard
    helper_fbst_ST0_A0();
1668 77f8dd5a bellard
}
1669 77f8dd5a bellard
1670 927f621e bellard
/* FPU move */
1671 927f621e bellard
1672 927f621e bellard
static inline void fpush(void)
1673 927f621e bellard
{
1674 927f621e bellard
    env->fpstt = (env->fpstt - 1) & 7;
1675 927f621e bellard
    env->fptags[env->fpstt] = 0; /* validate stack entry */
1676 927f621e bellard
}
1677 927f621e bellard
1678 927f621e bellard
static inline void fpop(void)
1679 927f621e bellard
{
1680 927f621e bellard
    env->fptags[env->fpstt] = 1; /* invvalidate stack entry */
1681 927f621e bellard
    env->fpstt = (env->fpstt + 1) & 7;
1682 927f621e bellard
}
1683 927f621e bellard
1684 927f621e bellard
void OPPROTO op_fpush(void)
1685 927f621e bellard
{
1686 927f621e bellard
    fpush();
1687 927f621e bellard
}
1688 927f621e bellard
1689 927f621e bellard
void OPPROTO op_fpop(void)
1690 927f621e bellard
{
1691 927f621e bellard
    fpop();
1692 927f621e bellard
}
1693 927f621e bellard
1694 927f621e bellard
void OPPROTO op_fdecstp(void)
1695 927f621e bellard
{
1696 927f621e bellard
    env->fpstt = (env->fpstt - 1) & 7;
1697 927f621e bellard
    env->fpus &= (~0x4700);
1698 927f621e bellard
}
1699 927f621e bellard
1700 927f621e bellard
void OPPROTO op_fincstp(void)
1701 927f621e bellard
{
1702 927f621e bellard
    env->fpstt = (env->fpstt + 1) & 7;
1703 927f621e bellard
    env->fpus &= (~0x4700);
1704 927f621e bellard
}
1705 927f621e bellard
1706 927f621e bellard
void OPPROTO op_fmov_ST0_FT0(void)
1707 927f621e bellard
{
1708 927f621e bellard
    ST0 = FT0;
1709 927f621e bellard
}
1710 927f621e bellard
1711 927f621e bellard
void OPPROTO op_fmov_FT0_STN(void)
1712 927f621e bellard
{
1713 927f621e bellard
    FT0 = ST(PARAM1);
1714 927f621e bellard
}
1715 927f621e bellard
1716 927f621e bellard
void OPPROTO op_fmov_ST0_STN(void)
1717 927f621e bellard
{
1718 927f621e bellard
    ST0 = ST(PARAM1);
1719 927f621e bellard
}
1720 927f621e bellard
1721 927f621e bellard
void OPPROTO op_fmov_STN_ST0(void)
1722 927f621e bellard
{
1723 927f621e bellard
    ST(PARAM1) = ST0;
1724 927f621e bellard
}
1725 927f621e bellard
1726 927f621e bellard
void OPPROTO op_fxchg_ST0_STN(void)
1727 927f621e bellard
{
1728 927f621e bellard
    CPU86_LDouble tmp;
1729 927f621e bellard
    tmp = ST(PARAM1);
1730 927f621e bellard
    ST(PARAM1) = ST0;
1731 927f621e bellard
    ST0 = tmp;
1732 927f621e bellard
}
1733 927f621e bellard
1734 927f621e bellard
/* FPU operations */
1735 927f621e bellard
1736 927f621e bellard
/* XXX: handle nans */
1737 927f621e bellard
void OPPROTO op_fcom_ST0_FT0(void)
1738 927f621e bellard
{
1739 927f621e bellard
    env->fpus &= (~0x4500);        /* (C3,C2,C0) <-- 000 */
1740 927f621e bellard
    if (ST0 < FT0)
1741 927f621e bellard
        env->fpus |= 0x100;        /* (C3,C2,C0) <-- 001 */
1742 927f621e bellard
    else if (ST0 == FT0)
1743 927f621e bellard
        env->fpus |= 0x4000; /* (C3,C2,C0) <-- 100 */
1744 927f621e bellard
    FORCE_RET();
1745 927f621e bellard
}
1746 927f621e bellard
1747 77f8dd5a bellard
/* XXX: handle nans */
1748 77f8dd5a bellard
void OPPROTO op_fucom_ST0_FT0(void)
1749 77f8dd5a bellard
{
1750 77f8dd5a bellard
    env->fpus &= (~0x4500);        /* (C3,C2,C0) <-- 000 */
1751 77f8dd5a bellard
    if (ST0 < FT0)
1752 77f8dd5a bellard
        env->fpus |= 0x100;        /* (C3,C2,C0) <-- 001 */
1753 77f8dd5a bellard
    else if (ST0 == FT0)
1754 77f8dd5a bellard
        env->fpus |= 0x4000; /* (C3,C2,C0) <-- 100 */
1755 77f8dd5a bellard
    FORCE_RET();
1756 77f8dd5a bellard
}
1757 77f8dd5a bellard
1758 927f621e bellard
void OPPROTO op_fadd_ST0_FT0(void)
1759 927f621e bellard
{
1760 927f621e bellard
    ST0 += FT0;
1761 927f621e bellard
}
1762 927f621e bellard
1763 927f621e bellard
void OPPROTO op_fmul_ST0_FT0(void)
1764 927f621e bellard
{
1765 927f621e bellard
    ST0 *= FT0;
1766 927f621e bellard
}
1767 927f621e bellard
1768 927f621e bellard
void OPPROTO op_fsub_ST0_FT0(void)
1769 927f621e bellard
{
1770 927f621e bellard
    ST0 -= FT0;
1771 927f621e bellard
}
1772 927f621e bellard
1773 927f621e bellard
void OPPROTO op_fsubr_ST0_FT0(void)
1774 927f621e bellard
{
1775 927f621e bellard
    ST0 = FT0 - ST0;
1776 927f621e bellard
}
1777 927f621e bellard
1778 927f621e bellard
void OPPROTO op_fdiv_ST0_FT0(void)
1779 927f621e bellard
{
1780 927f621e bellard
    ST0 /= FT0;
1781 927f621e bellard
}
1782 927f621e bellard
1783 927f621e bellard
void OPPROTO op_fdivr_ST0_FT0(void)
1784 927f621e bellard
{
1785 927f621e bellard
    ST0 = FT0 / ST0;
1786 927f621e bellard
}
1787 927f621e bellard
1788 927f621e bellard
/* fp operations between STN and ST0 */
1789 927f621e bellard
1790 927f621e bellard
void OPPROTO op_fadd_STN_ST0(void)
1791 927f621e bellard
{
1792 927f621e bellard
    ST(PARAM1) += ST0;
1793 927f621e bellard
}
1794 927f621e bellard
1795 927f621e bellard
void OPPROTO op_fmul_STN_ST0(void)
1796 927f621e bellard
{
1797 927f621e bellard
    ST(PARAM1) *= ST0;
1798 927f621e bellard
}
1799 927f621e bellard
1800 927f621e bellard
void OPPROTO op_fsub_STN_ST0(void)
1801 927f621e bellard
{
1802 927f621e bellard
    ST(PARAM1) -= ST0;
1803 927f621e bellard
}
1804 927f621e bellard
1805 927f621e bellard
void OPPROTO op_fsubr_STN_ST0(void)
1806 927f621e bellard
{
1807 927f621e bellard
    CPU86_LDouble *p;
1808 927f621e bellard
    p = &ST(PARAM1);
1809 927f621e bellard
    *p = ST0 - *p;
1810 927f621e bellard
}
1811 927f621e bellard
1812 927f621e bellard
void OPPROTO op_fdiv_STN_ST0(void)
1813 927f621e bellard
{
1814 927f621e bellard
    ST(PARAM1) /= ST0;
1815 927f621e bellard
}
1816 927f621e bellard
1817 927f621e bellard
void OPPROTO op_fdivr_STN_ST0(void)
1818 927f621e bellard
{
1819 927f621e bellard
    CPU86_LDouble *p;
1820 927f621e bellard
    p = &ST(PARAM1);
1821 927f621e bellard
    *p = ST0 / *p;
1822 927f621e bellard
}
1823 927f621e bellard
1824 927f621e bellard
/* misc FPU operations */
1825 927f621e bellard
void OPPROTO op_fchs_ST0(void)
1826 927f621e bellard
{
1827 927f621e bellard
    ST0 = -ST0;
1828 927f621e bellard
}
1829 927f621e bellard
1830 927f621e bellard
void OPPROTO op_fabs_ST0(void)
1831 927f621e bellard
{
1832 927f621e bellard
    ST0 = fabs(ST0);
1833 927f621e bellard
}
1834 927f621e bellard
1835 77f8dd5a bellard
void helper_fxam_ST0(void)
1836 927f621e bellard
{
1837 927f621e bellard
    CPU86_LDoubleU temp;
1838 927f621e bellard
    int expdif;
1839 927f621e bellard
1840 927f621e bellard
    temp.d = ST0;
1841 927f621e bellard
1842 927f621e bellard
    env->fpus &= (~0x4700);  /* (C3,C2,C1,C0) <-- 0000 */
1843 927f621e bellard
    if (SIGND(temp))
1844 927f621e bellard
        env->fpus |= 0x200; /* C1 <-- 1 */
1845 927f621e bellard
1846 927f621e bellard
    expdif = EXPD(temp);
1847 927f621e bellard
    if (expdif == MAXEXPD) {
1848 927f621e bellard
        if (MANTD(temp) == 0)
1849 927f621e bellard
            env->fpus |=  0x500 /*Infinity*/;
1850 927f621e bellard
        else
1851 927f621e bellard
            env->fpus |=  0x100 /*NaN*/;
1852 927f621e bellard
    } else if (expdif == 0) {
1853 927f621e bellard
        if (MANTD(temp) == 0)
1854 927f621e bellard
            env->fpus |=  0x4000 /*Zero*/;
1855 927f621e bellard
        else
1856 927f621e bellard
            env->fpus |= 0x4400 /*Denormal*/;
1857 927f621e bellard
    } else {
1858 927f621e bellard
        env->fpus |= 0x400;
1859 927f621e bellard
    }
1860 77f8dd5a bellard
}
1861 77f8dd5a bellard
1862 77f8dd5a bellard
void OPPROTO op_fxam_ST0(void)
1863 77f8dd5a bellard
{
1864 77f8dd5a bellard
    helper_fxam_ST0();
1865 927f621e bellard
}
1866 927f621e bellard
1867 927f621e bellard
void OPPROTO op_fld1_ST0(void)
1868 927f621e bellard
{
1869 927f621e bellard
    ST0 = *(CPU86_LDouble *)&f15rk[1];
1870 927f621e bellard
}
1871 927f621e bellard
1872 77f8dd5a bellard
void OPPROTO op_fldl2t_ST0(void)
1873 927f621e bellard
{
1874 927f621e bellard
    ST0 = *(CPU86_LDouble *)&f15rk[6];
1875 927f621e bellard
}
1876 927f621e bellard
1877 77f8dd5a bellard
void OPPROTO op_fldl2e_ST0(void)
1878 927f621e bellard
{
1879 927f621e bellard
    ST0 = *(CPU86_LDouble *)&f15rk[5];
1880 927f621e bellard
}
1881 927f621e bellard
1882 927f621e bellard
void OPPROTO op_fldpi_ST0(void)
1883 927f621e bellard
{
1884 927f621e bellard
    ST0 = *(CPU86_LDouble *)&f15rk[2];
1885 927f621e bellard
}
1886 927f621e bellard
1887 927f621e bellard
void OPPROTO op_fldlg2_ST0(void)
1888 927f621e bellard
{
1889 927f621e bellard
    ST0 = *(CPU86_LDouble *)&f15rk[3];
1890 927f621e bellard
}
1891 927f621e bellard
1892 927f621e bellard
void OPPROTO op_fldln2_ST0(void)
1893 927f621e bellard
{
1894 927f621e bellard
    ST0 = *(CPU86_LDouble *)&f15rk[4];
1895 927f621e bellard
}
1896 927f621e bellard
1897 927f621e bellard
void OPPROTO op_fldz_ST0(void)
1898 927f621e bellard
{
1899 927f621e bellard
    ST0 = *(CPU86_LDouble *)&f15rk[0];
1900 927f621e bellard
}
1901 927f621e bellard
1902 927f621e bellard
void OPPROTO op_fldz_FT0(void)
1903 927f621e bellard
{
1904 927f621e bellard
    ST0 = *(CPU86_LDouble *)&f15rk[0];
1905 927f621e bellard
}
1906 927f621e bellard
1907 927f621e bellard
void helper_f2xm1(void)
1908 927f621e bellard
{
1909 927f621e bellard
    ST0 = pow(2.0,ST0) - 1.0;
1910 927f621e bellard
}
1911 927f621e bellard
1912 927f621e bellard
void helper_fyl2x(void)
1913 927f621e bellard
{
1914 927f621e bellard
    CPU86_LDouble fptemp;
1915 927f621e bellard
    
1916 927f621e bellard
    fptemp = ST0;
1917 927f621e bellard
    if (fptemp>0.0){
1918 927f621e bellard
        fptemp = log(fptemp)/log(2.0);         /* log2(ST) */
1919 927f621e bellard
        ST1 *= fptemp;
1920 927f621e bellard
        fpop();
1921 927f621e bellard
    } else { 
1922 927f621e bellard
        env->fpus &= (~0x4700);
1923 927f621e bellard
        env->fpus |= 0x400;
1924 927f621e bellard
    }
1925 927f621e bellard
}
1926 927f621e bellard
1927 927f621e bellard
void helper_fptan(void)
1928 927f621e bellard
{
1929 927f621e bellard
    CPU86_LDouble fptemp;
1930 927f621e bellard
1931 927f621e bellard
    fptemp = ST0;
1932 927f621e bellard
    if((fptemp > MAXTAN)||(fptemp < -MAXTAN)) {
1933 927f621e bellard
        env->fpus |= 0x400;
1934 927f621e bellard
    } else {
1935 927f621e bellard
        ST0 = tan(fptemp);
1936 927f621e bellard
        fpush();
1937 927f621e bellard
        ST0 = 1.0;
1938 927f621e bellard
        env->fpus &= (~0x400);  /* C2 <-- 0 */
1939 927f621e bellard
        /* the above code is for  |arg| < 2**52 only */
1940 927f621e bellard
    }
1941 927f621e bellard
}
1942 927f621e bellard
1943 927f621e bellard
void helper_fpatan(void)
1944 927f621e bellard
{
1945 927f621e bellard
    CPU86_LDouble fptemp, fpsrcop;
1946 927f621e bellard
1947 927f621e bellard
    fpsrcop = ST1;
1948 927f621e bellard
    fptemp = ST0;
1949 927f621e bellard
    ST1 = atan2(fpsrcop,fptemp);
1950 927f621e bellard
    fpop();
1951 927f621e bellard
}
1952 927f621e bellard
1953 927f621e bellard
void helper_fxtract(void)
1954 927f621e bellard
{
1955 927f621e bellard
    CPU86_LDoubleU temp;
1956 927f621e bellard
    unsigned int expdif;
1957 927f621e bellard
1958 927f621e bellard
    temp.d = ST0;
1959 927f621e bellard
    expdif = EXPD(temp) - EXPBIAS;
1960 927f621e bellard
    /*DP exponent bias*/
1961 927f621e bellard
    ST0 = expdif;
1962 927f621e bellard
    fpush();
1963 927f621e bellard
    BIASEXPONENT(temp);
1964 927f621e bellard
    ST0 = temp.d;
1965 927f621e bellard
}
1966 927f621e bellard
1967 927f621e bellard
void helper_fprem1(void)
1968 927f621e bellard
{
1969 927f621e bellard
    CPU86_LDouble dblq, fpsrcop, fptemp;
1970 927f621e bellard
    CPU86_LDoubleU fpsrcop1, fptemp1;
1971 927f621e bellard
    int expdif;
1972 927f621e bellard
    int q;
1973 927f621e bellard
1974 927f621e bellard
    fpsrcop = ST0;
1975 927f621e bellard
    fptemp = ST1;
1976 927f621e bellard
    fpsrcop1.d = fpsrcop;
1977 927f621e bellard
    fptemp1.d = fptemp;
1978 927f621e bellard
    expdif = EXPD(fpsrcop1) - EXPD(fptemp1);
1979 927f621e bellard
    if (expdif < 53) {
1980 927f621e bellard
        dblq = fpsrcop / fptemp;
1981 927f621e bellard
        dblq = (dblq < 0.0)? ceil(dblq): floor(dblq);
1982 927f621e bellard
        ST0 = fpsrcop - fptemp*dblq;
1983 927f621e bellard
        q = (int)dblq; /* cutting off top bits is assumed here */
1984 927f621e bellard
        env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */
1985 927f621e bellard
                                /* (C0,C1,C3) <-- (q2,q1,q0) */
1986 927f621e bellard
        env->fpus |= (q&0x4) << 6; /* (C0) <-- q2 */
1987 927f621e bellard
        env->fpus |= (q&0x2) << 8; /* (C1) <-- q1 */
1988 927f621e bellard
        env->fpus |= (q&0x1) << 14; /* (C3) <-- q0 */
1989 927f621e bellard
    } else {
1990 927f621e bellard
        env->fpus |= 0x400;  /* C2 <-- 1 */
1991 927f621e bellard
        fptemp = pow(2.0, expdif-50);
1992 927f621e bellard
        fpsrcop = (ST0 / ST1) / fptemp;
1993 927f621e bellard
        /* fpsrcop = integer obtained by rounding to the nearest */
1994 927f621e bellard
        fpsrcop = (fpsrcop-floor(fpsrcop) < ceil(fpsrcop)-fpsrcop)?
1995 927f621e bellard
            floor(fpsrcop): ceil(fpsrcop);
1996 927f621e bellard
        ST0 -= (ST1 * fpsrcop * fptemp);
1997 927f621e bellard
    }
1998 927f621e bellard
}
1999 927f621e bellard
2000 927f621e bellard
void helper_fprem(void)
2001 927f621e bellard
{
2002 927f621e bellard
    CPU86_LDouble dblq, fpsrcop, fptemp;
2003 927f621e bellard
    CPU86_LDoubleU fpsrcop1, fptemp1;
2004 927f621e bellard
    int expdif;
2005 927f621e bellard
    int q;
2006 927f621e bellard
    
2007 927f621e bellard
    fpsrcop = ST0;
2008 927f621e bellard
    fptemp = ST1;
2009 927f621e bellard
    fpsrcop1.d = fpsrcop;
2010 927f621e bellard
    fptemp1.d = fptemp;
2011 927f621e bellard
    expdif = EXPD(fpsrcop1) - EXPD(fptemp1);
2012 927f621e bellard
    if ( expdif < 53 ) {
2013 927f621e bellard
        dblq = fpsrcop / fptemp;
2014 927f621e bellard
        dblq = (dblq < 0.0)? ceil(dblq): floor(dblq);
2015 927f621e bellard
        ST0 = fpsrcop - fptemp*dblq;
2016 927f621e bellard
        q = (int)dblq; /* cutting off top bits is assumed here */
2017 927f621e bellard
        env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */
2018 927f621e bellard
                                /* (C0,C1,C3) <-- (q2,q1,q0) */
2019 927f621e bellard
        env->fpus |= (q&0x4) << 6; /* (C0) <-- q2 */
2020 927f621e bellard
        env->fpus |= (q&0x2) << 8; /* (C1) <-- q1 */
2021 927f621e bellard
        env->fpus |= (q&0x1) << 14; /* (C3) <-- q0 */
2022 927f621e bellard
    } else {
2023 927f621e bellard
        env->fpus |= 0x400;  /* C2 <-- 1 */
2024 927f621e bellard
        fptemp = pow(2.0, expdif-50);
2025 927f621e bellard
        fpsrcop = (ST0 / ST1) / fptemp;
2026 927f621e bellard
        /* fpsrcop = integer obtained by chopping */
2027 927f621e bellard
        fpsrcop = (fpsrcop < 0.0)?
2028 927f621e bellard
            -(floor(fabs(fpsrcop))): floor(fpsrcop);
2029 927f621e bellard
        ST0 -= (ST1 * fpsrcop * fptemp);
2030 927f621e bellard
    }
2031 927f621e bellard
}
2032 927f621e bellard
2033 927f621e bellard
void helper_fyl2xp1(void)
2034 927f621e bellard
{
2035 927f621e bellard
    CPU86_LDouble fptemp;
2036 927f621e bellard
2037 927f621e bellard
    fptemp = ST0;
2038 927f621e bellard
    if ((fptemp+1.0)>0.0) {
2039 927f621e bellard
        fptemp = log(fptemp+1.0) / log(2.0); /* log2(ST+1.0) */
2040 927f621e bellard
        ST1 *= fptemp;
2041 927f621e bellard
        fpop();
2042 927f621e bellard
    } else { 
2043 927f621e bellard
        env->fpus &= (~0x4700);
2044 927f621e bellard
        env->fpus |= 0x400;
2045 927f621e bellard
    }
2046 927f621e bellard
}
2047 927f621e bellard
2048 927f621e bellard
void helper_fsqrt(void)
2049 927f621e bellard
{
2050 927f621e bellard
    CPU86_LDouble fptemp;
2051 927f621e bellard
2052 927f621e bellard
    fptemp = ST0;
2053 927f621e bellard
    if (fptemp<0.0) { 
2054 927f621e bellard
        env->fpus &= (~0x4700);  /* (C3,C2,C1,C0) <-- 0000 */
2055 927f621e bellard
        env->fpus |= 0x400;
2056 927f621e bellard
    }
2057 927f621e bellard
    ST0 = sqrt(fptemp);
2058 927f621e bellard
}
2059 927f621e bellard
2060 927f621e bellard
void helper_fsincos(void)
2061 927f621e bellard
{
2062 927f621e bellard
    CPU86_LDouble fptemp;
2063 927f621e bellard
2064 927f621e bellard
    fptemp = ST0;
2065 927f621e bellard
    if ((fptemp > MAXTAN)||(fptemp < -MAXTAN)) {
2066 927f621e bellard
        env->fpus |= 0x400;
2067 927f621e bellard
    } else {
2068 927f621e bellard
        ST0 = sin(fptemp);
2069 927f621e bellard
        fpush();
2070 927f621e bellard
        ST0 = cos(fptemp);
2071 927f621e bellard
        env->fpus &= (~0x400);  /* C2 <-- 0 */
2072 927f621e bellard
        /* the above code is for  |arg| < 2**63 only */
2073 927f621e bellard
    }
2074 927f621e bellard
}
2075 927f621e bellard
2076 927f621e bellard
void helper_frndint(void)
2077 927f621e bellard
{
2078 927f621e bellard
    ST0 = rint(ST0);
2079 927f621e bellard
}
2080 927f621e bellard
2081 927f621e bellard
void helper_fscale(void)
2082 927f621e bellard
{
2083 927f621e bellard
    CPU86_LDouble fpsrcop, fptemp;
2084 927f621e bellard
2085 927f621e bellard
    fpsrcop = 2.0;
2086 927f621e bellard
    fptemp = pow(fpsrcop,ST1);
2087 927f621e bellard
    ST0 *= fptemp;
2088 927f621e bellard
}
2089 927f621e bellard
2090 927f621e bellard
void helper_fsin(void)
2091 927f621e bellard
{
2092 927f621e bellard
    CPU86_LDouble fptemp;
2093 927f621e bellard
2094 927f621e bellard
    fptemp = ST0;
2095 927f621e bellard
    if ((fptemp > MAXTAN)||(fptemp < -MAXTAN)) {
2096 927f621e bellard
        env->fpus |= 0x400;
2097 927f621e bellard
    } else {
2098 927f621e bellard
        ST0 = sin(fptemp);
2099 927f621e bellard
        env->fpus &= (~0x400);  /* C2 <-- 0 */
2100 927f621e bellard
        /* the above code is for  |arg| < 2**53 only */
2101 927f621e bellard
    }
2102 927f621e bellard
}
2103 927f621e bellard
2104 927f621e bellard
void helper_fcos(void)
2105 927f621e bellard
{
2106 927f621e bellard
    CPU86_LDouble fptemp;
2107 927f621e bellard
2108 927f621e bellard
    fptemp = ST0;
2109 927f621e bellard
    if((fptemp > MAXTAN)||(fptemp < -MAXTAN)) {
2110 927f621e bellard
        env->fpus |= 0x400;
2111 927f621e bellard
    } else {
2112 927f621e bellard
        ST0 = cos(fptemp);
2113 927f621e bellard
        env->fpus &= (~0x400);  /* C2 <-- 0 */
2114 927f621e bellard
        /* the above code is for  |arg5 < 2**63 only */
2115 927f621e bellard
    }
2116 927f621e bellard
}
2117 927f621e bellard
2118 927f621e bellard
/* associated heplers to reduce generated code length and to simplify
2119 927f621e bellard
   relocation (FP constants are usually stored in .rodata section) */
2120 927f621e bellard
2121 927f621e bellard
void OPPROTO op_f2xm1(void)
2122 927f621e bellard
{
2123 927f621e bellard
    helper_f2xm1();
2124 927f621e bellard
}
2125 927f621e bellard
2126 927f621e bellard
void OPPROTO op_fyl2x(void)
2127 927f621e bellard
{
2128 927f621e bellard
    helper_fyl2x();
2129 927f621e bellard
}
2130 927f621e bellard
2131 927f621e bellard
void OPPROTO op_fptan(void)
2132 927f621e bellard
{
2133 927f621e bellard
    helper_fptan();
2134 927f621e bellard
}
2135 927f621e bellard
2136 927f621e bellard
void OPPROTO op_fpatan(void)
2137 927f621e bellard
{
2138 927f621e bellard
    helper_fpatan();
2139 927f621e bellard
}
2140 927f621e bellard
2141 927f621e bellard
void OPPROTO op_fxtract(void)
2142 927f621e bellard
{
2143 927f621e bellard
    helper_fxtract();
2144 927f621e bellard
}
2145 927f621e bellard
2146 927f621e bellard
void OPPROTO op_fprem1(void)
2147 927f621e bellard
{
2148 927f621e bellard
    helper_fprem1();
2149 927f621e bellard
}
2150 927f621e bellard
2151 927f621e bellard
2152 927f621e bellard
void OPPROTO op_fprem(void)
2153 927f621e bellard
{
2154 927f621e bellard
    helper_fprem();
2155 927f621e bellard
}
2156 927f621e bellard
2157 927f621e bellard
void OPPROTO op_fyl2xp1(void)
2158 927f621e bellard
{
2159 927f621e bellard
    helper_fyl2xp1();
2160 927f621e bellard
}
2161 927f621e bellard
2162 927f621e bellard
void OPPROTO op_fsqrt(void)
2163 927f621e bellard
{
2164 927f621e bellard
    helper_fsqrt();
2165 927f621e bellard
}
2166 927f621e bellard
2167 927f621e bellard
void OPPROTO op_fsincos(void)
2168 927f621e bellard
{
2169 927f621e bellard
    helper_fsincos();
2170 927f621e bellard
}
2171 927f621e bellard
2172 927f621e bellard
void OPPROTO op_frndint(void)
2173 927f621e bellard
{
2174 927f621e bellard
    helper_frndint();
2175 927f621e bellard
}
2176 927f621e bellard
2177 927f621e bellard
void OPPROTO op_fscale(void)
2178 927f621e bellard
{
2179 927f621e bellard
    helper_fscale();
2180 927f621e bellard
}
2181 927f621e bellard
2182 927f621e bellard
void OPPROTO op_fsin(void)
2183 927f621e bellard
{
2184 927f621e bellard
    helper_fsin();
2185 927f621e bellard
}
2186 927f621e bellard
2187 927f621e bellard
void OPPROTO op_fcos(void)
2188 927f621e bellard
{
2189 927f621e bellard
    helper_fcos();
2190 927f621e bellard
}
2191 927f621e bellard
2192 4b74fe1f bellard
void OPPROTO op_fnstsw_A0(void)
2193 4b74fe1f bellard
{
2194 4b74fe1f bellard
    int fpus;
2195 4b74fe1f bellard
    fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
2196 4b74fe1f bellard
    stw((void *)A0, fpus);
2197 4b74fe1f bellard
}
2198 4b74fe1f bellard
2199 77f8dd5a bellard
void OPPROTO op_fnstsw_EAX(void)
2200 77f8dd5a bellard
{
2201 77f8dd5a bellard
    int fpus;
2202 77f8dd5a bellard
    fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
2203 77f8dd5a bellard
    EAX = (EAX & 0xffff0000) | fpus;
2204 77f8dd5a bellard
}
2205 77f8dd5a bellard
2206 4b74fe1f bellard
void OPPROTO op_fnstcw_A0(void)
2207 4b74fe1f bellard
{
2208 4b74fe1f bellard
    stw((void *)A0, env->fpuc);
2209 4b74fe1f bellard
}
2210 4b74fe1f bellard
2211 4b74fe1f bellard
void OPPROTO op_fldcw_A0(void)
2212 4b74fe1f bellard
{
2213 4b74fe1f bellard
    int rnd_type;
2214 4b74fe1f bellard
    env->fpuc = lduw((void *)A0);
2215 4b74fe1f bellard
    /* set rounding mode */
2216 4b74fe1f bellard
    switch(env->fpuc & RC_MASK) {
2217 4b74fe1f bellard
    default:
2218 4b74fe1f bellard
    case RC_NEAR:
2219 4b74fe1f bellard
        rnd_type = FE_TONEAREST;
2220 4b74fe1f bellard
        break;
2221 4b74fe1f bellard
    case RC_DOWN:
2222 4b74fe1f bellard
        rnd_type = FE_DOWNWARD;
2223 4b74fe1f bellard
        break;
2224 4b74fe1f bellard
    case RC_UP:
2225 4b74fe1f bellard
        rnd_type = FE_UPWARD;
2226 4b74fe1f bellard
        break;
2227 4b74fe1f bellard
    case RC_CHOP:
2228 4b74fe1f bellard
        rnd_type = FE_TOWARDZERO;
2229 4b74fe1f bellard
        break;
2230 4b74fe1f bellard
    }
2231 4b74fe1f bellard
    fesetround(rnd_type);
2232 4b74fe1f bellard
}
2233 4b74fe1f bellard
2234 1a9353d2 bellard
void OPPROTO op_fclex(void)
2235 1a9353d2 bellard
{
2236 1a9353d2 bellard
    env->fpus &= 0x7f00;
2237 1a9353d2 bellard
}
2238 1a9353d2 bellard
2239 1a9353d2 bellard
void OPPROTO op_fninit(void)
2240 1a9353d2 bellard
{
2241 1a9353d2 bellard
    env->fpus = 0;
2242 1a9353d2 bellard
    env->fpstt = 0;
2243 1a9353d2 bellard
    env->fpuc = 0x37f;
2244 1a9353d2 bellard
    env->fptags[0] = 1;
2245 1a9353d2 bellard
    env->fptags[1] = 1;
2246 1a9353d2 bellard
    env->fptags[2] = 1;
2247 1a9353d2 bellard
    env->fptags[3] = 1;
2248 1a9353d2 bellard
    env->fptags[4] = 1;
2249 1a9353d2 bellard
    env->fptags[5] = 1;
2250 1a9353d2 bellard
    env->fptags[6] = 1;
2251 1a9353d2 bellard
    env->fptags[7] = 1;
2252 1a9353d2 bellard
}
2253 1b6b029e bellard
2254 1b6b029e bellard
/* threading support */
2255 1b6b029e bellard
void OPPROTO op_lock(void)
2256 1b6b029e bellard
{
2257 1b6b029e bellard
    cpu_lock();
2258 1b6b029e bellard
}
2259 1b6b029e bellard
2260 1b6b029e bellard
void OPPROTO op_unlock(void)
2261 1b6b029e bellard
{
2262 1b6b029e bellard
    cpu_unlock();
2263 1b6b029e bellard
}