| 617 | U32 getTestLeftRight(struct Op* op, char* left, char* right); |
| 618 | |
| 619 | U32 inlineTestJump(struct GenData* data, struct Op* op, U32 lazyFlag, const char* cycles) { |
| 620 | struct Op* nextOpToUseFlags = op->next; |
| 621 | |
| 622 | if (!needsToSetFlag(data->cpu, data->block, data->eip, op, CF|ZF|SF|OF|AF|PF, NULL)) { |
| 623 | out(data, "// removed unecessary TEST\n"); |
| 624 | out(data, "CYCLES("); |
| 625 | out(data, cycles); |
| 626 | out(data, ");"); |
| 627 | return 1; |
| 628 | } |
| 629 | while(nextOpToUseFlags) { |
| 630 | U16 flags = flagsThatOpUses(nextOpToUseFlags); |
| 631 | if (flags!=0) |
| 632 | break; |
| 633 | nextOpToUseFlags = nextOpToUseFlags->next; |
| 634 | } |
| 635 | if (!nextOpToUseFlags) { |
| 636 | // ran into something else besides a jump that used this test or maybe a retn |
| 637 | return 0; |
| 638 | } |
| 639 | if (isConditionalJump(nextOpToUseFlags)) { |
| 640 | if (!needsToSetFlag(data->cpu, data->block, data->eip, nextOpToUseFlags, CF|ZF|SF|OF|AF|PF, NULL)) { |
| 641 | out(data, "// inlined TEST\n "); |
| 642 | // TODO maybe in the future, the code will know what registers are set between these two instructions and whether or not it will cause a problem |
| 643 | data->inlinedLazyFlagOpAssignedToCPU = 0; |
| 644 | if (op->next != nextOpToUseFlags) { |
| 645 | char left[256]; |
| 646 | char right[256]; |
| 647 | U32 same = getTestLeftRight(op, left, right); |
| 648 | if (lazyFlag == sFLAGS_TEST8) { |
| 649 | out(data, "cpu->dst.u8 = "); |
| 650 | out(data, left); |
| 651 | if (!same) { |
| 652 | out(data, "; cpu->src.u8 = "); |
| 653 | out(data, right); |
| 654 | } |
| 655 | } else if (lazyFlag == sFLAGS_TEST16) { |
| 656 | out(data, "cpu->dst.u16 = "); |
| 657 | out(data, left); |
| 658 | if (!same) { |
| 659 | out(data, "; cpu->src.u16 = "); |
| 660 | out(data, right); |
| 661 | } |
| 662 | } else if (lazyFlag == sFLAGS_TEST32) { |
| 663 | out(data, "cpu->dst.u32 = "); |
| 664 | out(data, left); |
| 665 | if (!same) { |
| 666 | out(data, "; cpu->src.u32 = "); |
| 667 | out(data, right); |
| 668 | } |
| 669 | } else { |
| 670 | kpanic("inlineTestJump: lazyFlag unknown %d", lazyFlag); |
| 671 | } |
| 672 | out(data, "; "); |
| 673 | data->inlinedLazyFlagOpAssignedToCPU = 1; |
| 674 | } |
| 675 | out(data, "CYCLES("); |
| 676 | out(data, cycles); |