mirror of
				https://github.com/hedge-dev/XenonRecomp.git
				synced 2025-11-04 06:47:09 +00:00 
			
		
		
		
	Implement periodt variant of instructions.
This commit is contained in:
		@@ -6,7 +6,7 @@
 | 
				
			|||||||
#include <disasm.h>
 | 
					#include <disasm.h>
 | 
				
			||||||
#include <filesystem>
 | 
					#include <filesystem>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define TEST_FILE "cond.elf"
 | 
					#define TEST_FILE "add-cond.elf"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int main()
 | 
					int main()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -81,14 +81,13 @@ int main()
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
            else
 | 
					            else
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                // TODO: need to handle instructions that treat r0 as 0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                std::println(f, "\t// {:x} {} {}", base - 4, insn.opcode->name, insn.op_str);
 | 
					                std::println(f, "\t// {:x} {} {}", base - 4, insn.opcode->name, insn.op_str);
 | 
				
			||||||
                switch (insn.opcode->id)
 | 
					                switch (insn.opcode->id)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                case PPC_INST_ADD:
 | 
					                case PPC_INST_ADD:
 | 
				
			||||||
                    // TODO: . variant
 | 
					 | 
				
			||||||
                    std::println(f, "\tctx.r{}.u64 = ctx.r{}.u64 + ctx.r{}.u64;", insn.operands[0], insn.operands[1], insn.operands[2]);
 | 
					                    std::println(f, "\tctx.r{}.u64 = ctx.r{}.u64 + ctx.r{}.u64;", insn.operands[0], insn.operands[1], insn.operands[2]);
 | 
				
			||||||
 | 
					                    if (insn.opcode->opcode & 0x1)
 | 
				
			||||||
 | 
					                        std::println(f, "\tctx.cr0.compare<int32_t>(ctx.r{}.s32, 0, ctx.xer);", insn.operands[0]);
 | 
				
			||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                case PPC_INST_ADDI:
 | 
					                case PPC_INST_ADDI:
 | 
				
			||||||
