]> Git Repo - qemu.git/blob - ops_template.h
basic signal handling
[qemu.git] / ops_template.h
1 /*
2  *  i386 micro operations (included several times to generate
3  *  different operand sizes)
4  * 
5  *  Copyright (c) 2003 Fabrice Bellard
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 2 of the License, or
10  *  (at your option) any later version.
11  *
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with this program; if not, write to the Free Software
19  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  
20  */
21
22 #define DATA_BITS (1 << (3 + SHIFT))
23 #define SHIFT_MASK (DATA_BITS - 1)
24 #define SIGN_MASK (1 << (DATA_BITS - 1))
25
26 #if DATA_BITS == 8
27 #define SUFFIX b
28 #define DATA_TYPE uint8_t
29 #define DATA_STYPE int8_t
30 #define DATA_MASK 0xff
31 #elif DATA_BITS == 16
32 #define SUFFIX w
33 #define DATA_TYPE uint16_t
34 #define DATA_STYPE int16_t
35 #define DATA_MASK 0xffff
36 #elif DATA_BITS == 32
37 #define SUFFIX l
38 #define DATA_TYPE uint32_t
39 #define DATA_STYPE int32_t
40 #define DATA_MASK 0xffffffff
41 #else
42 #error unhandled operand size
43 #endif
44
45 /* dynamic flags computation */
46
47 static int glue(compute_all_add, SUFFIX)(void)
48 {
49     int cf, pf, af, zf, sf, of;
50     int src1, src2;
51     src1 = CC_SRC;
52     src2 = CC_DST - CC_SRC;
53     cf = (DATA_TYPE)CC_DST < (DATA_TYPE)src1;
54     pf = parity_table[(uint8_t)CC_DST];
55     af = (CC_DST ^ src1 ^ src2) & 0x10;
56     zf = ((DATA_TYPE)CC_DST == 0) << 6;
57     sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
58     of = lshift((src1 ^ src2 ^ -1) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
59     return cf | pf | af | zf | sf | of;
60 }
61
62 static int glue(compute_c_add, SUFFIX)(void)
63 {
64     int src1, cf;
65     src1 = CC_SRC;
66     cf = (DATA_TYPE)CC_DST < (DATA_TYPE)src1;
67     return cf;
68 }
69
70 static int glue(compute_all_adc, SUFFIX)(void)
71 {
72     int cf, pf, af, zf, sf, of;
73     int src1, src2;
74     src1 = CC_SRC;
75     src2 = CC_DST - CC_SRC - 1;
76     cf = (DATA_TYPE)CC_DST <= (DATA_TYPE)src1;
77     pf = parity_table[(uint8_t)CC_DST];
78     af = (CC_DST ^ src1 ^ src2) & 0x10;
79     zf = ((DATA_TYPE)CC_DST == 0) << 6;
80     sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
81     of = lshift((src1 ^ src2 ^ -1) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
82     return cf | pf | af | zf | sf | of;
83 }
84
85 static int glue(compute_c_adc, SUFFIX)(void)
86 {
87     int src1, cf;
88     src1 = CC_SRC;
89     cf = (DATA_TYPE)CC_DST <= (DATA_TYPE)src1;
90     return cf;
91 }
92
93 static int glue(compute_all_sub, SUFFIX)(void)
94 {
95     int cf, pf, af, zf, sf, of;
96     int src1, src2;
97     src1 = CC_SRC;
98     src2 = CC_SRC - CC_DST;
99     cf = (DATA_TYPE)src1 < (DATA_TYPE)src2;
100     pf = parity_table[(uint8_t)CC_DST];
101     af = (CC_DST ^ src1 ^ src2) & 0x10;
102     zf = ((DATA_TYPE)CC_DST == 0) << 6;
103     sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
104     of = lshift((src1 ^ src2) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
105     return cf | pf | af | zf | sf | of;
106 }
107
108 static int glue(compute_c_sub, SUFFIX)(void)
109 {
110     int src1, src2, cf;
111     src1 = CC_SRC;
112     src2 = CC_SRC - CC_DST;
113     cf = (DATA_TYPE)src1 < (DATA_TYPE)src2;
114     return cf;
115 }
116
117 static int glue(compute_all_sbb, SUFFIX)(void)
118 {
119     int cf, pf, af, zf, sf, of;
120     int src1, src2;
121     src1 = CC_SRC;
122     src2 = CC_SRC - CC_DST - 1;
123     cf = (DATA_TYPE)src1 <= (DATA_TYPE)src2;
124     pf = parity_table[(uint8_t)CC_DST];
125     af = (CC_DST ^ src1 ^ src2) & 0x10;
126     zf = ((DATA_TYPE)CC_DST == 0) << 6;
127     sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
128     of = lshift((src1 ^ src2) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
129     return cf | pf | af | zf | sf | of;
130 }
131
132 static int glue(compute_c_sbb, SUFFIX)(void)
133 {
134     int src1, src2, cf;
135     src1 = CC_SRC;
136     src2 = CC_SRC - CC_DST - 1;
137     cf = (DATA_TYPE)src1 <= (DATA_TYPE)src2;
138     return cf;
139 }
140
141 static int glue(compute_all_logic, SUFFIX)(void)
142 {
143     int cf, pf, af, zf, sf, of;
144     cf = 0;
145     pf = parity_table[(uint8_t)CC_DST];
146     af = 0;
147     zf = ((DATA_TYPE)CC_DST == 0) << 6;
148     sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
149     of = 0;
150     return cf | pf | af | zf | sf | of;
151 }
152
153 static int glue(compute_c_logic, SUFFIX)(void)
154 {
155     return 0;
156 }
157
158 static int glue(compute_all_inc, SUFFIX)(void)
159 {
160     int cf, pf, af, zf, sf, of;
161     int src1, src2;
162     src1 = CC_DST - 1;
163     src2 = 1;
164     cf = CC_SRC;
165     pf = parity_table[(uint8_t)CC_DST];
166     af = (CC_DST ^ src1 ^ src2) & 0x10;
167     zf = ((DATA_TYPE)CC_DST == 0) << 6;
168     sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
169     of = ((CC_DST & DATA_MASK) == SIGN_MASK) << 11;
170     return cf | pf | af | zf | sf | of;
171 }
172
173 #if DATA_BITS == 32
174 static int glue(compute_c_inc, SUFFIX)(void)
175 {
176     return CC_SRC;
177 }
178 #endif
179
180 static int glue(compute_all_dec, SUFFIX)(void)
181 {
182     int cf, pf, af, zf, sf, of;
183     int src1, src2;
184     src1 = CC_DST + 1;
185     src2 = 1;
186     cf = CC_SRC;
187     pf = parity_table[(uint8_t)CC_DST];
188     af = (CC_DST ^ src1 ^ src2) & 0x10;
189     zf = ((DATA_TYPE)CC_DST == 0) << 6;
190     sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
191     of = ((CC_DST & DATA_MASK) == ((uint32_t)SIGN_MASK - 1)) << 11;
192     return cf | pf | af | zf | sf | of;
193 }
194
195 static int glue(compute_all_shl, SUFFIX)(void)
196 {
197     int cf, pf, af, zf, sf, of;
198     cf = (CC_SRC >> (DATA_BITS - 1)) & CC_C;
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 #if DATA_BITS == 32
209 static int glue(compute_c_shl, SUFFIX)(void)
210 {
211     return CC_SRC & 1;
212 }
213 #endif
214
215 static int glue(compute_all_sar, SUFFIX)(void)
216 {
217     int cf, pf, af, zf, sf, of;
218     cf = CC_SRC & 1;
219     pf = parity_table[(uint8_t)CC_DST];
220     af = 0; /* undefined */
221     zf = ((DATA_TYPE)CC_DST == 0) << 6;
222     sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;
223     /* of is defined if shift count == 1 */
224     of = lshift(CC_SRC ^ CC_DST, 12 - DATA_BITS) & CC_O; 
225     return cf | pf | af | zf | sf | of;
226 }
227
228 /* various optimized jumps cases */
229
230 void OPPROTO glue(op_jb_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         EIP = PARAM1;
238     else
239         EIP = PARAM2;
240     FORCE_RET();
241 }
242
243 void OPPROTO glue(op_jz_sub, SUFFIX)(void)
244 {
245     if ((DATA_TYPE)CC_DST == 0)
246         EIP = PARAM1;
247     else
248         EIP = PARAM2;
249     FORCE_RET();
250 }
251
252 void OPPROTO glue(op_jbe_sub, SUFFIX)(void)
253 {
254     int src1, src2;
255     src1 = CC_SRC;
256     src2 = CC_SRC - CC_DST;
257
258     if ((DATA_TYPE)src1 <= (DATA_TYPE)src2)
259         EIP = PARAM1;
260     else
261         EIP = PARAM2;
262     FORCE_RET();
263 }
264
265 void OPPROTO glue(op_js_sub, SUFFIX)(void)
266 {
267     if (CC_DST & SIGN_MASK)
268         EIP = PARAM1;
269     else
270         EIP = PARAM2;
271     FORCE_RET();
272 }
273
274 void OPPROTO glue(op_jl_sub, SUFFIX)(void)
275 {
276     int src1, src2;
277     src1 = CC_SRC;
278     src2 = CC_SRC - CC_DST;
279
280     if ((DATA_STYPE)src1 < (DATA_STYPE)src2)
281         EIP = PARAM1;
282     else
283         EIP = PARAM2;
284     FORCE_RET();
285 }
286
287 void OPPROTO glue(op_jle_sub, SUFFIX)(void)
288 {
289     int src1, src2;
290     src1 = CC_SRC;
291     src2 = CC_SRC - CC_DST;
292
293     if ((DATA_STYPE)src1 <= (DATA_STYPE)src2)
294         EIP = PARAM1;
295     else
296         EIP = PARAM2;
297     FORCE_RET();
298 }
299
300 /* oldies */
301
302 #if DATA_BITS >= 16
303
304 void OPPROTO glue(op_loopnz, SUFFIX)(void)
305 {
306     unsigned int tmp;
307     int eflags;
308     eflags = cc_table[CC_OP].compute_all();
309     tmp = (ECX - 1) & DATA_MASK;
310     ECX = (ECX & ~DATA_MASK) | tmp;
311     if (tmp != 0 && !(eflags & CC_Z))
312         EIP = PARAM1;
313     else
314         EIP = PARAM2;
315     FORCE_RET();
316 }
317
318 void OPPROTO glue(op_loopz, SUFFIX)(void)
319 {
320     unsigned int tmp;
321     int eflags;
322     eflags = cc_table[CC_OP].compute_all();
323     tmp = (ECX - 1) & DATA_MASK;
324     ECX = (ECX & ~DATA_MASK) | tmp;
325     if (tmp != 0 && (eflags & CC_Z))
326         EIP = PARAM1;
327     else
328         EIP = PARAM2;
329     FORCE_RET();
330 }
331
332 void OPPROTO glue(op_loop, SUFFIX)(void)
333 {
334     unsigned int tmp;
335     tmp = (ECX - 1) & DATA_MASK;
336     ECX = (ECX & ~DATA_MASK) | tmp;
337     if (tmp != 0)
338         EIP = PARAM1;
339     else
340         EIP = PARAM2;
341     FORCE_RET();
342 }
343
344 void OPPROTO glue(op_jecxz, SUFFIX)(void)
345 {
346     if ((DATA_TYPE)ECX == 0)
347         EIP = PARAM1;
348     else
349         EIP = PARAM2;
350     FORCE_RET();
351 }
352
353 #endif
354
355 /* various optimized set cases */
356
357 void OPPROTO glue(op_setb_T0_sub, SUFFIX)(void)
358 {
359     int src1, src2;
360     src1 = CC_SRC;
361     src2 = CC_SRC - CC_DST;
362
363     T0 = ((DATA_TYPE)src1 < (DATA_TYPE)src2);
364 }
365
366 void OPPROTO glue(op_setz_T0_sub, SUFFIX)(void)
367 {
368     T0 = ((DATA_TYPE)CC_DST == 0);
369 }
370
371 void OPPROTO glue(op_setbe_T0_sub, SUFFIX)(void)
372 {
373     int src1, src2;
374     src1 = CC_SRC;
375     src2 = CC_SRC - CC_DST;
376
377     T0 = ((DATA_TYPE)src1 <= (DATA_TYPE)src2);
378 }
379
380 void OPPROTO glue(op_sets_T0_sub, SUFFIX)(void)
381 {
382     T0 = lshift(CC_DST, -(DATA_BITS - 1)) & 1;
383 }
384
385 void OPPROTO glue(op_setl_T0_sub, SUFFIX)(void)
386 {
387     int src1, src2;
388     src1 = CC_SRC;
389     src2 = CC_SRC - CC_DST;
390
391     T0 = ((DATA_STYPE)src1 < (DATA_STYPE)src2);
392 }
393
394 void OPPROTO glue(op_setle_T0_sub, SUFFIX)(void)
395 {
396     int src1, src2;
397     src1 = CC_SRC;
398     src2 = CC_SRC - CC_DST;
399
400     T0 = ((DATA_STYPE)src1 <= (DATA_STYPE)src2);
401 }
402
403 /* shifts */
404
405 void OPPROTO glue(glue(op_rol, SUFFIX), _T0_T1_cc)(void)
406 {
407     int count, src;
408     count = T1 & SHIFT_MASK;
409     if (count) {
410         CC_SRC = cc_table[CC_OP].compute_all() & ~(CC_O | CC_C);
411         src = T0;
412         T0 &= DATA_MASK;
413         T0 = (T0 << count) | (T0 >> (DATA_BITS - count));
414         CC_SRC |= (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) | 
415             (T0 & CC_C);
416         CC_OP = CC_OP_EFLAGS;
417     }
418     FORCE_RET();
419 }
420
421 void OPPROTO glue(glue(op_rol, SUFFIX), _T0_T1)(void)
422 {
423     int count;
424     count = T1 & SHIFT_MASK;
425     if (count) {
426         T0 &= DATA_MASK;
427         T0 = (T0 << count) | (T0 >> (DATA_BITS - count));
428     }
429     FORCE_RET();
430 }
431
432 void OPPROTO glue(glue(op_ror, SUFFIX), _T0_T1_cc)(void)
433 {
434     int count, src;
435     count = T1 & SHIFT_MASK;
436     if (count) {
437         CC_SRC = cc_table[CC_OP].compute_all() & ~(CC_O | CC_C);
438         src = T0;
439         T0 &= DATA_MASK;
440         T0 = (T0 >> count) | (T0 << (DATA_BITS - count));
441         CC_SRC |= (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) | 
442             ((T0 >> (DATA_BITS - 1)) & CC_C);
443         CC_OP = CC_OP_EFLAGS;
444     }
445     FORCE_RET();
446 }
447
448 void OPPROTO glue(glue(op_ror, SUFFIX), _T0_T1)(void)
449 {
450     int count;
451     count = T1 & SHIFT_MASK;
452     if (count) {
453         T0 &= DATA_MASK;
454         T0 = (T0 >> count) | (T0 << (DATA_BITS - count));
455     }
456     FORCE_RET();
457 }
458
459 void OPPROTO glue(glue(op_rcl, SUFFIX), _T0_T1_cc)(void)
460 {
461     int count, res, eflags;
462     unsigned int src;
463
464     count = T1 & 0x1f;
465 #if DATA_BITS == 16
466     count = rclw_table[count];
467 #elif DATA_BITS == 8
468     count = rclb_table[count];
469 #endif
470     if (count) {
471         eflags = cc_table[CC_OP].compute_all();
472         T0 &= DATA_MASK;
473         src = T0;
474         res = (T0 << count) | ((eflags & CC_C) << (count - 1));
475         if (count > 1)
476             res |= T0 >> (DATA_BITS + 1 - count);
477         T0 = res;
478         CC_SRC = (eflags & ~(CC_C | CC_O)) |
479             (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) | 
480             ((src >> (DATA_BITS - count)) & CC_C);
481         CC_OP = CC_OP_EFLAGS;
482     }
483     FORCE_RET();
484 }
485
486 void OPPROTO glue(glue(op_rcr, SUFFIX), _T0_T1_cc)(void)
487 {
488     int count, res, eflags;
489     unsigned int src;
490
491     count = T1 & 0x1f;
492 #if DATA_BITS == 16
493     count = rclw_table[count];
494 #elif DATA_BITS == 8
495     count = rclb_table[count];
496 #endif
497     if (count) {
498         eflags = cc_table[CC_OP].compute_all();
499         T0 &= DATA_MASK;
500         src = T0;
501         res = (T0 >> count) | ((eflags & CC_C) << (DATA_BITS - count));
502         if (count > 1)
503             res |= T0 << (DATA_BITS + 1 - count);
504         T0 = res;
505         CC_SRC = (eflags & ~(CC_C | CC_O)) |
506             (lshift(src ^ T0, 11 - (DATA_BITS - 1)) & CC_O) | 
507             ((src >> (count - 1)) & CC_C);
508         CC_OP = CC_OP_EFLAGS;
509     }
510     FORCE_RET();
511 }
512
513 void OPPROTO glue(glue(op_shl, SUFFIX), _T0_T1_cc)(void)
514 {
515     int count;
516     count = T1 & 0x1f;
517     if (count) {
518         CC_SRC = (DATA_TYPE)T0 << (count - 1);
519         T0 = T0 << count;
520         CC_DST = T0;
521         CC_OP = CC_OP_SHLB + SHIFT;
522     }
523     FORCE_RET();
524 }
525
526 void OPPROTO glue(glue(op_shl, SUFFIX), _T0_T1)(void)
527 {
528     int count;
529     count = T1 & 0x1f;
530     T0 = T0 << count;
531     FORCE_RET();
532 }
533
534 void OPPROTO glue(glue(op_shr, SUFFIX), _T0_T1_cc)(void)
535 {
536     int count;
537     count = T1 & 0x1f;
538     if (count) {
539         T0 &= DATA_MASK;
540         CC_SRC = T0 >> (count - 1);
541         T0 = T0 >> count;
542         CC_DST = T0;
543         CC_OP = CC_OP_SARB + SHIFT;
544     }
545     FORCE_RET();
546 }
547
548 void OPPROTO glue(glue(op_shr, SUFFIX), _T0_T1)(void)
549 {
550     int count;
551     count = T1 & 0x1f;
552     T0 &= DATA_MASK;
553     T0 = T0 >> count;
554     FORCE_RET();
555 }
556
557 void OPPROTO glue(glue(op_sar, SUFFIX), _T0_T1_cc)(void)
558 {
559     int count, src;
560     count = T1 & 0x1f;
561     if (count) {
562         src = (DATA_STYPE)T0;
563         CC_SRC = src >> (count - 1);
564         T0 = src >> count;
565         CC_DST = T0;
566         CC_OP = CC_OP_SARB + SHIFT;
567     }
568     FORCE_RET();
569 }
570
571 void OPPROTO glue(glue(op_sar, SUFFIX), _T0_T1)(void)
572 {
573     int count, src;
574     count = T1 & 0x1f;
575     src = (DATA_STYPE)T0;
576     T0 = src >> count;
577     FORCE_RET();
578 }
579
580 #if DATA_BITS == 16
581 /* XXX: overflow flag might be incorrect in some cases in shldw */
582 void OPPROTO glue(glue(op_shld, SUFFIX), _T0_T1_im_cc)(void)
583 {
584     int count;
585     unsigned int res;
586     count = PARAM1;
587     T1 &= 0xffff;
588     res = T1 | (T0 << 16);
589     CC_SRC = res >> (32 - count);
590     res <<= count;
591     if (count > 16)
592         res |= T1 << (count - 16);
593     T0 = res >> 16;
594     CC_DST = T0;
595 }
596
597 void OPPROTO glue(glue(op_shld, SUFFIX), _T0_T1_ECX_cc)(void)
598 {
599     int count;
600     unsigned int res;
601     count = ECX & 0x1f;
602     if (count) {
603         T1 &= 0xffff;
604         res = T1 | (T0 << 16);
605         CC_SRC = res >> (32 - count);
606         res <<= count;
607         if (count > 16)
608           res |= T1 << (count - 16);
609         T0 = res >> 16;
610         CC_DST = T0;
611         CC_OP = CC_OP_SARB + SHIFT;
612     }
613 }
614
615 void OPPROTO glue(glue(op_shrd, SUFFIX), _T0_T1_im_cc)(void)
616 {
617     int count;
618     unsigned int res;
619
620     count = PARAM1;
621     res = (T0 & 0xffff) | (T1 << 16);
622     CC_SRC = res >> (count - 1);
623     res >>= count;
624     if (count > 16)
625         res |= T1 << (32 - count);
626     T0 = res;
627     CC_DST = T0;
628 }
629
630
631 void OPPROTO glue(glue(op_shrd, SUFFIX), _T0_T1_ECX_cc)(void)
632 {
633     int count;
634     unsigned int res;
635
636     count = ECX & 0x1f;
637     if (count) {
638         res = (T0 & 0xffff) | (T1 << 16);
639         CC_SRC = res >> (count - 1);
640         res >>= count;
641         if (count > 16)
642             res |= T1 << (32 - count);
643         T0 = res;
644         CC_DST = T0;
645         CC_OP = CC_OP_SARB + SHIFT;
646     }
647 }
648 #endif
649
650 #if DATA_BITS == 32
651 void OPPROTO glue(glue(op_shld, SUFFIX), _T0_T1_im_cc)(void)
652 {
653     int count;
654     count = PARAM1;
655     T0 &= DATA_MASK;
656     T1 &= DATA_MASK;
657     CC_SRC = T0 << (count - 1);
658     T0 = (T0 << count) | (T1 >> (DATA_BITS - count));
659     CC_DST = T0;
660 }
661
662 void OPPROTO glue(glue(op_shld, SUFFIX), _T0_T1_ECX_cc)(void)
663 {
664     int count;
665     count = ECX & 0x1f;
666     if (count) {
667         T0 &= DATA_MASK;
668         T1 &= DATA_MASK;
669         CC_SRC = T0 << (count - 1);
670         T0 = (T0 << count) | (T1 >> (DATA_BITS - count));
671         CC_DST = T0;
672         CC_OP = CC_OP_SHLB + SHIFT;
673     }
674 }
675
676 void OPPROTO glue(glue(op_shrd, SUFFIX), _T0_T1_im_cc)(void)
677 {
678     int count;
679     count = PARAM1;
680     T0 &= DATA_MASK;
681     T1 &= DATA_MASK;
682     CC_SRC = T0 >> (count - 1);
683     T0 = (T0 >> count) | (T1 << (DATA_BITS - count));
684     CC_DST = T0;
685 }
686
687
688 void OPPROTO glue(glue(op_shrd, SUFFIX), _T0_T1_ECX_cc)(void)
689 {
690     int count;
691     count = ECX & 0x1f;
692     if (count) {
693         T0 &= DATA_MASK;
694         T1 &= DATA_MASK;
695         CC_SRC = T0 >> (count - 1);
696         T0 = (T0 >> count) | (T1 << (DATA_BITS - count));
697         CC_DST = T0;
698         CC_OP = CC_OP_SARB + SHIFT;
699     }
700 }
701 #endif
702
703 /* carry add/sub (we only need to set CC_OP differently) */
704
705 void OPPROTO glue(glue(op_adc, SUFFIX), _T0_T1_cc)(void)
706 {
707     int cf;
708     cf = cc_table[CC_OP].compute_c();
709     CC_SRC = T0;
710     T0 = T0 + T1 + cf;
711     CC_DST = T0;
712     CC_OP = CC_OP_ADDB + SHIFT + cf * 3;
713 }
714
715 void OPPROTO glue(glue(op_sbb, SUFFIX), _T0_T1_cc)(void)
716 {
717     int cf;
718     cf = cc_table[CC_OP].compute_c();
719     CC_SRC = T0;
720     T0 = T0 - T1 - cf;
721     CC_DST = T0;
722     CC_OP = CC_OP_SUBB + SHIFT + cf * 3;
723 }
724
725 void OPPROTO glue(glue(op_cmpxchg, SUFFIX), _T0_T1_EAX_cc)(void)
726 {
727     CC_SRC = EAX;
728     CC_DST = EAX - T0;
729     if ((DATA_TYPE)CC_DST == 0) {
730         T0 = T1;
731     } else {
732         EAX = (EAX & ~DATA_MASK) | (T0 & DATA_MASK);
733     }
734     FORCE_RET();
735 }
736
737 /* bit operations */
738 #if DATA_BITS >= 16
739
740 void OPPROTO glue(glue(op_bt, SUFFIX), _T0_T1_cc)(void)
741 {
742     int count;
743     count = T1 & SHIFT_MASK;
744     CC_SRC = T0 >> count;
745 }
746
747 void OPPROTO glue(glue(op_bts, SUFFIX), _T0_T1_cc)(void)
748 {
749     int count;
750     count = T1 & SHIFT_MASK;
751     CC_SRC = T0 >> count;
752     T0 |= (1 << count);
753 }
754
755 void OPPROTO glue(glue(op_btr, SUFFIX), _T0_T1_cc)(void)
756 {
757     int count;
758     count = T1 & SHIFT_MASK;
759     CC_SRC = T0 >> count;
760     T0 &= ~(1 << count);
761 }
762
763 void OPPROTO glue(glue(op_btc, SUFFIX), _T0_T1_cc)(void)
764 {
765     int count;
766     count = T1 & SHIFT_MASK;
767     CC_SRC = T0 >> count;
768     T0 ^= (1 << count);
769 }
770
771 void OPPROTO glue(glue(op_bsf, SUFFIX), _T0_cc)(void)
772 {
773     int res, count;
774     res = T0 & DATA_MASK;
775     if (res != 0) {
776         count = 0;
777         while ((res & 1) == 0) {
778             count++;
779             res >>= 1;
780         }
781         T0 = count;
782         CC_DST = 1; /* ZF = 1 */
783     } else {
784         CC_DST = 0; /* ZF = 1 */
785     }
786     FORCE_RET();
787 }
788
789 void OPPROTO glue(glue(op_bsr, SUFFIX), _T0_cc)(void)
790 {
791     int res, count;
792     res = T0 & DATA_MASK;
793     if (res != 0) {
794         count = DATA_BITS - 1;
795         while ((res & SIGN_MASK) == 0) {
796             count--;
797             res <<= 1;
798         }
799         T0 = count;
800         CC_DST = 1; /* ZF = 1 */
801     } else {
802         CC_DST = 0; /* ZF = 1 */
803     }
804     FORCE_RET();
805 }
806
807 #endif
808
809 /* string operations */
810 /* XXX: maybe use lower level instructions to ease exception handling */
811
812 void OPPROTO glue(op_movs, SUFFIX)(void)
813 {
814     int v;
815     v = glue(ldu, SUFFIX)((void *)ESI);
816     glue(st, SUFFIX)((void *)EDI, v);
817     ESI += (DF << SHIFT);
818     EDI += (DF << SHIFT);
819 }
820
821 void OPPROTO glue(op_rep_movs, SUFFIX)(void)
822 {
823     int v, inc;
824     inc = (DF << SHIFT);
825     while (ECX != 0) {
826         v = glue(ldu, SUFFIX)((void *)ESI);
827         glue(st, SUFFIX)((void *)EDI, v);
828         ESI += inc;
829         EDI += inc;
830         ECX--;
831     }
832     FORCE_RET();
833 }
834
835 void OPPROTO glue(op_stos, SUFFIX)(void)
836 {
837     glue(st, SUFFIX)((void *)EDI, EAX);
838     EDI += (DF << SHIFT);
839 }
840
841 void OPPROTO glue(op_rep_stos, SUFFIX)(void)
842 {
843     int inc;
844     inc = (DF << SHIFT);
845     while (ECX != 0) {
846         glue(st, SUFFIX)((void *)EDI, EAX);
847         EDI += inc;
848         ECX--;
849     }
850     FORCE_RET();
851 }
852
853 void OPPROTO glue(op_lods, SUFFIX)(void)
854 {
855     int v;
856     v = glue(ldu, SUFFIX)((void *)ESI);
857 #if SHIFT == 0
858     EAX = (EAX & ~0xff) | v;
859 #elif SHIFT == 1
860     EAX = (EAX & ~0xffff) | v;
861 #else
862     EAX = v;
863 #endif
864     ESI += (DF << SHIFT);
865 }
866
867 /* don't know if it is used */
868 void OPPROTO glue(op_rep_lods, SUFFIX)(void)
869 {
870     int v, inc;
871     inc = (DF << SHIFT);
872     while (ECX != 0) {
873         v = glue(ldu, SUFFIX)((void *)ESI);
874 #if SHIFT == 0
875         EAX = (EAX & ~0xff) | v;
876 #elif SHIFT == 1
877         EAX = (EAX & ~0xffff) | v;
878 #else
879         EAX = v;
880 #endif
881         ESI += inc;
882         ECX--;
883     }
884     FORCE_RET();
885 }
886
887 void OPPROTO glue(op_scas, SUFFIX)(void)
888 {
889     int v;
890
891     v = glue(ldu, SUFFIX)((void *)EDI);
892     EDI += (DF << SHIFT);
893     CC_SRC = EAX;
894     CC_DST = EAX - v;
895 }
896
897 void OPPROTO glue(op_repz_scas, SUFFIX)(void)
898 {
899     int v1, v2, inc;
900
901     if (ECX != 0) {
902         /* NOTE: the flags are not modified if ECX == 0 */
903         v1 = EAX & DATA_MASK;
904         inc = (DF << SHIFT);
905         do {
906             v2 = glue(ldu, SUFFIX)((void *)EDI);
907             EDI += inc;
908             ECX--;
909             if (v1 != v2)
910                 break;
911         } while (ECX != 0);
912         CC_SRC = v1;
913         CC_DST = v1 - v2;
914         CC_OP = CC_OP_SUBB + SHIFT;
915     }
916     FORCE_RET();
917 }
918
919 void OPPROTO glue(op_repnz_scas, SUFFIX)(void)
920 {
921     int v1, v2, inc;
922
923     if (ECX != 0) {
924         /* NOTE: the flags are not modified if ECX == 0 */
925         v1 = EAX & DATA_MASK;
926         inc = (DF << SHIFT);
927         do {
928             v2 = glue(ldu, SUFFIX)((void *)EDI);
929             EDI += inc;
930             ECX--;
931             if (v1 == v2)
932                 break;
933         } while (ECX != 0);
934         CC_SRC = v1;
935         CC_DST = v1 - v2;
936         CC_OP = CC_OP_SUBB + SHIFT;
937     }
938     FORCE_RET();
939 }
940
941 void OPPROTO glue(op_cmps, SUFFIX)(void)
942 {
943     int v1, v2;
944     v1 = glue(ldu, SUFFIX)((void *)ESI);
945     v2 = glue(ldu, SUFFIX)((void *)EDI);
946     ESI += (DF << SHIFT);
947     EDI += (DF << SHIFT);
948     CC_SRC = v1;
949     CC_DST = v1 - v2;
950 }
951
952 void OPPROTO glue(op_repz_cmps, SUFFIX)(void)
953 {
954     int v1, v2, inc;
955     if (ECX != 0) {
956         inc = (DF << SHIFT);
957         do {
958             v1 = glue(ldu, SUFFIX)((void *)ESI);
959             v2 = glue(ldu, SUFFIX)((void *)EDI);
960             ESI += inc;
961             EDI += inc;
962             ECX--;
963             if (v1 != v2)
964                 break;
965         } while (ECX != 0);
966         CC_SRC = v1;
967         CC_DST = v1 - v2;
968         CC_OP = CC_OP_SUBB + SHIFT;
969     }
970     FORCE_RET();
971 }
972
973 void OPPROTO glue(op_repnz_cmps, SUFFIX)(void)
974 {
975     int v1, v2, inc;
976     if (ECX != 0) {
977         inc = (DF << SHIFT);
978         do {
979             v1 = glue(ldu, SUFFIX)((void *)ESI);
980             v2 = glue(ldu, SUFFIX)((void *)EDI);
981             ESI += inc;
982             EDI += inc;
983             ECX--;
984             if (v1 == v2)
985                 break;
986         } while (ECX != 0);
987         CC_SRC = v1;
988         CC_DST = v1 - v2;
989         CC_OP = CC_OP_SUBB + SHIFT;
990     }
991     FORCE_RET();
992 }
993
994 /* port I/O */
995
996 void OPPROTO glue(op_outs, SUFFIX)(void)
997 {
998     int v, dx;
999     dx = EDX & 0xffff;
1000     v = glue(ldu, SUFFIX)((void *)ESI);
1001     glue(cpu_x86_out, SUFFIX)(dx, v);
1002     ESI += (DF << SHIFT);
1003 }
1004
1005 void OPPROTO glue(op_rep_outs, SUFFIX)(void)
1006 {
1007     int v, dx, inc;
1008     inc = (DF << SHIFT);
1009     dx = EDX & 0xffff;
1010     while (ECX != 0) {
1011         v = glue(ldu, SUFFIX)((void *)ESI);
1012         glue(cpu_x86_out, SUFFIX)(dx, v);
1013         ESI += inc;
1014         ECX--;
1015     }
1016     FORCE_RET();
1017 }
1018
1019 void OPPROTO glue(op_ins, SUFFIX)(void)
1020 {
1021     int v, dx;
1022     dx = EDX & 0xffff;
1023     v = glue(cpu_x86_in, SUFFIX)(dx);
1024     glue(st, SUFFIX)((void *)EDI, v);
1025     EDI += (DF << SHIFT);
1026 }
1027
1028 void OPPROTO glue(op_rep_ins, SUFFIX)(void)
1029 {
1030     int v, dx, inc;
1031     inc = (DF << SHIFT);
1032     dx = EDX & 0xffff;
1033     while (ECX != 0) {
1034         v = glue(cpu_x86_in, SUFFIX)(dx);
1035         glue(st, SUFFIX)((void *)EDI, v);
1036         EDI += (DF << SHIFT);
1037         ECX--;
1038     }
1039     FORCE_RET();
1040 }
1041
1042 void OPPROTO glue(glue(op_out, SUFFIX), _T0_T1)(void)
1043 {
1044     glue(cpu_x86_out, SUFFIX)(T0 & 0xffff, T1 & DATA_MASK);
1045 }
1046
1047 void OPPROTO glue(glue(op_in, SUFFIX), _T0_T1)(void)
1048 {
1049     T1 = glue(cpu_x86_in, SUFFIX)(T0 & 0xffff);
1050 }
1051
1052 #undef DATA_BITS
1053 #undef SHIFT_MASK
1054 #undef SIGN_MASK
1055 #undef DATA_TYPE
1056 #undef DATA_STYPE
1057 #undef DATA_MASK
1058 #undef SUFFIX
This page took 0.079971 seconds and 4 git commands to generate.