Statistics
| Branch: | Revision:

root / ops_template.h @ 2c1794c4

History | View | Annotate | Download (12.7 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 5797fa5d bellard
    src1 = CC_DST + CC_SRC;
97 5797fa5d bellard
    src2 = CC_SRC;
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 5797fa5d bellard
    src1 = CC_DST + CC_SRC;
111 5797fa5d bellard
    src2 = CC_SRC;
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 5797fa5d bellard
    src1 = CC_DST + CC_SRC + 1;
121 5797fa5d bellard
    src2 = CC_SRC;
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 5797fa5d bellard
    src1 = CC_DST + CC_SRC + 1;
135 5797fa5d bellard
    src2 = CC_SRC;
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 367e86e8 bellard
static int glue(compute_c_shl, SUFFIX)(void)
208 367e86e8 bellard
{
209 72cc3881 bellard
    return (CC_SRC >> (DATA_BITS - 1)) & CC_C;
210 72cc3881 bellard
}
211 72cc3881 bellard
212 72cc3881 bellard
#if DATA_BITS == 32
213 72cc3881 bellard
static int glue(compute_c_sar, SUFFIX)(void)
214 72cc3881 bellard
{
215 367e86e8 bellard
    return CC_SRC & 1;
216 367e86e8 bellard
}
217 4b74fe1f bellard
#endif
218 4b74fe1f bellard
219 4b74fe1f bellard
static int glue(compute_all_sar, SUFFIX)(void)
220 4b74fe1f bellard
{
221 4b74fe1f bellard
    int cf, pf, af, zf, sf, of;
222 4b74fe1f bellard
    cf = CC_SRC & 1;
223 4b74fe1f bellard
    pf = parity_table[(uint8_t)CC_DST];
224 4b74fe1f bellard
    af = 0; /* undefined */
225 4b74fe1f bellard
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
226 4b74fe1f bellard
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
227 d57c4e01 bellard
    /* of is defined if shift count == 1 */
228 d57c4e01 bellard
    of = lshift(CC_SRC ^ CC_DST, 12 - DATA_BITS) & CC_O; 
229 4b74fe1f bellard
    return cf | pf | af | zf | sf | of;
230 4b74fe1f bellard
}
231 367e86e8 bellard
232 367e86e8 bellard
/* various optimized jumps cases */
233 367e86e8 bellard
234 367e86e8 bellard
void OPPROTO glue(op_jb_sub, SUFFIX)(void)
235 367e86e8 bellard
{
236 367e86e8 bellard
    int src1, src2;
237 5797fa5d bellard
    src1 = CC_DST + CC_SRC;
238 5797fa5d bellard
    src2 = CC_SRC;
239 367e86e8 bellard
240 367e86e8 bellard
    if ((DATA_TYPE)src1 < (DATA_TYPE)src2)
241 d4e8164f bellard
        JUMP_TB(PARAM1, 0, PARAM2);
242 367e86e8 bellard
    else
243 d4e8164f bellard
        JUMP_TB(PARAM1, 1, PARAM3);
244 367e86e8 bellard
    FORCE_RET();
245 367e86e8 bellard
}
246 367e86e8 bellard
247 367e86e8 bellard
void OPPROTO glue(op_jz_sub, SUFFIX)(void)
248 367e86e8 bellard
{
249 4b74fe1f bellard
    if ((DATA_TYPE)CC_DST == 0)
250 d4e8164f bellard
        JUMP_TB(PARAM1, 0, PARAM2);
251 367e86e8 bellard
    else
252 d4e8164f bellard
        JUMP_TB(PARAM1, 1, PARAM3);
253 367e86e8 bellard
    FORCE_RET();
254 367e86e8 bellard
}
255 367e86e8 bellard
256 367e86e8 bellard
void OPPROTO glue(op_jbe_sub, SUFFIX)(void)
257 367e86e8 bellard
{
258 367e86e8 bellard
    int src1, src2;
259 5797fa5d bellard
    src1 = CC_DST + CC_SRC;
260 5797fa5d bellard
    src2 = CC_SRC;
261 367e86e8 bellard
262 367e86e8 bellard
    if ((DATA_TYPE)src1 <= (DATA_TYPE)src2)
263 d4e8164f bellard
        JUMP_TB(PARAM1, 0, PARAM2);
264 367e86e8 bellard
    else
265 d4e8164f bellard
        JUMP_TB(PARAM1, 1, PARAM3);
266 367e86e8 bellard
    FORCE_RET();
267 367e86e8 bellard
}
268 367e86e8 bellard
269 367e86e8 bellard
void OPPROTO glue(op_js_sub, SUFFIX)(void)
270 367e86e8 bellard
{
271 367e86e8 bellard
    if (CC_DST & SIGN_MASK)
272 d4e8164f bellard
        JUMP_TB(PARAM1, 0, PARAM2);
273 367e86e8 bellard
    else
274 d4e8164f bellard
        JUMP_TB(PARAM1, 1, PARAM3);
275 367e86e8 bellard
    FORCE_RET();
276 367e86e8 bellard
}
277 367e86e8 bellard
278 367e86e8 bellard
void OPPROTO glue(op_jl_sub, SUFFIX)(void)
279 367e86e8 bellard
{
280 367e86e8 bellard
    int src1, src2;
281 5797fa5d bellard
    src1 = CC_DST + CC_SRC;
282 5797fa5d bellard
    src2 = CC_SRC;
283 367e86e8 bellard
284 367e86e8 bellard
    if ((DATA_STYPE)src1 < (DATA_STYPE)src2)
285 d4e8164f bellard
        JUMP_TB(PARAM1, 0, PARAM2);
286 367e86e8 bellard
    else
287 d4e8164f bellard
        JUMP_TB(PARAM1, 1, PARAM3);
288 367e86e8 bellard
    FORCE_RET();
289 367e86e8 bellard
}
290 367e86e8 bellard
291 367e86e8 bellard
void OPPROTO glue(op_jle_sub, SUFFIX)(void)
292 367e86e8 bellard
{
293 367e86e8 bellard
    int src1, src2;
294 5797fa5d bellard
    src1 = CC_DST + CC_SRC;
295 5797fa5d bellard
    src2 = CC_SRC;
296 367e86e8 bellard
297 367e86e8 bellard
    if ((DATA_STYPE)src1 <= (DATA_STYPE)src2)
298 d4e8164f bellard
        JUMP_TB(PARAM1, 0, PARAM2);
299 367e86e8 bellard
    else
300 d4e8164f bellard
        JUMP_TB(PARAM1, 1, PARAM3);
301 367e86e8 bellard
    FORCE_RET();
302 367e86e8 bellard
}
303 367e86e8 bellard
304 1a9353d2 bellard
/* oldies */
305 1a9353d2 bellard
306 1a9353d2 bellard
#if DATA_BITS >= 16
307 1a9353d2 bellard
308 1a9353d2 bellard
void OPPROTO glue(op_loopnz, SUFFIX)(void)
309 1a9353d2 bellard
{
310 1a9353d2 bellard
    unsigned int tmp;
311 1a9353d2 bellard
    int eflags;
312 1a9353d2 bellard
    eflags = cc_table[CC_OP].compute_all();
313 1a9353d2 bellard
    tmp = (ECX - 1) & DATA_MASK;
314 1a9353d2 bellard
    ECX = (ECX & ~DATA_MASK) | tmp;
315 1a9353d2 bellard
    if (tmp != 0 && !(eflags & CC_Z))
316 dab2ed99 bellard
        EIP = PARAM1;
317 1a9353d2 bellard
    else
318 dab2ed99 bellard
        EIP = PARAM2;
319 1a9353d2 bellard
    FORCE_RET();
320 1a9353d2 bellard
}
321 1a9353d2 bellard
322 1a9353d2 bellard
void OPPROTO glue(op_loopz, SUFFIX)(void)
323 1a9353d2 bellard
{
324 1a9353d2 bellard
    unsigned int tmp;
325 1a9353d2 bellard
    int eflags;
326 1a9353d2 bellard
    eflags = cc_table[CC_OP].compute_all();
327 1a9353d2 bellard
    tmp = (ECX - 1) & DATA_MASK;
328 1a9353d2 bellard
    ECX = (ECX & ~DATA_MASK) | tmp;
329 1a9353d2 bellard
    if (tmp != 0 && (eflags & CC_Z))
330 dab2ed99 bellard
        EIP = PARAM1;
331 1a9353d2 bellard
    else
332 dab2ed99 bellard
        EIP = PARAM2;
333 1a9353d2 bellard
    FORCE_RET();
334 1a9353d2 bellard
}
335 1a9353d2 bellard
336 1a9353d2 bellard
void OPPROTO glue(op_loop, SUFFIX)(void)
337 1a9353d2 bellard
{
338 1a9353d2 bellard
    unsigned int tmp;
339 1a9353d2 bellard
    tmp = (ECX - 1) & DATA_MASK;
340 1a9353d2 bellard
    ECX = (ECX & ~DATA_MASK) | tmp;
341 1a9353d2 bellard
    if (tmp != 0)
342 dab2ed99 bellard
        EIP = PARAM1;
343 1a9353d2 bellard
    else
344 dab2ed99 bellard
        EIP = PARAM2;
345 1a9353d2 bellard
    FORCE_RET();
346 1a9353d2 bellard
}
347 1a9353d2 bellard
348 1a9353d2 bellard
void OPPROTO glue(op_jecxz, SUFFIX)(void)
349 1a9353d2 bellard
{
350 1a9353d2 bellard
    if ((DATA_TYPE)ECX == 0)
351 dab2ed99 bellard
        EIP = PARAM1;
352 1a9353d2 bellard
    else
353 dab2ed99 bellard
        EIP = PARAM2;
354 1a9353d2 bellard
    FORCE_RET();
355 1a9353d2 bellard
}
356 1a9353d2 bellard
357 1a9353d2 bellard
#endif
358 1a9353d2 bellard
359 367e86e8 bellard
/* various optimized set cases */
360 367e86e8 bellard
361 367e86e8 bellard
void OPPROTO glue(op_setb_T0_sub, SUFFIX)(void)
362 367e86e8 bellard
{
363 367e86e8 bellard
    int src1, src2;
364 5797fa5d bellard
    src1 = CC_DST + CC_SRC;
365 5797fa5d bellard
    src2 = CC_SRC;
366 367e86e8 bellard
367 367e86e8 bellard
    T0 = ((DATA_TYPE)src1 < (DATA_TYPE)src2);
368 367e86e8 bellard
}
369 367e86e8 bellard
370 367e86e8 bellard
void OPPROTO glue(op_setz_T0_sub, SUFFIX)(void)
371 367e86e8 bellard
{
372 4b74fe1f bellard
    T0 = ((DATA_TYPE)CC_DST == 0);
373 367e86e8 bellard
}
374 367e86e8 bellard
375 367e86e8 bellard
void OPPROTO glue(op_setbe_T0_sub, SUFFIX)(void)
376 367e86e8 bellard
{
377 367e86e8 bellard
    int src1, src2;
378 5797fa5d bellard
    src1 = CC_DST + CC_SRC;
379 5797fa5d bellard
    src2 = CC_SRC;
380 367e86e8 bellard
381 367e86e8 bellard
    T0 = ((DATA_TYPE)src1 <= (DATA_TYPE)src2);
382 367e86e8 bellard
}
383 367e86e8 bellard
384 367e86e8 bellard
void OPPROTO glue(op_sets_T0_sub, SUFFIX)(void)
385 367e86e8 bellard
{
386 367e86e8 bellard
    T0 = lshift(CC_DST, -(DATA_BITS - 1)) & 1;
387 367e86e8 bellard
}
388 367e86e8 bellard
389 367e86e8 bellard
void OPPROTO glue(op_setl_T0_sub, SUFFIX)(void)
390 367e86e8 bellard
{
391 367e86e8 bellard
    int src1, src2;
392 5797fa5d bellard
    src1 = CC_DST + CC_SRC;
393 5797fa5d bellard
    src2 = CC_SRC;
394 367e86e8 bellard
395 367e86e8 bellard
    T0 = ((DATA_STYPE)src1 < (DATA_STYPE)src2);
396 367e86e8 bellard
}
397 367e86e8 bellard
398 367e86e8 bellard
void OPPROTO glue(op_setle_T0_sub, SUFFIX)(void)
399 367e86e8 bellard
{
400 367e86e8 bellard
    int src1, src2;
401 5797fa5d bellard
    src1 = CC_DST + CC_SRC;
402 5797fa5d bellard
    src2 = CC_SRC;
403 367e86e8 bellard
404 367e86e8 bellard
    T0 = ((DATA_STYPE)src1 <= (DATA_STYPE)src2);
405 367e86e8 bellard
}
406 367e86e8 bellard
407 367e86e8 bellard
/* shifts */
408 367e86e8 bellard
409 dc99065b bellard
void OPPROTO glue(glue(op_shl, SUFFIX), _T0_T1)(void)
410 dc99065b bellard
{
411 dc99065b bellard
    int count;
412 dc99065b bellard
    count = T1 & 0x1f;
413 dc99065b bellard
    T0 = T0 << count;
414 dc99065b bellard
    FORCE_RET();
415 dc99065b bellard
}
416 dc99065b bellard
417 dc99065b bellard
void OPPROTO glue(glue(op_shr, SUFFIX), _T0_T1)(void)
418 dc99065b bellard
{
419 dc99065b bellard
    int count;
420 dc99065b bellard
    count = T1 & 0x1f;
421 dc99065b bellard
    T0 &= DATA_MASK;
422 dc99065b bellard
    T0 = T0 >> count;
423 dc99065b bellard
    FORCE_RET();
424 dc99065b bellard
}
425 dc99065b bellard
426 dc99065b bellard
void OPPROTO glue(glue(op_sar, SUFFIX), _T0_T1)(void)
427 dc99065b bellard
{
428 dc99065b bellard
    int count, src;
429 dc99065b bellard
    count = T1 & 0x1f;
430 dc99065b bellard
    src = (DATA_STYPE)T0;
431 dc99065b bellard
    T0 = src >> count;
432 dc99065b bellard
    FORCE_RET();
433 dc99065b bellard
}
434 dc99065b bellard
435 e477b8b8 bellard
#undef MEM_WRITE
436 e477b8b8 bellard
#include "ops_template_mem.h"
437 d57c4e01 bellard
438 e477b8b8 bellard
#define MEM_WRITE
439 e477b8b8 bellard
#include "ops_template_mem.h"
440 1a9353d2 bellard
441 4b74fe1f bellard
/* bit operations */
442 4b74fe1f bellard
#if DATA_BITS >= 16
443 4b74fe1f bellard
444 4b74fe1f bellard
void OPPROTO glue(glue(op_bt, SUFFIX), _T0_T1_cc)(void)
445 4b74fe1f bellard
{
446 4b74fe1f bellard
    int count;
447 4b74fe1f bellard
    count = T1 & SHIFT_MASK;
448 4b74fe1f bellard
    CC_SRC = T0 >> count;
449 4b74fe1f bellard
}
450 4b74fe1f bellard
451 4b74fe1f bellard
void OPPROTO glue(glue(op_bts, SUFFIX), _T0_T1_cc)(void)
452 4b74fe1f bellard
{
453 4b74fe1f bellard
    int count;
454 4b74fe1f bellard
    count = T1 & SHIFT_MASK;
455 e477b8b8 bellard
    T1 = T0 >> count;
456 4b74fe1f bellard
    T0 |= (1 << count);
457 4b74fe1f bellard
}
458 4b74fe1f bellard
459 4b74fe1f bellard
void OPPROTO glue(glue(op_btr, SUFFIX), _T0_T1_cc)(void)
460 4b74fe1f bellard
{
461 4b74fe1f bellard
    int count;
462 4b74fe1f bellard
    count = T1 & SHIFT_MASK;
463 e477b8b8 bellard
    T1 = T0 >> count;
464 4b74fe1f bellard
    T0 &= ~(1 << count);
465 4b74fe1f bellard
}
466 4b74fe1f bellard
467 4b74fe1f bellard
void OPPROTO glue(glue(op_btc, SUFFIX), _T0_T1_cc)(void)
468 4b74fe1f bellard
{
469 4b74fe1f bellard
    int count;
470 4b74fe1f bellard
    count = T1 & SHIFT_MASK;
471 e477b8b8 bellard
    T1 = T0 >> count;
472 4b74fe1f bellard
    T0 ^= (1 << count);
473 4b74fe1f bellard
}
474 4b74fe1f bellard
475 77f8dd5a bellard
void OPPROTO glue(glue(op_bsf, SUFFIX), _T0_cc)(void)
476 77f8dd5a bellard
{
477 77f8dd5a bellard
    int res, count;
478 77f8dd5a bellard
    res = T0 & DATA_MASK;
479 77f8dd5a bellard
    if (res != 0) {
480 77f8dd5a bellard
        count = 0;
481 77f8dd5a bellard
        while ((res & 1) == 0) {
482 77f8dd5a bellard
            count++;
483 77f8dd5a bellard
            res >>= 1;
484 77f8dd5a bellard
        }
485 77f8dd5a bellard
        T0 = count;
486 77f8dd5a bellard
        CC_DST = 1; /* ZF = 1 */
487 77f8dd5a bellard
    } else {
488 77f8dd5a bellard
        CC_DST = 0; /* ZF = 1 */
489 77f8dd5a bellard
    }
490 77f8dd5a bellard
    FORCE_RET();
491 77f8dd5a bellard
}
492 77f8dd5a bellard
493 77f8dd5a bellard
void OPPROTO glue(glue(op_bsr, SUFFIX), _T0_cc)(void)
494 77f8dd5a bellard
{
495 77f8dd5a bellard
    int res, count;
496 77f8dd5a bellard
    res = T0 & DATA_MASK;
497 77f8dd5a bellard
    if (res != 0) {
498 77f8dd5a bellard
        count = DATA_BITS - 1;
499 77f8dd5a bellard
        while ((res & SIGN_MASK) == 0) {
500 77f8dd5a bellard
            count--;
501 77f8dd5a bellard
            res <<= 1;
502 77f8dd5a bellard
        }
503 77f8dd5a bellard
        T0 = count;
504 77f8dd5a bellard
        CC_DST = 1; /* ZF = 1 */
505 77f8dd5a bellard
    } else {
506 77f8dd5a bellard
        CC_DST = 0; /* ZF = 1 */
507 77f8dd5a bellard
    }
508 77f8dd5a bellard
    FORCE_RET();
509 77f8dd5a bellard
}
510 77f8dd5a bellard
511 4b74fe1f bellard
#endif
512 4b74fe1f bellard
513 e477b8b8 bellard
#if DATA_BITS == 32
514 e477b8b8 bellard
void OPPROTO op_update_bt_cc(void)
515 e477b8b8 bellard
{
516 e477b8b8 bellard
    CC_SRC = T1;
517 e477b8b8 bellard
}
518 e477b8b8 bellard
#endif
519 e477b8b8 bellard
520 367e86e8 bellard
/* string operations */
521 24f9e90b bellard
/* XXX: maybe use lower level instructions to ease 16 bit / segment handling */
522 24f9e90b bellard
523 24f9e90b bellard
#define STRING_SUFFIX _fast
524 24f9e90b bellard
#define SI_ADDR (void *)ESI
525 24f9e90b bellard
#define DI_ADDR (void *)EDI
526 24f9e90b bellard
#define INC_SI() ESI += inc
527 24f9e90b bellard
#define INC_DI() EDI += inc
528 24f9e90b bellard
#define CX ECX
529 24f9e90b bellard
#define DEC_CX() ECX--
530 24f9e90b bellard
#include "op_string.h"
531 24f9e90b bellard
532 24f9e90b bellard
#define STRING_SUFFIX _a32
533 24f9e90b bellard
#define SI_ADDR (uint8_t *)A0 + ESI
534 970a87a6 bellard
#define DI_ADDR env->segs[R_ES].base + EDI
535 24f9e90b bellard
#define INC_SI() ESI += inc
536 24f9e90b bellard
#define INC_DI() EDI += inc
537 24f9e90b bellard
#define CX ECX
538 24f9e90b bellard
#define DEC_CX() ECX--
539 24f9e90b bellard
#include "op_string.h"
540 24f9e90b bellard
541 24f9e90b bellard
#define STRING_SUFFIX _a16
542 24f9e90b bellard
#define SI_ADDR (uint8_t *)A0 + (ESI & 0xffff)
543 970a87a6 bellard
#define DI_ADDR env->segs[R_ES].base + (EDI & 0xffff)
544 24f9e90b bellard
#define INC_SI() ESI = (ESI & ~0xffff) | ((ESI + inc) & 0xffff)
545 24f9e90b bellard
#define INC_DI() EDI = (EDI & ~0xffff) | ((EDI + inc) & 0xffff)
546 24f9e90b bellard
#define CX (ECX & 0xffff)
547 24f9e90b bellard
#define DEC_CX() ECX = (ECX & ~0xffff) | ((ECX - 1) & 0xffff)
548 24f9e90b bellard
#include "op_string.h"
549 367e86e8 bellard
550 ba1c6e37 bellard
/* port I/O */
551 ba1c6e37 bellard
552 ba1c6e37 bellard
void OPPROTO glue(glue(op_out, SUFFIX), _T0_T1)(void)
553 ba1c6e37 bellard
{
554 bf7c65bd bellard
    glue(cpu_x86_out, SUFFIX)(env, T0 & 0xffff, T1 & DATA_MASK);
555 ba1c6e37 bellard
}
556 ba1c6e37 bellard
557 ba1c6e37 bellard
void OPPROTO glue(glue(op_in, SUFFIX), _T0_T1)(void)
558 ba1c6e37 bellard
{
559 bf7c65bd bellard
    T1 = glue(cpu_x86_in, SUFFIX)(env, T0 & 0xffff);
560 ba1c6e37 bellard
}
561 ba1c6e37 bellard
562 367e86e8 bellard
#undef DATA_BITS
563 367e86e8 bellard
#undef SHIFT_MASK
564 367e86e8 bellard
#undef SIGN_MASK
565 367e86e8 bellard
#undef DATA_TYPE
566 367e86e8 bellard
#undef DATA_STYPE
567 367e86e8 bellard
#undef DATA_MASK
568 367e86e8 bellard
#undef SUFFIX