Merge branch 'master' into pspui

This commit is contained in:
Howard Su 2023-12-07 23:54:54 +08:00 committed by GitHub
commit 8791a7acb6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 177 additions and 69 deletions

View file

@ -58,7 +58,7 @@ We're on Discord, come catch up with the latest news. Chaos ensured. https://dis
## Credits
- StrmnNrmn - For bringing this project to us
- Kreationz, salvy, Corn, Chilly Willy, Azimer, Shinydude100 and missed folks for past contributions
- Kreationz, Howard0Su salvy, Corn, Chilly Willy, Azimer, Shinydude100 and missed folks for past contributions
- MasterFeizz for 3DS Support / ARM DynaRec
- Xerpi / Rinnegatamante / TheOfficialFloW for PS Vita and ARM Contributions
- z2442 & Wally: Compilation improvements and updating, optimizations

View file

@ -133,12 +133,13 @@ endif()
if(NOT WIN32)
add_compile_definitions(DAEDALUS_THREAD_CALL_TYPE=${})
add_compile_definitions(DAEDALUS_VARARG_CALL_TYPE=${})
add_compile_options("-g")
add_compile_options("-ffast-math")
endif()
if(UNIX)
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION FALSE)
if(NOT APPLE)
add_link_options("-Wl,-z,noexecstack")
endif()
endif(UNIX)
if (APPLE)

View file

