]> git.proxmox.com Git - qemu.git/blob - ops_template.h
many fixes
[qemu.git] / ops_template.h
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
27 static 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;
36 zf = ((DATA_TYPE)CC_DST == 0) << 6;
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
42 static 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
50 static 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
65 static 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
73 static 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;
82 zf = ((DATA_TYPE)CC_DST == 0) << 6;
83 sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
84 of = lshift((src1 ^ src2) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
85 return cf | pf | af | zf | sf | of;
86 }
87
88 static int glue(compute_c_sub, SUFFIX)(void)
89 {
90 int src1, src2, cf;
91 src1 = CC_SRC;
92 src2 = CC_SRC - CC_DST;
93 cf = (DATA_TYPE)src1 < (DATA_TYPE)src2;
94 return cf;
95 }
96
97 static 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
112 static 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;
118 return cf;
119 }
120
121 static 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;
127 zf = ((DATA_TYPE)CC_DST == 0) << 6;
128 sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
129 of = 0;
130 return cf | pf | af | zf | sf | of;
131 }
132
133 static int glue(compute_c_logic, SUFFIX)(void)
134 {
135 return 0;
136 }
137
138 static 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;
147 zf = ((DATA_TYPE)CC_DST == 0) << 6;
148 sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
149 of = ((CC_DST & DATA_MASK) == SIGN_MASK) << 11;
150 return cf | pf | af | zf | sf | of;
151 }
152
153 #if DATA_BITS == 32
154 static int glue(compute_c_inc, SUFFIX)(void)
155 {
156 return CC_SRC;
157 }
158 #endif
159
160 static 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;
169 zf = ((DATA_TYPE)CC_DST == 0) << 6;
170 sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
171 of = ((CC_DST & DATA_MASK) == ((uint32_t)SIGN_MASK - 1)) << 11;
172 return cf | pf | af | zf | sf | of;
173 }
174
175 static 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 */
181 zf = ((DATA_TYPE)CC_DST == 0) << 6;
182 sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
183 of = lshift(CC_SRC, 12 - DATA_BITS) & CC_O; /* only meaniful for shr with count == 1 */
184 return cf | pf | af | zf | sf | of;
185 }
186
187 #if DATA_BITS == 32
188 static int glue(compute_c_shl, SUFFIX)(void)
189 {
190 return CC_SRC & 1;
191 }
192 #endif
193
194 static 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 }
205
206 /* various optimized jumps cases */
207
208 void 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)
215 PC = PARAM1;
216 else
217 PC = PARAM2;
218 FORCE_RET();
219 }
220
221 void OPPROTO glue(op_jz_sub, SUFFIX)(void)
222 {
223 if ((DATA_TYPE)CC_DST == 0)
224 PC = PARAM1;
225 else
226 PC = PARAM2;
227 FORCE_RET();
228 }
229
230 void 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)
237 PC = PARAM1;
238 else
239 PC = PARAM2;
240 FORCE_RET();
241 }
242
243 void OPPROTO glue(op_js_sub, SUFFIX)(void)
244 {
245 if (CC_DST & SIGN_MASK)
246 PC = PARAM1;
247 else
248 PC = PARAM2;
249 FORCE_RET();
250 }
251
252 void 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)
259 PC = PARAM1;
260 else
261 PC = PARAM2;
262 FORCE_RET();
263 }
264
265 void 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)
272 PC = PARAM1;
273 else
274 PC = PARAM2;
275 FORCE_RET();
276 }
277
278 /* various optimized set cases */
279
280 void 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
289 void OPPROTO glue(op_setz_T0_sub, SUFFIX)(void)
290 {
291 T0 = ((DATA_TYPE)CC_DST == 0);
292 }
293
294 void 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
303 void OPPROTO glue(op_sets_T0_sub, SUFFIX)(void)
304 {
305 T0 = lshift(CC_DST, -(DATA_BITS - 1)) & 1;
306 }
307
308 void 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
317 void 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
328 void 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 }
341 FORCE_RET();
342 }
343
344 void 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 }
357 FORCE_RET();
358 }
359
360 void 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();
373 T0 &= DATA_MASK;
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 }
384 FORCE_RET();
385 }
386
387 void 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();
400 T0 &= DATA_MASK;
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 }
411 FORCE_RET();
412 }
413
414 void 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) {
424 CC_SRC = (DATA_TYPE)T0 >> (DATA_BITS - count);
425 T0 = T0 << count;
426 CC_DST = T0;
427 CC_OP = CC_OP_SHLB + SHIFT;
428 }
429 FORCE_RET();
430 }
431
432 void 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 }
443 FORCE_RET();
444 }
445
446 void 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;
455 CC_OP = CC_OP_SARB + SHIFT;
456 }
457 FORCE_RET();
458 }
459
460 /* carry add/sub (we only need to set CC_OP differently) */
461
462 void 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
472 void 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
485 void 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
492 void 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
500 void 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
508 void 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
518 /* string operations */
519 /* XXX: maybe use lower level instructions to ease exception handling */
520
521 void 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
530 void 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
543 void OPPROTO glue(op_stos, SUFFIX)(void)
544 {
545 glue(st, SUFFIX)((void *)EDI, EAX);
546 EDI += (DF << SHIFT);
547 }
548
549 void 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
560 void 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 */
575 void 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
593 void OPPROTO glue(op_scas, SUFFIX)(void)
594 {
595 int v;
596
597 v = glue(ldu, SUFFIX)((void *)EDI);
598 EDI += (DF << SHIFT);
599 CC_SRC = EAX;
600 CC_DST = EAX - v;
601 }
602
603 void 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 */
609 v1 = EAX & DATA_MASK;
610 inc = (DF << SHIFT);
611 do {
612 v2 = glue(ldu, SUFFIX)((void *)EDI);
613 EDI += inc;
614 ECX--;
615 if (v1 != v2)
616 break;
617 } while (ECX != 0);
618 CC_SRC = v1;
619 CC_DST = v1 - v2;
620 CC_OP = CC_OP_SUBB + SHIFT;
621 }
622 }
623
624 void 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 */
630 v1 = EAX & DATA_MASK;
631 inc = (DF << SHIFT);
632 do {
633 v2 = glue(ldu, SUFFIX)((void *)EDI);
634 EDI += inc;
635 ECX--;
636 if (v1 == v2)
637 break;
638 } while (ECX != 0);
639 CC_SRC = v1;
640 CC_DST = v1 - v2;
641 CC_OP = CC_OP_SUBB + SHIFT;
642 }
643 }
644
645 void 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
656 void 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);
664 ESI += inc;
665 EDI += inc;
666 ECX--;
667 if (v1 != v2)
668 break;
669 } while (ECX != 0);
670 CC_SRC = v1;
671 CC_DST = v1 - v2;
672 CC_OP = CC_OP_SUBB + SHIFT;
673 }
674 }
675
676 void 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);
684 ESI += inc;
685 EDI += inc;
686 ECX--;
687 if (v1 == v2)
688 break;
689 } while (ECX != 0);
690 CC_SRC = v1;
691 CC_DST = v1 - v2;
692 CC_OP = CC_OP_SUBB + SHIFT;
693 }
694 }
695
696 /* port I/O */
697
698 void OPPROTO glue(op_outs, SUFFIX)(void)
699 {
700 int v, dx;
701 dx = EDX & 0xffff;
702 v = glue(ldu, SUFFIX)((void *)ESI);
703 glue(cpu_x86_out, SUFFIX)(dx, v);
704 ESI += (DF << SHIFT);
705 }
706
707 void 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);
714 glue(cpu_x86_out, SUFFIX)(dx, v);
715 ESI += inc;
716 ECX--;
717 }
718 }
719
720 void OPPROTO glue(op_ins, SUFFIX)(void)
721 {
722 int v, dx;
723 dx = EDX & 0xffff;
724 v = glue(cpu_x86_in, SUFFIX)(dx);
725 glue(st, SUFFIX)((void *)EDI, v);
726 EDI += (DF << SHIFT);
727 }
728
729 void 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) {
735 v = glue(cpu_x86_in, SUFFIX)(dx);
736 glue(st, SUFFIX)((void *)EDI, v);
737 EDI += (DF << SHIFT);
738 ECX--;
739 }
740 }
741
742 void OPPROTO glue(glue(op_out, SUFFIX), _T0_T1)(void)
743 {
744 glue(cpu_x86_out, SUFFIX)(T0 & 0xffff, T1 & DATA_MASK);
745 }
746
747 void OPPROTO glue(glue(op_in, SUFFIX), _T0_T1)(void)
748 {
749 T1 = glue(cpu_x86_in, SUFFIX)(T0 & 0xffff);
750 }
751
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