Compare commits
6 Commits
Author | SHA1 | Date | |
---|---|---|---|
5c3112aaeb | |||
88d3ffb97c | |||
222b1ad7da | |||
d317cfd639 | |||
76b9041adf | |||
b944941733 |
@ -654,6 +654,7 @@ namespace ARMeilleure.Decoders
|
|||||||
SetA32("<<<<000101101111xxxx11110001xxxx", InstName.Clz, InstEmit32.Clz, OpCode32AluReg.Create);
|
SetA32("<<<<000101101111xxxx11110001xxxx", InstName.Clz, InstEmit32.Clz, OpCode32AluReg.Create);
|
||||||
SetA32("<<<<00110111xxxx0000xxxxxxxxxxxx", InstName.Cmn, InstEmit32.Cmn, OpCode32AluImm.Create);
|
SetA32("<<<<00110111xxxx0000xxxxxxxxxxxx", InstName.Cmn, InstEmit32.Cmn, OpCode32AluImm.Create);
|
||||||
SetA32("<<<<00010111xxxx0000xxxxxxx0xxxx", InstName.Cmn, InstEmit32.Cmn, OpCode32AluRsImm.Create);
|
SetA32("<<<<00010111xxxx0000xxxxxxx0xxxx", InstName.Cmn, InstEmit32.Cmn, OpCode32AluRsImm.Create);
|
||||||
|
SetA32("<<<<00010111xxxx0000xxxx0xx1xxxx", InstName.Cmn, InstEmit32.Cmn, OpCode32AluRsReg.Create);
|
||||||
SetA32("<<<<00110101xxxx0000xxxxxxxxxxxx", InstName.Cmp, InstEmit32.Cmp, OpCode32AluImm.Create);
|
SetA32("<<<<00110101xxxx0000xxxxxxxxxxxx", InstName.Cmp, InstEmit32.Cmp, OpCode32AluImm.Create);
|
||||||
SetA32("<<<<00010101xxxx0000xxxxxxx0xxxx", InstName.Cmp, InstEmit32.Cmp, OpCode32AluRsImm.Create);
|
SetA32("<<<<00010101xxxx0000xxxxxxx0xxxx", InstName.Cmp, InstEmit32.Cmp, OpCode32AluRsImm.Create);
|
||||||
SetA32("<<<<00010101xxxx0000xxxx0xx1xxxx", InstName.Cmp, InstEmit32.Cmp, OpCode32AluRsReg.Create);
|
SetA32("<<<<00010101xxxx0000xxxx0xx1xxxx", InstName.Cmp, InstEmit32.Cmp, OpCode32AluRsReg.Create);
|
||||||
@ -732,6 +733,7 @@ namespace ARMeilleure.Decoders
|
|||||||
SetA32("<<<<0000110xxxxxxxxxxxxx0xx1xxxx", InstName.Sbc, InstEmit32.Sbc, OpCode32AluRsReg.Create);
|
SetA32("<<<<0000110xxxxxxxxxxxxx0xx1xxxx", InstName.Sbc, InstEmit32.Sbc, OpCode32AluRsReg.Create);
|
||||||
SetA32("<<<<0111101xxxxxxxxxxxxxx101xxxx", InstName.Sbfx, InstEmit32.Sbfx, OpCode32AluBf.Create);
|
SetA32("<<<<0111101xxxxxxxxxxxxxx101xxxx", InstName.Sbfx, InstEmit32.Sbfx, OpCode32AluBf.Create);
|
||||||
SetA32("<<<<01110001xxxx1111xxxx0001xxxx", InstName.Sdiv, InstEmit32.Sdiv, OpCode32AluMla.Create);
|
SetA32("<<<<01110001xxxx1111xxxx0001xxxx", InstName.Sdiv, InstEmit32.Sdiv, OpCode32AluMla.Create);
|
||||||
|
SetA32("<<<<01100011xxxxxxxx11111001xxxx", InstName.Shadd8, InstEmit32.Shadd8, OpCode32AluReg.Create);
|
||||||
SetA32("<<<<00010000xxxxxxxxxxxx1xx0xxxx", InstName.Smla__, InstEmit32.Smla__, OpCode32AluMla.Create);
|
SetA32("<<<<00010000xxxxxxxxxxxx1xx0xxxx", InstName.Smla__, InstEmit32.Smla__, OpCode32AluMla.Create);
|
||||||
SetA32("<<<<0000111xxxxxxxxxxxxx1001xxxx", InstName.Smlal, InstEmit32.Smlal, OpCode32AluUmull.Create);
|
SetA32("<<<<0000111xxxxxxxxxxxxx1001xxxx", InstName.Smlal, InstEmit32.Smlal, OpCode32AluUmull.Create);
|
||||||
SetA32("<<<<00010100xxxxxxxxxxxx1xx0xxxx", InstName.Smlal__, InstEmit32.Smlal__, OpCode32AluUmull.Create);
|
SetA32("<<<<00010100xxxxxxxxxxxx1xx0xxxx", InstName.Smlal__, InstEmit32.Smlal__, OpCode32AluUmull.Create);
|
||||||
|
@ -387,6 +387,11 @@ namespace ARMeilleure.Instructions
|
|||||||
EmitDiv(context, false);
|
EmitDiv(context, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void Shadd8(ArmEmitterContext context)
|
||||||
|
{
|
||||||
|
EmitHadd8(context, false);
|
||||||
|
}
|
||||||
|
|
||||||
public static void Ssat(ArmEmitterContext context)
|
public static void Ssat(ArmEmitterContext context)
|
||||||
{
|
{
|
||||||
OpCode32Sat op = (OpCode32Sat)context.CurrOp;
|
OpCode32Sat op = (OpCode32Sat)context.CurrOp;
|
||||||
@ -474,20 +479,7 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
public static void Uhadd8(ArmEmitterContext context)
|
public static void Uhadd8(ArmEmitterContext context)
|
||||||
{
|
{
|
||||||
OpCode32AluReg op = (OpCode32AluReg)context.CurrOp;
|
EmitHadd8(context, true);
|
||||||
|
|
||||||
Operand m = GetIntA32(context, op.Rm);
|
|
||||||
Operand n = GetIntA32(context, op.Rn);
|
|
||||||
|
|
||||||
Operand xor, res;
|
|
||||||
|
|
||||||
res = context.BitwiseAnd(m, n);
|
|
||||||
xor = context.BitwiseExclusiveOr(m, n);
|
|
||||||
xor = context.ShiftRightUI(xor, Const(1));
|
|
||||||
xor = context.BitwiseAnd(xor, Const(0x7F7F7F7Fu));
|
|
||||||
res = context.Add(res, xor);
|
|
||||||
|
|
||||||
SetIntA32(context, op.Rd, res);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Usat(ArmEmitterContext context)
|
public static void Usat(ArmEmitterContext context)
|
||||||
@ -659,6 +651,36 @@ namespace ARMeilleure.Instructions
|
|||||||
context.MarkLabel(lblEnd);
|
context.MarkLabel(lblEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void EmitHadd8(ArmEmitterContext context, bool unsigned)
|
||||||
|
{
|
||||||
|
OpCode32AluReg op = (OpCode32AluReg)context.CurrOp;
|
||||||
|
|
||||||
|
Operand m = GetIntA32(context, op.Rm);
|
||||||
|
Operand n = GetIntA32(context, op.Rn);
|
||||||
|
|
||||||
|
Operand xor, res, carry;
|
||||||
|
|
||||||
|
// This relies on the equality x+y == ((x&y) << 1) + (x^y).
|
||||||
|
// Note that x^y always contains the LSB of the result.
|
||||||
|
// Since we want to calculate (x+y)/2, we can instead calculate (x&y) + ((x^y)>>1).
|
||||||
|
// We mask by 0x7F to remove the LSB so that it doesn't leak into the field below.
|
||||||
|
|
||||||
|
res = context.BitwiseAnd(m, n);
|
||||||
|
carry = context.BitwiseExclusiveOr(m, n);
|
||||||
|
xor = context.ShiftRightUI(carry, Const(1));
|
||||||
|
xor = context.BitwiseAnd(xor, Const(0x7F7F7F7Fu));
|
||||||
|
res = context.Add(res, xor);
|
||||||
|
|
||||||
|
if (!unsigned)
|
||||||
|
{
|
||||||
|
// Propagates the sign bit from (x^y)>>1 upwards by one.
|
||||||
|
carry = context.BitwiseAnd(carry, Const(0x80808080u));
|
||||||
|
res = context.BitwiseExclusiveOr(res, carry);
|
||||||
|
}
|
||||||
|
|
||||||
|
SetIntA32(context, op.Rd, res);
|
||||||
|
}
|
||||||
|
|
||||||
private static void EmitSat(ArmEmitterContext context, int intMin, int intMax)
|
private static void EmitSat(ArmEmitterContext context, int intMin, int intMax)
|
||||||
{
|
{
|
||||||
OpCode32Sat op = (OpCode32Sat)context.CurrOp;
|
OpCode32Sat op = (OpCode32Sat)context.CurrOp;
|
||||||
@ -772,4 +794,4 @@ namespace ARMeilleure.Instructions
|
|||||||
EmitGenericAluStoreA32(context, op.Rd, op.SetFlags, value);
|
EmitGenericAluStoreA32(context, op.Rd, op.SetFlags, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -516,6 +516,7 @@ namespace ARMeilleure.Instructions
|
|||||||
Rsb,
|
Rsb,
|
||||||
Rsc,
|
Rsc,
|
||||||
Sbfx,
|
Sbfx,
|
||||||
|
Shadd8,
|
||||||
Smla__,
|
Smla__,
|
||||||
Smlal,
|
Smlal,
|
||||||
Smlal__,
|
Smlal__,
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<br>
|
<br>
|
||||||
<b>Ryujinx</b>
|
<b>Ryujinx</b>
|
||||||
<br>
|
<br>
|
||||||
<sub><sup><b>(REE-YOU-JI-NX)</b></sup></sub>
|
<sub><sup><b>(REE-YOU-JINX)</b></sup></sub>
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
</h1>
|
</h1>
|
||||||
|
@ -6,7 +6,7 @@ namespace Ryujinx.Common.GraphicsDriver
|
|||||||
{
|
{
|
||||||
public static void ToggleOGLThreading(bool enabled)
|
public static void ToggleOGLThreading(bool enabled)
|
||||||
{
|
{
|
||||||
Environment.SetEnvironmentVariable("mesa_glthread", enabled.ToString());
|
Environment.SetEnvironmentVariable("mesa_glthread", enabled.ToString().ToLower());
|
||||||
Environment.SetEnvironmentVariable("__GL_THREADED_OPTIMIZATIONS", enabled ? "1" : "0");
|
Environment.SetEnvironmentVariable("__GL_THREADED_OPTIMIZATIONS", enabled ? "1" : "0");
|
||||||
|
|
||||||
try
|
try
|
||||||
|
@ -369,14 +369,14 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
|||||||
|
|
||||||
if (color != null)
|
if (color != null)
|
||||||
{
|
{
|
||||||
if (clipRegionWidth > color.Width)
|
if (clipRegionWidth > color.Width / samplesInX)
|
||||||
{
|
{
|
||||||
clipRegionWidth = color.Width;
|
clipRegionWidth = color.Width / samplesInX;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clipRegionHeight > color.Height)
|
if (clipRegionHeight > color.Height / samplesInY)
|
||||||
{
|
{
|
||||||
clipRegionHeight = color.Height;
|
clipRegionHeight = color.Height / samplesInY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -400,14 +400,14 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
|||||||
|
|
||||||
if (depthStencil != null)
|
if (depthStencil != null)
|
||||||
{
|
{
|
||||||
if (clipRegionWidth > depthStencil.Width)
|
if (clipRegionWidth > depthStencil.Width / samplesInX)
|
||||||
{
|
{
|
||||||
clipRegionWidth = depthStencil.Width;
|
clipRegionWidth = depthStencil.Width / samplesInX;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clipRegionHeight > depthStencil.Height)
|
if (clipRegionHeight > depthStencil.Height / samplesInY)
|
||||||
{
|
{
|
||||||
clipRegionHeight = depthStencil.Height;
|
clipRegionHeight = depthStencil.Height / samplesInY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -434,6 +434,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
{
|
{
|
||||||
new Span<ITexture>(_rtHostColors).Fill(null);
|
new Span<ITexture>(_rtHostColors).Fill(null);
|
||||||
_rtHostColors[index] = _rtColors[index]?.HostTexture;
|
_rtHostColors[index] = _rtColors[index]?.HostTexture;
|
||||||
|
_rtHostDs = null;
|
||||||
|
|
||||||
_context.Renderer.Pipeline.SetRenderTargets(_rtHostColors, null);
|
_context.Renderer.Pipeline.SetRenderTargets(_rtHostColors, null);
|
||||||
}
|
}
|
||||||
|
@ -505,7 +505,9 @@ namespace Ryujinx.HLE.FileSystem
|
|||||||
|
|
||||||
bool canFixBySaveDataId = extraData.Attribute.StaticSaveDataId == 0 && info.StaticSaveDataId != 0;
|
bool canFixBySaveDataId = extraData.Attribute.StaticSaveDataId == 0 && info.StaticSaveDataId != 0;
|
||||||
|
|
||||||
if (!canFixByProgramId && !canFixBySaveDataId)
|
bool hasEmptyOwnerId = extraData.OwnerId == 0 && info.Type != LibHac.Fs.SaveDataType.System;
|
||||||
|
|
||||||
|
if (!canFixByProgramId && !canFixBySaveDataId && !hasEmptyOwnerId)
|
||||||
{
|
{
|
||||||
wasFixNeeded = false;
|
wasFixNeeded = false;
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
|
@ -776,6 +776,7 @@ namespace Ryujinx.HLE.HOS
|
|||||||
// The set sizes don't actually matter as long as they're non-zero because we use directory savedata.
|
// The set sizes don't actually matter as long as they're non-zero because we use directory savedata.
|
||||||
control.UserAccountSaveDataSize = 0x4000;
|
control.UserAccountSaveDataSize = 0x4000;
|
||||||
control.UserAccountSaveDataJournalSize = 0x4000;
|
control.UserAccountSaveDataJournalSize = 0x4000;
|
||||||
|
control.SaveDataOwnerId = applicationId;
|
||||||
|
|
||||||
Logger.Warning?.Print(LogClass.Application,
|
Logger.Warning?.Print(LogClass.Application,
|
||||||
"No control file was found for this game. Using a dummy one instead. This may cause inaccuracies in some games.");
|
"No control file was found for this game. Using a dummy one instead. This may cause inaccuracies in some games.");
|
||||||
|
@ -77,6 +77,25 @@ namespace Ryujinx.Tests.Cpu
|
|||||||
CompareAgainstUnicorn();
|
CompareAgainstUnicorn();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test, Pairwise]
|
||||||
|
public void Shadd8([Values(0u, 0xdu)] uint rd,
|
||||||
|
[Values(1u)] uint rm,
|
||||||
|
[Values(2u)] uint rn,
|
||||||
|
[Random(RndCnt)] uint w0,
|
||||||
|
[Random(RndCnt)] uint w1,
|
||||||
|
[Random(RndCnt)] uint w2)
|
||||||
|
{
|
||||||
|
uint opcode = 0xE6300F90u; // SHADD8 R0, R0, R0
|
||||||
|
|
||||||
|
opcode |= ((rm & 15) << 0) | ((rd & 15) << 12) | ((rn & 15) << 16);
|
||||||
|
|
||||||
|
uint sp = TestContext.CurrentContext.Random.NextUInt();
|
||||||
|
|
||||||
|
SingleOpcode(opcode, r0: w0, r1: w1, r2: w2, sp: sp);
|
||||||
|
|
||||||
|
CompareAgainstUnicorn();
|
||||||
|
}
|
||||||
|
|
||||||
[Test, Pairwise]
|
[Test, Pairwise]
|
||||||
public void Ssat_Usat([ValueSource("_Ssat_Usat_")] uint opcode,
|
public void Ssat_Usat([ValueSource("_Ssat_Usat_")] uint opcode,
|
||||||
[Values(0u, 0xdu)] uint rd,
|
[Values(0u, 0xdu)] uint rd,
|
||||||
@ -120,7 +139,7 @@ namespace Ryujinx.Tests.Cpu
|
|||||||
[Random(RndCnt)] uint w1,
|
[Random(RndCnt)] uint w1,
|
||||||
[Random(RndCnt)] uint w2)
|
[Random(RndCnt)] uint w2)
|
||||||
{
|
{
|
||||||
uint opcode = 0xE6700F90u; //UHADD8 R0, R0, R0
|
uint opcode = 0xE6700F90u; // UHADD8 R0, R0, R0
|
||||||
|
|
||||||
opcode |= ((rm & 15) << 0) | ((rd & 15) << 12) | ((rn & 15) << 16);
|
opcode |= ((rm & 15) << 0) | ((rd & 15) << 12) | ((rn & 15) << 16);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user