Statistics
| Branch: | Revision:

root / ops_template.h @ 4b74fe1f

History | View | Annotate | Download (16.5 kB)

1 367e86e8 bellard
2 367e86e8 bellard
#define DATA_BITS (1 << (3 + SHIFT))
3 367e86e8 bellard
#define SHIFT_MASK (DATA_BITS - 1)
4 367e86e8 bellard
#define SIGN_MASK (1 << (DATA_BITS - 1))
5 367e86e8 bellard
6 367e86e8 bellard
#if DATA_BITS == 8
7 367e86e8 bellard
#define SUFFIX b
8 367e86e8 bellard
#define DATA_TYPE uint8_t
9 367e86e8 bellard
#define DATA_STYPE int8_t
10 367e86e8 bellard
#define DATA_MASK 0xff
11 367e86e8 bellard
#elif DATA_BITS == 16
12 367e86e8 bellard
#define SUFFIX w
13 367e86e8 bellard
#define DATA_TYPE uint16_t
14 367e86e8 bellard
#define DATA_STYPE int16_t
15 367e86e8 bellard
#define DATA_MASK 0xffff
16 367e86e8 bellard
#elif DATA_BITS == 32
17 367e86e8 bellard
#define SUFFIX l
18 367e86e8 bellard
#define DATA_TYPE uint32_t
19 367e86e8 bellard
#define DATA_STYPE int32_t
20 367e86e8 bellard
#define DATA_MASK 0xffffffff
21 367e86e8 bellard
#else
22 367e86e8 bellard
#error unhandled operand size
23 367e86e8 bellard
#endif
24 367e86e8 bellard
25 367e86e8 bellard
/* dynamic flags computation */
26 367e86e8 bellard
27 367e86e8 bellard
static int glue(compute_all_add, SUFFIX)(void)
28 367e86e8 bellard
{
29 367e86e8 bellard
    int cf, pf, af, zf, sf, of;
30 367e86e8 bellard
    int src1, src2;
31 367e86e8 bellard
    src1 = CC_SRC;
32 367e86e8 bellard
    src2 = CC_DST - CC_SRC;
33 367e86e8 bellard
    cf = (DATA_TYPE)CC_DST < (DATA_TYPE)src1;
34 367e86e8 bellard
    pf = parity_table[(uint8_t)CC_DST];
35 367e86e8 bellard
    af = (CC_DST ^ src1 ^ src2) & 0x10;
36 4b74fe1f bellard
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
37 367e86e8 bellard
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
38 367e86e8 bellard
    of = lshift((src1 ^ src2 ^ -1) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
39 367e86e8 bellard
    return cf | pf | af | zf | sf | of;
40 367e86e8 bellard
}
41 367e86e8 bellard
42 367e86e8 bellard
static int glue(compute_c_add, SUFFIX)(void)
43 367e86e8 bellard
{
44 367e86e8 bellard
    int src1, cf;
45 367e86e8 bellard
    src1 = CC_SRC;
46 367e86e8 bellard
    cf = (DATA_TYPE)CC_DST < (DATA_TYPE)src1;
47 367e86e8 bellard
    return cf;
48 367e86e8 bellard
}
49 367e86e8 bellard
50 4b74fe1f bellard
static int glue(compute_all_adc, SUFFIX)(void)
51 4b74fe1f bellard
{
52 4b74fe1f bellard
    int cf, pf, af, zf, sf, of;
53 4b74fe1f bellard
    int src1, src2;
54 4b74fe1f bellard
    src1 = CC_SRC;
55 4b74fe1f bellard
    src2 = CC_DST - CC_SRC - 1;
56 4b74fe1f bellard
    cf = (DATA_TYPE)CC_DST <= (DATA_TYPE)src1;
57 4b74fe1f bellard
    pf = parity_table[(uint8_t)CC_DST];
58 4b74fe1f bellard
    af = (CC_DST ^ src1 ^ src2) & 0x10;
59 4b74fe1f bellard
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
60 4b74fe1f bellard
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
61 4b74fe1f bellard
    of = lshift((src1 ^ src2 ^ -1) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
62 4b74fe1f bellard
    return cf | pf | af | zf | sf | of;
63 4b74fe1f bellard
}
64 4b74fe1f bellard
65 4b74fe1f bellard
static int glue(compute_c_adc, SUFFIX)(void)
66 4b74fe1f bellard
{
67 4b74fe1f bellard
    int src1, cf;
68 4b74fe1f bellard
    src1 = CC_SRC;
69 4b74fe1f bellard
    cf = (DATA_TYPE)CC_DST <= (DATA_TYPE)src1;
70 4b74fe1f bellard
    return cf;
71 4b74fe1f bellard
}
72 4b74fe1f bellard
73 367e86e8 bellard
static int glue(compute_all_sub, SUFFIX)(void)
74 367e86e8 bellard
{
75 367e86e8 bellard
    int cf, pf, af, zf, sf, of;
76 367e86e8 bellard
    int src1, src2;
77 367e86e8 bellard
    src1 = CC_SRC;
78 367e86e8 bellard
    src2 = CC_SRC - CC_DST;
79 367e86e8 bellard
    cf = (DATA_TYPE)src1 < (DATA_TYPE)src2;
80 367e86e8 bellard
    pf = parity_table[(uint8_t)CC_DST];
81 367e86e8 bellard
    af = (CC_DST ^ src1 ^ src2) & 0x10;
82 4b74fe1f bellard
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
83 367e86e8 bellard
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
84 4b74fe1f bellard
    of = lshift((src1 ^ src2) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
85 367e86e8 bellard
    return cf | pf | af | zf | sf | of;
86 367e86e8 bellard
}
87 367e86e8 bellard
88 367e86e8 bellard
static int glue(compute_c_sub, SUFFIX)(void)
89 367e86e8 bellard
{
90 367e86e8 bellard
    int src1, src2, cf;
91 367e86e8 bellard
    src1 = CC_SRC;
92 367e86e8 bellard
    src2 = CC_SRC - CC_DST;
93 4b74fe1f bellard
    cf = (DATA_TYPE)src1 < (DATA_TYPE)src2;
94 4b74fe1f bellard
    return cf;
95 4b74fe1f bellard
}
96 4b74fe1f bellard
97 4b74fe1f bellard
static int glue(compute_all_sbb, SUFFIX)(void)
98 4b74fe1f bellard
{
99 4b74fe1f bellard
    int cf, pf, af, zf, sf, of;
100 4b74fe1f bellard
    int src1, src2;
101 4b74fe1f bellard
    src1 = CC_SRC;
102 4b74fe1f bellard
    src2 = CC_SRC - CC_DST - 1;
103 4b74fe1f bellard
    cf = (DATA_TYPE)src1 <= (DATA_TYPE)src2;
104 4b74fe1f bellard
    pf = parity_table[(uint8_t)CC_DST];
105 4b74fe1f bellard
    af = (CC_DST ^ src1 ^ src2) & 0x10;
106 4b74fe1f bellard
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
107 4b74fe1f bellard
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
108 4b74fe1f bellard
    of = lshift((src1 ^ src2) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
109 4b74fe1f bellard
    return cf | pf | af | zf | sf | of;
110 4b74fe1f bellard
}
111 4b74fe1f bellard
112 4b74fe1f bellard
static int glue(compute_c_sbb, SUFFIX)(void)
113 4b74fe1f bellard
{
114 4b74fe1f bellard
    int src1, src2, cf;
115 4b74fe1f bellard
    src1 = CC_SRC;
116 4b74fe1f bellard
    src2 = CC_SRC - CC_DST - 1;
117 4b74fe1f bellard
    cf = (DATA_TYPE)src1 <= (DATA_TYPE)src2;
118 367e86e8 bellard
    return cf;
119 367e86e8 bellard
}
120 367e86e8 bellard
121 367e86e8 bellard
static int glue(compute_all_logic, SUFFIX)(void)
122 367e86e8 bellard
{
123 367e86e8 bellard
    int cf, pf, af, zf, sf, of;
124 367e86e8 bellard
    cf = 0;
125 367e86e8 bellard
    pf = parity_table[(uint8_t)CC_DST];
126 367e86e8 bellard
    af = 0;
127 4b74fe1f bellard
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
128 367e86e8 bellard
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
129 367e86e8 bellard
    of = 0;
130 367e86e8 bellard
    return cf | pf | af | zf | sf | of;
131 367e86e8 bellard
}
132 367e86e8 bellard
133 367e86e8 bellard
static int glue(compute_c_logic, SUFFIX)(void)
134 367e86e8 bellard
{
135 367e86e8 bellard
    return 0;
136 367e86e8 bellard
}
137 367e86e8 bellard
138 367e86e8 bellard
static int glue(compute_all_inc, SUFFIX)(void)
139 367e86e8 bellard
{
140 367e86e8 bellard
    int cf, pf, af, zf, sf, of;
141 367e86e8 bellard
    int src1, src2;
142 367e86e8 bellard
    src1 = CC_DST - 1;
143 367e86e8 bellard
    src2 = 1;
144 367e86e8 bellard
    cf = CC_SRC;
145 367e86e8 bellard
    pf = parity_table[(uint8_t)CC_DST];
146 367e86e8 bellard
    af = (CC_DST ^ src1 ^ src2) & 0x10;
147 4b74fe1f bellard
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
148 367e86e8 bellard
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
149 4b74fe1f bellard
    of = ((CC_DST & DATA_MASK) == SIGN_MASK) << 11;
150 367e86e8 bellard
    return cf | pf | af | zf | sf | of;
151 367e86e8 bellard
}
152 367e86e8 bellard
153 4b74fe1f bellard
#if DATA_BITS == 32
154 367e86e8 bellard
static int glue(compute_c_inc, SUFFIX)(void)
155 367e86e8 bellard
{
156 367e86e8 bellard
    return CC_SRC;
157 367e86e8 bellard
}
158 4b74fe1f bellard
#endif
159 367e86e8 bellard
160 367e86e8 bellard
static int glue(compute_all_dec, SUFFIX)(void)
161 367e86e8 bellard
{
162 367e86e8 bellard
    int cf, pf, af, zf, sf, of;
163 367e86e8 bellard
    int src1, src2;
164 367e86e8 bellard
    src1 = CC_DST + 1;
165 367e86e8 bellard
    src2 = 1;
166 367e86e8 bellard
    cf = CC_SRC;
167 367e86e8 bellard
    pf = parity_table[(uint8_t)CC_DST];
168 367e86e8 bellard
    af = (CC_DST ^ src1 ^ src2) & 0x10;
169 4b74fe1f bellard
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
170 367e86e8 bellard
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
171 4b74fe1f bellard
    of = ((CC_DST & DATA_MASK) == ((uint32_t)SIGN_MASK - 1)) << 11;
172 367e86e8 bellard
    return cf | pf | af | zf | sf | of;
173 367e86e8 bellard
}
174 367e86e8 bellard
175 367e86e8 bellard
static int glue(compute_all_shl, SUFFIX)(void)
176 367e86e8 bellard
{
177 367e86e8 bellard
    int cf, pf, af, zf, sf, of;
178 367e86e8 bellard
    cf = CC_SRC & 1;
179 367e86e8 bellard
    pf = parity_table[(uint8_t)CC_DST];
180 367e86e8 bellard
    af = 0; /* undefined */
181 4b74fe1f bellard
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
182 367e86e8 bellard
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
183 4b74fe1f bellard
    of = lshift(CC_SRC, 12 - DATA_BITS) & CC_O; /* only meaniful for shr with count == 1 */
184 367e86e8 bellard
    return cf | pf | af | zf | sf | of;
185 367e86e8 bellard
}
186 367e86e8 bellard
187 4b74fe1f bellard
#if DATA_BITS == 32
188 367e86e8 bellard
static int glue(compute_c_shl, SUFFIX)(void)
189 367e86e8 bellard
{
190 367e86e8 bellard
    return CC_SRC & 1;
191 367e86e8 bellard
}
192 4b74fe1f bellard
#endif
193 4b74fe1f bellard
194 4b74fe1f bellard
static int glue(compute_all_sar, SUFFIX)(void)
195 4b74fe1f bellard
{
196 4b74fe1f bellard
    int cf, pf, af, zf, sf, of;
197 4b74fe1f bellard
    cf = CC_SRC & 1;
198 4b74fe1f bellard
    pf = parity_table[(uint8_t)CC_DST];
199 4b74fe1f bellard
    af = 0; /* undefined */
200 4b74fe1f bellard
    zf = ((DATA_TYPE)CC_DST == 0) << 6;
201 4b74fe1f bellard
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
202 4b74fe1f bellard
    of = 0; /* only meaniful for shr with count == 1 */
203 4b74fe1f bellard
    return cf | pf | af | zf | sf | of;
204 4b74fe1f bellard
}
205 367e86e8 bellard
206 367e86e8 bellard
/* various optimized jumps cases */
207 367e86e8 bellard
208 367e86e8 bellard
void OPPROTO glue(op_jb_sub, SUFFIX)(void)
209 367e86e8 bellard
{
210 367e86e8 bellard
    int src1, src2;
211 367e86e8 bellard
    src1 = CC_SRC;
212 367e86e8 bellard
    src2 = CC_SRC - CC_DST;
213 367e86e8 bellard
214 367e86e8 bellard
    if ((DATA_TYPE)src1 < (DATA_TYPE)src2)
215 0ecfa993 bellard
        PC = PARAM1;
216 367e86e8 bellard
    else
217 0ecfa993 bellard
        PC = PARAM2;
218 367e86e8 bellard
    FORCE_RET();
219 367e86e8 bellard
}
220 367e86e8 bellard
221 367e86e8 bellard
void OPPROTO glue(op_jz_sub, SUFFIX)(void)
222 367e86e8 bellard
{
223 4b74fe1f bellard
    if ((DATA_TYPE)CC_DST == 0)
224 0ecfa993 bellard
        PC = PARAM1;
225 367e86e8 bellard
    else
226 0ecfa993 bellard
        PC = PARAM2;
227 367e86e8 bellard
    FORCE_RET();
228 367e86e8 bellard
}
229 367e86e8 bellard
230 367e86e8 bellard
void OPPROTO glue(op_jbe_sub, SUFFIX)(void)
231 367e86e8 bellard
{
232 367e86e8 bellard
    int src1, src2;
233 367e86e8 bellard
    src1 = CC_SRC;
234 367e86e8 bellard
    src2 = CC_SRC - CC_DST;
235 367e86e8 bellard
236 367e86e8 bellard
    if ((DATA_TYPE)src1 <= (DATA_TYPE)src2)
237 0ecfa993 bellard
        PC = PARAM1;
238 367e86e8 bellard
    else
239 0ecfa993 bellard
        PC = PARAM2;
240 367e86e8 bellard
    FORCE_RET();
241 367e86e8 bellard
}
242 367e86e8 bellard
243 367e86e8 bellard
void OPPROTO glue(op_js_sub, SUFFIX)(void)
244 367e86e8 bellard
{
245 367e86e8 bellard
    if (CC_DST & SIGN_MASK)
246 0ecfa993 bellard
        PC = PARAM1;
247 367e86e8 bellard
    else
248 0ecfa993 bellard
        PC = PARAM2;
249 367e86e8 bellard
    FORCE_RET();
250 367e86e8 bellard
}
251 367e86e8 bellard
252 367e86e8 bellard
void OPPROTO glue(op_jl_sub, SUFFIX)(void)
253 367e86e8 bellard
{
254 367e86e8 bellard
    int src1, src2;
255 367e86e8 bellard
    src1 = CC_SRC;
256 367e86e8 bellard
    src2 = CC_SRC - CC_DST;
257 367e86e8 bellard
258 367e86e8 bellard
    if ((DATA_STYPE)src1 < (DATA_STYPE)src2)
259 0ecfa993 bellard
        PC = PARAM1;
260 367e86e8 bellard
    else
261 0ecfa993 bellard
        PC = PARAM2;
262 367e86e8 bellard
    FORCE_RET();
263 367e86e8 bellard
}
264 367e86e8 bellard
265 367e86e8 bellard
void OPPROTO glue(op_jle_sub, SUFFIX)(void)
266 367e86e8 bellard
{
267 367e86e8 bellard
    int src1, src2;
268 367e86e8 bellard
    src1 = CC_SRC;
269 367e86e8 bellard
    src2 = CC_SRC - CC_DST;
270 367e86e8 bellard
271 367e86e8 bellard
    if ((DATA_STYPE)src1 <= (DATA_STYPE)src2)
272 0ecfa993 bellard
        PC = PARAM1;
273 367e86e8 bellard
    else
274 0ecfa993 bellard
        PC = PARAM2;
275 367e86e8 bellard
    FORCE_RET();
276 367e86e8 bellard
}
277 367e86e8 bellard
278 367e86e8 bellard
/* various optimized set cases */
279 367e86e8 bellard
280 367e86e8 bellard
void OPPROTO glue(op_setb_T0_sub, SUFFIX)(void)
281 367e86e8 bellard
{
282 367e86e8 bellard
    int src1, src2;
283 367e86e8 bellard
    src1 = CC_SRC;
284 367e86e8 bellard
    src2 = CC_SRC - CC_DST;
285 367e86e8 bellard
286 367e86e8 bellard
    T0 = ((DATA_TYPE)src1 < (DATA_TYPE)src2);
287 367e86e8 bellard
}
288 367e86e8 bellard
289 367e86e8 bellard
void OPPROTO glue(op_setz_T0_sub, SUFFIX)(void)
290 367e86e8 bellard
{
291 4b74fe1f bellard
    T0 = ((DATA_TYPE)CC_DST == 0);
292 367e86e8 bellard
}
293 367e86e8 bellard
294 367e86e8 bellard
void OPPROTO glue(op_setbe_T0_sub, SUFFIX)(void)
295 367e86e8 bellard
{
296 367e86e8 bellard
    int src1, src2;
297 367e86e8 bellard
    src1 = CC_SRC;
298 367e86e8 bellard
    src2 = CC_SRC - CC_DST;
299 367e86e8 bellard
300 367e86e8 bellard
    T0 = ((DATA_TYPE)src1 <= (DATA_TYPE)src2);
301 367e86e8 bellard
}
302 367e86e8 bellard
303 367e86e8 bellard
void OPPROTO glue(op_sets_T0_sub, SUFFIX)(void)
304 367e86e8 bellard
{
305 367e86e8 bellard
    T0 = lshift(CC_DST, -(DATA_BITS - 1)) & 1;
306 367e86e8 bellard
}
307 367e86e8 bellard
308 367e86e8 bellard
void OPPROTO glue(op_setl_T0_sub, SUFFIX)(void)
309 367e86e8 bellard
{
310 367e86e8 bellard
    int src1, src2;
311 367e86e8 bellard
    src1 = CC_SRC;
312 367e86e8 bellard
    src2 = CC_SRC - CC_DST;
313 367e86e8 bellard
314 367e86e8 bellard
    T0 = ((DATA_STYPE)src1 < (DATA_STYPE)src2);
315 367e86e8 bellard
}
316 367e86e8 bellard
317 367e86e8 bellard
void OPPROTO glue(op_setle_T0_sub, SUFFIX)(void)
318 367e86e8 bellard
{
319 367e86e8 bellard
    int src1, src2;
320 367e86e8 bellard
    src1 = CC_SRC;
321 367e86e8 bellard
    src2 = CC_SRC - CC_DST;
322 367e86e8 bellard
323 367e86e8 bellard
    T0 = ((DATA_STYPE)src1 <= (DATA_STYPE)src2);
324 367e86e8 bellard
}
325 367e86e8 bellard
326 367e86e8 bellard
/* shifts */
327 367e86e8 bellard
328 367e86e8 bellard
void OPPROTO glue(glue(op_rol, SUFFIX), _T0_T1_cc)(void)
329 367e86e8 bellard
{
330 367e86e8 bellard
    int count, src;
331 367e86e8 bellard
    count = T1 & SHIFT_MASK;
332 367e86e8 bellard
    if (count) {
333 367e86e8 bellard
        CC_SRC = cc_table[CC_OP].compute_all() & ~(CC_O | CC_C);
334 367e86e8 bellard
        src = T0;
335 367e86e8 bellard
        T0 &= DATA_MASK;
336 367e86e8 bellard
        T0 = (T0 << count) | (T0 >> (DATA_BITS - count));
337 367e86e8 bellard
        CC_SRC |= (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) | 
338 367e86e8 bellard
            (T0 & CC_C);
339 367e86e8 bellard
        CC_OP = CC_OP_EFLAGS;
340 367e86e8 bellard
    }
341 4b74fe1f bellard
    FORCE_RET();
342 367e86e8 bellard
}
343 367e86e8 bellard
344 367e86e8 bellard
void OPPROTO glue(glue(op_ror, SUFFIX), _T0_T1_cc)(void)
345 367e86e8 bellard
{
346 367e86e8 bellard
    int count, src;
347 367e86e8 bellard
    count = T1 & SHIFT_MASK;
348 367e86e8 bellard
    if (count) {
349 367e86e8 bellard
        CC_SRC = cc_table[CC_OP].compute_all() & ~(CC_O | CC_C);
350 367e86e8 bellard
        src = T0;
351 367e86e8 bellard
        T0 &= DATA_MASK;
352 367e86e8 bellard
        T0 = (T0 >> count) | (T0 << (DATA_BITS - count));
353 367e86e8 bellard
        CC_SRC |= (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) | 
354 367e86e8 bellard
            ((T0 >> (DATA_BITS - 1)) & CC_C);
355 367e86e8 bellard
        CC_OP = CC_OP_EFLAGS;
356 367e86e8 bellard
    }
357 4b74fe1f bellard
    FORCE_RET();
358 367e86e8 bellard
}
359 367e86e8 bellard
360 367e86e8 bellard
void OPPROTO glue(glue(op_rcl, SUFFIX), _T0_T1_cc)(void)
361 367e86e8 bellard
{
362 367e86e8 bellard
    int count, res, eflags;
363 367e86e8 bellard
    unsigned int src;
364 367e86e8 bellard
365 367e86e8 bellard
    count = T1 & 0x1f;
366 367e86e8 bellard
#if DATA_BITS == 16
367 367e86e8 bellard
    count = rclw_table[count];
368 367e86e8 bellard
#elif DATA_BITS == 8
369 367e86e8 bellard
    count = rclb_table[count];
370 367e86e8 bellard
#endif
371 367e86e8 bellard
    if (count) {
372 367e86e8 bellard
        eflags = cc_table[CC_OP].compute_all();
373 4b74fe1f bellard
        T0 &= DATA_MASK;
374 367e86e8 bellard
        src = T0;
375 367e86e8 bellard
        res = (T0 << count) | ((eflags & CC_C) << (count - 1));
376 367e86e8 bellard
        if (count > 1)
377 367e86e8 bellard
            res |= T0 >> (DATA_BITS + 1 - count);
378 367e86e8 bellard
        T0 = res;
379 367e86e8 bellard
        CC_SRC = (eflags & ~(CC_C | CC_O)) |
380 367e86e8 bellard
            (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) | 
381 367e86e8 bellard
            ((src >> (DATA_BITS - count)) & CC_C);
382 367e86e8 bellard
        CC_OP = CC_OP_EFLAGS;
383 367e86e8 bellard
    }
384 4b74fe1f bellard
    FORCE_RET();
385 367e86e8 bellard
}
386 367e86e8 bellard
387 367e86e8 bellard
void OPPROTO glue(glue(op_rcr, SUFFIX), _T0_T1_cc)(void)
388 367e86e8 bellard
{
389 367e86e8 bellard
    int count, res, eflags;
390 367e86e8 bellard
    unsigned int src;
391 367e86e8 bellard
392 367e86e8 bellard
    count = T1 & 0x1f;
393 367e86e8 bellard
#if DATA_BITS == 16
394 367e86e8 bellard
    count = rclw_table[count];
395 367e86e8 bellard
#elif DATA_BITS == 8
396 367e86e8 bellard
    count = rclb_table[count];
397 367e86e8 bellard
#endif
398 367e86e8 bellard
    if (count) {
399 367e86e8 bellard
        eflags = cc_table[CC_OP].compute_all();
400 4b74fe1f bellard
        T0 &= DATA_MASK;
401 367e86e8 bellard
        src = T0;
402 367e86e8 bellard
        res = (T0 >> count) | ((eflags & CC_C) << (DATA_BITS - count));
403 367e86e8 bellard
        if (count > 1)
404 367e86e8 bellard
            res |= T0 << (DATA_BITS + 1 - count);
405 367e86e8 bellard
        T0 = res;
406 367e86e8 bellard
        CC_SRC = (eflags & ~(CC_C | CC_O)) |
407 367e86e8 bellard
            (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) | 
408 367e86e8 bellard
            ((src >> (count - 1)) & CC_C);
409 367e86e8 bellard
        CC_OP = CC_OP_EFLAGS;
410 367e86e8 bellard
    }
411 4b74fe1f bellard
    FORCE_RET();
412 367e86e8 bellard
}
413 367e86e8 bellard
414 367e86e8 bellard
void OPPROTO glue(glue(op_shl, SUFFIX), _T0_T1_cc)(void)
415 367e86e8 bellard
{
416 367e86e8 bellard
    int count;
417 367e86e8 bellard
    count = T1 & 0x1f;
418 367e86e8 bellard
    if (count == 1) {
419 367e86e8 bellard
        CC_SRC = T0;
420 367e86e8 bellard
        T0 = T0 << 1;
421 367e86e8 bellard
        CC_DST = T0;
422 367e86e8 bellard
        CC_OP = CC_OP_ADDB + SHIFT;
423 367e86e8 bellard
    } else if (count) {
424 4b74fe1f bellard
        CC_SRC = (DATA_TYPE)T0 >> (DATA_BITS - count);
425 367e86e8 bellard
        T0 = T0 << count;
426 367e86e8 bellard
        CC_DST = T0;
427 367e86e8 bellard
        CC_OP = CC_OP_SHLB + SHIFT;
428 367e86e8 bellard
    }
429 4b74fe1f bellard
    FORCE_RET();
430 367e86e8 bellard
}
431 367e86e8 bellard
432 367e86e8 bellard
void OPPROTO glue(glue(op_shr, SUFFIX), _T0_T1_cc)(void)
433 367e86e8 bellard
{
434 367e86e8 bellard
    int count;
435 367e86e8 bellard
    count = T1 & 0x1f;
436 367e86e8 bellard
    if (count) {
437 367e86e8 bellard
        T0 &= DATA_MASK;
438 367e86e8 bellard
        CC_SRC = T0 >> (count - 1);
439 367e86e8 bellard
        T0 = T0 >> count;
440 367e86e8 bellard
        CC_DST = T0;
441 367e86e8 bellard
        CC_OP = CC_OP_SHLB + SHIFT;
442 367e86e8 bellard
    }
443 4b74fe1f bellard
    FORCE_RET();
444 367e86e8 bellard
}
445 367e86e8 bellard
446 367e86e8 bellard
void OPPROTO glue(glue(op_sar, SUFFIX), _T0_T1_cc)(void)
447 367e86e8 bellard
{
448 367e86e8 bellard
    int count, src;
449 367e86e8 bellard
    count = T1 & 0x1f;
450 367e86e8 bellard
    if (count) {
451 367e86e8 bellard
        src = (DATA_STYPE)T0;
452 367e86e8 bellard
        CC_SRC =  src >> (count - 1);
453 367e86e8 bellard
        T0 = src >> count;
454 367e86e8 bellard
        CC_DST = T0;
455 4b74fe1f bellard
        CC_OP = CC_OP_SARB + SHIFT;
456 367e86e8 bellard
    }
457 4b74fe1f bellard
    FORCE_RET();
458 367e86e8 bellard
}
459 367e86e8 bellard
460 4b74fe1f bellard
/* carry add/sub (we only need to set CC_OP differently) */
461 4b74fe1f bellard
462 4b74fe1f bellard
void OPPROTO glue(glue(op_adc, SUFFIX), _T0_T1_cc)(void)
463 4b74fe1f bellard
{
464 4b74fe1f bellard
    int cf;
465 4b74fe1f bellard
    cf = cc_table[CC_OP].compute_c();
466 4b74fe1f bellard
    CC_SRC = T0;
467 4b74fe1f bellard
    T0 = T0 + T1 + cf;
468 4b74fe1f bellard
    CC_DST = T0;
469 4b74fe1f bellard
    CC_OP = CC_OP_ADDB + SHIFT + cf * 3;
470 4b74fe1f bellard
}
471 4b74fe1f bellard
472 4b74fe1f bellard
void OPPROTO glue(glue(op_sbb, SUFFIX), _T0_T1_cc)(void)
473 4b74fe1f bellard
{
474 4b74fe1f bellard
    int cf;
475 4b74fe1f bellard
    cf = cc_table[CC_OP].compute_c();
476 4b74fe1f bellard
    CC_SRC = T0;
477 4b74fe1f bellard
    T0 = T0 - T1 - cf;
478 4b74fe1f bellard
    CC_DST = T0;
479 4b74fe1f bellard
    CC_OP = CC_OP_SUBB + SHIFT + cf * 3;
480 4b74fe1f bellard
}
481 4b74fe1f bellard
482 4b74fe1f bellard
/* bit operations */
483 4b74fe1f bellard
#if DATA_BITS >= 16
484 4b74fe1f bellard
485 4b74fe1f bellard
void OPPROTO glue(glue(op_bt, SUFFIX), _T0_T1_cc)(void)
486 4b74fe1f bellard
{
487 4b74fe1f bellard
    int count;
488 4b74fe1f bellard
    count = T1 & SHIFT_MASK;
489 4b74fe1f bellard
    CC_SRC = T0 >> count;
490 4b74fe1f bellard
}
491 4b74fe1f bellard
492 4b74fe1f bellard
void OPPROTO glue(glue(op_bts, SUFFIX), _T0_T1_cc)(void)
493 4b74fe1f bellard
{
494 4b74fe1f bellard
    int count;
495 4b74fe1f bellard
    count = T1 & SHIFT_MASK;
496 4b74fe1f bellard
    CC_SRC = T0 >> count;
497 4b74fe1f bellard
    T0 |= (1 << count);
498 4b74fe1f bellard
}
499 4b74fe1f bellard
500 4b74fe1f bellard
void OPPROTO glue(glue(op_btr, SUFFIX), _T0_T1_cc)(void)
501 4b74fe1f bellard
{
502 4b74fe1f bellard
    int count;
503 4b74fe1f bellard
    count = T1 & SHIFT_MASK;
504 4b74fe1f bellard
    CC_SRC = T0 >> count;
505 4b74fe1f bellard
    T0 &= ~(1 << count);
506 4b74fe1f bellard
}
507 4b74fe1f bellard
508 4b74fe1f bellard
void OPPROTO glue(glue(op_btc, SUFFIX), _T0_T1_cc)(void)
509 4b74fe1f bellard
{
510 4b74fe1f bellard
    int count;
511 4b74fe1f bellard
    count = T1 & SHIFT_MASK;
512 4b74fe1f bellard
    CC_SRC = T0 >> count;
513 4b74fe1f bellard
    T0 ^= (1 << count);
514 4b74fe1f bellard
}
515 4b74fe1f bellard
516 4b74fe1f bellard
#endif
517 4b74fe1f bellard
518 367e86e8 bellard
/* string operations */
519 367e86e8 bellard
/* XXX: maybe use lower level instructions to ease exception handling */
520 367e86e8 bellard
521 367e86e8 bellard
void OPPROTO glue(op_movs, SUFFIX)(void)
522 367e86e8 bellard
{
523 367e86e8 bellard
    int v;
524 367e86e8 bellard
    v = glue(ldu, SUFFIX)((void *)ESI);
525 367e86e8 bellard
    glue(st, SUFFIX)((void *)EDI, v);
526 367e86e8 bellard
    ESI += (DF << SHIFT);
527 367e86e8 bellard
    EDI += (DF << SHIFT);
528 367e86e8 bellard
}
529 367e86e8 bellard
530 367e86e8 bellard
void OPPROTO glue(op_rep_movs, SUFFIX)(void)
531 367e86e8 bellard
{
532 367e86e8 bellard
    int v, inc;
533 367e86e8 bellard
    inc = (DF << SHIFT);
534 367e86e8 bellard
    while (ECX != 0) {
535 367e86e8 bellard
        v = glue(ldu, SUFFIX)((void *)ESI);
536 367e86e8 bellard
        glue(st, SUFFIX)((void *)EDI, v);
537 367e86e8 bellard
        ESI += inc;
538 367e86e8 bellard
        EDI += inc;
539 367e86e8 bellard
        ECX--;
540 367e86e8 bellard
    }
541 367e86e8 bellard
}
542 367e86e8 bellard
543 367e86e8 bellard
void OPPROTO glue(op_stos, SUFFIX)(void)
544 367e86e8 bellard
{
545 367e86e8 bellard
    glue(st, SUFFIX)((void *)EDI, EAX);
546 367e86e8 bellard
    EDI += (DF << SHIFT);
547 367e86e8 bellard
}
548 367e86e8 bellard
549 367e86e8 bellard
void OPPROTO glue(op_rep_stos, SUFFIX)(void)
550 367e86e8 bellard
{
551 367e86e8 bellard
    int inc;
552 367e86e8 bellard
    inc = (DF << SHIFT);
553 367e86e8 bellard
    while (ECX != 0) {
554 367e86e8 bellard
        glue(st, SUFFIX)((void *)EDI, EAX);
555 367e86e8 bellard
        EDI += inc;
556 367e86e8 bellard
        ECX--;
557 367e86e8 bellard
    }
558 367e86e8 bellard
}
559 367e86e8 bellard
560 367e86e8 bellard
void OPPROTO glue(op_lods, SUFFIX)(void)
561 367e86e8 bellard
{
562 367e86e8 bellard
    int v;
563 367e86e8 bellard
    v = glue(ldu, SUFFIX)((void *)ESI);
564 367e86e8 bellard
#if SHIFT == 0
565 367e86e8 bellard
    EAX = (EAX & ~0xff) | v;
566 367e86e8 bellard
#elif SHIFT == 1
567 367e86e8 bellard
    EAX = (EAX & ~0xffff) | v;
568 367e86e8 bellard
#else
569 367e86e8 bellard
    EAX = v;
570 367e86e8 bellard
#endif
571 367e86e8 bellard
    ESI += (DF << SHIFT);
572 367e86e8 bellard
}
573 367e86e8 bellard
574 367e86e8 bellard
/* don't know if it is used */
575 367e86e8 bellard
void OPPROTO glue(op_rep_lods, SUFFIX)(void)
576 367e86e8 bellard
{
577 367e86e8 bellard
    int v, inc;
578 367e86e8 bellard
    inc = (DF << SHIFT);
579 367e86e8 bellard
    while (ECX != 0) {
580 367e86e8 bellard
        v = glue(ldu, SUFFIX)((void *)ESI);
581 367e86e8 bellard
#if SHIFT == 0
582 367e86e8 bellard
        EAX = (EAX & ~0xff) | v;
583 367e86e8 bellard
#elif SHIFT == 1
584 367e86e8 bellard
        EAX = (EAX & ~0xffff) | v;
585 367e86e8 bellard
#else
586 367e86e8 bellard
        EAX = v;
587 367e86e8 bellard
#endif
588 367e86e8 bellard
        ESI += inc;
589 367e86e8 bellard
        ECX--;
590 367e86e8 bellard
    }
591 367e86e8 bellard
}
592 367e86e8 bellard
593 367e86e8 bellard
void OPPROTO glue(op_scas, SUFFIX)(void)
594 367e86e8 bellard
{
595 367e86e8 bellard
    int v;
596 367e86e8 bellard
597 4b74fe1f bellard
    v = glue(ldu, SUFFIX)((void *)EDI);
598 4b74fe1f bellard
    EDI += (DF << SHIFT);
599 367e86e8 bellard
    CC_SRC = EAX;
600 367e86e8 bellard
    CC_DST = EAX - v;
601 367e86e8 bellard
}
602 367e86e8 bellard
603 367e86e8 bellard
void OPPROTO glue(op_repz_scas, SUFFIX)(void)
604 367e86e8 bellard
{
605 367e86e8 bellard
    int v1, v2, inc;
606 367e86e8 bellard
607 367e86e8 bellard
    if (ECX != 0) {
608 367e86e8 bellard
        /* NOTE: the flags are not modified if ECX == 0 */
609 4b74fe1f bellard
        v1 = EAX & DATA_MASK;
610 367e86e8 bellard
        inc = (DF << SHIFT);
611 367e86e8 bellard
        do {
612 4b74fe1f bellard
            v2 = glue(ldu, SUFFIX)((void *)EDI);
613 4b74fe1f bellard
            EDI += inc;
614 4b74fe1f bellard
            ECX--;
615 367e86e8 bellard
            if (v1 != v2)
616 367e86e8 bellard
                break;
617 367e86e8 bellard
        } while (ECX != 0);
618 367e86e8 bellard
        CC_SRC = v1;
619 367e86e8 bellard
        CC_DST = v1 - v2;
620 367e86e8 bellard
        CC_OP = CC_OP_SUBB + SHIFT;
621 367e86e8 bellard
    }
622 367e86e8 bellard
}
623 367e86e8 bellard
624 367e86e8 bellard
void OPPROTO glue(op_repnz_scas, SUFFIX)(void)
625 367e86e8 bellard
{
626 367e86e8 bellard
    int v1, v2, inc;
627 367e86e8 bellard
628 367e86e8 bellard
    if (ECX != 0) {
629 367e86e8 bellard
        /* NOTE: the flags are not modified if ECX == 0 */
630 4b74fe1f bellard
        v1 = EAX & DATA_MASK;
631 367e86e8 bellard
        inc = (DF << SHIFT);
632 367e86e8 bellard
        do {
633 4b74fe1f bellard
            v2 = glue(ldu, SUFFIX)((void *)EDI);
634 4b74fe1f bellard
            EDI += inc;
635 4b74fe1f bellard
            ECX--;
636 367e86e8 bellard
            if (v1 == v2)
637 367e86e8 bellard
                break;
638 367e86e8 bellard
        } while (ECX != 0);
639 367e86e8 bellard
        CC_SRC = v1;
640 367e86e8 bellard
        CC_DST = v1 - v2;
641 367e86e8 bellard
        CC_OP = CC_OP_SUBB + SHIFT;
642 367e86e8 bellard
    }
643 367e86e8 bellard
}
644 367e86e8 bellard
645 367e86e8 bellard
void OPPROTO glue(op_cmps, SUFFIX)(void)
646 367e86e8 bellard
{
647 367e86e8 bellard
    int v1, v2;
648 367e86e8 bellard
    v1 = glue(ldu, SUFFIX)((void *)ESI);
649 367e86e8 bellard
    v2 = glue(ldu, SUFFIX)((void *)EDI);
650 367e86e8 bellard
    ESI += (DF << SHIFT);
651 367e86e8 bellard
    EDI += (DF << SHIFT);
652 367e86e8 bellard
    CC_SRC = v1;
653 367e86e8 bellard
    CC_DST = v1 - v2;
654 367e86e8 bellard
}
655 367e86e8 bellard
656 367e86e8 bellard
void OPPROTO glue(op_repz_cmps, SUFFIX)(void)
657 367e86e8 bellard
{
658 367e86e8 bellard
    int v1, v2, inc;
659 367e86e8 bellard
    if (ECX != 0) {
660 367e86e8 bellard
        inc = (DF << SHIFT);
661 367e86e8 bellard
        do {
662 367e86e8 bellard
            v1 = glue(ldu, SUFFIX)((void *)ESI);
663 367e86e8 bellard
            v2 = glue(ldu, SUFFIX)((void *)EDI);
664 367e86e8 bellard
            ESI += inc;
665 367e86e8 bellard
            EDI += inc;
666 367e86e8 bellard
            ECX--;
667 4b74fe1f bellard
            if (v1 != v2)
668 4b74fe1f bellard
                break;
669 367e86e8 bellard
        } while (ECX != 0);
670 367e86e8 bellard
        CC_SRC = v1;
671 367e86e8 bellard
        CC_DST = v1 - v2;
672 367e86e8 bellard
        CC_OP = CC_OP_SUBB + SHIFT;
673 367e86e8 bellard
    }
674 367e86e8 bellard
}
675 367e86e8 bellard
676 367e86e8 bellard
void OPPROTO glue(op_repnz_cmps, SUFFIX)(void)
677 367e86e8 bellard
{
678 367e86e8 bellard
    int v1, v2, inc;
679 367e86e8 bellard
    if (ECX != 0) {
680 367e86e8 bellard
        inc = (DF << SHIFT);
681 367e86e8 bellard
        do {
682 367e86e8 bellard
            v1 = glue(ldu, SUFFIX)((void *)ESI);
683 367e86e8 bellard
            v2 = glue(ldu, SUFFIX)((void *)EDI);
684 367e86e8 bellard
            ESI += inc;
685 367e86e8 bellard
            EDI += inc;
686 367e86e8 bellard
            ECX--;
687 4b74fe1f bellard
            if (v1 == v2)
688 4b74fe1f bellard
                break;
689 367e86e8 bellard
        } while (ECX != 0);
690 367e86e8 bellard
        CC_SRC = v1;
691 367e86e8 bellard
        CC_DST = v1 - v2;
692 367e86e8 bellard
        CC_OP = CC_OP_SUBB + SHIFT;
693 367e86e8 bellard
    }
694 367e86e8 bellard
}
695 367e86e8 bellard
696 ba1c6e37 bellard
/* port I/O */
697 ba1c6e37 bellard
698 367e86e8 bellard
void OPPROTO glue(op_outs, SUFFIX)(void)
699 367e86e8 bellard
{
700 367e86e8 bellard
    int v, dx;
701 367e86e8 bellard
    dx = EDX & 0xffff;
702 367e86e8 bellard
    v = glue(ldu, SUFFIX)((void *)ESI);
703 ba1c6e37 bellard
    glue(cpu_x86_out, SUFFIX)(dx, v);
704 367e86e8 bellard
    ESI += (DF << SHIFT);
705 367e86e8 bellard
}
706 367e86e8 bellard
707 367e86e8 bellard
void OPPROTO glue(op_rep_outs, SUFFIX)(void)
708 367e86e8 bellard
{
709 367e86e8 bellard
    int v, dx, inc;
710 367e86e8 bellard
    inc = (DF << SHIFT);
711 367e86e8 bellard
    dx = EDX & 0xffff;
712 367e86e8 bellard
    while (ECX != 0) {
713 367e86e8 bellard
        v = glue(ldu, SUFFIX)((void *)ESI);
714 ba1c6e37 bellard
        glue(cpu_x86_out, SUFFIX)(dx, v);
715 367e86e8 bellard
        ESI += inc;
716 367e86e8 bellard
        ECX--;
717 367e86e8 bellard
    }
718 367e86e8 bellard
}
719 367e86e8 bellard
720 367e86e8 bellard
void OPPROTO glue(op_ins, SUFFIX)(void)
721 367e86e8 bellard
{
722 367e86e8 bellard
    int v, dx;
723 367e86e8 bellard
    dx = EDX & 0xffff;
724 ba1c6e37 bellard
    v = glue(cpu_x86_in, SUFFIX)(dx);
725 367e86e8 bellard
    glue(st, SUFFIX)((void *)EDI, v);
726 367e86e8 bellard
    EDI += (DF << SHIFT);
727 367e86e8 bellard
}
728 367e86e8 bellard
729 367e86e8 bellard
void OPPROTO glue(op_rep_ins, SUFFIX)(void)
730 367e86e8 bellard
{
731 367e86e8 bellard
    int v, dx, inc;
732 367e86e8 bellard
    inc = (DF << SHIFT);
733 367e86e8 bellard
    dx = EDX & 0xffff;
734 367e86e8 bellard
    while (ECX != 0) {
735 ba1c6e37 bellard
        v = glue(cpu_x86_in, SUFFIX)(dx);
736 367e86e8 bellard
        glue(st, SUFFIX)((void *)EDI, v);
737 367e86e8 bellard
        EDI += (DF << SHIFT);
738 367e86e8 bellard
        ECX--;
739 367e86e8 bellard
    }
740 367e86e8 bellard
}
741 367e86e8 bellard
742 ba1c6e37 bellard
void OPPROTO glue(glue(op_out, SUFFIX), _T0_T1)(void)
743 ba1c6e37 bellard
{
744 ba1c6e37 bellard
    glue(cpu_x86_out, SUFFIX)(T0 & 0xffff, T1 & DATA_MASK);
745 ba1c6e37 bellard
}
746 ba1c6e37 bellard
747 ba1c6e37 bellard
void OPPROTO glue(glue(op_in, SUFFIX), _T0_T1)(void)
748 ba1c6e37 bellard
{
749 ba1c6e37 bellard
    T1 = glue(cpu_x86_in, SUFFIX)(T0 & 0xffff);
750 ba1c6e37 bellard
}
751 ba1c6e37 bellard
752 367e86e8 bellard
#undef DATA_BITS
753 367e86e8 bellard
#undef SHIFT_MASK
754 367e86e8 bellard
#undef SIGN_MASK
755 367e86e8 bellard
#undef DATA_TYPE
756 367e86e8 bellard
#undef DATA_STYPE
757 367e86e8 bellard
#undef DATA_MASK
758 367e86e8 bellard
#undef SUFFIX