| 1479 | } |
| 1480 | |
| 1481 | void N64Recomp::LiveGenerator::emit_branch_condition(const ConditionalBranchOp& op, const InstructionContext& ctx) const { |
| 1482 | // Make sure there's no pending jump. |
| 1483 | if(context->cur_branch_jump != nullptr) { |
| 1484 | assert(false); |
| 1485 | errored = true; |
| 1486 | return; |
| 1487 | } |
| 1488 | |
| 1489 | // Branch conditions do not allow unary ops, except for ToS64 on the first operand to indicate the branch comparison is signed. |
| 1490 | if(op.operands.operand_operations[0] != UnaryOpType::None && op.operands.operand_operations[0] != UnaryOpType::ToS64) { |
| 1491 | assert(false); |
| 1492 | errored = true; |
| 1493 | return; |
| 1494 | } |
| 1495 | |
| 1496 | if (op.operands.operand_operations[1] != UnaryOpType::None) { |
| 1497 | assert(false); |
| 1498 | errored = true; |
| 1499 | return; |
| 1500 | } |
| 1501 | |
| 1502 | // Branch conditions do not allow float u32l operands. |
| 1503 | if (is_fpr_u32l(op.operands.operands[0]) || is_fpr_u32l(op.operands.operands[1])) { |
| 1504 | assert(false); |
| 1505 | errored = true; |
| 1506 | return; |
| 1507 | } |
| 1508 | |
| 1509 | sljit_s32 condition_type; |
| 1510 | bool cmp_signed = op.operands.operand_operations[0] == UnaryOpType::ToS64; |
| 1511 | // Comparisons need to be inverted to account for the fact that the generator is expected to generate a code block that only runs if |
| 1512 | // the condition is met, meaning the branch should be taken if the condition isn't met. |
| 1513 | switch (op.comparison) { |
| 1514 | case BinaryOpType::Equal: |
| 1515 | condition_type = SLJIT_NOT_EQUAL; |
| 1516 | break; |
| 1517 | case BinaryOpType::NotEqual: |
| 1518 | condition_type = SLJIT_EQUAL; |
| 1519 | break; |
| 1520 | case BinaryOpType::GreaterEq: |
| 1521 | if (cmp_signed) { |
| 1522 | condition_type = SLJIT_SIG_LESS; |
| 1523 | } |
| 1524 | else { |
| 1525 | condition_type = SLJIT_LESS; |
| 1526 | } |
| 1527 | break; |
| 1528 | case BinaryOpType::Greater: |
| 1529 | if (cmp_signed) { |
| 1530 | condition_type = SLJIT_SIG_LESS_EQUAL; |
| 1531 | } |
| 1532 | else { |
| 1533 | condition_type = SLJIT_LESS_EQUAL; |
| 1534 | } |
| 1535 | break; |
| 1536 | case BinaryOpType::LessEq: |
| 1537 | if (cmp_signed) { |
| 1538 | condition_type = SLJIT_SIG_GREATER; |
nothing calls this directly
no test coverage detected