mirror of
https://github.com/cemu-project/Cemu.git
synced 2025-02-19 19:42:48 +01:00
PPCRec: Further unify CR code
This commit is contained in:
parent
2535cf43d8
commit
8df0281baa
@ -582,7 +582,6 @@ bool PPCRecompilerX64Gen_imlInstruction_store(PPCRecFunction_t* PPCRecFunction,
|
||||
// bswap EAX
|
||||
x64Gen_bswap_reg64Lower32bit(x64GenContext, X86_REG_EAX);
|
||||
|
||||
//x64Gen_lock_cmpxchg_mem32Reg64PlusReg64_reg64(x64GenContext, REG_RESV_MEMBASE, realRegisterMem, 0, REG_RESV_TEMP);
|
||||
x64Gen_lock_cmpxchg_mem32Reg64_reg64(x64GenContext, REG_RESV_MEMBASE, 0, REG_RESV_TEMP);
|
||||
|
||||
x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_EQUAL, X86_REG_RSP, offsetof(PPCInterpreter_t, cr) + sizeof(uint8)*(crRegister * 4 + PPCREC_CR_BIT_EQ));
|
||||
@ -761,6 +760,7 @@ bool PPCRecompilerX64Gen_imlInstruction_r_r(PPCRecFunction_t* PPCRecFunction, pp
|
||||
}
|
||||
else if( imlInstruction->operation == PPCREC_IML_OP_ADD_CARRY )
|
||||
{
|
||||
cemu_assert_debug(imlInstruction->crRegister == PPC_REC_INVALID_REGISTER);
|
||||
PPCRecompilerX64Gen_crConditionFlags_forget(PPCRecFunction, ppcImlGenContext, x64GenContext);
|
||||
// copy operand to result if different registers
|
||||
if( imlInstruction->op_r_r.registerResult != imlInstruction->op_r_r.registerA )
|
||||
@ -773,19 +773,10 @@ bool PPCRecompilerX64Gen_imlInstruction_r_r(PPCRecFunction_t* PPCRecFunction, pp
|
||||
x64Gen_adc_reg64Low32_imm32(x64GenContext, imlInstruction->op_r_r.registerResult, 0);
|
||||
// update xer carry
|
||||
x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_CARRY, X86_REG_RSP, offsetof(PPCInterpreter_t, xer_ca));
|
||||
if( imlInstruction->crRegister != PPC_REC_INVALID_REGISTER )
|
||||
{
|
||||
// set cr bits
|
||||
sint32 crRegister = imlInstruction->crRegister;
|
||||
x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_SIGN, X86_REG_RSP, offsetof(PPCInterpreter_t, cr)+sizeof(uint8)*(crRegister*4+PPCREC_CR_BIT_LT)); // check for sign instead of _BELOW (CF) which is not set by AND/OR
|
||||
x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_UNSIGNED_ABOVE, X86_REG_RSP, offsetof(PPCInterpreter_t, cr)+sizeof(uint8)*(crRegister*4+PPCREC_CR_BIT_GT));
|
||||
x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_EQUAL, X86_REG_RSP, offsetof(PPCInterpreter_t, cr)+sizeof(uint8)*(crRegister*4+PPCREC_CR_BIT_EQ));
|
||||
// todo: Use different version of PPCRecompilerX64Gen_updateCRLogical(PPCRecFunction, ppcImlGenContext, x64GenContext, imlInstruction)
|
||||
// todo: Also set summary overflow if xer bit is set
|
||||
}
|
||||
}
|
||||
else if( imlInstruction->operation == PPCREC_IML_OP_ADD_CARRY_ME )
|
||||
{
|
||||
cemu_assert_debug(imlInstruction->crRegister == PPC_REC_INVALID_REGISTER);
|
||||
PPCRecompilerX64Gen_crConditionFlags_forget(PPCRecFunction, ppcImlGenContext, x64GenContext);
|
||||
// copy operand to result if different registers
|
||||
if( imlInstruction->op_r_r.registerResult != imlInstruction->op_r_r.registerA )
|
||||
@ -798,16 +789,10 @@ bool PPCRecompilerX64Gen_imlInstruction_r_r(PPCRecFunction_t* PPCRecFunction, pp
|
||||
x64Gen_adc_reg64Low32_imm32(x64GenContext, imlInstruction->op_r_r.registerResult, (uint32)-1);
|
||||
// update xer carry
|
||||
x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_CARRY, X86_REG_RSP, offsetof(PPCInterpreter_t, xer_ca));
|
||||
if( imlInstruction->crRegister != PPC_REC_INVALID_REGISTER )
|
||||
{
|
||||
// set cr bits
|
||||
sint32 crRegister = imlInstruction->crRegister;
|
||||
x64Gen_test_reg64Low32_reg64Low32(x64GenContext, imlInstruction->op_r_r.registerResult, imlInstruction->op_r_r.registerResult);
|
||||
PPCRecompilerX64Gen_updateCRLogical(PPCRecFunction, ppcImlGenContext, x64GenContext, imlInstruction);
|
||||
}
|
||||
}
|
||||
else if( imlInstruction->operation == PPCREC_IML_OP_SUB_CARRY_UPDATE_CARRY )
|
||||
{
|
||||
cemu_assert_debug(imlInstruction->crRegister == PPC_REC_INVALID_REGISTER);
|
||||
// registerResult = ~registerOperand1 + carry
|
||||
PPCRecompilerX64Gen_crConditionFlags_forget(PPCRecFunction, ppcImlGenContext, x64GenContext);
|
||||
sint32 rRegResult = imlInstruction->op_r_r.registerResult;
|
||||
@ -822,23 +807,10 @@ bool PPCRecompilerX64Gen_imlInstruction_r_r(PPCRecFunction_t* PPCRecFunction, pp
|
||||
x64Gen_adc_reg64Low32_imm32(x64GenContext, rRegResult, 0);
|
||||
// update carry
|
||||
x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_CARRY, X86_REG_RSP, offsetof(PPCInterpreter_t, xer_ca));
|
||||
// update cr if requested
|
||||
if( imlInstruction->crRegister != PPC_REC_INVALID_REGISTER )
|
||||
{
|
||||
if( imlInstruction->crMode == PPCREC_CR_MODE_LOGICAL )
|
||||
{
|
||||
x64Gen_test_reg64Low32_reg64Low32(x64GenContext, rRegResult, rRegResult);
|
||||
// set cr bits
|
||||
PPCRecompilerX64Gen_updateCRLogical(PPCRecFunction, ppcImlGenContext, x64GenContext, imlInstruction);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert_dbg();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( imlInstruction->operation == PPCREC_IML_OP_DCBZ )
|
||||
{
|
||||
cemu_assert_debug(imlInstruction->crRegister == PPC_REC_INVALID_REGISTER);
|
||||
PPCRecompilerX64Gen_crConditionFlags_forget(PPCRecFunction, ppcImlGenContext, x64GenContext);
|
||||
if( imlInstruction->op_r_r.registerResult != imlInstruction->op_r_r.registerA )
|
||||
{
|
||||
@ -878,23 +850,14 @@ bool PPCRecompilerX64Gen_imlInstruction_r_s32(PPCRecFunction_t* PPCRecFunction,
|
||||
else if( imlInstruction->operation == PPCREC_IML_OP_AND )
|
||||
{
|
||||
// registerResult &= immS32
|
||||
cemu_assert_debug(imlInstruction->crRegister == PPC_REC_INVALID_REGISTER);
|
||||
PPCRecompilerX64Gen_crConditionFlags_forget(PPCRecFunction, ppcImlGenContext, x64GenContext);
|
||||
x64Gen_and_reg64Low32_imm32(x64GenContext, imlInstruction->op_r_immS32.registerIndex, (uint32)imlInstruction->op_r_immS32.immS32);
|
||||
if( imlInstruction->crRegister != PPC_REC_INVALID_REGISTER )
|
||||
{
|
||||
if( imlInstruction->crMode != PPCREC_CR_MODE_LOGICAL )
|
||||
{
|
||||
assert_dbg();
|
||||
}
|
||||
// set cr bits
|
||||
sint32 crRegister = imlInstruction->crRegister;
|
||||
PPCRecompilerX64Gen_updateCRLogical(PPCRecFunction, ppcImlGenContext, x64GenContext, imlInstruction);
|
||||
// todo: Set CR SO if XER SO bit is set
|
||||
}
|
||||
}
|
||||
else if( imlInstruction->operation == PPCREC_IML_OP_OR )
|
||||
{
|
||||
// registerResult |= immS32
|
||||
cemu_assert_debug(imlInstruction->crRegister == PPC_REC_INVALID_REGISTER);
|
||||
PPCRecompilerX64Gen_crConditionFlags_forget(PPCRecFunction, ppcImlGenContext, x64GenContext);
|
||||
cemu_assert_debug(imlInstruction->crRegister == PPC_REC_INVALID_REGISTER);
|
||||
x64Gen_or_reg64Low32_imm32(x64GenContext, imlInstruction->op_r_immS32.registerIndex, (uint32)imlInstruction->op_r_immS32.immS32);
|
||||
@ -902,12 +865,14 @@ bool PPCRecompilerX64Gen_imlInstruction_r_s32(PPCRecFunction_t* PPCRecFunction,
|
||||
else if( imlInstruction->operation == PPCREC_IML_OP_XOR )
|
||||
{
|
||||
// registerResult ^= immS32
|
||||
cemu_assert_debug(imlInstruction->crRegister == PPC_REC_INVALID_REGISTER);
|
||||
PPCRecompilerX64Gen_crConditionFlags_forget(PPCRecFunction, ppcImlGenContext, x64GenContext);
|
||||
cemu_assert_debug(imlInstruction->crRegister == PPC_REC_INVALID_REGISTER);
|
||||
x64Gen_xor_reg64Low32_imm32(x64GenContext, imlInstruction->op_r_immS32.registerIndex, (uint32)imlInstruction->op_r_immS32.immS32);
|
||||
}
|
||||
else if( imlInstruction->operation == PPCREC_IML_OP_LEFT_ROTATE )
|
||||
{
|
||||
cemu_assert_debug(imlInstruction->crRegister == PPC_REC_INVALID_REGISTER);
|
||||
// registerResult <<<= immS32
|
||||
PPCRecompilerX64Gen_crConditionFlags_forget(PPCRecFunction, ppcImlGenContext, x64GenContext);
|
||||
cemu_assert_debug(imlInstruction->crRegister == PPC_REC_INVALID_REGISTER);
|
||||
@ -1076,6 +1041,8 @@ bool PPCRecompilerX64Gen_imlInstruction_conditional_r_s32(PPCRecFunction_t* PPCR
|
||||
|
||||
bool PPCRecompilerX64Gen_imlInstruction_r_r_r(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, IMLInstruction* imlInstruction)
|
||||
{
|
||||
cemu_assert_debug(imlInstruction->crRegister == PPC_REC_INVALID_REGISTER);
|
||||
|
||||
if( imlInstruction->operation == PPCREC_IML_OP_ADD || imlInstruction->operation == PPCREC_IML_OP_ADD_UPDATE_CARRY || imlInstruction->operation == PPCREC_IML_OP_ADD_CARRY_UPDATE_CARRY )
|
||||
{
|
||||
// registerResult = registerOperand1 + registerOperand2
|
||||
@ -1127,17 +1094,6 @@ bool PPCRecompilerX64Gen_imlInstruction_r_r_r(PPCRecFunction_t* PPCRecFunction,
|
||||
{
|
||||
x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_CARRY, X86_REG_RSP, offsetof(PPCInterpreter_t, xer_ca));
|
||||
}
|
||||
// set cr bits if enabled
|
||||
if( imlInstruction->crRegister != PPC_REC_INVALID_REGISTER )
|
||||
{
|
||||
if( imlInstruction->crMode != PPCREC_CR_MODE_LOGICAL )
|
||||
{
|
||||
assert_dbg();
|
||||
}
|
||||
sint32 crRegister = imlInstruction->crRegister;
|
||||
PPCRecompilerX64Gen_updateCRLogical(PPCRecFunction, ppcImlGenContext, x64GenContext, imlInstruction);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if( imlInstruction->operation == PPCREC_IML_OP_SUB )
|
||||
{
|
||||
@ -1171,20 +1127,10 @@ bool PPCRecompilerX64Gen_imlInstruction_r_r_r(PPCRecFunction_t* PPCRecFunction,
|
||||
// sub operand2
|
||||
x64Gen_sub_reg64Low32_reg64Low32(x64GenContext, rRegResult, rRegOperand2);
|
||||
}
|
||||
// set cr bits if enabled
|
||||
if( imlInstruction->crRegister != PPC_REC_INVALID_REGISTER )
|
||||
{
|
||||
if( imlInstruction->crMode != PPCREC_CR_MODE_LOGICAL )
|
||||
{
|
||||
assert_dbg();
|
||||
}
|
||||
sint32 crRegister = imlInstruction->crRegister;
|
||||
PPCRecompilerX64Gen_updateCRLogical(PPCRecFunction, ppcImlGenContext, x64GenContext, imlInstruction);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if( imlInstruction->operation == PPCREC_IML_OP_SUB_CARRY_UPDATE_CARRY )
|
||||
{
|
||||
cemu_assert_debug(imlInstruction->crRegister == PPC_REC_INVALID_REGISTER);
|
||||
// registerResult = registerOperand1 - registerOperand2 + carry
|
||||
PPCRecompilerX64Gen_crConditionFlags_forget(PPCRecFunction, ppcImlGenContext, x64GenContext);
|
||||
sint32 rRegResult = imlInstruction->op_r_r_r.registerResult;
|
||||
@ -1228,14 +1174,6 @@ bool PPCRecompilerX64Gen_imlInstruction_r_r_r(PPCRecFunction_t* PPCRecFunction,
|
||||
}
|
||||
// update carry flag (todo: is this actually correct in all cases?)
|
||||
x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_CARRY, X86_REG_RSP, offsetof(PPCInterpreter_t, xer_ca));
|
||||
// update cr0 if requested
|
||||
if( imlInstruction->crRegister != PPC_REC_INVALID_REGISTER )
|
||||
{
|
||||
if( imlInstruction->crMode != PPCREC_CR_MODE_LOGICAL )
|
||||
assert_dbg();
|
||||
x64Gen_test_reg64Low32_reg64Low32(x64GenContext, rRegResult, rRegResult);
|
||||
PPCRecompilerX64Gen_updateCRLogical(PPCRecFunction, ppcImlGenContext, x64GenContext, imlInstruction);
|
||||
}
|
||||
}
|
||||
else if( imlInstruction->operation == PPCREC_IML_OP_MULTIPLY_SIGNED )
|
||||
{
|
||||
@ -1259,17 +1197,6 @@ bool PPCRecompilerX64Gen_imlInstruction_r_r_r(PPCRecFunction_t* PPCRecFunction,
|
||||
// add operand2
|
||||
x64Gen_imul_reg64Low32_reg64Low32(x64GenContext, rRegResult, rRegOperand2);
|
||||
}
|
||||
// set cr bits if enabled
|
||||
if( imlInstruction->crRegister != PPC_REC_INVALID_REGISTER )
|
||||
{
|
||||
if( imlInstruction->crMode != PPCREC_CR_MODE_LOGICAL )
|
||||
{
|
||||
assert_dbg();
|
||||
}
|
||||
// since IMUL instruction leaves relevant flags undefined, we have to use another TEST instruction to get the correct results
|
||||
x64Gen_test_reg64Low32_reg64Low32(x64GenContext, rRegResult, rRegResult);
|
||||
PPCRecompilerX64Gen_updateCRLogical(PPCRecFunction, ppcImlGenContext, x64GenContext, imlInstruction);
|
||||
}
|
||||
}
|
||||
else if( imlInstruction->operation == PPCREC_IML_OP_SUBFC )
|
||||
{
|
||||
@ -1387,16 +1314,6 @@ bool PPCRecompilerX64Gen_imlInstruction_r_r_r(PPCRecFunction_t* PPCRecFunction,
|
||||
}
|
||||
x64Gen_mov_reg64_reg64(x64GenContext, rRegResult, REG_RESV_TEMP);
|
||||
}
|
||||
// set cr bits if enabled
|
||||
if( imlInstruction->crRegister != PPC_REC_INVALID_REGISTER )
|
||||
{
|
||||
if( imlInstruction->crMode != PPCREC_CR_MODE_LOGICAL )
|
||||
{
|
||||
assert_dbg();
|
||||
}
|
||||
x64Gen_test_reg64Low32_reg64Low32(x64GenContext, rRegResult, rRegResult);
|
||||
PPCRecompilerX64Gen_updateCRLogical(PPCRecFunction, ppcImlGenContext, x64GenContext, imlInstruction);
|
||||
}
|
||||
}
|
||||
else if( imlInstruction->operation == PPCREC_IML_OP_LEFT_ROTATE )
|
||||
{
|
||||
@ -1433,16 +1350,6 @@ bool PPCRecompilerX64Gen_imlInstruction_r_r_r(PPCRecFunction_t* PPCRecFunction,
|
||||
}
|
||||
x64Gen_mov_reg64_reg64(x64GenContext, rRegResult, REG_RESV_TEMP);
|
||||
}
|
||||
// set cr bits if enabled
|
||||
if( imlInstruction->crRegister != PPC_REC_INVALID_REGISTER )
|
||||
{
|
||||
if( imlInstruction->crMode != PPCREC_CR_MODE_LOGICAL )
|
||||
{
|
||||
assert_dbg();
|
||||
}
|
||||
x64Gen_test_reg64Low32_reg64Low32(x64GenContext, rRegResult, rRegResult);
|
||||
PPCRecompilerX64Gen_updateCRLogical(PPCRecFunction, ppcImlGenContext, x64GenContext, imlInstruction);
|
||||
}
|
||||
}
|
||||
else if( imlInstruction->operation == PPCREC_IML_OP_SRAW )
|
||||
{
|
||||
@ -1519,6 +1426,7 @@ bool PPCRecompilerX64Gen_imlInstruction_r_r_r(PPCRecFunction_t* PPCRecFunction,
|
||||
}
|
||||
else if( imlInstruction->operation == PPCREC_IML_OP_DIVIDE_SIGNED || imlInstruction->operation == PPCREC_IML_OP_DIVIDE_UNSIGNED )
|
||||
{
|
||||
cemu_assert_debug(imlInstruction->crRegister == PPC_REC_INVALID_REGISTER);
|
||||
PPCRecompilerX64Gen_crConditionFlags_forget(PPCRecFunction, ppcImlGenContext, x64GenContext);
|
||||
sint32 rRegResult = imlInstruction->op_r_r_r.registerResult;
|
||||
sint32 rRegOperand1 = imlInstruction->op_r_r_r.registerA;
|
||||
@ -1551,19 +1459,10 @@ bool PPCRecompilerX64Gen_imlInstruction_r_r_r(PPCRecFunction_t* PPCRecFunction,
|
||||
x64Emit_mov_reg64_mem32(x64GenContext, X86_REG_EAX, X86_REG_RSP, (uint32)offsetof(PPCInterpreter_t, temporaryGPR[0]));
|
||||
if( rRegResult != X86_REG_RDX )
|
||||
x64Emit_mov_reg64_mem32(x64GenContext, X86_REG_EDX, X86_REG_RSP, (uint32)offsetof(PPCInterpreter_t, temporaryGPR[1]));
|
||||
// set cr bits if requested
|
||||
if( imlInstruction->crRegister != PPC_REC_INVALID_REGISTER )
|
||||
{
|
||||
if( imlInstruction->crMode != PPCREC_CR_MODE_ARITHMETIC )
|
||||
{
|
||||
assert_dbg();
|
||||
}
|
||||
x64Gen_test_reg64Low32_reg64Low32(x64GenContext, rRegResult, rRegResult);
|
||||
PPCRecompilerX64Gen_updateCRLogical(PPCRecFunction, ppcImlGenContext, x64GenContext, imlInstruction);
|
||||
}
|
||||
}
|
||||
else if( imlInstruction->operation == PPCREC_IML_OP_MULTIPLY_HIGH_SIGNED || imlInstruction->operation == PPCREC_IML_OP_MULTIPLY_HIGH_UNSIGNED )
|
||||
{
|
||||
cemu_assert_debug(imlInstruction->crRegister == PPC_REC_INVALID_REGISTER);
|
||||
PPCRecompilerX64Gen_crConditionFlags_forget(PPCRecFunction, ppcImlGenContext, x64GenContext);
|
||||
sint32 rRegResult = imlInstruction->op_r_r_r.registerResult;
|
||||
sint32 rRegOperand1 = imlInstruction->op_r_r_r.registerA;
|
||||
@ -1598,16 +1497,6 @@ bool PPCRecompilerX64Gen_imlInstruction_r_r_r(PPCRecFunction_t* PPCRecFunction,
|
||||
x64Emit_mov_reg64_mem32(x64GenContext, X86_REG_EAX, X86_REG_RSP, (uint32)offsetof(PPCInterpreter_t, temporaryGPR[0]));
|
||||
if( rRegResult != X86_REG_RDX )
|
||||
x64Emit_mov_reg64_mem32(x64GenContext, X86_REG_EDX, X86_REG_RSP, (uint32)offsetof(PPCInterpreter_t, temporaryGPR[1]));
|
||||
// set cr bits if requested
|
||||
if( imlInstruction->crRegister != PPC_REC_INVALID_REGISTER )
|
||||
{
|
||||
if( imlInstruction->crMode != PPCREC_CR_MODE_LOGICAL )
|
||||
{
|
||||
assert_dbg();
|
||||
}
|
||||
x64Gen_test_reg64Low32_reg64Low32(x64GenContext, rRegResult, rRegResult);
|
||||
PPCRecompilerX64Gen_updateCRLogical(PPCRecFunction, ppcImlGenContext, x64GenContext, imlInstruction);
|
||||
}
|
||||
}
|
||||
else if( imlInstruction->operation == PPCREC_IML_OP_ORC )
|
||||
{
|
||||
@ -1622,17 +1511,6 @@ bool PPCRecompilerX64Gen_imlInstruction_r_r_r(PPCRecFunction_t* PPCRecFunction,
|
||||
if( rRegResult != rRegOperand1 )
|
||||
x64Gen_mov_reg64Low32_reg64Low32(x64GenContext, rRegResult, rRegOperand1);
|
||||
x64Gen_or_reg64Low32_reg64Low32(x64GenContext, rRegResult, REG_RESV_TEMP);
|
||||
|
||||
// set cr bits if enabled
|
||||
if( imlInstruction->crRegister != PPC_REC_INVALID_REGISTER )
|
||||
{
|
||||
if( imlInstruction->crMode != PPCREC_CR_MODE_LOGICAL )
|
||||
{
|
||||
assert_dbg();
|
||||
}
|
||||
PPCRecompilerX64Gen_updateCRLogical(PPCRecFunction, ppcImlGenContext, x64GenContext, imlInstruction);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1681,6 +1559,8 @@ bool PPCRecompilerX64Gen_imlInstruction_cjump2(PPCRecFunction_t* PPCRecFunction,
|
||||
|
||||
bool PPCRecompilerX64Gen_imlInstruction_r_r_s32(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, IMLInstruction* imlInstruction)
|
||||
{
|
||||
cemu_assert_debug(imlInstruction->crRegister == PPC_REC_INVALID_REGISTER);
|
||||
|
||||
sint32 regResult = imlInstruction->op_r_r_s32.registerResult;
|
||||
sint32 regOperand = imlInstruction->op_r_r_s32.registerA;
|
||||
uint32 immS32 = imlInstruction->op_r_r_s32.immS32;
|
||||
@ -1706,6 +1586,7 @@ bool PPCRecompilerX64Gen_imlInstruction_r_r_s32(PPCRecFunction_t* PPCRecFunction
|
||||
}
|
||||
else if( imlInstruction->operation == PPCREC_IML_OP_ADD_UPDATE_CARRY )
|
||||
{
|
||||
cemu_assert_debug(imlInstruction->crRegister == PPC_REC_INVALID_REGISTER);
|
||||
// registerResult = registerOperand + immS32
|
||||
PPCRecompilerX64Gen_crConditionFlags_forget(PPCRecFunction, ppcImlGenContext, x64GenContext);
|
||||
sint32 rRegResult = imlInstruction->op_r_r_s32.registerResult;
|
||||
@ -1719,16 +1600,6 @@ bool PPCRecompilerX64Gen_imlInstruction_r_r_s32(PPCRecFunction_t* PPCRecFunction
|
||||
x64Gen_add_reg64Low32_imm32(x64GenContext, rRegResult, (uint32)immU32);
|
||||
// update carry flag
|
||||
x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_CARRY, X86_REG_RSP, offsetof(PPCInterpreter_t, xer_ca));
|
||||
// set cr bits if enabled
|
||||
if( imlInstruction->crRegister != PPC_REC_INVALID_REGISTER )
|
||||
{
|
||||
if( imlInstruction->crMode != PPCREC_CR_MODE_LOGICAL )
|
||||
{
|
||||
assert_dbg();
|
||||
}
|
||||
sint32 crRegister = imlInstruction->crRegister;
|
||||
PPCRecompilerX64Gen_updateCRLogical(PPCRecFunction, ppcImlGenContext, x64GenContext, imlInstruction);
|
||||
}
|
||||
}
|
||||
else if( imlInstruction->operation == PPCREC_IML_OP_SUBFC )
|
||||
{
|
||||
@ -1836,15 +1707,6 @@ bool PPCRecompilerX64Gen_imlInstruction_r_r_s32(PPCRecFunction_t* PPCRecFunction
|
||||
x64Gen_mov_mem8Reg64_imm8(x64GenContext, X86_REG_RSP, offsetof(PPCInterpreter_t, xer_ca), 0);
|
||||
// jump destination
|
||||
PPCRecompilerX64Gen_redirectRelativeJump(x64GenContext, jumpInstructionOffset, x64GenContext->emitter->GetWriteIndex());
|
||||
// CR update
|
||||
if (imlInstruction->crRegister != PPC_REC_INVALID_REGISTER)
|
||||
{
|
||||
sint32 crRegister = imlInstruction->crRegister;
|
||||
x64Gen_test_reg64Low32_reg64Low32(x64GenContext, imlInstruction->op_r_r_s32.registerResult, imlInstruction->op_r_r_s32.registerResult);
|
||||
x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_SIGN, X86_REG_RSP, offsetof(PPCInterpreter_t, cr) + sizeof(uint8)*(crRegister * 4 + PPCREC_CR_BIT_LT));
|
||||
x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_SIGNED_GREATER, X86_REG_RSP, offsetof(PPCInterpreter_t, cr) + sizeof(uint8)*(crRegister * 4 + PPCREC_CR_BIT_GT));
|
||||
x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_EQUAL, X86_REG_RSP, offsetof(PPCInterpreter_t, cr) + sizeof(uint8)*(crRegister * 4 + PPCREC_CR_BIT_EQ));
|
||||
}
|
||||
}
|
||||
else if( imlInstruction->operation == PPCREC_IML_OP_LEFT_SHIFT ||
|
||||
imlInstruction->operation == PPCREC_IML_OP_RIGHT_SHIFT )
|
||||
@ -1858,13 +1720,6 @@ bool PPCRecompilerX64Gen_imlInstruction_r_r_s32(PPCRecFunction_t* PPCRecFunction
|
||||
x64Gen_shl_reg64Low32_imm8(x64GenContext, imlInstruction->op_r_r_s32.registerResult, imlInstruction->op_r_r_s32.immS32);
|
||||
else
|
||||
x64Gen_shr_reg64Low32_imm8(x64GenContext, imlInstruction->op_r_r_s32.registerResult, imlInstruction->op_r_r_s32.immS32);
|
||||
// CR update
|
||||
if (imlInstruction->crRegister != PPC_REC_INVALID_REGISTER)
|
||||
{
|
||||
// since SHL/SHR only modifies the OF flag we need another TEST reg,reg here
|
||||
x64Gen_test_reg64Low32_reg64Low32(x64GenContext, imlInstruction->op_r_r_s32.registerResult, imlInstruction->op_r_r_s32.registerResult);
|
||||
PPCRecompilerX64Gen_updateCRLogical(PPCRecFunction, ppcImlGenContext, x64GenContext, imlInstruction);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -4,7 +4,6 @@ enum
|
||||
{
|
||||
PPCREC_IML_OP_ASSIGN, // '=' operator
|
||||
PPCREC_IML_OP_ENDIAN_SWAP, // '=' operator with 32bit endian swap
|
||||
PPCREC_IML_OP_SUB_CARRY_UPDATE_CARRY, // complex operation, result = operand + ~operand2 + carry bit, updates carry bit
|
||||
PPCREC_IML_OP_COMPARE_SIGNED, // arithmetic/signed comparison operator (updates cr)
|
||||
PPCREC_IML_OP_COMPARE_UNSIGNED, // logical/unsigned comparison operator (updates cr)
|
||||
PPCREC_IML_OP_MULTIPLY_SIGNED, // '*' operator (signed multiply)
|
||||
@ -12,10 +11,7 @@ enum
|
||||
PPCREC_IML_OP_MULTIPLY_HIGH_SIGNED, // signed 64bit multiply, store only high 32bit-word of result
|
||||
PPCREC_IML_OP_DIVIDE_SIGNED, // '/' operator (signed divide)
|
||||
PPCREC_IML_OP_DIVIDE_UNSIGNED, // '/' operator (unsigned divide)
|
||||
PPCREC_IML_OP_ADD_CARRY, // complex operation, result = operand + carry bit, updates carry bit
|
||||
PPCREC_IML_OP_ADD_CARRY_ME, // complex operation, result = operand + carry bit + (-1), updates carry bit
|
||||
PPCREC_IML_OP_ADD_UPDATE_CARRY, // '+' operator but also updates carry flag
|
||||
PPCREC_IML_OP_ADD_CARRY_UPDATE_CARRY, // '+' operator and also adds carry, updates carry flag
|
||||
|
||||
// binary operation
|
||||
PPCREC_IML_OP_OR, // '|' operator
|
||||
PPCREC_IML_OP_ORC, // '|' operator, second operand is complemented first
|
||||
@ -96,6 +92,12 @@ enum
|
||||
PPCREC_IML_OP_ASSIGN_S16_TO_S32,
|
||||
PPCREC_IML_OP_ASSIGN_S8_TO_S32,
|
||||
|
||||
// deprecated
|
||||
PPCREC_IML_OP_SUB_CARRY_UPDATE_CARRY, // complex operation, result = operand + ~operand2 + carry bit, updates carry bit
|
||||
PPCREC_IML_OP_ADD_CARRY, // complex operation, result = operand + carry bit, updates carry bit
|
||||
PPCREC_IML_OP_ADD_CARRY_ME, // complex operation, result = operand + carry bit + (-1), updates carry bit
|
||||
PPCREC_IML_OP_ADD_UPDATE_CARRY, // '+' operator but also updates carry flag
|
||||
PPCREC_IML_OP_ADD_CARRY_UPDATE_CARRY, // '+' operator and also adds carry, updates carry flag
|
||||
|
||||
};
|
||||
#define PPCREC_IML_OP_FPR_COPY_PAIR (PPCREC_IML_OP_ASSIGN)
|
||||
@ -147,7 +149,6 @@ enum
|
||||
PPCREC_CR_MODE_COMPARE_SIGNED,
|
||||
PPCREC_CR_MODE_COMPARE_UNSIGNED, // alias logic compare
|
||||
|
||||
PPCREC_CR_MODE_ARITHMETIC, // arithmetic use (for use with add/sub instructions without generating extra code)
|
||||
PPCREC_CR_MODE_LOGICAL,
|
||||
};
|
||||
|
||||
|
@ -776,14 +776,9 @@ bool PPCRecompilerImlGen_ADD(ppcImlGenContext_t* ppcImlGenContext, uint32 opcode
|
||||
uint32 registerRA = PPCRecompilerImlGen_loadRegister(ppcImlGenContext, PPCREC_NAME_R0+rA, false);
|
||||
uint32 registerRB = PPCRecompilerImlGen_loadRegister(ppcImlGenContext, PPCREC_NAME_R0+rB, false);
|
||||
uint32 registerRD = PPCRecompilerImlGen_loadOverwriteRegister(ppcImlGenContext, PPCREC_NAME_R0+rD);
|
||||
if( opcode&PPC_OPC_RC )
|
||||
{
|
||||
ppcImlGenContext->emitInst().make_r_r_r(PPCREC_IML_OP_ADD, registerRD, registerRA, registerRB, 0, PPCREC_CR_MODE_LOGICAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
ppcImlGenContext->emitInst().make_r_r_r(PPCREC_IML_OP_ADD, registerRD, registerRA, registerRB);
|
||||
}
|
||||
ppcImlGenContext->emitInst().make_r_r_r(PPCREC_IML_OP_ADD, registerRD, registerRA, registerRB);
|
||||
if ((opcode & PPC_OPC_RC))
|
||||
PPCImlGen_UpdateCR0Logical(ppcImlGenContext, registerRD);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -795,10 +790,9 @@ bool PPCRecompilerImlGen_ADDC(ppcImlGenContext_t* ppcImlGenContext, uint32 opcod
|
||||
uint32 registerRA = PPCRecompilerImlGen_loadRegister(ppcImlGenContext, PPCREC_NAME_R0+rA, false);
|
||||
uint32 registerRB = PPCRecompilerImlGen_loadRegister(ppcImlGenContext, PPCREC_NAME_R0+rB, false);
|
||||
uint32 registerRD = PPCRecompilerImlGen_loadOverwriteRegister(ppcImlGenContext, PPCREC_NAME_R0+rD);
|
||||
if( opcode&PPC_OPC_RC )
|
||||
ppcImlGenContext->emitInst().make_r_r_r(PPCREC_IML_OP_ADD_UPDATE_CARRY, registerRD, registerRA, registerRB, 0, PPCREC_CR_MODE_LOGICAL);
|
||||
else
|
||||
ppcImlGenContext->emitInst().make_r_r_r(PPCREC_IML_OP_ADD_UPDATE_CARRY, registerRD, registerRA, registerRB);
|
||||
ppcImlGenContext->emitInst().make_r_r_r(PPCREC_IML_OP_ADD_UPDATE_CARRY, registerRD, registerRA, registerRB);
|
||||
if ((opcode & PPC_OPC_RC))
|
||||
PPCImlGen_UpdateCR0Logical(ppcImlGenContext, registerRD);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -810,10 +804,9 @@ bool PPCRecompilerImlGen_ADDE(ppcImlGenContext_t* ppcImlGenContext, uint32 opcod
|
||||
uint32 registerRA = PPCRecompilerImlGen_loadRegister(ppcImlGenContext, PPCREC_NAME_R0+rA, false);
|
||||
uint32 registerRB = PPCRecompilerImlGen_loadRegister(ppcImlGenContext, PPCREC_NAME_R0+rB, false);
|
||||
uint32 registerRD = PPCRecompilerImlGen_loadOverwriteRegister(ppcImlGenContext, PPCREC_NAME_R0+rD);
|
||||
if( opcode&PPC_OPC_RC )
|
||||
ppcImlGenContext->emitInst().make_r_r_r(PPCREC_IML_OP_ADD_CARRY_UPDATE_CARRY, registerRD, registerRB, registerRA, 0, PPCREC_CR_MODE_LOGICAL);
|
||||
else
|
||||
ppcImlGenContext->emitInst().make_r_r_r(PPCREC_IML_OP_ADD_CARRY_UPDATE_CARRY, registerRD, registerRB, registerRA);
|
||||
ppcImlGenContext->emitInst().make_r_r_r(PPCREC_IML_OP_ADD_CARRY_UPDATE_CARRY, registerRD, registerRB, registerRA);
|
||||
if ((opcode & PPC_OPC_RC))
|
||||
PPCImlGen_UpdateCR0Logical(ppcImlGenContext, registerRD);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -833,14 +826,9 @@ bool PPCRecompilerImlGen_ADDZE(ppcImlGenContext_t* ppcImlGenContext, uint32 opco
|
||||
{
|
||||
ppcImlGenContext->emitInst().make_r_r(PPCREC_IML_OP_ASSIGN, registerRD, registerRA);
|
||||
}
|
||||
if( opcode&PPC_OPC_RC )
|
||||
{
|
||||
ppcImlGenContext->emitInst().make_r_r(PPCREC_IML_OP_ADD_CARRY, registerRD, registerRD, 0, PPCREC_CR_MODE_LOGICAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
ppcImlGenContext->emitInst().make_r_r(PPCREC_IML_OP_ADD_CARRY, registerRD, registerRD);
|
||||
}
|
||||
ppcImlGenContext->emitInst().make_r_r(PPCREC_IML_OP_ADD_CARRY, registerRD, registerRD);
|
||||
if ((opcode & PPC_OPC_RC))
|
||||
PPCImlGen_UpdateCR0Logical(ppcImlGenContext, registerRD);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -860,14 +848,9 @@ bool PPCRecompilerImlGen_ADDME(ppcImlGenContext_t* ppcImlGenContext, uint32 opco
|
||||
{
|
||||
ppcImlGenContext->emitInst().make_r_r(PPCREC_IML_OP_ASSIGN, registerRD, registerRA);
|
||||
}
|
||||
if( opcode&PPC_OPC_RC )
|
||||
{
|
||||
ppcImlGenContext->emitInst().make_r_r(PPCREC_IML_OP_ADD_CARRY_ME, registerRD, registerRD, 0, PPCREC_CR_MODE_LOGICAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
ppcImlGenContext->emitInst().make_r_r(PPCREC_IML_OP_ADD_CARRY_ME, registerRD, registerRD);
|
||||
}
|
||||
ppcImlGenContext->emitInst().make_r_r(PPCREC_IML_OP_ADD_CARRY_ME, registerRD, registerRD);
|
||||
if ((opcode & PPC_OPC_RC))
|
||||
PPCImlGen_UpdateCR0Logical(ppcImlGenContext, registerRD);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -889,7 +872,7 @@ bool PPCRecompilerImlGen_ADDI(ppcImlGenContext_t* ppcImlGenContext, uint32 opcod
|
||||
// rA not used, instruction is value assignment
|
||||
// rD = imm
|
||||
uint32 registerRD = PPCRecompilerImlGen_loadOverwriteRegister(ppcImlGenContext, PPCREC_NAME_R0+rD);
|
||||
ppcImlGenContext->emitInst().make_r_s32(PPCREC_IML_OP_ASSIGN, registerRD, imm, PPC_REC_INVALID_REGISTER, 0);
|
||||
ppcImlGenContext->emitInst().make_r_s32(PPCREC_IML_OP_ASSIGN, registerRD, imm);
|
||||
}
|
||||
// never updates any cr
|
||||
return true;
|
||||
@ -925,7 +908,6 @@ bool PPCRecompilerImlGen_ADDIC(ppcImlGenContext_t* ppcImlGenContext, uint32 opco
|
||||
PPC_OPC_TEMPL_D_SImm(opcode, rD, rA, imm);
|
||||
// rD = rA + imm;
|
||||
uint32 registerRA = PPCRecompilerImlGen_loadRegister(ppcImlGenContext, PPCREC_NAME_R0+rA, false);
|
||||
// check if rD is already loaded, else use new temporary register
|
||||
uint32 registerRD = PPCRecompilerImlGen_loadOverwriteRegister(ppcImlGenContext, PPCREC_NAME_R0+rD);
|
||||
ppcImlGenContext->emitInst().make_r_r_s32(PPCREC_IML_OP_ADD_UPDATE_CARRY, registerRD, registerRA, imm);
|
||||
// never updates any cr
|
||||
@ -940,9 +922,9 @@ bool PPCRecompilerImlGen_ADDIC_(ppcImlGenContext_t* ppcImlGenContext, uint32 opc
|
||||
PPC_OPC_TEMPL_D_SImm(opcode, rD, rA, imm);
|
||||
// rD = rA + imm;
|
||||
uint32 registerRA = PPCRecompilerImlGen_loadRegister(ppcImlGenContext, PPCREC_NAME_R0+rA, false);
|
||||
// check if rD is already loaded, else use new temporary register
|
||||
uint32 registerRD = PPCRecompilerImlGen_loadOverwriteRegister(ppcImlGenContext, PPCREC_NAME_R0+rD);
|
||||
ppcImlGenContext->emitInst().make_r_r_s32(PPCREC_IML_OP_ADD_UPDATE_CARRY, registerRD, registerRA, imm, 0, PPCREC_CR_MODE_LOGICAL);
|
||||
ppcImlGenContext->emitInst().make_r_r_s32(PPCREC_IML_OP_ADD_UPDATE_CARRY, registerRD, registerRA, imm);
|
||||
PPCImlGen_UpdateCR0Logical(ppcImlGenContext, registerRD);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -955,10 +937,9 @@ bool PPCRecompilerImlGen_SUBF(ppcImlGenContext_t* ppcImlGenContext, uint32 opcod
|
||||
uint32 registerRA = PPCRecompilerImlGen_loadRegister(ppcImlGenContext, PPCREC_NAME_R0+rA, false);
|
||||
uint32 registerRB = PPCRecompilerImlGen_loadRegister(ppcImlGenContext, PPCREC_NAME_R0+rB, false);
|
||||
uint32 registerRD = PPCRecompilerImlGen_loadOverwriteRegister(ppcImlGenContext, PPCREC_NAME_R0+rD);
|
||||
if( opcode&PPC_OPC_RC )
|
||||
ppcImlGenContext->emitInst().make_r_r_r(PPCREC_IML_OP_SUB, registerRD, registerRB, registerRA, 0, PPCREC_CR_MODE_LOGICAL);
|
||||
else
|
||||
ppcImlGenContext->emitInst().make_r_r_r(PPCREC_IML_OP_SUB, registerRD, registerRB, registerRA);
|
||||
ppcImlGenContext->emitInst().make_r_r_r(PPCREC_IML_OP_SUB, registerRD, registerRB, registerRA);
|
||||
if ((opcode & PPC_OPC_RC))
|
||||
PPCImlGen_UpdateCR0Logical(ppcImlGenContext, registerRD);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -970,10 +951,9 @@ bool PPCRecompilerImlGen_SUBFE(ppcImlGenContext_t* ppcImlGenContext, uint32 opco
|
||||
uint32 registerRA = PPCRecompilerImlGen_loadRegister(ppcImlGenContext, PPCREC_NAME_R0+rA, false);
|
||||
uint32 registerRB = PPCRecompilerImlGen_loadRegister(ppcImlGenContext, PPCREC_NAME_R0+rB, false);
|
||||
uint32 registerRD = PPCRecompilerImlGen_loadOverwriteRegister(ppcImlGenContext, PPCREC_NAME_R0+rD);
|
||||
if( opcode&PPC_OPC_RC )
|
||||
ppcImlGenContext->emitInst().make_r_r_r(PPCREC_IML_OP_SUB_CARRY_UPDATE_CARRY, registerRD, registerRB, registerRA, 0, PPCREC_CR_MODE_LOGICAL);
|
||||
else
|
||||
ppcImlGenContext->emitInst().make_r_r_r(PPCREC_IML_OP_SUB_CARRY_UPDATE_CARRY, registerRD, registerRB, registerRA);
|
||||
ppcImlGenContext->emitInst().make_r_r_r(PPCREC_IML_OP_SUB_CARRY_UPDATE_CARRY, registerRD, registerRB, registerRA);
|
||||
if ((opcode & PPC_OPC_RC))
|
||||
PPCImlGen_UpdateCR0Logical(ppcImlGenContext, registerRD);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -985,10 +965,9 @@ bool PPCRecompilerImlGen_SUBFZE(ppcImlGenContext_t* ppcImlGenContext, uint32 opc
|
||||
debugBreakpoint();
|
||||
uint32 registerRA = PPCRecompilerImlGen_loadRegister(ppcImlGenContext, PPCREC_NAME_R0+rA, false);
|
||||
uint32 registerRD = PPCRecompilerImlGen_loadOverwriteRegister(ppcImlGenContext, PPCREC_NAME_R0+rD);
|
||||
if( opcode&PPC_OPC_RC )
|
||||
ppcImlGenContext->emitInst().make_r_r(PPCREC_IML_OP_SUB_CARRY_UPDATE_CARRY, registerRD, registerRA, 0, PPCREC_CR_MODE_LOGICAL);
|
||||
else
|
||||
ppcImlGenContext->emitInst().make_r_r(PPCREC_IML_OP_SUB_CARRY_UPDATE_CARRY, registerRD, registerRA);
|
||||
ppcImlGenContext->emitInst().make_r_r(PPCREC_IML_OP_SUB_CARRY_UPDATE_CARRY, registerRD, registerRA);
|
||||
if ((opcode & PPC_OPC_RC))
|
||||
PPCImlGen_UpdateCR0Logical(ppcImlGenContext, registerRD);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1045,10 +1024,9 @@ bool PPCRecompilerImlGen_MULLW(ppcImlGenContext_t* ppcImlGenContext, uint32 opco
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if( opcode&PPC_OPC_RC )
|
||||
ppcImlGenContext->emitInst().make_r_r_r(PPCREC_IML_OP_MULTIPLY_SIGNED, registerResult, registerOperand1, registerOperand2, 0, PPCREC_CR_MODE_LOGICAL);
|
||||
else
|
||||
ppcImlGenContext->emitInst().make_r_r_r(PPCREC_IML_OP_MULTIPLY_SIGNED, registerResult, registerOperand1, registerOperand2);
|
||||
ppcImlGenContext->emitInst().make_r_r_r(PPCREC_IML_OP_MULTIPLY_SIGNED, registerResult, registerOperand1, registerOperand2);
|
||||
if (opcode & PPC_OPC_RC)
|
||||
PPCImlGen_UpdateCR0Logical(ppcImlGenContext, registerResult);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1060,10 +1038,9 @@ bool PPCRecompilerImlGen_MULHW(ppcImlGenContext_t* ppcImlGenContext, uint32 opco
|
||||
uint32 registerResult = PPCRecompilerImlGen_loadRegister(ppcImlGenContext, PPCREC_NAME_R0+rD, false);
|
||||
uint32 registerOperand1 = PPCRecompilerImlGen_loadRegister(ppcImlGenContext, PPCREC_NAME_R0+rA, false);
|
||||
uint32 registerOperand2 = PPCRecompilerImlGen_loadRegister(ppcImlGenContext, PPCREC_NAME_R0+rB, false);
|
||||
if( opcode&PPC_OPC_RC )
|
||||
ppcImlGenContext->emitInst().make_r_r_r(PPCREC_IML_OP_MULTIPLY_HIGH_SIGNED, registerResult, registerOperand1, registerOperand2, 0, PPCREC_CR_MODE_LOGICAL);
|
||||
else
|
||||
ppcImlGenContext->emitInst().make_r_r_r(PPCREC_IML_OP_MULTIPLY_HIGH_SIGNED, registerResult, registerOperand1, registerOperand2);
|
||||
ppcImlGenContext->emitInst().make_r_r_r(PPCREC_IML_OP_MULTIPLY_HIGH_SIGNED, registerResult, registerOperand1, registerOperand2);
|
||||
if (opcode & PPC_OPC_RC)
|
||||
PPCImlGen_UpdateCR0Logical(ppcImlGenContext, registerResult);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1075,10 +1052,9 @@ bool PPCRecompilerImlGen_MULHWU(ppcImlGenContext_t* ppcImlGenContext, uint32 opc
|
||||
uint32 registerResult = PPCRecompilerImlGen_loadRegister(ppcImlGenContext, PPCREC_NAME_R0+rD, false);
|
||||
uint32 registerOperand1 = PPCRecompilerImlGen_loadRegister(ppcImlGenContext, PPCREC_NAME_R0+rA, false);
|
||||
uint32 registerOperand2 = PPCRecompilerImlGen_loadRegister(ppcImlGenContext, PPCREC_NAME_R0+rB, false);
|
||||
if( opcode&PPC_OPC_RC )
|
||||
ppcImlGenContext->emitInst().make_r_r_r(PPCREC_IML_OP_MULTIPLY_HIGH_UNSIGNED, registerResult, registerOperand1, registerOperand2, 0, PPCREC_CR_MODE_LOGICAL);
|
||||
else
|
||||
ppcImlGenContext->emitInst().make_r_r_r(PPCREC_IML_OP_MULTIPLY_HIGH_UNSIGNED, registerResult, registerOperand1, registerOperand2);
|
||||
ppcImlGenContext->emitInst().make_r_r_r(PPCREC_IML_OP_MULTIPLY_HIGH_UNSIGNED, registerResult, registerOperand1, registerOperand2);
|
||||
if (opcode & PPC_OPC_RC)
|
||||
PPCImlGen_UpdateCR0Logical(ppcImlGenContext, registerResult);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1090,14 +1066,9 @@ bool PPCRecompilerImlGen_DIVW(ppcImlGenContext_t* ppcImlGenContext, uint32 opcod
|
||||
uint32 registerResult = PPCRecompilerImlGen_loadRegister(ppcImlGenContext, PPCREC_NAME_R0+rD, false);
|
||||
uint32 registerOperand1 = PPCRecompilerImlGen_loadRegister(ppcImlGenContext, PPCREC_NAME_R0+rA, false);
|
||||
uint32 registerOperand2 = PPCRecompilerImlGen_loadRegister(ppcImlGenContext, PPCREC_NAME_R0+rB, false);
|
||||
ppcImlGenContext->emitInst().make_r_r_r(PPCREC_IML_OP_DIVIDE_SIGNED, registerResult, registerOperand1, registerOperand2);
|
||||
if (opcode & PPC_OPC_RC)
|
||||
{
|
||||
ppcImlGenContext->emitInst().make_r_r_r(PPCREC_IML_OP_DIVIDE_SIGNED, registerResult, registerOperand1, registerOperand2, 0, PPCREC_CR_MODE_ARITHMETIC);
|
||||
}
|
||||
else
|
||||
{
|
||||
ppcImlGenContext->emitInst().make_r_r_r(PPCREC_IML_OP_DIVIDE_SIGNED, registerResult, registerOperand1, registerOperand2);
|
||||
}
|
||||
PPCImlGen_UpdateCR0Logical(ppcImlGenContext, registerResult);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1109,14 +1080,9 @@ bool PPCRecompilerImlGen_DIVWU(ppcImlGenContext_t* ppcImlGenContext, uint32 opco
|
||||
uint32 registerResult = PPCRecompilerImlGen_loadRegister(ppcImlGenContext, PPCREC_NAME_R0+rD, false);
|
||||
uint32 registerOperand1 = PPCRecompilerImlGen_loadRegister(ppcImlGenContext, PPCREC_NAME_R0+rA, false);
|
||||
uint32 registerOperand2 = PPCRecompilerImlGen_loadRegister(ppcImlGenContext, PPCREC_NAME_R0+rB, false);
|
||||
ppcImlGenContext->emitInst().make_r_r_r(PPCREC_IML_OP_DIVIDE_UNSIGNED, registerResult, registerOperand1, registerOperand2);
|
||||
if (opcode & PPC_OPC_RC)
|
||||
{
|
||||
ppcImlGenContext->emitInst().make_r_r_r(PPCREC_IML_OP_DIVIDE_UNSIGNED, registerResult, registerOperand1, registerOperand2, 0, PPCREC_CR_MODE_ARITHMETIC);
|
||||
}
|
||||
else
|
||||
{
|
||||
ppcImlGenContext->emitInst().make_r_r_r(PPCREC_IML_OP_DIVIDE_UNSIGNED, registerResult, registerOperand1, registerOperand2);
|
||||
}
|
||||
PPCImlGen_UpdateCR0Logical(ppcImlGenContext, registerResult);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1125,42 +1091,29 @@ bool PPCRecompilerImlGen_RLWINM(ppcImlGenContext_t* ppcImlGenContext, uint32 opc
|
||||
int rS, rA, SH, MB, ME;
|
||||
PPC_OPC_TEMPL_M(opcode, rS, rA, SH, MB, ME);
|
||||
uint32 mask = ppc_mask(MB, ME);
|
||||
//uint32 v = ppc_word_rotl(hCPU->gpr[rS], SH);
|
||||
//hCPU->gpr[rA] = v & mask;
|
||||
|
||||
uint32 registerRS = PPCRecompilerImlGen_loadRegister(ppcImlGenContext, PPCREC_NAME_R0+rS, false);
|
||||
uint32 registerRA = PPCRecompilerImlGen_loadOverwriteRegister(ppcImlGenContext, PPCREC_NAME_R0+rA);
|
||||
// handle special forms of RLWINM
|
||||
if( SH == 0 && SH == (ME-SH) && MB == 0 )
|
||||
{
|
||||
// CLRRWI
|
||||
// todo
|
||||
}
|
||||
else if( ME == (31-SH) && MB == 0 )
|
||||
if( ME == (31-SH) && MB == 0 )
|
||||
{
|
||||
// SLWI
|
||||
if(opcode&PPC_OPC_RC)
|
||||
ppcImlGenContext->emitInst().make_r_r_s32(PPCREC_IML_OP_LEFT_SHIFT, registerRA, registerRS, SH, 0, PPCREC_CR_MODE_LOGICAL);
|
||||
else
|
||||
ppcImlGenContext->emitInst().make_r_r_s32(PPCREC_IML_OP_LEFT_SHIFT, registerRA, registerRS, SH);
|
||||
return true;
|
||||
ppcImlGenContext->emitInst().make_r_r_s32(PPCREC_IML_OP_LEFT_SHIFT, registerRA, registerRS, SH);
|
||||
}
|
||||
else if( SH == (32-MB) && ME == 31 )
|
||||
{
|
||||
// SRWI
|
||||
if(opcode&PPC_OPC_RC)
|
||||
ppcImlGenContext->emitInst().make_r_r_s32(PPCREC_IML_OP_RIGHT_SHIFT, registerRA, registerRS, MB, 0, PPCREC_CR_MODE_LOGICAL);
|
||||
else
|
||||
ppcImlGenContext->emitInst().make_r_r_s32(PPCREC_IML_OP_RIGHT_SHIFT, registerRA, registerRS, MB);
|
||||
return true;
|
||||
ppcImlGenContext->emitInst().make_r_r_s32(PPCREC_IML_OP_RIGHT_SHIFT, registerRA, registerRS, MB);
|
||||
}
|
||||
else
|
||||
{
|
||||
// general handler
|
||||
if (registerRA != registerRS)
|
||||
ppcImlGenContext->emitInst().make_r_r(PPCREC_IML_OP_ASSIGN, registerRA, registerRS);
|
||||
if (SH != 0)
|
||||
ppcImlGenContext->emitInst().make_r_s32(PPCREC_IML_OP_LEFT_ROTATE, registerRA, SH);
|
||||
if (mask != 0xFFFFFFFF)
|
||||
ppcImlGenContext->emitInst().make_r_s32(PPCREC_IML_OP_AND, registerRA, (sint32)mask);
|
||||
}
|
||||
// general handler
|
||||
if( registerRA != registerRS )
|
||||
ppcImlGenContext->emitInst().make_r_r(PPCREC_IML_OP_ASSIGN, registerRA, registerRS);
|
||||
if( SH != 0 )
|
||||
ppcImlGenContext->emitInst().make_r_s32(PPCREC_IML_OP_LEFT_ROTATE, registerRA, SH);
|
||||
if( mask != 0xFFFFFFFF )
|
||||
ppcImlGenContext->emitInst().make_r_s32(PPCREC_IML_OP_AND, registerRA, (sint32)mask);
|
||||
if (opcode & PPC_OPC_RC)
|
||||
PPCImlGen_UpdateCR0Logical(ppcImlGenContext, registerRA);
|
||||
return true;
|
||||
@ -1185,14 +1138,10 @@ bool PPCRecompilerImlGen_RLWNM(ppcImlGenContext_t* ppcImlGenContext, uint32 opco
|
||||
{
|
||||
sint32 rS, rA, rB, MB, ME;
|
||||
PPC_OPC_TEMPL_M(opcode, rS, rA, rB, MB, ME);
|
||||
// uint32 v = ppc_word_rotl(hCPU->gpr[rS], hCPU->gpr[rB]);
|
||||
uint32 mask = ppc_mask(MB, ME);
|
||||
// uint32 v = ppc_word_rotl(hCPU->gpr[rS], hCPU->gpr[rB]);
|
||||
// hCPU->gpr[rA] = v & mask;
|
||||
uint32 registerRS = PPCRecompilerImlGen_loadRegister(ppcImlGenContext, PPCREC_NAME_R0+rS, false);
|
||||
uint32 registerRB = PPCRecompilerImlGen_loadRegister(ppcImlGenContext, PPCREC_NAME_R0+rB, false);
|
||||
uint32 registerRA = PPCRecompilerImlGen_loadOverwriteRegister(ppcImlGenContext, PPCREC_NAME_R0+rA);
|
||||
|
||||
ppcImlGenContext->emitInst().make_r_r_r(PPCREC_IML_OP_LEFT_ROTATE, registerRA, registerRS, registerRB);
|
||||
if( mask != 0xFFFFFFFF )
|
||||
ppcImlGenContext->emitInst().make_r_s32(PPCREC_IML_OP_AND, registerRA, (sint32)mask);
|
||||
@ -1208,10 +1157,9 @@ bool PPCRecompilerImlGen_SRAW(ppcImlGenContext_t* ppcImlGenContext, uint32 opcod
|
||||
uint32 registerRS = PPCRecompilerImlGen_loadRegister(ppcImlGenContext, PPCREC_NAME_R0+rS, false);
|
||||
uint32 registerRB = PPCRecompilerImlGen_loadRegister(ppcImlGenContext, PPCREC_NAME_R0+rB, false);
|
||||
uint32 registerRA = PPCRecompilerImlGen_loadOverwriteRegister(ppcImlGenContext, PPCREC_NAME_R0+rA);
|
||||
if( (opcode&PPC_OPC_RC) != 0 )
|
||||
ppcImlGenContext->emitInst().make_r_r_r(PPCREC_IML_OP_SRAW, registerRA, registerRS, registerRB, 0, PPCREC_CR_MODE_LOGICAL);
|
||||
else
|
||||
ppcImlGenContext->emitInst().make_r_r_r(PPCREC_IML_OP_SRAW, registerRA, registerRS, registerRB);
|
||||
ppcImlGenContext->emitInst().make_r_r_r(PPCREC_IML_OP_SRAW, registerRA, registerRS, registerRB);
|
||||
if ((opcode & PPC_OPC_RC))
|
||||
PPCImlGen_UpdateCR0Logical(ppcImlGenContext, registerRA);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1223,10 +1171,9 @@ bool PPCRecompilerImlGen_SRAWI(ppcImlGenContext_t* ppcImlGenContext, uint32 opco
|
||||
cemu_assert_debug(SH < 32);
|
||||
uint32 registerRS = PPCRecompilerImlGen_loadRegister(ppcImlGenContext, PPCREC_NAME_R0+rS, false);
|
||||
uint32 registerRA = PPCRecompilerImlGen_loadOverwriteRegister(ppcImlGenContext, PPCREC_NAME_R0+rA);
|
||||
if( opcode&PPC_OPC_RC )
|
||||
ppcImlGenContext->emitInst().make_r_r_s32(PPCREC_IML_OP_SRAW, registerRA, registerRS, (sint32)SH, 0, PPCREC_CR_MODE_LOGICAL);
|
||||
else
|
||||
ppcImlGenContext->emitInst().make_r_r_s32(PPCREC_IML_OP_SRAW, registerRA, registerRS, (sint32)SH);
|
||||
ppcImlGenContext->emitInst().make_r_r_s32(PPCREC_IML_OP_SRAW, registerRA, registerRS, (sint32)SH);
|
||||
if ((opcode & PPC_OPC_RC))
|
||||
PPCImlGen_UpdateCR0Logical(ppcImlGenContext, registerRA);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1238,14 +1185,9 @@ bool PPCRecompilerImlGen_SLW(ppcImlGenContext_t* ppcImlGenContext, uint32 opcode
|
||||
uint32 registerRS = PPCRecompilerImlGen_loadRegister(ppcImlGenContext, PPCREC_NAME_R0+rS, false);
|
||||
uint32 registerRB = PPCRecompilerImlGen_loadRegister(ppcImlGenContext, PPCREC_NAME_R0+rB, false);
|
||||
uint32 registerRA = PPCRecompilerImlGen_loadOverwriteRegister(ppcImlGenContext, PPCREC_NAME_R0+rA);
|
||||
if (opcode & PPC_OPC_RC)
|
||||
{
|
||||
ppcImlGenContext->emitInst().make_r_r_r(PPCREC_IML_OP_SLW, registerRA, registerRS, registerRB, 0, PPCREC_CR_MODE_LOGICAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
ppcImlGenContext->emitInst().make_r_r_r(PPCREC_IML_OP_SLW, registerRA, registerRS, registerRB, PPC_REC_INVALID_REGISTER, 0);
|
||||
}
|
||||
ppcImlGenContext->emitInst().make_r_r_r(PPCREC_IML_OP_SLW, registerRA, registerRS, registerRB);
|
||||
if ((opcode & PPC_OPC_RC))
|
||||
PPCImlGen_UpdateCR0Logical(ppcImlGenContext, registerRA);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1257,14 +1199,9 @@ bool PPCRecompilerImlGen_SRW(ppcImlGenContext_t* ppcImlGenContext, uint32 opcode
|
||||
uint32 registerRS = PPCRecompilerImlGen_loadRegister(ppcImlGenContext, PPCREC_NAME_R0+rS, false);
|
||||
uint32 registerRB = PPCRecompilerImlGen_loadRegister(ppcImlGenContext, PPCREC_NAME_R0+rB, false);
|
||||
uint32 registerRA = PPCRecompilerImlGen_loadOverwriteRegister(ppcImlGenContext, PPCREC_NAME_R0+rA);
|
||||
if (opcode & PPC_OPC_RC)
|
||||
{
|
||||
ppcImlGenContext->emitInst().make_r_r_r(PPCREC_IML_OP_SRW, registerRA, registerRS, registerRB, 0, PPCREC_CR_MODE_LOGICAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
ppcImlGenContext->emitInst().make_r_r_r(PPCREC_IML_OP_SRW, registerRA, registerRS, registerRB, PPC_REC_INVALID_REGISTER, 0);
|
||||
}
|
||||
ppcImlGenContext->emitInst().make_r_r_r(PPCREC_IML_OP_SRW, registerRA, registerRS, registerRB, PPC_REC_INVALID_REGISTER, 0);
|
||||
if ((opcode & PPC_OPC_RC))
|
||||
PPCImlGen_UpdateCR0Logical(ppcImlGenContext, registerRA);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1890,10 +1827,10 @@ void PPCRecompilerImlGen_STBU(ppcImlGenContext_t* ppcImlGenContext, uint32 opcod
|
||||
PPCRecompilerImlGen_generateNewInstruction_memory_r(ppcImlGenContext, sourceRegister, gprRegister, (rD==rA)?imm:0, 8, true);
|
||||
// add imm to memory register late if we couldn't do it early
|
||||
if( rD == rA )
|
||||
ppcImlGenContext->emitInst().make_r_r_s32(PPCREC_IML_OP_ADD, gprRegister, gprRegister, (sint32)imm, PPC_REC_INVALID_REGISTER, 0);
|
||||
ppcImlGenContext->emitInst().make_r_r_s32(PPCREC_IML_OP_ADD, gprRegister, gprRegister, (sint32)imm);
|
||||
}
|
||||
|
||||
// generic indexed store (STWX, STHX, STBX, STWUX. If bitReversed == true -> STHBRX)
|
||||
// generic indexed store (STWX, STHX, STBX, STWUX. If byteReversed == true -> STHBRX)
|
||||
bool PPCRecompilerImlGen_STORE_INDEXED(ppcImlGenContext_t* ppcImlGenContext, uint32 opcode, uint32 storeBitWidth, bool byteReversed = false)
|
||||
{
|
||||
sint32 rA, rS, rB;
|
||||
|
@ -258,7 +258,7 @@ bool PPCRecompilerImlGen_LFDU(ppcImlGenContext_t* ppcImlGenContext, uint32 opcod
|
||||
// get memory gpr register index
|
||||
uint32 gprRegister = PPCRecompilerImlGen_loadRegister(ppcImlGenContext, PPCREC_NAME_R0+rA, false);
|
||||
// add imm to memory register
|
||||
ppcImlGenContext->emitInst().make_r_r_s32(PPCREC_IML_OP_ADD, gprRegister, gprRegister, (sint32)imm, PPC_REC_INVALID_REGISTER, 0);
|
||||
ppcImlGenContext->emitInst().make_r_r_s32(PPCREC_IML_OP_ADD, gprRegister, gprRegister, (sint32)imm);
|
||||
// get fpr register index
|
||||
uint32 fprRegister = PPCRecompilerImlGen_loadOverwriteFPRRegister(ppcImlGenContext, PPCREC_NAME_FPR0+frD);
|
||||
// emit load iml
|
||||
|
Loading…
x
Reference in New Issue
Block a user