]>
git.proxmox.com Git - qemu.git/blob - ops_template.h
2 #define DATA_BITS (1 << (3 + SHIFT))
3 #define SHIFT_MASK (DATA_BITS - 1)
4 #define SIGN_MASK (1 << (DATA_BITS - 1))
8 #define DATA_TYPE uint8_t
9 #define DATA_STYPE int8_t
10 #define DATA_MASK 0xff
13 #define DATA_TYPE uint16_t
14 #define DATA_STYPE int16_t
15 #define DATA_MASK 0xffff
18 #define DATA_TYPE uint32_t
19 #define DATA_STYPE int32_t
20 #define DATA_MASK 0xffffffff
22 #error unhandled operand size
25 /* dynamic flags computation */
27 static int glue(compute_all_add
, SUFFIX
)(void)
29 int cf
, pf
, af
, zf
, sf
, of
;
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
;
42 static int glue(compute_c_add
, SUFFIX
)(void)
46 cf
= (DATA_TYPE
)CC_DST
< (DATA_TYPE
)src1
;
50 static int glue(compute_all_adc
, SUFFIX
)(void)
52 int cf
, pf
, af
, zf
, sf
, of
;
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
;
65 static int glue(compute_c_adc
, SUFFIX
)(void)
69 cf
= (DATA_TYPE
)CC_DST
<= (DATA_TYPE
)src1
;
73 static int glue(compute_all_sub
, SUFFIX
)(void)
75 int cf
, pf
, af
, zf
, sf
, of
;
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
;
88 static int glue(compute_c_sub
, SUFFIX
)(void)
92 src2
= CC_SRC
- CC_DST
;
93 cf
= (DATA_TYPE
)src1
< (DATA_TYPE
)src2
;
97 static int glue(compute_all_sbb
, SUFFIX
)(void)
99 int cf
, pf
, af
, zf
, sf
, of
;
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
;
112 static int glue(compute_c_sbb
, SUFFIX
)(void)
116 src2
= CC_SRC
- CC_DST
- 1;
117 cf
= (DATA_TYPE
)src1
<= (DATA_TYPE
)src2
;
121 static int glue(compute_all_logic
, SUFFIX
)(void)
123 int cf
, pf
, af
, zf
, sf
, of
;
125 pf
= parity_table
[(uint8_t)CC_DST
];
127 zf
= ((DATA_TYPE
)CC_DST
== 0) << 6;
128 sf
= lshift(CC_DST
, 8 - DATA_BITS
) & 0x80;
130 return cf
| pf
| af
| zf
| sf
| of
;
133 static int glue(compute_c_logic
, SUFFIX
)(void)
138 static int glue(compute_all_inc
, SUFFIX
)(void)
140 int cf
, pf
, af
, zf
, sf
, of
;
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
;
154 static int glue(compute_c_inc
, SUFFIX
)(void)
160 static int glue(compute_all_dec
, SUFFIX
)(void)
162 int cf
, pf
, af
, zf
, sf
, of
;
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
;
175 static int glue(compute_all_shl
, SUFFIX
)(void)
177 int cf
, pf
, af
, zf
, sf
, of
;
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
;
188 static int glue(compute_c_shl
, SUFFIX
)(void)
194 static int glue(compute_all_sar
, SUFFIX
)(void)
196 int cf
, pf
, af
, zf
, sf
, of
;
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
;
206 /* various optimized jumps cases */
208 void OPPROTO
glue(op_jb_sub
, SUFFIX
)(void)
212 src2
= CC_SRC
- CC_DST
;
214 if ((DATA_TYPE
)src1
< (DATA_TYPE
)src2
)
221 void OPPROTO
glue(op_jz_sub
, SUFFIX
)(void)
223 if ((DATA_TYPE
)CC_DST
== 0)
230 void OPPROTO
glue(op_jbe_sub
, SUFFIX
)(void)
234 src2
= CC_SRC
- CC_DST
;
236 if ((DATA_TYPE
)src1
<= (DATA_TYPE
)src2
)
243 void OPPROTO
glue(op_js_sub
, SUFFIX
)(void)
245 if (CC_DST
& SIGN_MASK
)
252 void OPPROTO
glue(op_jl_sub
, SUFFIX
)(void)
256 src2
= CC_SRC
- CC_DST
;
258 if ((DATA_STYPE
)src1
< (DATA_STYPE
)src2
)
265 void OPPROTO
glue(op_jle_sub
, SUFFIX
)(void)
269 src2
= CC_SRC
- CC_DST
;
271 if ((DATA_STYPE
)src1
<= (DATA_STYPE
)src2
)
278 /* various optimized set cases */
280 void OPPROTO
glue(op_setb_T0_sub
, SUFFIX
)(void)
284 src2
= CC_SRC
- CC_DST
;
286 T0
= ((DATA_TYPE
)src1
< (DATA_TYPE
)src2
);
289 void OPPROTO
glue(op_setz_T0_sub
, SUFFIX
)(void)
291 T0
= ((DATA_TYPE
)CC_DST
== 0);
294 void OPPROTO
glue(op_setbe_T0_sub
, SUFFIX
)(void)
298 src2
= CC_SRC
- CC_DST
;
300 T0
= ((DATA_TYPE
)src1
<= (DATA_TYPE
)src2
);
303 void OPPROTO
glue(op_sets_T0_sub
, SUFFIX
)(void)
305 T0
= lshift(CC_DST
, -(DATA_BITS
- 1)) & 1;
308 void OPPROTO
glue(op_setl_T0_sub
, SUFFIX
)(void)
312 src2
= CC_SRC
- CC_DST
;
314 T0
= ((DATA_STYPE
)src1
< (DATA_STYPE
)src2
);
317 void OPPROTO
glue(op_setle_T0_sub
, SUFFIX
)(void)
321 src2
= CC_SRC
- CC_DST
;
323 T0
= ((DATA_STYPE
)src1
<= (DATA_STYPE
)src2
);
328 void OPPROTO
glue(glue(op_rol
, SUFFIX
), _T0_T1_cc
)(void)
331 count
= T1
& SHIFT_MASK
;
333 CC_SRC
= cc_table
[CC_OP
].compute_all() & ~(CC_O
| CC_C
);
336 T0
= (T0
<< count
) | (T0
>> (DATA_BITS
- count
));
337 CC_SRC
|= (lshift(src
^ T0
, 11 - (DATA_BITS
- 1)) & CC_O
) |
339 CC_OP
= CC_OP_EFLAGS
;
344 void OPPROTO
glue(glue(op_ror
, SUFFIX
), _T0_T1_cc
)(void)
347 count
= T1
& SHIFT_MASK
;
349 CC_SRC
= cc_table
[CC_OP
].compute_all() & ~(CC_O
| CC_C
);
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
;
360 void OPPROTO
glue(glue(op_rcl
, SUFFIX
), _T0_T1_cc
)(void)
362 int count
, res
, eflags
;
367 count
= rclw_table
[count
];
369 count
= rclb_table
[count
];
372 eflags
= cc_table
[CC_OP
].compute_all();
375 res
= (T0
<< count
) | ((eflags
& CC_C
) << (count
- 1));
377 res
|= T0
>> (DATA_BITS
+ 1 - count
);
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
;
387 void OPPROTO
glue(glue(op_rcr
, SUFFIX
), _T0_T1_cc
)(void)
389 int count
, res
, eflags
;
394 count
= rclw_table
[count
];
396 count
= rclb_table
[count
];
399 eflags
= cc_table
[CC_OP
].compute_all();
402 res
= (T0
>> count
) | ((eflags
& CC_C
) << (DATA_BITS
- count
));
404 res
|= T0
<< (DATA_BITS
+ 1 - count
);
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
;
414 void OPPROTO
glue(glue(op_shl
, SUFFIX
), _T0_T1_cc
)(void)
422 CC_OP
= CC_OP_ADDB
+ SHIFT
;
424 CC_SRC
= (DATA_TYPE
)T0
>> (DATA_BITS
- count
);
427 CC_OP
= CC_OP_SHLB
+ SHIFT
;
432 void OPPROTO
glue(glue(op_shr
, SUFFIX
), _T0_T1_cc
)(void)
438 CC_SRC
= T0
>> (count
- 1);
441 CC_OP
= CC_OP_SHLB
+ SHIFT
;
446 void OPPROTO
glue(glue(op_sar
, SUFFIX
), _T0_T1_cc
)(void)
451 src
= (DATA_STYPE
)T0
;
452 CC_SRC
= src
>> (count
- 1);
455 CC_OP
= CC_OP_SARB
+ SHIFT
;
460 /* carry add/sub (we only need to set CC_OP differently) */
462 void OPPROTO
glue(glue(op_adc
, SUFFIX
), _T0_T1_cc
)(void)
465 cf
= cc_table
[CC_OP
].compute_c();
469 CC_OP
= CC_OP_ADDB
+ SHIFT
+ cf
* 3;
472 void OPPROTO
glue(glue(op_sbb
, SUFFIX
), _T0_T1_cc
)(void)
475 cf
= cc_table
[CC_OP
].compute_c();
479 CC_OP
= CC_OP_SUBB
+ SHIFT
+ cf
* 3;
485 void OPPROTO
glue(glue(op_bt
, SUFFIX
), _T0_T1_cc
)(void)
488 count
= T1
& SHIFT_MASK
;
489 CC_SRC
= T0
>> count
;
492 void OPPROTO
glue(glue(op_bts
, SUFFIX
), _T0_T1_cc
)(void)
495 count
= T1
& SHIFT_MASK
;
496 CC_SRC
= T0
>> count
;
500 void OPPROTO
glue(glue(op_btr
, SUFFIX
), _T0_T1_cc
)(void)
503 count
= T1
& SHIFT_MASK
;
504 CC_SRC
= T0
>> count
;
508 void OPPROTO
glue(glue(op_btc
, SUFFIX
), _T0_T1_cc
)(void)
511 count
= T1
& SHIFT_MASK
;
512 CC_SRC
= T0
>> count
;
518 /* string operations */
519 /* XXX: maybe use lower level instructions to ease exception handling */
521 void OPPROTO
glue(op_movs
, SUFFIX
)(void)
524 v
= glue(ldu
, SUFFIX
)((void *)ESI
);
525 glue(st
, SUFFIX
)((void *)EDI
, v
);
526 ESI
+= (DF
<< SHIFT
);
527 EDI
+= (DF
<< SHIFT
);
530 void OPPROTO
glue(op_rep_movs
, SUFFIX
)(void)
535 v
= glue(ldu
, SUFFIX
)((void *)ESI
);
536 glue(st
, SUFFIX
)((void *)EDI
, v
);
543 void OPPROTO
glue(op_stos
, SUFFIX
)(void)
545 glue(st
, SUFFIX
)((void *)EDI
, EAX
);
546 EDI
+= (DF
<< SHIFT
);
549 void OPPROTO
glue(op_rep_stos
, SUFFIX
)(void)
554 glue(st
, SUFFIX
)((void *)EDI
, EAX
);
560 void OPPROTO
glue(op_lods
, SUFFIX
)(void)
563 v
= glue(ldu
, SUFFIX
)((void *)ESI
);
565 EAX
= (EAX
& ~0xff) | v
;
567 EAX
= (EAX
& ~0xffff) | v
;
571 ESI
+= (DF
<< SHIFT
);
574 /* don't know if it is used */
575 void OPPROTO
glue(op_rep_lods
, SUFFIX
)(void)
580 v
= glue(ldu
, SUFFIX
)((void *)ESI
);
582 EAX
= (EAX
& ~0xff) | v
;
584 EAX
= (EAX
& ~0xffff) | v
;
593 void OPPROTO
glue(op_scas
, SUFFIX
)(void)
597 v
= glue(ldu
, SUFFIX
)((void *)EDI
);
598 EDI
+= (DF
<< SHIFT
);
603 void OPPROTO
glue(op_repz_scas
, SUFFIX
)(void)
608 /* NOTE: the flags are not modified if ECX == 0 */
609 v1
= EAX
& DATA_MASK
;
612 v2
= glue(ldu
, SUFFIX
)((void *)EDI
);
620 CC_OP
= CC_OP_SUBB
+ SHIFT
;
624 void OPPROTO
glue(op_repnz_scas
, SUFFIX
)(void)
629 /* NOTE: the flags are not modified if ECX == 0 */
630 v1
= EAX
& DATA_MASK
;
633 v2
= glue(ldu
, SUFFIX
)((void *)EDI
);
641 CC_OP
= CC_OP_SUBB
+ SHIFT
;
645 void OPPROTO
glue(op_cmps
, SUFFIX
)(void)
648 v1
= glue(ldu
, SUFFIX
)((void *)ESI
);
649 v2
= glue(ldu
, SUFFIX
)((void *)EDI
);
650 ESI
+= (DF
<< SHIFT
);
651 EDI
+= (DF
<< SHIFT
);
656 void OPPROTO
glue(op_repz_cmps
, SUFFIX
)(void)
662 v1
= glue(ldu
, SUFFIX
)((void *)ESI
);
663 v2
= glue(ldu
, SUFFIX
)((void *)EDI
);
672 CC_OP
= CC_OP_SUBB
+ SHIFT
;
676 void OPPROTO
glue(op_repnz_cmps
, SUFFIX
)(void)
682 v1
= glue(ldu
, SUFFIX
)((void *)ESI
);
683 v2
= glue(ldu
, SUFFIX
)((void *)EDI
);
692 CC_OP
= CC_OP_SUBB
+ SHIFT
;
698 void OPPROTO
glue(op_outs
, SUFFIX
)(void)
702 v
= glue(ldu
, SUFFIX
)((void *)ESI
);
703 glue(cpu_x86_out
, SUFFIX
)(dx
, v
);
704 ESI
+= (DF
<< SHIFT
);
707 void OPPROTO
glue(op_rep_outs
, SUFFIX
)(void)
713 v
= glue(ldu
, SUFFIX
)((void *)ESI
);
714 glue(cpu_x86_out
, SUFFIX
)(dx
, v
);
720 void OPPROTO
glue(op_ins
, SUFFIX
)(void)
724 v
= glue(cpu_x86_in
, SUFFIX
)(dx
);
725 glue(st
, SUFFIX
)((void *)EDI
, v
);
726 EDI
+= (DF
<< SHIFT
);
729 void OPPROTO
glue(op_rep_ins
, SUFFIX
)(void)
735 v
= glue(cpu_x86_in
, SUFFIX
)(dx
);
736 glue(st
, SUFFIX
)((void *)EDI
, v
);
737 EDI
+= (DF
<< SHIFT
);
742 void OPPROTO
glue(glue(op_out
, SUFFIX
), _T0_T1
)(void)
744 glue(cpu_x86_out
, SUFFIX
)(T0
& 0xffff, T1
& DATA_MASK
);
747 void OPPROTO
glue(glue(op_in
, SUFFIX
), _T0_T1
)(void)
749 T1
= glue(cpu_x86_in
, SUFFIX
)(T0
& 0xffff);