| 571 | } |
| 572 | |
| 573 | std::optional<CondClassType> OpDispatchBuilder::DecodeNZCVCondition(uint8_t OP) { |
| 574 | switch (OP) { |
| 575 | case 0x0: { // JO - Jump if OF == 1 |
| 576 | return CondClassType {COND_FU}; |
| 577 | } |
| 578 | case 0x1: { // JNO - Jump if OF == 0 |
| 579 | return CondClassType {COND_FNU}; |
| 580 | } |
| 581 | case 0x2: { // JC - Jump if CF == 1 |
| 582 | return CondClassType {CFInverted ? COND_ULT : COND_UGE}; |
| 583 | } |
| 584 | case 0x3: { // JNC - Jump if CF == 0 |
| 585 | return CondClassType {CFInverted ? COND_UGE : COND_ULT}; |
| 586 | } |
| 587 | case 0x4: { // JE - Jump if ZF == 1 |
| 588 | return CondClassType {COND_EQ}; |
| 589 | } |
| 590 | case 0x5: { // JNE - Jump if ZF == 0 |
| 591 | return CondClassType {COND_NEQ}; |
| 592 | } |
| 593 | case 0x6: { // JNA - Jump if CF == 1 || ZF == 1 |
| 594 | // With CF, we want (C == 0 || Z == 1). By De Morgan's, that's |
| 595 | // equivalent to !(C == 1 && Z == 0). That's .ls |
| 596 | RectifyCarryInvert(true); |
| 597 | return CondClassType {COND_ULE}; |
| 598 | } |
| 599 | case 0x7: { // JA - Jump if CF == 0 && ZF == 0 |
| 600 | // With CF inverted, we want (C == 1 && Z == 0). That's .hi |
| 601 | RectifyCarryInvert(true); |
| 602 | return CondClassType {COND_UGT}; |
| 603 | } |
| 604 | case 0x8: { // JS - Jump if SF == 1 |
| 605 | return CondClassType {COND_MI}; |
| 606 | } |
| 607 | case 0x9: { // JNS - Jump if SF == 0 |
| 608 | return CondClassType {COND_PL}; |
| 609 | } |
| 610 | case 0xC: { // SF <> OF |
| 611 | return CondClassType {COND_SLT}; |
| 612 | } |
| 613 | case 0xD: { // SF = OF |
| 614 | return CondClassType {COND_SGE}; |
| 615 | } |
| 616 | case 0xE: { // ZF = 1 || SF <> OF |
| 617 | return CondClassType {COND_SLE}; |
| 618 | } |
| 619 | case 0xF: { // ZF = 0 && SF = OF |
| 620 | return CondClassType {COND_SGT}; |
| 621 | } |
| 622 | default: |
| 623 | // Other conditions do not map directly, caller gets to deal with it. |
| 624 | return std::nullopt; |
| 625 | } |
| 626 | } |
| 627 | |
| 628 | static bool ParityJumpIsJP(uint8_t OP) { |
| 629 | LOGMAN_THROW_A_FMT(OP == 0xA || OP == 0xB, "JP or JNP"); |
nothing calls this directly
no outgoing calls
no test coverage detected