@ -245,11 +245,21 @@ void CAssemblyWriterX64::NOT(EIntelReg reg1, bool is64)
//*****************************************************************************
// Use short form (0x83c0) if data is just one byte!
//*****************************************************************************
void CAssemblyWriterX64::ADDI(EIntelReg reg, s32 data)
void CAssemblyWriterX64::ADDI(EIntelReg reg, s32 data, bool is64)
{
if (data == 0)
return;
if (is64)
{
u8 first_byte = 0x48;
if (reg >= R8_CODE) {
first_byte |= 0x4;
reg = EIntelReg(reg & 7);
}
EmitBYTE(first_byte);
}
if (data <= 127 && data > -127)
{
EmitBYTE(0x83);
@ -293,14 +303,24 @@ void CAssemblyWriterX64::ADCI(EIntelReg reg, s32 data)
//*****************************************************************************
//
//*****************************************************************************
void CAssemblyWriterX64::ANDI(EIntelReg reg, u32 data)
void CAssemblyWriterX64::ANDI(EIntelReg reg1, u32 data, bool is64)
{
if (is64) {
u8 first_byte = 0x48;
if (reg1 >= R8_CODE) {
first_byte |= 0x4;
reg1 = EIntelReg(reg1 & 7);
}
EmitBYTE(first_byte);
}
/*if (reg == EAX_CODE)
EmitBYTE(0x25);
else */
{
EmitBYTE(0x81);
EmitBYTE(0xe0 | reg);
EmitBYTE(0xe0 | reg1);
}
EmitDWORD(data);
}
@ -308,14 +328,24 @@ void CAssemblyWriterX64::ANDI(EIntelReg reg, u32 data)
//*****************************************************************************
//
//*****************************************************************************
void CAssemblyWriterX64::ORI(EIntelReg reg, u32 data)
void CAssemblyWriterX64::ORI(EIntelReg reg1, u32 data, bool is64)
{
if (is64) {
u8 first_byte = 0x48;
if (reg1 >= R8_CODE) {
first_byte |= 0x4;
reg1 = EIntelReg(reg1 & 7);
}
EmitBYTE(first_byte);
}
/*if (reg == EAX_CODE)
EmitBYTE(0x0D);
else*/
{
EmitBYTE(0x81);
EmitBYTE(0xc8 | reg);
EmitBYTE(0xc8 | reg1);
}
EmitDWORD(data);
}
@ -323,27 +353,30 @@ void CAssemblyWriterX64::ORI(EIntelReg reg, u32 data)
//*****************************************************************************
//
//*****************************************************************************
void CAssemblyWriterX64::XOR_I32(EIntelReg reg, u32 data)
void CAssemblyWriterX64::XORI(EIntelReg reg, u32 data, bool is64)
{
if (is64) {
u8 first_byte = 0x48;
if (reg >= R8_CODE) {
first_byte |= 0x4;
reg = EIntelReg(reg & 7);
}
/*if (reg == EAX_CODE)
EmitBYTE(0x35);
else */
EmitBYTE(first_byte);
}
if (data <= 255)
{
EmitBYTE(0x83);
EmitBYTE(0xf0 | reg);
EmitBYTE((u8)data);
}
else
{
EmitBYTE(0x81);
EmitBYTE(0xf0 | reg);
EmitDWORD(data);
}
EmitDWORD(data);
}
//*****************************************************************************
//
//*****************************************************************************
void CAssemblyWriterX64::XOR_I8(EIntelReg reg, u8 data)
{
EmitBYTE(0x83);
EmitBYTE(0xf0 | reg);
EmitBYTE(data);
}
//*****************************************************************************
@ -673,7 +706,7 @@ void CAssemblyWriterX64::MOV(EIntelReg reg1, EIntelReg reg2, bool is64)
}
EmitBYTE(first_byte);
}
}
EmitBYTE(0x8b);
EmitBYTE(0xc0 | (reg1<<3) | reg2);
@ -1014,31 +1047,19 @@ void CAssemblyWriterX64::FSTP_MEMp32( u32 * pmem )
//*****************************************************************************
//
//*****************************************************************************
void CAssemblyWriterX64::FLD_MEMp64( u32 * memlo, u32 * memhi )
void CAssemblyWriterX64::FLD_MEMp64( u64 * mem)
{
// static s64 longtemp;
// MOV_REG_MEM(EAX_CODE, (u8*)(memlo) );
// MOV_REG_MEM(EDX_CODE, (u8*)(memhi) );
// MOV_MEM_REG(((u8*)&longtemp) + 0, EAX_CODE);
// MOV_MEM_REG(((u8*)&longtemp) + 4, EDX_CODE);
// EmitWORD(0x05dd);
// EmitDWORD( u32(&longtemp) );
EmitWORD(0xabdf);
EmitADDR(mem); // df ab 78 56 34 12 fild QWORD PTR [rbx+0x12345678]
}
//*****************************************************************************
//
//*****************************************************************************
void CAssemblyWriterX64::FSTP_MEMp64( u32 * memlo, u32 * memhi )
void CAssemblyWriterX64::FSTP_MEMp64( u64 * mem)
{
// static s64 longtemp;
// EmitWORD(0x1ddd);
// EmitDWORD( u32(&longtemp) );
// MOV_REG_MEM(EAX_CODE, ((u8*)(&longtemp))+0);
// MOV_REG_MEM(EDX_CODE, ((u8*)(&longtemp))+4);
// MOV_MEM_REG(((u8*)(memlo)), EAX_CODE);
// MOV_MEM_REG(((u8*)(memhi)), EDX_CODE);
EmitWORD(0x9bdd);
EmitADDR(mem); // dd 9b 78 56 34 12 fstp QWORD PTR [rbx+0x12345678]
}
//*****************************************************************************

View file

@ -77,12 +77,11 @@ class CAssemblyWriterX64
void XOR(EIntelReg reg1, EIntelReg reg2, bool is64 = false);
void NOT(EIntelReg reg1, bool is64 = false);
void ADDI(EIntelReg reg, s32 data);
void ADDI(EIntelReg reg, s32 data, bool is64 = false);
void ADCI(EIntelReg reg, s32 data);
void ANDI(EIntelReg reg, u32 data);
void ORI(EIntelReg reg, u32 data);
void XOR_I32(EIntelReg reg, u32 data);
void XOR_I8(EIntelReg reg, u8 data);
void ANDI(EIntelReg reg, u32 data, bool is64 = false);
void ORI(EIntelReg reg, u32 data, bool is64 = false);
void XORI(EIntelReg reg, u32 data, bool is64 = false);
void SHLI(EIntelReg reg, u8 sa);
void SHRI(EIntelReg reg, u8 sa);
@ -164,8 +163,8 @@ class CAssemblyWriterX64
void FILD_MEM( u32 * pmem );
void FLD_MEMp32( u32 * pmem );
void FSTP_MEMp32( u32 * pmem );
void FLD_MEMp64( u32 * memlo, u32 * memhi );
void FSTP_MEMp64( u32 * memlo, u32 * memhi );
void FLD_MEMp64( u64 * pmem );
void FSTP_MEMp64( u64 * pmem );
void FISTP_MEMp( u32 * pmem );
void FLD( u32 i );

View file

@ -521,6 +521,9 @@ CJumpLocation CCodeGeneratorX64::GenerateOpCode( const STraceEntry& ti, bool bra
case OP_JAL: GenerateJAL( address ); handled = true; break;
case OP_CACHE: GenerateCACHE( base, op_code.immediate, rt ); handled = true; break;
case OP_DADDI: GenerateDADDIU( rt, rs, s16( op_code.immediate ) ); handled = true; break;
case OP_DADDIU: GenerateDADDIU( rt, rs, s16( op_code.immediate ) ); handled = true; break;
// For LW, SW, SWC1, LB etc, only generate an exception handler if access wasn't done through the stack (handle = false)
// This will have to be reworked once we handle accesses other than the stack!
case OP_SW:
@ -587,12 +590,17 @@ CJumpLocation CCodeGeneratorX64::GenerateOpCode( const STraceEntry& ti, bool bra
case SpecOp_XOR: GenerateXOR( rd, rs, rt ); handled = true; break;
case SpecOp_NOR: GenerateNOR( rd, rs, rt ); handled = true; break;
case SpecOp_ADD: GenerateADDU( rd, rs, rt ); handled = true; break;
// this break something don't know yet
//case SpecOp_ADDU: GenerateADDU( rd, rs, rt ); handled = true; break;
case SpecOp_ADD:
case SpecOp_ADDU: GenerateADDU( rd, rs, rt ); handled = true; break;
case SpecOp_SUB: GenerateSUBU( rd, rs, rt ); handled = true; break;
case SpecOp_DADD:
case SpecOp_DADDU: GenerateDADDU( rd, rs, rt ); handled = true; break;
case SpecOp_SUB:
case SpecOp_SUBU: GenerateSUBU( rd, rs, rt ); handled = true; break;
case SpecOp_DSUB:
case SpecOp_DSUBU: GenerateDSUBU( rd, rs, rt ); handled = true; break;
}
}
break;
@ -721,7 +729,7 @@ void CCodeGeneratorX64::GenerateLoad(EN64Reg base, s16 offset, u8 twiddle, u8 bi
else
{
ADDI(RCX_CODE, offset);
XOR_I8(RCX_CODE, twiddle);
XORI(RCX_CODE, twiddle);
ADD(RCX_CODE, R15_CODE, true);
switch(bits)
{
@ -769,6 +777,8 @@ bool CCodeGeneratorX64::GenerateSWC1( u32 ft, EN64Reg base, s16 offset )
return false;
}
//u32 address = (u32)( gGPR[op_code.base]._s32_0 + (s32)(s16)op_code.immediate );
// Write32Bits(address, gGPR[op_code.rt]._u32_0);
bool CCodeGeneratorX64::GenerateSW( EN64Reg rt, EN64Reg base, s16 offset )
{
if (gDynarecStackOptimisation && base == N64Reg_SP)
@ -831,16 +841,32 @@ bool CCodeGeneratorX64::GenerateLH( EN64Reg rt, EN64Reg base, s16 offset )
return false;
}
//gGPR[op_code.rt]._s64 = (s64)(s32)((s32)(s16)op_code.immediate<<16);
void CCodeGeneratorX64::GenerateLUI( EN64Reg rt, s16 immediate )
{
if (rt == 0) return;
MOVI(RAX_CODE, s32(immediate) << 16);
CDQ();
MOV_MEM_REG(&gCPUState.CPU[rt]._u32_0, RAX_CODE);
MOV_MEM_REG(&gCPUState.CPU[rt]._u32_1, RDX_CODE);
}
//gGPR[op_code.rt]._s64 = gGPR[op_code.rs]._s64 + (s32)(s16)op_code.immediate;
void CCodeGeneratorX64::GenerateDADDIU( EN64Reg rt, EN64Reg rs, s16 immediate )
{
if (rt == 0) return;
MOV64_REG_MEM(RAX_CODE, &gCPUState.CPU[rs]._u64);
ADDI(RAX_CODE, immediate, true);
MOV64_MEM_REG(&gCPUState.CPU[rt]._u64, RAX_CODE);
}
// gGPR[op_code.rt]._s64 = (s64)(s32)(gGPR[op_code.rs]._s32_0 + (s32)(s16)op_code.immediate);
void CCodeGeneratorX64::GenerateADDIU( EN64Reg rt, EN64Reg rs, s16 immediate )
{
if (rt == 0) return;
MOV_REG_MEM(RAX_CODE, &gCPUState.CPU[rs]._u32_0);
ADDI(RAX_CODE, immediate);
CDQ();
@ -848,35 +874,42 @@ void CCodeGeneratorX64::GenerateADDIU( EN64Reg rt, EN64Reg rs, s16 immediate )
MOV_MEM_REG(&gCPUState.CPU[rt]._u32_1, RDX_CODE);
}
//gGPR[op_code.rt]._u64 = gGPR[op_code.rs]._u64 & (u64)(u16)op_code.immediate;
void CCodeGeneratorX64::GenerateANDI( EN64Reg rt, EN64Reg rs, u16 immediate )
{
MOV_REG_MEM(RAX_CODE, &gCPUState.CPU[rs]._u32_0);
ANDI(RAX_CODE, immediate);
CDQ();
MOV_MEM_REG(&gCPUState.CPU[rt]._u32_0, RAX_CODE);
MOV_MEM_REG(&gCPUState.CPU[rt]._u32_1, RDX_CODE);
if (rt == 0) return;
MOV64_REG_MEM(RAX_CODE, &gCPUState.CPU[rs]._u64);
ANDI(RAX_CODE, immediate, true);
MOV64_MEM_REG(&gCPUState.CPU[rt]._u64, RAX_CODE);
}
//gGPR[op_code.rt]._u64 = gGPR[op_code.rs]._u64 | (u64)(u16)op_code.immediate;
void CCodeGeneratorX64::GenerateORI( EN64Reg rt, EN64Reg rs, u16 immediate )
{
MOV_REG_MEM(RAX_CODE, &gCPUState.CPU[rs]._u32_0);
ORI(RAX_CODE, immediate);
CDQ();
MOV_MEM_REG(&gCPUState.CPU[rt]._u32_0, RAX_CODE);
MOV_MEM_REG(&gCPUState.CPU[rt]._u32_1, RDX_CODE);
if (rt == 0) return;
MOV64_REG_MEM(RAX_CODE, &gCPUState.CPU[rs]._u64);
ORI(RAX_CODE, immediate, true);
MOV64_MEM_REG(&gCPUState.CPU[rt]._u64, RAX_CODE);
}
// gGPR[op_code.rt]._u64 = gGPR[op_code.rs]._u64 ^ (u64)(u16)op_code.immediate;
void CCodeGeneratorX64::GenerateXORI( EN64Reg rt, EN64Reg rs, u16 immediate )
{
MOV_REG_MEM(RAX_CODE, &gCPUState.CPU[rs]._u32_0);
XOR_I32(RAX_CODE, immediate);
CDQ();
MOV_MEM_REG(&gCPUState.CPU[rt]._u32_0, RAX_CODE);
MOV_MEM_REG(&gCPUState.CPU[rt]._u32_1, RDX_CODE);
if (rt == 0) return;
MOV64_REG_MEM(RAX_CODE, &gCPUState.CPU[rs]._u64);
XORI(RAX_CODE, immediate, true);
MOV64_MEM_REG(&gCPUState.CPU[rt]._u64, RAX_CODE);
}
// gGPR[ op_code.rd ]._s64 = (s64)(s32)( (gGPR[ op_code.rt ]._u32_0 << op_code.sa) & 0xFFFFFFFF );
void CCodeGeneratorX64::GenerateSLL( EN64Reg rd, EN64Reg rt, u32 sa )
{
// NOP
if (rd == 0) return;
MOV_REG_MEM(RAX_CODE, &gCPUState.CPU[rt]._u32_0);
SHLI(RAX_CODE, sa);
CDQ();
@ -884,8 +917,11 @@ void CCodeGeneratorX64::GenerateSLL( EN64Reg rd, EN64Reg rt, u32 sa )
MOV_MEM_REG(&gCPUState.CPU[rd]._u32_1, RDX_CODE);
}
// gGPR[ op_code.rd ]._s64 = (s64)(s32)( gGPR[ op_code.rt ]._u32_0 >> op_code.sa );
void CCodeGeneratorX64::GenerateSRL( EN64Reg rd, EN64Reg rt, u32 sa )
{
if (rd == 0) return;
MOV_REG_MEM(RAX_CODE, &gCPUState.CPU[rt]._u32_0);
SHRI(RAX_CODE, sa);
CDQ();
@ -893,8 +929,11 @@ void CCodeGeneratorX64::GenerateSRL( EN64Reg rd, EN64Reg rt, u32 sa )
MOV_MEM_REG(&gCPUState.CPU[rd]._u32_1, RDX_CODE);
}
//gGPR[ op_code.rd ]._s64 = (s64)(s32)( gGPR[ op_code.rt ]._s32_0 >> op_code.sa );
void CCodeGeneratorX64::GenerateSRA( EN64Reg rd, EN64Reg rt, u32 sa )
{
if (rd == 0) return;
MOV_REG_MEM(RAX_CODE, &gCPUState.CPU[rt]._u32_0);
SARI(RAX_CODE, sa);
CDQ();
@ -902,32 +941,44 @@ void CCodeGeneratorX64::GenerateSRA( EN64Reg rd, EN64Reg rt, u32 sa )
MOV_MEM_REG(&gCPUState.CPU[rd]._u32_1, RDX_CODE);
}
//gGPR[ op_code.rd ]._u64 = gGPR[ op_code.rs ]._u64 | gGPR[ op_code.rt ]._u64;
void CCodeGeneratorX64::GenerateOR( EN64Reg rd, EN64Reg rs, EN64Reg rt )
{
if (rd == 0) return;
MOV64_REG_MEM(RAX_CODE, &gCPUState.CPU[rs]._u64);
MOV64_REG_MEM(RCX_CODE, &gCPUState.CPU[rt]._u64);
OR(RAX_CODE, RCX_CODE, true);
MOV64_MEM_REG(&gCPUState.CPU[rd]._u64, RAX_CODE);
}
//gGPR[ op_code.rd ]._u64 = gGPR[ op_code.rs ]._u64 & gGPR[ op_code.rt ]._u64;
void CCodeGeneratorX64::GenerateAND( EN64Reg rd, EN64Reg rs, EN64Reg rt )
{
if (rd == 0) return;
MOV64_REG_MEM(RAX_CODE, &gCPUState.CPU[rs]._u64);
MOV64_REG_MEM(RCX_CODE, &gCPUState.CPU[rt]._u64);
AND(RAX_CODE, RCX_CODE, true);
MOV64_MEM_REG(&gCPUState.CPU[rd]._u64, RAX_CODE);
}
//gGPR[ op_code.rd ]._u64 = gGPR[ op_code.rs ]._u64 ^ gGPR[ op_code.rt ]._u64;
void CCodeGeneratorX64::GenerateXOR( EN64Reg rd, EN64Reg rs, EN64Reg rt )
{
if (rd == 0) return;
MOV64_REG_MEM(RAX_CODE, &gCPUState.CPU[rs]._u64);
MOV64_REG_MEM(RCX_CODE, &gCPUState.CPU[rt]._u64);
XOR(RAX_CODE, RCX_CODE, true);
MOV64_MEM_REG(&gCPUState.CPU[rd]._u64, RAX_CODE);
}
//gGPR[ op_code.rd ]._u64 = ~(gGPR[ op_code.rs ]._u64 | gGPR[ op_code.rt ]._u64);
void CCodeGeneratorX64::GenerateNOR( EN64Reg rd, EN64Reg rs, EN64Reg rt )
{
if (rd == 0) return;
MOV64_REG_MEM(RAX_CODE, &gCPUState.CPU[rs]._u64);
MOV64_REG_MEM(RCX_CODE, &gCPUState.CPU[rt]._u64);
OR(RAX_CODE, RCX_CODE, true);
@ -935,16 +986,48 @@ void CCodeGeneratorX64::GenerateNOR( EN64Reg rd, EN64Reg rs, EN64Reg rt )
MOV64_MEM_REG(&gCPUState.CPU[rd]._u64, RAX_CODE);
}
// gGPR[ op_code.rd ]._s64 = (s64)(s32)( gGPR[ op_code.rs ]._s32_0 + gGPR[ op_code.rt ]._s32_0 );
void CCodeGeneratorX64::GenerateADDU( EN64Reg rd, EN64Reg rs, EN64Reg rt )
{
if (rd == 0) return;
MOV_REG_MEM(RAX_CODE, &gCPUState.CPU[rs]._u32_0);
MOV_REG_MEM(RCX_CODE, &gCPUState.CPU[rt]._u32_0);
ADD(RAX_CODE, RCX_CODE);
CDQ();
MOV_MEM_REG(&gCPUState.CPU[rd]._u32_0, RAX_CODE);
MOV_MEM_REG(&gCPUState.CPU[rd]._u32_1, RDX_CODE);
}
// gGPR[ op_code.rd ]._u64 = gGPR[ op_code.rs ]._u64 + gGPR[ op_code.rt ]._u64;
void CCodeGeneratorX64::GenerateDADDU( EN64Reg rd, EN64Reg rs, EN64Reg rt )
{
if (rd == 0) return;
MOV64_REG_MEM(RAX_CODE, &gCPUState.CPU[rs]._u64);
MOV64_REG_MEM(RCX_CODE, &gCPUState.CPU[rt]._u64);
ADD(RAX_CODE, RCX_CODE, true);
MOV64_MEM_REG(&gCPUState.CPU[rd]._u64, RAX_CODE);
}
// gGPR[ op_code.rd ]._s64 = (s64)(s32)( gGPR[ op_code.rs ]._s32_0 - gGPR[ op_code.rt ]._s32_0 );
void CCodeGeneratorX64::GenerateSUBU( EN64Reg rd, EN64Reg rs, EN64Reg rt )
{
if (rd == 0) return;
MOV_REG_MEM(RAX_CODE, &gCPUState.CPU[rs]._u32_0);
MOV_REG_MEM(RCX_CODE, &gCPUState.CPU[rt]._u32_0);
SUB(RAX_CODE, RCX_CODE);
CDQ();
MOV_MEM_REG(&gCPUState.CPU[rd]._u32_0, RAX_CODE);
MOV_MEM_REG(&gCPUState.CPU[rd]._u32_1, RDX_CODE);
}
//gGPR[ op_code.rd ]._u64 = gGPR[ op_code.rs ]._u64 - gGPR[ op_code.rt ]._u64;
void CCodeGeneratorX64::GenerateDSUBU( EN64Reg rd, EN64Reg rs, EN64Reg rt )
{
if (rd == 0) return;
MOV64_REG_MEM(RAX_CODE, &gCPUState.CPU[rs]._u64);
MOV64_REG_MEM(RCX_CODE, &gCPUState.CPU[rt]._u64);
SUB(RAX_CODE, RCX_CODE, true);

View file

@ -104,6 +104,7 @@ class CCodeGeneratorX64 : public CCodeGenerator, public CAssemblyWriterX64
void GenerateLUI(EN64Reg rt, s16 offset );
void GenerateDADDIU( EN64Reg rt, EN64Reg rs, s16 immediate );
void GenerateADDIU( EN64Reg rt, EN64Reg rs, s16 immediate );
void GenerateANDI( EN64Reg rt, EN64Reg rs, u16 immediate );
void GenerateORI( EN64Reg rt, EN64Reg rs, u16 immediate );
@ -123,6 +124,9 @@ class CCodeGeneratorX64 : public CCodeGenerator, public CAssemblyWriterX64
void GenerateADDU( EN64Reg rd, EN64Reg rs, EN64Reg rt );
void GenerateSUBU( EN64Reg rd, EN64Reg rs, EN64Reg rt );
void GenerateDADDU( EN64Reg rd, EN64Reg rs, EN64Reg rt );
void GenerateDSUBU( EN64Reg rd, EN64Reg rs, EN64Reg rt );
};
#endif // SYSW32_DYNAREC_X64_CODEGENERATORX64_H_