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