@@ -99,7 +98,6 @@ int main()
 | 
				
			|||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                case PPC_INST_ADDIS:
 | 
					                case PPC_INST_ADDIS:
 | 
				
			||||||
                    // TODO: validate the sign extend
 | 
					 | 
				
			||||||
                    std::println(f, "\tctx.r{}.s64 = ctx.r{}.s64 + {};", insn.operands[0], insn.operands[1], static_cast<int32_t>(insn.operands[2] << 16));
 | 
					                    std::println(f, "\tctx.r{}.s64 = ctx.r{}.s64 + {};", insn.operands[0], insn.operands[1], static_cast<int32_t>(insn.operands[2] << 16));
 | 
				
			||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -107,23 +105,27 @@ int main()
 | 
				
			|||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                case PPC_INST_AND:
 | 
					                case PPC_INST_AND:
 | 
				
			||||||
                    // TODO: . variant
 | 
					 | 
				
			||||||
                    std::println(f, "\tctx.r{}.u64 = ctx.r{}.u64 & ctx.r{}.u64;", insn.operands[0], insn.operands[1], insn.operands[2]);
 | 
					                    std::println(f, "\tctx.r{}.u64 = ctx.r{}.u64 & ctx.r{}.u64;", insn.operands[0], insn.operands[1], insn.operands[2]);
 | 
				
			||||||
 | 
					                    if (insn.opcode->opcode & 0x1)
 | 
				
			||||||
 | 
					                        std::println(f, "\tctx.cr0.compare<int32_t>(ctx.r{}.s32, 0, ctx.xer);", insn.operands[0]);
 | 
				
			||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                case PPC_INST_ANDC:
 | 
					                case PPC_INST_ANDC:
 | 
				
			||||||
                    // TODO: . variant
 | 
					 | 
				
			||||||
                    std::println(f, "\tctx.r{}.u64 = ctx.r{}.u64 & ~ctx.r{}.u64;", insn.operands[0], insn.operands[1], insn.operands[2]);
 | 
					                    std::println(f, "\tctx.r{}.u64 = ctx.r{}.u64 & ~ctx.r{}.u64;", insn.operands[0], insn.operands[1], insn.operands[2]);
 | 
				
			||||||
 | 
					                    if (insn.opcode->opcode & 0x1)
 | 
				
			||||||
 | 
					                        std::println(f, "\tctx.cr0.compare<int32_t>(ctx.r{}.s32, 0, ctx.xer);", insn.operands[0]);
 | 
				
			||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                case PPC_INST_ANDI:
 | 
					                case PPC_INST_ANDI:
 | 
				
			||||||
                    // TODO: . variant
 | 
					 | 
				
			||||||
                    std::println(f, "\tctx.r{}.u64 = ctx.r{}.u64 & {};", insn.operands[0], insn.operands[1], insn.operands[2]);
 | 
					                    std::println(f, "\tctx.r{}.u64 = ctx.r{}.u64 & {};", insn.operands[0], insn.operands[1], insn.operands[2]);
 | 
				
			||||||
 | 
					                    if (insn.opcode->opcode & 0x1)
 | 
				
			||||||
 | 
					                        std::println(f, "\tctx.cr0.compare<int32_t>(ctx.r{}.s32, 0, ctx.xer);", insn.operands[0]);
 | 
				
			||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                case PPC_INST_ANDIS:
 | 
					                case PPC_INST_ANDIS:
 | 
				
			||||||
                    // TODO: . variant
 | 
					 | 
				
			||||||
                    std::println(f, "\tctx.r{}.u64 = ctx.r{}.u64 & {};", insn.operands[0], insn.operands[1], insn.operands[2] << 16);
 | 
					                    std::println(f, "\tctx.r{}.u64 = ctx.r{}.u64 & {};", insn.operands[0], insn.operands[1], insn.operands[2] << 16);
 | 
				
			||||||
 | 
					                    if (insn.opcode->opcode & 0x1)
 | 
				
			||||||
 | 
					                        std::println(f, "\tctx.cr0.compare<int32_t>(ctx.r{}.s32, 0, ctx.xer);", insn.operands[0]);
 | 
				
			||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                case PPC_INST_ATTN:
 | 
					                case PPC_INST_ATTN:
 | 
				
			||||||
@@ -222,9 +224,21 @@ int main()
 | 
				
			|||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                case PPC_INST_CCTPL:
 | 
					                case PPC_INST_CCTPL:
 | 
				
			||||||
 | 
					                    // no op
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                case PPC_INST_CCTPM:
 | 
					                case PPC_INST_CCTPM:
 | 
				
			||||||
 | 
					                    // no op
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                case PPC_INST_CLRLDI:
 | 
					                case PPC_INST_CLRLDI:
 | 
				
			||||||
 | 
					                    std::println(f, "\tctx.r{}.u64 = ctx.r{}.u64 & 0x{:X};", insn.operands[0], insn.operands[1], (1ull << (64 - insn.operands[2])) - 1);
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                case PPC_INST_CLRLWI:
 | 
					                case PPC_INST_CLRLWI:
 | 
				
			||||||
 | 
					                    std::println(f, "\tctx.r{}.u64 = ctx.r{}.u32 & 0x{:X};", insn.operands[0], insn.operands[1], (1ull << (32 - insn.operands[2])) - 1);
 | 
				
			||||||
 | 
					                    if (insn.opcode->opcode & 0x1)
 | 
				
			||||||
 | 
					                        std::println(f, "\tctx.cr0.compare<int32_t>(ctx.r{}.s32, 0, ctx.xer);", insn.operands[0]);
 | 
				
			||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                case PPC_INST_CMPD:
 | 
					                case PPC_INST_CMPD:
 | 
				
			||||||
@@ -261,7 +275,11 @@ int main()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                case PPC_INST_CNTLZD:
 | 
					                case PPC_INST_CNTLZD:
 | 
				
			||||||
                case PPC_INST_CNTLZW:
 | 
					                case PPC_INST_CNTLZW:
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                case PPC_INST_DB16CYC:
 | 
					                case PPC_INST_DB16CYC:
 | 
				
			||||||
 | 
					                    // no op
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                case PPC_INST_DCBF:
 | 
					                case PPC_INST_DCBF:
 | 
				
			||||||
                    // no op
 | 
					                    // no op
 | 
				
			||||||
