Revision 4b74fe1f ops_template.h
b/ops_template.h | ||
---|---|---|
33 | 33 |
cf = (DATA_TYPE)CC_DST < (DATA_TYPE)src1; |
34 | 34 |
pf = parity_table[(uint8_t)CC_DST]; |
35 | 35 |
af = (CC_DST ^ src1 ^ src2) & 0x10; |
36 |
zf = ((DATA_TYPE)CC_DST != 0) << 6;
|
|
36 |
zf = ((DATA_TYPE)CC_DST == 0) << 6;
|
|
37 | 37 |
sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80; |
38 | 38 |
of = lshift((src1 ^ src2 ^ -1) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O; |
39 | 39 |
return cf | pf | af | zf | sf | of; |
... | ... | |
47 | 47 |
return cf; |
48 | 48 |
} |
49 | 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 |
|
|
50 | 73 |
static int glue(compute_all_sub, SUFFIX)(void) |
51 | 74 |
{ |
52 | 75 |
int cf, pf, af, zf, sf, of; |
... | ... | |
56 | 79 |
cf = (DATA_TYPE)src1 < (DATA_TYPE)src2; |
57 | 80 |
pf = parity_table[(uint8_t)CC_DST]; |
58 | 81 |
af = (CC_DST ^ src1 ^ src2) & 0x10; |
59 |
zf = ((DATA_TYPE)CC_DST != 0) << 6;
|
|
82 |
zf = ((DATA_TYPE)CC_DST == 0) << 6;
|
|
60 | 83 |
sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80; |
61 |
of = lshift((src1 ^ src2 ^ -1) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
|
|
84 |
of = lshift((src1 ^ src2) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O; |
|
62 | 85 |
return cf | pf | af | zf | sf | of; |
63 | 86 |
} |
64 | 87 |
|
... | ... | |
67 | 90 |
int src1, src2, cf; |
68 | 91 |
src1 = CC_SRC; |
69 | 92 |
src2 = CC_SRC - CC_DST; |
70 |
cf = (DATA_TYPE)src1 < (DATA_TYPE)src1; |
|
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; |
|
71 | 118 |
return cf; |
72 | 119 |
} |
73 | 120 |
|
... | ... | |
77 | 124 |
cf = 0; |
78 | 125 |
pf = parity_table[(uint8_t)CC_DST]; |
79 | 126 |
af = 0; |
80 |
zf = ((DATA_TYPE)CC_DST != 0) << 6;
|
|
127 |
zf = ((DATA_TYPE)CC_DST == 0) << 6;
|
|
81 | 128 |
sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80; |
82 | 129 |
of = 0; |
83 | 130 |
return cf | pf | af | zf | sf | of; |
... | ... | |
97 | 144 |
cf = CC_SRC; |
98 | 145 |
pf = parity_table[(uint8_t)CC_DST]; |
99 | 146 |
af = (CC_DST ^ src1 ^ src2) & 0x10; |
100 |
zf = ((DATA_TYPE)CC_DST != 0) << 6;
|
|
147 |
zf = ((DATA_TYPE)CC_DST == 0) << 6;
|
|
101 | 148 |
sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80; |
102 |
of = lshift((src1 ^ src2 ^ -1) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
|
|
149 |
of = ((CC_DST & DATA_MASK) == SIGN_MASK) << 11;
|
|
103 | 150 |
return cf | pf | af | zf | sf | of; |
104 | 151 |
} |
105 | 152 |
|
153 |
#if DATA_BITS == 32 |
|
106 | 154 |
static int glue(compute_c_inc, SUFFIX)(void) |
107 | 155 |
{ |
108 | 156 |
return CC_SRC; |
109 | 157 |
} |
158 |
#endif |
|
110 | 159 |
|
111 | 160 |
static int glue(compute_all_dec, SUFFIX)(void) |
112 | 161 |
{ |
... | ... | |
117 | 166 |
cf = CC_SRC; |
118 | 167 |
pf = parity_table[(uint8_t)CC_DST]; |
119 | 168 |
af = (CC_DST ^ src1 ^ src2) & 0x10; |
120 |
zf = ((DATA_TYPE)CC_DST != 0) << 6;
|
|
169 |
zf = ((DATA_TYPE)CC_DST == 0) << 6;
|
|
121 | 170 |
sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80; |
122 |
of = lshift((src1 ^ src2 ^ -1) & (src1 ^ CC_DST), 12 - DATA_BITS) & CC_O;
|
|
171 |
of = ((CC_DST & DATA_MASK) == ((uint32_t)SIGN_MASK - 1)) << 11;
|
|
123 | 172 |
return cf | pf | af | zf | sf | of; |
124 | 173 |
} |
125 | 174 |
|
... | ... | |
129 | 178 |
cf = CC_SRC & 1; |
130 | 179 |
pf = parity_table[(uint8_t)CC_DST]; |
131 | 180 |
af = 0; /* undefined */ |
132 |
zf = ((DATA_TYPE)CC_DST != 0) << 6;
|
|
181 |
zf = ((DATA_TYPE)CC_DST == 0) << 6;
|
|
133 | 182 |
sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80; |
134 |
of = sf << 4; /* only meaniful for shr with count == 1 */
|
|
183 |
of = lshift(CC_SRC, 12 - DATA_BITS) & CC_O; /* only meaniful for shr with count == 1 */
|
|
135 | 184 |
return cf | pf | af | zf | sf | of; |
136 | 185 |
} |
137 | 186 |
|
187 |
#if DATA_BITS == 32 |
|
138 | 188 |
static int glue(compute_c_shl, SUFFIX)(void) |
139 | 189 |
{ |
140 | 190 |
return CC_SRC & 1; |
141 | 191 |
} |
192 |
#endif |
|
193 |
|
|
194 |
static int glue(compute_all_sar, SUFFIX)(void) |
|
195 |
{ |
|
196 |
int cf, pf, af, zf, sf, of; |
|
197 |
cf = CC_SRC & 1; |
|
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; |
|
204 |
} |
|
142 | 205 |
|
143 | 206 |
/* various optimized jumps cases */ |
144 | 207 |
|
... | ... | |
157 | 220 |
|
158 | 221 |
void OPPROTO glue(op_jz_sub, SUFFIX)(void) |
159 | 222 |
{ |
160 |
if ((DATA_TYPE)CC_DST != 0)
|
|
223 |
if ((DATA_TYPE)CC_DST == 0)
|
|
161 | 224 |
PC = PARAM1; |
162 | 225 |
else |
163 | 226 |
PC = PARAM2; |
... | ... | |
225 | 288 |
|
226 | 289 |
void OPPROTO glue(op_setz_T0_sub, SUFFIX)(void) |
227 | 290 |
{ |
228 |
T0 = ((DATA_TYPE)CC_DST != 0);
|
|
291 |
T0 = ((DATA_TYPE)CC_DST == 0);
|
|
229 | 292 |
} |
230 | 293 |
|
231 | 294 |
void OPPROTO glue(op_setbe_T0_sub, SUFFIX)(void) |
... | ... | |
275 | 338 |
(T0 & CC_C); |
276 | 339 |
CC_OP = CC_OP_EFLAGS; |
277 | 340 |
} |
341 |
FORCE_RET(); |
|
278 | 342 |
} |
279 | 343 |
|
280 | 344 |
void OPPROTO glue(glue(op_ror, SUFFIX), _T0_T1_cc)(void) |
... | ... | |
290 | 354 |
((T0 >> (DATA_BITS - 1)) & CC_C); |
291 | 355 |
CC_OP = CC_OP_EFLAGS; |
292 | 356 |
} |
357 |
FORCE_RET(); |
|
293 | 358 |
} |
294 | 359 |
|
295 | 360 |
void OPPROTO glue(glue(op_rcl, SUFFIX), _T0_T1_cc)(void) |
... | ... | |
305 | 370 |
#endif |
306 | 371 |
if (count) { |
307 | 372 |
eflags = cc_table[CC_OP].compute_all(); |
373 |
T0 &= DATA_MASK; |
|
308 | 374 |
src = T0; |
309 | 375 |
res = (T0 << count) | ((eflags & CC_C) << (count - 1)); |
310 | 376 |
if (count > 1) |
... | ... | |
315 | 381 |
((src >> (DATA_BITS - count)) & CC_C); |
316 | 382 |
CC_OP = CC_OP_EFLAGS; |
317 | 383 |
} |
384 |
FORCE_RET(); |
|
318 | 385 |
} |
319 | 386 |
|
320 | 387 |
void OPPROTO glue(glue(op_rcr, SUFFIX), _T0_T1_cc)(void) |
... | ... | |
330 | 397 |
#endif |
331 | 398 |
if (count) { |
332 | 399 |
eflags = cc_table[CC_OP].compute_all(); |
400 |
T0 &= DATA_MASK; |
|
333 | 401 |
src = T0; |
334 | 402 |
res = (T0 >> count) | ((eflags & CC_C) << (DATA_BITS - count)); |
335 | 403 |
if (count > 1) |
... | ... | |
340 | 408 |
((src >> (count - 1)) & CC_C); |
341 | 409 |
CC_OP = CC_OP_EFLAGS; |
342 | 410 |
} |
411 |
FORCE_RET(); |
|
343 | 412 |
} |
344 | 413 |
|
345 | 414 |
void OPPROTO glue(glue(op_shl, SUFFIX), _T0_T1_cc)(void) |
... | ... | |
352 | 421 |
CC_DST = T0; |
353 | 422 |
CC_OP = CC_OP_ADDB + SHIFT; |
354 | 423 |
} else if (count) { |
355 |
CC_SRC = T0 >> (DATA_BITS - count); |
|
424 |
CC_SRC = (DATA_TYPE)T0 >> (DATA_BITS - count);
|
|
356 | 425 |
T0 = T0 << count; |
357 | 426 |
CC_DST = T0; |
358 | 427 |
CC_OP = CC_OP_SHLB + SHIFT; |
359 | 428 |
} |
429 |
FORCE_RET(); |
|
360 | 430 |
} |
361 | 431 |
|
362 | 432 |
void OPPROTO glue(glue(op_shr, SUFFIX), _T0_T1_cc)(void) |
... | ... | |
370 | 440 |
CC_DST = T0; |
371 | 441 |
CC_OP = CC_OP_SHLB + SHIFT; |
372 | 442 |
} |
443 |
FORCE_RET(); |
|
373 | 444 |
} |
374 | 445 |
|
375 | 446 |
void OPPROTO glue(glue(op_sar, SUFFIX), _T0_T1_cc)(void) |
... | ... | |
381 | 452 |
CC_SRC = src >> (count - 1); |
382 | 453 |
T0 = src >> count; |
383 | 454 |
CC_DST = T0; |
384 |
CC_OP = CC_OP_SHLB + SHIFT;
|
|
455 |
CC_OP = CC_OP_SARB + SHIFT;
|
|
385 | 456 |
} |
457 |
FORCE_RET(); |
|
386 | 458 |
} |
387 | 459 |
|
460 |
/* carry add/sub (we only need to set CC_OP differently) */ |
|
461 |
|
|
462 |
void OPPROTO glue(glue(op_adc, SUFFIX), _T0_T1_cc)(void) |
|
463 |
{ |
|
464 |
int cf; |
|
465 |
cf = cc_table[CC_OP].compute_c(); |
|
466 |
CC_SRC = T0; |
|
467 |
T0 = T0 + T1 + cf; |
|
468 |
CC_DST = T0; |
|
469 |
CC_OP = CC_OP_ADDB + SHIFT + cf * 3; |
|
470 |
} |
|
471 |
|
|
472 |
void OPPROTO glue(glue(op_sbb, SUFFIX), _T0_T1_cc)(void) |
|
473 |
{ |
|
474 |
int cf; |
|
475 |
cf = cc_table[CC_OP].compute_c(); |
|
476 |
CC_SRC = T0; |
|
477 |
T0 = T0 - T1 - cf; |
|
478 |
CC_DST = T0; |
|
479 |
CC_OP = CC_OP_SUBB + SHIFT + cf * 3; |
|
480 |
} |
|
481 |
|
|
482 |
/* bit operations */ |
|
483 |
#if DATA_BITS >= 16 |
|
484 |
|
|
485 |
void OPPROTO glue(glue(op_bt, SUFFIX), _T0_T1_cc)(void) |
|
486 |
{ |
|
487 |
int count; |
|
488 |
count = T1 & SHIFT_MASK; |
|
489 |
CC_SRC = T0 >> count; |
|
490 |
} |
|
491 |
|
|
492 |
void OPPROTO glue(glue(op_bts, SUFFIX), _T0_T1_cc)(void) |
|
493 |
{ |
|
494 |
int count; |
|
495 |
count = T1 & SHIFT_MASK; |
|
496 |
CC_SRC = T0 >> count; |
|
497 |
T0 |= (1 << count); |
|
498 |
} |
|
499 |
|
|
500 |
void OPPROTO glue(glue(op_btr, SUFFIX), _T0_T1_cc)(void) |
|
501 |
{ |
|
502 |
int count; |
|
503 |
count = T1 & SHIFT_MASK; |
|
504 |
CC_SRC = T0 >> count; |
|
505 |
T0 &= ~(1 << count); |
|
506 |
} |
|
507 |
|
|
508 |
void OPPROTO glue(glue(op_btc, SUFFIX), _T0_T1_cc)(void) |
|
509 |
{ |
|
510 |
int count; |
|
511 |
count = T1 & SHIFT_MASK; |
|
512 |
CC_SRC = T0 >> count; |
|
513 |
T0 ^= (1 << count); |
|
514 |
} |
|
515 |
|
|
516 |
#endif |
|
517 |
|
|
388 | 518 |
/* string operations */ |
389 | 519 |
/* XXX: maybe use lower level instructions to ease exception handling */ |
390 | 520 |
|
... | ... | |
464 | 594 |
{ |
465 | 595 |
int v; |
466 | 596 |
|
467 |
v = glue(ldu, SUFFIX)((void *)ESI);
|
|
468 |
ESI += (DF << SHIFT);
|
|
597 |
v = glue(ldu, SUFFIX)((void *)EDI);
|
|
598 |
EDI += (DF << SHIFT);
|
|
469 | 599 |
CC_SRC = EAX; |
470 | 600 |
CC_DST = EAX - v; |
471 | 601 |
} |
... | ... | |
476 | 606 |
|
477 | 607 |
if (ECX != 0) { |
478 | 608 |
/* NOTE: the flags are not modified if ECX == 0 */ |
479 |
#if SHIFT == 0 |
|
480 |
v1 = EAX & 0xff; |
|
481 |
#elif SHIFT == 1 |
|
482 |
v1 = EAX & 0xffff; |
|
483 |
#else |
|
484 |
v1 = EAX; |
|
485 |
#endif |
|
609 |
v1 = EAX & DATA_MASK; |
|
486 | 610 |
inc = (DF << SHIFT); |
487 | 611 |
do { |
488 |
v2 = glue(ldu, SUFFIX)((void *)ESI); |
|
612 |
v2 = glue(ldu, SUFFIX)((void *)EDI); |
|
613 |
EDI += inc; |
|
614 |
ECX--; |
|
489 | 615 |
if (v1 != v2) |
490 | 616 |
break; |
491 |
ESI += inc; |
|
492 |
ECX--; |
|
493 | 617 |
} while (ECX != 0); |
494 | 618 |
CC_SRC = v1; |
495 | 619 |
CC_DST = v1 - v2; |
... | ... | |
503 | 627 |
|
504 | 628 |
if (ECX != 0) { |
505 | 629 |
/* NOTE: the flags are not modified if ECX == 0 */ |
506 |
#if SHIFT == 0 |
|
507 |
v1 = EAX & 0xff; |
|
508 |
#elif SHIFT == 1 |
|
509 |
v1 = EAX & 0xffff; |
|
510 |
#else |
|
511 |
v1 = EAX; |
|
512 |
#endif |
|
630 |
v1 = EAX & DATA_MASK; |
|
513 | 631 |
inc = (DF << SHIFT); |
514 | 632 |
do { |
515 |
v2 = glue(ldu, SUFFIX)((void *)ESI); |
|
633 |
v2 = glue(ldu, SUFFIX)((void *)EDI); |
|
634 |
EDI += inc; |
|
635 |
ECX--; |
|
516 | 636 |
if (v1 == v2) |
517 | 637 |
break; |
518 |
ESI += inc; |
|
519 |
ECX--; |
|
520 | 638 |
} while (ECX != 0); |
521 | 639 |
CC_SRC = v1; |
522 | 640 |
CC_DST = v1 - v2; |
... | ... | |
543 | 661 |
do { |
544 | 662 |
v1 = glue(ldu, SUFFIX)((void *)ESI); |
545 | 663 |
v2 = glue(ldu, SUFFIX)((void *)EDI); |
546 |
if (v1 != v2) |
|
547 |
break; |
|
548 | 664 |
ESI += inc; |
549 | 665 |
EDI += inc; |
550 | 666 |
ECX--; |
667 |
if (v1 != v2) |
|
668 |
break; |
|
551 | 669 |
} while (ECX != 0); |
552 | 670 |
CC_SRC = v1; |
553 | 671 |
CC_DST = v1 - v2; |
... | ... | |
563 | 681 |
do { |
564 | 682 |
v1 = glue(ldu, SUFFIX)((void *)ESI); |
565 | 683 |
v2 = glue(ldu, SUFFIX)((void *)EDI); |
566 |
if (v1 == v2) |
|
567 |
break; |
|
568 | 684 |
ESI += inc; |
569 | 685 |
EDI += inc; |
570 | 686 |
ECX--; |
687 |
if (v1 == v2) |
|
688 |
break; |
|
571 | 689 |
} while (ECX != 0); |
572 | 690 |
CC_SRC = v1; |
573 | 691 |
CC_DST = v1 - v2; |
Also available in: Unified diff