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);