@@ -399,8 +417,9 @@ int main()
 | 
				
			|||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                case PPC_INST_MR:
 | 
					                case PPC_INST_MR:
 | 
				
			||||||
                    // TODO: . variant
 | 
					 | 
				
			||||||
                    std::println(f, "\tctx.r{}.u64 = ctx.r{}.u64;", insn.operands[0], insn.operands[1]);
 | 
					                    std::println(f, "\tctx.r{}.u64 = ctx.r{}.u64;", insn.operands[0], insn.operands[1]);
 | 
				
			||||||
 | 
					                    if (insn.opcode->opcode & 0x1)
 | 
				
			||||||
 | 
					                        std::println(f, "\tctx.cr0.compare<int32_t>(ctx.r{}.s32, 0, ctx.xer);", insn.operands[0]);
 | 
				
			||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                case PPC_INST_MTCR:
 | 
					                case PPC_INST_MTCR:
 | 
				
			||||||
@@ -431,8 +450,9 @@ int main()
 | 
				
			|||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                case PPC_INST_MULLW:
 | 
					                case PPC_INST_MULLW:
 | 
				
			||||||
                    // TODO: . variant
 | 
					 | 
				
			||||||
                    std::println(f, "\tctx.r{}.s64 = ctx.r{}.s32 * ctx.r{}.s32;", insn.operands[0], insn.operands[1], insn.operands[2]);
 | 
					                    std::println(f, "\tctx.r{}.s64 = ctx.r{}.s32 * ctx.r{}.s32;", insn.operands[0], insn.operands[1], insn.operands[2]);
 | 
				
			||||||
 | 
					                    if (insn.opcode->opcode & 0x1)
 | 
				
			||||||
 | 
					                        std::println(f, "\tctx.cr0.compare<int32_t>(ctx.r{}.s32, 0, ctx.xer);", insn.operands[0]);
 | 
				
			||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                case PPC_INST_NAND:
 | 
					                case PPC_INST_NAND:
 | 
				
			||||||
@@ -440,8 +460,9 @@ int main()
 | 
				
			|||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                case PPC_INST_NEG:
 | 
					                case PPC_INST_NEG:
 | 
				
			||||||
                    // TODO: . variant
 | 
					 | 
				
			||||||
                    std::println(f, "\tctx.r{}.s64 = -ctx.r{}.s64;", insn.operands[0], insn.operands[1]);
 | 
					                    std::println(f, "\tctx.r{}.s64 = -ctx.r{}.s64;", insn.operands[0], insn.operands[1]);
 | 
				
			||||||
 | 
					                    if (insn.opcode->opcode & 0x1)
 | 
				
			||||||
 | 
					                        std::println(f, "\tctx.cr0.compare<int32_t>(ctx.r{}.s32, 0, ctx.xer);", insn.operands[0]);
 | 
				
			||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                case PPC_INST_NOP:
 | 
					                case PPC_INST_NOP:
 | 
				
			||||||
@@ -453,13 +474,15 @@ int main()
 | 
				
			|||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                case PPC_INST_NOT:
 | 
					                case PPC_INST_NOT:
 | 
				
			||||||
                    // TODO: . variant
 | 
					 | 
				
			||||||
                    std::println(f, "\tctx.r{}.u64 = ~ctx.r{}.u64;", insn.operands[0], insn.operands[1]);
 | 
					                    std::println(f, "\tctx.r{}.u64 = ~ctx.r{}.u64;", insn.operands[0], insn.operands[1]);
 | 
				
			||||||
 | 
					                    if (insn.opcode->opcode & 0x1)
 | 
				
			||||||
 | 
					                        std::println(f, "\tctx.cr0.compare<int32_t>(ctx.r{}.s32, 0, ctx.xer);", insn.operands[0]);
 | 
				
			||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                case PPC_INST_OR:
 | 
					                case PPC_INST_OR:
 | 
				
			||||||
                    // TODO: . variant
 | 
					 | 
				
			||||||
                    std::println(f, "\tctx.r{}.u64 = ctx.r{}.u64 | ctx.r{}.u64;", insn.operands[0], insn.operands[1], insn.operands[2]);
 | 
					                    std::println(f, "\tctx.r{}.u64 = ctx.r{}.u64 | ctx.r{}.u64;", insn.operands[0], insn.operands[1], insn.operands[2]);
 | 
				
			||||||
 | 
					                    if (insn.opcode->opcode & 0x1)
 | 
				
			||||||
 | 
					                        std::println(f, "\tctx.cr0.compare<int32_t>(ctx.r{}.s32, 0, ctx.xer);", insn.operands[0]);
 | 
				
			||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                case PPC_INST_ORC:
 | 
					                case PPC_INST_ORC:
 | 
				
			||||||
