PPCRec: Rename register constants to avoid name collision

This commit is contained in:
Exzap 2022-12-14 06:52:06 +01:00
parent d420622da7
commit 53436f1c79
6 changed files with 328 additions and 354 deletions

View file

@ -70,11 +70,11 @@ void PPCRecompilerX64Gen_updateCRLogical(PPCRecFunction_t* PPCRecFunction, ppcIm
{ {
sint32 crRegister = imlInstruction->crRegister; sint32 crRegister = imlInstruction->crRegister;
if( (imlInstruction->crIgnoreMask&(1<<(crRegister*4+PPCREC_CR_BIT_LT))) == 0 ) if( (imlInstruction->crIgnoreMask&(1<<(crRegister*4+PPCREC_CR_BIT_LT))) == 0 )
x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_SIGN, 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 TEST 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 TEST
if( (imlInstruction->crIgnoreMask&(1<<(crRegister*4+PPCREC_CR_BIT_GT))) == 0 ) if( (imlInstruction->crIgnoreMask&(1<<(crRegister*4+PPCREC_CR_BIT_GT))) == 0 )
x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_SIGNED_GREATER, REG_RSP, offsetof(PPCInterpreter_t, cr)+sizeof(uint8)*(crRegister*4+PPCREC_CR_BIT_GT)); x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_SIGNED_GREATER, X86_REG_RSP, offsetof(PPCInterpreter_t, cr)+sizeof(uint8)*(crRegister*4+PPCREC_CR_BIT_GT));
if( (imlInstruction->crIgnoreMask&(1<<(crRegister*4+PPCREC_CR_BIT_EQ))) == 0 ) if( (imlInstruction->crIgnoreMask&(1<<(crRegister*4+PPCREC_CR_BIT_EQ))) == 0 )
x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_EQUAL, REG_RSP, offsetof(PPCInterpreter_t, cr)+sizeof(uint8)*(crRegister*4+PPCREC_CR_BIT_EQ)); x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_EQUAL, X86_REG_RSP, offsetof(PPCInterpreter_t, cr)+sizeof(uint8)*(crRegister*4+PPCREC_CR_BIT_EQ));
// todo: Set CR SO if XER SO bit is set // todo: Set CR SO if XER SO bit is set
PPCRecompilerX64Gen_crConditionFlags_set(PPCRecFunction, ppcImlGenContext, x64GenContext, crRegister, PPCREC_CR_STATE_TYPE_LOGICAL); PPCRecompilerX64Gen_crConditionFlags_set(PPCRecFunction, ppcImlGenContext, x64GenContext, crRegister, PPCREC_CR_STATE_TYPE_LOGICAL);
} }
@ -117,8 +117,8 @@ bool PPCRecompilerX64Gen_imlInstruction_macro(PPCRecFunction_t* PPCRecFunction,
if (imlInstruction->operation == PPCREC_IML_MACRO_B_TO_REG) if (imlInstruction->operation == PPCREC_IML_MACRO_B_TO_REG)
{ {
uint32 branchDstReg = imlInstruction->op_macro.param; uint32 branchDstReg = imlInstruction->op_macro.param;
if(REG_RDX != branchDstReg) if(X86_REG_RDX != branchDstReg)
x64Gen_mov_reg64_reg64(x64GenContext, REG_RDX, branchDstReg); x64Gen_mov_reg64_reg64(x64GenContext, X86_REG_RDX, branchDstReg);
// potential optimization: Use branchDstReg directly if possible instead of moving to RDX/EDX // potential optimization: Use branchDstReg directly if possible instead of moving to RDX/EDX
// JMP [offset+RDX*(8/4)+R15] // JMP [offset+RDX*(8/4)+R15]
x64Gen_writeU8(x64GenContext, 0x41); x64Gen_writeU8(x64GenContext, 0x41);
@ -132,10 +132,10 @@ bool PPCRecompilerX64Gen_imlInstruction_macro(PPCRecFunction_t* PPCRecFunction,
{ {
// MOV DWORD [SPR_LinkRegister], newLR // MOV DWORD [SPR_LinkRegister], newLR
uint32 newLR = imlInstruction->op_macro.param + 4; uint32 newLR = imlInstruction->op_macro.param + 4;
x64Gen_mov_mem32Reg64_imm32(x64GenContext, REG_RSP, offsetof(PPCInterpreter_t, spr.LR), newLR); x64Gen_mov_mem32Reg64_imm32(x64GenContext, X86_REG_RSP, offsetof(PPCInterpreter_t, spr.LR), newLR);
// remember new instruction pointer in RDX // remember new instruction pointer in RDX
uint32 newIP = imlInstruction->op_macro.param2; uint32 newIP = imlInstruction->op_macro.param2;
x64Gen_mov_reg64Low32_imm32(x64GenContext, REG_RDX, newIP); x64Gen_mov_reg64Low32_imm32(x64GenContext, X86_REG_RDX, newIP);
// since RDX is constant we can use JMP [R15+const_offset] if jumpTableOffset+RDX*2 does not exceed the 2GB boundary // since RDX is constant we can use JMP [R15+const_offset] if jumpTableOffset+RDX*2 does not exceed the 2GB boundary
uint64 lookupOffset = (uint64)offsetof(PPCRecompilerInstanceData_t, ppcRecompilerDirectJumpTable) + (uint64)newIP * 2ULL; uint64 lookupOffset = (uint64)offsetof(PPCRecompilerInstanceData_t, ppcRecompilerDirectJumpTable) + (uint64)newIP * 2ULL;
if (lookupOffset >= 0x80000000ULL) if (lookupOffset >= 0x80000000ULL)
@ -160,7 +160,7 @@ bool PPCRecompilerX64Gen_imlInstruction_macro(PPCRecFunction_t* PPCRecFunction,
{ {
// remember new instruction pointer in RDX // remember new instruction pointer in RDX
uint32 newIP = imlInstruction->op_macro.param2; uint32 newIP = imlInstruction->op_macro.param2;
x64Gen_mov_reg64Low32_imm32(x64GenContext, REG_RDX, newIP); x64Gen_mov_reg64Low32_imm32(x64GenContext, X86_REG_RDX, newIP);
// Since RDX is constant we can use JMP [R15+const_offset] if jumpTableOffset+RDX*2 does not exceed the 2GB boundary // Since RDX is constant we can use JMP [R15+const_offset] if jumpTableOffset+RDX*2 does not exceed the 2GB boundary
uint64 lookupOffset = (uint64)offsetof(PPCRecompilerInstanceData_t, ppcRecompilerDirectJumpTable) + (uint64)newIP * 2ULL; uint64 lookupOffset = (uint64)offsetof(PPCRecompilerInstanceData_t, ppcRecompilerDirectJumpTable) + (uint64)newIP * 2ULL;
if (lookupOffset >= 0x80000000ULL) if (lookupOffset >= 0x80000000ULL)
@ -185,7 +185,7 @@ bool PPCRecompilerX64Gen_imlInstruction_macro(PPCRecFunction_t* PPCRecFunction,
{ {
uint32 currentInstructionAddress = imlInstruction->op_macro.param; uint32 currentInstructionAddress = imlInstruction->op_macro.param;
// remember PC value in REG_EDX // remember PC value in REG_EDX
x64Gen_mov_reg64Low32_imm32(x64GenContext, REG_RDX, currentInstructionAddress); x64Gen_mov_reg64Low32_imm32(x64GenContext, X86_REG_RDX, currentInstructionAddress);
uint32 newIP = 0; // special value for recompiler exit uint32 newIP = 0; // special value for recompiler exit
uint64 lookupOffset = (uint64)&(((PPCRecompilerInstanceData_t*)NULL)->ppcRecompilerDirectJumpTable) + (uint64)newIP * 2ULL; uint64 lookupOffset = (uint64)&(((PPCRecompilerInstanceData_t*)NULL)->ppcRecompilerDirectJumpTable) + (uint64)newIP * 2ULL;
@ -205,7 +205,7 @@ bool PPCRecompilerX64Gen_imlInstruction_macro(PPCRecFunction_t* PPCRecFunction,
else if( imlInstruction->operation == PPCREC_IML_MACRO_COUNT_CYCLES ) else if( imlInstruction->operation == PPCREC_IML_MACRO_COUNT_CYCLES )
{ {
uint32 cycleCount = imlInstruction->op_macro.param; uint32 cycleCount = imlInstruction->op_macro.param;
x64Gen_sub_mem32reg64_imm32(x64GenContext, REG_RSP, offsetof(PPCInterpreter_t, remainingCycles), cycleCount); x64Gen_sub_mem32reg64_imm32(x64GenContext, X86_REG_RSP, offsetof(PPCInterpreter_t, remainingCycles), cycleCount);
return true; return true;
} }
else if( imlInstruction->operation == PPCREC_IML_MACRO_HLE ) else if( imlInstruction->operation == PPCREC_IML_MACRO_HLE )
@ -214,58 +214,58 @@ bool PPCRecompilerX64Gen_imlInstruction_macro(PPCRecFunction_t* PPCRecFunction,
uint32 funcId = imlInstruction->op_macro.param2; uint32 funcId = imlInstruction->op_macro.param2;
//x64Gen_int3(x64GenContext); //x64Gen_int3(x64GenContext);
// update instruction pointer // update instruction pointer
x64Gen_mov_mem32Reg64_imm32(x64GenContext, REG_RSP, offsetof(PPCInterpreter_t, instructionPointer), ppcAddress); x64Gen_mov_mem32Reg64_imm32(x64GenContext, X86_REG_RSP, offsetof(PPCInterpreter_t, instructionPointer), ppcAddress);
//// save hCPU (RSP) //// save hCPU (RSP)
//x64Gen_mov_reg64_imm64(x64GenContext, REG_RESV_TEMP, (uint64)&ppcRecompilerX64_hCPUTemp); //x64Gen_mov_reg64_imm64(x64GenContext, REG_RESV_TEMP, (uint64)&ppcRecompilerX64_hCPUTemp);
//x64Emit_mov_mem64_reg64(x64GenContext, REG_RESV_TEMP, 0, REG_RSP); //x64Emit_mov_mem64_reg64(x64GenContext, REG_RESV_TEMP, 0, REG_RSP);
// set parameters // set parameters
x64Gen_mov_reg64_reg64(x64GenContext, REG_RCX, REG_RSP); x64Gen_mov_reg64_reg64(x64GenContext, X86_REG_RCX, X86_REG_RSP);
x64Gen_mov_reg64_imm64(x64GenContext, REG_RDX, funcId); x64Gen_mov_reg64_imm64(x64GenContext, X86_REG_RDX, funcId);
// restore stackpointer from executionContext/hCPU->rspTemp // restore stackpointer from executionContext/hCPU->rspTemp
x64Emit_mov_reg64_mem64(x64GenContext, REG_RSP, REG_RESV_HCPU, offsetof(PPCInterpreter_t, rspTemp)); x64Emit_mov_reg64_mem64(x64GenContext, X86_REG_RSP, REG_RESV_HCPU, offsetof(PPCInterpreter_t, rspTemp));
//x64Emit_mov_reg64_mem64(x64GenContext, REG_RSP, REG_R14, 0); //x64Emit_mov_reg64_mem64(x64GenContext, REG_RSP, REG_R14, 0);
//x64Gen_int3(x64GenContext); //x64Gen_int3(x64GenContext);
// reserve space on stack for call parameters // reserve space on stack for call parameters
x64Gen_sub_reg64_imm32(x64GenContext, REG_RSP, 8*11); // must be uneven number in order to retain stack 0x10 alignment x64Gen_sub_reg64_imm32(x64GenContext, X86_REG_RSP, 8*11); // must be uneven number in order to retain stack 0x10 alignment
x64Gen_mov_reg64_imm64(x64GenContext, REG_RBP, 0); x64Gen_mov_reg64_imm64(x64GenContext, X86_REG_RBP, 0);
// call HLE function // call HLE function
x64Gen_mov_reg64_imm64(x64GenContext, REG_RAX, (uint64)PPCRecompiler_virtualHLE); x64Gen_mov_reg64_imm64(x64GenContext, X86_REG_RAX, (uint64)PPCRecompiler_virtualHLE);
x64Gen_call_reg64(x64GenContext, REG_RAX); x64Gen_call_reg64(x64GenContext, X86_REG_RAX);
// restore RSP to hCPU (from RAX, result of PPCRecompiler_virtualHLE) // restore RSP to hCPU (from RAX, result of PPCRecompiler_virtualHLE)
//x64Gen_mov_reg64_imm64(x64GenContext, REG_RESV_TEMP, (uint64)&ppcRecompilerX64_hCPUTemp); //x64Gen_mov_reg64_imm64(x64GenContext, REG_RESV_TEMP, (uint64)&ppcRecompilerX64_hCPUTemp);
//x64Emit_mov_reg64_mem64Reg64(x64GenContext, REG_RSP, REG_RESV_TEMP, 0); //x64Emit_mov_reg64_mem64Reg64(x64GenContext, REG_RSP, REG_RESV_TEMP, 0);
x64Gen_mov_reg64_reg64(x64GenContext, REG_RSP, REG_RAX); x64Gen_mov_reg64_reg64(x64GenContext, X86_REG_RSP, X86_REG_RAX);
// MOV R15, ppcRecompilerInstanceData // MOV R15, ppcRecompilerInstanceData
x64Gen_mov_reg64_imm64(x64GenContext, REG_R15, (uint64)ppcRecompilerInstanceData); x64Gen_mov_reg64_imm64(x64GenContext, X86_REG_R15, (uint64)ppcRecompilerInstanceData);
// MOV R13, memory_base // MOV R13, memory_base
x64Gen_mov_reg64_imm64(x64GenContext, REG_R13, (uint64)memory_base); x64Gen_mov_reg64_imm64(x64GenContext, X86_REG_R13, (uint64)memory_base);
// check if cycles where decreased beyond zero, if yes -> leave recompiler // check if cycles where decreased beyond zero, if yes -> leave recompiler
x64Gen_bt_mem8(x64GenContext, REG_RSP, offsetof(PPCInterpreter_t, remainingCycles), 31); // check if negative x64Gen_bt_mem8(x64GenContext, X86_REG_RSP, offsetof(PPCInterpreter_t, remainingCycles), 31); // check if negative
sint32 jumpInstructionOffset1 = x64GenContext->codeBufferIndex; sint32 jumpInstructionOffset1 = x64GenContext->codeBufferIndex;
x64Gen_jmpc_near(x64GenContext, X86_CONDITION_NOT_CARRY, 0); x64Gen_jmpc_near(x64GenContext, X86_CONDITION_NOT_CARRY, 0);
//x64Gen_int3(x64GenContext); //x64Gen_int3(x64GenContext);
//x64Gen_mov_reg64Low32_imm32(x64GenContext, REG_RDX, ppcAddress); //x64Gen_mov_reg64Low32_imm32(x64GenContext, REG_RDX, ppcAddress);
x64Emit_mov_reg64_mem32(x64GenContext, REG_RDX, REG_RSP, offsetof(PPCInterpreter_t, instructionPointer)); x64Emit_mov_reg64_mem32(x64GenContext, X86_REG_RDX, X86_REG_RSP, offsetof(PPCInterpreter_t, instructionPointer));
// set EAX to 0 (we assume that ppcRecompilerDirectJumpTable[0] will be a recompiler escape function) // set EAX to 0 (we assume that ppcRecompilerDirectJumpTable[0] will be a recompiler escape function)
x64Gen_xor_reg32_reg32(x64GenContext, REG_RAX, REG_RAX); x64Gen_xor_reg32_reg32(x64GenContext, X86_REG_RAX, X86_REG_RAX);
// ADD RAX, R15 (R15 -> Pointer to ppcRecompilerInstanceData // ADD RAX, R15 (R15 -> Pointer to ppcRecompilerInstanceData
x64Gen_add_reg64_reg64(x64GenContext, REG_RAX, REG_R15); x64Gen_add_reg64_reg64(x64GenContext, X86_REG_RAX, X86_REG_R15);
//// JMP [recompilerCallTable+EAX/4*8] //// JMP [recompilerCallTable+EAX/4*8]
//x64Gen_int3(x64GenContext); //x64Gen_int3(x64GenContext);
x64Gen_jmp_memReg64(x64GenContext, REG_RAX, (uint32)offsetof(PPCRecompilerInstanceData_t, ppcRecompilerDirectJumpTable)); x64Gen_jmp_memReg64(x64GenContext, X86_REG_RAX, (uint32)offsetof(PPCRecompilerInstanceData_t, ppcRecompilerDirectJumpTable));
PPCRecompilerX64Gen_redirectRelativeJump(x64GenContext, jumpInstructionOffset1, x64GenContext->codeBufferIndex); PPCRecompilerX64Gen_redirectRelativeJump(x64GenContext, jumpInstructionOffset1, x64GenContext->codeBufferIndex);
// check if instruction pointer was changed // check if instruction pointer was changed
// assign new instruction pointer to EAX // assign new instruction pointer to EAX
x64Emit_mov_reg64_mem32(x64GenContext, REG_RAX, REG_RSP, offsetof(PPCInterpreter_t, instructionPointer)); x64Emit_mov_reg64_mem32(x64GenContext, X86_REG_RAX, X86_REG_RSP, offsetof(PPCInterpreter_t, instructionPointer));
// remember instruction pointer in REG_EDX // remember instruction pointer in REG_EDX
x64Gen_mov_reg64_reg64(x64GenContext, REG_RDX, REG_RAX); x64Gen_mov_reg64_reg64(x64GenContext, X86_REG_RDX, X86_REG_RAX);
// EAX *= 2 // EAX *= 2
x64Gen_add_reg64_reg64(x64GenContext, REG_RAX, REG_RAX); x64Gen_add_reg64_reg64(x64GenContext, X86_REG_RAX, X86_REG_RAX);
// ADD RAX, R15 (R15 -> Pointer to ppcRecompilerInstanceData // ADD RAX, R15 (R15 -> Pointer to ppcRecompilerInstanceData
x64Gen_add_reg64_reg64(x64GenContext, REG_RAX, REG_R15); x64Gen_add_reg64_reg64(x64GenContext, X86_REG_RAX, X86_REG_R15);
// JMP [ppcRecompilerDirectJumpTable+RAX/4*8] // JMP [ppcRecompilerDirectJumpTable+RAX/4*8]
x64Gen_jmp_memReg64(x64GenContext, REG_RAX, (uint32)offsetof(PPCRecompilerInstanceData_t, ppcRecompilerDirectJumpTable)); x64Gen_jmp_memReg64(x64GenContext, X86_REG_RAX, (uint32)offsetof(PPCRecompilerInstanceData_t, ppcRecompilerDirectJumpTable));
return true; return true;
} }
else if( imlInstruction->operation == PPCREC_IML_MACRO_MFTB ) else if( imlInstruction->operation == PPCREC_IML_MACRO_MFTB )
@ -277,32 +277,32 @@ bool PPCRecompilerX64Gen_imlInstruction_macro(PPCRecFunction_t* PPCRecFunction,
uint32 sprId = imlInstruction->op_macro.param2&0xFFFF; uint32 sprId = imlInstruction->op_macro.param2&0xFFFF;
uint32 gprIndex = (imlInstruction->op_macro.param2>>16)&0x1F; uint32 gprIndex = (imlInstruction->op_macro.param2>>16)&0x1F;
// update instruction pointer // update instruction pointer
x64Gen_mov_mem32Reg64_imm32(x64GenContext, REG_RSP, offsetof(PPCInterpreter_t, instructionPointer), ppcAddress); x64Gen_mov_mem32Reg64_imm32(x64GenContext, X86_REG_RSP, offsetof(PPCInterpreter_t, instructionPointer), ppcAddress);
// set parameters // set parameters
x64Gen_mov_reg64_reg64(x64GenContext, REG_RCX, REG_RSP); x64Gen_mov_reg64_reg64(x64GenContext, X86_REG_RCX, X86_REG_RSP);
x64Gen_mov_reg64_imm64(x64GenContext, REG_RDX, gprIndex); x64Gen_mov_reg64_imm64(x64GenContext, X86_REG_RDX, gprIndex);
// restore stackpointer to original RSP // restore stackpointer to original RSP
x64Emit_mov_reg64_mem64(x64GenContext, REG_RSP, REG_RESV_HCPU, offsetof(PPCInterpreter_t, rspTemp)); x64Emit_mov_reg64_mem64(x64GenContext, X86_REG_RSP, REG_RESV_HCPU, offsetof(PPCInterpreter_t, rspTemp));
// push hCPU on stack // push hCPU on stack
x64Gen_push_reg64(x64GenContext, REG_RCX); x64Gen_push_reg64(x64GenContext, X86_REG_RCX);
// reserve space on stack for call parameters // reserve space on stack for call parameters
x64Gen_sub_reg64_imm32(x64GenContext, REG_RSP, 8*11 + 8); x64Gen_sub_reg64_imm32(x64GenContext, X86_REG_RSP, 8*11 + 8);
x64Gen_mov_reg64_imm64(x64GenContext, REG_RBP, 0); x64Gen_mov_reg64_imm64(x64GenContext, X86_REG_RBP, 0);
// call function // call function
if( sprId == SPR_TBL ) if( sprId == SPR_TBL )
x64Gen_mov_reg64_imm64(x64GenContext, REG_RAX, (uint64)PPCRecompiler_getTBL); x64Gen_mov_reg64_imm64(x64GenContext, X86_REG_RAX, (uint64)PPCRecompiler_getTBL);
else if( sprId == SPR_TBU ) else if( sprId == SPR_TBU )
x64Gen_mov_reg64_imm64(x64GenContext, REG_RAX, (uint64)PPCRecompiler_getTBU); x64Gen_mov_reg64_imm64(x64GenContext, X86_REG_RAX, (uint64)PPCRecompiler_getTBU);
else else
assert_dbg(); assert_dbg();
x64Gen_call_reg64(x64GenContext, REG_RAX); x64Gen_call_reg64(x64GenContext, X86_REG_RAX);
// restore hCPU from stack // restore hCPU from stack
x64Gen_add_reg64_imm32(x64GenContext, REG_RSP, 8 * 11 + 8); x64Gen_add_reg64_imm32(x64GenContext, X86_REG_RSP, 8 * 11 + 8);
x64Gen_pop_reg64(x64GenContext, REG_RSP); x64Gen_pop_reg64(x64GenContext, X86_REG_RSP);
// MOV R15, ppcRecompilerInstanceData // MOV R15, ppcRecompilerInstanceData
x64Gen_mov_reg64_imm64(x64GenContext, REG_R15, (uint64)ppcRecompilerInstanceData); x64Gen_mov_reg64_imm64(x64GenContext, X86_REG_R15, (uint64)ppcRecompilerInstanceData);
// MOV R13, memory_base // MOV R13, memory_base
x64Gen_mov_reg64_imm64(x64GenContext, REG_R13, (uint64)memory_base); x64Gen_mov_reg64_imm64(x64GenContext, X86_REG_R13, (uint64)memory_base);
return true; return true;
} }
else else
@ -350,20 +350,20 @@ bool PPCRecompilerX64Gen_imlInstruction_load(PPCRecFunction_t* PPCRecFunction, p
{ {
if (indexed) if (indexed)
{ {
x64Gen_movBEZeroExtend_reg64_mem32Reg64PlusReg64(x64GenContext, realRegisterData, REG_R13, REG_RESV_TEMP, imlInstruction->op_storeLoad.immS32); x64Gen_movBEZeroExtend_reg64_mem32Reg64PlusReg64(x64GenContext, realRegisterData, X86_REG_R13, REG_RESV_TEMP, imlInstruction->op_storeLoad.immS32);
//if (indexed && realRegisterMem != realRegisterData) //if (indexed && realRegisterMem != realRegisterData)
// x64Gen_sub_reg64Low32_reg64Low32(x64GenContext, realRegisterMem, realRegisterMem2); // x64Gen_sub_reg64Low32_reg64Low32(x64GenContext, realRegisterMem, realRegisterMem2);
} }
else else
{ {
x64Gen_movBEZeroExtend_reg64_mem32Reg64PlusReg64(x64GenContext, realRegisterData, REG_R13, realRegisterMem, imlInstruction->op_storeLoad.immS32); x64Gen_movBEZeroExtend_reg64_mem32Reg64PlusReg64(x64GenContext, realRegisterData, X86_REG_R13, realRegisterMem, imlInstruction->op_storeLoad.immS32);
} }
} }
else else
{ {
if (indexed) if (indexed)
{ {
x64Emit_mov_reg32_mem32(x64GenContext, realRegisterData, REG_R13, REG_RESV_TEMP, imlInstruction->op_storeLoad.immS32); x64Emit_mov_reg32_mem32(x64GenContext, realRegisterData, X86_REG_R13, REG_RESV_TEMP, imlInstruction->op_storeLoad.immS32);
//if (realRegisterMem != realRegisterData) //if (realRegisterMem != realRegisterData)
// x64Gen_sub_reg64Low32_reg64Low32(x64GenContext, realRegisterMem, realRegisterMem2); // x64Gen_sub_reg64Low32_reg64Low32(x64GenContext, realRegisterMem, realRegisterMem2);
if (switchEndian) if (switchEndian)
@ -371,7 +371,7 @@ bool PPCRecompilerX64Gen_imlInstruction_load(PPCRecFunction_t* PPCRecFunction, p
} }
else else
{ {
x64Emit_mov_reg32_mem32(x64GenContext, realRegisterData, REG_R13, realRegisterMem, imlInstruction->op_storeLoad.immS32); x64Emit_mov_reg32_mem32(x64GenContext, realRegisterData, X86_REG_R13, realRegisterMem, imlInstruction->op_storeLoad.immS32);
if (switchEndian) if (switchEndian)
x64Gen_bswap_reg64Lower32bit(x64GenContext, realRegisterData); x64Gen_bswap_reg64Lower32bit(x64GenContext, realRegisterData);
} }
@ -386,13 +386,13 @@ bool PPCRecompilerX64Gen_imlInstruction_load(PPCRecFunction_t* PPCRecFunction, p
} }
if(g_CPUFeatures.x86.movbe && switchEndian ) if(g_CPUFeatures.x86.movbe && switchEndian )
{ {
x64Gen_movBEZeroExtend_reg64Low16_mem16Reg64PlusReg64(x64GenContext, realRegisterData, REG_R13, realRegisterMem, imlInstruction->op_storeLoad.immS32); x64Gen_movBEZeroExtend_reg64Low16_mem16Reg64PlusReg64(x64GenContext, realRegisterData, X86_REG_R13, realRegisterMem, imlInstruction->op_storeLoad.immS32);
if( indexed && realRegisterMem != realRegisterData ) if( indexed && realRegisterMem != realRegisterData )
x64Gen_sub_reg64Low32_reg64Low32(x64GenContext, realRegisterMem, realRegisterMem2); x64Gen_sub_reg64Low32_reg64Low32(x64GenContext, realRegisterMem, realRegisterMem2);
} }
else else
{ {
x64Gen_movZeroExtend_reg64Low16_mem16Reg64PlusReg64(x64GenContext, realRegisterData, REG_R13, realRegisterMem, imlInstruction->op_storeLoad.immS32); x64Gen_movZeroExtend_reg64Low16_mem16Reg64PlusReg64(x64GenContext, realRegisterData, X86_REG_R13, realRegisterMem, imlInstruction->op_storeLoad.immS32);
if( indexed && realRegisterMem != realRegisterData ) if( indexed && realRegisterMem != realRegisterData )
x64Gen_sub_reg64Low32_reg64Low32(x64GenContext, realRegisterMem, realRegisterMem2); x64Gen_sub_reg64Low32_reg64Low32(x64GenContext, realRegisterMem, realRegisterMem2);
if( switchEndian ) if( switchEndian )
@ -411,9 +411,9 @@ bool PPCRecompilerX64Gen_imlInstruction_load(PPCRecFunction_t* PPCRecFunction, p
if( indexed ) if( indexed )
x64Gen_add_reg64Low32_reg64Low32(x64GenContext, realRegisterMem, realRegisterMem2); x64Gen_add_reg64Low32_reg64Low32(x64GenContext, realRegisterMem, realRegisterMem2);
if( signExtend ) if( signExtend )
x64Gen_movSignExtend_reg64Low32_mem8Reg64PlusReg64(x64GenContext, realRegisterData, REG_R13, realRegisterMem, imlInstruction->op_storeLoad.immS32); x64Gen_movSignExtend_reg64Low32_mem8Reg64PlusReg64(x64GenContext, realRegisterData, X86_REG_R13, realRegisterMem, imlInstruction->op_storeLoad.immS32);
else else
x64Emit_movZX_reg32_mem8(x64GenContext, realRegisterData, REG_R13, realRegisterMem, imlInstruction->op_storeLoad.immS32); x64Emit_movZX_reg32_mem8(x64GenContext, realRegisterData, X86_REG_R13, realRegisterMem, imlInstruction->op_storeLoad.immS32);
if( indexed && realRegisterMem != realRegisterData ) if( indexed && realRegisterMem != realRegisterData )
x64Gen_sub_reg64Low32_reg64Low32(x64GenContext, realRegisterMem, realRegisterMem2); x64Gen_sub_reg64Low32_reg64Low32(x64GenContext, realRegisterMem, realRegisterMem2);
} }
@ -424,15 +424,15 @@ bool PPCRecompilerX64Gen_imlInstruction_load(PPCRecFunction_t* PPCRecFunction, p
assert_dbg(); // not supported assert_dbg(); // not supported
if( indexed ) if( indexed )
x64Gen_add_reg64Low32_reg64Low32(x64GenContext, realRegisterMem, realRegisterMem2); x64Gen_add_reg64Low32_reg64Low32(x64GenContext, realRegisterMem, realRegisterMem2);
x64Emit_mov_mem32_reg32(x64GenContext, REG_RSP, (uint32)offsetof(PPCInterpreter_t, reservedMemAddr), realRegisterMem); // remember EA for reservation x64Emit_mov_mem32_reg32(x64GenContext, X86_REG_RSP, (uint32)offsetof(PPCInterpreter_t, reservedMemAddr), realRegisterMem); // remember EA for reservation
x64Emit_mov_reg32_mem32(x64GenContext, realRegisterData, REG_R13, realRegisterMem, imlInstruction->op_storeLoad.immS32); x64Emit_mov_reg32_mem32(x64GenContext, realRegisterData, X86_REG_R13, realRegisterMem, imlInstruction->op_storeLoad.immS32);
if( indexed && realRegisterMem != realRegisterData ) if( indexed && realRegisterMem != realRegisterData )
x64Gen_sub_reg64Low32_reg64Low32(x64GenContext, realRegisterMem, realRegisterMem2); x64Gen_sub_reg64Low32_reg64Low32(x64GenContext, realRegisterMem, realRegisterMem2);
if( switchEndian ) if( switchEndian )
x64Gen_bswap_reg64Lower32bit(x64GenContext, realRegisterData); x64Gen_bswap_reg64Lower32bit(x64GenContext, realRegisterData);
x64Emit_mov_mem32_reg32(x64GenContext, REG_RSP, (uint32)offsetof(PPCInterpreter_t, reservedMemValue), realRegisterData); // remember value for reservation x64Emit_mov_mem32_reg32(x64GenContext, X86_REG_RSP, (uint32)offsetof(PPCInterpreter_t, reservedMemValue), realRegisterData); // remember value for reservation
// LWARX instruction costs extra cycles (this speeds up busy loops) // LWARX instruction costs extra cycles (this speeds up busy loops)
x64Gen_sub_mem32reg64_imm32(x64GenContext, REG_RSP, offsetof(PPCInterpreter_t, remainingCycles), 20); x64Gen_sub_mem32reg64_imm32(x64GenContext, X86_REG_RSP, offsetof(PPCInterpreter_t, remainingCycles), 20);
} }
else else
return false; return false;
@ -484,9 +484,9 @@ bool PPCRecompilerX64Gen_imlInstruction_store(PPCRecFunction_t* PPCRecFunction,
if (indexed) if (indexed)
x64Gen_add_reg64Low32_reg64Low32(x64GenContext, realRegisterMem, realRegisterMem2); x64Gen_add_reg64Low32_reg64Low32(x64GenContext, realRegisterMem, realRegisterMem2);
if (g_CPUFeatures.x86.movbe && swapEndian) if (g_CPUFeatures.x86.movbe && swapEndian)
x64Gen_movBETruncate_mem32Reg64PlusReg64_reg64(x64GenContext, REG_R13, realRegisterMem, imlInstruction->op_storeLoad.immS32, valueRegister); x64Gen_movBETruncate_mem32Reg64PlusReg64_reg64(x64GenContext, X86_REG_R13, realRegisterMem, imlInstruction->op_storeLoad.immS32, valueRegister);
else else
x64Gen_movTruncate_mem32Reg64PlusReg64_reg64(x64GenContext, REG_R13, realRegisterMem, imlInstruction->op_storeLoad.immS32, valueRegister); x64Gen_movTruncate_mem32Reg64PlusReg64_reg64(x64GenContext, X86_REG_R13, realRegisterMem, imlInstruction->op_storeLoad.immS32, valueRegister);
if (indexed) if (indexed)
x64Gen_sub_reg64Low32_reg64Low32(x64GenContext, realRegisterMem, realRegisterMem2); x64Gen_sub_reg64Low32_reg64Low32(x64GenContext, realRegisterMem, realRegisterMem2);
} }
@ -499,7 +499,7 @@ bool PPCRecompilerX64Gen_imlInstruction_store(PPCRecFunction_t* PPCRecFunction,
x64Gen_rol_reg64Low16_imm8(x64GenContext, REG_RESV_TEMP, 8); x64Gen_rol_reg64Low16_imm8(x64GenContext, REG_RESV_TEMP, 8);
if (indexed) if (indexed)
x64Gen_add_reg64Low32_reg64Low32(x64GenContext, realRegisterMem, realRegisterMem2); x64Gen_add_reg64Low32_reg64Low32(x64GenContext, realRegisterMem, realRegisterMem2);
x64Gen_movTruncate_mem16Reg64PlusReg64_reg64(x64GenContext, REG_R13, realRegisterMem, imlInstruction->op_storeLoad.immS32, REG_RESV_TEMP); x64Gen_movTruncate_mem16Reg64PlusReg64_reg64(x64GenContext, X86_REG_R13, realRegisterMem, imlInstruction->op_storeLoad.immS32, REG_RESV_TEMP);
if (indexed) if (indexed)
x64Gen_sub_reg64Low32_reg64Low32(x64GenContext, realRegisterMem, realRegisterMem2); x64Gen_sub_reg64Low32_reg64Low32(x64GenContext, realRegisterMem, realRegisterMem2);
// todo: Optimize this, e.g. by using MOVBE // todo: Optimize this, e.g. by using MOVBE
@ -526,9 +526,9 @@ bool PPCRecompilerX64Gen_imlInstruction_store(PPCRecFunction_t* PPCRecFunction,
assert_dbg(); // todo assert_dbg(); // todo
// reset cr0 LT, GT and EQ // reset cr0 LT, GT and EQ
sint32 crRegister = 0; sint32 crRegister = 0;
x64Gen_mov_mem8Reg64_imm8(x64GenContext, REG_RSP, offsetof(PPCInterpreter_t, cr) + sizeof(uint8)*(crRegister * 4 + PPCREC_CR_BIT_LT), 0); x64Gen_mov_mem8Reg64_imm8(x64GenContext, X86_REG_RSP, offsetof(PPCInterpreter_t, cr) + sizeof(uint8)*(crRegister * 4 + PPCREC_CR_BIT_LT), 0);
x64Gen_mov_mem8Reg64_imm8(x64GenContext, REG_RSP, offsetof(PPCInterpreter_t, cr) + sizeof(uint8)*(crRegister * 4 + PPCREC_CR_BIT_GT), 0); x64Gen_mov_mem8Reg64_imm8(x64GenContext, X86_REG_RSP, offsetof(PPCInterpreter_t, cr) + sizeof(uint8)*(crRegister * 4 + PPCREC_CR_BIT_GT), 0);
x64Gen_mov_mem8Reg64_imm8(x64GenContext, REG_RSP, offsetof(PPCInterpreter_t, cr) + sizeof(uint8)*(crRegister * 4 + PPCREC_CR_BIT_EQ), 0); x64Gen_mov_mem8Reg64_imm8(x64GenContext, X86_REG_RSP, offsetof(PPCInterpreter_t, cr) + sizeof(uint8)*(crRegister * 4 + PPCREC_CR_BIT_EQ), 0);
// calculate effective address // calculate effective address
x64Gen_mov_reg64_reg64(x64GenContext, REG_RESV_TEMP, realRegisterData); x64Gen_mov_reg64_reg64(x64GenContext, REG_RESV_TEMP, realRegisterData);
if (swapEndian) if (swapEndian)
@ -541,32 +541,32 @@ bool PPCRecompilerX64Gen_imlInstruction_store(PPCRecFunction_t* PPCRecFunction,
x64Gen_jmpc_near(x64GenContext, X86_CONDITION_NOT_EQUAL, 0); x64Gen_jmpc_near(x64GenContext, X86_CONDITION_NOT_EQUAL, 0);
// EA matches reservation // EA matches reservation
// backup EAX (since it's an explicit operand of CMPXCHG and will be overwritten) // backup EAX (since it's an explicit operand of CMPXCHG and will be overwritten)
x64Emit_mov_mem32_reg32(x64GenContext, REG_RSP, (uint32)offsetof(PPCInterpreter_t, temporaryGPR[0]), REG_EAX); x64Emit_mov_mem32_reg32(x64GenContext, X86_REG_RSP, (uint32)offsetof(PPCInterpreter_t, temporaryGPR[0]), X86_REG_EAX);
// backup REG_RESV_MEMBASE // backup REG_RESV_MEMBASE
x64Emit_mov_mem64_reg64(x64GenContext, REG_RESV_HCPU, (uint32)offsetof(PPCInterpreter_t, temporaryGPR[2]), REG_RESV_MEMBASE); x64Emit_mov_mem64_reg64(x64GenContext, REG_RESV_HCPU, (uint32)offsetof(PPCInterpreter_t, temporaryGPR[2]), REG_RESV_MEMBASE);
// add mem register to REG_RESV_MEMBASE // add mem register to REG_RESV_MEMBASE
x64Gen_add_reg64_reg64(x64GenContext, REG_RESV_MEMBASE, realRegisterMem); x64Gen_add_reg64_reg64(x64GenContext, REG_RESV_MEMBASE, realRegisterMem);
// load reserved value in EAX // load reserved value in EAX
x64Emit_mov_reg64_mem32(x64GenContext, REG_EAX, REG_RESV_HCPU, offsetof(PPCInterpreter_t, reservedMemValue)); x64Emit_mov_reg64_mem32(x64GenContext, X86_REG_EAX, REG_RESV_HCPU, offsetof(PPCInterpreter_t, reservedMemValue));
// bswap EAX // bswap EAX
x64Gen_bswap_reg64Lower32bit(x64GenContext, REG_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_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_lock_cmpxchg_mem32Reg64_reg64(x64GenContext, REG_RESV_MEMBASE, 0, REG_RESV_TEMP);
x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_EQUAL, REG_RSP, offsetof(PPCInterpreter_t, cr) + sizeof(uint8)*(crRegister * 4 + PPCREC_CR_BIT_EQ)); x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_EQUAL, X86_REG_RSP, offsetof(PPCInterpreter_t, cr) + sizeof(uint8)*(crRegister * 4 + PPCREC_CR_BIT_EQ));
// reset reservation // reset reservation
x64Gen_mov_mem32Reg64_imm32(x64GenContext, REG_RESV_HCPU, (uint32)offsetof(PPCInterpreter_t, reservedMemAddr), 0); x64Gen_mov_mem32Reg64_imm32(x64GenContext, REG_RESV_HCPU, (uint32)offsetof(PPCInterpreter_t, reservedMemAddr), 0);
x64Gen_mov_mem32Reg64_imm32(x64GenContext, REG_RESV_HCPU, (uint32)offsetof(PPCInterpreter_t, reservedMemValue), 0); x64Gen_mov_mem32Reg64_imm32(x64GenContext, REG_RESV_HCPU, (uint32)offsetof(PPCInterpreter_t, reservedMemValue), 0);
// restore EAX // restore EAX
x64Emit_mov_reg64_mem32(x64GenContext, REG_EAX, REG_RESV_HCPU, (uint32)offsetof(PPCInterpreter_t, temporaryGPR[0])); x64Emit_mov_reg64_mem32(x64GenContext, X86_REG_EAX, REG_RESV_HCPU, (uint32)offsetof(PPCInterpreter_t, temporaryGPR[0]));
// restore REG_RESV_MEMBASE // restore REG_RESV_MEMBASE
x64Emit_mov_reg64_mem64(x64GenContext, REG_RESV_MEMBASE, REG_RESV_HCPU, (uint32)offsetof(PPCInterpreter_t, temporaryGPR[2])); x64Emit_mov_reg64_mem64(x64GenContext, REG_RESV_MEMBASE, REG_RESV_HCPU, (uint32)offsetof(PPCInterpreter_t, temporaryGPR[2]));
// copy XER SO to CR0 SO // copy XER SO to CR0 SO
x64Gen_bt_mem8(x64GenContext, REG_RSP, offsetof(PPCInterpreter_t, spr.XER), 31); x64Gen_bt_mem8(x64GenContext, X86_REG_RSP, offsetof(PPCInterpreter_t, spr.XER), 31);
x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_CARRY, REG_RESV_HCPU, offsetof(PPCInterpreter_t, cr) + sizeof(uint8)*(crRegister * 4 + PPCREC_CR_BIT_SO)); x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_CARRY, REG_RESV_HCPU, offsetof(PPCInterpreter_t, cr) + sizeof(uint8)*(crRegister * 4 + PPCREC_CR_BIT_SO));
// end // end
PPCRecompilerX64Gen_redirectRelativeJump(x64GenContext, jumpInstructionOffsetJumpToEnd, x64GenContext->codeBufferIndex); PPCRecompilerX64Gen_redirectRelativeJump(x64GenContext, jumpInstructionOffsetJumpToEnd, x64GenContext->codeBufferIndex);
@ -726,21 +726,21 @@ bool PPCRecompilerX64Gen_imlInstruction_r_r(PPCRecFunction_t* PPCRecFunction, pp
if( imlInstruction->operation == PPCREC_IML_OP_COMPARE_SIGNED ) if( imlInstruction->operation == PPCREC_IML_OP_COMPARE_SIGNED )
{ {
if( (imlInstruction->crIgnoreMask&(1<<(crRegister*4+PPCREC_CR_BIT_LT))) == 0 ) if( (imlInstruction->crIgnoreMask&(1<<(crRegister*4+PPCREC_CR_BIT_LT))) == 0 )
x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_SIGNED_LESS, REG_ESP, offsetof(PPCInterpreter_t, cr)+sizeof(uint8)*(crRegister*4+PPCREC_CR_BIT_LT)); x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_SIGNED_LESS, X86_REG_ESP, offsetof(PPCInterpreter_t, cr)+sizeof(uint8)*(crRegister*4+PPCREC_CR_BIT_LT));
if( (imlInstruction->crIgnoreMask&(1<<(crRegister*4+PPCREC_CR_BIT_GT))) == 0 ) if( (imlInstruction->crIgnoreMask&(1<<(crRegister*4+PPCREC_CR_BIT_GT))) == 0 )
x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_SIGNED_GREATER, REG_ESP, offsetof(PPCInterpreter_t, cr)+sizeof(uint8)*(crRegister*4+PPCREC_CR_BIT_GT)); x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_SIGNED_GREATER, X86_REG_ESP, offsetof(PPCInterpreter_t, cr)+sizeof(uint8)*(crRegister*4+PPCREC_CR_BIT_GT));
if( (imlInstruction->crIgnoreMask&(1<<(crRegister*4+PPCREC_CR_BIT_EQ))) == 0 ) if( (imlInstruction->crIgnoreMask&(1<<(crRegister*4+PPCREC_CR_BIT_EQ))) == 0 )
x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_EQUAL, REG_ESP, offsetof(PPCInterpreter_t, cr)+sizeof(uint8)*(crRegister*4+PPCREC_CR_BIT_EQ)); x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_EQUAL, X86_REG_ESP, offsetof(PPCInterpreter_t, cr)+sizeof(uint8)*(crRegister*4+PPCREC_CR_BIT_EQ));
// todo: Also set summary overflow if xer bit is set // todo: Also set summary overflow if xer bit is set
} }
else if( imlInstruction->operation == PPCREC_IML_OP_COMPARE_UNSIGNED ) else if( imlInstruction->operation == PPCREC_IML_OP_COMPARE_UNSIGNED )
{ {
if( (imlInstruction->crIgnoreMask&(1<<(crRegister*4+PPCREC_CR_BIT_LT))) == 0 ) if( (imlInstruction->crIgnoreMask&(1<<(crRegister*4+PPCREC_CR_BIT_LT))) == 0 )
x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_UNSIGNED_BELOW, REG_ESP, offsetof(PPCInterpreter_t, cr)+sizeof(uint8)*(crRegister*4+PPCREC_CR_BIT_LT)); x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_UNSIGNED_BELOW, X86_REG_ESP, offsetof(PPCInterpreter_t, cr)+sizeof(uint8)*(crRegister*4+PPCREC_CR_BIT_LT));
if( (imlInstruction->crIgnoreMask&(1<<(crRegister*4+PPCREC_CR_BIT_GT))) == 0 ) if( (imlInstruction->crIgnoreMask&(1<<(crRegister*4+PPCREC_CR_BIT_GT))) == 0 )
x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_UNSIGNED_ABOVE, REG_ESP, offsetof(PPCInterpreter_t, cr)+sizeof(uint8)*(crRegister*4+PPCREC_CR_BIT_GT)); x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_UNSIGNED_ABOVE, X86_REG_ESP, offsetof(PPCInterpreter_t, cr)+sizeof(uint8)*(crRegister*4+PPCREC_CR_BIT_GT));
if( (imlInstruction->crIgnoreMask&(1<<(crRegister*4+PPCREC_CR_BIT_EQ))) == 0 ) if( (imlInstruction->crIgnoreMask&(1<<(crRegister*4+PPCREC_CR_BIT_EQ))) == 0 )
x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_EQUAL, REG_ESP, offsetof(PPCInterpreter_t, cr)+sizeof(uint8)*(crRegister*4+PPCREC_CR_BIT_EQ)); x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_EQUAL, X86_REG_ESP, offsetof(PPCInterpreter_t, cr)+sizeof(uint8)*(crRegister*4+PPCREC_CR_BIT_EQ));
// todo: Also set summary overflow if xer bit is set // todo: Also set summary overflow if xer bit is set
} }
else else
@ -772,18 +772,18 @@ bool PPCRecompilerX64Gen_imlInstruction_r_r(PPCRecFunction_t* PPCRecFunction, pp
x64Gen_mov_reg64_reg64(x64GenContext, imlInstruction->op_r_r.registerResult, imlInstruction->op_r_r.registerA); x64Gen_mov_reg64_reg64(x64GenContext, imlInstruction->op_r_r.registerResult, imlInstruction->op_r_r.registerA);
} }
// copy xer_ca to eflags carry // copy xer_ca to eflags carry
x64Gen_bt_mem8(x64GenContext, REG_RSP, offsetof(PPCInterpreter_t, xer_ca), 0); x64Gen_bt_mem8(x64GenContext, X86_REG_RSP, offsetof(PPCInterpreter_t, xer_ca), 0);
// add carry bit // add carry bit
x64Gen_adc_reg64Low32_imm32(x64GenContext, imlInstruction->op_r_r.registerResult, 0); x64Gen_adc_reg64Low32_imm32(x64GenContext, imlInstruction->op_r_r.registerResult, 0);
// update xer carry // update xer carry
x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_CARRY, REG_RSP, offsetof(PPCInterpreter_t, xer_ca)); x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_CARRY, X86_REG_RSP, offsetof(PPCInterpreter_t, xer_ca));
if( imlInstruction->crRegister != PPC_REC_INVALID_REGISTER ) if( imlInstruction->crRegister != PPC_REC_INVALID_REGISTER )
{ {
// set cr bits // set cr bits
sint32 crRegister = imlInstruction->crRegister; sint32 crRegister = imlInstruction->crRegister;
x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_SIGN, 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_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, REG_RSP, offsetof(PPCInterpreter_t, cr)+sizeof(uint8)*(crRegister*4+PPCREC_CR_BIT_GT)); 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, REG_RSP, offsetof(PPCInterpreter_t, cr)+sizeof(uint8)*(crRegister*4+PPCREC_CR_BIT_EQ)); 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: Use different version of PPCRecompilerX64Gen_updateCRLogical(PPCRecFunction, ppcImlGenContext, x64GenContext, imlInstruction)
// todo: Also set summary overflow if xer bit is set // todo: Also set summary overflow if xer bit is set
} }
@ -797,11 +797,11 @@ bool PPCRecompilerX64Gen_imlInstruction_r_r(PPCRecFunction_t* PPCRecFunction, pp
x64Gen_mov_reg64_reg64(x64GenContext, imlInstruction->op_r_r.registerResult, imlInstruction->op_r_r.registerA); x64Gen_mov_reg64_reg64(x64GenContext, imlInstruction->op_r_r.registerResult, imlInstruction->op_r_r.registerA);
} }
// copy xer_ca to eflags carry // copy xer_ca to eflags carry
x64Gen_bt_mem8(x64GenContext, REG_RSP, offsetof(PPCInterpreter_t, xer_ca), 0); x64Gen_bt_mem8(x64GenContext, X86_REG_RSP, offsetof(PPCInterpreter_t, xer_ca), 0);
// add carry bit // add carry bit
x64Gen_adc_reg64Low32_imm32(x64GenContext, imlInstruction->op_r_r.registerResult, (uint32)-1); x64Gen_adc_reg64Low32_imm32(x64GenContext, imlInstruction->op_r_r.registerResult, (uint32)-1);
// update xer carry // update xer carry
x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_CARRY, REG_RSP, offsetof(PPCInterpreter_t, xer_ca)); x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_CARRY, X86_REG_RSP, offsetof(PPCInterpreter_t, xer_ca));
if( imlInstruction->crRegister != PPC_REC_INVALID_REGISTER ) if( imlInstruction->crRegister != PPC_REC_INVALID_REGISTER )
{ {
// set cr bits // set cr bits
@ -821,11 +821,11 @@ bool PPCRecompilerX64Gen_imlInstruction_r_r(PPCRecFunction_t* PPCRecFunction, pp
// execute NOT on result // execute NOT on result
x64Gen_not_reg64Low32(x64GenContext, rRegResult); x64Gen_not_reg64Low32(x64GenContext, rRegResult);
// copy xer_ca to eflags carry // copy xer_ca to eflags carry
x64Gen_bt_mem8(x64GenContext, REG_RSP, offsetof(PPCInterpreter_t, xer_ca), 0); x64Gen_bt_mem8(x64GenContext, X86_REG_RSP, offsetof(PPCInterpreter_t, xer_ca), 0);
// add carry // add carry
x64Gen_adc_reg64Low32_imm32(x64GenContext, rRegResult, 0); x64Gen_adc_reg64Low32_imm32(x64GenContext, rRegResult, 0);
// update carry // update carry
x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_CARRY, REG_RSP, offsetof(PPCInterpreter_t, xer_ca)); x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_CARRY, X86_REG_RSP, offsetof(PPCInterpreter_t, xer_ca));
// update cr if requested // update cr if requested
if( imlInstruction->crRegister != PPC_REC_INVALID_REGISTER ) if( imlInstruction->crRegister != PPC_REC_INVALID_REGISTER )
{ {
@ -990,20 +990,20 @@ bool PPCRecompilerX64Gen_imlInstruction_r_s32(PPCRecFunction_t* PPCRecFunction,
if( imlInstruction->operation == PPCREC_IML_OP_COMPARE_SIGNED ) if( imlInstruction->operation == PPCREC_IML_OP_COMPARE_SIGNED )
{ {
if( (imlInstruction->crIgnoreMask&(1<<(crRegister*4+PPCREC_CR_BIT_LT))) == 0 ) if( (imlInstruction->crIgnoreMask&(1<<(crRegister*4+PPCREC_CR_BIT_LT))) == 0 )
x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_SIGNED_LESS, REG_ESP, offsetof(PPCInterpreter_t, cr)+sizeof(uint8)*(crRegister*4+PPCREC_CR_BIT_LT)); x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_SIGNED_LESS, X86_REG_ESP, offsetof(PPCInterpreter_t, cr)+sizeof(uint8)*(crRegister*4+PPCREC_CR_BIT_LT));
if( (imlInstruction->crIgnoreMask&(1<<(crRegister*4+PPCREC_CR_BIT_GT))) == 0 ) if( (imlInstruction->crIgnoreMask&(1<<(crRegister*4+PPCREC_CR_BIT_GT))) == 0 )
x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_SIGNED_GREATER, REG_ESP, offsetof(PPCInterpreter_t, cr)+sizeof(uint8)*(crRegister*4+PPCREC_CR_BIT_GT)); x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_SIGNED_GREATER, X86_REG_ESP, offsetof(PPCInterpreter_t, cr)+sizeof(uint8)*(crRegister*4+PPCREC_CR_BIT_GT));
if( (imlInstruction->crIgnoreMask&(1<<(crRegister*4+PPCREC_CR_BIT_EQ))) == 0 ) if( (imlInstruction->crIgnoreMask&(1<<(crRegister*4+PPCREC_CR_BIT_EQ))) == 0 )
x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_EQUAL, REG_ESP, offsetof(PPCInterpreter_t, cr)+sizeof(uint8)*(crRegister*4+PPCREC_CR_BIT_EQ)); x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_EQUAL, X86_REG_ESP, offsetof(PPCInterpreter_t, cr)+sizeof(uint8)*(crRegister*4+PPCREC_CR_BIT_EQ));
} }
else if( imlInstruction->operation == PPCREC_IML_OP_COMPARE_UNSIGNED ) else if( imlInstruction->operation == PPCREC_IML_OP_COMPARE_UNSIGNED )
{ {
if( (imlInstruction->crIgnoreMask&(1<<(crRegister*4+PPCREC_CR_BIT_LT))) == 0 ) if( (imlInstruction->crIgnoreMask&(1<<(crRegister*4+PPCREC_CR_BIT_LT))) == 0 )
x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_UNSIGNED_BELOW, REG_ESP, offsetof(PPCInterpreter_t, cr)+sizeof(uint8)*(crRegister*4+PPCREC_CR_BIT_LT)); x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_UNSIGNED_BELOW, X86_REG_ESP, offsetof(PPCInterpreter_t, cr)+sizeof(uint8)*(crRegister*4+PPCREC_CR_BIT_LT));
if( (imlInstruction->crIgnoreMask&(1<<(crRegister*4+PPCREC_CR_BIT_GT))) == 0 ) if( (imlInstruction->crIgnoreMask&(1<<(crRegister*4+PPCREC_CR_BIT_GT))) == 0 )
x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_UNSIGNED_ABOVE, REG_ESP, offsetof(PPCInterpreter_t, cr)+sizeof(uint8)*(crRegister*4+PPCREC_CR_BIT_GT)); x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_UNSIGNED_ABOVE, X86_REG_ESP, offsetof(PPCInterpreter_t, cr)+sizeof(uint8)*(crRegister*4+PPCREC_CR_BIT_GT));
if( (imlInstruction->crIgnoreMask&(1<<(crRegister*4+PPCREC_CR_BIT_EQ))) == 0 ) if( (imlInstruction->crIgnoreMask&(1<<(crRegister*4+PPCREC_CR_BIT_EQ))) == 0 )
x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_EQUAL, REG_ESP, offsetof(PPCInterpreter_t, cr)+sizeof(uint8)*(crRegister*4+PPCREC_CR_BIT_EQ)); x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_EQUAL, X86_REG_ESP, offsetof(PPCInterpreter_t, cr)+sizeof(uint8)*(crRegister*4+PPCREC_CR_BIT_EQ));
} }
else else
assert_dbg(); assert_dbg();
@ -1016,7 +1016,7 @@ bool PPCRecompilerX64Gen_imlInstruction_r_s32(PPCRecFunction_t* PPCRecFunction,
x64Gen_xor_reg64Low32_reg64Low32(x64GenContext, destRegister, destRegister); x64Gen_xor_reg64Low32_reg64Low32(x64GenContext, destRegister, destRegister);
for(sint32 f=0; f<32; f++) for(sint32 f=0; f<32; f++)
{ {
x64Gen_bt_mem8(x64GenContext, REG_RSP, offsetof(PPCInterpreter_t, cr)+f, 0); x64Gen_bt_mem8(x64GenContext, X86_REG_RSP, offsetof(PPCInterpreter_t, cr)+f, 0);
x64Gen_adc_reg64Low32_reg64Low32(x64GenContext, destRegister, destRegister); x64Gen_adc_reg64Low32_reg64Low32(x64GenContext, destRegister, destRegister);
} }
} }
@ -1029,9 +1029,9 @@ bool PPCRecompilerX64Gen_imlInstruction_r_s32(PPCRecFunction_t* PPCRecFunction,
{ {
if(((crBitMask >> f) & 1) == 0) if(((crBitMask >> f) & 1) == 0)
continue; continue;
x64Gen_mov_mem8Reg64_imm8(x64GenContext, REG_ESP, offsetof(PPCInterpreter_t, cr) + sizeof(uint8) * (f), 0); x64Gen_mov_mem8Reg64_imm8(x64GenContext, X86_REG_ESP, offsetof(PPCInterpreter_t, cr) + sizeof(uint8) * (f), 0);
x64Gen_test_reg64Low32_imm32(x64GenContext, srcRegister, 0x80000000>>f); x64Gen_test_reg64Low32_imm32(x64GenContext, srcRegister, 0x80000000>>f);
x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_NOT_EQUAL, REG_ESP, offsetof(PPCInterpreter_t, cr) + sizeof(uint8) * (f)); x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_NOT_EQUAL, X86_REG_ESP, offsetof(PPCInterpreter_t, cr) + sizeof(uint8) * (f));
} }
} }
else else
@ -1113,7 +1113,7 @@ bool PPCRecompilerX64Gen_imlInstruction_conditional_r_s32(PPCRecFunction_t* PPCR
} }
} }
PPCRecompilerX64Gen_crConditionFlags_forget(PPCRecFunction, ppcImlGenContext, x64GenContext); PPCRecompilerX64Gen_crConditionFlags_forget(PPCRecFunction, ppcImlGenContext, x64GenContext);
x64Gen_bt_mem8(x64GenContext, REG_RSP, offsetof(PPCInterpreter_t, cr) + crBitIndex * sizeof(uint8), 0); x64Gen_bt_mem8(x64GenContext, X86_REG_RSP, offsetof(PPCInterpreter_t, cr) + crBitIndex * sizeof(uint8), 0);
if (imlInstruction->op_conditional_r_s32.bitMustBeSet) if (imlInstruction->op_conditional_r_s32.bitMustBeSet)
x64Gen_cmovcc_reg64Low32_reg64Low32(x64GenContext, X86_CONDITION_CARRY, imlInstruction->op_conditional_r_s32.registerIndex, REG_RESV_TEMP); x64Gen_cmovcc_reg64Low32_reg64Low32(x64GenContext, X86_CONDITION_CARRY, imlInstruction->op_conditional_r_s32.registerIndex, REG_RESV_TEMP);
else else
@ -1141,7 +1141,7 @@ bool PPCRecompilerX64Gen_imlInstruction_r_r_r(PPCRecFunction_t* PPCRecFunction,
{ {
if( addCarry ) if( addCarry )
{ {
x64Gen_bt_mem8(x64GenContext, REG_RSP, offsetof(PPCInterpreter_t, xer_ca), 0); x64Gen_bt_mem8(x64GenContext, X86_REG_RSP, offsetof(PPCInterpreter_t, xer_ca), 0);
x64Gen_adc_reg64Low32_reg64Low32(x64GenContext, rRegResult, rRegOperand2); x64Gen_adc_reg64Low32_reg64Low32(x64GenContext, rRegResult, rRegOperand2);
} }
else else
@ -1151,7 +1151,7 @@ bool PPCRecompilerX64Gen_imlInstruction_r_r_r(PPCRecFunction_t* PPCRecFunction,
{ {
if( addCarry ) if( addCarry )
{ {
x64Gen_bt_mem8(x64GenContext, REG_RSP, offsetof(PPCInterpreter_t, xer_ca), 0); x64Gen_bt_mem8(x64GenContext, X86_REG_RSP, offsetof(PPCInterpreter_t, xer_ca), 0);
x64Gen_adc_reg64Low32_reg64Low32(x64GenContext, rRegResult, rRegOperand1); x64Gen_adc_reg64Low32_reg64Low32(x64GenContext, rRegResult, rRegOperand1);
} }
else else
@ -1165,7 +1165,7 @@ bool PPCRecompilerX64Gen_imlInstruction_r_r_r(PPCRecFunction_t* PPCRecFunction,
// add operand2 // add operand2
if( addCarry ) if( addCarry )
{ {
x64Gen_bt_mem8(x64GenContext, REG_RSP, offsetof(PPCInterpreter_t, xer_ca), 0); x64Gen_bt_mem8(x64GenContext, X86_REG_RSP, offsetof(PPCInterpreter_t, xer_ca), 0);
x64Gen_adc_reg64Low32_reg64Low32(x64GenContext, rRegResult, rRegOperand2); x64Gen_adc_reg64Low32_reg64Low32(x64GenContext, rRegResult, rRegOperand2);
} }
else else
@ -1174,7 +1174,7 @@ bool PPCRecompilerX64Gen_imlInstruction_r_r_r(PPCRecFunction_t* PPCRecFunction,
// update carry // update carry
if( imlInstruction->operation == PPCREC_IML_OP_ADD_UPDATE_CARRY || imlInstruction->operation == PPCREC_IML_OP_ADD_CARRY_UPDATE_CARRY ) if( imlInstruction->operation == PPCREC_IML_OP_ADD_UPDATE_CARRY || imlInstruction->operation == PPCREC_IML_OP_ADD_CARRY_UPDATE_CARRY )
{ {
x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_CARRY, REG_RSP, offsetof(PPCInterpreter_t, xer_ca)); x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_CARRY, X86_REG_RSP, offsetof(PPCInterpreter_t, xer_ca));
} }
// set cr bits if enabled // set cr bits if enabled
if( imlInstruction->crRegister != PPC_REC_INVALID_REGISTER ) if( imlInstruction->crRegister != PPC_REC_INVALID_REGISTER )
@ -1242,7 +1242,7 @@ bool PPCRecompilerX64Gen_imlInstruction_r_r_r(PPCRecFunction_t* PPCRecFunction,
if( rRegOperand1 == rRegOperand2 ) if( rRegOperand1 == rRegOperand2 )
{ {
// copy xer_ca to eflags carry // copy xer_ca to eflags carry
x64Gen_bt_mem8(x64GenContext, REG_RSP, offsetof(PPCInterpreter_t, xer_ca), 0); x64Gen_bt_mem8(x64GenContext, X86_REG_RSP, offsetof(PPCInterpreter_t, xer_ca), 0);
x64Gen_cmc(x64GenContext); x64Gen_cmc(x64GenContext);
// result = operand1 - operand1 -> 0 // result = operand1 - operand1 -> 0
x64Gen_sbb_reg64Low32_reg64Low32(x64GenContext, rRegResult, rRegResult); x64Gen_sbb_reg64Low32_reg64Low32(x64GenContext, rRegResult, rRegResult);
@ -1250,7 +1250,7 @@ bool PPCRecompilerX64Gen_imlInstruction_r_r_r(PPCRecFunction_t* PPCRecFunction,
else if( rRegResult == rRegOperand1 ) else if( rRegResult == rRegOperand1 )
{ {
// copy inverted xer_ca to eflags carry // copy inverted xer_ca to eflags carry
x64Gen_bt_mem8(x64GenContext, REG_RSP, offsetof(PPCInterpreter_t, xer_ca), 0); x64Gen_bt_mem8(x64GenContext, X86_REG_RSP, offsetof(PPCInterpreter_t, xer_ca), 0);
x64Gen_cmc(x64GenContext); x64Gen_cmc(x64GenContext);
// result = result - operand2 // result = result - operand2
x64Gen_sbb_reg64Low32_reg64Low32(x64GenContext, rRegResult, rRegOperand2); x64Gen_sbb_reg64Low32_reg64Low32(x64GenContext, rRegResult, rRegOperand2);
@ -1261,7 +1261,7 @@ bool PPCRecompilerX64Gen_imlInstruction_r_r_r(PPCRecFunction_t* PPCRecFunction,
// NOT result // NOT result
x64Gen_not_reg64Low32(x64GenContext, rRegResult); x64Gen_not_reg64Low32(x64GenContext, rRegResult);
// copy xer_ca to eflags carry // copy xer_ca to eflags carry
x64Gen_bt_mem8(x64GenContext, REG_RSP, offsetof(PPCInterpreter_t, xer_ca), 0); x64Gen_bt_mem8(x64GenContext, X86_REG_RSP, offsetof(PPCInterpreter_t, xer_ca), 0);
// ADC result, operand1 // ADC result, operand1
x64Gen_adc_reg64Low32_reg64Low32(x64GenContext, rRegResult, rRegOperand1); x64Gen_adc_reg64Low32_reg64Low32(x64GenContext, rRegResult, rRegOperand1);
} }
@ -1270,13 +1270,13 @@ bool PPCRecompilerX64Gen_imlInstruction_r_r_r(PPCRecFunction_t* PPCRecFunction,
// copy operand1 to destination register before doing addition // copy operand1 to destination register before doing addition
x64Gen_mov_reg64_reg64(x64GenContext, rRegResult, rRegOperand1); x64Gen_mov_reg64_reg64(x64GenContext, rRegResult, rRegOperand1);
// copy xer_ca to eflags carry // copy xer_ca to eflags carry
x64Gen_bt_mem8(x64GenContext, REG_RSP, offsetof(PPCInterpreter_t, xer_ca), 0); x64Gen_bt_mem8(x64GenContext, X86_REG_RSP, offsetof(PPCInterpreter_t, xer_ca), 0);
x64Gen_cmc(x64GenContext); x64Gen_cmc(x64GenContext);
// sub operand2 // sub operand2
x64Gen_sbb_reg64Low32_reg64Low32(x64GenContext, rRegResult, rRegOperand2); x64Gen_sbb_reg64Low32_reg64Low32(x64GenContext, rRegResult, rRegOperand2);
} }
// update carry flag (todo: is this actually correct in all cases?) // update carry flag (todo: is this actually correct in all cases?)
x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_CARRY, REG_RSP, offsetof(PPCInterpreter_t, xer_ca)); x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_CARRY, X86_REG_RSP, offsetof(PPCInterpreter_t, xer_ca));
// update cr0 if requested // update cr0 if requested
if( imlInstruction->crRegister != PPC_REC_INVALID_REGISTER ) if( imlInstruction->crRegister != PPC_REC_INVALID_REGISTER )
{ {
@ -1341,7 +1341,7 @@ bool PPCRecompilerX64Gen_imlInstruction_r_r_r(PPCRecFunction_t* PPCRecFunction,
// return true; // return true;
//} //}
// set carry to zero // set carry to zero
x64Gen_mov_mem8Reg64_imm8(x64GenContext, REG_RSP, offsetof(PPCInterpreter_t, xer_ca), 0); x64Gen_mov_mem8Reg64_imm8(x64GenContext, X86_REG_RSP, offsetof(PPCInterpreter_t, xer_ca), 0);
// ((~a+b)<~a) == true -> ca = 1 // ((~a+b)<~a) == true -> ca = 1
x64Gen_mov_reg64_reg64(x64GenContext, REG_RESV_TEMP, rRegOperandA); x64Gen_mov_reg64_reg64(x64GenContext, REG_RESV_TEMP, rRegOperandA);
x64Gen_not_reg64Low32(x64GenContext, REG_RESV_TEMP); x64Gen_not_reg64Low32(x64GenContext, REG_RESV_TEMP);
@ -1352,7 +1352,7 @@ bool PPCRecompilerX64Gen_imlInstruction_r_r_r(PPCRecFunction_t* PPCRecFunction,
sint32 jumpInstructionOffset1 = x64GenContext->codeBufferIndex; sint32 jumpInstructionOffset1 = x64GenContext->codeBufferIndex;
x64Gen_jmpc_near(x64GenContext, X86_CONDITION_UNSIGNED_ABOVE_EQUAL, 0); x64Gen_jmpc_near(x64GenContext, X86_CONDITION_UNSIGNED_ABOVE_EQUAL, 0);
// reset carry flag + jump destination afterwards // reset carry flag + jump destination afterwards
x64Gen_mov_mem8Reg64_imm8(x64GenContext, REG_RSP, offsetof(PPCInterpreter_t, xer_ca), 1); x64Gen_mov_mem8Reg64_imm8(x64GenContext, X86_REG_RSP, offsetof(PPCInterpreter_t, xer_ca), 1);
PPCRecompilerX64Gen_redirectRelativeJump(x64GenContext, jumpInstructionOffset1, x64GenContext->codeBufferIndex); PPCRecompilerX64Gen_redirectRelativeJump(x64GenContext, jumpInstructionOffset1, x64GenContext->codeBufferIndex);
// OR ((~a+b+1)<1) == true -> ca = 1 // OR ((~a+b+1)<1) == true -> ca = 1
x64Gen_mov_reg64_reg64(x64GenContext, REG_RESV_TEMP, rRegOperandA); x64Gen_mov_reg64_reg64(x64GenContext, REG_RESV_TEMP, rRegOperandA);
@ -1364,7 +1364,7 @@ bool PPCRecompilerX64Gen_imlInstruction_r_r_r(PPCRecFunction_t* PPCRecFunction,
sint32 jumpInstructionOffset2 = x64GenContext->codeBufferIndex; sint32 jumpInstructionOffset2 = x64GenContext->codeBufferIndex;
x64Gen_jmpc_near(x64GenContext, X86_CONDITION_UNSIGNED_ABOVE_EQUAL, 0); x64Gen_jmpc_near(x64GenContext, X86_CONDITION_UNSIGNED_ABOVE_EQUAL, 0);
// reset carry flag + jump destination afterwards // reset carry flag + jump destination afterwards
x64Gen_mov_mem8Reg64_imm8(x64GenContext, REG_RSP, offsetof(PPCInterpreter_t, xer_ca), 1); x64Gen_mov_mem8Reg64_imm8(x64GenContext, X86_REG_RSP, offsetof(PPCInterpreter_t, xer_ca), 1);
PPCRecompilerX64Gen_redirectRelativeJump(x64GenContext, jumpInstructionOffset2, x64GenContext->codeBufferIndex); PPCRecompilerX64Gen_redirectRelativeJump(x64GenContext, jumpInstructionOffset2, x64GenContext->codeBufferIndex);
// do subtraction // do subtraction
if( rRegOperandB == rRegOperandA ) if( rRegOperandB == rRegOperandA )
@ -1455,16 +1455,16 @@ bool PPCRecompilerX64Gen_imlInstruction_r_r_r(PPCRecFunction_t* PPCRecFunction,
sint32 rRegOperand2 = imlInstruction->op_r_r_r.registerB; sint32 rRegOperand2 = imlInstruction->op_r_r_r.registerB;
// todo: Use BMI2 rotate if available // todo: Use BMI2 rotate if available
// check if CL/ECX/RCX is available // check if CL/ECX/RCX is available
if( rRegResult != REG_RCX && rRegOperand1 != REG_RCX && rRegOperand2 != REG_RCX ) if( rRegResult != X86_REG_RCX && rRegOperand1 != X86_REG_RCX && rRegOperand2 != X86_REG_RCX )
{ {
// swap operand 2 with RCX // swap operand 2 with RCX
x64Gen_xchg_reg64_reg64(x64GenContext, REG_RCX, rRegOperand2); x64Gen_xchg_reg64_reg64(x64GenContext, X86_REG_RCX, rRegOperand2);
// move operand 1 to temp register // move operand 1 to temp register
x64Gen_mov_reg64_reg64(x64GenContext, REG_RESV_TEMP, rRegOperand1); x64Gen_mov_reg64_reg64(x64GenContext, REG_RESV_TEMP, rRegOperand1);
// rotate // rotate
x64Gen_rol_reg64Low32_cl(x64GenContext, REG_RESV_TEMP); x64Gen_rol_reg64Low32_cl(x64GenContext, REG_RESV_TEMP);
// undo swap operand 2 with RCX // undo swap operand 2 with RCX
x64Gen_xchg_reg64_reg64(x64GenContext, REG_RCX, rRegOperand2); x64Gen_xchg_reg64_reg64(x64GenContext, X86_REG_RCX, rRegOperand2);
// copy to result register // copy to result register
x64Gen_mov_reg64_reg64(x64GenContext, rRegResult, REG_RESV_TEMP); x64Gen_mov_reg64_reg64(x64GenContext, rRegResult, REG_RESV_TEMP);
} }
@ -1509,7 +1509,7 @@ bool PPCRecompilerX64Gen_imlInstruction_r_r_r(PPCRecFunction_t* PPCRecFunction,
// MOV registerResult, registerOperand (if different) // MOV registerResult, registerOperand (if different)
x64Gen_mov_reg64_reg64(x64GenContext, REG_RESV_TEMP, rRegOperand1); x64Gen_mov_reg64_reg64(x64GenContext, REG_RESV_TEMP, rRegOperand1);
// reset carry // reset carry
x64Gen_mov_mem8Reg64_imm8(x64GenContext, REG_RSP, offsetof(PPCInterpreter_t, xer_ca), 0); x64Gen_mov_mem8Reg64_imm8(x64GenContext, X86_REG_RSP, offsetof(PPCInterpreter_t, xer_ca), 0);
// we use the same shift by register approach as in SLW/SRW, but we have to differentiate by signed/unsigned shift since it influences how the carry flag is set // we use the same shift by register approach as in SLW/SRW, but we have to differentiate by signed/unsigned shift since it influences how the carry flag is set
x64Gen_test_reg64Low32_imm32(x64GenContext, REG_RESV_TEMP, 0x80000000); x64Gen_test_reg64Low32_imm32(x64GenContext, REG_RESV_TEMP, 0x80000000);
sint32 jumpInstructionJumpToSignedShift = x64GenContext->codeBufferIndex; sint32 jumpInstructionJumpToSignedShift = x64GenContext->codeBufferIndex;
@ -1547,7 +1547,7 @@ bool PPCRecompilerX64Gen_imlInstruction_r_r_r(PPCRecFunction_t* PPCRecFunction,
x64Gen_test_reg64Low32_imm32(x64GenContext, REG_RESV_TEMP, (1<<(1<<b))-1); x64Gen_test_reg64Low32_imm32(x64GenContext, REG_RESV_TEMP, (1<<(1<<b))-1);
sint32 jumpInstructionJumpToAfterCa = x64GenContext->codeBufferIndex; sint32 jumpInstructionJumpToAfterCa = x64GenContext->codeBufferIndex;
x64Gen_jmpc_near(x64GenContext, X86_CONDITION_EQUAL, 0); // jump if no bit is set x64Gen_jmpc_near(x64GenContext, X86_CONDITION_EQUAL, 0); // jump if no bit is set
x64Gen_mov_mem8Reg64_imm8(x64GenContext, REG_RSP, offsetof(PPCInterpreter_t, xer_ca), 1); x64Gen_mov_mem8Reg64_imm8(x64GenContext, X86_REG_RSP, offsetof(PPCInterpreter_t, xer_ca), 1);
PPCRecompilerX64Gen_redirectRelativeJump(x64GenContext, jumpInstructionJumpToAfterCa, x64GenContext->codeBufferIndex); PPCRecompilerX64Gen_redirectRelativeJump(x64GenContext, jumpInstructionJumpToAfterCa, x64GenContext->codeBufferIndex);
// arithmetic shift // arithmetic shift
if( b == 5 ) if( b == 5 )
@ -1575,17 +1575,17 @@ bool PPCRecompilerX64Gen_imlInstruction_r_r_r(PPCRecFunction_t* PPCRecFunction,
sint32 rRegOperand1 = imlInstruction->op_r_r_r.registerA; sint32 rRegOperand1 = imlInstruction->op_r_r_r.registerA;
sint32 rRegOperand2 = imlInstruction->op_r_r_r.registerB; sint32 rRegOperand2 = imlInstruction->op_r_r_r.registerB;
x64Emit_mov_mem32_reg32(x64GenContext, REG_RSP, (uint32)offsetof(PPCInterpreter_t, temporaryGPR[0]), REG_EAX); x64Emit_mov_mem32_reg32(x64GenContext, X86_REG_RSP, (uint32)offsetof(PPCInterpreter_t, temporaryGPR[0]), X86_REG_EAX);
x64Emit_mov_mem32_reg32(x64GenContext, REG_RSP, (uint32)offsetof(PPCInterpreter_t, temporaryGPR[1]), REG_EDX); x64Emit_mov_mem32_reg32(x64GenContext, X86_REG_RSP, (uint32)offsetof(PPCInterpreter_t, temporaryGPR[1]), X86_REG_EDX);
// mov operand 2 to temp register // mov operand 2 to temp register
x64Gen_mov_reg64_reg64(x64GenContext, REG_RESV_TEMP, rRegOperand2); x64Gen_mov_reg64_reg64(x64GenContext, REG_RESV_TEMP, rRegOperand2);
// mov operand1 to EAX // mov operand1 to EAX
x64Gen_mov_reg64Low32_reg64Low32(x64GenContext, REG_EAX, rRegOperand1); x64Gen_mov_reg64Low32_reg64Low32(x64GenContext, X86_REG_EAX, rRegOperand1);
// sign or zero extend EAX to EDX:EAX based on division sign mode // sign or zero extend EAX to EDX:EAX based on division sign mode
if( imlInstruction->operation == PPCREC_IML_OP_DIVIDE_SIGNED ) if( imlInstruction->operation == PPCREC_IML_OP_DIVIDE_SIGNED )
x64Gen_cdq(x64GenContext); x64Gen_cdq(x64GenContext);
else else
x64Gen_xor_reg64Low32_reg64Low32(x64GenContext, REG_EDX, REG_EDX); x64Gen_xor_reg64Low32_reg64Low32(x64GenContext, X86_REG_EDX, X86_REG_EDX);
// make sure we avoid division by zero // make sure we avoid division by zero
x64Gen_test_reg64Low32_reg64Low32(x64GenContext, REG_RESV_TEMP, REG_RESV_TEMP); x64Gen_test_reg64Low32_reg64Low32(x64GenContext, REG_RESV_TEMP, REG_RESV_TEMP);
x64Gen_jmpc_near(x64GenContext, X86_CONDITION_EQUAL, 3); x64Gen_jmpc_near(x64GenContext, X86_CONDITION_EQUAL, 3);
@ -1595,13 +1595,13 @@ bool PPCRecompilerX64Gen_imlInstruction_r_r_r(PPCRecFunction_t* PPCRecFunction,
else else
x64Gen_div_reg64Low32(x64GenContext, REG_RESV_TEMP); x64Gen_div_reg64Low32(x64GenContext, REG_RESV_TEMP);
// result of division is now stored in EAX, move it to result register // result of division is now stored in EAX, move it to result register
if( rRegResult != REG_EAX ) if( rRegResult != X86_REG_EAX )
x64Gen_mov_reg64_reg64(x64GenContext, rRegResult, REG_EAX); x64Gen_mov_reg64_reg64(x64GenContext, rRegResult, X86_REG_EAX);
// restore EAX / EDX // restore EAX / EDX
if( rRegResult != REG_RAX ) if( rRegResult != X86_REG_RAX )
x64Emit_mov_reg64_mem32(x64GenContext, REG_EAX, REG_RSP, (uint32)offsetof(PPCInterpreter_t, temporaryGPR[0])); x64Emit_mov_reg64_mem32(x64GenContext, X86_REG_EAX, X86_REG_RSP, (uint32)offsetof(PPCInterpreter_t, temporaryGPR[0]));
if( rRegResult != REG_RDX ) if( rRegResult != X86_REG_RDX )
x64Emit_mov_reg64_mem32(x64GenContext, REG_EDX, REG_RSP, (uint32)offsetof(PPCInterpreter_t, temporaryGPR[1])); x64Emit_mov_reg64_mem32(x64GenContext, X86_REG_EDX, X86_REG_RSP, (uint32)offsetof(PPCInterpreter_t, temporaryGPR[1]));
// set cr bits if requested // set cr bits if requested
if( imlInstruction->crRegister != PPC_REC_INVALID_REGISTER ) if( imlInstruction->crRegister != PPC_REC_INVALID_REGISTER )
{ {
@ -1620,16 +1620,16 @@ bool PPCRecompilerX64Gen_imlInstruction_r_r_r(PPCRecFunction_t* PPCRecFunction,
sint32 rRegOperand1 = imlInstruction->op_r_r_r.registerA; sint32 rRegOperand1 = imlInstruction->op_r_r_r.registerA;
sint32 rRegOperand2 = imlInstruction->op_r_r_r.registerB; sint32 rRegOperand2 = imlInstruction->op_r_r_r.registerB;
x64Emit_mov_mem32_reg32(x64GenContext, REG_RSP, (uint32)offsetof(PPCInterpreter_t, temporaryGPR[0]), REG_EAX); x64Emit_mov_mem32_reg32(x64GenContext, X86_REG_RSP, (uint32)offsetof(PPCInterpreter_t, temporaryGPR[0]), X86_REG_EAX);
x64Emit_mov_mem32_reg32(x64GenContext, REG_RSP, (uint32)offsetof(PPCInterpreter_t, temporaryGPR[1]), REG_EDX); x64Emit_mov_mem32_reg32(x64GenContext, X86_REG_RSP, (uint32)offsetof(PPCInterpreter_t, temporaryGPR[1]), X86_REG_EDX);
// mov operand 2 to temp register // mov operand 2 to temp register
x64Gen_mov_reg64_reg64(x64GenContext, REG_RESV_TEMP, rRegOperand2); x64Gen_mov_reg64_reg64(x64GenContext, REG_RESV_TEMP, rRegOperand2);
// mov operand1 to EAX // mov operand1 to EAX
x64Gen_mov_reg64Low32_reg64Low32(x64GenContext, REG_EAX, rRegOperand1); x64Gen_mov_reg64Low32_reg64Low32(x64GenContext, X86_REG_EAX, rRegOperand1);
if( imlInstruction->operation == PPCREC_IML_OP_MULTIPLY_HIGH_SIGNED ) if( imlInstruction->operation == PPCREC_IML_OP_MULTIPLY_HIGH_SIGNED )
{ {
// zero extend EAX to EDX:EAX // zero extend EAX to EDX:EAX
x64Gen_xor_reg64Low32_reg64Low32(x64GenContext, REG_EDX, REG_EDX); x64Gen_xor_reg64Low32_reg64Low32(x64GenContext, X86_REG_EDX, X86_REG_EDX);
} }
else else
{ {
@ -1642,13 +1642,13 @@ bool PPCRecompilerX64Gen_imlInstruction_r_r_r(PPCRecFunction_t* PPCRecFunction,
else else
x64Gen_mul_reg64Low32(x64GenContext, REG_RESV_TEMP); x64Gen_mul_reg64Low32(x64GenContext, REG_RESV_TEMP);
// result of multiplication is now stored in EDX:EAX, move it to result register // result of multiplication is now stored in EDX:EAX, move it to result register
if( rRegResult != REG_EDX ) if( rRegResult != X86_REG_EDX )
x64Gen_mov_reg64_reg64(x64GenContext, rRegResult, REG_EDX); x64Gen_mov_reg64_reg64(x64GenContext, rRegResult, X86_REG_EDX);
// restore EAX / EDX // restore EAX / EDX
if( rRegResult != REG_RAX ) if( rRegResult != X86_REG_RAX )
x64Emit_mov_reg64_mem32(x64GenContext, REG_EAX, REG_RSP, (uint32)offsetof(PPCInterpreter_t, temporaryGPR[0])); x64Emit_mov_reg64_mem32(x64GenContext, X86_REG_EAX, X86_REG_RSP, (uint32)offsetof(PPCInterpreter_t, temporaryGPR[0]));
if( rRegResult != REG_RDX ) if( rRegResult != X86_REG_RDX )
x64Emit_mov_reg64_mem32(x64GenContext, REG_EDX, REG_RSP, (uint32)offsetof(PPCInterpreter_t, temporaryGPR[1])); x64Emit_mov_reg64_mem32(x64GenContext, X86_REG_EDX, X86_REG_RSP, (uint32)offsetof(PPCInterpreter_t, temporaryGPR[1]));
// set cr bits if requested // set cr bits if requested
if( imlInstruction->crRegister != PPC_REC_INVALID_REGISTER ) if( imlInstruction->crRegister != PPC_REC_INVALID_REGISTER )
{ {
@ -1724,7 +1724,7 @@ bool PPCRecompilerX64Gen_imlInstruction_r_r_s32(PPCRecFunction_t* PPCRecFunction
} }
x64Gen_add_reg64Low32_imm32(x64GenContext, rRegResult, (uint32)immU32); x64Gen_add_reg64Low32_imm32(x64GenContext, rRegResult, (uint32)immU32);
// update carry flag // update carry flag
x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_CARRY, REG_RSP, offsetof(PPCInterpreter_t, xer_ca)); x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_CARRY, X86_REG_RSP, offsetof(PPCInterpreter_t, xer_ca));
// set cr bits if enabled // set cr bits if enabled
if( imlInstruction->crRegister != PPC_REC_INVALID_REGISTER ) if( imlInstruction->crRegister != PPC_REC_INVALID_REGISTER )
{ {
@ -1753,7 +1753,7 @@ bool PPCRecompilerX64Gen_imlInstruction_r_r_s32(PPCRecFunction_t* PPCRecFunction
x64Gen_mov_reg64_reg64(x64GenContext, rRegResult, rRegOperand); x64Gen_mov_reg64_reg64(x64GenContext, rRegResult, rRegOperand);
} }
// set carry to zero // set carry to zero
x64Gen_mov_mem8Reg64_imm8(x64GenContext, REG_RSP, offsetof(PPCInterpreter_t, xer_ca), 0); x64Gen_mov_mem8Reg64_imm8(x64GenContext, X86_REG_RSP, offsetof(PPCInterpreter_t, xer_ca), 0);
// ((~a+b)<~a) == true -> ca = 1 // ((~a+b)<~a) == true -> ca = 1
x64Gen_mov_reg64_reg64(x64GenContext, REG_RESV_TEMP, rRegOperand); x64Gen_mov_reg64_reg64(x64GenContext, REG_RESV_TEMP, rRegOperand);
x64Gen_not_reg64Low32(x64GenContext, REG_RESV_TEMP); x64Gen_not_reg64Low32(x64GenContext, REG_RESV_TEMP);
@ -1764,7 +1764,7 @@ bool PPCRecompilerX64Gen_imlInstruction_r_r_s32(PPCRecFunction_t* PPCRecFunction
sint32 jumpInstructionOffset1 = x64GenContext->codeBufferIndex; sint32 jumpInstructionOffset1 = x64GenContext->codeBufferIndex;
x64Gen_jmpc_far(x64GenContext, X86_CONDITION_UNSIGNED_ABOVE_EQUAL, 0); x64Gen_jmpc_far(x64GenContext, X86_CONDITION_UNSIGNED_ABOVE_EQUAL, 0);
// reset carry flag + jump destination afterwards // reset carry flag + jump destination afterwards
x64Gen_mov_mem8Reg64_imm8(x64GenContext, REG_RSP, offsetof(PPCInterpreter_t, xer_ca), 1); x64Gen_mov_mem8Reg64_imm8(x64GenContext, X86_REG_RSP, offsetof(PPCInterpreter_t, xer_ca), 1);
PPCRecompilerX64Gen_redirectRelativeJump(x64GenContext, jumpInstructionOffset1, x64GenContext->codeBufferIndex); PPCRecompilerX64Gen_redirectRelativeJump(x64GenContext, jumpInstructionOffset1, x64GenContext->codeBufferIndex);
// OR ((~a+b+1)<1) == true -> ca = 1 // OR ((~a+b+1)<1) == true -> ca = 1
x64Gen_mov_reg64_reg64(x64GenContext, REG_RESV_TEMP, rRegOperand); x64Gen_mov_reg64_reg64(x64GenContext, REG_RESV_TEMP, rRegOperand);
@ -1776,7 +1776,7 @@ bool PPCRecompilerX64Gen_imlInstruction_r_r_s32(PPCRecFunction_t* PPCRecFunction
sint32 jumpInstructionOffset2 = x64GenContext->codeBufferIndex; sint32 jumpInstructionOffset2 = x64GenContext->codeBufferIndex;
x64Gen_jmpc_far(x64GenContext, X86_CONDITION_UNSIGNED_ABOVE_EQUAL, 0); x64Gen_jmpc_far(x64GenContext, X86_CONDITION_UNSIGNED_ABOVE_EQUAL, 0);
// reset carry flag + jump destination afterwards // reset carry flag + jump destination afterwards
x64Gen_mov_mem8Reg64_imm8(x64GenContext, REG_RSP, offsetof(PPCInterpreter_t, xer_ca), 1); x64Gen_mov_mem8Reg64_imm8(x64GenContext, X86_REG_RSP, offsetof(PPCInterpreter_t, xer_ca), 1);
PPCRecompilerX64Gen_redirectRelativeJump(x64GenContext, jumpInstructionOffset2, x64GenContext->codeBufferIndex); PPCRecompilerX64Gen_redirectRelativeJump(x64GenContext, jumpInstructionOffset2, x64GenContext->codeBufferIndex);
// do actual computation of value, note: a - b is equivalent to a + ~b + 1 // do actual computation of value, note: a - b is equivalent to a + ~b + 1
x64Gen_not_reg64Low32(x64GenContext, rRegResult); x64Gen_not_reg64Low32(x64GenContext, rRegResult);
@ -1835,14 +1835,14 @@ bool PPCRecompilerX64Gen_imlInstruction_r_r_s32(PPCRecFunction_t* PPCRecFunction
caTestMask = (1 << (sh)) - 1; caTestMask = (1 << (sh)) - 1;
x64Gen_test_reg64Low32_imm32(x64GenContext, imlInstruction->op_r_r_s32.registerResult, caTestMask); x64Gen_test_reg64Low32_imm32(x64GenContext, imlInstruction->op_r_r_s32.registerResult, caTestMask);
// SETNE/NZ [ESP+XER_CA] // SETNE/NZ [ESP+XER_CA]
x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_NOT_EQUAL, REG_RSP, offsetof(PPCInterpreter_t, xer_ca)); x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_NOT_EQUAL, X86_REG_RSP, offsetof(PPCInterpreter_t, xer_ca));
// SAR registerResult, SH // SAR registerResult, SH
x64Gen_sar_reg64Low32_imm8(x64GenContext, imlInstruction->op_r_r_s32.registerResult, sh); x64Gen_sar_reg64Low32_imm8(x64GenContext, imlInstruction->op_r_r_s32.registerResult, sh);
// JNS <skipInstruction> (if sign not set) // JNS <skipInstruction> (if sign not set)
sint32 jumpInstructionOffset = x64GenContext->codeBufferIndex; sint32 jumpInstructionOffset = x64GenContext->codeBufferIndex;
x64Gen_jmpc_near(x64GenContext, X86_CONDITION_SIGN, 0); // todo: Can use 2-byte form of jump instruction here x64Gen_jmpc_near(x64GenContext, X86_CONDITION_SIGN, 0); // todo: Can use 2-byte form of jump instruction here
// MOV BYTE [ESP+xer_ca], 0 // MOV BYTE [ESP+xer_ca], 0
x64Gen_mov_mem8Reg64_imm8(x64GenContext, REG_RSP, offsetof(PPCInterpreter_t, xer_ca), 0); x64Gen_mov_mem8Reg64_imm8(x64GenContext, X86_REG_RSP, offsetof(PPCInterpreter_t, xer_ca), 0);
// jump destination // jump destination
PPCRecompilerX64Gen_redirectRelativeJump(x64GenContext, jumpInstructionOffset, x64GenContext->codeBufferIndex); PPCRecompilerX64Gen_redirectRelativeJump(x64GenContext, jumpInstructionOffset, x64GenContext->codeBufferIndex);
// CR update // CR update
@ -1850,9 +1850,9 @@ bool PPCRecompilerX64Gen_imlInstruction_r_r_s32(PPCRecFunction_t* PPCRecFunction
{ {
sint32 crRegister = imlInstruction->crRegister; sint32 crRegister = imlInstruction->crRegister;
x64Gen_test_reg64Low32_reg64Low32(x64GenContext, imlInstruction->op_r_r_s32.registerResult, imlInstruction->op_r_r_s32.registerResult); x64Gen_test_reg64Low32_reg64Low32(x64GenContext, imlInstruction->op_r_r_s32.registerResult, imlInstruction->op_r_r_s32.registerResult);
x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_SIGN, REG_RSP, offsetof(PPCInterpreter_t, cr) + sizeof(uint8)*(crRegister * 4 + PPCREC_CR_BIT_LT)); 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, REG_RSP, offsetof(PPCInterpreter_t, cr) + sizeof(uint8)*(crRegister * 4 + PPCREC_CR_BIT_GT)); 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, REG_RSP, offsetof(PPCInterpreter_t, cr) + sizeof(uint8)*(crRegister * 4 + PPCREC_CR_BIT_EQ)); 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 || else if( imlInstruction->operation == PPCREC_IML_OP_LEFT_SHIFT ||
@ -1978,7 +1978,7 @@ bool PPCRecompilerX64Gen_imlInstruction_conditionalJump(PPCRecFunction_t* PPCRec
} }
cemu_assert_debug(false); // should not reach? cemu_assert_debug(false); // should not reach?
} }
x64Gen_bt_mem8(x64GenContext, REG_RSP, offsetof(PPCInterpreter_t, cr) + crBitIndex * sizeof(uint8), 0); x64Gen_bt_mem8(x64GenContext, X86_REG_RSP, offsetof(PPCInterpreter_t, cr) + crBitIndex * sizeof(uint8), 0);
cemu_assert_debug(imlSegment->GetBranchTaken()); cemu_assert_debug(imlSegment->GetBranchTaken());
PPCRecompilerX64Gen_rememberRelocatableOffset(x64GenContext, (void*)imlSegment->GetBranchTaken()); PPCRecompilerX64Gen_rememberRelocatableOffset(x64GenContext, (void*)imlSegment->GetBranchTaken());
if( imlInstruction->op_conditionalJump.bitMustBeSet ) if( imlInstruction->op_conditionalJump.bitMustBeSet )
@ -2002,7 +2002,7 @@ bool PPCRecompilerX64Gen_imlInstruction_conditionalJumpCycleCheck(PPCRecFunction
// 2) CMP [mem], 0 + JG has about equal (or slightly worse) performance than BT + JNC // 2) CMP [mem], 0 + JG has about equal (or slightly worse) performance than BT + JNC
// BT // BT
x64Gen_bt_mem8(x64GenContext, REG_RSP, offsetof(PPCInterpreter_t, remainingCycles), 31); // check if negative x64Gen_bt_mem8(x64GenContext, X86_REG_RSP, offsetof(PPCInterpreter_t, remainingCycles), 31); // check if negative
cemu_assert_debug(x64GenContext->currentSegment->GetBranchTaken()); cemu_assert_debug(x64GenContext->currentSegment->GetBranchTaken());
PPCRecompilerX64Gen_rememberRelocatableOffset(x64GenContext, x64GenContext->currentSegment->GetBranchTaken()); PPCRecompilerX64Gen_rememberRelocatableOffset(x64GenContext, x64GenContext->currentSegment->GetBranchTaken());
x64Gen_jmpc_far(x64GenContext, X86_CONDITION_CARRY, 0); x64Gen_jmpc_far(x64GenContext, X86_CONDITION_CARRY, 0);
@ -2018,19 +2018,19 @@ bool PPCRecompilerX64Gen_imlInstruction_cr(PPCRecFunction_t* PPCRecFunction, ppc
if (imlInstruction->operation == PPCREC_IML_OP_CR_CLEAR) if (imlInstruction->operation == PPCREC_IML_OP_CR_CLEAR)
{ {
// clear cr bit // clear cr bit
x64Gen_mov_mem8Reg64_imm8(x64GenContext, REG_RSP, offsetof(PPCInterpreter_t, cr) + sizeof(uint8)*imlInstruction->op_cr.crD, 0); x64Gen_mov_mem8Reg64_imm8(x64GenContext, X86_REG_RSP, offsetof(PPCInterpreter_t, cr) + sizeof(uint8)*imlInstruction->op_cr.crD, 0);
return true; return true;
} }
else if (imlInstruction->operation == PPCREC_IML_OP_CR_SET) else if (imlInstruction->operation == PPCREC_IML_OP_CR_SET)
{ {
// set cr bit // set cr bit
x64Gen_mov_mem8Reg64_imm8(x64GenContext, REG_RSP, offsetof(PPCInterpreter_t, cr) + sizeof(uint8)*imlInstruction->op_cr.crD, 1); x64Gen_mov_mem8Reg64_imm8(x64GenContext, X86_REG_RSP, offsetof(PPCInterpreter_t, cr) + sizeof(uint8)*imlInstruction->op_cr.crD, 1);
return true; return true;
} }
else if(imlInstruction->operation == PPCREC_IML_OP_CR_OR || imlInstruction->operation == PPCREC_IML_OP_CR_ORC || else if(imlInstruction->operation == PPCREC_IML_OP_CR_OR || imlInstruction->operation == PPCREC_IML_OP_CR_ORC ||
imlInstruction->operation == PPCREC_IML_OP_CR_AND || imlInstruction->operation == PPCREC_IML_OP_CR_ANDC ) imlInstruction->operation == PPCREC_IML_OP_CR_AND || imlInstruction->operation == PPCREC_IML_OP_CR_ANDC )
{ {
x64Emit_movZX_reg64_mem8(x64GenContext, REG_RESV_TEMP, REG_RSP, offsetof(PPCInterpreter_t, cr) + sizeof(uint8)*imlInstruction->op_cr.crB); x64Emit_movZX_reg64_mem8(x64GenContext, REG_RESV_TEMP, X86_REG_RSP, offsetof(PPCInterpreter_t, cr) + sizeof(uint8)*imlInstruction->op_cr.crB);
if (imlInstruction->operation == PPCREC_IML_OP_CR_ORC || imlInstruction->operation == PPCREC_IML_OP_CR_ANDC) if (imlInstruction->operation == PPCREC_IML_OP_CR_ORC || imlInstruction->operation == PPCREC_IML_OP_CR_ANDC)
{ {
return false; // untested return false; // untested
@ -2038,11 +2038,11 @@ bool PPCRecompilerX64Gen_imlInstruction_cr(PPCRecFunction_t* PPCRecFunction, ppc
x64Gen_xor_reg64Low32_imm32(x64GenContext, REG_RESV_TEMP, 1); // complement x64Gen_xor_reg64Low32_imm32(x64GenContext, REG_RESV_TEMP, 1); // complement
} }
if(imlInstruction->operation == PPCREC_IML_OP_CR_OR || imlInstruction->operation == PPCREC_IML_OP_CR_ORC) if(imlInstruction->operation == PPCREC_IML_OP_CR_OR || imlInstruction->operation == PPCREC_IML_OP_CR_ORC)
x64Gen_or_reg64Low8_mem8Reg64(x64GenContext, REG_RESV_TEMP, REG_RSP, offsetof(PPCInterpreter_t, cr) + sizeof(uint8)*imlInstruction->op_cr.crA); x64Gen_or_reg64Low8_mem8Reg64(x64GenContext, REG_RESV_TEMP, X86_REG_RSP, offsetof(PPCInterpreter_t, cr) + sizeof(uint8)*imlInstruction->op_cr.crA);
else else
x64Gen_and_reg64Low8_mem8Reg64(x64GenContext, REG_RESV_TEMP, REG_RSP, offsetof(PPCInterpreter_t, cr) + sizeof(uint8)*imlInstruction->op_cr.crA); x64Gen_and_reg64Low8_mem8Reg64(x64GenContext, REG_RESV_TEMP, X86_REG_RSP, offsetof(PPCInterpreter_t, cr) + sizeof(uint8)*imlInstruction->op_cr.crA);
x64Gen_mov_mem8Reg64_reg64Low8(x64GenContext, REG_RESV_TEMP, REG_RSP, offsetof(PPCInterpreter_t, cr) + sizeof(uint8)*imlInstruction->op_cr.crD); x64Gen_mov_mem8Reg64_reg64Low8(x64GenContext, REG_RESV_TEMP, X86_REG_RSP, offsetof(PPCInterpreter_t, cr) + sizeof(uint8)*imlInstruction->op_cr.crD);
return true; return true;
} }
@ -2058,28 +2058,28 @@ void PPCRecompilerX64Gen_imlInstruction_r_name(PPCRecFunction_t* PPCRecFunction,
uint32 name = imlInstruction->op_r_name.name; uint32 name = imlInstruction->op_r_name.name;
if( name >= PPCREC_NAME_R0 && name < PPCREC_NAME_R0+32 ) if( name >= PPCREC_NAME_R0 && name < PPCREC_NAME_R0+32 )
{ {
x64Emit_mov_reg64_mem32(x64GenContext, imlInstruction->op_r_name.registerIndex, REG_RSP, offsetof(PPCInterpreter_t, gpr)+sizeof(uint32)*(name-PPCREC_NAME_R0)); x64Emit_mov_reg64_mem32(x64GenContext, imlInstruction->op_r_name.registerIndex, X86_REG_RSP, offsetof(PPCInterpreter_t, gpr)+sizeof(uint32)*(name-PPCREC_NAME_R0));
} }
else if( name >= PPCREC_NAME_SPR0 && name < PPCREC_NAME_SPR0+999 ) else if( name >= PPCREC_NAME_SPR0 && name < PPCREC_NAME_SPR0+999 )
{ {
sint32 sprIndex = (name - PPCREC_NAME_SPR0); sint32 sprIndex = (name - PPCREC_NAME_SPR0);
if (sprIndex == SPR_LR) if (sprIndex == SPR_LR)
x64Emit_mov_reg64_mem32(x64GenContext, imlInstruction->op_r_name.registerIndex, REG_RSP, offsetof(PPCInterpreter_t, spr.LR)); x64Emit_mov_reg64_mem32(x64GenContext, imlInstruction->op_r_name.registerIndex, X86_REG_RSP, offsetof(PPCInterpreter_t, spr.LR));
else if (sprIndex == SPR_CTR) else if (sprIndex == SPR_CTR)
x64Emit_mov_reg64_mem32(x64GenContext, imlInstruction->op_r_name.registerIndex, REG_RSP, offsetof(PPCInterpreter_t, spr.CTR)); x64Emit_mov_reg64_mem32(x64GenContext, imlInstruction->op_r_name.registerIndex, X86_REG_RSP, offsetof(PPCInterpreter_t, spr.CTR));
else if (sprIndex == SPR_XER) else if (sprIndex == SPR_XER)
x64Emit_mov_reg64_mem32(x64GenContext, imlInstruction->op_r_name.registerIndex, REG_RSP, offsetof(PPCInterpreter_t, spr.XER)); x64Emit_mov_reg64_mem32(x64GenContext, imlInstruction->op_r_name.registerIndex, X86_REG_RSP, offsetof(PPCInterpreter_t, spr.XER));
else if (sprIndex >= SPR_UGQR0 && sprIndex <= SPR_UGQR7) else if (sprIndex >= SPR_UGQR0 && sprIndex <= SPR_UGQR7)
{ {
sint32 memOffset = offsetof(PPCInterpreter_t, spr.UGQR) + sizeof(PPCInterpreter_t::spr.UGQR[0]) * (sprIndex - SPR_UGQR0); sint32 memOffset = offsetof(PPCInterpreter_t, spr.UGQR) + sizeof(PPCInterpreter_t::spr.UGQR[0]) * (sprIndex - SPR_UGQR0);
x64Emit_mov_reg64_mem32(x64GenContext, imlInstruction->op_r_name.registerIndex, REG_RSP, memOffset); x64Emit_mov_reg64_mem32(x64GenContext, imlInstruction->op_r_name.registerIndex, X86_REG_RSP, memOffset);
} }
else else
assert_dbg(); assert_dbg();
} }
else if (name >= PPCREC_NAME_TEMPORARY && name < PPCREC_NAME_TEMPORARY + 4) else if (name >= PPCREC_NAME_TEMPORARY && name < PPCREC_NAME_TEMPORARY + 4)
{ {
x64Emit_mov_reg64_mem32(x64GenContext, imlInstruction->op_r_name.registerIndex, REG_RSP, offsetof(PPCInterpreter_t, temporaryGPR) + sizeof(uint32) * (name - PPCREC_NAME_TEMPORARY)); x64Emit_mov_reg64_mem32(x64GenContext, imlInstruction->op_r_name.registerIndex, X86_REG_RSP, offsetof(PPCInterpreter_t, temporaryGPR) + sizeof(uint32) * (name - PPCREC_NAME_TEMPORARY));
} }
else else
assert_dbg(); assert_dbg();
@ -2090,28 +2090,28 @@ void PPCRecompilerX64Gen_imlInstruction_name_r(PPCRecFunction_t* PPCRecFunction,
uint32 name = imlInstruction->op_r_name.name; uint32 name = imlInstruction->op_r_name.name;
if( name >= PPCREC_NAME_R0 && name < PPCREC_NAME_R0+32 ) if( name >= PPCREC_NAME_R0 && name < PPCREC_NAME_R0+32 )
{ {
x64Emit_mov_mem32_reg64(x64GenContext, REG_RSP, offsetof(PPCInterpreter_t, gpr)+sizeof(uint32)*(name-PPCREC_NAME_R0), imlInstruction->op_r_name.registerIndex); x64Emit_mov_mem32_reg64(x64GenContext, X86_REG_RSP, offsetof(PPCInterpreter_t, gpr)+sizeof(uint32)*(name-PPCREC_NAME_R0), imlInstruction->op_r_name.registerIndex);
} }
else if( name >= PPCREC_NAME_SPR0 && name < PPCREC_NAME_SPR0+999 ) else if( name >= PPCREC_NAME_SPR0 && name < PPCREC_NAME_SPR0+999 )
{ {
uint32 sprIndex = (name - PPCREC_NAME_SPR0); uint32 sprIndex = (name - PPCREC_NAME_SPR0);
if (sprIndex == SPR_LR) if (sprIndex == SPR_LR)
x64Emit_mov_mem32_reg64(x64GenContext, REG_RSP, offsetof(PPCInterpreter_t, spr.LR), imlInstruction->op_r_name.registerIndex); x64Emit_mov_mem32_reg64(x64GenContext, X86_REG_RSP, offsetof(PPCInterpreter_t, spr.LR), imlInstruction->op_r_name.registerIndex);
else if (sprIndex == SPR_CTR) else if (sprIndex == SPR_CTR)
x64Emit_mov_mem32_reg64(x64GenContext, REG_RSP, offsetof(PPCInterpreter_t, spr.CTR), imlInstruction->op_r_name.registerIndex); x64Emit_mov_mem32_reg64(x64GenContext, X86_REG_RSP, offsetof(PPCInterpreter_t, spr.CTR), imlInstruction->op_r_name.registerIndex);
else if (sprIndex == SPR_XER) else if (sprIndex == SPR_XER)
x64Emit_mov_mem32_reg64(x64GenContext, REG_RSP, offsetof(PPCInterpreter_t, spr.XER), imlInstruction->op_r_name.registerIndex); x64Emit_mov_mem32_reg64(x64GenContext, X86_REG_RSP, offsetof(PPCInterpreter_t, spr.XER), imlInstruction->op_r_name.registerIndex);
else if (sprIndex >= SPR_UGQR0 && sprIndex <= SPR_UGQR7) else if (sprIndex >= SPR_UGQR0 && sprIndex <= SPR_UGQR7)
{ {
sint32 memOffset = offsetof(PPCInterpreter_t, spr.UGQR) + sizeof(PPCInterpreter_t::spr.UGQR[0]) * (sprIndex - SPR_UGQR0); sint32 memOffset = offsetof(PPCInterpreter_t, spr.UGQR) + sizeof(PPCInterpreter_t::spr.UGQR[0]) * (sprIndex - SPR_UGQR0);
x64Emit_mov_mem32_reg64(x64GenContext, REG_RSP, memOffset, imlInstruction->op_r_name.registerIndex); x64Emit_mov_mem32_reg64(x64GenContext, X86_REG_RSP, memOffset, imlInstruction->op_r_name.registerIndex);
} }
else else
assert_dbg(); assert_dbg();
} }
else if (name >= PPCREC_NAME_TEMPORARY && name < PPCREC_NAME_TEMPORARY + 4) else if (name >= PPCREC_NAME_TEMPORARY && name < PPCREC_NAME_TEMPORARY + 4)
{ {
x64Emit_mov_mem32_reg64(x64GenContext, REG_RSP, offsetof(PPCInterpreter_t, temporaryGPR) + sizeof(uint32) * (name - PPCREC_NAME_TEMPORARY), imlInstruction->op_r_name.registerIndex); x64Emit_mov_mem32_reg64(x64GenContext, X86_REG_RSP, offsetof(PPCInterpreter_t, temporaryGPR) + sizeof(uint32) * (name - PPCREC_NAME_TEMPORARY), imlInstruction->op_r_name.registerIndex);
} }
else else
assert_dbg(); assert_dbg();
@ -2392,21 +2392,21 @@ void PPCRecompilerX64Gen_generateEnterRecompilerCode()
x64GenContext.activeCRRegister = PPC_REC_INVALID_REGISTER; x64GenContext.activeCRRegister = PPC_REC_INVALID_REGISTER;
// start of recompiler entry function // start of recompiler entry function
x64Gen_push_reg64(&x64GenContext, REG_RAX); x64Gen_push_reg64(&x64GenContext, X86_REG_RAX);
x64Gen_push_reg64(&x64GenContext, REG_RCX); x64Gen_push_reg64(&x64GenContext, X86_REG_RCX);
x64Gen_push_reg64(&x64GenContext, REG_RDX); x64Gen_push_reg64(&x64GenContext, X86_REG_RDX);
x64Gen_push_reg64(&x64GenContext, REG_RBX); x64Gen_push_reg64(&x64GenContext, X86_REG_RBX);
x64Gen_push_reg64(&x64GenContext, REG_RBP); x64Gen_push_reg64(&x64GenContext, X86_REG_RBP);
x64Gen_push_reg64(&x64GenContext, REG_RDI); x64Gen_push_reg64(&x64GenContext, X86_REG_RDI);
x64Gen_push_reg64(&x64GenContext, REG_RSI); x64Gen_push_reg64(&x64GenContext, X86_REG_RSI);
x64Gen_push_reg64(&x64GenContext, REG_R8); x64Gen_push_reg64(&x64GenContext, X86_REG_R8);
x64Gen_push_reg64(&x64GenContext, REG_R9); x64Gen_push_reg64(&x64GenContext, X86_REG_R9);
x64Gen_push_reg64(&x64GenContext, REG_R10); x64Gen_push_reg64(&x64GenContext, X86_REG_R10);
x64Gen_push_reg64(&x64GenContext, REG_R11); x64Gen_push_reg64(&x64GenContext, X86_REG_R11);
x64Gen_push_reg64(&x64GenContext, REG_R12); x64Gen_push_reg64(&x64GenContext, X86_REG_R12);
x64Gen_push_reg64(&x64GenContext, REG_R13); x64Gen_push_reg64(&x64GenContext, X86_REG_R13);
x64Gen_push_reg64(&x64GenContext, REG_R14); x64Gen_push_reg64(&x64GenContext, X86_REG_R14);
x64Gen_push_reg64(&x64GenContext, REG_R15); x64Gen_push_reg64(&x64GenContext, X86_REG_R15);
// 000000007775EF04 | E8 00 00 00 00 call +0x00 // 000000007775EF04 | E8 00 00 00 00 call +0x00
x64Gen_writeU8(&x64GenContext, 0xE8); x64Gen_writeU8(&x64GenContext, 0xE8);
@ -2421,37 +2421,37 @@ void PPCRecompilerX64Gen_generateEnterRecompilerCode()
x64Gen_writeU8(&x64GenContext, 0x24); x64Gen_writeU8(&x64GenContext, 0x24);
uint32 jmpPatchOffset = x64GenContext.codeBufferIndex; uint32 jmpPatchOffset = x64GenContext.codeBufferIndex;
x64Gen_writeU8(&x64GenContext, 0); // skip the distance until after the JMP x64Gen_writeU8(&x64GenContext, 0); // skip the distance until after the JMP
x64Emit_mov_mem64_reg64(&x64GenContext, REG_RDX, offsetof(PPCInterpreter_t, rspTemp), REG_RSP); x64Emit_mov_mem64_reg64(&x64GenContext, X86_REG_RDX, offsetof(PPCInterpreter_t, rspTemp), X86_REG_RSP);
// MOV RSP, RDX (ppc interpreter instance) // MOV RSP, RDX (ppc interpreter instance)
x64Gen_mov_reg64_reg64(&x64GenContext, REG_RSP, REG_RDX); x64Gen_mov_reg64_reg64(&x64GenContext, X86_REG_RSP, X86_REG_RDX);
// MOV R15, ppcRecompilerInstanceData // MOV R15, ppcRecompilerInstanceData
x64Gen_mov_reg64_imm64(&x64GenContext, REG_R15, (uint64)ppcRecompilerInstanceData); x64Gen_mov_reg64_imm64(&x64GenContext, X86_REG_R15, (uint64)ppcRecompilerInstanceData);
// MOV R13, memory_base // MOV R13, memory_base
x64Gen_mov_reg64_imm64(&x64GenContext, REG_R13, (uint64)memory_base); x64Gen_mov_reg64_imm64(&x64GenContext, X86_REG_R13, (uint64)memory_base);
//JMP recFunc //JMP recFunc
x64Gen_jmp_reg64(&x64GenContext, REG_RCX); // call argument 1 x64Gen_jmp_reg64(&x64GenContext, X86_REG_RCX); // call argument 1
x64GenContext.codeBuffer[jmpPatchOffset] = (x64GenContext.codeBufferIndex-(jmpPatchOffset-4)); x64GenContext.codeBuffer[jmpPatchOffset] = (x64GenContext.codeBufferIndex-(jmpPatchOffset-4));
//recompilerExit1: //recompilerExit1:
x64Gen_pop_reg64(&x64GenContext, REG_R15); x64Gen_pop_reg64(&x64GenContext, X86_REG_R15);
x64Gen_pop_reg64(&x64GenContext, REG_R14); x64Gen_pop_reg64(&x64GenContext, X86_REG_R14);
x64Gen_pop_reg64(&x64GenContext, REG_R13); x64Gen_pop_reg64(&x64GenContext, X86_REG_R13);
x64Gen_pop_reg64(&x64GenContext, REG_R12); x64Gen_pop_reg64(&x64GenContext, X86_REG_R12);
x64Gen_pop_reg64(&x64GenContext, REG_R11); x64Gen_pop_reg64(&x64GenContext, X86_REG_R11);
x64Gen_pop_reg64(&x64GenContext, REG_R10); x64Gen_pop_reg64(&x64GenContext, X86_REG_R10);
x64Gen_pop_reg64(&x64GenContext, REG_R9); x64Gen_pop_reg64(&x64GenContext, X86_REG_R9);
x64Gen_pop_reg64(&x64GenContext, REG_R8); x64Gen_pop_reg64(&x64GenContext, X86_REG_R8);
x64Gen_pop_reg64(&x64GenContext, REG_RSI); x64Gen_pop_reg64(&x64GenContext, X86_REG_RSI);
x64Gen_pop_reg64(&x64GenContext, REG_RDI); x64Gen_pop_reg64(&x64GenContext, X86_REG_RDI);
x64Gen_pop_reg64(&x64GenContext, REG_RBP); x64Gen_pop_reg64(&x64GenContext, X86_REG_RBP);
x64Gen_pop_reg64(&x64GenContext, REG_RBX); x64Gen_pop_reg64(&x64GenContext, X86_REG_RBX);
x64Gen_pop_reg64(&x64GenContext, REG_RDX); x64Gen_pop_reg64(&x64GenContext, X86_REG_RDX);
x64Gen_pop_reg64(&x64GenContext, REG_RCX); x64Gen_pop_reg64(&x64GenContext, X86_REG_RCX);
x64Gen_pop_reg64(&x64GenContext, REG_RAX); x64Gen_pop_reg64(&x64GenContext, X86_REG_RAX);
// RET // RET
x64Gen_ret(&x64GenContext); x64Gen_ret(&x64GenContext);
@ -2473,10 +2473,10 @@ void* PPCRecompilerX64Gen_generateLeaveRecompilerCode()
// update instruction pointer // update instruction pointer
// LR is in EDX // LR is in EDX
x64Emit_mov_mem32_reg32(&x64GenContext, REG_RSP, offsetof(PPCInterpreter_t, instructionPointer), REG_EDX); x64Emit_mov_mem32_reg32(&x64GenContext, X86_REG_RSP, offsetof(PPCInterpreter_t, instructionPointer), X86_REG_EDX);
// MOV RSP, [ppcRecompilerX64_rspTemp] // MOV RSP, [ppcRecompilerX64_rspTemp]
x64Emit_mov_reg64_mem64(&x64GenContext, REG_RSP, REG_RESV_HCPU, offsetof(PPCInterpreter_t, rspTemp)); x64Emit_mov_reg64_mem64(&x64GenContext, X86_REG_RSP, REG_RESV_HCPU, offsetof(PPCInterpreter_t, rspTemp));
// RET // RET
x64Gen_ret(&x64GenContext); x64Gen_ret(&x64GenContext);

View file

@ -23,74 +23,48 @@ struct x64GenContext_t
std::vector<x64RelocEntry_t> relocateOffsetTable2; std::vector<x64RelocEntry_t> relocateOffsetTable2;
}; };
// Some of these are defined by winnt.h and gnu headers // todo - these definitions are part of the x86_64 emitter. Not the backend itself. We should move them eventually
#undef REG_EAX #define X86_REG_EAX 0
#undef REG_ECX #define X86_REG_ECX 1
#undef REG_EDX #define X86_REG_EDX 2
#undef REG_EBX #define X86_REG_EBX 3
#undef REG_ESP #define X86_REG_ESP 4 // reserved for low half of hCPU pointer
#undef REG_EBP #define X86_REG_EBP 5
#undef REG_ESI #define X86_REG_ESI 6
#undef REG_EDI #define X86_REG_EDI 7
#undef REG_NONE #define X86_REG_NONE -1
#undef REG_RAX
#undef REG_RCX
#undef REG_RDX
#undef REG_RBX
#undef REG_RSP
#undef REG_RBP
#undef REG_RSI
#undef REG_RDI
#undef REG_R8
#undef REG_R9
#undef REG_R10
#undef REG_R11
#undef REG_R12
#undef REG_R13
#undef REG_R14
#undef REG_R15
#define REG_EAX 0 #define X86_REG_RAX 0
#define REG_ECX 1 #define X86_REG_RCX 1
#define REG_EDX 2 #define X86_REG_RDX 2
#define REG_EBX 3 #define X86_REG_RBX 3
#define REG_ESP 4 // reserved for low half of hCPU pointer #define X86_REG_RSP 4 // reserved for hCPU pointer
#define REG_EBP 5 #define X86_REG_RBP 5
#define REG_ESI 6 #define X86_REG_RSI 6
#define REG_EDI 7 #define X86_REG_RDI 7
#define REG_NONE -1 #define X86_REG_R8 8
#define X86_REG_R9 9
#define X86_REG_R10 10
#define X86_REG_R11 11
#define X86_REG_R12 12
#define X86_REG_R13 13 // reserved to hold pointer to memory base? (Not decided yet)
#define X86_REG_R14 14 // reserved as temporary register
#define X86_REG_R15 15 // reserved for pointer to ppcRecompilerInstanceData
#define REG_RAX 0 #define X86_REG_AL 0
#define REG_RCX 1 #define X86_REG_CL 1
#define REG_RDX 2 #define X86_REG_DL 2
#define REG_RBX 3 #define X86_REG_BL 3
#define REG_RSP 4 // reserved for hCPU pointer #define X86_REG_AH 4
#define REG_RBP 5 #define X86_REG_CH 5
#define REG_RSI 6 #define X86_REG_DH 6
#define REG_RDI 7 #define X86_REG_BH 7
#define REG_R8 8
#define REG_R9 9
#define REG_R10 10
#define REG_R11 11
#define REG_R12 12
#define REG_R13 13 // reserved to hold pointer to memory base? (Not decided yet)
#define REG_R14 14 // reserved as temporary register
#define REG_R15 15 // reserved for pointer to ppcRecompilerInstanceData
#define REG_AL 0
#define REG_CL 1
#define REG_DL 2
#define REG_BL 3
#define REG_AH 4
#define REG_CH 5
#define REG_DH 6
#define REG_BH 7
// reserved registers // reserved registers
#define REG_RESV_TEMP (REG_R14) #define REG_RESV_TEMP (X86_REG_R14)
#define REG_RESV_HCPU (REG_RSP) #define REG_RESV_HCPU (X86_REG_RSP)
#define REG_RESV_MEMBASE (REG_R13) #define REG_RESV_MEMBASE (X86_REG_R13)
#define REG_RESV_RECDATA (REG_R15) #define REG_RESV_RECDATA (X86_REG_R15)
// reserved floating-point registers // reserved floating-point registers
#define REG_RESV_FPR_TEMP (15) #define REG_RESV_FPR_TEMP (15)

View file

@ -10,11 +10,11 @@ void PPCRecompilerX64Gen_imlInstruction_fpr_r_name(PPCRecFunction_t* PPCRecFunct
uint32 name = imlInstruction->op_r_name.name; uint32 name = imlInstruction->op_r_name.name;
if( name >= PPCREC_NAME_FPR0 && name < (PPCREC_NAME_FPR0+32) ) if( name >= PPCREC_NAME_FPR0 && name < (PPCREC_NAME_FPR0+32) )
{ {
x64Gen_movupd_xmmReg_memReg128(x64GenContext, imlInstruction->op_r_name.registerIndex, REG_ESP, offsetof(PPCInterpreter_t, fpr)+sizeof(FPR_t)*(name-PPCREC_NAME_FPR0)); x64Gen_movupd_xmmReg_memReg128(x64GenContext, imlInstruction->op_r_name.registerIndex, X86_REG_ESP, offsetof(PPCInterpreter_t, fpr)+sizeof(FPR_t)*(name-PPCREC_NAME_FPR0));
} }
else if( name >= PPCREC_NAME_TEMPORARY_FPR0 || name < (PPCREC_NAME_TEMPORARY_FPR0+8) ) else if( name >= PPCREC_NAME_TEMPORARY_FPR0 || name < (PPCREC_NAME_TEMPORARY_FPR0+8) )
{ {
x64Gen_movupd_xmmReg_memReg128(x64GenContext, imlInstruction->op_r_name.registerIndex, REG_ESP, offsetof(PPCInterpreter_t, temporaryFPR)+sizeof(FPR_t)*(name-PPCREC_NAME_TEMPORARY_FPR0)); x64Gen_movupd_xmmReg_memReg128(x64GenContext, imlInstruction->op_r_name.registerIndex, X86_REG_ESP, offsetof(PPCInterpreter_t, temporaryFPR)+sizeof(FPR_t)*(name-PPCREC_NAME_TEMPORARY_FPR0));
} }
else else
{ {
@ -27,11 +27,11 @@ void PPCRecompilerX64Gen_imlInstruction_fpr_name_r(PPCRecFunction_t* PPCRecFunct
uint32 name = imlInstruction->op_r_name.name; uint32 name = imlInstruction->op_r_name.name;
if( name >= PPCREC_NAME_FPR0 && name < (PPCREC_NAME_FPR0+32) ) if( name >= PPCREC_NAME_FPR0 && name < (PPCREC_NAME_FPR0+32) )
{ {
x64Gen_movupd_memReg128_xmmReg(x64GenContext, imlInstruction->op_r_name.registerIndex, REG_ESP, offsetof(PPCInterpreter_t, fpr)+sizeof(FPR_t)*(name-PPCREC_NAME_FPR0)); x64Gen_movupd_memReg128_xmmReg(x64GenContext, imlInstruction->op_r_name.registerIndex, X86_REG_ESP, offsetof(PPCInterpreter_t, fpr)+sizeof(FPR_t)*(name-PPCREC_NAME_FPR0));
} }
else if( name >= PPCREC_NAME_TEMPORARY_FPR0 && name < (PPCREC_NAME_TEMPORARY_FPR0+8) ) else if( name >= PPCREC_NAME_TEMPORARY_FPR0 && name < (PPCREC_NAME_TEMPORARY_FPR0+8) )
{ {
x64Gen_movupd_memReg128_xmmReg(x64GenContext, imlInstruction->op_r_name.registerIndex, REG_ESP, offsetof(PPCInterpreter_t, temporaryFPR)+sizeof(FPR_t)*(name-PPCREC_NAME_TEMPORARY_FPR0)); x64Gen_movupd_memReg128_xmmReg(x64GenContext, imlInstruction->op_r_name.registerIndex, X86_REG_ESP, offsetof(PPCInterpreter_t, temporaryFPR)+sizeof(FPR_t)*(name-PPCREC_NAME_TEMPORARY_FPR0));
} }
else else
{ {
@ -75,7 +75,7 @@ void PPCRecompilerX64Gen_imlInstr_psq_load(ppcImlGenContext_t* ppcImlGenContext,
assert_dbg(); assert_dbg();
} }
// optimized code for ps float load // optimized code for ps float load
x64Emit_mov_reg64_mem64(x64GenContext, REG_RESV_TEMP, REG_R13, memReg, memImmS32); x64Emit_mov_reg64_mem64(x64GenContext, REG_RESV_TEMP, X86_REG_R13, memReg, memImmS32);
x64Gen_bswap_reg64(x64GenContext, REG_RESV_TEMP); x64Gen_bswap_reg64(x64GenContext, REG_RESV_TEMP);
x64Gen_rol_reg64_imm8(x64GenContext, REG_RESV_TEMP, 32); // swap upper and lower DWORD x64Gen_rol_reg64_imm8(x64GenContext, REG_RESV_TEMP, 32); // swap upper and lower DWORD
x64Gen_movq_xmmReg_reg64(x64GenContext, registerXMM, REG_RESV_TEMP); x64Gen_movq_xmmReg_reg64(x64GenContext, registerXMM, REG_RESV_TEMP);
@ -116,8 +116,8 @@ void PPCRecompilerX64Gen_imlInstr_psq_load(ppcImlGenContext_t* ppcImlGenContext,
} }
else else
{ {
x64Emit_mov_mem32_reg64(x64GenContext, REG_RSP, offsetof(PPCInterpreter_t, temporaryFPR), REG_RESV_TEMP); x64Emit_mov_mem32_reg64(x64GenContext, X86_REG_RSP, offsetof(PPCInterpreter_t, temporaryFPR), REG_RESV_TEMP);
x64Gen_movddup_xmmReg_memReg64(x64GenContext, REG_RESV_FPR_TEMP, REG_RSP, offsetof(PPCInterpreter_t, temporaryFPR)); x64Gen_movddup_xmmReg_memReg64(x64GenContext, REG_RESV_FPR_TEMP, X86_REG_RSP, offsetof(PPCInterpreter_t, temporaryFPR));
} }
x64Gen_cvtss2sd_xmmReg_xmmReg(x64GenContext, REG_RESV_FPR_TEMP, REG_RESV_FPR_TEMP); x64Gen_cvtss2sd_xmmReg_xmmReg(x64GenContext, REG_RESV_FPR_TEMP, REG_RESV_FPR_TEMP);
// load constant 1.0 into lower half and upper half of temp register // load constant 1.0 into lower half and upper half of temp register
@ -179,7 +179,7 @@ void PPCRecompilerX64Gen_imlInstr_psq_load(ppcImlGenContext_t* ppcImlGenContext,
if (readSize == 16) if (readSize == 16)
{ {
// half word // half word
x64Gen_movZeroExtend_reg64Low16_mem16Reg64PlusReg64(x64GenContext, REG_RESV_TEMP, REG_R13, memReg, memOffset); x64Gen_movZeroExtend_reg64Low16_mem16Reg64PlusReg64(x64GenContext, REG_RESV_TEMP, X86_REG_R13, memReg, memOffset);
x64Gen_rol_reg64Low16_imm8(x64GenContext, REG_RESV_TEMP, 8); // endian swap x64Gen_rol_reg64Low16_imm8(x64GenContext, REG_RESV_TEMP, 8); // endian swap
if (isSigned) if (isSigned)
x64Gen_movSignExtend_reg64Low32_reg64Low16(x64GenContext, REG_RESV_TEMP, REG_RESV_TEMP); x64Gen_movSignExtend_reg64Low32_reg64Low16(x64GenContext, REG_RESV_TEMP, REG_RESV_TEMP);
@ -189,7 +189,7 @@ void PPCRecompilerX64Gen_imlInstr_psq_load(ppcImlGenContext_t* ppcImlGenContext,
else if (readSize == 8) else if (readSize == 8)
{ {
// byte // byte
x64Emit_mov_reg64b_mem8(x64GenContext, REG_RESV_TEMP, REG_R13, memReg, memOffset); x64Emit_mov_reg64b_mem8(x64GenContext, REG_RESV_TEMP, X86_REG_R13, memReg, memOffset);
if (isSigned) if (isSigned)
x64Gen_movSignExtend_reg64Low32_reg64Low8(x64GenContext, REG_RESV_TEMP, REG_RESV_TEMP); x64Gen_movSignExtend_reg64Low32_reg64Low8(x64GenContext, REG_RESV_TEMP, REG_RESV_TEMP);
else else
@ -318,14 +318,14 @@ bool PPCRecompilerX64Gen_imlInstruction_fpr_load(PPCRecFunction_t* PPCRecFunctio
x64Gen_mov_reg64Low32_reg64Low32(x64GenContext, REG_RESV_TEMP, realRegisterMem); x64Gen_mov_reg64Low32_reg64Low32(x64GenContext, REG_RESV_TEMP, realRegisterMem);
x64Gen_add_reg64Low32_reg64Low32(x64GenContext, REG_RESV_TEMP, realRegisterMem2); x64Gen_add_reg64Low32_reg64Low32(x64GenContext, REG_RESV_TEMP, realRegisterMem2);
// load value // load value
x64Emit_mov_reg64_mem64(x64GenContext, REG_RESV_TEMP, REG_R13, REG_RESV_TEMP, imlInstruction->op_storeLoad.immS32+0); x64Emit_mov_reg64_mem64(x64GenContext, REG_RESV_TEMP, X86_REG_R13, REG_RESV_TEMP, imlInstruction->op_storeLoad.immS32+0);
x64Gen_bswap_reg64(x64GenContext, REG_RESV_TEMP); x64Gen_bswap_reg64(x64GenContext, REG_RESV_TEMP);
x64Gen_movq_xmmReg_reg64(x64GenContext, REG_RESV_FPR_TEMP, REG_RESV_TEMP); x64Gen_movq_xmmReg_reg64(x64GenContext, REG_RESV_FPR_TEMP, REG_RESV_TEMP);
x64Gen_movsd_xmmReg_xmmReg(x64GenContext, realRegisterXMM, REG_RESV_FPR_TEMP); x64Gen_movsd_xmmReg_xmmReg(x64GenContext, realRegisterXMM, REG_RESV_FPR_TEMP);
} }
else else
{ {
x64Emit_mov_reg64_mem64(x64GenContext, REG_RESV_TEMP, REG_R13, realRegisterMem, imlInstruction->op_storeLoad.immS32+0); x64Emit_mov_reg64_mem64(x64GenContext, REG_RESV_TEMP, X86_REG_R13, realRegisterMem, imlInstruction->op_storeLoad.immS32+0);
x64Gen_bswap_reg64(x64GenContext, REG_RESV_TEMP); x64Gen_bswap_reg64(x64GenContext, REG_RESV_TEMP);
x64Gen_movq_xmmReg_reg64(x64GenContext, REG_RESV_FPR_TEMP, REG_RESV_TEMP); x64Gen_movq_xmmReg_reg64(x64GenContext, REG_RESV_FPR_TEMP, REG_RESV_TEMP);
x64Gen_movsd_xmmReg_xmmReg(x64GenContext, realRegisterXMM, REG_RESV_FPR_TEMP); x64Gen_movsd_xmmReg_xmmReg(x64GenContext, realRegisterXMM, REG_RESV_FPR_TEMP);
@ -339,31 +339,31 @@ bool PPCRecompilerX64Gen_imlInstruction_fpr_load(PPCRecFunction_t* PPCRecFunctio
x64Gen_mov_reg64Low32_reg64Low32(x64GenContext, REG_RESV_TEMP, realRegisterMem); x64Gen_mov_reg64Low32_reg64Low32(x64GenContext, REG_RESV_TEMP, realRegisterMem);
x64Gen_add_reg64Low32_reg64Low32(x64GenContext, REG_RESV_TEMP, realRegisterMem2); x64Gen_add_reg64Low32_reg64Low32(x64GenContext, REG_RESV_TEMP, realRegisterMem2);
// load double low part to temporaryFPR // load double low part to temporaryFPR
x64Emit_mov_reg32_mem32(x64GenContext, REG_RESV_TEMP, REG_R13, REG_RESV_TEMP, imlInstruction->op_storeLoad.immS32+0); x64Emit_mov_reg32_mem32(x64GenContext, REG_RESV_TEMP, X86_REG_R13, REG_RESV_TEMP, imlInstruction->op_storeLoad.immS32+0);
x64Gen_bswap_reg64Lower32bit(x64GenContext, REG_RESV_TEMP); x64Gen_bswap_reg64Lower32bit(x64GenContext, REG_RESV_TEMP);
x64Emit_mov_mem32_reg64(x64GenContext, REG_RSP, offsetof(PPCInterpreter_t, temporaryFPR)+4, REG_RESV_TEMP); x64Emit_mov_mem32_reg64(x64GenContext, X86_REG_RSP, offsetof(PPCInterpreter_t, temporaryFPR)+4, REG_RESV_TEMP);
// calculate offset again // calculate offset again
x64Gen_mov_reg64Low32_reg64Low32(x64GenContext, REG_RESV_TEMP, realRegisterMem); x64Gen_mov_reg64Low32_reg64Low32(x64GenContext, REG_RESV_TEMP, realRegisterMem);
x64Gen_add_reg64Low32_reg64Low32(x64GenContext, REG_RESV_TEMP, realRegisterMem2); x64Gen_add_reg64Low32_reg64Low32(x64GenContext, REG_RESV_TEMP, realRegisterMem2);
// load double high part to temporaryFPR // load double high part to temporaryFPR
x64Emit_mov_reg32_mem32(x64GenContext, REG_RESV_TEMP, REG_R13, REG_RESV_TEMP, imlInstruction->op_storeLoad.immS32+4); x64Emit_mov_reg32_mem32(x64GenContext, REG_RESV_TEMP, X86_REG_R13, REG_RESV_TEMP, imlInstruction->op_storeLoad.immS32+4);
x64Gen_bswap_reg64Lower32bit(x64GenContext, REG_RESV_TEMP); x64Gen_bswap_reg64Lower32bit(x64GenContext, REG_RESV_TEMP);
x64Emit_mov_mem32_reg64(x64GenContext, REG_RSP, offsetof(PPCInterpreter_t, temporaryFPR)+0, REG_RESV_TEMP); x64Emit_mov_mem32_reg64(x64GenContext, X86_REG_RSP, offsetof(PPCInterpreter_t, temporaryFPR)+0, REG_RESV_TEMP);
// load double from temporaryFPR // load double from temporaryFPR
x64Gen_movlpd_xmmReg_memReg64(x64GenContext, realRegisterXMM, REG_RSP, offsetof(PPCInterpreter_t, temporaryFPR)); x64Gen_movlpd_xmmReg_memReg64(x64GenContext, realRegisterXMM, X86_REG_RSP, offsetof(PPCInterpreter_t, temporaryFPR));
} }
else else
{ {
// load double low part to temporaryFPR // load double low part to temporaryFPR
x64Emit_mov_reg32_mem32(x64GenContext, REG_RESV_TEMP, REG_R13, realRegisterMem, imlInstruction->op_storeLoad.immS32+0); x64Emit_mov_reg32_mem32(x64GenContext, REG_RESV_TEMP, X86_REG_R13, realRegisterMem, imlInstruction->op_storeLoad.immS32+0);
x64Gen_bswap_reg64Lower32bit(x64GenContext, REG_RESV_TEMP); x64Gen_bswap_reg64Lower32bit(x64GenContext, REG_RESV_TEMP);
x64Emit_mov_mem32_reg64(x64GenContext, REG_RSP, offsetof(PPCInterpreter_t, temporaryFPR)+4, REG_RESV_TEMP); x64Emit_mov_mem32_reg64(x64GenContext, X86_REG_RSP, offsetof(PPCInterpreter_t, temporaryFPR)+4, REG_RESV_TEMP);
// load double high part to temporaryFPR // load double high part to temporaryFPR
x64Emit_mov_reg32_mem32(x64GenContext, REG_RESV_TEMP, REG_R13, realRegisterMem, imlInstruction->op_storeLoad.immS32+4); x64Emit_mov_reg32_mem32(x64GenContext, REG_RESV_TEMP, X86_REG_R13, realRegisterMem, imlInstruction->op_storeLoad.immS32+4);
x64Gen_bswap_reg64Lower32bit(x64GenContext, REG_RESV_TEMP); x64Gen_bswap_reg64Lower32bit(x64GenContext, REG_RESV_TEMP);
x64Emit_mov_mem32_reg64(x64GenContext, REG_RSP, offsetof(PPCInterpreter_t, temporaryFPR)+0, REG_RESV_TEMP); x64Emit_mov_mem32_reg64(x64GenContext, X86_REG_RSP, offsetof(PPCInterpreter_t, temporaryFPR)+0, REG_RESV_TEMP);
// load double from temporaryFPR // load double from temporaryFPR
x64Gen_movlpd_xmmReg_memReg64(x64GenContext, realRegisterXMM, REG_RSP, offsetof(PPCInterpreter_t, temporaryFPR)); x64Gen_movlpd_xmmReg_memReg64(x64GenContext, realRegisterXMM, X86_REG_RSP, offsetof(PPCInterpreter_t, temporaryFPR));
} }
} }
} }
@ -422,9 +422,9 @@ void PPCRecompilerX64Gen_imlInstr_psq_store(ppcImlGenContext_t* ppcImlGenContext
x64Gen_add_reg64Low32_reg64Low32(x64GenContext, memReg, memRegEx); x64Gen_add_reg64Low32_reg64Low32(x64GenContext, memReg, memRegEx);
} }
if (g_CPUFeatures.x86.movbe) if (g_CPUFeatures.x86.movbe)
x64Gen_movBETruncate_mem32Reg64PlusReg64_reg64(x64GenContext, REG_R13, memReg, memImmS32, REG_RESV_TEMP); x64Gen_movBETruncate_mem32Reg64PlusReg64_reg64(x64GenContext, X86_REG_R13, memReg, memImmS32, REG_RESV_TEMP);
else else
x64Gen_movTruncate_mem32Reg64PlusReg64_reg64(x64GenContext, REG_R13, memReg, memImmS32, REG_RESV_TEMP); x64Gen_movTruncate_mem32Reg64PlusReg64_reg64(x64GenContext, X86_REG_R13, memReg, memImmS32, REG_RESV_TEMP);
if (indexed) if (indexed)
{ {
x64Gen_sub_reg64Low32_reg64Low32(x64GenContext, memReg, memRegEx); x64Gen_sub_reg64Low32_reg64Low32(x64GenContext, memReg, memRegEx);
@ -439,7 +439,7 @@ void PPCRecompilerX64Gen_imlInstr_psq_store(ppcImlGenContext_t* ppcImlGenContext
x64Gen_movq_reg64_xmmReg(x64GenContext, REG_RESV_TEMP, REG_RESV_FPR_TEMP); x64Gen_movq_reg64_xmmReg(x64GenContext, REG_RESV_TEMP, REG_RESV_FPR_TEMP);
x64Gen_rol_reg64_imm8(x64GenContext, REG_RESV_TEMP, 32); // swap upper and lower DWORD x64Gen_rol_reg64_imm8(x64GenContext, REG_RESV_TEMP, 32); // swap upper and lower DWORD
x64Gen_bswap_reg64(x64GenContext, REG_RESV_TEMP); x64Gen_bswap_reg64(x64GenContext, REG_RESV_TEMP);
x64Gen_mov_mem64Reg64PlusReg64_reg64(x64GenContext, REG_RESV_TEMP, REG_R13, memReg, memImmS32); x64Gen_mov_mem64Reg64PlusReg64_reg64(x64GenContext, REG_RESV_TEMP, X86_REG_R13, memReg, memImmS32);
return; return;
} }
// store as integer // store as integer
@ -606,9 +606,9 @@ bool PPCRecompilerX64Gen_imlInstruction_fpr_store(PPCRecFunction_t* PPCRecFuncti
x64Gen_add_reg64Low32_reg64Low32(x64GenContext, realRegisterMem, realRegisterMem2); x64Gen_add_reg64Low32_reg64Low32(x64GenContext, realRegisterMem, realRegisterMem2);
} }
if(g_CPUFeatures.x86.movbe) if(g_CPUFeatures.x86.movbe)
x64Gen_movBETruncate_mem32Reg64PlusReg64_reg64(x64GenContext, REG_R13, realRegisterMem, imlInstruction->op_storeLoad.immS32, REG_RESV_TEMP); x64Gen_movBETruncate_mem32Reg64PlusReg64_reg64(x64GenContext, X86_REG_R13, realRegisterMem, imlInstruction->op_storeLoad.immS32, REG_RESV_TEMP);
else else
x64Gen_movTruncate_mem32Reg64PlusReg64_reg64(x64GenContext, REG_R13, realRegisterMem, imlInstruction->op_storeLoad.immS32, REG_RESV_TEMP); x64Gen_movTruncate_mem32Reg64PlusReg64_reg64(x64GenContext, X86_REG_R13, realRegisterMem, imlInstruction->op_storeLoad.immS32, REG_RESV_TEMP);
if( indexed ) if( indexed )
{ {
x64Gen_sub_reg64Low32_reg64Low32(x64GenContext, realRegisterMem, realRegisterMem2); x64Gen_sub_reg64Low32_reg64Low32(x64GenContext, realRegisterMem, realRegisterMem2);
@ -622,15 +622,15 @@ bool PPCRecompilerX64Gen_imlInstruction_fpr_store(PPCRecFunction_t* PPCRecFuncti
assert_dbg(); assert_dbg();
x64Gen_add_reg64Low32_reg64Low32(x64GenContext, realRegisterMem, realRegisterMem2); x64Gen_add_reg64Low32_reg64Low32(x64GenContext, realRegisterMem, realRegisterMem2);
} }
x64Gen_movsd_memReg64_xmmReg(x64GenContext, realRegisterXMM, REG_RSP, offsetof(PPCInterpreter_t, temporaryFPR)); x64Gen_movsd_memReg64_xmmReg(x64GenContext, realRegisterXMM, X86_REG_RSP, offsetof(PPCInterpreter_t, temporaryFPR));
// store double low part // store double low part
x64Emit_mov_reg64_mem32(x64GenContext, REG_RESV_TEMP, REG_RSP, offsetof(PPCInterpreter_t, temporaryFPR)+0); x64Emit_mov_reg64_mem32(x64GenContext, REG_RESV_TEMP, X86_REG_RSP, offsetof(PPCInterpreter_t, temporaryFPR)+0);
x64Gen_bswap_reg64Lower32bit(x64GenContext, REG_RESV_TEMP); x64Gen_bswap_reg64Lower32bit(x64GenContext, REG_RESV_TEMP);
x64Gen_movTruncate_mem32Reg64PlusReg64_reg64(x64GenContext, REG_R13, realRegisterMem, imlInstruction->op_storeLoad.immS32+4, REG_RESV_TEMP); x64Gen_movTruncate_mem32Reg64PlusReg64_reg64(x64GenContext, X86_REG_R13, realRegisterMem, imlInstruction->op_storeLoad.immS32+4, REG_RESV_TEMP);
// store double high part // store double high part
x64Emit_mov_reg64_mem32(x64GenContext, REG_RESV_TEMP, REG_RSP, offsetof(PPCInterpreter_t, temporaryFPR)+4); x64Emit_mov_reg64_mem32(x64GenContext, REG_RESV_TEMP, X86_REG_RSP, offsetof(PPCInterpreter_t, temporaryFPR)+4);
x64Gen_bswap_reg64Lower32bit(x64GenContext, REG_RESV_TEMP); x64Gen_bswap_reg64Lower32bit(x64GenContext, REG_RESV_TEMP);
x64Gen_movTruncate_mem32Reg64PlusReg64_reg64(x64GenContext, REG_R13, realRegisterMem, imlInstruction->op_storeLoad.immS32+0, REG_RESV_TEMP); x64Gen_movTruncate_mem32Reg64PlusReg64_reg64(x64GenContext, X86_REG_R13, realRegisterMem, imlInstruction->op_storeLoad.immS32+0, REG_RESV_TEMP);
if( indexed ) if( indexed )
{ {
x64Gen_sub_reg64Low32_reg64Low32(x64GenContext, realRegisterMem, realRegisterMem2); x64Gen_sub_reg64Low32_reg64Low32(x64GenContext, realRegisterMem, realRegisterMem2);
@ -645,12 +645,12 @@ bool PPCRecompilerX64Gen_imlInstruction_fpr_store(PPCRecFunction_t* PPCRecFuncti
if( realRegisterMem == realRegisterMem2 ) if( realRegisterMem == realRegisterMem2 )
assert_dbg(); assert_dbg();
x64Gen_add_reg64Low32_reg64Low32(x64GenContext, realRegisterMem, realRegisterMem2); x64Gen_add_reg64Low32_reg64Low32(x64GenContext, realRegisterMem, realRegisterMem2);
x64Gen_movTruncate_mem32Reg64PlusReg64_reg64(x64GenContext, REG_R13, realRegisterMem, imlInstruction->op_storeLoad.immS32, REG_RESV_TEMP); x64Gen_movTruncate_mem32Reg64PlusReg64_reg64(x64GenContext, X86_REG_R13, realRegisterMem, imlInstruction->op_storeLoad.immS32, REG_RESV_TEMP);
x64Gen_sub_reg64Low32_reg64Low32(x64GenContext, realRegisterMem, realRegisterMem2); x64Gen_sub_reg64Low32_reg64Low32(x64GenContext, realRegisterMem, realRegisterMem2);
} }
else else
{ {
x64Gen_movTruncate_mem32Reg64PlusReg64_reg64(x64GenContext, REG_R13, realRegisterMem, imlInstruction->op_storeLoad.immS32, REG_RESV_TEMP); x64Gen_movTruncate_mem32Reg64PlusReg64_reg64(x64GenContext, X86_REG_R13, realRegisterMem, imlInstruction->op_storeLoad.immS32, REG_RESV_TEMP);
} }
} }
else if(mode == PPCREC_FPR_ST_MODE_PSQ_FLOAT_PS0_PS1 || else if(mode == PPCREC_FPR_ST_MODE_PSQ_FLOAT_PS0_PS1 ||
@ -872,18 +872,18 @@ void PPCRecompilerX64Gen_imlInstruction_fpr_r_r(PPCRecFunction_t* PPCRecFunction
// update cr // update cr
sint32 crRegister = imlInstruction->crRegister; sint32 crRegister = imlInstruction->crRegister;
// if the parity bit is set (NaN) we need to manually set CR LT, GT and EQ to 0 (comisd/ucomisd sets the respective flags to 1 in case of NaN) // if the parity bit is set (NaN) we need to manually set CR LT, GT and EQ to 0 (comisd/ucomisd sets the respective flags to 1 in case of NaN)
x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_PARITY, REG_RSP, offsetof(PPCInterpreter_t, cr)+sizeof(uint8)*(crRegister*4+PPCREC_CR_BIT_SO)); // unordered x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_PARITY, X86_REG_RSP, offsetof(PPCInterpreter_t, cr)+sizeof(uint8)*(crRegister*4+PPCREC_CR_BIT_SO)); // unordered
sint32 jumpInstructionOffset1 = x64GenContext->codeBufferIndex; sint32 jumpInstructionOffset1 = x64GenContext->codeBufferIndex;
x64Gen_jmpc_near(x64GenContext, X86_CONDITION_PARITY, 0); x64Gen_jmpc_near(x64GenContext, X86_CONDITION_PARITY, 0);
x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_UNSIGNED_BELOW, REG_RSP, offsetof(PPCInterpreter_t, cr)+sizeof(uint8)*(crRegister*4+PPCREC_CR_BIT_LT)); // same as X64_CONDITION_CARRY x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_UNSIGNED_BELOW, X86_REG_RSP, offsetof(PPCInterpreter_t, cr)+sizeof(uint8)*(crRegister*4+PPCREC_CR_BIT_LT)); // same as X64_CONDITION_CARRY
x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_UNSIGNED_ABOVE, REG_RSP, offsetof(PPCInterpreter_t, cr)+sizeof(uint8)*(crRegister*4+PPCREC_CR_BIT_GT)); 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, REG_RSP, offsetof(PPCInterpreter_t, cr)+sizeof(uint8)*(crRegister*4+PPCREC_CR_BIT_EQ)); x64Gen_setcc_mem8(x64GenContext, X86_CONDITION_EQUAL, X86_REG_RSP, offsetof(PPCInterpreter_t, cr)+sizeof(uint8)*(crRegister*4+PPCREC_CR_BIT_EQ));
sint32 jumpInstructionOffset2 = x64GenContext->codeBufferIndex; sint32 jumpInstructionOffset2 = x64GenContext->codeBufferIndex;
x64Gen_jmpc_near(x64GenContext, X86_CONDITION_NONE, 0); x64Gen_jmpc_near(x64GenContext, X86_CONDITION_NONE, 0);
PPCRecompilerX64Gen_redirectRelativeJump(x64GenContext, jumpInstructionOffset1, x64GenContext->codeBufferIndex); PPCRecompilerX64Gen_redirectRelativeJump(x64GenContext, jumpInstructionOffset1, x64GenContext->codeBufferIndex);
x64Gen_mov_mem8Reg64_imm8(x64GenContext, REG_RSP, offsetof(PPCInterpreter_t, cr)+sizeof(uint8)*(crRegister*4+PPCREC_CR_BIT_LT), 0); x64Gen_mov_mem8Reg64_imm8(x64GenContext, X86_REG_RSP, offsetof(PPCInterpreter_t, cr)+sizeof(uint8)*(crRegister*4+PPCREC_CR_BIT_LT), 0);
x64Gen_mov_mem8Reg64_imm8(x64GenContext, REG_RSP, offsetof(PPCInterpreter_t, cr)+sizeof(uint8)*(crRegister*4+PPCREC_CR_BIT_GT), 0); x64Gen_mov_mem8Reg64_imm8(x64GenContext, X86_REG_RSP, offsetof(PPCInterpreter_t, cr)+sizeof(uint8)*(crRegister*4+PPCREC_CR_BIT_GT), 0);
x64Gen_mov_mem8Reg64_imm8(x64GenContext, REG_RSP, offsetof(PPCInterpreter_t, cr)+sizeof(uint8)*(crRegister*4+PPCREC_CR_BIT_EQ), 0); x64Gen_mov_mem8Reg64_imm8(x64GenContext, X86_REG_RSP, offsetof(PPCInterpreter_t, cr)+sizeof(uint8)*(crRegister*4+PPCREC_CR_BIT_EQ), 0);
PPCRecompilerX64Gen_redirectRelativeJump(x64GenContext, jumpInstructionOffset2, x64GenContext->codeBufferIndex); PPCRecompilerX64Gen_redirectRelativeJump(x64GenContext, jumpInstructionOffset2, x64GenContext->codeBufferIndex);
} }
else if( imlInstruction->operation == PPCREC_IML_OP_FPR_BOTTOM_FRES_TO_BOTTOM_AND_TOP ) else if( imlInstruction->operation == PPCREC_IML_OP_FPR_BOTTOM_FRES_TO_BOTTOM_AND_TOP )

View file

@ -60,7 +60,7 @@ void _x64Gen_writeMODRMDeprecated(x64GenContext_t* x64GenContext, sint32 dataReg
forceUseOffset = true; forceUseOffset = true;
} }
if (memRegisterB64 == REG_NONE) if (memRegisterB64 == X86_REG_NONE)
{ {
// memRegisterA64 + memImmS32 // memRegisterA64 + memImmS32
uint8 modRM = (dataRegister & 7) * 8 + (memRegisterA64 & 7); uint8 modRM = (dataRegister & 7) * 8 + (memRegisterA64 & 7);
@ -345,7 +345,7 @@ void x64Gen_mov_mem32Reg64_imm32(x64GenContext_t* x64GenContext, sint32 memRegis
void x64Gen_mov_mem64Reg64_imm32(x64GenContext_t* x64GenContext, sint32 memRegister, uint32 memImmU32, uint32 dataImmU32) void x64Gen_mov_mem64Reg64_imm32(x64GenContext_t* x64GenContext, sint32 memRegister, uint32 memImmU32, uint32 dataImmU32)
{ {
// MOV QWORD [<memReg>+<memImmU32>], dataImmU32 // MOV QWORD [<memReg>+<memImmU32>], dataImmU32
if( memRegister == REG_R14 ) if( memRegister == X86_REG_R14 )
{ {
sint32 memImmS32 = (sint32)memImmU32; sint32 memImmS32 = (sint32)memImmU32;
if( memImmS32 == 0 ) if( memImmS32 == 0 )
@ -377,7 +377,7 @@ void x64Gen_mov_mem64Reg64_imm32(x64GenContext_t* x64GenContext, sint32 memRegis
void x64Gen_mov_mem8Reg64_imm8(x64GenContext_t* x64GenContext, sint32 memRegister, uint32 memImmU32, uint8 dataImmU8) void x64Gen_mov_mem8Reg64_imm8(x64GenContext_t* x64GenContext, sint32 memRegister, uint32 memImmU32, uint8 dataImmU8)
{ {
// MOV BYTE [<memReg64>+<memImmU32>], dataImmU8 // MOV BYTE [<memReg64>+<memImmU32>], dataImmU8
if( memRegister == REG_RSP ) if( memRegister == X86_REG_RSP )
{ {
sint32 memImmS32 = (sint32)memImmU32; sint32 memImmS32 = (sint32)memImmU32;
if( memImmS32 >= -128 && memImmS32 <= 127 ) if( memImmS32 >= -128 && memImmS32 <= 127 )
@ -618,7 +618,7 @@ void _x64_op_reg64Low_mem8Reg64(x64GenContext_t* x64GenContext, sint32 dstRegist
if (memRegister64 >= 8) if (memRegister64 >= 8)
x64Gen_writeU8(x64GenContext, 0x41); x64Gen_writeU8(x64GenContext, 0x41);
x64Gen_writeU8(x64GenContext, opByte); x64Gen_writeU8(x64GenContext, opByte);
_x64Gen_writeMODRMDeprecated(x64GenContext, dstRegister, memRegister64, REG_NONE, memImmS32); _x64Gen_writeMODRMDeprecated(x64GenContext, dstRegister, memRegister64, X86_REG_NONE, memImmS32);
} }
void x64Gen_or_reg64Low8_mem8Reg64(x64GenContext_t* x64GenContext, sint32 dstRegister, sint32 memRegister64, sint32 memImmS32) void x64Gen_or_reg64Low8_mem8Reg64(x64GenContext_t* x64GenContext, sint32 dstRegister, sint32 memRegister64, sint32 memImmS32)
@ -725,7 +725,7 @@ void x64Gen_add_reg64Low32_imm32(x64GenContext_t* x64GenContext, sint32 srcRegis
} }
else else
{ {
if( srcRegister == REG_RAX ) if( srcRegister == X86_REG_RAX )
{ {
// special EAX short form // special EAX short form
x64Gen_writeU8(x64GenContext, 0x05); x64Gen_writeU8(x64GenContext, 0x05);
@ -765,7 +765,7 @@ void x64Gen_sub_reg64Low32_imm32(x64GenContext_t* x64GenContext, sint32 srcRegis
} }
else else
{ {
if( srcRegister == REG_RAX ) if( srcRegister == X86_REG_RAX )
{ {
// special EAX short form // special EAX short form
x64Gen_writeU8(x64GenContext, 0x2D); x64Gen_writeU8(x64GenContext, 0x2D);
@ -804,7 +804,7 @@ void x64Gen_sub_mem32reg64_imm32(x64GenContext_t* x64GenContext, sint32 memRegis
{ {
// SUB <mem32_memReg64>, <imm32> // SUB <mem32_memReg64>, <imm32>
sint32 immS32 = (sint32)immU32; sint32 immS32 = (sint32)immU32;
if( memRegister == REG_RSP ) if( memRegister == X86_REG_RSP )
{ {
if( memImmS32 >= 128 ) if( memImmS32 >= 128 )
{ {
@ -875,7 +875,7 @@ void x64Gen_adc_reg64Low32_imm32(x64GenContext_t* x64GenContext, sint32 srcRegis
} }
else else
{ {
if( srcRegister == REG_RAX ) if( srcRegister == X86_REG_RAX )
{ {
// special EAX short form // special EAX short form
x64Gen_writeU8(x64GenContext, 0x15); x64Gen_writeU8(x64GenContext, 0x15);
@ -893,7 +893,7 @@ void x64Gen_dec_mem32(x64GenContext_t* x64GenContext, sint32 memoryRegister, uin
{ {
// DEC dword [<reg64>+imm] // DEC dword [<reg64>+imm]
sint32 memoryImmS32 = (sint32)memoryImmU32; sint32 memoryImmS32 = (sint32)memoryImmU32;
if (memoryRegister != REG_RSP) if (memoryRegister != X86_REG_RSP)
assert_dbg(); // not supported yet assert_dbg(); // not supported yet
if (memoryImmS32 >= -128 && memoryImmS32 <= 127) if (memoryImmS32 >= -128 && memoryImmS32 <= 127)
{ {
@ -974,7 +974,7 @@ void x64Gen_and_reg64Low32_imm32(x64GenContext_t* x64GenContext, sint32 srcRegis
} }
else else
{ {
if( srcRegister == REG_RAX ) if( srcRegister == X86_REG_RAX )
{ {
// special EAX short form // special EAX short form
x64Gen_writeU8(x64GenContext, 0x25); x64Gen_writeU8(x64GenContext, 0x25);
@ -1019,7 +1019,7 @@ void x64Gen_test_reg64Low32_imm32(x64GenContext_t* x64GenContext, sint32 srcRegi
sint32 immS32 = (sint32)immU32; sint32 immS32 = (sint32)immU32;
if( srcRegister >= 8 ) if( srcRegister >= 8 )
x64Gen_writeU8(x64GenContext, 0x41); x64Gen_writeU8(x64GenContext, 0x41);
if( srcRegister == REG_RAX ) if( srcRegister == X86_REG_RAX )
{ {
// special EAX short form // special EAX short form
x64Gen_writeU8(x64GenContext, 0xA9); x64Gen_writeU8(x64GenContext, 0xA9);
@ -1045,7 +1045,7 @@ void x64Gen_cmp_reg64Low32_imm32(x64GenContext_t* x64GenContext, sint32 srcRegis
} }
else else
{ {
if( srcRegister == REG_RAX ) if( srcRegister == X86_REG_RAX )
{ {
// special RAX short form // special RAX short form
x64Gen_writeU8(x64GenContext, 0x3D); x64Gen_writeU8(x64GenContext, 0x3D);
@ -1075,7 +1075,7 @@ void x64Gen_cmp_reg64Low32_reg64Low32(x64GenContext_t* x64GenContext, sint32 des
void x64Gen_cmp_reg64Low32_mem32reg64(x64GenContext_t* x64GenContext, sint32 destRegister, sint32 memRegister, sint32 memImmS32) void x64Gen_cmp_reg64Low32_mem32reg64(x64GenContext_t* x64GenContext, sint32 destRegister, sint32 memRegister, sint32 memImmS32)
{ {
// CMP <destReg64_lowDWORD>, DWORD [<memRegister>+<immS32>] // CMP <destReg64_lowDWORD>, DWORD [<memRegister>+<immS32>]
if( memRegister == REG_RSP ) if( memRegister == X86_REG_RSP )
{ {
if( memImmS32 >= -128 && memImmS32 <= 127 ) if( memImmS32 >= -128 && memImmS32 <= 127 )
assert_dbg(); // todo -> Shorter instruction form assert_dbg(); // todo -> Shorter instruction form
@ -1105,7 +1105,7 @@ void x64Gen_or_reg64Low32_imm32(x64GenContext_t* x64GenContext, sint32 srcRegist
} }
else else
{ {
if( srcRegister == REG_RAX ) if( srcRegister == X86_REG_RAX )
{ {
// special EAX short form // special EAX short form
x64Gen_writeU8(x64GenContext, 0x0D); x64Gen_writeU8(x64GenContext, 0x0D);
@ -1165,7 +1165,7 @@ void x64Gen_xor_reg64Low32_imm32(x64GenContext_t* x64GenContext, sint32 srcRegis
} }
else else
{ {
if( srcRegister == REG_RAX ) if( srcRegister == X86_REG_RAX )
{ {
// special EAX short form // special EAX short form
x64Gen_writeU8(x64GenContext, 0x35); x64Gen_writeU8(x64GenContext, 0x35);
@ -1381,7 +1381,7 @@ void x64Gen_setcc_mem8(x64GenContext_t* x64GenContext, sint32 conditionType, sin
{ {
// SETcc [<reg64>+imm] // SETcc [<reg64>+imm]
sint32 memoryImmS32 = (sint32)memoryImmU32; sint32 memoryImmS32 = (sint32)memoryImmU32;
if( memoryRegister != REG_RSP ) if( memoryRegister != X86_REG_RSP )
assert_dbg(); // not supported assert_dbg(); // not supported
if( memoryRegister >= 8 ) if( memoryRegister >= 8 )
assert_dbg(); // not supported assert_dbg(); // not supported
@ -1620,7 +1620,7 @@ void x64Gen_bt_mem8(x64GenContext_t* x64GenContext, sint32 memoryRegister, uint3
{ {
// BT [<reg64>+imm], bitIndex (bit test) // BT [<reg64>+imm], bitIndex (bit test)
sint32 memoryImmS32 = (sint32)memoryImmU32; sint32 memoryImmS32 = (sint32)memoryImmU32;
if( memoryRegister != REG_RSP ) if( memoryRegister != X86_REG_RSP )
assert_dbg(); // not supported yet assert_dbg(); // not supported yet
if( memoryImmS32 >= -128 && memoryImmS32 <= 127 ) if( memoryImmS32 >= -128 && memoryImmS32 <= 127 )
{ {
@ -1655,7 +1655,7 @@ void x64Gen_jmp_imm32(x64GenContext_t* x64GenContext, uint32 destImm32)
void x64Gen_jmp_memReg64(x64GenContext_t* x64GenContext, sint32 memRegister, uint32 immU32) void x64Gen_jmp_memReg64(x64GenContext_t* x64GenContext, sint32 memRegister, uint32 immU32)
{ {
if( memRegister == REG_NONE ) if( memRegister == X86_REG_NONE )
{ {
assert_dbg(); assert_dbg();
} }

View file

@ -42,7 +42,7 @@ void x64Gen_movupd_xmmReg_memReg128(x64GenContext_t* x64GenContext, sint32 xmmRe
// SSE2 // SSE2
// move two doubles from memory into xmm register // move two doubles from memory into xmm register
// MOVUPD <xmm>, [<reg>+<imm>] // MOVUPD <xmm>, [<reg>+<imm>]
if( memRegister == REG_ESP ) if( memRegister == X86_REG_ESP )
{ {
// todo: Short form of instruction if memImmU32 is 0 or in -128 to 127 range // todo: Short form of instruction if memImmU32 is 0 or in -128 to 127 range
// 66 0F 10 84 E4 23 01 00 00 // 66 0F 10 84 E4 23 01 00 00
@ -54,7 +54,7 @@ void x64Gen_movupd_xmmReg_memReg128(x64GenContext_t* x64GenContext, sint32 xmmRe
x64Gen_writeU8(x64GenContext, 0xE4); x64Gen_writeU8(x64GenContext, 0xE4);
x64Gen_writeU32(x64GenContext, memImmU32); x64Gen_writeU32(x64GenContext, memImmU32);
} }
else if( memRegister == REG_NONE ) else if( memRegister == X86_REG_NONE )
{ {
assert_dbg(); assert_dbg();
//x64Gen_writeU8(x64GenContext, 0x66); //x64Gen_writeU8(x64GenContext, 0x66);
@ -74,7 +74,7 @@ void x64Gen_movupd_memReg128_xmmReg(x64GenContext_t* x64GenContext, sint32 xmmRe
// SSE2 // SSE2
// move two doubles from memory into xmm register // move two doubles from memory into xmm register
// MOVUPD [<reg>+<imm>], <xmm> // MOVUPD [<reg>+<imm>], <xmm>
if( memRegister == REG_ESP ) if( memRegister == X86_REG_ESP )
{ {
// todo: Short form of instruction if memImmU32 is 0 or in -128 to 127 range // todo: Short form of instruction if memImmU32 is 0 or in -128 to 127 range
x64Gen_writeU8(x64GenContext, 0x66); x64Gen_writeU8(x64GenContext, 0x66);
@ -85,7 +85,7 @@ void x64Gen_movupd_memReg128_xmmReg(x64GenContext_t* x64GenContext, sint32 xmmRe
x64Gen_writeU8(x64GenContext, 0xE4); x64Gen_writeU8(x64GenContext, 0xE4);
x64Gen_writeU32(x64GenContext, memImmU32); x64Gen_writeU32(x64GenContext, memImmU32);
} }
else if( memRegister == REG_NONE ) else if( memRegister == X86_REG_NONE )
{ {
assert_dbg(); assert_dbg();
//x64Gen_writeU8(x64GenContext, 0x66); //x64Gen_writeU8(x64GenContext, 0x66);
@ -104,7 +104,7 @@ void x64Gen_movddup_xmmReg_memReg64(x64GenContext_t* x64GenContext, sint32 xmmRe
{ {
// SSE3 // SSE3
// move one double from memory into lower and upper half of a xmm register // move one double from memory into lower and upper half of a xmm register
if( memRegister == REG_RSP ) if( memRegister == X86_REG_RSP )
{ {
// MOVDDUP <xmm>, [<reg>+<imm>] // MOVDDUP <xmm>, [<reg>+<imm>]
// todo: Short form of instruction if memImmU32 is 0 or in -128 to 127 range // todo: Short form of instruction if memImmU32 is 0 or in -128 to 127 range
@ -117,7 +117,7 @@ void x64Gen_movddup_xmmReg_memReg64(x64GenContext_t* x64GenContext, sint32 xmmRe
x64Gen_writeU8(x64GenContext, 0xE4); x64Gen_writeU8(x64GenContext, 0xE4);
x64Gen_writeU32(x64GenContext, memImmU32); x64Gen_writeU32(x64GenContext, memImmU32);
} }
else if( memRegister == REG_R15 ) else if( memRegister == X86_REG_R15 )
{ {
// MOVDDUP <xmm>, [<reg>+<imm>] // MOVDDUP <xmm>, [<reg>+<imm>]
// todo: Short form of instruction if memImmU32 is 0 or in -128 to 127 range // todo: Short form of instruction if memImmU32 is 0 or in -128 to 127 range
@ -129,7 +129,7 @@ void x64Gen_movddup_xmmReg_memReg64(x64GenContext_t* x64GenContext, sint32 xmmRe
x64Gen_writeU8(x64GenContext, 0x87+(xmmRegister&7)*8); x64Gen_writeU8(x64GenContext, 0x87+(xmmRegister&7)*8);
x64Gen_writeU32(x64GenContext, memImmU32); x64Gen_writeU32(x64GenContext, memImmU32);
} }
else if( memRegister == REG_NONE ) else if( memRegister == X86_REG_NONE )
{ {
// MOVDDUP <xmm>, [<imm>] // MOVDDUP <xmm>, [<imm>]
// 36 F2 0F 12 05 - 00 00 00 00 // 36 F2 0F 12 05 - 00 00 00 00
@ -183,7 +183,7 @@ void x64Gen_movsd_memReg64_xmmReg(x64GenContext_t* x64GenContext, sint32 xmmRegi
{ {
// SSE2 // SSE2
// move lower 64bits (double) of xmm register to memory location // move lower 64bits (double) of xmm register to memory location
if( memRegister == REG_NONE ) if( memRegister == X86_REG_NONE )
{ {
// MOVSD [<imm>], <xmm> // MOVSD [<imm>], <xmm>
// F2 0F 11 05 - 45 23 01 00 // F2 0F 11 05 - 45 23 01 00
@ -195,7 +195,7 @@ void x64Gen_movsd_memReg64_xmmReg(x64GenContext_t* x64GenContext, sint32 xmmRegi
//x64Gen_writeU8(x64GenContext, 0x05+xmmRegister*8); //x64Gen_writeU8(x64GenContext, 0x05+xmmRegister*8);
//x64Gen_writeU32(x64GenContext, memImmU32); //x64Gen_writeU32(x64GenContext, memImmU32);
} }
else if( memRegister == REG_RSP ) else if( memRegister == X86_REG_RSP )
{ {
// MOVSD [RSP+<imm>], <xmm> // MOVSD [RSP+<imm>], <xmm>
// F2 0F 11 84 24 - 33 22 11 00 // F2 0F 11 84 24 - 33 22 11 00
@ -217,7 +217,7 @@ void x64Gen_movlpd_xmmReg_memReg64(x64GenContext_t* x64GenContext, sint32 xmmReg
{ {
// SSE3 // SSE3
// move one double from memory into lower half of a xmm register, leave upper half unchanged(?) // move one double from memory into lower half of a xmm register, leave upper half unchanged(?)
if( memRegister == REG_NONE ) if( memRegister == X86_REG_NONE )
{ {
// MOVLPD <xmm>, [<imm>] // MOVLPD <xmm>, [<imm>]
//x64Gen_writeU8(x64GenContext, 0x66); //x64Gen_writeU8(x64GenContext, 0x66);
@ -227,7 +227,7 @@ void x64Gen_movlpd_xmmReg_memReg64(x64GenContext_t* x64GenContext, sint32 xmmReg
//x64Gen_writeU32(x64GenContext, memImmU32); //x64Gen_writeU32(x64GenContext, memImmU32);
assert_dbg(); assert_dbg();
} }
else if( memRegister == REG_RSP ) else if( memRegister == X86_REG_RSP )
{ {
// MOVLPD <xmm>, [<reg64>+<imm>] // MOVLPD <xmm>, [<reg64>+<imm>]
// 66 0F 12 84 24 - 33 22 11 00 // 66 0F 12 84 24 - 33 22 11 00
@ -346,11 +346,11 @@ void x64Gen_mulpd_xmmReg_xmmReg(x64GenContext_t* x64GenContext, sint32 xmmRegist
void x64Gen_mulpd_xmmReg_memReg128(x64GenContext_t* x64GenContext, sint32 xmmRegister, sint32 memRegister, uint32 memImmU32) void x64Gen_mulpd_xmmReg_memReg128(x64GenContext_t* x64GenContext, sint32 xmmRegister, sint32 memRegister, uint32 memImmU32)
{ {
// SSE2 // SSE2
if (memRegister == REG_NONE) if (memRegister == X86_REG_NONE)
{ {
assert_dbg(); assert_dbg();
} }
else if (memRegister == REG_R14) else if (memRegister == X86_REG_R14)
{ {
x64Gen_writeU8(x64GenContext, 0x66); x64Gen_writeU8(x64GenContext, 0x66);
x64Gen_writeU8(x64GenContext, (xmmRegister < 8) ? 0x41 : 0x45); x64Gen_writeU8(x64GenContext, (xmmRegister < 8) ? 0x41 : 0x45);
@ -402,7 +402,7 @@ void x64Gen_comisd_xmmReg_mem64Reg64(x64GenContext_t* x64GenContext, sint32 xmmR
{ {
// SSE2 // SSE2
// compare bottom double with double from memory location // compare bottom double with double from memory location
if( memoryReg == REG_R15 ) if( memoryReg == X86_REG_R15 )
{ {
x64Gen_writeU8(x64GenContext, 0x66); x64Gen_writeU8(x64GenContext, 0x66);
x64Gen_genSSEVEXPrefix1(x64GenContext, xmmRegisterDest, true); x64Gen_genSSEVEXPrefix1(x64GenContext, xmmRegisterDest, true);
@ -430,7 +430,7 @@ void x64Gen_comiss_xmmReg_mem64Reg64(x64GenContext_t* x64GenContext, sint32 xmmR
{ {
// SSE2 // SSE2
// compare bottom float with float from memory location // compare bottom float with float from memory location
if (memoryReg == REG_R15) if (memoryReg == X86_REG_R15)
{ {
x64Gen_genSSEVEXPrefix1(x64GenContext, xmmRegisterDest, true); x64Gen_genSSEVEXPrefix1(x64GenContext, xmmRegisterDest, true);
x64Gen_writeU8(x64GenContext, 0x0F); x64Gen_writeU8(x64GenContext, 0x0F);
@ -446,7 +446,7 @@ void x64Gen_orps_xmmReg_mem128Reg64(x64GenContext_t* x64GenContext, sint32 xmmRe
{ {
// SSE2 // SSE2
// and xmm register with 128 bit value from memory // and xmm register with 128 bit value from memory
if( memReg == REG_R15 ) if( memReg == X86_REG_R15 )
{ {
x64Gen_genSSEVEXPrefix2(x64GenContext, memReg, xmmRegisterDest, false); x64Gen_genSSEVEXPrefix2(x64GenContext, memReg, xmmRegisterDest, false);
x64Gen_writeU8(x64GenContext, 0x0F); x64Gen_writeU8(x64GenContext, 0x0F);
@ -462,7 +462,7 @@ void x64Gen_xorps_xmmReg_mem128Reg64(x64GenContext_t* x64GenContext, sint32 xmmR
{ {
// SSE2 // SSE2
// xor xmm register with 128 bit value from memory // xor xmm register with 128 bit value from memory
if( memReg == REG_R15 ) if( memReg == X86_REG_R15 )
{ {
x64Gen_genSSEVEXPrefix1(x64GenContext, xmmRegisterDest, true); // todo: should be x64Gen_genSSEVEXPrefix2() with memReg? x64Gen_genSSEVEXPrefix1(x64GenContext, xmmRegisterDest, true); // todo: should be x64Gen_genSSEVEXPrefix2() with memReg?
x64Gen_writeU8(x64GenContext, 0x0F); x64Gen_writeU8(x64GenContext, 0x0F);
@ -477,11 +477,11 @@ void x64Gen_xorps_xmmReg_mem128Reg64(x64GenContext_t* x64GenContext, sint32 xmmR
void x64Gen_andpd_xmmReg_memReg128(x64GenContext_t* x64GenContext, sint32 xmmRegister, sint32 memRegister, uint32 memImmU32) void x64Gen_andpd_xmmReg_memReg128(x64GenContext_t* x64GenContext, sint32 xmmRegister, sint32 memRegister, uint32 memImmU32)
{ {
// SSE2 // SSE2
if (memRegister == REG_NONE) if (memRegister == X86_REG_NONE)
{ {
assert_dbg(); assert_dbg();
} }
else if (memRegister == REG_R14) else if (memRegister == X86_REG_R14)
{ {
x64Gen_writeU8(x64GenContext, 0x66); x64Gen_writeU8(x64GenContext, 0x66);
x64Gen_writeU8(x64GenContext, (xmmRegister < 8) ? 0x41 : 0x45); x64Gen_writeU8(x64GenContext, (xmmRegister < 8) ? 0x41 : 0x45);
@ -500,7 +500,7 @@ void x64Gen_andps_xmmReg_mem128Reg64(x64GenContext_t* x64GenContext, sint32 xmmR
{ {
// SSE2 // SSE2
// and xmm register with 128 bit value from memory // and xmm register with 128 bit value from memory
if( memReg == REG_R15 ) if( memReg == X86_REG_R15 )
{ {
x64Gen_genSSEVEXPrefix1(x64GenContext, xmmRegisterDest, true); // todo: should be x64Gen_genSSEVEXPrefix2() with memReg? x64Gen_genSSEVEXPrefix1(x64GenContext, xmmRegisterDest, true); // todo: should be x64Gen_genSSEVEXPrefix2() with memReg?
x64Gen_writeU8(x64GenContext, 0x0F); x64Gen_writeU8(x64GenContext, 0x0F);
@ -526,7 +526,7 @@ void x64Gen_pcmpeqd_xmmReg_mem128Reg64(x64GenContext_t* x64GenContext, sint32 xm
{ {
// SSE2 // SSE2
// doubleword integer compare // doubleword integer compare
if( memReg == REG_R15 ) if( memReg == X86_REG_R15 )
{ {
x64Gen_writeU8(x64GenContext, 0x66); x64Gen_writeU8(x64GenContext, 0x66);
x64Gen_genSSEVEXPrefix1(x64GenContext, xmmRegisterDest, true); x64Gen_genSSEVEXPrefix1(x64GenContext, xmmRegisterDest, true);
@ -608,7 +608,7 @@ void x64Gen_cvtpi2pd_xmmReg_mem64Reg64(x64GenContext_t* x64GenContext, sint32 xm
{ {
// SSE2 // SSE2
// converts two signed 32bit integers to two doubles // converts two signed 32bit integers to two doubles
if( memReg == REG_RSP ) if( memReg == X86_REG_RSP )
{ {
x64Gen_writeU8(x64GenContext, 0x66); x64Gen_writeU8(x64GenContext, 0x66);
x64Gen_genSSEVEXPrefix1(x64GenContext, xmmRegisterDest, false); x64Gen_genSSEVEXPrefix1(x64GenContext, xmmRegisterDest, false);
@ -682,7 +682,7 @@ void x64Gen_rcpss_xmmReg_xmmReg(x64GenContext_t* x64GenContext, sint32 xmmRegist
void x64Gen_mulss_xmmReg_memReg64(x64GenContext_t* x64GenContext, sint32 xmmRegister, sint32 memRegister, uint32 memImmU32) void x64Gen_mulss_xmmReg_memReg64(x64GenContext_t* x64GenContext, sint32 xmmRegister, sint32 memRegister, uint32 memImmU32)
{ {
// SSE2 // SSE2
if( memRegister == REG_NONE ) if( memRegister == X86_REG_NONE )
{ {
assert_dbg(); assert_dbg();
} }

View file

@ -274,18 +274,18 @@ bool PPCRecompiler_ApplyIMLPasses(ppcImlGenContext_t& ppcImlGenContext)
} }
IMLRegisterAllocatorParameters raParam; IMLRegisterAllocatorParameters raParam;
raParam.physicalRegisterPool.SetAvailable(REG_RAX); raParam.physicalRegisterPool.SetAvailable(X86_REG_RAX);
raParam.physicalRegisterPool.SetAvailable(REG_RDX); raParam.physicalRegisterPool.SetAvailable(X86_REG_RDX);
raParam.physicalRegisterPool.SetAvailable(REG_RBX); raParam.physicalRegisterPool.SetAvailable(X86_REG_RBX);
raParam.physicalRegisterPool.SetAvailable(REG_RBP); raParam.physicalRegisterPool.SetAvailable(X86_REG_RBP);
raParam.physicalRegisterPool.SetAvailable(REG_RSI); raParam.physicalRegisterPool.SetAvailable(X86_REG_RSI);
raParam.physicalRegisterPool.SetAvailable(REG_RDI); raParam.physicalRegisterPool.SetAvailable(X86_REG_RDI);
raParam.physicalRegisterPool.SetAvailable(REG_R8); raParam.physicalRegisterPool.SetAvailable(X86_REG_R8);
raParam.physicalRegisterPool.SetAvailable(REG_R9); raParam.physicalRegisterPool.SetAvailable(X86_REG_R9);
raParam.physicalRegisterPool.SetAvailable(REG_R10); raParam.physicalRegisterPool.SetAvailable(X86_REG_R10);
raParam.physicalRegisterPool.SetAvailable(REG_R11); raParam.physicalRegisterPool.SetAvailable(X86_REG_R11);
raParam.physicalRegisterPool.SetAvailable(REG_R12); raParam.physicalRegisterPool.SetAvailable(X86_REG_R12);
raParam.physicalRegisterPool.SetAvailable(REG_RCX); raParam.physicalRegisterPool.SetAvailable(X86_REG_RCX);
IMLRegisterAllocator_AllocateRegisters(&ppcImlGenContext, raParam); IMLRegisterAllocator_AllocateRegisters(&ppcImlGenContext, raParam);