]> git.proxmox.com Git - qemu.git/blob - ops_template.h
float fixes - added bsr/bsf support
[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 >> (DATA_BITS - 1)) & CC_C;
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 is defined if shift count == 1 */
184 of = lshift(CC_SRC ^ CC_DST, 12 - DATA_BITS) & CC_O;
185 return cf | pf | af | zf | sf | of;
186 }
187
188 #if DATA_BITS == 32
189 static int glue(compute_c_shl, SUFFIX)(void)
190 {
191 return CC_SRC & 1;
192 }
193 #endif
194
195 static int glue(compute_all_sar, SUFFIX)(void)
196 {
197 int cf, pf, af, zf, sf, of;
198 cf = CC_SRC & 1;
199 pf = parity_table[(uint8_t)CC_DST];
200 af = 0; /* undefined */
201 zf = ((DATA_TYPE)CC_DST == 0) << 6;
202 sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
203 /* of is defined if shift count == 1 */
204 of = lshift(CC_SRC ^ CC_DST, 12 - DATA_BITS) & CC_O;
205 return cf | pf | af | zf | sf | of;
206 }
207
208 /* various optimized jumps cases */
209
210 void OPPROTO glue(op_jb_sub, SUFFIX)(void)
211 {
212 int src1, src2;
213 src1 = CC_SRC;
214 src2 = CC_SRC - CC_DST;
215
216 if ((DATA_TYPE)src1 < (DATA_TYPE)src2)
217 PC = PARAM1;
218 else
219 PC = PARAM2;
220 FORCE_RET();
221 }
222
223 void OPPROTO glue(op_jz_sub, SUFFIX)(void)
224 {
225 if ((DATA_TYPE)CC_DST == 0)
226 PC = PARAM1;
227 else
228 PC = PARAM2;
229 FORCE_RET();
230 }
231
232 void OPPROTO glue(op_jbe_sub, SUFFIX)(void)
233 {
234 int src1, src2;
235 src1 = CC_SRC;
236 src2 = CC_SRC - CC_DST;
237
238 if ((DATA_TYPE)src1 <= (DATA_TYPE)src2)
239 PC = PARAM1;
240 else
241 PC = PARAM2;
242 FORCE_RET();
243 }
244
245 void OPPROTO glue(op_js_sub, SUFFIX)(void)
246 {
247 if (CC_DST & SIGN_MASK)
248 PC = PARAM1;
249 else
250 PC = PARAM2;
251 FORCE_RET();
252 }
253
254 void OPPROTO glue(op_jl_sub, SUFFIX)(void)
255 {
256 int src1, src2;
257 src1 = CC_SRC;
258 src2 = CC_SRC - CC_DST;
259
260 if ((DATA_STYPE)src1 < (DATA_STYPE)src2)
261 PC = PARAM1;
262 else
263 PC = PARAM2;
264 FORCE_RET();
265 }
266
267 void OPPROTO glue(op_jle_sub, SUFFIX)(void)
268 {
269 int src1, src2;
270 src1 = CC_SRC;
271 src2 = CC_SRC - CC_DST;
272
273 if ((DATA_STYPE)src1 <= (DATA_STYPE)src2)
274 PC = PARAM1;
275 else
276 PC = PARAM2;
277 FORCE_RET();
278 }
279
280 /* various optimized set cases */
281
282 void OPPROTO glue(op_setb_T0_sub, SUFFIX)(void)
283 {
284 int src1, src2;
285 src1 = CC_SRC;
286 src2 = CC_SRC - CC_DST;
287
288 T0 = ((DATA_TYPE)src1 < (DATA_TYPE)src2);
289 }
290
291 void OPPROTO glue(op_setz_T0_sub, SUFFIX)(void)
292 {
293 T0 = ((DATA_TYPE)CC_DST == 0);
294 }
295
296 void OPPROTO glue(op_setbe_T0_sub, SUFFIX)(void)
297 {
298 int src1, src2;
299 src1 = CC_SRC;
300 src2 = CC_SRC - CC_DST;
301
302 T0 = ((DATA_TYPE)src1 <= (DATA_TYPE)src2);
303 }
304
305 void OPPROTO glue(op_sets_T0_sub, SUFFIX)(void)
306 {
307 T0 = lshift(CC_DST, -(DATA_BITS - 1)) & 1;
308 }
309
310 void OPPROTO glue(op_setl_T0_sub, SUFFIX)(void)
311 {
312 int src1, src2;
313 src1 = CC_SRC;
314 src2 = CC_SRC - CC_DST;
315
316 T0 = ((DATA_STYPE)src1 < (DATA_STYPE)src2);
317 }
318
319 void OPPROTO glue(op_setle_T0_sub, SUFFIX)(void)
320 {
321 int src1, src2;
322 src1 = CC_SRC;
323 src2 = CC_SRC - CC_DST;
324
325 T0 = ((DATA_STYPE)src1 <= (DATA_STYPE)src2);
326 }
327
328 /* shifts */
329
330 void OPPROTO glue(glue(op_rol, SUFFIX), _T0_T1_cc)(void)
331 {
332 int count, src;
333 count = T1 & SHIFT_MASK;
334 if (count) {
335 CC_SRC = cc_table[CC_OP].compute_all() & ~(CC_O | CC_C);
336 src = T0;
337 T0 &= DATA_MASK;
338 T0 = (T0 << count) | (T0 >> (DATA_BITS - count));
339 CC_SRC |= (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
340 (T0 & CC_C);
341 CC_OP = CC_OP_EFLAGS;
342 }
343 FORCE_RET();
344 }
345
346 void OPPROTO glue(glue(op_ror, SUFFIX), _T0_T1_cc)(void)
347 {
348 int count, src;
349 count = T1 & SHIFT_MASK;
350 if (count) {
351 CC_SRC = cc_table[CC_OP].compute_all() & ~(CC_O | CC_C);
352 src = T0;
353 T0 &= DATA_MASK;
354 T0 = (T0 >> count) | (T0 << (DATA_BITS - count));
355 CC_SRC |= (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
356 ((T0 >> (DATA_BITS - 1)) & CC_C);
357 CC_OP = CC_OP_EFLAGS;
358 }
359 FORCE_RET();
360 }
361
362 void OPPROTO glue(glue(op_rcl, SUFFIX), _T0_T1_cc)(void)
363 {
364 int count, res, eflags;
365 unsigned int src;
366
367 count = T1 & 0x1f;
368 #if DATA_BITS == 16
369 count = rclw_table[count];
370 #elif DATA_BITS == 8
371 count = rclb_table[count];
372 #endif
373 if (count) {
374 eflags = cc_table[CC_OP].compute_all();
375 T0 &= DATA_MASK;
376 src = T0;
377 res = (T0 << count) | ((eflags & CC_C) << (count - 1));
378 if (count > 1)
379 res |= T0 >> (DATA_BITS + 1 - count);
380 T0 = res;
381 CC_SRC = (eflags & ~(CC_C | CC_O)) |
382 (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
383 ((src >> (DATA_BITS - count)) & CC_C);
384 CC_OP = CC_OP_EFLAGS;
385 }
386 FORCE_RET();
387 }
388
389 void OPPROTO glue(glue(op_rcr, SUFFIX), _T0_T1_cc)(void)
390 {
391 int count, res, eflags;
392 unsigned int src;
393
394 count = T1 & 0x1f;
395 #if DATA_BITS == 16
396 count = rclw_table[count];
397 #elif DATA_BITS == 8
398 count = rclb_table[count];
399 #endif
400 if (count) {
401 eflags = cc_table[CC_OP].compute_all();
402 T0 &= DATA_MASK;
403 src = T0;
404 res = (T0 >> count) | ((eflags & CC_C) << (DATA_BITS - count));
405 if (count > 1)
406 res |= T0 << (DATA_BITS + 1 - count);
407 T0 = res;
408 CC_SRC = (eflags & ~(CC_C | CC_O)) |
409 (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) |
410 ((src >> (count - 1)) & CC_C);
411 CC_OP = CC_OP_EFLAGS;
412 }
413 FORCE_RET();
414 }
415
416 void OPPROTO glue(glue(op_shl, SUFFIX), _T0_T1_cc)(void)
417 {
418 int count;
419 count = T1 & 0x1f;
420 if (count) {
421 CC_SRC = (DATA_TYPE)T0 << (count - 1);
422 T0 = T0 << count;
423 CC_DST = T0;
424 CC_OP = CC_OP_SHLB + SHIFT;
425 }
426 FORCE_RET();
427 }
428
429 void OPPROTO glue(glue(op_shr, SUFFIX), _T0_T1_cc)(void)
430 {
431 int count;
432 count = T1 & 0x1f;
433 if (count) {
434 T0 &= DATA_MASK;
435 CC_SRC = T0 >> (count - 1);
436 T0 = T0 >> count;
437 CC_DST = T0;
438 CC_OP = CC_OP_SARB + SHIFT;
439 }
440 FORCE_RET();
441 }
442
443 void OPPROTO glue(glue(op_sar, SUFFIX), _T0_T1_cc)(void)
444 {
445 int count, src;
446 count = T1 & 0x1f;
447 if (count) {
448 src = (DATA_STYPE)T0;
449 CC_SRC = src >> (count - 1);
450 T0 = src >> count;
451 CC_DST = T0;
452 CC_OP = CC_OP_SARB + SHIFT;
453 }
454 FORCE_RET();
455 }
456
457 #if DATA_BITS == 16
458 /* XXX: overflow flag might be incorrect in some cases in shldw */
459 void OPPROTO glue(glue(op_shld, SUFFIX), _T0_T1_im_cc)(void)
460 {
461 int count;
462 unsigned int res;
463 count = PARAM1;
464 T1 &= 0xffff;
465 res = T1 | (T0 << 16);
466 CC_SRC = res >> (32 - count);
467 res <<= count;
468 if (count > 16)
469 res |= T1 << (count - 16);
470 T0 = res >> 16;
471 CC_DST = T0;
472 }
473
474 void OPPROTO glue(glue(op_shld, SUFFIX), _T0_T1_ECX_cc)(void)
475 {
476 int count;
477 unsigned int res;
478 count = ECX & 0x1f;
479 if (count) {
480 T1 &= 0xffff;
481 res = T1 | (T0 << 16);
482 CC_SRC = res >> (32 - count);
483 res <<= count;
484 if (count > 16)
485 res |= T1 << (count - 16);
486 T0 = res >> 16;
487 CC_DST = T0;
488 CC_OP = CC_OP_SARB + SHIFT;
489 }
490 }
491
492 void OPPROTO glue(glue(op_shrd, SUFFIX), _T0_T1_im_cc)(void)
493 {
494 int count;
495 unsigned int res;
496
497 count = PARAM1;
498 res = (T0 & 0xffff) | (T1 << 16);
499 CC_SRC = res >> (count - 1);
500 res >>= count;
501 if (count > 16)
502 res |= T1 << (32 - count);
503 T0 = res;
504 CC_DST = T0;
505 }
506
507
508 void OPPROTO glue(glue(op_shrd, SUFFIX), _T0_T1_ECX_cc)(void)
509 {
510 int count;
511 unsigned int res;
512
513 count = ECX & 0x1f;
514 if (count) {
515 res = (T0 & 0xffff) | (T1 << 16);
516 CC_SRC = res >> (count - 1);
517 res >>= count;
518 if (count > 16)
519 res |= T1 << (32 - count);
520 T0 = res;
521 CC_DST = T0;
522 CC_OP = CC_OP_SARB + SHIFT;
523 }
524 }
525 #endif
526
527 #if DATA_BITS == 32
528 void OPPROTO glue(glue(op_shld, SUFFIX), _T0_T1_im_cc)(void)
529 {
530 int count;
531 count = PARAM1;
532 T0 &= DATA_MASK;
533 T1 &= DATA_MASK;
534 CC_SRC = T0 << (count - 1);
535 T0 = (T0 << count) | (T1 >> (DATA_BITS - count));
536 CC_DST = T0;
537 }
538
539 void OPPROTO glue(glue(op_shld, SUFFIX), _T0_T1_ECX_cc)(void)
540 {
541 int count;
542 count = ECX & 0x1f;
543 if (count) {
544 T0 &= DATA_MASK;
545 T1 &= DATA_MASK;
546 CC_SRC = T0 << (count - 1);
547 T0 = (T0 << count) | (T1 >> (DATA_BITS - count));
548 CC_DST = T0;
549 CC_OP = CC_OP_SHLB + SHIFT;
550 }
551 }
552
553 void OPPROTO glue(glue(op_shrd, SUFFIX), _T0_T1_im_cc)(void)
554 {
555 int count;
556 count = PARAM1;
557 T0 &= DATA_MASK;
558 T1 &= DATA_MASK;
559 CC_SRC = T0 >> (count - 1);
560 T0 = (T0 >> count) | (T1 << (DATA_BITS - count));
561 CC_DST = T0;
562 }
563
564
565 void OPPROTO glue(glue(op_shrd, SUFFIX), _T0_T1_ECX_cc)(void)
566 {
567 int count;
568 count = ECX & 0x1f;
569 if (count) {
570 T0 &= DATA_MASK;
571 T1 &= DATA_MASK;
572 CC_SRC = T0 >> (count - 1);
573 T0 = (T0 >> count) | (T1 << (DATA_BITS - count));
574 CC_DST = T0;
575 CC_OP = CC_OP_SARB + SHIFT;
576 }
577 }
578 #endif
579
580 /* carry add/sub (we only need to set CC_OP differently) */
581
582 void OPPROTO glue(glue(op_adc, SUFFIX), _T0_T1_cc)(void)
583 {
584 int cf;
585 cf = cc_table[CC_OP].compute_c();
586 CC_SRC = T0;
587 T0 = T0 + T1 + cf;
588 CC_DST = T0;
589 CC_OP = CC_OP_ADDB + SHIFT + cf * 3;
590 }
591
592 void OPPROTO glue(glue(op_sbb, SUFFIX), _T0_T1_cc)(void)
593 {
594 int cf;
595 cf = cc_table[CC_OP].compute_c();
596 CC_SRC = T0;
597 T0 = T0 - T1 - cf;
598 CC_DST = T0;
599 CC_OP = CC_OP_SUBB + SHIFT + cf * 3;
600 }
601
602 /* bit operations */
603 #if DATA_BITS >= 16
604
605 void OPPROTO glue(glue(op_bt, SUFFIX), _T0_T1_cc)(void)
606 {
607 int count;
608 count = T1 & SHIFT_MASK;
609 CC_SRC = T0 >> count;
610 }
611
612 void OPPROTO glue(glue(op_bts, SUFFIX), _T0_T1_cc)(void)
613 {
614 int count;
615 count = T1 & SHIFT_MASK;
616 CC_SRC = T0 >> count;
617 T0 |= (1 << count);
618 }
619
620 void OPPROTO glue(glue(op_btr, SUFFIX), _T0_T1_cc)(void)
621 {
622 int count;
623 count = T1 & SHIFT_MASK;
624 CC_SRC = T0 >> count;
625 T0 &= ~(1 << count);
626 }
627
628 void OPPROTO glue(glue(op_btc, SUFFIX), _T0_T1_cc)(void)
629 {
630 int count;
631 count = T1 & SHIFT_MASK;
632 CC_SRC = T0 >> count;
633 T0 ^= (1 << count);
634 }
635
636 void OPPROTO glue(glue(op_bsf, SUFFIX), _T0_cc)(void)
637 {
638 int res, count;
639 res = T0 & DATA_MASK;
640 if (res != 0) {
641 count = 0;
642 while ((res & 1) == 0) {
643 count++;
644 res >>= 1;
645 }
646 T0 = count;
647 CC_DST = 1; /* ZF = 1 */
648 } else {
649 CC_DST = 0; /* ZF = 1 */
650 }
651 FORCE_RET();
652 }
653
654 void OPPROTO glue(glue(op_bsr, SUFFIX), _T0_cc)(void)
655 {
656 int res, count;
657 res = T0 & DATA_MASK;
658 if (res != 0) {
659 count = DATA_BITS - 1;
660 while ((res & SIGN_MASK) == 0) {
661 count--;
662 res <<= 1;
663 }
664 T0 = count;
665 CC_DST = 1; /* ZF = 1 */
666 } else {
667 CC_DST = 0; /* ZF = 1 */
668 }
669 FORCE_RET();
670 }
671
672 #endif
673
674 /* string operations */
675 /* XXX: maybe use lower level instructions to ease exception handling */
676
677 void OPPROTO glue(op_movs, SUFFIX)(void)
678 {
679 int v;
680 v = glue(ldu, SUFFIX)((void *)ESI);
681 glue(st, SUFFIX)((void *)EDI, v);
682 ESI += (DF << SHIFT);
683 EDI += (DF << SHIFT);
684 }
685
686 void OPPROTO glue(op_rep_movs, SUFFIX)(void)
687 {
688 int v, inc;
689 inc = (DF << SHIFT);
690 while (ECX != 0) {
691 v = glue(ldu, SUFFIX)((void *)ESI);
692 glue(st, SUFFIX)((void *)EDI, v);
693 ESI += inc;
694 EDI += inc;
695 ECX--;
696 }
697 }
698
699 void OPPROTO glue(op_stos, SUFFIX)(void)
700 {
701 glue(st, SUFFIX)((void *)EDI, EAX);
702 EDI += (DF << SHIFT);
703 }
704
705 void OPPROTO glue(op_rep_stos, SUFFIX)(void)
706 {
707 int inc;
708 inc = (DF << SHIFT);
709 while (ECX != 0) {
710 glue(st, SUFFIX)((void *)EDI, EAX);
711 EDI += inc;
712 ECX--;
713 }
714 }
715
716 void OPPROTO glue(op_lods, SUFFIX)(void)
717 {
718 int v;
719 v = glue(ldu, SUFFIX)((void *)ESI);
720 #if SHIFT == 0
721 EAX = (EAX & ~0xff) | v;
722 #elif SHIFT == 1
723 EAX = (EAX & ~0xffff) | v;
724 #else
725 EAX = v;
726 #endif
727 ESI += (DF << SHIFT);
728 }
729
730 /* don't know if it is used */
731 void OPPROTO glue(op_rep_lods, SUFFIX)(void)
732 {
733 int v, inc;
734 inc = (DF << SHIFT);
735 while (ECX != 0) {
736 v = glue(ldu, SUFFIX)((void *)ESI);
737 #if SHIFT == 0
738 EAX = (EAX & ~0xff) | v;
739 #elif SHIFT == 1
740 EAX = (EAX & ~0xffff) | v;
741 #else
742 EAX = v;
743 #endif
744 ESI += inc;
745 ECX--;
746 }
747 }
748
749 void OPPROTO glue(op_scas, SUFFIX)(void)
750 {
751 int v;
752
753 v = glue(ldu, SUFFIX)((void *)EDI);
754 EDI += (DF << SHIFT);
755 CC_SRC = EAX;
756 CC_DST = EAX - v;
757 }
758
759 void OPPROTO glue(op_repz_scas, SUFFIX)(void)
760 {
761 int v1, v2, inc;
762
763 if (ECX != 0) {
764 /* NOTE: the flags are not modified if ECX == 0 */
765 v1 = EAX & DATA_MASK;
766 inc = (DF << SHIFT);
767 do {
768 v2 = glue(ldu, SUFFIX)((void *)EDI);
769 EDI += inc;
770 ECX--;
771 if (v1 != v2)
772 break;
773 } while (ECX != 0);
774 CC_SRC = v1;
775 CC_DST = v1 - v2;
776 CC_OP = CC_OP_SUBB + SHIFT;
777 }
778 }
779
780 void OPPROTO glue(op_repnz_scas, SUFFIX)(void)
781 {
782 int v1, v2, inc;
783
784 if (ECX != 0) {
785 /* NOTE: the flags are not modified if ECX == 0 */
786 v1 = EAX & DATA_MASK;
787 inc = (DF << SHIFT);
788 do {
789 v2 = glue(ldu, SUFFIX)((void *)EDI);
790 EDI += inc;
791 ECX--;
792 if (v1 == v2)
793 break;
794 } while (ECX != 0);
795 CC_SRC = v1;
796 CC_DST = v1 - v2;
797 CC_OP = CC_OP_SUBB + SHIFT;
798 }
799 }
800
801 void OPPROTO glue(op_cmps, SUFFIX)(void)
802 {
803 int v1, v2;
804 v1 = glue(ldu, SUFFIX)((void *)ESI);
805 v2 = glue(ldu, SUFFIX)((void *)EDI);
806 ESI += (DF << SHIFT);
807 EDI += (DF << SHIFT);
808 CC_SRC = v1;
809 CC_DST = v1 - v2;
810 }
811
812 void OPPROTO glue(op_repz_cmps, SUFFIX)(void)
813 {
814 int v1, v2, inc;
815 if (ECX != 0) {
816 inc = (DF << SHIFT);
817 do {
818 v1 = glue(ldu, SUFFIX)((void *)ESI);
819 v2 = glue(ldu, SUFFIX)((void *)EDI);
820 ESI += inc;
821 EDI += inc;
822 ECX--;
823 if (v1 != v2)
824 break;
825 } while (ECX != 0);
826 CC_SRC = v1;
827 CC_DST = v1 - v2;
828 CC_OP = CC_OP_SUBB + SHIFT;
829 }
830 }
831
832 void OPPROTO glue(op_repnz_cmps, SUFFIX)(void)
833 {
834 int v1, v2, inc;
835 if (ECX != 0) {
836 inc = (DF << SHIFT);
837 do {
838 v1 = glue(ldu, SUFFIX)((void *)ESI);
839 v2 = glue(ldu, SUFFIX)((void *)EDI);
840 ESI += inc;
841 EDI += inc;
842 ECX--;
843 if (v1 == v2)
844 break;
845 } while (ECX != 0);
846 CC_SRC = v1;
847 CC_DST = v1 - v2;
848 CC_OP = CC_OP_SUBB + SHIFT;
849 }
850 }
851
852 /* port I/O */
853
854 void OPPROTO glue(op_outs, SUFFIX)(void)
855 {
856 int v, dx;
857 dx = EDX & 0xffff;
858 v = glue(ldu, SUFFIX)((void *)ESI);
859 glue(cpu_x86_out, SUFFIX)(dx, v);
860 ESI += (DF << SHIFT);
861 }
862
863 void OPPROTO glue(op_rep_outs, SUFFIX)(void)
864 {
865 int v, dx, inc;
866 inc = (DF << SHIFT);
867 dx = EDX & 0xffff;
868 while (ECX != 0) {
869 v = glue(ldu, SUFFIX)((void *)ESI);
870 glue(cpu_x86_out, SUFFIX)(dx, v);
871 ESI += inc;
872 ECX--;
873 }
874 }
875
876 void OPPROTO glue(op_ins, SUFFIX)(void)
877 {
878 int v, dx;
879 dx = EDX & 0xffff;
880 v = glue(cpu_x86_in, SUFFIX)(dx);
881 glue(st, SUFFIX)((void *)EDI, v);
882 EDI += (DF << SHIFT);
883 }
884
885 void OPPROTO glue(op_rep_ins, SUFFIX)(void)
886 {
887 int v, dx, inc;
888 inc = (DF << SHIFT);
889 dx = EDX & 0xffff;
890 while (ECX != 0) {
891 v = glue(cpu_x86_in, SUFFIX)(dx);
892 glue(st, SUFFIX)((void *)EDI, v);
893 EDI += (DF << SHIFT);
894 ECX--;
895 }
896 }
897
898 void OPPROTO glue(glue(op_out, SUFFIX), _T0_T1)(void)
899 {
900 glue(cpu_x86_out, SUFFIX)(T0 & 0xffff, T1 & DATA_MASK);
901 }
902
903 void OPPROTO glue(glue(op_in, SUFFIX), _T0_T1)(void)
904 {
905 T1 = glue(cpu_x86_in, SUFFIX)(T0 & 0xffff);
906 }
907
908 #undef DATA_BITS
909 #undef SHIFT_MASK
910 #undef SIGN_MASK
911 #undef DATA_TYPE
912 #undef DATA_STYPE
913 #undef DATA_MASK
914 #undef SUFFIX