mirror of
https://github.com/N64Recomp/N64Recomp.git
synced 2025-05-14 08:12:19 +00:00
Add operands for other uses of float registers
This commit is contained in:
parent
c3de49c944
commit
d91f1cf3a8
1 changed files with 94 additions and 45 deletions
|
@ -84,6 +84,21 @@ enum class Operand {
|
|||
Fd, // FPR
|
||||
Fs, // FPR
|
||||
Ft, // FPR
|
||||
FdDouble, // Double float in fd FPR
|
||||
FsDouble, // Double float in fs FPR
|
||||
FtDouble, // Double float in ft FPR
|
||||
// Raw low 32-bit values of FPRs with handling for mips3 float mode behavior
|
||||
FdU32L,
|
||||
FsU32L,
|
||||
FtU32L,
|
||||
// Raw high 32-bit values of FPRs with handling for mips3 float mode behavior
|
||||
FdU32H,
|
||||
FsU32H,
|
||||
FtU32H,
|
||||
// Raw 64-bit values of FPRs
|
||||
FdU64,
|
||||
FsU64,
|
||||
FtU64,
|
||||
ImmU16, // 16-bit immediate, unsigned
|
||||
ImmS16, // 16-bit immediate, signed
|
||||
Sa, // Shift amount
|
||||
|
@ -135,6 +150,8 @@ const std::unordered_map<InstrId, UnaryOp> unary_ops {
|
|||
{ InstrId::cpu_mtlo, { UnaryOpType::None, Operand::Lo, Operand::Rs } },
|
||||
{ InstrId::cpu_mfhi, { UnaryOpType::None, Operand::Rd, Operand::Hi } },
|
||||
{ InstrId::cpu_mflo, { UnaryOpType::None, Operand::Rd, Operand::Lo } },
|
||||
{ InstrId::cpu_mtc1, { UnaryOpType::None, Operand::FsU32L, Operand::Rt } },
|
||||
{ InstrId::cpu_mfc1, { UnaryOpType::ToInt32, Operand::Rt, Operand::FsU32L } },
|
||||
};
|
||||
|
||||
const std::unordered_map<InstrId, BinaryOp> binary_ops {
|
||||
|
@ -190,17 +207,19 @@ const std::unordered_map<InstrId, BinaryOp> binary_ops {
|
|||
{ InstrId::cpu_slti, { BinaryOpType::Less, Operand::Rt, {{ UnaryOpType::ToS64, UnaryOpType::None }, { Operand::Rs, Operand::ImmS16 }}} },
|
||||
{ InstrId::cpu_sltiu, { BinaryOpType::Less, Operand::Rt, {{ UnaryOpType::ToU64, UnaryOpType::None }, { Operand::Rs, Operand::ImmS16 }}} },
|
||||
// Loads
|
||||
{ InstrId::cpu_ld, { BinaryOpType::LD, Operand::Rt, {{ UnaryOpType::None, UnaryOpType::None }, { Operand::ImmS16, Operand::Base }}} },
|
||||
{ InstrId::cpu_lw, { BinaryOpType::LW, Operand::Rt, {{ UnaryOpType::None, UnaryOpType::None }, { Operand::ImmS16, Operand::Base }}} },
|
||||
{ InstrId::cpu_lwu, { BinaryOpType::LWU, Operand::Rt, {{ UnaryOpType::None, UnaryOpType::None }, { Operand::ImmS16, Operand::Base }}} },
|
||||
{ InstrId::cpu_lh, { BinaryOpType::LH, Operand::Rt, {{ UnaryOpType::None, UnaryOpType::None }, { Operand::ImmS16, Operand::Base }}} },
|
||||
{ InstrId::cpu_lhu, { BinaryOpType::LHU, Operand::Rt, {{ UnaryOpType::None, UnaryOpType::None }, { Operand::ImmS16, Operand::Base }}} },
|
||||
{ InstrId::cpu_lb, { BinaryOpType::LB, Operand::Rt, {{ UnaryOpType::None, UnaryOpType::None }, { Operand::ImmS16, Operand::Base }}} },
|
||||
{ InstrId::cpu_lbu, { BinaryOpType::LBU, Operand::Rt, {{ UnaryOpType::None, UnaryOpType::None }, { Operand::ImmS16, Operand::Base }}} },
|
||||
{ InstrId::cpu_ldl, { BinaryOpType::LDL, Operand::Rt, {{ UnaryOpType::None, UnaryOpType::None }, { Operand::ImmS16, Operand::Base }}} },
|
||||
{ InstrId::cpu_ldr, { BinaryOpType::LDR, Operand::Rt, {{ UnaryOpType::None, UnaryOpType::None }, { Operand::ImmS16, Operand::Base }}} },
|
||||
{ InstrId::cpu_lwl, { BinaryOpType::LWL, Operand::Rt, {{ UnaryOpType::None, UnaryOpType::None }, { Operand::ImmS16, Operand::Base }}} },
|
||||
{ InstrId::cpu_lwr, { BinaryOpType::LWR, Operand::Rt, {{ UnaryOpType::None, UnaryOpType::None }, { Operand::ImmS16, Operand::Base }}} },
|
||||
{ InstrId::cpu_ld, { BinaryOpType::LD, Operand::Rt, {{ UnaryOpType::None, UnaryOpType::None }, { Operand::ImmS16, Operand::Base }}} },
|
||||
{ InstrId::cpu_lw, { BinaryOpType::LW, Operand::Rt, {{ UnaryOpType::None, UnaryOpType::None }, { Operand::ImmS16, Operand::Base }}} },
|
||||
{ InstrId::cpu_lwu, { BinaryOpType::LWU, Operand::Rt, {{ UnaryOpType::None, UnaryOpType::None }, { Operand::ImmS16, Operand::Base }}} },
|
||||
{ InstrId::cpu_lh, { BinaryOpType::LH, Operand::Rt, {{ UnaryOpType::None, UnaryOpType::None }, { Operand::ImmS16, Operand::Base }}} },
|
||||
{ InstrId::cpu_lhu, { BinaryOpType::LHU, Operand::Rt, {{ UnaryOpType::None, UnaryOpType::None }, { Operand::ImmS16, Operand::Base }}} },
|
||||
{ InstrId::cpu_lb, { BinaryOpType::LB, Operand::Rt, {{ UnaryOpType::None, UnaryOpType::None }, { Operand::ImmS16, Operand::Base }}} },
|
||||
{ InstrId::cpu_lbu, { BinaryOpType::LBU, Operand::Rt, {{ UnaryOpType::None, UnaryOpType::None }, { Operand::ImmS16, Operand::Base }}} },
|
||||
{ InstrId::cpu_ldl, { BinaryOpType::LDL, Operand::Rt, {{ UnaryOpType::None, UnaryOpType::None }, { Operand::ImmS16, Operand::Base }}} },
|
||||
{ InstrId::cpu_ldr, { BinaryOpType::LDR, Operand::Rt, {{ UnaryOpType::None, UnaryOpType::None }, { Operand::ImmS16, Operand::Base }}} },
|
||||
{ InstrId::cpu_lwl, { BinaryOpType::LWL, Operand::Rt, {{ UnaryOpType::None, UnaryOpType::None }, { Operand::ImmS16, Operand::Base }}} },
|
||||
{ InstrId::cpu_lwr, { BinaryOpType::LWR, Operand::Rt, {{ UnaryOpType::None, UnaryOpType::None }, { Operand::ImmS16, Operand::Base }}} },
|
||||
{ InstrId::cpu_lwc1, { BinaryOpType::LW, Operand::FtU32L, {{ UnaryOpType::None, UnaryOpType::None }, { Operand::ImmS16, Operand::Base }}} },
|
||||
{ InstrId::cpu_ldc1, { BinaryOpType::LD, Operand::FtU64, {{ UnaryOpType::None, UnaryOpType::None }, { Operand::ImmS16, Operand::Base }}} },
|
||||
};
|
||||
|
||||
const std::unordered_map<InstrId, ConditionalBranchOp> conditional_branch_ops {
|
||||
|
@ -321,6 +340,27 @@ std::string gpr_to_string(int gpr_index) {
|
|||
return fmt::format("ctx->r{}", gpr_index);
|
||||
}
|
||||
|
||||
std::string fpr_to_string(int fpr_index) {
|
||||
return fmt::format("ctx->f{}.fl", fpr_index);
|
||||
}
|
||||
|
||||
std::string fpr_double_to_string(int fpr_index) {
|
||||
return fmt::format("ctx->f{}.d", fpr_index);
|
||||
}
|
||||
|
||||
std::string fpr_u32l_to_string(int fpr_index) {
|
||||
if (fpr_index & 1) {
|
||||
return fmt::format("ctx->f_odd[({} - 1) * 2]", fpr_index);
|
||||
}
|
||||
else {
|
||||
return fmt::format("ctx->f{}.u32l", fpr_index);
|
||||
}
|
||||
}
|
||||
|
||||
std::string fpr_u64_to_string(int fpr_index) {
|
||||
return fmt::format("ctx->f{}.u64", fpr_index);
|
||||
}
|
||||
|
||||
std::string unsigned_reloc(const InstructionContext& context) {
|
||||
switch (context.reloc_type) {
|
||||
case RecompPort::RelocType::R_MIPS_HI16:
|
||||
|
@ -348,14 +388,50 @@ void CGenerator::get_operand_string(Operand operand, UnaryOpType operation, cons
|
|||
operand_string = gpr_to_string(context.rt);
|
||||
break;
|
||||
case Operand::Fd:
|
||||
assert(false);
|
||||
operand_string = fpr_to_string(context.fd);
|
||||
break;
|
||||
case Operand::Fs:
|
||||
assert(false);
|
||||
operand_string = fpr_to_string(context.fs);
|
||||
break;
|
||||
case Operand::Ft:
|
||||
operand_string = fpr_to_string(context.ft);
|
||||
break;
|
||||
case Operand::FdDouble:
|
||||
operand_string = fpr_double_to_string(context.fd);
|
||||
break;
|
||||
case Operand::FsDouble:
|
||||
operand_string = fpr_double_to_string(context.fs);
|
||||
break;
|
||||
case Operand::FtDouble:
|
||||
operand_string = fpr_double_to_string(context.ft);
|
||||
break;
|
||||
case Operand::FdU32L:
|
||||
operand_string = fpr_u32l_to_string(context.fd);
|
||||
break;
|
||||
case Operand::FsU32L:
|
||||
operand_string = fpr_u32l_to_string(context.fs);
|
||||
break;
|
||||
case Operand::FtU32L:
|
||||
operand_string = fpr_u32l_to_string(context.ft);
|
||||
break;
|
||||
case Operand::FdU32H:
|
||||
assert(false);
|
||||
break;
|
||||
case Operand::FsU32H:
|
||||
assert(false);
|
||||
break;
|
||||
case Operand::FtU32H:
|
||||
assert(false);
|
||||
break;
|
||||
case Operand::FdU64:
|
||||
operand_string = fpr_u64_to_string(context.fd);
|
||||
break;
|
||||
case Operand::FsU64:
|
||||
operand_string = fpr_u64_to_string(context.fs);
|
||||
break;
|
||||
case Operand::FtU64:
|
||||
operand_string = fpr_u64_to_string(context.ft);
|
||||
break;
|
||||
case Operand::ImmU16:
|
||||
if (context.reloc_type != RecompPort::RelocType::R_MIPS_NONE) {
|
||||
operand_string = unsigned_reloc(context);
|
||||
|
@ -499,6 +575,11 @@ void CGenerator::process_binary_op(std::ostream& output_file, const BinaryOp& op
|
|||
get_operand_string(op.output, UnaryOpType::None, ctx, output);
|
||||
get_binary_expr_string(op.type, op.operands, ctx, output, expression);
|
||||
|
||||
// TODO remove this after the refactor is done, temporary hack to match the old recompiler output.
|
||||
if (op.type == BinaryOpType::LD && op.output == Operand::FtU64) {
|
||||
fmt::print(output_file, "CHECK_FR(ctx, {});\n ", ctx.ft);
|
||||
}
|
||||
|
||||
fmt::print(output_file, "{} = {};\n", output, expression);
|
||||
}
|
||||
|
||||
|
@ -1044,25 +1125,6 @@ bool process_instruction(const RecompPort::Context& context, const RecompPort::C
|
|||
break;
|
||||
|
||||
// Cop1 loads/stores
|
||||
case InstrId::cpu_mtc1:
|
||||
if ((fs & 1) == 0) {
|
||||
// even fpr
|
||||
print_line("ctx->f{}.u32l = {}{}", fs, ctx_gpr_prefix(rt), rt);
|
||||
}
|
||||
else {
|
||||
// odd fpr
|
||||
print_line("ctx->f_odd[({} - 1) * 2] = {}{}", fs, ctx_gpr_prefix(rt), rt);
|
||||
}
|
||||
break;
|
||||
case InstrId::cpu_mfc1:
|
||||
if ((fs & 1) == 0) {
|
||||
// even fpr
|
||||
print_line("{}{} = (int32_t)ctx->f{}.u32l", ctx_gpr_prefix(rt), rt, fs);
|
||||
} else {
|
||||
// odd fpr
|
||||
print_line("{}{} = (int32_t)ctx->f_odd[({} - 1) * 2]", ctx_gpr_prefix(rt), rt, fs);
|
||||
}
|
||||
break;
|
||||
//case InstrId::cpu_dmfc1:
|
||||
// if ((fs & 1) == 0) {
|
||||
// // even fpr
|
||||
|
@ -1072,19 +1134,6 @@ bool process_instruction(const RecompPort::Context& context, const RecompPort::C
|
|||
// return false;
|
||||
// }
|
||||
// break;
|
||||
case InstrId::cpu_lwc1:
|
||||
if ((ft & 1) == 0) {
|
||||
// even fpr
|
||||
print_line("ctx->f{}.u32l = MEM_W({}, {}{})", ft, signed_imm_string, ctx_gpr_prefix(base), base);
|
||||
} else {
|
||||
// odd fpr
|
||||
print_line("ctx->f_odd[({} - 1) * 2] = MEM_W({}, {}{})", ft, signed_imm_string, ctx_gpr_prefix(base), base);
|
||||
}
|
||||
break;
|
||||
case InstrId::cpu_ldc1:
|
||||
print_line("CHECK_FR(ctx, {})", ft);
|
||||
print_line("ctx->f{}.u64 = LD({}, {}{})", ft, signed_imm_string, ctx_gpr_prefix(base), base);
|
||||
break;
|
||||
case InstrId::cpu_swc1:
|
||||
if ((ft & 1) == 0) {
|
||||
// even fpr
|
||||
|
|
Loading…
Add table
Reference in a new issue