mirror of
				https://github.com/hedge-dev/XenonRecomp.git
				synced 2025-11-04 06:47:09 +00:00 
			
		
		
		
	bctr and conditional returns
This commit is contained in:
		@@ -18,9 +18,19 @@ size_t Function::SearchBlock(size_t address) const
 | 
				
			|||||||
        const auto begin = base + block.base;
 | 
					        const auto begin = base + block.base;
 | 
				
			||||||
        const auto end = begin + block.size;
 | 
					        const auto end = begin + block.size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (address >= begin && address < end)
 | 
					        if (begin != end)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return i;
 | 
					            if (address >= begin && address < end)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                return i;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else // fresh block
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (address == begin)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                return i;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -53,6 +63,7 @@ Function Function::Analyze(const void* code, size_t size, size_t base)
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        auto& curBlock = blocks[blockStack.back()];
 | 
					        auto& curBlock = blocks[blockStack.back()];
 | 
				
			||||||
 | 
					        DEBUG(const auto blockBase = curBlock.base);
 | 
				
			||||||
        const auto instruction = std::byteswap(*data);
 | 
					        const auto instruction = std::byteswap(*data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const auto op = PPC_OP(instruction);
 | 
					        const auto op = PPC_OP(instruction);
 | 
				
			||||||
@@ -98,7 +109,6 @@ Function Function::Analyze(const void* code, size_t size, size_t base)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            if (lBlock == -1)
 | 
					            if (lBlock == -1)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                DEBUG(const auto blockBase = curBlock.base);
 | 
					 | 
				
			||||||
                blocks.emplace_back(lBase, 0).projectedSize = rBase - lBase;
 | 
					                blocks.emplace_back(lBase, 0).projectedSize = rBase - lBase;
 | 
				
			||||||
                lBlock = blocks.size() - 1;
 | 
					                lBlock = blocks.size() - 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -110,7 +120,6 @@ Function Function::Analyze(const void* code, size_t size, size_t base)
 | 
				
			|||||||
            auto rBlock = fn.SearchBlock(base + rBase);
 | 
					            auto rBlock = fn.SearchBlock(base + rBase);
 | 
				
			||||||
            if (rBlock == -1)
 | 
					            if (rBlock == -1)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                DEBUG(const auto blockBase = curBlock.base);
 | 
					 | 
				
			||||||
                blocks.emplace_back(branchDest - base, 0);
 | 
					                blocks.emplace_back(branchDest - base, 0);
 | 
				
			||||||
                rBlock = blocks.size() - 1;
 | 
					                rBlock = blocks.size() - 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -120,7 +129,7 @@ Function Function::Analyze(const void* code, size_t size, size_t base)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            RESTORE_DATA();
 | 
					            RESTORE_DATA();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else if (op == PPC_OP_B || instruction == 0 || (insn.opcode != nullptr && insn.opcode->id == PPC_INST_BLR)) // b, blr, end padding
 | 
					        else if (op == PPC_OP_B || instruction == 0 || (op == PPC_OP_CTR && (xop == 16 || xop == 528))) // b, blr, end padding
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (!isLink)
 | 
					            if (!isLink)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
@@ -135,7 +144,6 @@ Function Function::Analyze(const void* code, size_t size, size_t base)
 | 
				
			|||||||
                        continue;
 | 
					                        continue;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    // Keep analyzing if we have continuity
 | 
					 | 
				
			||||||
                    assert(!PPC_BA(instruction));
 | 
					                    assert(!PPC_BA(instruction));
 | 
				
			||||||
                    const auto branchDest = addr + PPC_BI(instruction);
 | 
					                    const auto branchDest = addr + PPC_BI(instruction);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -160,15 +168,36 @@ Function Function::Analyze(const void* code, size_t size, size_t base)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                    if (branchBlock == -1)
 | 
					                    if (branchBlock == -1)
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        DEBUG(const auto blockBase = curBlock.base);
 | 
					 | 
				
			||||||
                        blocks.emplace_back(branchBase, 0, sizeProjection);
 | 
					                        blocks.emplace_back(branchBase, 0, sizeProjection);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        blockStack.emplace_back(blocks.size() - 1);
 | 
					                        blockStack.emplace_back(blocks.size() - 1);
 | 
				
			||||||
 | 
					                        
 | 
				
			||||||
                        DEBUG(blocks.back().parent = blockBase);
 | 
					                        DEBUG(blocks.back().parent = blockBase);
 | 
				
			||||||
                        RESTORE_DATA();
 | 
					                        RESTORE_DATA();
 | 
				
			||||||
                        continue;
 | 
					                        continue;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					                else if (op == PPC_OP_CTR)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    // 5th bit of BO tells cpu to ignore the counter, which is a blr/bctr otherwise it's conditional
 | 
				
			||||||
 | 
					                    const auto conditional = !(PPC_BO(instruction) & 0x10);
 | 
				
			||||||
 | 
					                    if (conditional)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        // right block's just going to return
 | 
				
			||||||
 | 
					                        const auto lBase = (addr - base) + 4;
 | 
				
			||||||
 | 
					                        auto lBlock = fn.SearchBlock(lBase);
 | 
				
			||||||
 | 
					                        if (lBlock == -1)
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            blocks.emplace_back(lBase, 0);
 | 
				
			||||||
 | 
					                            lBlock = blocks.size() - 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                            DEBUG(blocks[lBlock].parent = blockBase);
 | 
				
			||||||
 | 
					                            blockStack.emplace_back(lBlock);
 | 
				
			||||||
 | 
					                            RESTORE_DATA();
 | 
				
			||||||
 | 
					                            continue;
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                RESTORE_DATA();
 | 
					                RESTORE_DATA();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user