| 2658 | } |
| 2659 | |
| 2660 | void GdEd(int instruction, struct Data* data, bool includeLock = false) { |
| 2661 | while (data->valid) { |
| 2662 | int ed; |
| 2663 | int gd; |
| 2664 | int rm; |
| 2665 | |
| 2666 | for (ed = 0; ed < 8; ed++) { |
| 2667 | for (gd = 0; gd < 8; gd++) { |
| 2668 | Reg* e; |
| 2669 | Reg* g; |
| 2670 | |
| 2671 | if (ed == gd) |
| 2672 | continue; |
| 2673 | rm = ed | (gd << 3) | 0xC0; |
| 2674 | newInstructionWithRM(instruction, rm, data->flags); |
| 2675 | pushConstant(data); |
| 2676 | e = &cpu->reg[ed]; |
| 2677 | g = &cpu->reg[gd]; |
| 2678 | e->u32 = data->var2; |
| 2679 | g->u32 = data->var1; |
| 2680 | runTestCPU(); |
| 2681 | assertResult(data, cpu, instruction, g->u32, e->u32, -1, -1, 0, 0); |
| 2682 | |
| 2683 | if (gd == 4 || ed == 4) { |
| 2684 | continue; |
| 2685 | } |
| 2686 | newInstructionWithRM(instruction, rm, data->flags); |
| 2687 | pushConstant(data); |
| 2688 | e = &cpu->reg[ed]; |
| 2689 | g = &cpu->reg[gd]; |
| 2690 | e->u32 = data->var2; |
| 2691 | g->u32 = data->var1; |
| 2692 | pushCode8(0x39); |
| 2693 | pushCode8(0xc0); // cmp eax, eax: this will overwrite flags so the above code might take a different path in the dynamic cores that optimize away flag calculation |
| 2694 | runTestCPU(); |
| 2695 | assertResult(data, cpu, instruction, g->u32, e->u32, -1, -1, 0, 0, true); |
| 2696 | } |
| 2697 | } |
| 2698 | |
| 2699 | for (int lock = 0; lock < 2; lock++) { |
| 2700 | for (gd = 0; gd < 8; gd++) { |
| 2701 | Reg* g; |
| 2702 | U32 result; |
| 2703 | |
| 2704 | rm = (gd << 3); |
| 2705 | if (cpu->big) |
| 2706 | rm += 5; |
| 2707 | else |
| 2708 | rm += 6; |
| 2709 | newInstructionWithRM(instruction, rm, data->flags, lock ? LOCK_PREFIX : 0); |
| 2710 | U16 addressOffset = lock == 2 ? 202 : 200; |
| 2711 | |
| 2712 | if (cpu->big) |
| 2713 | pushCode32(addressOffset); |
| 2714 | else |
| 2715 | pushCode16(addressOffset); |
| 2716 | pushConstant(data); |
| 2717 | memory->writed(cpu->seg[DS].address + addressOffset, data->var2); |
no test coverage detected