@@ -535,8 +558,9 @@ int main()
 | 
				
			|||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                case PPC_INST_SUBF:
 | 
					                case PPC_INST_SUBF:
 | 
				
			||||||
                    // TODO: . variant
 | 
					 | 
				
			||||||
                    std::println(f, "\tctx.r{}.s64 = ctx.r{}.s64 - ctx.r{}.s64;", insn.operands[0], insn.operands[1], insn.operands[2]);
 | 
					                    std::println(f, "\tctx.r{}.s64 = ctx.r{}.s64 - ctx.r{}.s64;", insn.operands[0], insn.operands[1], insn.operands[2]);
 | 
				
			||||||
 | 
					                    if (insn.opcode->opcode & 0x1)
 | 
				
			||||||
 | 
					                        std::println(f, "\tctx.cr0.compare<int32_t>(ctx.r{}.s32, 0, ctx.xer);", insn.operands[0]);
 | 
				
			||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                case PPC_INST_SUBFC:
 | 
					                case PPC_INST_SUBFC:
 | 
				
			||||||
@@ -649,8 +673,9 @@ int main()
 | 
				
			|||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                case PPC_INST_XOR:
 | 
					                case PPC_INST_XOR:
 | 
				
			||||||
                    // TODO: . variant
 | 
					 | 
				
			||||||
                    std::println(f, "\tctx.r{}.u64 = ctx.r{}.u64 ^ ctx.r{}.u64;", insn.operands[0], insn.operands[1], insn.operands[2]);
 | 
					                    std::println(f, "\tctx.r{}.u64 = ctx.r{}.u64 ^ ctx.r{}.u64;", insn.operands[0], insn.operands[1], insn.operands[2]);
 | 
				
			||||||
 | 
					                    if (insn.opcode->opcode & 0x1)
 | 
				
			||||||
 | 
					                        std::println(f, "\tctx.cr0.compare<int32_t>(ctx.r{}.s32, 0, ctx.xer);", insn.operands[0]);
 | 
				
			||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                case PPC_INST_XORI:
 | 
					                case PPC_INST_XORI:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,7 +7,7 @@
 | 
				
			|||||||
#define _byteswap_ushort __builtin_bswap16
 | 
					#define _byteswap_ushort __builtin_bswap16
 | 
				
			||||||
#define _byteswap_ulong __builtin_bswap32
 | 
					#define _byteswap_ulong __builtin_bswap32
 | 
				
			||||||
#define _byteswap_uint64 __builtin_bswap64
 | 
					#define _byteswap_uint64 __builtin_bswap64
 | 
				
			||||||
#define PPC_FUNC extern inline __attribute__((weak,noinline))
 | 
					#define PPC_FUNC __attribute__((weak,noinline))
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
#define PPC_FUNC __declspec(noinline)
 | 
					#define PPC_FUNC __declspec(noinline)
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										10
									
								
								tests/PowerAnalyse/add-cond.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								tests/PowerAnalyse/add-cond.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
				
			|||||||
 | 
					int add(int a, int b)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int c = a + b;
 | 
				
			||||||
 | 
					    return c == 0 ? 50000 : c;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern "C" int _start()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return add(1, 2);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								tests/PowerAnalyse/add-cond.elf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								tests/PowerAnalyse/add-cond.elf
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
		Reference in New Issue
	
	Block a user