mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 13:50:03 +00:00 
			
		
		
		
	Merge pull request #1008 from lioncash/pc
dyncom: Handle the case where PC is the source register for STR/VSTM/VLDM
This commit is contained in:
		
						commit
						ce65925bc3
					
				
					 2 changed files with 40 additions and 21 deletions
				
			
		|  | @ -5994,7 +5994,12 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | ||||||
|             ldst_inst* inst_cream = (ldst_inst*)inst_base->component; |             ldst_inst* inst_cream = (ldst_inst*)inst_base->component; | ||||||
|             inst_cream->get_addr(cpu, inst_cream->inst, addr); |             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->WriteMemory32(addr, value); | ||||||
|         } |         } | ||||||
|         cpu->Reg[15] += cpu->GetInstructionSize(); |         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 | #ifdef VFP_INTERPRETER_IMPL | ||||||
| VSTM_INST: /* encoding 1 */ | 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; |         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++) |         for (unsigned int i = 0; i < inst_cream->regs; i++) | ||||||
|         { |         { | ||||||
|             if (inst_cream->single) |             if (inst_cream->single) | ||||||
|             { |             { | ||||||
|                 cpu->WriteMemory32(addr, cpu->ExtReg[inst_cream->d+i]); |                 cpu->WriteMemory32(address, cpu->ExtReg[inst_cream->d+i]); | ||||||
|                 addr += 4; |                 address += 4; | ||||||
|             } |             } | ||||||
|             else |             else | ||||||
|             { |             { | ||||||
|  | @ -1531,17 +1538,17 @@ VSTM_INST: /* encoding 1 */ | ||||||
|                 const u32 word2 = cpu->ExtReg[(inst_cream->d+i)*2+1]; |                 const u32 word2 = cpu->ExtReg[(inst_cream->d+i)*2+1]; | ||||||
| 
 | 
 | ||||||
|                 if (cpu->InBigEndianMode()) { |                 if (cpu->InBigEndianMode()) { | ||||||
|                     cpu->WriteMemory32(addr + 0, word2); |                     cpu->WriteMemory32(address + 0, word2); | ||||||
|                     cpu->WriteMemory32(addr + 4, word1); |                     cpu->WriteMemory32(address + 4, word1); | ||||||
|                 } else { |                 } else { | ||||||
|                     cpu->WriteMemory32(addr + 0, word1); |                     cpu->WriteMemory32(address + 0, word1); | ||||||
|                     cpu->WriteMemory32(addr + 4, word2); |                     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->add ? cpu->Reg[inst_cream->n] + inst_cream->imm32 : | ||||||
|                 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 | #ifdef VFP_INTERPRETER_IMPL | ||||||
| VLDM_INST: | 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; |         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++) |         for (unsigned int i = 0; i < inst_cream->regs; i++) | ||||||
|         { |         { | ||||||
|             if (inst_cream->single) |             if (inst_cream->single) | ||||||
|             { |             { | ||||||
|                 cpu->ExtReg[inst_cream->d+i] = cpu->ReadMemory32(addr); |                 cpu->ExtReg[inst_cream->d+i] = cpu->ReadMemory32(address); | ||||||
|                 addr += 4; |                 address += 4; | ||||||
|             } |             } | ||||||
|             else |             else | ||||||
|             { |             { | ||||||
|                 const u32 word1 = cpu->ReadMemory32(addr + 0); |                 const u32 word1 = cpu->ReadMemory32(address + 0); | ||||||
|                 const u32 word2 = cpu->ReadMemory32(addr + 4); |                 const u32 word2 = cpu->ReadMemory32(address + 4); | ||||||
| 
 | 
 | ||||||
|                 if (cpu->InBigEndianMode()) { |                 if (cpu->InBigEndianMode()) { | ||||||
|                     cpu->ExtReg[(inst_cream->d+i)*2+0] = word2; |                     cpu->ExtReg[(inst_cream->d+i)*2+0] = word2; | ||||||
|  | @ -1758,10 +1772,10 @@ VLDM_INST: | ||||||
|                     cpu->ExtReg[(inst_cream->d+i)*2+1] = word2; |                     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->add ? cpu->Reg[inst_cream->n] + inst_cream->imm32 : | ||||||
|                 cpu->Reg[inst_cream->n] - inst_cream->imm32); |                 cpu->Reg[inst_cream->n] - inst_cream->imm32); | ||||||
|         } |         } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue