mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu.git
				synced 2025-05-12 00:45:25 +00:00 
			
		
		
		
	dyncom: Handle the case where PC is the source register for STR/VSTM/VLDM
This commit is contained in:
		
							parent
							
								
									7c7eeb9d34
								
							
						
					
					
						commit
						2e420aba3c
					
				@ -5997,7 +5997,12 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
 | 
			
		||||
            ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
 | 
			
		||||
            inst_cream->get_addr(cpu, inst_cream->inst, addr);
 | 
			
		||||
 | 
			
		||||
            unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)];
 | 
			
		||||
            unsigned int reg = BITS(inst_cream->inst, 12, 15);
 | 
			
		||||
            unsigned int value = cpu->Reg[reg];
 | 
			
		||||
 | 
			
		||||
            if (reg == 15)
 | 
			
		||||
                value += 2 * cpu->GetInstructionSize();
 | 
			
		||||
 | 
			
		||||
            cpu->WriteMemory32(addr, value);
 | 
			
		||||
        }
 | 
			
		||||
        cpu->Reg[15] += cpu->GetInstructionSize();
 | 
			
		||||
 | 
			
		||||
@ -1511,19 +1511,26 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vstm)(unsigned int inst, int index)
 | 
			
		||||
#ifdef VFP_INTERPRETER_IMPL
 | 
			
		||||
VSTM_INST: /* encoding 1 */
 | 
			
		||||
{
 | 
			
		||||
    if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
 | 
			
		||||
    if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
 | 
			
		||||
        CHECK_VFP_ENABLED;
 | 
			
		||||
 | 
			
		||||
        vstm_inst *inst_cream = (vstm_inst *)inst_base->component;
 | 
			
		||||
        vstm_inst* inst_cream = (vstm_inst*)inst_base->component;
 | 
			
		||||
 | 
			
		||||
        addr = (inst_cream->add ? cpu->Reg[inst_cream->n] : cpu->Reg[inst_cream->n] - inst_cream->imm32);
 | 
			
		||||
        u32 address = cpu->Reg[inst_cream->n];
 | 
			
		||||
 | 
			
		||||
        // Only possible in ARM mode, where PC accesses have an 8 byte offset.
 | 
			
		||||
        if (inst_cream->n == 15)
 | 
			
		||||
            address += 8;
 | 
			
		||||
 | 
			
		||||
        if (inst_cream->add == 0)
 | 
			
		||||
            address -= inst_cream->imm32;
 | 
			
		||||
 | 
			
		||||
        for (unsigned int i = 0; i < inst_cream->regs; i++)
 | 
			
		||||
        {
 | 
			
		||||
            if (inst_cream->single)
 | 
			
		||||
            {
 | 
			
		||||
                cpu->WriteMemory32(addr, cpu->ExtReg[inst_cream->d+i]);
 | 
			
		||||
                addr += 4;
 | 
			
		||||
                cpu->WriteMemory32(address, cpu->ExtReg[inst_cream->d+i]);
 | 
			
		||||
                address += 4;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
@ -1531,17 +1538,17 @@ VSTM_INST: /* encoding 1 */
 | 
			
		||||
                const u32 word2 = cpu->ExtReg[(inst_cream->d+i)*2+1];
 | 
			
		||||
 | 
			
		||||
                if (cpu->InBigEndianMode()) {
 | 
			
		||||
                    cpu->WriteMemory32(addr + 0, word2);
 | 
			
		||||
                    cpu->WriteMemory32(addr + 4, word1);
 | 
			
		||||
                    cpu->WriteMemory32(address + 0, word2);
 | 
			
		||||
                    cpu->WriteMemory32(address + 4, word1);
 | 
			
		||||
                } else {
 | 
			
		||||
                    cpu->WriteMemory32(addr + 0, word1);
 | 
			
		||||
                    cpu->WriteMemory32(addr + 4, word2);
 | 
			
		||||
                    cpu->WriteMemory32(address + 0, word1);
 | 
			
		||||
                    cpu->WriteMemory32(address + 4, word2);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                addr += 8;
 | 
			
		||||
                address += 8;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (inst_cream->wback){
 | 
			
		||||
        if (inst_cream->wback) {
 | 
			
		||||
            cpu->Reg[inst_cream->n] = (inst_cream->add ? cpu->Reg[inst_cream->n] + inst_cream->imm32 :
 | 
			
		||||
                cpu->Reg[inst_cream->n] - inst_cream->imm32);
 | 
			
		||||
        }
 | 
			
		||||
@ -1731,24 +1738,31 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vldm)(unsigned int inst, int index)
 | 
			
		||||
#ifdef VFP_INTERPRETER_IMPL
 | 
			
		||||
VLDM_INST:
 | 
			
		||||
{
 | 
			
		||||
    if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
 | 
			
		||||
    if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
 | 
			
		||||
        CHECK_VFP_ENABLED;
 | 
			
		||||
 | 
			
		||||
        vldm_inst *inst_cream = (vldm_inst *)inst_base->component;
 | 
			
		||||
        vldm_inst* inst_cream = (vldm_inst*)inst_base->component;
 | 
			
		||||
 | 
			
		||||
        addr = (inst_cream->add ? cpu->Reg[inst_cream->n] : cpu->Reg[inst_cream->n] - inst_cream->imm32);
 | 
			
		||||
        u32 address = cpu->Reg[inst_cream->n];
 | 
			
		||||
 | 
			
		||||
        // Only possible in ARM mode, where PC accesses have an 8 byte offset.
 | 
			
		||||
        if (inst_cream->n == 15)
 | 
			
		||||
            address += 8;
 | 
			
		||||
 | 
			
		||||
        if (inst_cream->add == 0)
 | 
			
		||||
            address -= inst_cream->imm32;
 | 
			
		||||
 | 
			
		||||
        for (unsigned int i = 0; i < inst_cream->regs; i++)
 | 
			
		||||
        {
 | 
			
		||||
            if (inst_cream->single)
 | 
			
		||||
            {
 | 
			
		||||
                cpu->ExtReg[inst_cream->d+i] = cpu->ReadMemory32(addr);
 | 
			
		||||
                addr += 4;
 | 
			
		||||
                cpu->ExtReg[inst_cream->d+i] = cpu->ReadMemory32(address);
 | 
			
		||||
                address += 4;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                const u32 word1 = cpu->ReadMemory32(addr + 0);
 | 
			
		||||
                const u32 word2 = cpu->ReadMemory32(addr + 4);
 | 
			
		||||
                const u32 word1 = cpu->ReadMemory32(address + 0);
 | 
			
		||||
                const u32 word2 = cpu->ReadMemory32(address + 4);
 | 
			
		||||
 | 
			
		||||
                if (cpu->InBigEndianMode()) {
 | 
			
		||||
                    cpu->ExtReg[(inst_cream->d+i)*2+0] = word2;
 | 
			
		||||
@ -1758,10 +1772,10 @@ VLDM_INST:
 | 
			
		||||
                    cpu->ExtReg[(inst_cream->d+i)*2+1] = word2;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                addr += 8;
 | 
			
		||||
                address += 8;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (inst_cream->wback){
 | 
			
		||||
        if (inst_cream->wback) {
 | 
			
		||||
            cpu->Reg[inst_cream->n] = (inst_cream->add ? cpu->Reg[inst_cream->n] + inst_cream->imm32 :
 | 
			
		||||
                cpu->Reg[inst_cream->n] - inst_cream->imm32);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user