]>
git.proxmox.com Git - qemu.git/blob - ops_template.h
18b2ffb4920fc83370246dfa714126622738b940
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_sub
, SUFFIX
)(void)
52 int cf
, pf
, af
, zf
, sf
, of
;
55 src2
= CC_SRC
- CC_DST
;
56 cf
= (DATA_TYPE
)src1
< (DATA_TYPE
)src2
;
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_sub
, SUFFIX
)(void)
69 src2
= CC_SRC
- CC_DST
;
70 cf
= (DATA_TYPE
)src1
< (DATA_TYPE
)src1
;
74 static int glue(compute_all_logic
, SUFFIX
)(void)
76 int cf
, pf
, af
, zf
, sf
, of
;
78 pf
= parity_table
[(uint8_t)CC_DST
];
80 zf
= ((DATA_TYPE
)CC_DST
!= 0) << 6;
81 sf
= lshift(CC_DST
, 8 - DATA_BITS
) & 0x80;
83 return cf
| pf
| af
| zf
| sf
| of
;
86 static int glue(compute_c_logic
, SUFFIX
)(void)
91 static int glue(compute_all_inc
, SUFFIX
)(void)
93 int cf
, pf
, af
, zf
, sf
, of
;
98 pf
= parity_table
[(uint8_t)CC_DST
];
99 af
= (CC_DST
^ src1
^ src2
) & 0x10;
100 zf
= ((DATA_TYPE
)CC_DST
!= 0) << 6;
101 sf
= lshift(CC_DST
, 8 - DATA_BITS
) & 0x80;
102 of
= lshift((src1
^ src2
^ -1) & (src1
^ CC_DST
), 12 - DATA_BITS
) & CC_O
;
103 return cf
| pf
| af
| zf
| sf
| of
;
106 static int glue(compute_c_inc
, SUFFIX
)(void)
111 static int glue(compute_all_dec
, SUFFIX
)(void)
113 int cf
, pf
, af
, zf
, sf
, of
;
118 pf
= parity_table
[(uint8_t)CC_DST
];
119 af
= (CC_DST
^ src1
^ src2
) & 0x10;
120 zf
= ((DATA_TYPE
)CC_DST
!= 0) << 6;
121 sf
= lshift(CC_DST
, 8 - DATA_BITS
) & 0x80;
122 of
= lshift((src1
^ src2
^ -1) & (src1
^ CC_DST
), 12 - DATA_BITS
) & CC_O
;
123 return cf
| pf
| af
| zf
| sf
| of
;
126 static int glue(compute_all_shl
, SUFFIX
)(void)
128 int cf
, pf
, af
, zf
, sf
, of
;
130 pf
= parity_table
[(uint8_t)CC_DST
];
131 af
= 0; /* undefined */
132 zf
= ((DATA_TYPE
)CC_DST
!= 0) << 6;
133 sf
= lshift(CC_DST
, 8 - DATA_BITS
) & 0x80;
134 of
= sf
<< 4; /* only meaniful for shr with count == 1 */
135 return cf
| pf
| af
| zf
| sf
| of
;
138 static int glue(compute_c_shl
, SUFFIX
)(void)
143 /* various optimized jumps cases */
145 void OPPROTO
glue(op_jb_sub
, SUFFIX
)(void)
149 src2
= CC_SRC
- CC_DST
;
151 if ((DATA_TYPE
)src1
< (DATA_TYPE
)src2
)
158 void OPPROTO
glue(op_jz_sub
, SUFFIX
)(void)
160 if ((DATA_TYPE
)CC_DST
!= 0)
167 void OPPROTO
glue(op_jbe_sub
, SUFFIX
)(void)
171 src2
= CC_SRC
- CC_DST
;
173 if ((DATA_TYPE
)src1
<= (DATA_TYPE
)src2
)
180 void OPPROTO
glue(op_js_sub
, SUFFIX
)(void)
182 if (CC_DST
& SIGN_MASK
)
189 void OPPROTO
glue(op_jl_sub
, SUFFIX
)(void)
193 src2
= CC_SRC
- CC_DST
;
195 if ((DATA_STYPE
)src1
< (DATA_STYPE
)src2
)
202 void OPPROTO
glue(op_jle_sub
, SUFFIX
)(void)
206 src2
= CC_SRC
- CC_DST
;
208 if ((DATA_STYPE
)src1
<= (DATA_STYPE
)src2
)
215 /* various optimized set cases */
217 void OPPROTO
glue(op_setb_T0_sub
, SUFFIX
)(void)
221 src2
= CC_SRC
- CC_DST
;
223 T0
= ((DATA_TYPE
)src1
< (DATA_TYPE
)src2
);
226 void OPPROTO
glue(op_setz_T0_sub
, SUFFIX
)(void)
228 T0
= ((DATA_TYPE
)CC_DST
!= 0);
231 void OPPROTO
glue(op_setbe_T0_sub
, SUFFIX
)(void)
235 src2
= CC_SRC
- CC_DST
;
237 T0
= ((DATA_TYPE
)src1
<= (DATA_TYPE
)src2
);
240 void OPPROTO
glue(op_sets_T0_sub
, SUFFIX
)(void)
242 T0
= lshift(CC_DST
, -(DATA_BITS
- 1)) & 1;
245 void OPPROTO
glue(op_setl_T0_sub
, SUFFIX
)(void)
249 src2
= CC_SRC
- CC_DST
;
251 T0
= ((DATA_STYPE
)src1
< (DATA_STYPE
)src2
);
254 void OPPROTO
glue(op_setle_T0_sub
, SUFFIX
)(void)
258 src2
= CC_SRC
- CC_DST
;
260 T0
= ((DATA_STYPE
)src1
<= (DATA_STYPE
)src2
);
265 void OPPROTO
glue(glue(op_rol
, SUFFIX
), _T0_T1_cc
)(void)
268 count
= T1
& SHIFT_MASK
;
270 CC_SRC
= cc_table
[CC_OP
].compute_all() & ~(CC_O
| CC_C
);
273 T0
= (T0
<< count
) | (T0
>> (DATA_BITS
- count
));
274 CC_SRC
|= (lshift(src
^ T0
, 11 - (DATA_BITS
- 1)) & CC_O
) |
276 CC_OP
= CC_OP_EFLAGS
;
280 void OPPROTO
glue(glue(op_ror
, SUFFIX
), _T0_T1_cc
)(void)
283 count
= T1
& SHIFT_MASK
;
285 CC_SRC
= cc_table
[CC_OP
].compute_all() & ~(CC_O
| CC_C
);
288 T0
= (T0
>> count
) | (T0
<< (DATA_BITS
- count
));
289 CC_SRC
|= (lshift(src
^ T0
, 11 - (DATA_BITS
- 1)) & CC_O
) |
290 ((T0
>> (DATA_BITS
- 1)) & CC_C
);
291 CC_OP
= CC_OP_EFLAGS
;
295 void OPPROTO
glue(glue(op_rcl
, SUFFIX
), _T0_T1_cc
)(void)
297 int count
, res
, eflags
;
302 count
= rclw_table
[count
];
304 count
= rclb_table
[count
];
307 eflags
= cc_table
[CC_OP
].compute_all();
309 res
= (T0
<< count
) | ((eflags
& CC_C
) << (count
- 1));
311 res
|= T0
>> (DATA_BITS
+ 1 - count
);
313 CC_SRC
= (eflags
& ~(CC_C
| CC_O
)) |
314 (lshift(src
^ T0
, 11 - (DATA_BITS
- 1)) & CC_O
) |
315 ((src
>> (DATA_BITS
- count
)) & CC_C
);
316 CC_OP
= CC_OP_EFLAGS
;
320 void OPPROTO
glue(glue(op_rcr
, SUFFIX
), _T0_T1_cc
)(void)
322 int count
, res
, eflags
;
327 count
= rclw_table
[count
];
329 count
= rclb_table
[count
];
332 eflags
= cc_table
[CC_OP
].compute_all();
334 res
= (T0
>> count
) | ((eflags
& CC_C
) << (DATA_BITS
- count
));
336 res
|= T0
<< (DATA_BITS
+ 1 - count
);
338 CC_SRC
= (eflags
& ~(CC_C
| CC_O
)) |
339 (lshift(src
^ T0
, 11 - (DATA_BITS
- 1)) & CC_O
) |
340 ((src
>> (count
- 1)) & CC_C
);
341 CC_OP
= CC_OP_EFLAGS
;
345 void OPPROTO
glue(glue(op_shl
, SUFFIX
), _T0_T1_cc
)(void)
353 CC_OP
= CC_OP_ADDB
+ SHIFT
;
355 CC_SRC
= T0
>> (DATA_BITS
- count
);
358 CC_OP
= CC_OP_SHLB
+ SHIFT
;
362 void OPPROTO
glue(glue(op_shr
, SUFFIX
), _T0_T1_cc
)(void)
368 CC_SRC
= T0
>> (count
- 1);
371 CC_OP
= CC_OP_SHLB
+ SHIFT
;
375 void OPPROTO
glue(glue(op_sar
, SUFFIX
), _T0_T1_cc
)(void)
380 src
= (DATA_STYPE
)T0
;
381 CC_SRC
= src
>> (count
- 1);
384 CC_OP
= CC_OP_SHLB
+ SHIFT
;
388 /* string operations */
389 /* XXX: maybe use lower level instructions to ease exception handling */
391 void OPPROTO
glue(op_movs
, SUFFIX
)(void)
394 v
= glue(ldu
, SUFFIX
)((void *)ESI
);
395 glue(st
, SUFFIX
)((void *)EDI
, v
);
396 ESI
+= (DF
<< SHIFT
);
397 EDI
+= (DF
<< SHIFT
);
400 void OPPROTO
glue(op_rep_movs
, SUFFIX
)(void)
405 v
= glue(ldu
, SUFFIX
)((void *)ESI
);
406 glue(st
, SUFFIX
)((void *)EDI
, v
);
413 void OPPROTO
glue(op_stos
, SUFFIX
)(void)
415 glue(st
, SUFFIX
)((void *)EDI
, EAX
);
416 EDI
+= (DF
<< SHIFT
);
419 void OPPROTO
glue(op_rep_stos
, SUFFIX
)(void)
424 glue(st
, SUFFIX
)((void *)EDI
, EAX
);
430 void OPPROTO
glue(op_lods
, SUFFIX
)(void)
433 v
= glue(ldu
, SUFFIX
)((void *)ESI
);
435 EAX
= (EAX
& ~0xff) | v
;
437 EAX
= (EAX
& ~0xffff) | v
;
441 ESI
+= (DF
<< SHIFT
);
444 /* don't know if it is used */
445 void OPPROTO
glue(op_rep_lods
, SUFFIX
)(void)
450 v
= glue(ldu
, SUFFIX
)((void *)ESI
);
452 EAX
= (EAX
& ~0xff) | v
;
454 EAX
= (EAX
& ~0xffff) | v
;
463 void OPPROTO
glue(op_scas
, SUFFIX
)(void)
467 v
= glue(ldu
, SUFFIX
)((void *)ESI
);
468 ESI
+= (DF
<< SHIFT
);
473 void OPPROTO
glue(op_repz_scas
, SUFFIX
)(void)
478 /* NOTE: the flags are not modified if ECX == 0 */
488 v2
= glue(ldu
, SUFFIX
)((void *)ESI
);
496 CC_OP
= CC_OP_SUBB
+ SHIFT
;
500 void OPPROTO
glue(op_repnz_scas
, SUFFIX
)(void)
505 /* NOTE: the flags are not modified if ECX == 0 */
515 v2
= glue(ldu
, SUFFIX
)((void *)ESI
);
523 CC_OP
= CC_OP_SUBB
+ SHIFT
;
527 void OPPROTO
glue(op_cmps
, SUFFIX
)(void)
530 v1
= glue(ldu
, SUFFIX
)((void *)ESI
);
531 v2
= glue(ldu
, SUFFIX
)((void *)EDI
);
532 ESI
+= (DF
<< SHIFT
);
533 EDI
+= (DF
<< SHIFT
);
538 void OPPROTO
glue(op_repz_cmps
, SUFFIX
)(void)
544 v1
= glue(ldu
, SUFFIX
)((void *)ESI
);
545 v2
= glue(ldu
, SUFFIX
)((void *)EDI
);
554 CC_OP
= CC_OP_SUBB
+ SHIFT
;
558 void OPPROTO
glue(op_repnz_cmps
, SUFFIX
)(void)
564 v1
= glue(ldu
, SUFFIX
)((void *)ESI
);
565 v2
= glue(ldu
, SUFFIX
)((void *)EDI
);
574 CC_OP
= CC_OP_SUBB
+ SHIFT
;
580 void OPPROTO
glue(op_outs
, SUFFIX
)(void)
584 v
= glue(ldu
, SUFFIX
)((void *)ESI
);
585 glue(cpu_x86_out
, SUFFIX
)(dx
, v
);
586 ESI
+= (DF
<< SHIFT
);
589 void OPPROTO
glue(op_rep_outs
, SUFFIX
)(void)
595 v
= glue(ldu
, SUFFIX
)((void *)ESI
);
596 glue(cpu_x86_out
, SUFFIX
)(dx
, v
);
602 void OPPROTO
glue(op_ins
, SUFFIX
)(void)
606 v
= glue(cpu_x86_in
, SUFFIX
)(dx
);
607 glue(st
, SUFFIX
)((void *)EDI
, v
);
608 EDI
+= (DF
<< SHIFT
);
611 void OPPROTO
glue(op_rep_ins
, SUFFIX
)(void)
617 v
= glue(cpu_x86_in
, SUFFIX
)(dx
);
618 glue(st
, SUFFIX
)((void *)EDI
, v
);
619 EDI
+= (DF
<< SHIFT
);
624 void OPPROTO
glue(glue(op_out
, SUFFIX
), _T0_T1
)(void)
626 glue(cpu_x86_out
, SUFFIX
)(T0
& 0xffff, T1
& DATA_MASK
);
629 void OPPROTO
glue(glue(op_in
, SUFFIX
), _T0_T1
)(void)
631 T1
= glue(cpu_x86_in
, SUFFIX
)(T0
& 0xffff);