| 576 | } |
| 577 | |
| 578 | void GcnCompiler::emitVectorCmp(const GcnShaderInstruction& ins) |
| 579 | { |
| 580 | const std::array<GcnRegisterValuePair, 2> src = { |
| 581 | emitRegisterLoad(ins.src[0]), |
| 582 | emitRegisterLoad(ins.src[1]), |
| 583 | }; |
| 584 | |
| 585 | // Condition, which is a boolean vector used |
| 586 | // to select between the ~0u and 0u vectors. |
| 587 | uint32_t condition = 0; |
| 588 | uint32_t conditionType = m_module.defBoolType(); |
| 589 | |
| 590 | // TODO: |
| 591 | // unordered float support. |
| 592 | |
| 593 | bool updateExec = false; |
| 594 | |
| 595 | auto op = ins.opcode; |
| 596 | switch (op) |
| 597 | { |
| 598 | case GcnOpcode::V_CMPX_EQ_U32: |
| 599 | updateExec = true; |
| 600 | [[fallthrough]]; |
| 601 | case GcnOpcode::V_CMP_EQ_U32: |
| 602 | case GcnOpcode::V_CMP_EQ_I32: |
| 603 | condition = m_module.opIEqual(conditionType, |
| 604 | src[0].low.id, |
| 605 | src[1].low.id); |
| 606 | break; |
| 607 | case GcnOpcode::V_CMP_GT_I32: |
| 608 | condition = m_module.opSGreaterThan(conditionType, |
| 609 | src[0].low.id, |
| 610 | src[1].low.id); |
| 611 | break; |
| 612 | case GcnOpcode::V_CMPX_GT_U32: |
| 613 | updateExec = true; |
| 614 | [[fallthrough]]; |
| 615 | case GcnOpcode::V_CMP_GT_U32: |
| 616 | condition = m_module.opUGreaterThan(conditionType, |
| 617 | src[0].low.id, |
| 618 | src[1].low.id); |
| 619 | break; |
| 620 | case GcnOpcode::V_CMPX_GE_U32: |
| 621 | updateExec = true; |
| 622 | [[fallthrough]]; |
| 623 | case GcnOpcode::V_CMP_GE_U32: |
| 624 | condition = m_module.opUGreaterThanEqual(conditionType, |
| 625 | src[0].low.id, |
| 626 | src[1].low.id); |
| 627 | break; |
| 628 | case GcnOpcode::V_CMPX_NLE_F32: |
| 629 | updateExec = true; |
| 630 | [[fallthrough]]; |
| 631 | case GcnOpcode::V_CMP_GT_F32: |
| 632 | case GcnOpcode::V_CMP_NLE_F32: |
| 633 | condition = m_module.opFOrdGreaterThan(conditionType, |
| 634 | src[0].low.id, |
| 635 | src[1].low.id); |
no test coverage detected