| 397 | } |
| 398 | |
| 399 | void N64Recomp::LiveGenerator::process_binary_op(const BinaryOp& op, const InstructionContext& ctx) const { |
| 400 | // Skip instructions that output to $zero |
| 401 | if (outputs_to_zero(op.output, ctx)) { |
| 402 | return; |
| 403 | } |
| 404 | |
| 405 | // Float u32l input operands are not allowed in a binary operation. |
| 406 | if (is_fpr_u32l(op.operands.operands[0]) || is_fpr_u32l(op.operands.operands[1])) { |
| 407 | assert(false); |
| 408 | errored = true; |
| 409 | return; |
| 410 | } |
| 411 | |
| 412 | // A float u32l output operand is only allowed for lwc1, which has an op type of LW. |
| 413 | if (is_fpr_u32l(op.output) && op.type != BinaryOpType::LW) { |
| 414 | assert(false); |
| 415 | errored = true; |
| 416 | return; |
| 417 | } |
| 418 | |
| 419 | sljit_sw dst; |
| 420 | sljit_sw dstw; |
| 421 | sljit_sw src1; |
| 422 | sljit_sw src1w; |
| 423 | sljit_sw src2; |
| 424 | sljit_sw src2w; |
| 425 | bool output_good = get_operand_values(op.output, ctx, dst, dstw, compiler, Registers::arithmetic_temp2); |
| 426 | bool input0_good = get_operand_values(op.operands.operands[0], ctx, src1, src1w, nullptr, 0); |
| 427 | bool input1_good = get_operand_values(op.operands.operands[1], ctx, src2, src2w, nullptr, 0); |
| 428 | |
| 429 | if (!output_good || !input0_good || !input1_good) { |
| 430 | assert(false); |
| 431 | errored = true; |
| 432 | return; |
| 433 | } |
| 434 | |
| 435 | // If a relocation is present, perform the relocation and change src1/src1w to use the relocated value. |
| 436 | if (ctx.reloc_type != RelocType::R_MIPS_NONE) { |
| 437 | // Only allow LO16 relocations. |
| 438 | if (ctx.reloc_type != RelocType::R_MIPS_LO16) { |
| 439 | assert(false); |
| 440 | errored = true; |
| 441 | return; |
| 442 | } |
| 443 | // Only allow relocations on immediates. |
| 444 | if (src2 != SLJIT_IMM) { |
| 445 | assert(false); |
| 446 | errored = true; |
| 447 | return; |
| 448 | } |
| 449 | // Only allow relocations on loads and adds. |
| 450 | switch (op.type) { |
| 451 | case BinaryOpType::LD: |
| 452 | case BinaryOpType::LW: |
| 453 | case BinaryOpType::LWU: |
| 454 | case BinaryOpType::LH: |
| 455 | case BinaryOpType::LHU: |
| 456 | case BinaryOpType::LB: |
nothing calls this directly
no test coverage detected