mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	dyncom: Handle unprivileged load/store variants correctly
LDRT/LDRBT/STRBT/STRT should simulate the load or store as if the host CPU is in user mode. STRT is also allowed to use the PC as an operand
This commit is contained in:
		
							parent
							
								
									bbb96a392d
								
							
						
					
					
						commit
						5a531d7ec2
					
				
					 1 changed files with 33 additions and 7 deletions
				
			
		|  | @ -4494,9 +4494,16 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
|             ldst_inst* inst_cream = (ldst_inst*)inst_base->component; | ||||
|             inst_cream->get_addr(cpu, inst_cream->inst, addr); | ||||
| 
 | ||||
|             cpu->Reg[BITS(inst_cream->inst, 12, 15)] = cpu->ReadMemory8(addr); | ||||
|             const u32 dest_index = BITS(inst_cream->inst, 12, 15); | ||||
|             const u32 previous_mode = cpu->Mode; | ||||
| 
 | ||||
|             if (BITS(inst_cream->inst, 12, 15) == 15) { | ||||
|             cpu->ChangePrivilegeMode(USER32MODE); | ||||
|             const u8 value = cpu->ReadMemory8(addr); | ||||
|             cpu->ChangePrivilegeMode(previous_mode); | ||||
| 
 | ||||
|             cpu->Reg[dest_index] = value; | ||||
| 
 | ||||
|             if (dest_index == 15) { | ||||
|                 INC_PC(sizeof(ldst_inst)); | ||||
|                 goto DISPATCH; | ||||
|             } | ||||
|  | @ -4668,10 +4675,16 @@ 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->ReadMemory32(addr); | ||||
|             cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; | ||||
|             const u32 dest_index = BITS(inst_cream->inst, 12, 15); | ||||
|             const u32 previous_mode = cpu->Mode; | ||||
| 
 | ||||
|             if (BITS(inst_cream->inst, 12, 15) == 15) { | ||||
|             cpu->ChangePrivilegeMode(USER32MODE); | ||||
|             const u32 value = cpu->ReadMemory32(addr); | ||||
|             cpu->ChangePrivilegeMode(previous_mode); | ||||
| 
 | ||||
|             cpu->Reg[dest_index] = value; | ||||
| 
 | ||||
|             if (dest_index == 15) { | ||||
|                 INC_PC(sizeof(ldst_inst)); | ||||
|                 goto DISPATCH; | ||||
|             } | ||||
|  | @ -6061,8 +6074,13 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
|         if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { | ||||
|             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)] & 0xff; | ||||
| 
 | ||||
|             const u32 previous_mode = cpu->Mode; | ||||
|             const u32 value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff; | ||||
| 
 | ||||
|             cpu->ChangePrivilegeMode(USER32MODE); | ||||
|             cpu->WriteMemory8(addr, value); | ||||
|             cpu->ChangePrivilegeMode(previous_mode); | ||||
|         } | ||||
|         cpu->Reg[15] += cpu->GetInstructionSize(); | ||||
|         INC_PC(sizeof(ldst_inst)); | ||||
|  | @ -6196,8 +6214,16 @@ 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)]; | ||||
|             const u32 previous_mode = cpu->Mode; | ||||
|             const u32 rt_index = BITS(inst_cream->inst, 12, 15); | ||||
| 
 | ||||
|             u32 value = cpu->Reg[rt_index]; | ||||
|             if (rt_index == 15) | ||||
|                 value += 2 * cpu->GetInstructionSize(); | ||||
| 
 | ||||
|             cpu->ChangePrivilegeMode(USER32MODE); | ||||
|             cpu->WriteMemory32(addr, value); | ||||
|             cpu->ChangePrivilegeMode(previous_mode); | ||||
|         } | ||||
|         cpu->Reg[15] += cpu->GetInstructionSize(); | ||||
|         INC_PC(sizeof(ldst_inst)); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue