Statistics
| Branch: | Revision:

root / ops_template.h @ a69d83b6

History | View | Annotate | Download (19.2 kB)

1 66fb9763 bellard
/*
2 66fb9763 bellard
 *  i386 micro operations (included several times to generate
3 66fb9763 bellard
 *  different operand sizes)
4 66fb9763 bellard
 * 
5 66fb9763 bellard
 *  Copyright (c) 2003 Fabrice Bellard
6 66fb9763 bellard
 *
7 d691f669 bellard
 * This library is free software; you can redistribute it and/or
8 d691f669 bellard
 * modify it under the terms of the GNU Lesser General Public
9 d691f669 bellard
 * License as published by the Free Software Foundation; either
10 d691f669 bellard
 * version 2 of the License, or (at your option) any later version.
11 66fb9763 bellard
 *
12 d691f669 bellard
 * This library is distributed in the hope that it will be useful,
13 d691f669 bellard
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 d691f669 bellard
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 d691f669 bellard
 * Lesser General Public License for more details.
16 66fb9763 bellard
 *
17 d691f669 bellard
 * You should have received a copy of the GNU Lesser General Public
18 d691f669 bellard
 * License along with this library; if not, write to the Free Software
19 d691f669 bellard
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20 66fb9763 bellard
 */
21 367e86e8 bellard
#define DATA_BITS (1 << (3 + SHIFT))
22 367e86e8 bellard
#define SHIFT_MASK (DATA_BITS - 1)
23 367e86e8 bellard
#define SIGN_MASK (1 << (DATA_BITS - 1))
24 367e86e8 bellard
25 367e86e8 bellard
#if DATA_BITS == 8
26 367e86e8 bellard
#define SUFFIX b
27 367e86e8 bellard
#define DATA_TYPE uint8_t
28 367e86e8 bellard
#define DATA_STYPE int8_t
29 367e86e8 bellard
#define DATA_MASK 0xff
30 367e86e8 bellard
#elif DATA_BITS == 16
31 367e86e8 bellard
#define SUFFIX w
32 367e86e8 bellard
#define DATA_TYPE uint16_t
33 367e86e8 bellard
#define DATA_STYPE int16_t
34 367e86e8 bellard
#define DATA_MASK 0xffff
35 367e86e8 bellard
#elif DATA_BITS == 32
36 367e86e8 bellard
#define SUFFIX l
37 367e86e8 bellard
#define DATA_TYPE uint32_t
38 367e86e8 bellard
#define DATA_STYPE int32_t
39 367e86e8 bellard
#define DATA_MASK 0xffffffff
40 367e86e8 bellard
#else
41 367e86e8 bellard
#error unhandled operand size
42 367e86e8 bellard
#endif
43 367e86e8 bellard
44 367e86e8 bellard
/* dynamic flags computation */
45 367e86e8 bellard
46 367e86e8 bellard
static int glue(compute_all_add, SUFFIX)(void)
47 367e86e8 bellard
{
48 367e86e8 bellard
    int cf, pf, af, zf, sf, of;
49 367e86e8 bellard
    int src1, src2;
50 367e86e8 bellard
    src1 = CC_SRC;
51 367e86e8 bellard
    src2 = CC_DST - CC_SRC;
52 367e86e8 bellard
    cf = (DATA_TYPE)CC_DST < (DATA_TYPE)src1;
53 367e86e8 bellard
    pf = parity_table[(uint8_t)CC_DST];
54 367e86e8 bellard
    af = (CC_DST ^ src1 ^ src2) & 0x10;
55 4b74fe1f bellard
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
56 367e86e8 bellard
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
57 367e86e8 bellard
    of = lshift((src1 ^ src2 ^ -1) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
58 367e86e8 bellard
    return cf | pf | af | zf | sf | of;
59 367e86e8 bellard
}
60 367e86e8 bellard
61 367e86e8 bellard
static int glue(compute_c_add, SUFFIX)(void)
62 367e86e8 bellard
{
63 367e86e8 bellard
    int src1, cf;
64 367e86e8 bellard
    src1 = CC_SRC;
65 367e86e8 bellard
    cf = (DATA_TYPE)CC_DST < (DATA_TYPE)src1;
66 367e86e8 bellard
    return cf;
67 367e86e8 bellard
}
68 367e86e8 bellard
69 4b74fe1f bellard
static int glue(compute_all_adc, SUFFIX)(void)
70 4b74fe1f bellard
{
71 4b74fe1f bellard
    int cf, pf, af, zf, sf, of;
72 4b74fe1f bellard
    int src1, src2;
73 4b74fe1f bellard
    src1 = CC_SRC;
74 4b74fe1f bellard
    src2 = CC_DST - CC_SRC - 1;
75 4b74fe1f bellard
    cf = (DATA_TYPE)CC_DST <= (DATA_TYPE)src1;
76 4b74fe1f bellard
    pf = parity_table[(uint8_t)CC_DST];
77 4b74fe1f bellard
    af = (CC_DST ^ src1 ^ src2) & 0x10;
78 4b74fe1f bellard
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
79 4b74fe1f bellard
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
80 4b74fe1f bellard
    of = lshift((src1 ^ src2 ^ -1) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
81 4b74fe1f bellard
    return cf | pf | af | zf | sf | of;
82 4b74fe1f bellard
}
83 4b74fe1f bellard
84 4b74fe1f bellard
static int glue(compute_c_adc, SUFFIX)(void)
85 4b74fe1f bellard
{
86 4b74fe1f bellard
    int src1, cf;
87 4b74fe1f bellard
    src1 = CC_SRC;
88 4b74fe1f bellard
    cf = (DATA_TYPE)CC_DST <= (DATA_TYPE)src1;
89 4b74fe1f bellard
    return cf;
90 4b74fe1f bellard
}
91 4b74fe1f bellard
92 367e86e8 bellard
static int glue(compute_all_sub, SUFFIX)(void)
93 367e86e8 bellard
{
94 367e86e8 bellard
    int cf, pf, af, zf, sf, of;
95 367e86e8 bellard
    int src1, src2;
96 367e86e8 bellard
    src1 = CC_SRC;
97 367e86e8 bellard
    src2 = CC_SRC - CC_DST;
98 367e86e8 bellard
    cf = (DATA_TYPE)src1 < (DATA_TYPE)src2;
99 367e86e8 bellard
    pf = parity_table[(uint8_t)CC_DST];
100 367e86e8 bellard
    af = (CC_DST ^ src1 ^ src2) & 0x10;
101 4b74fe1f bellard
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
102 367e86e8 bellard
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
103 4b74fe1f bellard
    of = lshift((src1 ^ src2) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
104 367e86e8 bellard
    return cf | pf | af | zf | sf | of;
105 367e86e8 bellard
}
106 367e86e8 bellard
107 367e86e8 bellard
static int glue(compute_c_sub, SUFFIX)(void)
108 367e86e8 bellard
{
109 367e86e8 bellard
    int src1, src2, cf;
110 367e86e8 bellard
    src1 = CC_SRC;
111 367e86e8 bellard
    src2 = CC_SRC - CC_DST;
112 4b74fe1f bellard
    cf = (DATA_TYPE)src1 < (DATA_TYPE)src2;
113 4b74fe1f bellard
    return cf;
114 4b74fe1f bellard
}
115 4b74fe1f bellard
116 4b74fe1f bellard
static int glue(compute_all_sbb, SUFFIX)(void)
117 4b74fe1f bellard
{
118 4b74fe1f bellard
    int cf, pf, af, zf, sf, of;
119 4b74fe1f bellard
    int src1, src2;
120 4b74fe1f bellard
    src1 = CC_SRC;
121 4b74fe1f bellard
    src2 = CC_SRC - CC_DST - 1;
122 4b74fe1f bellard
    cf = (DATA_TYPE)src1 <= (DATA_TYPE)src2;
123 4b74fe1f bellard
    pf = parity_table[(uint8_t)CC_DST];
124 4b74fe1f bellard
    af = (CC_DST ^ src1 ^ src2) & 0x10;
125 4b74fe1f bellard
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
126 4b74fe1f bellard
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
127 4b74fe1f bellard
    of = lshift((src1 ^ src2) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
128 4b74fe1f bellard
    return cf | pf | af | zf | sf | of;
129 4b74fe1f bellard
}
130 4b74fe1f bellard
131 4b74fe1f bellard
static int glue(compute_c_sbb, SUFFIX)(void)
132 4b74fe1f bellard
{
133 4b74fe1f bellard
    int src1, src2, cf;
134 4b74fe1f bellard
    src1 = CC_SRC;
135 4b74fe1f bellard
    src2 = CC_SRC - CC_DST - 1;
136 4b74fe1f bellard
    cf = (DATA_TYPE)src1 <= (DATA_TYPE)src2;
137 367e86e8 bellard
    return cf;
138 367e86e8 bellard
}
139 367e86e8 bellard
140 367e86e8 bellard
static int glue(compute_all_logic, SUFFIX)(void)
141 367e86e8 bellard
{
142 367e86e8 bellard
    int cf, pf, af, zf, sf, of;
143 367e86e8 bellard
    cf = 0;
144 367e86e8 bellard
    pf = parity_table[(uint8_t)CC_DST];
145 367e86e8 bellard
    af = 0;
146 4b74fe1f bellard
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
147 367e86e8 bellard
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
148 367e86e8 bellard
    of = 0;
149 367e86e8 bellard
    return cf | pf | af | zf | sf | of;
150 367e86e8 bellard
}
151 367e86e8 bellard
152 367e86e8 bellard
static int glue(compute_c_logic, SUFFIX)(void)
153 367e86e8 bellard
{
154 367e86e8 bellard
    return 0;
155 367e86e8 bellard
}
156 367e86e8 bellard
157 367e86e8 bellard
static int glue(compute_all_inc, SUFFIX)(void)
158 367e86e8 bellard
{
159 367e86e8 bellard
    int cf, pf, af, zf, sf, of;
160 367e86e8 bellard
    int src1, src2;
161 367e86e8 bellard
    src1 = CC_DST - 1;
162 367e86e8 bellard
    src2 = 1;
163 367e86e8 bellard
    cf = CC_SRC;
164 367e86e8 bellard
    pf = parity_table[(uint8_t)CC_DST];
165 367e86e8 bellard
    af = (CC_DST ^ src1 ^ src2) & 0x10;
166 4b74fe1f bellard
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
167 367e86e8 bellard
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
168 4b74fe1f bellard
    of = ((CC_DST & DATA_MASK) == SIGN_MASK) << 11;
169 367e86e8 bellard
    return cf | pf | af | zf | sf | of;
170 367e86e8 bellard
}
171 367e86e8 bellard
172 4b74fe1f bellard
#if DATA_BITS == 32
173 367e86e8 bellard
static int glue(compute_c_inc, SUFFIX)(void)
174 367e86e8 bellard
{
175 367e86e8 bellard
    return CC_SRC;
176 367e86e8 bellard
}
177 4b74fe1f bellard
#endif
178 367e86e8 bellard
179 367e86e8 bellard
static int glue(compute_all_dec, SUFFIX)(void)
180 367e86e8 bellard
{
181 367e86e8 bellard
    int cf, pf, af, zf, sf, of;
182 367e86e8 bellard
    int src1, src2;
183 367e86e8 bellard
    src1 = CC_DST + 1;
184 367e86e8 bellard
    src2 = 1;
185 367e86e8 bellard
    cf = CC_SRC;
186 367e86e8 bellard
    pf = parity_table[(uint8_t)CC_DST];
187 367e86e8 bellard
    af = (CC_DST ^ src1 ^ src2) & 0x10;
188 4b74fe1f bellard
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
189 367e86e8 bellard
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
190 4b74fe1f bellard
    of = ((CC_DST & DATA_MASK) == ((uint32_t)SIGN_MASK - 1)) << 11;
191 367e86e8 bellard
    return cf | pf | af | zf | sf | of;
192 367e86e8 bellard
}
193 367e86e8 bellard
194 367e86e8 bellard
static int glue(compute_all_shl, SUFFIX)(void)
195 367e86e8 bellard
{
196 367e86e8 bellard
    int cf, pf, af, zf, sf, of;
197 d57c4e01 bellard
    cf = (CC_SRC >> (DATA_BITS - 1)) & CC_C;
198 367e86e8 bellard
    pf = parity_table[(uint8_t)CC_DST];
199 367e86e8 bellard
    af = 0; /* undefined */
200 4b74fe1f bellard
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
201 367e86e8 bellard
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
202 d57c4e01 bellard
    /* of is defined if shift count == 1 */
203 d57c4e01 bellard
    of = lshift(CC_SRC ^ CC_DST, 12 - DATA_BITS) & CC_O;
204 367e86e8 bellard
    return cf | pf | af | zf | sf | of;
205 367e86e8 bellard
}
206 367e86e8 bellard
207 4b74fe1f bellard
#if DATA_BITS == 32
208 367e86e8 bellard
static int glue(compute_c_shl, SUFFIX)(void)
209 367e86e8 bellard
{
210 367e86e8 bellard
    return CC_SRC & 1;
211 367e86e8 bellard
}
212 4b74fe1f bellard
#endif
213 4b74fe1f bellard
214 4b74fe1f bellard
static int glue(compute_all_sar, SUFFIX)(void)
215 4b74fe1f bellard
{
216 4b74fe1f bellard
    int cf, pf, af, zf, sf, of;
217 4b74fe1f bellard
    cf = CC_SRC & 1;
218 4b74fe1f bellard
    pf = parity_table[(uint8_t)CC_DST];
219 4b74fe1f bellard
    af = 0; /* undefined */
220 4b74fe1f bellard
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
221 4b74fe1f bellard
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
222 d57c4e01 bellard
    /* of is defined if shift count == 1 */
223 d57c4e01 bellard
    of = lshift(CC_SRC ^ CC_DST, 12 - DATA_BITS) & CC_O; 
224 4b74fe1f bellard
    return cf | pf | af | zf | sf | of;
225 4b74fe1f bellard
}
226 367e86e8 bellard
227 367e86e8 bellard
/* various optimized jumps cases */
228 367e86e8 bellard
229 367e86e8 bellard
void OPPROTO glue(op_jb_sub, SUFFIX)(void)
230 367e86e8 bellard
{
231 367e86e8 bellard
    int src1, src2;
232 367e86e8 bellard
    src1 = CC_SRC;
233 367e86e8 bellard
    src2 = CC_SRC - CC_DST;
234 367e86e8 bellard
235 367e86e8 bellard
    if ((DATA_TYPE)src1 < (DATA_TYPE)src2)
236 dab2ed99 bellard
        EIP = PARAM1;
237 367e86e8 bellard
    else
238 dab2ed99 bellard
        EIP = PARAM2;
239 367e86e8 bellard
    FORCE_RET();
240 367e86e8 bellard
}
241 367e86e8 bellard
242 367e86e8 bellard
void OPPROTO glue(op_jz_sub, SUFFIX)(void)
243 367e86e8 bellard
{
244 4b74fe1f bellard
    if ((DATA_TYPE)CC_DST == 0)
245 dab2ed99 bellard
        EIP = PARAM1;
246 367e86e8 bellard
    else
247 dab2ed99 bellard
        EIP = PARAM2;
248 367e86e8 bellard
    FORCE_RET();
249 367e86e8 bellard
}
250 367e86e8 bellard
251 367e86e8 bellard
void OPPROTO glue(op_jbe_sub, SUFFIX)(void)
252 367e86e8 bellard
{
253 367e86e8 bellard
    int src1, src2;
254 367e86e8 bellard
    src1 = CC_SRC;
255 367e86e8 bellard
    src2 = CC_SRC - CC_DST;
256 367e86e8 bellard
257 367e86e8 bellard
    if ((DATA_TYPE)src1 <= (DATA_TYPE)src2)
258 dab2ed99 bellard
        EIP = PARAM1;
259 367e86e8 bellard
    else
260 dab2ed99 bellard
        EIP = PARAM2;
261 367e86e8 bellard
    FORCE_RET();
262 367e86e8 bellard
}
263 367e86e8 bellard
264 367e86e8 bellard
void OPPROTO glue(op_js_sub, SUFFIX)(void)
265 367e86e8 bellard
{
266 367e86e8 bellard
    if (CC_DST & SIGN_MASK)
267 dab2ed99 bellard
        EIP = PARAM1;
268 367e86e8 bellard
    else
269 dab2ed99 bellard
        EIP = PARAM2;
270 367e86e8 bellard
    FORCE_RET();
271 367e86e8 bellard
}
272 367e86e8 bellard
273 367e86e8 bellard
void OPPROTO glue(op_jl_sub, SUFFIX)(void)
274 367e86e8 bellard
{
275 367e86e8 bellard
    int src1, src2;
276 367e86e8 bellard
    src1 = CC_SRC;
277 367e86e8 bellard
    src2 = CC_SRC - CC_DST;
278 367e86e8 bellard
279 367e86e8 bellard
    if ((DATA_STYPE)src1 < (DATA_STYPE)src2)
280 dab2ed99 bellard
        EIP = PARAM1;
281 367e86e8 bellard
    else
282 dab2ed99 bellard
        EIP = PARAM2;
283 367e86e8 bellard
    FORCE_RET();
284 367e86e8 bellard
}
285 367e86e8 bellard
286 367e86e8 bellard
void OPPROTO glue(op_jle_sub, SUFFIX)(void)
287 367e86e8 bellard
{
288 367e86e8 bellard
    int src1, src2;
289 367e86e8 bellard
    src1 = CC_SRC;
290 367e86e8 bellard
    src2 = CC_SRC - CC_DST;
291 367e86e8 bellard
292 367e86e8 bellard
    if ((DATA_STYPE)src1 <= (DATA_STYPE)src2)
293 dab2ed99 bellard
        EIP = PARAM1;
294 367e86e8 bellard
    else
295 dab2ed99 bellard
        EIP = PARAM2;
296 367e86e8 bellard
    FORCE_RET();
297 367e86e8 bellard
}
298 367e86e8 bellard
299 1a9353d2 bellard
/* oldies */
300 1a9353d2 bellard
301 1a9353d2 bellard
#if DATA_BITS >= 16
302 1a9353d2 bellard
303 1a9353d2 bellard
void OPPROTO glue(op_loopnz, SUFFIX)(void)
304 1a9353d2 bellard
{
305 1a9353d2 bellard
    unsigned int tmp;
306 1a9353d2 bellard
    int eflags;
307 1a9353d2 bellard
    eflags = cc_table[CC_OP].compute_all();
308 1a9353d2 bellard
    tmp = (ECX - 1) & DATA_MASK;
309 1a9353d2 bellard
    ECX = (ECX & ~DATA_MASK) | tmp;
310 1a9353d2 bellard
    if (tmp != 0 && !(eflags & CC_Z))
311 dab2ed99 bellard
        EIP = PARAM1;
312 1a9353d2 bellard
    else
313 dab2ed99 bellard
        EIP = PARAM2;
314 1a9353d2 bellard
    FORCE_RET();
315 1a9353d2 bellard
}
316 1a9353d2 bellard
317 1a9353d2 bellard
void OPPROTO glue(op_loopz, SUFFIX)(void)
318 1a9353d2 bellard
{
319 1a9353d2 bellard
    unsigned int tmp;
320 1a9353d2 bellard
    int eflags;
321 1a9353d2 bellard
    eflags = cc_table[CC_OP].compute_all();
322 1a9353d2 bellard
    tmp = (ECX - 1) & DATA_MASK;
323 1a9353d2 bellard
    ECX = (ECX & ~DATA_MASK) | tmp;
324 1a9353d2 bellard
    if (tmp != 0 && (eflags & CC_Z))
325 dab2ed99 bellard
        EIP = PARAM1;
326 1a9353d2 bellard
    else
327 dab2ed99 bellard
        EIP = PARAM2;
328 1a9353d2 bellard
    FORCE_RET();
329 1a9353d2 bellard
}
330 1a9353d2 bellard
331 1a9353d2 bellard
void OPPROTO glue(op_loop, SUFFIX)(void)
332 1a9353d2 bellard
{
333 1a9353d2 bellard
    unsigned int tmp;
334 1a9353d2 bellard
    tmp = (ECX - 1) & DATA_MASK;
335 1a9353d2 bellard
    ECX = (ECX & ~DATA_MASK) | tmp;
336 1a9353d2 bellard
    if (tmp != 0)
337 dab2ed99 bellard
        EIP = PARAM1;
338 1a9353d2 bellard
    else
339 dab2ed99 bellard
        EIP = PARAM2;
340 1a9353d2 bellard
    FORCE_RET();
341 1a9353d2 bellard
}
342 1a9353d2 bellard
343 1a9353d2 bellard
void OPPROTO glue(op_jecxz, SUFFIX)(void)
344 1a9353d2 bellard
{
345 1a9353d2 bellard
    if ((DATA_TYPE)ECX == 0)
346 dab2ed99 bellard
        EIP = PARAM1;
347 1a9353d2 bellard
    else
348 dab2ed99 bellard
        EIP = PARAM2;
349 1a9353d2 bellard
    FORCE_RET();
350 1a9353d2 bellard
}
351 1a9353d2 bellard
352 1a9353d2 bellard
#endif
353 1a9353d2 bellard
354 367e86e8 bellard
/* various optimized set cases */
355 367e86e8 bellard
356 367e86e8 bellard
void OPPROTO glue(op_setb_T0_sub, SUFFIX)(void)
357 367e86e8 bellard
{
358 367e86e8 bellard
    int src1, src2;
359 367e86e8 bellard
    src1 = CC_SRC;
360 367e86e8 bellard
    src2 = CC_SRC - CC_DST;
361 367e86e8 bellard
362 367e86e8 bellard
    T0 = ((DATA_TYPE)src1 < (DATA_TYPE)src2);
363 367e86e8 bellard
}
364 367e86e8 bellard
365 367e86e8 bellard
void OPPROTO glue(op_setz_T0_sub, SUFFIX)(void)
366 367e86e8 bellard
{
367 4b74fe1f bellard
    T0 = ((DATA_TYPE)CC_DST == 0);
368 367e86e8 bellard
}
369 367e86e8 bellard
370 367e86e8 bellard
void OPPROTO glue(op_setbe_T0_sub, SUFFIX)(void)
371 367e86e8 bellard
{
372 367e86e8 bellard
    int src1, src2;
373 367e86e8 bellard
    src1 = CC_SRC;
374 367e86e8 bellard
    src2 = CC_SRC - CC_DST;
375 367e86e8 bellard
376 367e86e8 bellard
    T0 = ((DATA_TYPE)src1 <= (DATA_TYPE)src2);
377 367e86e8 bellard
}
378 367e86e8 bellard
379 367e86e8 bellard
void OPPROTO glue(op_sets_T0_sub, SUFFIX)(void)
380 367e86e8 bellard
{
381 367e86e8 bellard
    T0 = lshift(CC_DST, -(DATA_BITS - 1)) & 1;
382 367e86e8 bellard
}
383 367e86e8 bellard
384 367e86e8 bellard
void OPPROTO glue(op_setl_T0_sub, SUFFIX)(void)
385 367e86e8 bellard
{
386 367e86e8 bellard
    int src1, src2;
387 367e86e8 bellard
    src1 = CC_SRC;
388 367e86e8 bellard
    src2 = CC_SRC - CC_DST;
389 367e86e8 bellard
390 367e86e8 bellard
    T0 = ((DATA_STYPE)src1 < (DATA_STYPE)src2);
391 367e86e8 bellard
}
392 367e86e8 bellard
393 367e86e8 bellard
void OPPROTO glue(op_setle_T0_sub, SUFFIX)(void)
394 367e86e8 bellard
{
395 367e86e8 bellard
    int src1, src2;
396 367e86e8 bellard
    src1 = CC_SRC;
397 367e86e8 bellard
    src2 = CC_SRC - CC_DST;
398 367e86e8 bellard
399 367e86e8 bellard
    T0 = ((DATA_STYPE)src1 <= (DATA_STYPE)src2);
400 367e86e8 bellard
}
401 367e86e8 bellard
402 367e86e8 bellard
/* shifts */
403 367e86e8 bellard
404 367e86e8 bellard
void OPPROTO glue(glue(op_rol, SUFFIX), _T0_T1_cc)(void)
405 367e86e8 bellard
{
406 367e86e8 bellard
    int count, src;
407 367e86e8 bellard
    count = T1 & SHIFT_MASK;
408 367e86e8 bellard
    if (count) {
409 367e86e8 bellard
        CC_SRC = cc_table[CC_OP].compute_all() & ~(CC_O | CC_C);
410 367e86e8 bellard
        src = T0;
411 367e86e8 bellard
        T0 &= DATA_MASK;
412 367e86e8 bellard
        T0 = (T0 << count) | (T0 >> (DATA_BITS - count));
413 367e86e8 bellard
        CC_SRC |= (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) | 
414 367e86e8 bellard
            (T0 & CC_C);
415 367e86e8 bellard
        CC_OP = CC_OP_EFLAGS;
416 367e86e8 bellard
    }
417 4b74fe1f bellard
    FORCE_RET();
418 367e86e8 bellard
}
419 367e86e8 bellard
420 dc99065b bellard
void OPPROTO glue(glue(op_rol, SUFFIX), _T0_T1)(void)
421 dc99065b bellard
{
422 dc99065b bellard
    int count;
423 dc99065b bellard
    count = T1 & SHIFT_MASK;
424 dc99065b bellard
    if (count) {
425 dc99065b bellard
        T0 &= DATA_MASK;
426 dc99065b bellard
        T0 = (T0 << count) | (T0 >> (DATA_BITS - count));
427 dc99065b bellard
    }
428 dc99065b bellard
    FORCE_RET();
429 dc99065b bellard
}
430 dc99065b bellard
431 367e86e8 bellard
void OPPROTO glue(glue(op_ror, SUFFIX), _T0_T1_cc)(void)
432 367e86e8 bellard
{
433 367e86e8 bellard
    int count, src;
434 367e86e8 bellard
    count = T1 & SHIFT_MASK;
435 367e86e8 bellard
    if (count) {
436 367e86e8 bellard
        CC_SRC = cc_table[CC_OP].compute_all() & ~(CC_O | CC_C);
437 367e86e8 bellard
        src = T0;
438 367e86e8 bellard
        T0 &= DATA_MASK;
439 367e86e8 bellard
        T0 = (T0 >> count) | (T0 << (DATA_BITS - count));
440 367e86e8 bellard
        CC_SRC |= (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) | 
441 367e86e8 bellard
            ((T0 >> (DATA_BITS - 1)) & CC_C);
442 367e86e8 bellard
        CC_OP = CC_OP_EFLAGS;
443 367e86e8 bellard
    }
444 4b74fe1f bellard
    FORCE_RET();
445 367e86e8 bellard
}
446 367e86e8 bellard
447 dc99065b bellard
void OPPROTO glue(glue(op_ror, SUFFIX), _T0_T1)(void)
448 dc99065b bellard
{
449 dc99065b bellard
    int count;
450 dc99065b bellard
    count = T1 & SHIFT_MASK;
451 dc99065b bellard
    if (count) {
452 dc99065b bellard
        T0 &= DATA_MASK;
453 dc99065b bellard
        T0 = (T0 >> count) | (T0 << (DATA_BITS - count));
454 dc99065b bellard
    }
455 dc99065b bellard
    FORCE_RET();
456 dc99065b bellard
}
457 dc99065b bellard
458 367e86e8 bellard
void OPPROTO glue(glue(op_rcl, SUFFIX), _T0_T1_cc)(void)
459 367e86e8 bellard
{
460 367e86e8 bellard
    int count, res, eflags;
461 367e86e8 bellard
    unsigned int src;
462 367e86e8 bellard
463 367e86e8 bellard
    count = T1 & 0x1f;
464 367e86e8 bellard
#if DATA_BITS == 16
465 367e86e8 bellard
    count = rclw_table[count];
466 367e86e8 bellard
#elif DATA_BITS == 8
467 367e86e8 bellard
    count = rclb_table[count];
468 367e86e8 bellard
#endif
469 367e86e8 bellard
    if (count) {
470 367e86e8 bellard
        eflags = cc_table[CC_OP].compute_all();
471 4b74fe1f bellard
        T0 &= DATA_MASK;
472 367e86e8 bellard
        src = T0;
473 367e86e8 bellard
        res = (T0 << count) | ((eflags & CC_C) << (count - 1));
474 367e86e8 bellard
        if (count > 1)
475 367e86e8 bellard
            res |= T0 >> (DATA_BITS + 1 - count);
476 367e86e8 bellard
        T0 = res;
477 367e86e8 bellard
        CC_SRC = (eflags & ~(CC_C | CC_O)) |
478 367e86e8 bellard
            (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) | 
479 367e86e8 bellard
            ((src >> (DATA_BITS - count)) & CC_C);
480 367e86e8 bellard
        CC_OP = CC_OP_EFLAGS;
481 367e86e8 bellard
    }
482 4b74fe1f bellard
    FORCE_RET();
483 367e86e8 bellard
}
484 367e86e8 bellard
485 367e86e8 bellard
void OPPROTO glue(glue(op_rcr, SUFFIX), _T0_T1_cc)(void)
486 367e86e8 bellard
{
487 367e86e8 bellard
    int count, res, eflags;
488 367e86e8 bellard
    unsigned int src;
489 367e86e8 bellard
490 367e86e8 bellard
    count = T1 & 0x1f;
491 367e86e8 bellard
#if DATA_BITS == 16
492 367e86e8 bellard
    count = rclw_table[count];
493 367e86e8 bellard
#elif DATA_BITS == 8
494 367e86e8 bellard
    count = rclb_table[count];
495 367e86e8 bellard
#endif
496 367e86e8 bellard
    if (count) {
497 367e86e8 bellard
        eflags = cc_table[CC_OP].compute_all();
498 4b74fe1f bellard
        T0 &= DATA_MASK;
499 367e86e8 bellard
        src = T0;
500 367e86e8 bellard
        res = (T0 >> count) | ((eflags & CC_C) << (DATA_BITS - count));
501 367e86e8 bellard
        if (count > 1)
502 367e86e8 bellard
            res |= T0 << (DATA_BITS + 1 - count);
503 367e86e8 bellard
        T0 = res;
504 367e86e8 bellard
        CC_SRC = (eflags & ~(CC_C | CC_O)) |
505 367e86e8 bellard
            (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) | 
506 367e86e8 bellard
            ((src >> (count - 1)) & CC_C);
507 367e86e8 bellard
        CC_OP = CC_OP_EFLAGS;
508 367e86e8 bellard
    }
509 4b74fe1f bellard
    FORCE_RET();
510 367e86e8 bellard
}
511 367e86e8 bellard
512 367e86e8 bellard
void OPPROTO glue(glue(op_shl, SUFFIX), _T0_T1_cc)(void)
513 367e86e8 bellard
{
514 367e86e8 bellard
    int count;
515 367e86e8 bellard
    count = T1 & 0x1f;
516 d57c4e01 bellard
    if (count) {
517 d57c4e01 bellard
        CC_SRC = (DATA_TYPE)T0 << (count - 1);
518 367e86e8 bellard
        T0 = T0 << count;
519 367e86e8 bellard
        CC_DST = T0;
520 367e86e8 bellard
        CC_OP = CC_OP_SHLB + SHIFT;
521 367e86e8 bellard
    }
522 4b74fe1f bellard
    FORCE_RET();
523 367e86e8 bellard
}
524 367e86e8 bellard
525 dc99065b bellard
void OPPROTO glue(glue(op_shl, SUFFIX), _T0_T1)(void)
526 dc99065b bellard
{
527 dc99065b bellard
    int count;
528 dc99065b bellard
    count = T1 & 0x1f;
529 dc99065b bellard
    T0 = T0 << count;
530 dc99065b bellard
    FORCE_RET();
531 dc99065b bellard
}
532 dc99065b bellard
533 367e86e8 bellard
void OPPROTO glue(glue(op_shr, SUFFIX), _T0_T1_cc)(void)
534 367e86e8 bellard
{
535 367e86e8 bellard
    int count;
536 367e86e8 bellard
    count = T1 & 0x1f;
537 367e86e8 bellard
    if (count) {
538 367e86e8 bellard
        T0 &= DATA_MASK;
539 367e86e8 bellard
        CC_SRC = T0 >> (count - 1);
540 367e86e8 bellard
        T0 = T0 >> count;
541 367e86e8 bellard
        CC_DST = T0;
542 d57c4e01 bellard
        CC_OP = CC_OP_SARB + SHIFT;
543 367e86e8 bellard
    }
544 4b74fe1f bellard
    FORCE_RET();
545 367e86e8 bellard
}
546 367e86e8 bellard
547 dc99065b bellard
void OPPROTO glue(glue(op_shr, SUFFIX), _T0_T1)(void)
548 dc99065b bellard
{
549 dc99065b bellard
    int count;
550 dc99065b bellard
    count = T1 & 0x1f;
551 dc99065b bellard
    T0 &= DATA_MASK;
552 dc99065b bellard
    T0 = T0 >> count;
553 dc99065b bellard
    FORCE_RET();
554 dc99065b bellard
}
555 dc99065b bellard
556 367e86e8 bellard
void OPPROTO glue(glue(op_sar, SUFFIX), _T0_T1_cc)(void)
557 367e86e8 bellard
{
558 367e86e8 bellard
    int count, src;
559 367e86e8 bellard
    count = T1 & 0x1f;
560 367e86e8 bellard
    if (count) {
561 367e86e8 bellard
        src = (DATA_STYPE)T0;
562 d57c4e01 bellard
        CC_SRC = src >> (count - 1);
563 367e86e8 bellard
        T0 = src >> count;
564 367e86e8 bellard
        CC_DST = T0;
565 4b74fe1f bellard
        CC_OP = CC_OP_SARB + SHIFT;
566 367e86e8 bellard
    }
567 4b74fe1f bellard
    FORCE_RET();
568 367e86e8 bellard
}
569 367e86e8 bellard
570 dc99065b bellard
void OPPROTO glue(glue(op_sar, SUFFIX), _T0_T1)(void)
571 dc99065b bellard
{
572 dc99065b bellard
    int count, src;
573 dc99065b bellard
    count = T1 & 0x1f;
574 dc99065b bellard
    src = (DATA_STYPE)T0;
575 dc99065b bellard
    T0 = src >> count;
576 dc99065b bellard
    FORCE_RET();
577 dc99065b bellard
}
578 dc99065b bellard
579 d57c4e01 bellard
#if DATA_BITS == 16
580 d57c4e01 bellard
/* XXX: overflow flag might be incorrect in some cases in shldw */
581 d57c4e01 bellard
void OPPROTO glue(glue(op_shld, SUFFIX), _T0_T1_im_cc)(void)
582 d57c4e01 bellard
{
583 d57c4e01 bellard
    int count;
584 d57c4e01 bellard
    unsigned int res;
585 d57c4e01 bellard
    count = PARAM1;
586 d57c4e01 bellard
    T1 &= 0xffff;
587 d57c4e01 bellard
    res = T1 | (T0 << 16);
588 d57c4e01 bellard
    CC_SRC = res >> (32 - count);
589 d57c4e01 bellard
    res <<= count;
590 d57c4e01 bellard
    if (count > 16)
591 d57c4e01 bellard
        res |= T1 << (count - 16);
592 d57c4e01 bellard
    T0 = res >> 16;
593 d57c4e01 bellard
    CC_DST = T0;
594 d57c4e01 bellard
}
595 d57c4e01 bellard
596 d57c4e01 bellard
void OPPROTO glue(glue(op_shld, SUFFIX), _T0_T1_ECX_cc)(void)
597 d57c4e01 bellard
{
598 d57c4e01 bellard
    int count;
599 d57c4e01 bellard
    unsigned int res;
600 d57c4e01 bellard
    count = ECX & 0x1f;
601 d57c4e01 bellard
    if (count) {
602 d57c4e01 bellard
        T1 &= 0xffff;
603 d57c4e01 bellard
        res = T1 | (T0 << 16);
604 d57c4e01 bellard
        CC_SRC = res >> (32 - count);
605 d57c4e01 bellard
        res <<= count;
606 d57c4e01 bellard
        if (count > 16)
607 d57c4e01 bellard
          res |= T1 << (count - 16);
608 d57c4e01 bellard
        T0 = res >> 16;
609 d57c4e01 bellard
        CC_DST = T0;
610 d57c4e01 bellard
        CC_OP = CC_OP_SARB + SHIFT;
611 d57c4e01 bellard
    }
612 7fe70ecc bellard
    FORCE_RET();
613 d57c4e01 bellard
}
614 d57c4e01 bellard
615 d57c4e01 bellard
void OPPROTO glue(glue(op_shrd, SUFFIX), _T0_T1_im_cc)(void)
616 d57c4e01 bellard
{
617 d57c4e01 bellard
    int count;
618 d57c4e01 bellard
    unsigned int res;
619 d57c4e01 bellard
620 d57c4e01 bellard
    count = PARAM1;
621 d57c4e01 bellard
    res = (T0 & 0xffff) | (T1 << 16);
622 d57c4e01 bellard
    CC_SRC = res >> (count - 1);
623 d57c4e01 bellard
    res >>= count;
624 d57c4e01 bellard
    if (count > 16)
625 d57c4e01 bellard
        res |= T1 << (32 - count);
626 d57c4e01 bellard
    T0 = res;
627 d57c4e01 bellard
    CC_DST = T0;
628 d57c4e01 bellard
}
629 d57c4e01 bellard
630 d57c4e01 bellard
631 d57c4e01 bellard
void OPPROTO glue(glue(op_shrd, SUFFIX), _T0_T1_ECX_cc)(void)
632 d57c4e01 bellard
{
633 d57c4e01 bellard
    int count;
634 d57c4e01 bellard
    unsigned int res;
635 d57c4e01 bellard
636 d57c4e01 bellard
    count = ECX & 0x1f;
637 d57c4e01 bellard
    if (count) {
638 d57c4e01 bellard
        res = (T0 & 0xffff) | (T1 << 16);
639 d57c4e01 bellard
        CC_SRC = res >> (count - 1);
640 d57c4e01 bellard
        res >>= count;
641 d57c4e01 bellard
        if (count > 16)
642 d57c4e01 bellard
            res |= T1 << (32 - count);
643 d57c4e01 bellard
        T0 = res;
644 d57c4e01 bellard
        CC_DST = T0;
645 d57c4e01 bellard
        CC_OP = CC_OP_SARB + SHIFT;
646 d57c4e01 bellard
    }
647 7fe70ecc bellard
    FORCE_RET();
648 d57c4e01 bellard
}
649 d57c4e01 bellard
#endif
650 d57c4e01 bellard
651 d57c4e01 bellard
#if DATA_BITS == 32
652 d57c4e01 bellard
void OPPROTO glue(glue(op_shld, SUFFIX), _T0_T1_im_cc)(void)
653 d57c4e01 bellard
{
654 d57c4e01 bellard
    int count;
655 d57c4e01 bellard
    count = PARAM1;
656 d57c4e01 bellard
    T0 &= DATA_MASK;
657 d57c4e01 bellard
    T1 &= DATA_MASK;
658 d57c4e01 bellard
    CC_SRC = T0 << (count - 1);
659 d57c4e01 bellard
    T0 = (T0 << count) | (T1 >> (DATA_BITS - count));
660 d57c4e01 bellard
    CC_DST = T0;
661 d57c4e01 bellard
}
662 d57c4e01 bellard
663 d57c4e01 bellard
void OPPROTO glue(glue(op_shld, SUFFIX), _T0_T1_ECX_cc)(void)
664 d57c4e01 bellard
{
665 d57c4e01 bellard
    int count;
666 d57c4e01 bellard
    count = ECX & 0x1f;
667 d57c4e01 bellard
    if (count) {
668 d57c4e01 bellard
        T0 &= DATA_MASK;
669 d57c4e01 bellard
        T1 &= DATA_MASK;
670 d57c4e01 bellard
        CC_SRC = T0 << (count - 1);
671 d57c4e01 bellard
        T0 = (T0 << count) | (T1 >> (DATA_BITS - count));
672 d57c4e01 bellard
        CC_DST = T0;
673 d57c4e01 bellard
        CC_OP = CC_OP_SHLB + SHIFT;
674 d57c4e01 bellard
    }
675 7fe70ecc bellard
    FORCE_RET();
676 d57c4e01 bellard
}
677 d57c4e01 bellard
678 d57c4e01 bellard
void OPPROTO glue(glue(op_shrd, SUFFIX), _T0_T1_im_cc)(void)
679 d57c4e01 bellard
{
680 d57c4e01 bellard
    int count;
681 d57c4e01 bellard
    count = PARAM1;
682 d57c4e01 bellard
    T0 &= DATA_MASK;
683 d57c4e01 bellard
    T1 &= DATA_MASK;
684 d57c4e01 bellard
    CC_SRC = T0 >> (count - 1);
685 d57c4e01 bellard
    T0 = (T0 >> count) | (T1 << (DATA_BITS - count));
686 d57c4e01 bellard
    CC_DST = T0;
687 d57c4e01 bellard
}
688 d57c4e01 bellard
689 d57c4e01 bellard
690 d57c4e01 bellard
void OPPROTO glue(glue(op_shrd, SUFFIX), _T0_T1_ECX_cc)(void)
691 d57c4e01 bellard
{
692 d57c4e01 bellard
    int count;
693 d57c4e01 bellard
    count = ECX & 0x1f;
694 d57c4e01 bellard
    if (count) {
695 d57c4e01 bellard
        T0 &= DATA_MASK;
696 d57c4e01 bellard
        T1 &= DATA_MASK;
697 d57c4e01 bellard
        CC_SRC = T0 >> (count - 1);
698 d57c4e01 bellard
        T0 = (T0 >> count) | (T1 << (DATA_BITS - count));
699 d57c4e01 bellard
        CC_DST = T0;
700 d57c4e01 bellard
        CC_OP = CC_OP_SARB + SHIFT;
701 d57c4e01 bellard
    }
702 7fe70ecc bellard
    FORCE_RET();
703 d57c4e01 bellard
}
704 d57c4e01 bellard
#endif
705 d57c4e01 bellard
706 4b74fe1f bellard
/* carry add/sub (we only need to set CC_OP differently) */
707 4b74fe1f bellard
708 4b74fe1f bellard
void OPPROTO glue(glue(op_adc, SUFFIX), _T0_T1_cc)(void)
709 4b74fe1f bellard
{
710 4b74fe1f bellard
    int cf;
711 4b74fe1f bellard
    cf = cc_table[CC_OP].compute_c();
712 4b74fe1f bellard
    CC_SRC = T0;
713 4b74fe1f bellard
    T0 = T0 + T1 + cf;
714 4b74fe1f bellard
    CC_DST = T0;
715 4b74fe1f bellard
    CC_OP = CC_OP_ADDB + SHIFT + cf * 3;
716 4b74fe1f bellard
}
717 4b74fe1f bellard
718 4b74fe1f bellard
void OPPROTO glue(glue(op_sbb, SUFFIX), _T0_T1_cc)(void)
719 4b74fe1f bellard
{
720 4b74fe1f bellard
    int cf;
721 4b74fe1f bellard
    cf = cc_table[CC_OP].compute_c();
722 4b74fe1f bellard
    CC_SRC = T0;
723 4b74fe1f bellard
    T0 = T0 - T1 - cf;
724 4b74fe1f bellard
    CC_DST = T0;
725 4b74fe1f bellard
    CC_OP = CC_OP_SUBB + SHIFT + cf * 3;
726 4b74fe1f bellard
}
727 4b74fe1f bellard
728 1a9353d2 bellard
void OPPROTO glue(glue(op_cmpxchg, SUFFIX), _T0_T1_EAX_cc)(void)
729 1a9353d2 bellard
{
730 1a9353d2 bellard
    CC_SRC = EAX;
731 1a9353d2 bellard
    CC_DST = EAX - T0;
732 1a9353d2 bellard
    if ((DATA_TYPE)CC_DST == 0) {
733 1a9353d2 bellard
        T0 = T1;
734 1a9353d2 bellard
    } else {
735 1a9353d2 bellard
        EAX = (EAX & ~DATA_MASK) | (T0 & DATA_MASK);
736 1a9353d2 bellard
    }
737 1a9353d2 bellard
    FORCE_RET();
738 1a9353d2 bellard
}
739 1a9353d2 bellard
740 4b74fe1f bellard
/* bit operations */
741 4b74fe1f bellard
#if DATA_BITS >= 16
742 4b74fe1f bellard
743 4b74fe1f bellard
void OPPROTO glue(glue(op_bt, SUFFIX), _T0_T1_cc)(void)
744 4b74fe1f bellard
{
745 4b74fe1f bellard
    int count;
746 4b74fe1f bellard
    count = T1 & SHIFT_MASK;
747 4b74fe1f bellard
    CC_SRC = T0 >> count;
748 4b74fe1f bellard
}
749 4b74fe1f bellard
750 4b74fe1f bellard
void OPPROTO glue(glue(op_bts, SUFFIX), _T0_T1_cc)(void)
751 4b74fe1f bellard
{
752 4b74fe1f bellard
    int count;
753 4b74fe1f bellard
    count = T1 & SHIFT_MASK;
754 4b74fe1f bellard
    CC_SRC = T0 >> count;
755 4b74fe1f bellard
    T0 |= (1 << count);
756 4b74fe1f bellard
}
757 4b74fe1f bellard
758 4b74fe1f bellard
void OPPROTO glue(glue(op_btr, SUFFIX), _T0_T1_cc)(void)
759 4b74fe1f bellard
{
760 4b74fe1f bellard
    int count;
761 4b74fe1f bellard
    count = T1 & SHIFT_MASK;
762 4b74fe1f bellard
    CC_SRC = T0 >> count;
763 4b74fe1f bellard
    T0 &= ~(1 << count);
764 4b74fe1f bellard
}
765 4b74fe1f bellard
766 4b74fe1f bellard
void OPPROTO glue(glue(op_btc, SUFFIX), _T0_T1_cc)(void)
767 4b74fe1f bellard
{
768 4b74fe1f bellard
    int count;
769 4b74fe1f bellard
    count = T1 & SHIFT_MASK;
770 4b74fe1f bellard
    CC_SRC = T0 >> count;
771 4b74fe1f bellard
    T0 ^= (1 << count);
772 4b74fe1f bellard
}
773 4b74fe1f bellard
774 77f8dd5a bellard
void OPPROTO glue(glue(op_bsf, SUFFIX), _T0_cc)(void)
775 77f8dd5a bellard
{
776 77f8dd5a bellard
    int res, count;
777 77f8dd5a bellard
    res = T0 & DATA_MASK;
778 77f8dd5a bellard
    if (res != 0) {
779 77f8dd5a bellard
        count = 0;
780 77f8dd5a bellard
        while ((res & 1) == 0) {
781 77f8dd5a bellard
            count++;
782 77f8dd5a bellard
            res >>= 1;
783 77f8dd5a bellard
        }
784 77f8dd5a bellard
        T0 = count;
785 77f8dd5a bellard
        CC_DST = 1; /* ZF = 1 */
786 77f8dd5a bellard
    } else {
787 77f8dd5a bellard
        CC_DST = 0; /* ZF = 1 */
788 77f8dd5a bellard
    }
789 77f8dd5a bellard
    FORCE_RET();
790 77f8dd5a bellard
}
791 77f8dd5a bellard
792 77f8dd5a bellard
void OPPROTO glue(glue(op_bsr, SUFFIX), _T0_cc)(void)
793 77f8dd5a bellard
{
794 77f8dd5a bellard
    int res, count;
795 77f8dd5a bellard
    res = T0 & DATA_MASK;
796 77f8dd5a bellard
    if (res != 0) {
797 77f8dd5a bellard
        count = DATA_BITS - 1;
798 77f8dd5a bellard
        while ((res & SIGN_MASK) == 0) {
799 77f8dd5a bellard
            count--;
800 77f8dd5a bellard
            res <<= 1;
801 77f8dd5a bellard
        }
802 77f8dd5a bellard
        T0 = count;
803 77f8dd5a bellard
        CC_DST = 1; /* ZF = 1 */
804 77f8dd5a bellard
    } else {
805 77f8dd5a bellard
        CC_DST = 0; /* ZF = 1 */
806 77f8dd5a bellard
    }
807 77f8dd5a bellard
    FORCE_RET();
808 77f8dd5a bellard
}
809 77f8dd5a bellard
810 4b74fe1f bellard
#endif
811 4b74fe1f bellard
812 367e86e8 bellard
/* string operations */
813 24f9e90b bellard
/* XXX: maybe use lower level instructions to ease 16 bit / segment handling */
814 24f9e90b bellard
815 24f9e90b bellard
#define STRING_SUFFIX _fast
816 24f9e90b bellard
#define SI_ADDR (void *)ESI
817 24f9e90b bellard
#define DI_ADDR (void *)EDI
818 24f9e90b bellard
#define INC_SI() ESI += inc
819 24f9e90b bellard
#define INC_DI() EDI += inc
820 24f9e90b bellard
#define CX ECX
821 24f9e90b bellard
#define DEC_CX() ECX--
822 24f9e90b bellard
#include "op_string.h"
823 24f9e90b bellard
824 24f9e90b bellard
#define STRING_SUFFIX _a32
825 24f9e90b bellard
#define SI_ADDR (uint8_t *)A0 + ESI
826 24f9e90b bellard
#define DI_ADDR env->seg_cache[R_ES].base + EDI
827 24f9e90b bellard
#define INC_SI() ESI += inc
828 24f9e90b bellard
#define INC_DI() EDI += inc
829 24f9e90b bellard
#define CX ECX
830 24f9e90b bellard
#define DEC_CX() ECX--
831 24f9e90b bellard
#include "op_string.h"
832 24f9e90b bellard
833 24f9e90b bellard
#define STRING_SUFFIX _a16
834 24f9e90b bellard
#define SI_ADDR (uint8_t *)A0 + (ESI & 0xffff)
835 24f9e90b bellard
#define DI_ADDR env->seg_cache[R_ES].base + (EDI & 0xffff)
836 24f9e90b bellard
#define INC_SI() ESI = (ESI & ~0xffff) | ((ESI + inc) & 0xffff)
837 24f9e90b bellard
#define INC_DI() EDI = (EDI & ~0xffff) | ((EDI + inc) & 0xffff)
838 24f9e90b bellard
#define CX (ECX & 0xffff)
839 24f9e90b bellard
#define DEC_CX() ECX = (ECX & ~0xffff) | ((ECX - 1) & 0xffff)
840 24f9e90b bellard
#include "op_string.h"
841 367e86e8 bellard
842 ba1c6e37 bellard
/* port I/O */
843 ba1c6e37 bellard
844 ba1c6e37 bellard
void OPPROTO glue(glue(op_out, SUFFIX), _T0_T1)(void)
845 ba1c6e37 bellard
{
846 ba1c6e37 bellard
    glue(cpu_x86_out, SUFFIX)(T0 & 0xffff, T1 & DATA_MASK);
847 ba1c6e37 bellard
}
848 ba1c6e37 bellard
849 ba1c6e37 bellard
void OPPROTO glue(glue(op_in, SUFFIX), _T0_T1)(void)
850 ba1c6e37 bellard
{
851 ba1c6e37 bellard
    T1 = glue(cpu_x86_in, SUFFIX)(T0 & 0xffff);
852 ba1c6e37 bellard
}
853 ba1c6e37 bellard
854 367e86e8 bellard
#undef DATA_BITS
855 367e86e8 bellard
#undef SHIFT_MASK
856 367e86e8 bellard
#undef SIGN_MASK
857 367e86e8 bellard
#undef DATA_TYPE
858 367e86e8 bellard
#undef DATA_STYPE
859 367e86e8 bellard
#undef DATA_MASK
860 367e86e8 bellard
#undef SUFFIX