Pass memory manager type around

This commit is contained in:
Gabriel A 2024-01-04 17:42:33 -03:00
parent 133f7d10de
commit 98c16ed3b0
6 changed files with 119 additions and 97 deletions

View File

@ -1,3 +1,4 @@
using ARMeilleure.Memory;
using Ryujinx.Cpu.LightningJit.CodeGen.Arm64; using Ryujinx.Cpu.LightningJit.CodeGen.Arm64;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -10,6 +11,8 @@ namespace Ryujinx.Cpu.LightningJit.Arm32
public Assembler Arm64Assembler { get; } public Assembler Arm64Assembler { get; }
public RegisterAllocator RegisterAllocator { get; } public RegisterAllocator RegisterAllocator { get; }
public MemoryManagerType MemoryManagerType { get; }
private uint _instructionAddress; private uint _instructionAddress;
public bool IsThumb { get; } public bool IsThumb { get; }
@ -26,11 +29,12 @@ namespace Ryujinx.Cpu.LightningJit.Arm32
private bool _nzcvModified; private bool _nzcvModified;
public CodeGenContext(CodeWriter codeWriter, Assembler arm64Assembler, RegisterAllocator registerAllocator, bool isThumb) public CodeGenContext(CodeWriter codeWriter, Assembler arm64Assembler, RegisterAllocator registerAllocator, MemoryManagerType mmType, bool isThumb)
{ {
CodeWriter = codeWriter; CodeWriter = codeWriter;
Arm64Assembler = arm64Assembler; Arm64Assembler = arm64Assembler;
RegisterAllocator = registerAllocator; RegisterAllocator = registerAllocator;
MemoryManagerType = mmType;
_itConditions = new ArmCondition[4]; _itConditions = new ArmCondition[4];
_pendingBranches = new(); _pendingBranches = new();
IsThumb = isThumb; IsThumb = isThumb;

View File

@ -21,6 +21,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
{ {
public readonly CodeWriter Writer; public readonly CodeWriter Writer;
public readonly RegisterAllocator RegisterAllocator; public readonly RegisterAllocator RegisterAllocator;
public readonly MemoryManagerType MemoryManagerType;
public readonly TailMerger TailMerger; public readonly TailMerger TailMerger;
public readonly AddressTable<ulong> FuncTable; public readonly AddressTable<ulong> FuncTable;
public readonly IntPtr DispatchStubPointer; public readonly IntPtr DispatchStubPointer;
@ -31,6 +32,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
public Context( public Context(
CodeWriter writer, CodeWriter writer,
RegisterAllocator registerAllocator, RegisterAllocator registerAllocator,
MemoryManagerType mmType,
TailMerger tailMerger, TailMerger tailMerger,
AddressTable<ulong> funcTable, AddressTable<ulong> funcTable,
RegisterSaveRestore registerSaveRestore, RegisterSaveRestore registerSaveRestore,
@ -39,6 +41,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
{ {
Writer = writer; Writer = writer;
RegisterAllocator = registerAllocator; RegisterAllocator = registerAllocator;
MemoryManagerType = mmType;
TailMerger = tailMerger; TailMerger = tailMerger;
FuncTable = funcTable; FuncTable = funcTable;
_registerSaveRestore = registerSaveRestore; _registerSaveRestore = registerSaveRestore;
@ -232,7 +235,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
CodeWriter writer = new(); CodeWriter writer = new();
RegisterAllocator regAlloc = new(); RegisterAllocator regAlloc = new();
Assembler asm = new(writer); Assembler asm = new(writer);
CodeGenContext cgContext = new(writer, asm, regAlloc, isThumb); CodeGenContext cgContext = new(writer, asm, regAlloc, memoryManager.Type, isThumb);
ArmCondition lastCondition = ArmCondition.Al; ArmCondition lastCondition = ArmCondition.Al;
int lastConditionIp = 0; int lastConditionIp = 0;
@ -311,7 +314,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
TailMerger tailMerger = new(); TailMerger tailMerger = new();
Context context = new(writer, regAlloc, tailMerger, funcTable, rsr, dispatchStubPtr, memoryManager.PageTablePointer); Context context = new(writer, regAlloc, memoryManager.Type, tailMerger, funcTable, rsr, dispatchStubPtr, memoryManager.PageTablePointer);
InstInfo lastInstruction = multiBlock.Blocks[^1].Instructions[^1]; InstInfo lastInstruction = multiBlock.Blocks[^1].Instructions[^1];
bool lastInstIsConditional = GetCondition(lastInstruction, isThumb) != ArmCondition.Al; bool lastInstIsConditional = GetCondition(lastInstruction, isThumb) != ArmCondition.Al;
@ -635,7 +638,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
ArmShiftType.Lsl, ArmShiftType.Lsl,
halfword ? 1 : 0); halfword ? 1 : 0);
InstEmitMemory.WriteAddressTranslation(context.RegisterAllocator, asm, target.Operand, target.Operand); InstEmitMemory.WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, asm, target.Operand, target.Operand);
if (halfword) if (halfword)
{ {

View File

@ -1,3 +1,4 @@
using ARMeilleure.Memory;
using Ryujinx.Cpu.LightningJit.CodeGen; using Ryujinx.Cpu.LightningJit.CodeGen;
using Ryujinx.Cpu.LightningJit.CodeGen.Arm64; using Ryujinx.Cpu.LightningJit.CodeGen.Arm64;
using System; using System;
@ -66,7 +67,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
WriteAddressTranslation(context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, baseAddress); WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, baseAddress);
EmitMemoryMultipleInstructionCore( EmitMemoryMultipleInstructionCore(
context, context,
@ -335,7 +336,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
WriteAddressTranslation(context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, baseAddress); WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, baseAddress);
EmitMemoryMultipleInstructionCore( EmitMemoryMultipleInstructionCore(
context, context,
@ -477,7 +478,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
offset = InstEmitCommon.Const(BitOperations.PopCount(registerList) * 4 - 4); offset = InstEmitCommon.Const(BitOperations.PopCount(registerList) * 4 - 4);
WriteAddShiftOffset(context.Arm64Assembler, tempRegister.Operand, baseAddress, offset, false, ArmShiftType.Lsl, 0); WriteAddShiftOffset(context.Arm64Assembler, tempRegister.Operand, baseAddress, offset, false, ArmShiftType.Lsl, 0);
WriteAddressTranslation(context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, tempRegister.Operand); WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, tempRegister.Operand);
EmitMemoryMultipleInstructionCore( EmitMemoryMultipleInstructionCore(
context, context,
@ -516,12 +517,12 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
if (w && !writesToRn) if (w && !writesToRn)
{ {
WriteAddShiftOffset(context.Arm64Assembler, baseAddress, baseAddress, offset, false, ArmShiftType.Lsl, 0); WriteAddShiftOffset(context.Arm64Assembler, baseAddress, baseAddress, offset, false, ArmShiftType.Lsl, 0);
WriteAddressTranslation(context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, baseAddress); WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, baseAddress);
} }
else else
{ {
WriteAddShiftOffset(context.Arm64Assembler, tempRegister.Operand, baseAddress, offset, false, ArmShiftType.Lsl, 0); WriteAddShiftOffset(context.Arm64Assembler, tempRegister.Operand, baseAddress, offset, false, ArmShiftType.Lsl, 0);
WriteAddressTranslation(context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, tempRegister.Operand); WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, tempRegister.Operand);
} }
EmitMemoryMultipleInstructionCore( EmitMemoryMultipleInstructionCore(
@ -554,7 +555,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
Operand offset = InstEmitCommon.Const(4); Operand offset = InstEmitCommon.Const(4);
WriteAddShiftOffset(context.Arm64Assembler, tempRegister.Operand, baseAddress, offset, true, ArmShiftType.Lsl, 0); WriteAddShiftOffset(context.Arm64Assembler, tempRegister.Operand, baseAddress, offset, true, ArmShiftType.Lsl, 0);
WriteAddressTranslation(context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, tempRegister.Operand); WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, tempRegister.Operand);
EmitMemoryMultipleInstructionCore( EmitMemoryMultipleInstructionCore(
context, context,
@ -663,7 +664,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
WriteAddressTranslation(context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, rnOperand); WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, rnOperand);
action(rtOperand, tempRegister.Operand); action(rtOperand, tempRegister.Operand);
} }
@ -676,7 +677,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
WriteAddressTranslation(context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, rnOperand); WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, rnOperand);
action(rtOperand, rt2Operand, tempRegister.Operand); action(rtOperand, rt2Operand, tempRegister.Operand);
} }
@ -746,17 +747,17 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
if (offset.Kind == OperandKind.Constant && offset.Value == 0) if (offset.Kind == OperandKind.Constant && offset.Value == 0)
{ {
WriteAddressTranslation(regAlloc, asm, tempRegister.Operand, baseAddress); WriteAddressTranslation(context.MemoryManagerType, regAlloc, asm, tempRegister.Operand, baseAddress);
} }
else if (offset.Kind == OperandKind.Constant && CanFoldDWordOffset(signedOffs)) else if (offset.Kind == OperandKind.Constant && CanFoldDWordOffset(context.MemoryManagerType, signedOffs))
{ {
WriteAddressTranslation(regAlloc, asm, tempRegister.Operand, baseAddress); WriteAddressTranslation(context.MemoryManagerType, regAlloc, asm, tempRegister.Operand, baseAddress);
offs = signedOffs; offs = signedOffs;
} }
else else
{ {
WriteAddShiftOffset(asm, tempRegister.Operand, baseAddress, offset, add, ArmShiftType.Lsl, 0); WriteAddShiftOffset(asm, tempRegister.Operand, baseAddress, offset, add, ArmShiftType.Lsl, 0);
WriteAddressTranslation(regAlloc, asm, tempRegister.Operand, tempRegister.Operand); WriteAddressTranslation(context.MemoryManagerType, regAlloc, asm, tempRegister.Operand, tempRegister.Operand);
} }
action(rt, rt2, tempRegister.Operand, offs); action(rt, rt2, tempRegister.Operand, offs);
@ -767,7 +768,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
using ScopedRegister tempRegister = regAlloc.AllocateTempGprRegisterScoped(); using ScopedRegister tempRegister = regAlloc.AllocateTempGprRegisterScoped();
WriteAddressTranslation(regAlloc, asm, tempRegister.Operand, baseAddress); WriteAddressTranslation(context.MemoryManagerType, regAlloc, asm, tempRegister.Operand, baseAddress);
action(rt, rt2, tempRegister.Operand, 0); action(rt, rt2, tempRegister.Operand, 0);
@ -784,7 +785,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
// If Rt and Rn are the same register, ensure we perform the write back after the read/write. // If Rt and Rn are the same register, ensure we perform the write back after the read/write.
WriteAddShiftOffset(asm, tempRegister.Operand, baseAddress, offset, add, ArmShiftType.Lsl, 0); WriteAddShiftOffset(asm, tempRegister.Operand, baseAddress, offset, add, ArmShiftType.Lsl, 0);
WriteAddressTranslation(regAlloc, asm, tempRegister.Operand, tempRegister.Operand); WriteAddressTranslation(context.MemoryManagerType, regAlloc, asm, tempRegister.Operand, tempRegister.Operand);
action(rt, rt2, tempRegister.Operand, 0); action(rt, rt2, tempRegister.Operand, 0);
@ -793,7 +794,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
else else
{ {
WriteAddShiftOffset(asm, baseAddress, baseAddress, offset, add, ArmShiftType.Lsl, 0); WriteAddShiftOffset(asm, baseAddress, baseAddress, offset, add, ArmShiftType.Lsl, 0);
WriteAddressTranslation(regAlloc, asm, tempRegister.Operand, baseAddress); WriteAddressTranslation(context.MemoryManagerType, regAlloc, asm, tempRegister.Operand, baseAddress);
action(rt, rt2, tempRegister.Operand, 0); action(rt, rt2, tempRegister.Operand, 0);
} }
@ -808,7 +809,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
WriteAddressTranslation(context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, rnOperand); WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, rnOperand);
action(rdOperand, rtOperand, tempRegister.Operand); action(rdOperand, rtOperand, tempRegister.Operand);
} }
@ -822,7 +823,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
WriteAddressTranslation(context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, rnOperand); WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, rnOperand);
action(rdOperand, rtOperand, rt2Operand, tempRegister.Operand); action(rdOperand, rtOperand, rt2Operand, tempRegister.Operand);
} }
@ -856,17 +857,17 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
if (offset.Kind == OperandKind.Constant && offset.Value == 0) if (offset.Kind == OperandKind.Constant && offset.Value == 0)
{ {
WriteAddressTranslation(regAlloc, asm, tempRegister.Operand, baseAddress); WriteAddressTranslation(context.MemoryManagerType, regAlloc, asm, tempRegister.Operand, baseAddress);
} }
else if (offset.Kind == OperandKind.Constant && shift == 0 && CanFoldOffset(signedOffs, scale, writeInstUnscaled != null, out unscaled)) else if (offset.Kind == OperandKind.Constant && shift == 0 && CanFoldOffset(context.MemoryManagerType, signedOffs, scale, writeInstUnscaled != null, out unscaled))
{ {
WriteAddressTranslation(regAlloc, asm, tempRegister.Operand, baseAddress); WriteAddressTranslation(context.MemoryManagerType, regAlloc, asm, tempRegister.Operand, baseAddress);
offs = signedOffs; offs = signedOffs;
} }
else else
{ {
WriteAddShiftOffset(asm, tempRegister.Operand, baseAddress, offset, add, shiftType, shift); WriteAddShiftOffset(asm, tempRegister.Operand, baseAddress, offset, add, shiftType, shift);
WriteAddressTranslation(regAlloc, asm, tempRegister.Operand, tempRegister.Operand); WriteAddressTranslation(context.MemoryManagerType, regAlloc, asm, tempRegister.Operand, tempRegister.Operand);
} }
if (unscaled) if (unscaled)
@ -891,7 +892,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
{ {
using ScopedRegister tempRegister = regAlloc.AllocateTempGprRegisterScoped(); using ScopedRegister tempRegister = regAlloc.AllocateTempGprRegisterScoped();
WriteAddressTranslation(regAlloc, asm, tempRegister.Operand, baseAddress); WriteAddressTranslation(context.MemoryManagerType, regAlloc, asm, tempRegister.Operand, baseAddress);
WriteAddShiftOffset(asm, baseAddress, baseAddress, offset, add, shiftType, shift); WriteAddShiftOffset(asm, baseAddress, baseAddress, offset, add, shiftType, shift);
writeInst(rt, tempRegister.Operand, 0); writeInst(rt, tempRegister.Operand, 0);
@ -901,7 +902,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
using ScopedRegister tempRegister = regAlloc.AllocateTempGprRegisterScoped(); using ScopedRegister tempRegister = regAlloc.AllocateTempGprRegisterScoped();
using ScopedRegister tempRegister2 = regAlloc.AllocateTempGprRegisterScoped(); using ScopedRegister tempRegister2 = regAlloc.AllocateTempGprRegisterScoped();
WriteAddressTranslation(regAlloc, asm, tempRegister.Operand, baseAddress); WriteAddressTranslation(context.MemoryManagerType, regAlloc, asm, tempRegister.Operand, baseAddress);
WriteAddShiftOffset(asm, tempRegister2.Operand, baseAddress, offset, add, shiftType, shift); WriteAddShiftOffset(asm, tempRegister2.Operand, baseAddress, offset, add, shiftType, shift);
writeInst(rt, tempRegister.Operand, 0); writeInst(rt, tempRegister.Operand, 0);
@ -913,7 +914,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
{ {
using ScopedRegister tempRegister = regAlloc.AllocateTempGprRegisterScoped(); using ScopedRegister tempRegister = regAlloc.AllocateTempGprRegisterScoped();
WriteAddressTranslation(regAlloc, asm, tempRegister.Operand, baseAddress); WriteAddressTranslation(context.MemoryManagerType, regAlloc, asm, tempRegister.Operand, baseAddress);
writeInst(rt, tempRegister.Operand, 0); writeInst(rt, tempRegister.Operand, 0);
@ -931,7 +932,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
// If Rt and Rn are the same register, ensure we perform the write back after the read/write. // If Rt and Rn are the same register, ensure we perform the write back after the read/write.
WriteAddShiftOffset(asm, tempRegister.Operand, baseAddress, offset, add, shiftType, shift); WriteAddShiftOffset(asm, tempRegister.Operand, baseAddress, offset, add, shiftType, shift);
WriteAddressTranslation(regAlloc, asm, tempRegister.Operand, tempRegister.Operand); WriteAddressTranslation(context.MemoryManagerType, regAlloc, asm, tempRegister.Operand, tempRegister.Operand);
writeInst(rt, tempRegister.Operand, 0); writeInst(rt, tempRegister.Operand, 0);
@ -940,7 +941,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
else else
{ {
WriteAddShiftOffset(asm, baseAddress, baseAddress, offset, add, shiftType, shift); WriteAddShiftOffset(asm, baseAddress, baseAddress, offset, add, shiftType, shift);
WriteAddressTranslation(regAlloc, asm, tempRegister.Operand, baseAddress); WriteAddressTranslation(context.MemoryManagerType, regAlloc, asm, tempRegister.Operand, baseAddress);
writeInst(rt, tempRegister.Operand, 0); writeInst(rt, tempRegister.Operand, 0);
} }
@ -974,7 +975,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
WriteAddressTranslation(context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, targetAddress); WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, targetAddress);
action(rtOperand, tempRegister.Operand, 0); action(rtOperand, tempRegister.Operand, 0);
} }
@ -1003,7 +1004,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
WriteAddressTranslation(context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, targetAddress); WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, targetAddress);
action(rtOperand, rt2Operand, tempRegister.Operand, 0); action(rtOperand, rt2Operand, tempRegister.Operand, 0);
} }
@ -1020,17 +1021,17 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
if (imm == 0) if (imm == 0)
{ {
WriteAddressTranslation(context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, rnOperand); WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, rnOperand);
} }
else if (CanFoldOffset(signedOffs, 3, true, out unscaled)) else if (CanFoldOffset(context.MemoryManagerType, signedOffs, 3, true, out unscaled))
{ {
WriteAddressTranslation(context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, rnOperand); WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, rnOperand);
offs = signedOffs; offs = signedOffs;
} }
else else
{ {
WriteAddShiftOffset(context.Arm64Assembler, tempRegister.Operand, rnOperand, InstEmitCommon.Const((int)imm), u, ArmShiftType.Lsl, 0); WriteAddShiftOffset(context.Arm64Assembler, tempRegister.Operand, rnOperand, InstEmitCommon.Const((int)imm), u, ArmShiftType.Lsl, 0);
WriteAddressTranslation(context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, tempRegister.Operand); WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, tempRegister.Operand);
} }
if (unscaled) if (unscaled)
@ -1051,7 +1052,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
WriteAddShiftOffset(context.Arm64Assembler, tempRegister.Operand, rnOperand, rmOperand, u, (ArmShiftType)sType, (int)shift); WriteAddShiftOffset(context.Arm64Assembler, tempRegister.Operand, rnOperand, rmOperand, u, (ArmShiftType)sType, (int)shift);
WriteAddressTranslation(context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, tempRegister.Operand); WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, tempRegister.Operand);
context.Arm64Assembler.PrfmI(tempRegister.Operand, 0, (uint)type, 0, 0); context.Arm64Assembler.PrfmI(tempRegister.Operand, 0, (uint)type, 0, 0);
} }
@ -1071,14 +1072,19 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped(); using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
WriteAddressTranslation(context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, targetAddress); WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, targetAddress);
context.Arm64Assembler.PrfmI(tempRegister.Operand, 0, (uint)type, 0, 0); context.Arm64Assembler.PrfmI(tempRegister.Operand, 0, (uint)type, 0, 0);
} }
public static bool CanFoldOffset(int offset, int scale, bool hasUnscaled, out bool unscaled) public static bool CanFoldOffset(MemoryManagerType mmType, int offset, int scale, bool hasUnscaled, out bool unscaled)
{ {
// TODO: Check if the memory manager mode also works with folded offsets. if (mmType != MemoryManagerType.HostMappedUnsafe)
{
unscaled = false;
return false;
}
int mask = (1 << scale) - 1; int mask = (1 << scale) - 1;
@ -1098,21 +1104,24 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
return unscaled; return unscaled;
} }
private static bool CanFoldDWordOffset(int offset) private static bool CanFoldDWordOffset(MemoryManagerType mmType, int offset)
{ {
// TODO: Check if the memory manager mode also works with folded offsets. if (mmType != MemoryManagerType.HostMappedUnsafe)
{
return false;
}
return offset >= 0 && offset < 0x40 && (offset & 3) == 0; return offset >= 0 && offset < 0x40 && (offset & 3) == 0;
} }
private static void WriteAddressTranslation(RegisterAllocator regAlloc, in Assembler asm, Operand destination, uint guestAddress) private static void WriteAddressTranslation(MemoryManagerType mmType, RegisterAllocator regAlloc, in Assembler asm, Operand destination, uint guestAddress)
{ {
asm.Mov(destination, guestAddress); asm.Mov(destination, guestAddress);
WriteAddressTranslation(regAlloc, asm, destination, destination); WriteAddressTranslation(mmType, regAlloc, asm, destination, destination);
} }
public static void WriteAddressTranslation(RegisterAllocator regAlloc, in Assembler asm, Operand destination, Operand guestAddress) public static void WriteAddressTranslation(MemoryManagerType mmType, RegisterAllocator regAlloc, in Assembler asm, Operand destination, Operand guestAddress)
{ {
Operand destination64 = new(destination.Kind, OperandType.I64, destination.Value); Operand destination64 = new(destination.Kind, OperandType.I64, destination.Value);
Operand basePointer = new(regAlloc.FixedPageTableRegister, RegisterType.Integer, OperandType.I64); Operand basePointer = new(regAlloc.FixedPageTableRegister, RegisterType.Integer, OperandType.I64);

View File

@ -258,17 +258,17 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
if (wBack) if (wBack)
{ {
InstEmitMemory.WriteAddShiftOffset(context.Arm64Assembler, baseAddress, baseAddress, offset, false, ArmShiftType.Lsl, 0); InstEmitMemory.WriteAddShiftOffset(context.Arm64Assembler, baseAddress, baseAddress, offset, false, ArmShiftType.Lsl, 0);
InstEmitMemory.WriteAddressTranslation(context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, baseAddress); InstEmitMemory.WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, baseAddress);
} }
else else
{ {
InstEmitMemory.WriteAddShiftOffset(context.Arm64Assembler, tempRegister.Operand, baseAddress, offset, false, ArmShiftType.Lsl, 0); InstEmitMemory.WriteAddShiftOffset(context.Arm64Assembler, tempRegister.Operand, baseAddress, offset, false, ArmShiftType.Lsl, 0);
InstEmitMemory.WriteAddressTranslation(context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, tempRegister.Operand); InstEmitMemory.WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, tempRegister.Operand);
} }
} }
else else
{ {
InstEmitMemory.WriteAddressTranslation(context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, baseAddress); InstEmitMemory.WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, tempRegister.Operand, baseAddress);
} }
EmitMemoryMultipleInstructionCore(context, tempRegister.Operand, rd, registerCount, singleRegs, isStore); EmitMemoryMultipleInstructionCore(context, tempRegister.Operand, rd, registerCount, singleRegs, isStore);
@ -402,7 +402,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
context.Arm64Assembler.Mov(address.Operand, (context.Pc & ~3u) + (uint)offs); context.Arm64Assembler.Mov(address.Operand, (context.Pc & ~3u) + (uint)offs);
InstEmitMemory.WriteAddressTranslation(context.RegisterAllocator, context.Arm64Assembler, address.Operand, address.Operand); InstEmitMemory.WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, address.Operand, address.Operand);
offs = 0; offs = 0;
} }
@ -410,9 +410,9 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
{ {
Operand rnOperand = context.RegisterAllocator.RemapGprRegister((int)rn); Operand rnOperand = context.RegisterAllocator.RemapGprRegister((int)rn);
if (InstEmitMemory.CanFoldOffset(add ? offs : -offs, (int)size, true, out _)) if (InstEmitMemory.CanFoldOffset(context.MemoryManagerType, add ? offs : -offs, (int)size, true, out _))
{ {
InstEmitMemory.WriteAddressTranslation(context.RegisterAllocator, context.Arm64Assembler, address.Operand, rnOperand); InstEmitMemory.WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, address.Operand, rnOperand);
if (!add) if (!add)
{ {
@ -422,7 +422,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
else else
{ {
InstEmitMemory.WriteAddShiftOffset(context.Arm64Assembler, address.Operand, rnOperand, InstEmitCommon.Const(offs), add, ArmShiftType.Lsl, 0); InstEmitMemory.WriteAddShiftOffset(context.Arm64Assembler, address.Operand, rnOperand, InstEmitCommon.Const(offs), add, ArmShiftType.Lsl, 0);
InstEmitMemory.WriteAddressTranslation(context.RegisterAllocator, context.Arm64Assembler, address.Operand, address.Operand); InstEmitMemory.WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, address.Operand, address.Operand);
offs = 0; offs = 0;
} }
@ -473,7 +473,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
using ScopedRegister address = context.RegisterAllocator.AllocateTempGprRegisterScoped(); using ScopedRegister address = context.RegisterAllocator.AllocateTempGprRegisterScoped();
InstEmitMemory.WriteAddressTranslation(context.RegisterAllocator, context.Arm64Assembler, address.Operand, rnOperand); InstEmitMemory.WriteAddressTranslation(context.MemoryManagerType, context.RegisterAllocator, context.Arm64Assembler, address.Operand, rnOperand);
callback(address.Operand); callback(address.Operand);

View File

@ -350,11 +350,11 @@ namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64
if (instInfo.AddressForm != AddressForm.None) if (instInfo.AddressForm != AddressForm.None)
{ {
InstEmitMemory.RewriteInstruction(writer, regAlloc, instInfo.Name, instInfo.Flags, instInfo.AddressForm, pc, encoding); InstEmitMemory.RewriteInstruction(memoryManager.Type, writer, regAlloc, instInfo.Name, instInfo.Flags, instInfo.AddressForm, pc, encoding);
} }
else if (instInfo.Name == InstName.Sys) else if (instInfo.Name == InstName.Sys)
{ {
InstEmitMemory.RewriteSysInstruction(writer, regAlloc, encoding); InstEmitMemory.RewriteSysInstruction(memoryManager.Type, writer, regAlloc, encoding);
} }
else if (instInfo.Name.IsSystem()) else if (instInfo.Name.IsSystem())
{ {

View File

@ -1,3 +1,4 @@
using ARMeilleure.Memory;
using Ryujinx.Cpu.LightningJit.CodeGen; using Ryujinx.Cpu.LightningJit.CodeGen;
using Ryujinx.Cpu.LightningJit.CodeGen.Arm64; using Ryujinx.Cpu.LightningJit.CodeGen.Arm64;
using System; using System;
@ -10,7 +11,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64
private const uint XMask = 0x3f808000u; private const uint XMask = 0x3f808000u;
private const uint XValue = 0x8000000u; private const uint XValue = 0x8000000u;
public static void RewriteSysInstruction(CodeWriter writer, RegisterAllocator regAlloc, uint encoding) public static void RewriteSysInstruction(MemoryManagerType mmType, CodeWriter writer, RegisterAllocator regAlloc, uint encoding)
{ {
int rtIndex = RegisterUtils.ExtractRt(encoding); int rtIndex = RegisterUtils.ExtractRt(encoding);
if (rtIndex == RegisterUtils.ZrIndex) if (rtIndex == RegisterUtils.ZrIndex)
@ -26,7 +27,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64
Assembler asm = new(writer); Assembler asm = new(writer);
WriteAddressTranslation(regAlloc, ref asm, rt, guestAddress); WriteAddressTranslation(mmType, regAlloc, ref asm, rt, guestAddress);
encoding = RegisterUtils.ReplaceRt(encoding, tempRegister); encoding = RegisterUtils.ReplaceRt(encoding, tempRegister);
@ -36,6 +37,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64
} }
public static void RewriteInstruction( public static void RewriteInstruction(
MemoryManagerType mmType,
CodeWriter writer, CodeWriter writer,
RegisterAllocator regAlloc, RegisterAllocator regAlloc,
InstName name, InstName name,
@ -47,19 +49,19 @@ namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64
switch (addressForm) switch (addressForm)
{ {
case AddressForm.OffsetReg: case AddressForm.OffsetReg:
RewriteOffsetRegMemoryInstruction(writer, regAlloc, flags, encoding); RewriteOffsetRegMemoryInstruction(mmType, writer, regAlloc, flags, encoding);
break; break;
case AddressForm.PostIndexed: case AddressForm.PostIndexed:
RewritePostIndexedMemoryInstruction(writer, regAlloc, flags, encoding); RewritePostIndexedMemoryInstruction(mmType, writer, regAlloc, flags, encoding);
break; break;
case AddressForm.PreIndexed: case AddressForm.PreIndexed:
RewritePreIndexedMemoryInstruction(writer, regAlloc, flags, encoding); RewritePreIndexedMemoryInstruction(mmType, writer, regAlloc, flags, encoding);
break; break;
case AddressForm.SignedScaled: case AddressForm.SignedScaled:
RewriteSignedScaledMemoryInstruction(writer, regAlloc, flags, encoding); RewriteSignedScaledMemoryInstruction(mmType, writer, regAlloc, flags, encoding);
break; break;
case AddressForm.UnsignedScaled: case AddressForm.UnsignedScaled:
RewriteUnsignedScaledMemoryInstruction(writer, regAlloc, flags, encoding); RewriteUnsignedScaledMemoryInstruction(mmType, writer, regAlloc, flags, encoding);
break; break;
case AddressForm.BaseRegister: case AddressForm.BaseRegister:
// Some applications uses unordered memory instructions in places where // Some applications uses unordered memory instructions in places where
@ -72,19 +74,19 @@ namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64
encoding |= 1u << 15; encoding |= 1u << 15;
} }
RewriteBaseRegisterMemoryInstruction(writer, regAlloc, encoding); RewriteBaseRegisterMemoryInstruction(mmType, writer, regAlloc, encoding);
break; break;
case AddressForm.StructNoOffset: case AddressForm.StructNoOffset:
RewriteBaseRegisterMemoryInstruction(writer, regAlloc, encoding); RewriteBaseRegisterMemoryInstruction(mmType, writer, regAlloc, encoding);
break; break;
case AddressForm.BasePlusOffset: case AddressForm.BasePlusOffset:
RewriteBasePlusOffsetMemoryInstruction(writer, regAlloc, encoding); RewriteBasePlusOffsetMemoryInstruction(mmType, writer, regAlloc, encoding);
break; break;
case AddressForm.Literal: case AddressForm.Literal:
RewriteLiteralMemoryInstruction(writer, regAlloc, name, pc, encoding); RewriteLiteralMemoryInstruction(mmType, writer, regAlloc, name, pc, encoding);
break; break;
case AddressForm.StructPostIndexedReg: case AddressForm.StructPostIndexedReg:
RewriteStructPostIndexedRegMemoryInstruction(writer, regAlloc, encoding); RewriteStructPostIndexedRegMemoryInstruction(mmType, writer, regAlloc, encoding);
break; break;
default: default:
writer.WriteInstruction(encoding); writer.WriteInstruction(encoding);
@ -92,7 +94,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64
} }
} }
private static void RewriteOffsetRegMemoryInstruction(CodeWriter writer, RegisterAllocator regAlloc, InstFlags flags, uint encoding) private static void RewriteOffsetRegMemoryInstruction(MemoryManagerType mmType, CodeWriter writer, RegisterAllocator regAlloc, InstFlags flags, uint encoding)
{ {
// TODO: Some unallocated encoding cases. // TODO: Some unallocated encoding cases.
@ -116,7 +118,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64
asm.Add(rn, guestAddress, guestOffset, extensionType, shift); asm.Add(rn, guestAddress, guestOffset, extensionType, shift);
WriteAddressTranslation(regAlloc, ref asm, rn, rn); WriteAddressTranslation(mmType, regAlloc, ref asm, rn, rn);
encoding = RegisterUtils.ReplaceRn(encoding, tempRegister); encoding = RegisterUtils.ReplaceRn(encoding, tempRegister);
encoding = (encoding & ~(0xfffu << 10)) | (1u << 24); // Register -> Unsigned offset encoding = (encoding & ~(0xfffu << 10)) | (1u << 24); // Register -> Unsigned offset
@ -126,7 +128,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64
regAlloc.FreeTempGprRegister(tempRegister); regAlloc.FreeTempGprRegister(tempRegister);
} }
private static void RewritePostIndexedMemoryInstruction(CodeWriter writer, RegisterAllocator regAlloc, InstFlags flags, uint encoding) private static void RewritePostIndexedMemoryInstruction(MemoryManagerType mmType, CodeWriter writer, RegisterAllocator regAlloc, InstFlags flags, uint encoding)
{ {
bool isPair = flags.HasFlag(InstFlags.Rt2); bool isPair = flags.HasFlag(InstFlags.Rt2);
int imm = isPair ? ExtractSImm7Scaled(flags, encoding) : ExtractSImm9(encoding); int imm = isPair ? ExtractSImm7Scaled(flags, encoding) : ExtractSImm9(encoding);
@ -137,7 +139,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64
Assembler asm = new(writer); Assembler asm = new(writer);
WriteAddressTranslation(regAlloc, ref asm, rn, guestAddress); WriteAddressTranslation(mmType, regAlloc, ref asm, rn, guestAddress);
encoding = RegisterUtils.ReplaceRn(encoding, tempRegister); encoding = RegisterUtils.ReplaceRn(encoding, tempRegister);
@ -160,7 +162,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64
regAlloc.FreeTempGprRegister(tempRegister); regAlloc.FreeTempGprRegister(tempRegister);
} }
private static void RewritePreIndexedMemoryInstruction(CodeWriter writer, RegisterAllocator regAlloc, InstFlags flags, uint encoding) private static void RewritePreIndexedMemoryInstruction(MemoryManagerType mmType, CodeWriter writer, RegisterAllocator regAlloc, InstFlags flags, uint encoding)
{ {
bool isPair = flags.HasFlag(InstFlags.Rt2); bool isPair = flags.HasFlag(InstFlags.Rt2);
int imm = isPair ? ExtractSImm7Scaled(flags, encoding) : ExtractSImm9(encoding); int imm = isPair ? ExtractSImm7Scaled(flags, encoding) : ExtractSImm9(encoding);
@ -172,7 +174,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64
Assembler asm = new(writer); Assembler asm = new(writer);
WriteAddConstant(ref asm, guestAddress, guestAddress, imm); WriteAddConstant(ref asm, guestAddress, guestAddress, imm);
WriteAddressTranslation(regAlloc, ref asm, rn, guestAddress); WriteAddressTranslation(mmType, regAlloc, ref asm, rn, guestAddress);
encoding = RegisterUtils.ReplaceRn(encoding, tempRegister); encoding = RegisterUtils.ReplaceRn(encoding, tempRegister);
@ -193,27 +195,27 @@ namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64
regAlloc.FreeTempGprRegister(tempRegister); regAlloc.FreeTempGprRegister(tempRegister);
} }
private static void RewriteSignedScaledMemoryInstruction(CodeWriter writer, RegisterAllocator regAlloc, InstFlags flags, uint encoding) private static void RewriteSignedScaledMemoryInstruction(MemoryManagerType mmType, CodeWriter writer, RegisterAllocator regAlloc, InstFlags flags, uint encoding)
{ {
RewriteMemoryInstruction(writer, regAlloc, encoding, ExtractSImm7Scaled(flags, encoding), 0x7fu << 15); RewriteMemoryInstruction(mmType, writer, regAlloc, encoding, ExtractSImm7Scaled(flags, encoding), 0x7fu << 15);
} }
private static void RewriteUnsignedScaledMemoryInstruction(CodeWriter writer, RegisterAllocator regAlloc, InstFlags flags, uint encoding) private static void RewriteUnsignedScaledMemoryInstruction(MemoryManagerType mmType, CodeWriter writer, RegisterAllocator regAlloc, InstFlags flags, uint encoding)
{ {
RewriteMemoryInstruction(writer, regAlloc, encoding, ExtractUImm12Scaled(flags, encoding), 0xfffu << 10); RewriteMemoryInstruction(mmType, writer, regAlloc, encoding, ExtractUImm12Scaled(flags, encoding), 0xfffu << 10);
} }
private static void RewriteBaseRegisterMemoryInstruction(CodeWriter writer, RegisterAllocator regAlloc, uint encoding) private static void RewriteBaseRegisterMemoryInstruction(MemoryManagerType mmType, CodeWriter writer, RegisterAllocator regAlloc, uint encoding)
{ {
RewriteMemoryInstruction(writer, regAlloc, encoding, 0, 0u); RewriteMemoryInstruction(mmType, writer, regAlloc, encoding, 0, 0u);
} }
private static void RewriteBasePlusOffsetMemoryInstruction(CodeWriter writer, RegisterAllocator regAlloc, uint encoding) private static void RewriteBasePlusOffsetMemoryInstruction(MemoryManagerType mmType, CodeWriter writer, RegisterAllocator regAlloc, uint encoding)
{ {
RewriteMemoryInstruction(writer, regAlloc, encoding, ExtractSImm9(encoding), 0x1ffu << 12); RewriteMemoryInstruction(mmType, writer, regAlloc, encoding, ExtractSImm9(encoding), 0x1ffu << 12);
} }
private static void RewriteMemoryInstruction(CodeWriter writer, RegisterAllocator regAlloc, uint encoding, int imm, uint immMask) private static void RewriteMemoryInstruction(MemoryManagerType mmType, CodeWriter writer, RegisterAllocator regAlloc, uint encoding, int imm, uint immMask)
{ {
int tempRegister = regAlloc.AllocateTempGprRegister(); int tempRegister = regAlloc.AllocateTempGprRegister();
Operand rn = new(tempRegister, RegisterType.Integer, OperandType.I64); Operand rn = new(tempRegister, RegisterType.Integer, OperandType.I64);
@ -221,13 +223,13 @@ namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64
Assembler asm = new(writer); Assembler asm = new(writer);
bool canFoldOffset = CanFoldOffset(imm); bool canFoldOffset = CanFoldOffset(mmType, imm);
if (canFoldOffset) if (canFoldOffset)
{ {
imm = 0; imm = 0;
} }
WriteAddressTranslation(regAlloc, ref asm, rn, guestAddress, imm); WriteAddressTranslation(mmType, regAlloc, ref asm, rn, guestAddress, imm);
encoding = RegisterUtils.ReplaceRn(encoding, tempRegister); encoding = RegisterUtils.ReplaceRn(encoding, tempRegister);
@ -241,7 +243,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64
regAlloc.FreeTempGprRegister(tempRegister); regAlloc.FreeTempGprRegister(tempRegister);
} }
private static void RewriteLiteralMemoryInstruction(CodeWriter writer, RegisterAllocator regAlloc, InstName name, ulong pc, uint encoding) private static void RewriteLiteralMemoryInstruction(MemoryManagerType mmType, CodeWriter writer, RegisterAllocator regAlloc, InstName name, ulong pc, uint encoding)
{ {
Assembler asm = new(writer); Assembler asm = new(writer);
@ -306,7 +308,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64
int tempRegister = regAlloc.AllocateTempGprRegister(); int tempRegister = regAlloc.AllocateTempGprRegister();
Operand rn = new(tempRegister, RegisterType.Integer, OperandType.I64); Operand rn = new(tempRegister, RegisterType.Integer, OperandType.I64);
WriteAddressTranslation(regAlloc, ref asm, rn, targetAddress); WriteAddressTranslation(mmType, regAlloc, ref asm, rn, targetAddress);
switch (name) switch (name)
{ {
@ -330,7 +332,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64
} }
} }
private static void RewriteStructPostIndexedRegMemoryInstruction(CodeWriter writer, RegisterAllocator regAlloc, uint encoding) private static void RewriteStructPostIndexedRegMemoryInstruction(MemoryManagerType mmType, CodeWriter writer, RegisterAllocator regAlloc, uint encoding)
{ {
// TODO: Some unallocated encoding cases. // TODO: Some unallocated encoding cases.
@ -342,7 +344,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64
Assembler asm = new(writer); Assembler asm = new(writer);
WriteAddressTranslation(regAlloc, ref asm, rn, guestAddress); WriteAddressTranslation(mmType, regAlloc, ref asm, rn, guestAddress);
encoding = RegisterUtils.ReplaceRn(encoding, tempRegister); encoding = RegisterUtils.ReplaceRn(encoding, tempRegister);
encoding &= ~((0x1fu << 16) | (1u << 23)); // Post-index -> No offset encoding &= ~((0x1fu << 16) | (1u << 23)); // Post-index -> No offset
@ -468,7 +470,13 @@ namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64
regAlloc.FreeTempGprRegister(tempRegister); regAlloc.FreeTempGprRegister(tempRegister);
} }
private static void WriteAddressTranslation(RegisterAllocator regAlloc, ref Assembler asm, Operand destination, Operand guestAddress, int offset) private static void WriteAddressTranslation(
MemoryManagerType mmType,
RegisterAllocator regAlloc,
ref Assembler asm,
Operand destination,
Operand guestAddress,
int offset)
{ {
if (offset != 0) if (offset != 0)
{ {
@ -490,17 +498,17 @@ namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64
guestAddress = destination; guestAddress = destination;
} }
WriteAddressTranslation(regAlloc, ref asm, destination, guestAddress); WriteAddressTranslation(mmType, regAlloc, ref asm, destination, guestAddress);
} }
private static void WriteAddressTranslation(RegisterAllocator regAlloc, ref Assembler asm, Operand destination, ulong guestAddress) private static void WriteAddressTranslation(MemoryManagerType mmType, RegisterAllocator regAlloc, ref Assembler asm, Operand destination, ulong guestAddress)
{ {
asm.Mov(destination, guestAddress); asm.Mov(destination, guestAddress);
WriteAddressTranslation(regAlloc, ref asm, destination, destination); WriteAddressTranslation(mmType, regAlloc, ref asm, destination, destination);
} }
private static void WriteAddressTranslation(RegisterAllocator regAlloc, ref Assembler asm, Operand destination, Operand guestAddress) private static void WriteAddressTranslation(MemoryManagerType mmType, RegisterAllocator regAlloc, ref Assembler asm, Operand destination, Operand guestAddress)
{ {
Operand basePointer = new(regAlloc.FixedPageTableRegister, RegisterType.Integer, OperandType.I64); Operand basePointer = new(regAlloc.FixedPageTableRegister, RegisterType.Integer, OperandType.I64);
@ -519,11 +527,9 @@ namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64
} }
} }
private static bool CanFoldOffset(int offset) private static bool CanFoldOffset(MemoryManagerType mmType, int offset)
{ {
// TODO: Check based on the memory manager mode. return mmType == MemoryManagerType.HostMappedUnsafe;
return true;
} }
private static int ExtractSImm7Scaled(InstFlags flags, uint encoding) private static int ExtractSImm7Scaled(InstFlags flags, uint encoding)