mirror of
				https://github.com/hedge-dev/XenonRecomp.git
				synced 2025-10-30 07:11:38 +00:00 
			
		
		
		
	Fix tests.
This commit is contained in:
		
							parent
							
								
									510cff56f2
								
							
						
					
					
						commit
						1914b941a2
					
				
					 6 changed files with 271 additions and 281 deletions
				
			
		|  | @ -168,7 +168,7 @@ bool Recompiler::Recompile(const Function& fn, uint32_t base, const ppc_insn& in | |||
|             } | ||||
| 
 | ||||
|             println("\tdefault:"); | ||||
|             println("\t\t__unreachable();"); | ||||
|             println("\t\t__builtin_unreachable();"); | ||||
|             println("\t}}"); | ||||
| 
 | ||||
|             switchTable = switchTables.end(); | ||||
|  | @ -738,7 +738,7 @@ bool Recompiler::Recompile(const Function& fn, uint32_t base, const ppc_insn& in | |||
|         break; | ||||
| 
 | ||||
|     case PPC_INST_LWBRX: | ||||
|         print("\tctx.r{}.u64 = _byteswap_ulong(PPC_LOAD_U32(", insn.operands[0]); | ||||
|         print("\tctx.r{}.u64 = __builtin_bswap32(PPC_LOAD_U32(", insn.operands[0]); | ||||
|         if (insn.operands[1] != 0) | ||||
|             print("ctx.r{}.u32 + ", insn.operands[1]); | ||||
|         println("ctx.r{}.u32));", insn.operands[2]); | ||||
|  | @ -1022,7 +1022,7 @@ bool Recompiler::Recompile(const Function& fn, uint32_t base, const ppc_insn& in | |||
|         print("\tctx.cr0.eq = _InterlockedCompareExchange64(reinterpret_cast<__int64*>(base + "); | ||||
|         if (insn.operands[1] != 0) | ||||
|             print("ctx.r{}.u32 + ", insn.operands[1]); | ||||
|         println("ctx.r{}.u32), _byteswap_uint64(ctx.r{}.s64), _byteswap_uint64(ctx.reserved.s64)) == _byteswap_uint64(ctx.reserved.s64);", | ||||
|         println("ctx.r{}.u32), __builtin_bswap64(ctx.r{}.s64), __builtin_bswap64(ctx.reserved.s64)) == __builtin_bswap64(ctx.reserved.s64);", | ||||
|             insn.operands[2], insn.operands[0]); | ||||
|         println("\tctx.cr0.so = ctx.xer.so;"); | ||||
|         break; | ||||
|  | @ -1093,7 +1093,7 @@ bool Recompiler::Recompile(const Function& fn, uint32_t base, const ppc_insn& in | |||
|         print("\tPPC_STORE_U16("); | ||||
|         if (insn.operands[1] != 0) | ||||
|             print("ctx.r{}.u32 + ", insn.operands[1]); | ||||
|         println("ctx.r{}.u32, _byteswap_ushort(ctx.r{}.u16));", insn.operands[2], insn.operands[0]); | ||||
|         println("ctx.r{}.u32, __builtin_bswap16(ctx.r{}.u16));", insn.operands[2], insn.operands[0]); | ||||
|         break; | ||||
| 
 | ||||
|     case PPC_INST_STHX: | ||||
|  | @ -1169,7 +1169,7 @@ bool Recompiler::Recompile(const Function& fn, uint32_t base, const ppc_insn& in | |||
|         print("\tPPC_STORE_U32("); | ||||
|         if (insn.operands[1] != 0) | ||||
|             print("ctx.r{}.u32 + ", insn.operands[1]); | ||||
|         println("ctx.r{}.u32, _byteswap_ulong(ctx.r{}.u32));", insn.operands[2], insn.operands[0]); | ||||
|         println("ctx.r{}.u32, __builtin_bswap32(ctx.r{}.u32));", insn.operands[2], insn.operands[0]); | ||||
|         break; | ||||
| 
 | ||||
|     case PPC_INST_STWCX: | ||||
|  | @ -1178,7 +1178,7 @@ bool Recompiler::Recompile(const Function& fn, uint32_t base, const ppc_insn& in | |||
|         print("\tctx.cr0.eq = _InterlockedCompareExchange(reinterpret_cast<long*>(base + "); | ||||
|         if (insn.operands[1] != 0) | ||||
|             print("ctx.r{}.u32 + ", insn.operands[1]); | ||||
|         println("ctx.r{}.u32), _byteswap_ulong(ctx.r{}.s32), _byteswap_ulong(ctx.reserved.s32)) == _byteswap_ulong(ctx.reserved.s32);", | ||||
|         println("ctx.r{}.u32), __builtin_bswap32(ctx.r{}.s32), __builtin_bswap32(ctx.reserved.s32)) == __builtin_bswap32(ctx.reserved.s32);", | ||||
|             insn.operands[2], insn.operands[0]); | ||||
|         println("\tctx.cr0.so = ctx.xer.so;"); | ||||
|         break; | ||||
|  | @ -1228,7 +1228,7 @@ bool Recompiler::Recompile(const Function& fn, uint32_t base, const ppc_insn& in | |||
|         break; | ||||
| 
 | ||||
|     case PPC_INST_SYNC: | ||||
|         println("\t__faststorefence();"); | ||||
|         // no op
 | ||||
|         break; | ||||
| 
 | ||||
|     case PPC_INST_TDLGEI: | ||||
|  | @ -1328,6 +1328,7 @@ bool Recompiler::Recompile(const Function& fn, uint32_t base, const ppc_insn& in | |||
|         break; | ||||
|     } | ||||
| 
 | ||||
|     case PPC_INST_VCMPBFP: | ||||
|     case PPC_INST_VCMPBFP128: | ||||
|         println("\t__debugbreak();"); | ||||
|         break; | ||||
|  | @ -1377,6 +1378,7 @@ bool Recompiler::Recompile(const Function& fn, uint32_t base, const ppc_insn& in | |||
|         println("\t_mm_store_si128((__m128i*)ctx.v{}.u8, _mm_cmpgt_epu16(_mm_load_si128((__m128i*)ctx.v{}.u16), _mm_load_si128((__m128i*)ctx.v{}.u16)));", insn.operands[0], insn.operands[1], insn.operands[2]); | ||||
|         break; | ||||
| 
 | ||||
|     case PPC_INST_VEXPTEFP: | ||||
|     case PPC_INST_VEXPTEFP128: | ||||
|         // TODO: vectorize
 | ||||
|         println("\tctx.fpscr.setFlushMode(true);"); | ||||
|  | @ -1384,6 +1386,7 @@ bool Recompiler::Recompile(const Function& fn, uint32_t base, const ppc_insn& in | |||
|             println("\tctx.v{}.f32[{}] = exp2f(ctx.v{}.f32[{}]);", insn.operands[0], i, insn.operands[1], i); | ||||
|         break; | ||||
| 
 | ||||
|     case PPC_INST_VLOGEFP: | ||||
|     case PPC_INST_VLOGEFP128: | ||||
|         // TODO: vectorize
 | ||||
|         println("\tctx.fpscr.setFlushMode(true);"); | ||||
|  | @ -1509,6 +1512,7 @@ bool Recompiler::Recompile(const Function& fn, uint32_t base, const ppc_insn& in | |||
|         break; | ||||
| 
 | ||||
|     case PPC_INST_VPKSHUS: | ||||
|     case PPC_INST_VPKSHUS128: | ||||
|         println("\t_mm_store_si128((__m128i*)ctx.v{}.u8, _mm_packus_epi16(_mm_load_si128((__m128i*)ctx.v{}.s16), _mm_load_si128((__m128i*)ctx.v{}.s16)));", insn.operands[0], insn.operands[2], insn.operands[1]); | ||||
|         break; | ||||
| 
 | ||||
|  | @ -1518,6 +1522,7 @@ bool Recompiler::Recompile(const Function& fn, uint32_t base, const ppc_insn& in | |||
|         println("\t_mm_store_ps(ctx.v{}.f32, _mm_rcp_ps(_mm_load_ps(ctx.v{}.f32)));", insn.operands[0], insn.operands[1]); | ||||
|         break; | ||||
| 
 | ||||
|     case PPC_INST_VRFIM: | ||||
|     case PPC_INST_VRFIM128: | ||||
|         println("\tctx.fpscr.setFlushMode(true);"); | ||||
|         println("\t_mm_store_ps(ctx.v{}.f32, _mm_round_ps(_mm_load_ps(ctx.v{}.f32), _MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC));", insn.operands[0], insn.operands[1]); | ||||
|  | @ -1529,6 +1534,7 @@ bool Recompiler::Recompile(const Function& fn, uint32_t base, const ppc_insn& in | |||
|         println("\t_mm_store_ps(ctx.v{}.f32, _mm_round_ps(_mm_load_ps(ctx.v{}.f32), _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC));", insn.operands[0], insn.operands[1]); | ||||
|         break; | ||||
| 
 | ||||
|     case PPC_INST_VRFIZ: | ||||
|     case PPC_INST_VRFIZ128: | ||||
|         println("\tctx.fpscr.setFlushMode(true);"); | ||||
|         println("\t_mm_store_ps(ctx.v{}.f32, _mm_round_ps(_mm_load_ps(ctx.v{}.f32), _MM_FROUND_TO_ZERO | _MM_FROUND_NO_EXC));", insn.operands[0], insn.operands[1]); | ||||
|  | @ -1562,6 +1568,7 @@ bool Recompiler::Recompile(const Function& fn, uint32_t base, const ppc_insn& in | |||
|         println("\t_mm_store_si128((__m128i*)ctx.v{}.u8, _mm_alignr_epi8(_mm_load_si128((__m128i*)ctx.v{}.u8), _mm_load_si128((__m128i*)ctx.v{}.u8), {}));", insn.operands[0], insn.operands[1], insn.operands[2], 16 - insn.operands[3]); | ||||
|         break; | ||||
| 
 | ||||
|     case PPC_INST_VSLW: | ||||
|     case PPC_INST_VSLW128: | ||||
|         // TODO: vectorize, ensure endianness is correct
 | ||||
|         for (size_t i = 0; i < 4; i++) | ||||
|  | @ -1608,6 +1615,7 @@ bool Recompiler::Recompile(const Function& fn, uint32_t base, const ppc_insn& in | |||
|         println("\t_mm_store_si128((__m128i*)ctx.v{}.u8, _mm_vsr(_mm_load_si128((__m128i*)ctx.v{}.u8), _mm_load_si128((__m128i*)ctx.v{}.u8)));", insn.operands[0], insn.operands[1], insn.operands[2]); | ||||
|         break; | ||||
| 
 | ||||
|     case PPC_INST_VSRAW: | ||||
|     case PPC_INST_VSRAW128: | ||||
|         // TODO: vectorize, ensure endianness is correct
 | ||||
|         for (size_t i = 0; i < 4; i++) | ||||
|  | @ -1676,6 +1684,7 @@ bool Recompiler::Recompile(const Function& fn, uint32_t base, const ppc_insn& in | |||
|         } | ||||
|         break; | ||||
| 
 | ||||
|     case PPC_INST_VUPKHSB: | ||||
|     case PPC_INST_VUPKHSB128: | ||||
|         println("\t_mm_store_si128((__m128i*)ctx.v{}.s16, _mm_cvtepi8_epi16(_mm_unpackhi_epi64(_mm_load_si128((__m128i*)ctx.v{}.s8), _mm_load_si128((__m128i*)ctx.v{}.s8))));", insn.operands[0], insn.operands[1], insn.operands[1]); | ||||
|         break; | ||||
|  | @ -1685,6 +1694,7 @@ bool Recompiler::Recompile(const Function& fn, uint32_t base, const ppc_insn& in | |||
|         println("\t_mm_store_si128((__m128i*)ctx.v{}.s32, _mm_cvtepi16_epi32(_mm_unpackhi_epi64(_mm_load_si128((__m128i*)ctx.v{}.s16), _mm_load_si128((__m128i*)ctx.v{}.s16))));", insn.operands[0], insn.operands[1], insn.operands[1]); | ||||
|         break; | ||||
| 
 | ||||
|     case PPC_INST_VUPKLSB: | ||||
|     case PPC_INST_VUPKLSB128: | ||||
|         println("\t_mm_store_si128((__m128i*)ctx.v{}.s32, _mm_cvtepi8_epi16(_mm_load_si128((__m128i*)ctx.v{}.s16)));", insn.operands[0], insn.operands[1]); | ||||
|         break; | ||||
|  | @ -1780,6 +1790,11 @@ bool Recompiler::Recompile(const Function& fn) | |||
|         } | ||||
|     } | ||||
| 
 | ||||
| #if 0 | ||||
|     if (insn.opcode == nullptr || (insn.opcode->id != PPC_INST_B && insn.opcode->id != PPC_INST_BCTR && insn.opcode->id != PPC_INST_BLR)) | ||||
|         std::println("Function at {:X} ends prematurely with instruction {} at {:X}", fn.base, insn.opcode != nullptr ? insn.opcode->name : "INVALID", base - 4); | ||||
| #endif | ||||
| 
 | ||||
|     println("}}\n"); | ||||
| 
 | ||||
|     return allRecompiled; | ||||
|  |  | |||
|  | @ -72,9 +72,10 @@ void SWARecompiler::Analyse() | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     auto hardcodedFuncCheck = [&](Function& f) | ||||
|     auto hardcodedFuncCheck = [&](uint8_t* data, Function& f) | ||||
|         { | ||||
|             if (f.base == 0x824E7EF0) f.size = 0x98; | ||||
|             if (*(uint32_t*)(data + 4) == 0x04000048) f.size = 0x8; // shifted ptr tail call
 | ||||
|             else if (f.base == 0x824E7EF0) f.size = 0x98; | ||||
|             else if (f.base == 0x824E7F28) f.size = 0x60; | ||||
|             else if (f.base == 0x82C980E8) f.size = 0x110; | ||||
|             else if (f.base == 0x82CF7080) f.size = 0x80; | ||||
|  | @ -137,8 +138,9 @@ void SWARecompiler::Analyse() | |||
| 
 | ||||
|                 if (address >= section.base && address < section.base + section.size && image.symbols.find(address) == image.symbols.end()) | ||||
|                 { | ||||
|                     auto& fn = functions.emplace_back(Function::Analyze(section.data + address - section.base, section.base + section.size - address, address)); | ||||
|                     hardcodedFuncCheck(fn); | ||||
|                     auto data = section.data + address - section.base; | ||||
|                     auto& fn = functions.emplace_back(Function::Analyze(data, section.base + section.size - address, address)); | ||||
|                     hardcodedFuncCheck(data, fn); | ||||
|                     image.symbols.emplace(std::format("sub_{:X}", fn.base), fn.base, fn.size, Symbol_Function); | ||||
|                 } | ||||
|             } | ||||
|  | @ -179,7 +181,7 @@ void SWARecompiler::Analyse() | |||
|             else | ||||
|             { | ||||
|                 auto& fn = functions.emplace_back(Function::Analyze(data, dataEnd - data, base)); | ||||
|                 hardcodedFuncCheck(fn); | ||||
|                 hardcodedFuncCheck(data, fn); | ||||
|                 image.symbols.emplace(std::format("sub_{:X}", fn.base), fn.base, fn.size, Symbol_Function); | ||||
| 
 | ||||
|                 base += fn.size; | ||||
|  |  | |||
|  | @ -98,8 +98,8 @@ void TestRecompiler::RecompileTests(const char* srcDirectoryPath, const char* ds | |||
|     std::println(file, "#include <ppc_context.h>"); | ||||
|     std::println(file, "#include <Windows.h>"); | ||||
|     std::println(file, "#include <print>\n"); | ||||
|     std::println(file, "#define PPC_CHECK_VALUE_U(lhs, rhs) if (lhs != rhs) std::println(__FUNCTION__ \" \" #lhs \" EXPECTED \" #rhs \" ACTUAL {{:X}}\", lhs)\n"); | ||||
|     std::println(file, "#define PPC_CHECK_VALUE_F(lhs, rhs) if (lhs != rhs) std::println(__FUNCTION__ \" \" #lhs \" EXPECTED \" #rhs \" ACTUAL {{}}\", lhs)\n"); | ||||
|     std::println(file, "#define PPC_CHECK_VALUE_U(f, lhs, rhs) if (lhs != rhs) std::println(#f \" \" #lhs \" EXPECTED \" #rhs \" ACTUAL {{:X}}\", lhs)\n"); | ||||
|     std::println(file, "#define PPC_CHECK_VALUE_F(f, lhs, rhs) if (lhs != rhs) std::println(#f \" \" #lhs \" EXPECTED \" #rhs \" ACTUAL {{}}\", lhs)\n"); | ||||
| 
 | ||||
|     for (auto& [fn, addr] : functions) | ||||
|     { | ||||
|  | @ -212,15 +212,16 @@ void TestRecompiler::RecompileTests(const char* srcDirectoryPath, const char* ds | |||
|                                             int commaIndex2 = str.find(',', commaIndex1 + 1); | ||||
|                                             int closingBracketIndex = str.find(']', commaIndex2 + 1); | ||||
| 
 | ||||
|                                             std::println(file, "\tPPC_CHECK_VALUE_U(ctx.{}.u32[3], 0x{});", reg, str.substr(openingBracketIndex + 1, commaIndex0 - openingBracketIndex - 1)); | ||||
|                                             std::println(file, "\tPPC_CHECK_VALUE_U(ctx.{}.u32[2], 0x{});", reg, str.substr(commaIndex0 + 2, commaIndex1 - commaIndex0 - 2)); | ||||
|                                             std::println(file, "\tPPC_CHECK_VALUE_U(ctx.{}.u32[1], 0x{});", reg, str.substr(commaIndex1 + 2, commaIndex2 - commaIndex1 - 2)); | ||||
|                                             std::println(file, "\tPPC_CHECK_VALUE_U(ctx.{}.u32[0], 0x{});", reg, str.substr(commaIndex2 + 2, closingBracketIndex - commaIndex2 - 2)); | ||||
|                                             std::println(file, "\tPPC_CHECK_VALUE_U({}, ctx.{}.u32[3], 0x{});", name, reg, str.substr(openingBracketIndex + 1, commaIndex0 - openingBracketIndex - 1)); | ||||
|                                             std::println(file, "\tPPC_CHECK_VALUE_U({}, ctx.{}.u32[2], 0x{});", name, reg, str.substr(commaIndex0 + 2, commaIndex1 - commaIndex0 - 2)); | ||||
|                                             std::println(file, "\tPPC_CHECK_VALUE_U({}, ctx.{}.u32[1], 0x{});", name, reg, str.substr(commaIndex1 + 2, commaIndex2 - commaIndex1 - 2)); | ||||
|                                             std::println(file, "\tPPC_CHECK_VALUE_U({}, ctx.{}.u32[0], 0x{});", name, reg, str.substr(commaIndex2 + 2, closingBracketIndex - commaIndex2 - 2)); | ||||
|                                         } | ||||
|                                         else | ||||
|                                         { | ||||
|                                             std::println(file, "\tPPC_CHECK_VALUE_{}(ctx.{}.{}64, {});", | ||||
|                                             std::println(file, "\tPPC_CHECK_VALUE_{}({}, ctx.{}.{}64, {});", | ||||
|                                                 str.find('.', secondSpaceIndex) != std::string::npos ? 'F' : 'U', | ||||
|                                                 name, | ||||
|                                                 reg, | ||||
|                                                 str.find('.', secondSpaceIndex) != std::string::npos ? 'f' : 'u', | ||||
|                                                 str.substr(secondSpaceIndex + 1)); | ||||
|  | @ -238,7 +239,7 @@ void TestRecompiler::RecompileTests(const char* srcDirectoryPath, const char* ds | |||
|                                             { | ||||
|                                                 if (str[i] != ' ') | ||||
|                                                 { | ||||
|                                                     std::println(file, "\tPPC_CHECK_VALUE_U(base[0x{} + 0x{:X}], 0x{}{});", address, j, str[i], str[i + 1]); | ||||
|                                                     std::println(file, "\tPPC_CHECK_VALUE_U({}, base[0x{} + 0x{:X}], 0x{}{});", name, address, j, str[i], str[i + 1]); | ||||
|                                                     ++i; // the loop adds another
 | ||||
|                                                     ++j; | ||||
|                                                 } | ||||
|  | @ -266,9 +267,10 @@ void TestRecompiler::RecompileTests(const char* srcDirectoryPath, const char* ds | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     std::println(file, "void main() {{"); | ||||
|     std::println(file, "int main() {{"); | ||||
|     std::println(file, "\tuint8_t* base = reinterpret_cast<uint8_t*>(VirtualAlloc(nullptr, 0x100000000, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE));"); | ||||
|     fwrite(main.data(), 1, main.size(), file); | ||||
|     std::println(file, "\treturn 0;"); | ||||
|     std::println(file, "}}"); | ||||
| 
 | ||||
|     fclose(file); | ||||
|  |  | |||
|  | @ -1,6 +1,10 @@ | |||
| project("PowerTests") | ||||
| 
 | ||||
| add_compile_options( | ||||
|     "-march=x86-64-v3" | ||||
|     "-Wno-unused-label" | ||||
|     "-Wno-unused-variable") | ||||
| 
 | ||||
| file(GLOB TestFiles *.cpp) | ||||
| add_executable(PowerTests ${TestFiles}) | ||||
| 
 | ||||
| target_link_libraries(PowerTests PUBLIC PowerUtils) | ||||
|  |  | |||
|  | @ -11,12 +11,7 @@ void Image::Map(const std::string_view& name, size_t base, uint32_t size, uint8_ | |||
| 
 | ||||
| const void* Image::Find(size_t address) const | ||||
| { | ||||
|     const auto section = sections.lower_bound(address); | ||||
|     if (section == sections.end()) | ||||
|     { | ||||
|         return nullptr; | ||||
|     } | ||||
| 
 | ||||
|     const auto section = std::prev(sections.upper_bound(address)); | ||||
|     return section->data + (address - section->base); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -6,37 +6,36 @@ | |||
| 
 | ||||
| #ifdef __clang__ | ||||
| #include <x86intrin.h> | ||||
| #define __restrict __restrict__ | ||||
| #define _byteswap_ushort __builtin_bswap16 | ||||
| #define _byteswap_ulong __builtin_bswap32 | ||||
| #define _byteswap_uint64 __builtin_bswap64 | ||||
| #define isnan __builtin_isnan | ||||
| #define __assume __builtin_assume | ||||
| #define __unreachable() __builtin_unreachable() | ||||
| #else | ||||
| #include <intrin.h> | ||||
| #define __unreachable() __assume(0) | ||||
| #define __restrict__ __restrict  | ||||
| #define __builtin_bswap16 _byteswap_ushort  | ||||
| #define __builtin_bswap32 _byteswap_ulong  | ||||
| #define __builtin_bswap64 _byteswap_uint64  | ||||
| #define __builtin_isnan isnan | ||||
| #define __builtin_assume __assume | ||||
| #define __builtin_unreachable() __assume(0) | ||||
| #endif | ||||
| 
 | ||||
| #define PPC_FUNC(x) extern "C" void x(PPCContext& __restrict ctx, uint8_t* base) noexcept | ||||
| #define PPC_FUNC(x) extern "C" void x(PPCContext& __restrict__ ctx, uint8_t* base) noexcept | ||||
| 
 | ||||
| #define PPC_FUNC_PROLOGUE() \ | ||||
| 	__assume((reinterpret_cast<size_t>(base) & 0xFFFFFFFF) == 0); \ | ||||
| 	__builtin_assume((reinterpret_cast<size_t>(base) & 0xFFFFFFFF) == 0); \ | ||||
|     PPCRegister temp; \ | ||||
|     PPCVRegister vtemp; \ | ||||
|     uint32_t ea | ||||
| 
 | ||||
| #define PPC_LOAD_U8(x) *(uint8_t*)(base + (x)) | ||||
| #define PPC_LOAD_U16(x) _byteswap_ushort(*(uint16_t*)(base + (x))) | ||||
| #define PPC_LOAD_U32(x) _byteswap_ulong(*(uint32_t*)(base + (x))) | ||||
| #define PPC_LOAD_U64(x) _byteswap_uint64(*(uint64_t*)(base + (x))) | ||||
| #define PPC_LOAD_U16(x) __builtin_bswap16(*(uint16_t*)(base + (x))) | ||||
| #define PPC_LOAD_U32(x) __builtin_bswap32(*(uint32_t*)(base + (x))) | ||||
| #define PPC_LOAD_U64(x) __builtin_bswap64(*(uint64_t*)(base + (x))) | ||||
| 
 | ||||
| #define PPC_STORE_U8(x, y) *(uint8_t*)(base + (x)) = (y) | ||||
| #define PPC_STORE_U16(x, y) *(uint16_t*)(base + (x)) = _byteswap_ushort(y) | ||||
| #define PPC_STORE_U32(x, y) *(uint32_t*)(base + (x)) = _byteswap_ulong(y) | ||||
| #define PPC_STORE_U64(x, y) *(uint64_t*)(base + (x)) = _byteswap_uint64(y) | ||||
| #define PPC_STORE_U16(x, y) *(uint16_t*)(base + (x)) = __builtin_bswap16(y) | ||||
| #define PPC_STORE_U32(x, y) *(uint32_t*)(base + (x)) = __builtin_bswap32(y) | ||||
| #define PPC_STORE_U64(x, y) *(uint64_t*)(base + (x)) = __builtin_bswap64(y) | ||||
| 
 | ||||
| typedef void PPCFunc(struct PPCContext& __restrict ctx, uint8_t* base); | ||||
| typedef void PPCFunc(struct PPCContext& __restrict__ ctx, uint8_t* base); | ||||
| 
 | ||||
| struct PPCFuncMapping | ||||
| { | ||||
|  | @ -92,10 +91,10 @@ struct PPCCRRegister | |||
| 
 | ||||
|     void compare(double left, double right) | ||||
|     { | ||||
|         lt = left < right; | ||||
|         gt = left > right; | ||||
|         eq = left == right; | ||||
|         un = isnan(left) || isnan(right); | ||||
|         un = __builtin_isnan(left) || __builtin_isnan(right); | ||||
|         lt = !un && (left < right); | ||||
|         gt = !un && (left > right); | ||||
|         eq = !un && (left == right); | ||||
|     } | ||||
| 
 | ||||
|     void setFromMask(__m128 mask, int imm) | ||||
|  | @ -171,13 +170,8 @@ struct PPCContext | |||
|     PPCRegister ctr; | ||||
|     PPCXERRegister xer; | ||||
|     PPCRegister reserved; | ||||
|     uint32_t msr; | ||||
|     PPCFPSCRRegister fpscr; | ||||
|     uint32_t msr = 0x200A000; | ||||
| 
 | ||||
|     union | ||||
|     { | ||||
|         struct | ||||
|         { | ||||
|     PPCCRRegister cr0; | ||||
|     PPCCRRegister cr1; | ||||
|     PPCCRRegister cr2; | ||||
|  | @ -186,14 +180,7 @@ struct PPCContext | |||
|     PPCCRRegister cr5; | ||||
|     PPCCRRegister cr6; | ||||
|     PPCCRRegister cr7; | ||||
|         }; | ||||
|         PPCCRRegister cr[8]; | ||||
|     }; | ||||
|      | ||||
|     union | ||||
|     { | ||||
|         struct | ||||
|         { | ||||
|     PPCRegister r0; | ||||
|     PPCRegister r1; | ||||
|     PPCRegister r2; | ||||
|  | @ -226,14 +213,9 @@ struct PPCContext | |||
|     PPCRegister r29; | ||||
|     PPCRegister r30; | ||||
|     PPCRegister r31; | ||||
|         }; | ||||
|         PPCRegister r[32]; | ||||
|     }; | ||||
| 
 | ||||
|     union | ||||
|     { | ||||
|         struct | ||||
|         { | ||||
|     PPCFPSCRRegister fpscr; | ||||
| 
 | ||||
|     PPCRegister f0; | ||||
|     PPCRegister f1; | ||||
|     PPCRegister f2; | ||||
|  | @ -266,14 +248,7 @@ struct PPCContext | |||
|     PPCRegister f29; | ||||
|     PPCRegister f30; | ||||
|     PPCRegister f31; | ||||
|         }; | ||||
|         PPCRegister f[32]; | ||||
|     }; | ||||
|      | ||||
|     union | ||||
|     { | ||||
|         struct | ||||
|         { | ||||
|     PPCVRegister v0; | ||||
|     PPCVRegister v1; | ||||
|     PPCVRegister v2; | ||||
|  | @ -403,9 +378,6 @@ struct PPCContext | |||
|     PPCVRegister v126; | ||||
|     PPCVRegister v127; | ||||
| }; | ||||
|         PPCVRegister v[128]; | ||||
|     }; | ||||
| }; | ||||
| 
 | ||||
| inline uint8_t VectorMaskL[] = | ||||
| { | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Skyth
						Skyth