Compare commits
11 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
5af8ce7c38 | ||
|
77c4291c34 | ||
|
6e92b7a378 | ||
|
9b852c7481 | ||
|
c40c3905e2 | ||
|
a6cd044f0f | ||
|
f5a1de6ac5 | ||
|
2aeb5b00e3 | ||
|
60ba7b71f2 | ||
|
7c1d2bbb98 | ||
|
beacf8c1c8 |
@@ -1617,18 +1617,32 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
public static void Frinta_S(ArmEmitterContext context)
|
public static void Frinta_S(ArmEmitterContext context)
|
||||||
{
|
{
|
||||||
EmitScalarUnaryOpF(context, (op1) =>
|
if (Optimizations.UseSse41)
|
||||||
{
|
{
|
||||||
return EmitRoundMathCall(context, MidpointRounding.AwayFromZero, op1);
|
EmitSse41ScalarRoundOpF(context, FPRoundingMode.ToNearestAway);
|
||||||
});
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EmitScalarUnaryOpF(context, (op1) =>
|
||||||
|
{
|
||||||
|
return EmitRoundMathCall(context, MidpointRounding.AwayFromZero, op1);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Frinta_V(ArmEmitterContext context)
|
public static void Frinta_V(ArmEmitterContext context)
|
||||||
{
|
{
|
||||||
EmitVectorUnaryOpF(context, (op1) =>
|
if (Optimizations.UseSse41)
|
||||||
{
|
{
|
||||||
return EmitRoundMathCall(context, MidpointRounding.AwayFromZero, op1);
|
EmitSse41VectorRoundOpF(context, FPRoundingMode.ToNearestAway);
|
||||||
});
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EmitVectorUnaryOpF(context, (op1) =>
|
||||||
|
{
|
||||||
|
return EmitRoundMathCall(context, MidpointRounding.AwayFromZero, op1);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Frinti_S(ArmEmitterContext context)
|
public static void Frinti_S(ArmEmitterContext context)
|
||||||
@@ -3516,9 +3530,18 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
Operand n = GetVec(op.Rn);
|
Operand n = GetVec(op.Rn);
|
||||||
|
|
||||||
Intrinsic inst = (op.Size & 1) != 0 ? Intrinsic.X86Roundsd : Intrinsic.X86Roundss;
|
Operand res;
|
||||||
|
|
||||||
Operand res = context.AddIntrinsic(inst, n, Const(X86GetRoundControl(roundMode)));
|
if (roundMode != FPRoundingMode.ToNearestAway)
|
||||||
|
{
|
||||||
|
Intrinsic inst = (op.Size & 1) != 0 ? Intrinsic.X86Roundsd : Intrinsic.X86Roundss;
|
||||||
|
|
||||||
|
res = context.AddIntrinsic(inst, n, Const(X86GetRoundControl(roundMode)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
res = EmitSse41RoundToNearestWithTiesToAwayOpF(context, n, scalar: true);
|
||||||
|
}
|
||||||
|
|
||||||
if ((op.Size & 1) != 0)
|
if ((op.Size & 1) != 0)
|
||||||
{
|
{
|
||||||
@@ -3538,9 +3561,18 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
Operand n = GetVec(op.Rn);
|
Operand n = GetVec(op.Rn);
|
||||||
|
|
||||||
Intrinsic inst = (op.Size & 1) != 0 ? Intrinsic.X86Roundpd : Intrinsic.X86Roundps;
|
Operand res;
|
||||||
|
|
||||||
Operand res = context.AddIntrinsic(inst, n, Const(X86GetRoundControl(roundMode)));
|
if (roundMode != FPRoundingMode.ToNearestAway)
|
||||||
|
{
|
||||||
|
Intrinsic inst = (op.Size & 1) != 0 ? Intrinsic.X86Roundpd : Intrinsic.X86Roundps;
|
||||||
|
|
||||||
|
res = context.AddIntrinsic(inst, n, Const(X86GetRoundControl(roundMode)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
res = EmitSse41RoundToNearestWithTiesToAwayOpF(context, n, scalar: false);
|
||||||
|
}
|
||||||
|
|
||||||
if (op.RegisterSize == RegisterSize.Simd64)
|
if (op.RegisterSize == RegisterSize.Simd64)
|
||||||
{
|
{
|
||||||
|
@@ -164,32 +164,74 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
public static void Fcvtas_Gp(ArmEmitterContext context)
|
public static void Fcvtas_Gp(ArmEmitterContext context)
|
||||||
{
|
{
|
||||||
EmitFcvt_s_Gp(context, (op1) => EmitRoundMathCall(context, MidpointRounding.AwayFromZero, op1));
|
if (Optimizations.UseSse41)
|
||||||
|
{
|
||||||
|
EmitSse41Fcvts_Gp(context, FPRoundingMode.ToNearestAway, isFixed: false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EmitFcvt_s_Gp(context, (op1) => EmitRoundMathCall(context, MidpointRounding.AwayFromZero, op1));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Fcvtas_S(ArmEmitterContext context)
|
public static void Fcvtas_S(ArmEmitterContext context)
|
||||||
{
|
{
|
||||||
EmitFcvt(context, (op1) => EmitRoundMathCall(context, MidpointRounding.AwayFromZero, op1), signed: true, scalar: true);
|
if (Optimizations.UseSse41)
|
||||||
|
{
|
||||||
|
EmitSse41FcvtsOpF(context, FPRoundingMode.ToNearestAway, scalar: true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EmitFcvt(context, (op1) => EmitRoundMathCall(context, MidpointRounding.AwayFromZero, op1), signed: true, scalar: true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Fcvtas_V(ArmEmitterContext context)
|
public static void Fcvtas_V(ArmEmitterContext context)
|
||||||
{
|
{
|
||||||
EmitFcvt(context, (op1) => EmitRoundMathCall(context, MidpointRounding.AwayFromZero, op1), signed: true, scalar: false);
|
if (Optimizations.UseSse41)
|
||||||
|
{
|
||||||
|
EmitSse41FcvtsOpF(context, FPRoundingMode.ToNearestAway, scalar: false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EmitFcvt(context, (op1) => EmitRoundMathCall(context, MidpointRounding.AwayFromZero, op1), signed: true, scalar: false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Fcvtau_Gp(ArmEmitterContext context)
|
public static void Fcvtau_Gp(ArmEmitterContext context)
|
||||||
{
|
{
|
||||||
EmitFcvt_u_Gp(context, (op1) => EmitRoundMathCall(context, MidpointRounding.AwayFromZero, op1));
|
if (Optimizations.UseSse41)
|
||||||
|
{
|
||||||
|
EmitSse41Fcvtu_Gp(context, FPRoundingMode.ToNearestAway, isFixed: false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EmitFcvt_u_Gp(context, (op1) => EmitRoundMathCall(context, MidpointRounding.AwayFromZero, op1));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Fcvtau_S(ArmEmitterContext context)
|
public static void Fcvtau_S(ArmEmitterContext context)
|
||||||
{
|
{
|
||||||
EmitFcvt(context, (op1) => EmitRoundMathCall(context, MidpointRounding.AwayFromZero, op1), signed: false, scalar: true);
|
if (Optimizations.UseSse41)
|
||||||
|
{
|
||||||
|
EmitSse41FcvtuOpF(context, FPRoundingMode.ToNearestAway, scalar: true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EmitFcvt(context, (op1) => EmitRoundMathCall(context, MidpointRounding.AwayFromZero, op1), signed: false, scalar: true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Fcvtau_V(ArmEmitterContext context)
|
public static void Fcvtau_V(ArmEmitterContext context)
|
||||||
{
|
{
|
||||||
EmitFcvt(context, (op1) => EmitRoundMathCall(context, MidpointRounding.AwayFromZero, op1), signed: false, scalar: false);
|
if (Optimizations.UseSse41)
|
||||||
|
{
|
||||||
|
EmitSse41FcvtuOpF(context, FPRoundingMode.ToNearestAway, scalar: false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EmitFcvt(context, (op1) => EmitRoundMathCall(context, MidpointRounding.AwayFromZero, op1), signed: false, scalar: false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Fcvtl_V(ArmEmitterContext context)
|
public static void Fcvtl_V(ArmEmitterContext context)
|
||||||
@@ -1223,7 +1265,14 @@ namespace ARMeilleure.Instructions
|
|||||||
nRes = context.AddIntrinsic(Intrinsic.X86Mulps, nRes, fpScaledMask);
|
nRes = context.AddIntrinsic(Intrinsic.X86Mulps, nRes, fpScaledMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
nRes = context.AddIntrinsic(Intrinsic.X86Roundps, nRes, Const(X86GetRoundControl(roundMode)));
|
if (roundMode != FPRoundingMode.ToNearestAway)
|
||||||
|
{
|
||||||
|
nRes = context.AddIntrinsic(Intrinsic.X86Roundps, nRes, Const(X86GetRoundControl(roundMode)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nRes = EmitSse41RoundToNearestWithTiesToAwayOpF(context, nRes, scalar);
|
||||||
|
}
|
||||||
|
|
||||||
Operand nInt = context.AddIntrinsic(Intrinsic.X86Cvtps2dq, nRes);
|
Operand nInt = context.AddIntrinsic(Intrinsic.X86Cvtps2dq, nRes);
|
||||||
|
|
||||||
@@ -1265,7 +1314,14 @@ namespace ARMeilleure.Instructions
|
|||||||
nRes = context.AddIntrinsic(Intrinsic.X86Mulpd, nRes, fpScaledMask);
|
nRes = context.AddIntrinsic(Intrinsic.X86Mulpd, nRes, fpScaledMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
nRes = context.AddIntrinsic(Intrinsic.X86Roundpd, nRes, Const(X86GetRoundControl(roundMode)));
|
if (roundMode != FPRoundingMode.ToNearestAway)
|
||||||
|
{
|
||||||
|
nRes = context.AddIntrinsic(Intrinsic.X86Roundpd, nRes, Const(X86GetRoundControl(roundMode)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nRes = EmitSse41RoundToNearestWithTiesToAwayOpF(context, nRes, scalar);
|
||||||
|
}
|
||||||
|
|
||||||
Operand nLong = EmitSse2CvtDoubleToInt64OpF(context, nRes, scalar);
|
Operand nLong = EmitSse2CvtDoubleToInt64OpF(context, nRes, scalar);
|
||||||
|
|
||||||
@@ -1314,7 +1370,14 @@ namespace ARMeilleure.Instructions
|
|||||||
nRes = context.AddIntrinsic(Intrinsic.X86Mulps, nRes, fpScaledMask);
|
nRes = context.AddIntrinsic(Intrinsic.X86Mulps, nRes, fpScaledMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
nRes = context.AddIntrinsic(Intrinsic.X86Roundps, nRes, Const(X86GetRoundControl(roundMode)));
|
if (roundMode != FPRoundingMode.ToNearestAway)
|
||||||
|
{
|
||||||
|
nRes = context.AddIntrinsic(Intrinsic.X86Roundps, nRes, Const(X86GetRoundControl(roundMode)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nRes = EmitSse41RoundToNearestWithTiesToAwayOpF(context, nRes, scalar);
|
||||||
|
}
|
||||||
|
|
||||||
Operand zero = context.VectorZero();
|
Operand zero = context.VectorZero();
|
||||||
|
|
||||||
@@ -1369,7 +1432,14 @@ namespace ARMeilleure.Instructions
|
|||||||
nRes = context.AddIntrinsic(Intrinsic.X86Mulpd, nRes, fpScaledMask);
|
nRes = context.AddIntrinsic(Intrinsic.X86Mulpd, nRes, fpScaledMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
nRes = context.AddIntrinsic(Intrinsic.X86Roundpd, nRes, Const(X86GetRoundControl(roundMode)));
|
if (roundMode != FPRoundingMode.ToNearestAway)
|
||||||
|
{
|
||||||
|
nRes = context.AddIntrinsic(Intrinsic.X86Roundpd, nRes, Const(X86GetRoundControl(roundMode)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nRes = EmitSse41RoundToNearestWithTiesToAwayOpF(context, nRes, scalar);
|
||||||
|
}
|
||||||
|
|
||||||
Operand zero = context.VectorZero();
|
Operand zero = context.VectorZero();
|
||||||
|
|
||||||
@@ -1424,7 +1494,14 @@ namespace ARMeilleure.Instructions
|
|||||||
nRes = context.AddIntrinsic(Intrinsic.X86Mulss, nRes, fpScaledMask);
|
nRes = context.AddIntrinsic(Intrinsic.X86Mulss, nRes, fpScaledMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
nRes = context.AddIntrinsic(Intrinsic.X86Roundss, nRes, Const(X86GetRoundControl(roundMode)));
|
if (roundMode != FPRoundingMode.ToNearestAway)
|
||||||
|
{
|
||||||
|
nRes = context.AddIntrinsic(Intrinsic.X86Roundss, nRes, Const(X86GetRoundControl(roundMode)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nRes = EmitSse41RoundToNearestWithTiesToAwayOpF(context, nRes, scalar: true);
|
||||||
|
}
|
||||||
|
|
||||||
Operand nIntOrLong = op.RegisterSize == RegisterSize.Int32
|
Operand nIntOrLong = op.RegisterSize == RegisterSize.Int32
|
||||||
? context.AddIntrinsicInt (Intrinsic.X86Cvtss2si, nRes)
|
? context.AddIntrinsicInt (Intrinsic.X86Cvtss2si, nRes)
|
||||||
@@ -1464,7 +1541,14 @@ namespace ARMeilleure.Instructions
|
|||||||
nRes = context.AddIntrinsic(Intrinsic.X86Mulsd, nRes, fpScaledMask);
|
nRes = context.AddIntrinsic(Intrinsic.X86Mulsd, nRes, fpScaledMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
nRes = context.AddIntrinsic(Intrinsic.X86Roundsd, nRes, Const(X86GetRoundControl(roundMode)));
|
if (roundMode != FPRoundingMode.ToNearestAway)
|
||||||
|
{
|
||||||
|
nRes = context.AddIntrinsic(Intrinsic.X86Roundsd, nRes, Const(X86GetRoundControl(roundMode)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nRes = EmitSse41RoundToNearestWithTiesToAwayOpF(context, nRes, scalar: true);
|
||||||
|
}
|
||||||
|
|
||||||
Operand nIntOrLong = op.RegisterSize == RegisterSize.Int32
|
Operand nIntOrLong = op.RegisterSize == RegisterSize.Int32
|
||||||
? context.AddIntrinsicInt (Intrinsic.X86Cvtsd2si, nRes)
|
? context.AddIntrinsicInt (Intrinsic.X86Cvtsd2si, nRes)
|
||||||
@@ -1512,7 +1596,14 @@ namespace ARMeilleure.Instructions
|
|||||||
nRes = context.AddIntrinsic(Intrinsic.X86Mulss, nRes, fpScaledMask);
|
nRes = context.AddIntrinsic(Intrinsic.X86Mulss, nRes, fpScaledMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
nRes = context.AddIntrinsic(Intrinsic.X86Roundss, nRes, Const(X86GetRoundControl(roundMode)));
|
if (roundMode != FPRoundingMode.ToNearestAway)
|
||||||
|
{
|
||||||
|
nRes = context.AddIntrinsic(Intrinsic.X86Roundss, nRes, Const(X86GetRoundControl(roundMode)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nRes = EmitSse41RoundToNearestWithTiesToAwayOpF(context, nRes, scalar: true);
|
||||||
|
}
|
||||||
|
|
||||||
Operand zero = context.VectorZero();
|
Operand zero = context.VectorZero();
|
||||||
|
|
||||||
@@ -1567,7 +1658,14 @@ namespace ARMeilleure.Instructions
|
|||||||
nRes = context.AddIntrinsic(Intrinsic.X86Mulsd, nRes, fpScaledMask);
|
nRes = context.AddIntrinsic(Intrinsic.X86Mulsd, nRes, fpScaledMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
nRes = context.AddIntrinsic(Intrinsic.X86Roundsd, nRes, Const(X86GetRoundControl(roundMode)));
|
if (roundMode != FPRoundingMode.ToNearestAway)
|
||||||
|
{
|
||||||
|
nRes = context.AddIntrinsic(Intrinsic.X86Roundsd, nRes, Const(X86GetRoundControl(roundMode)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nRes = EmitSse41RoundToNearestWithTiesToAwayOpF(context, nRes, scalar: true);
|
||||||
|
}
|
||||||
|
|
||||||
Operand zero = context.VectorZero();
|
Operand zero = context.VectorZero();
|
||||||
|
|
||||||
|
@@ -203,6 +203,9 @@ namespace ARMeilleure.Instructions
|
|||||||
FPRoundingMode roundMode;
|
FPRoundingMode roundMode;
|
||||||
switch (rm)
|
switch (rm)
|
||||||
{
|
{
|
||||||
|
case 0b00:
|
||||||
|
roundMode = FPRoundingMode.ToNearestAway;
|
||||||
|
break;
|
||||||
case 0b01:
|
case 0b01:
|
||||||
roundMode = FPRoundingMode.ToNearest;
|
roundMode = FPRoundingMode.ToNearest;
|
||||||
break;
|
break;
|
||||||
@@ -228,7 +231,7 @@ namespace ARMeilleure.Instructions
|
|||||||
bool unsigned = op.Opc == 0;
|
bool unsigned = op.Opc == 0;
|
||||||
int rm = op.Opc2 & 3;
|
int rm = op.Opc2 & 3;
|
||||||
|
|
||||||
if (Optimizations.UseSse41 && rm != 0b00)
|
if (Optimizations.UseSse41)
|
||||||
{
|
{
|
||||||
EmitSse41ConvertInt32(context, RMToRoundMode(rm), !unsigned);
|
EmitSse41ConvertInt32(context, RMToRoundMode(rm), !unsigned);
|
||||||
}
|
}
|
||||||
@@ -267,15 +270,21 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
int rm = op.Opc2 & 3;
|
int rm = op.Opc2 & 3;
|
||||||
|
|
||||||
if (Optimizations.UseSse2 && rm != 0b00)
|
if (Optimizations.UseSse41)
|
||||||
{
|
{
|
||||||
EmitScalarUnaryOpSimd32(context, (m) =>
|
EmitScalarUnaryOpSimd32(context, (m) =>
|
||||||
{
|
{
|
||||||
Intrinsic inst = (op.Size & 1) == 0 ? Intrinsic.X86Roundss : Intrinsic.X86Roundsd;
|
|
||||||
|
|
||||||
FPRoundingMode roundMode = RMToRoundMode(rm);
|
FPRoundingMode roundMode = RMToRoundMode(rm);
|
||||||
|
|
||||||
return context.AddIntrinsic(inst, m, Const(X86GetRoundControl(roundMode)));
|
if (roundMode != FPRoundingMode.ToNearestAway)
|
||||||
|
{
|
||||||
|
Intrinsic inst = (op.Size & 1) == 0 ? Intrinsic.X86Roundss : Intrinsic.X86Roundsd;
|
||||||
|
return context.AddIntrinsic(inst, m, Const(X86GetRoundControl(roundMode)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return EmitSse41RoundToNearestWithTiesToAwayOpF(context, m, scalar: true);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -305,7 +314,17 @@ namespace ARMeilleure.Instructions
|
|||||||
// VRINTA (vector).
|
// VRINTA (vector).
|
||||||
public static void Vrinta_V(ArmEmitterContext context)
|
public static void Vrinta_V(ArmEmitterContext context)
|
||||||
{
|
{
|
||||||
EmitVectorUnaryOpF32(context, (m) => EmitRoundMathCall(context, MidpointRounding.AwayFromZero, m));
|
if (Optimizations.UseSse41)
|
||||||
|
{
|
||||||
|
EmitVectorUnaryOpSimd32(context, (m) =>
|
||||||
|
{
|
||||||
|
return EmitSse41RoundToNearestWithTiesToAwayOpF(context, m, scalar: false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EmitVectorUnaryOpF32(context, (m) => EmitRoundMathCall(context, MidpointRounding.AwayFromZero, m));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// VRINTM (vector).
|
// VRINTM (vector).
|
||||||
@@ -413,7 +432,14 @@ namespace ARMeilleure.Instructions
|
|||||||
Operand nRes = context.AddIntrinsic(Intrinsic.X86Cmpss, n, n, Const((int)CmpCondition.OrderedQ));
|
Operand nRes = context.AddIntrinsic(Intrinsic.X86Cmpss, n, n, Const((int)CmpCondition.OrderedQ));
|
||||||
nRes = context.AddIntrinsic(Intrinsic.X86Pand, nRes, n);
|
nRes = context.AddIntrinsic(Intrinsic.X86Pand, nRes, n);
|
||||||
|
|
||||||
nRes = context.AddIntrinsic(Intrinsic.X86Roundss, nRes, Const(X86GetRoundControl(roundMode)));
|
if (roundMode != FPRoundingMode.ToNearestAway)
|
||||||
|
{
|
||||||
|
nRes = context.AddIntrinsic(Intrinsic.X86Roundss, nRes, Const(X86GetRoundControl(roundMode)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nRes = EmitSse41RoundToNearestWithTiesToAwayOpF(context, nRes, scalar: true);
|
||||||
|
}
|
||||||
|
|
||||||
Operand zero = context.VectorZero();
|
Operand zero = context.VectorZero();
|
||||||
|
|
||||||
@@ -464,7 +490,14 @@ namespace ARMeilleure.Instructions
|
|||||||
Operand nRes = context.AddIntrinsic(Intrinsic.X86Cmpsd, n, n, Const((int)CmpCondition.OrderedQ));
|
Operand nRes = context.AddIntrinsic(Intrinsic.X86Cmpsd, n, n, Const((int)CmpCondition.OrderedQ));
|
||||||
nRes = context.AddIntrinsic(Intrinsic.X86Pand, nRes, n);
|
nRes = context.AddIntrinsic(Intrinsic.X86Pand, nRes, n);
|
||||||
|
|
||||||
nRes = context.AddIntrinsic(Intrinsic.X86Roundsd, nRes, Const(X86GetRoundControl(roundMode)));
|
if (roundMode != FPRoundingMode.ToNearestAway)
|
||||||
|
{
|
||||||
|
nRes = context.AddIntrinsic(Intrinsic.X86Roundsd, nRes, Const(X86GetRoundControl(roundMode)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nRes = EmitSse41RoundToNearestWithTiesToAwayOpF(context, nRes, scalar: true);
|
||||||
|
}
|
||||||
|
|
||||||
Operand zero = context.VectorZero();
|
Operand zero = context.VectorZero();
|
||||||
|
|
||||||
|
@@ -33,6 +33,14 @@ namespace ARMeilleure.Instructions
|
|||||||
};
|
};
|
||||||
|
|
||||||
public static readonly long ZeroMask = 128L << 56 | 128L << 48 | 128L << 40 | 128L << 32 | 128L << 24 | 128L << 16 | 128L << 8 | 128L << 0;
|
public static readonly long ZeroMask = 128L << 56 | 128L << 48 | 128L << 40 | 128L << 32 | 128L << 24 | 128L << 16 | 128L << 8 | 128L << 0;
|
||||||
|
|
||||||
|
public static ulong X86GetGf2p8LogicalShiftLeft(int shift)
|
||||||
|
{
|
||||||
|
ulong identity = (0b00000001UL << 56) | (0b00000010UL << 48) | (0b00000100UL << 40) | (0b00001000UL << 32) |
|
||||||
|
(0b00010000UL << 24) | (0b00100000UL << 16) | (0b01000000UL << 8) | (0b10000000UL << 0);
|
||||||
|
|
||||||
|
return shift >= 0 ? identity >> (shift * 8) : identity << (-shift * 8);
|
||||||
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region "X86 SSE Intrinsics"
|
#region "X86 SSE Intrinsics"
|
||||||
@@ -243,19 +251,44 @@ namespace ARMeilleure.Instructions
|
|||||||
throw new ArgumentException($"Invalid rounding mode \"{roundMode}\".");
|
throw new ArgumentException($"Invalid rounding mode \"{roundMode}\".");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ulong X86GetGf2p8LogicalShiftLeft(int shift)
|
public static Operand EmitSse41RoundToNearestWithTiesToAwayOpF(ArmEmitterContext context, Operand n, bool scalar)
|
||||||
{
|
{
|
||||||
ulong identity =
|
Debug.Assert(n.Type == OperandType.V128);
|
||||||
(0b00000001UL << 56) |
|
|
||||||
(0b00000010UL << 48) |
|
|
||||||
(0b00000100UL << 40) |
|
|
||||||
(0b00001000UL << 32) |
|
|
||||||
(0b00010000UL << 24) |
|
|
||||||
(0b00100000UL << 16) |
|
|
||||||
(0b01000000UL << 8) |
|
|
||||||
(0b10000000UL << 0);
|
|
||||||
|
|
||||||
return shift >= 0 ? identity >> (shift * 8) : identity << (-shift * 8);
|
Operand nCopy = context.Copy(n);
|
||||||
|
|
||||||
|
Operand rC = Const(X86GetRoundControl(FPRoundingMode.TowardsZero));
|
||||||
|
|
||||||
|
IOpCodeSimd op = (IOpCodeSimd)context.CurrOp;
|
||||||
|
|
||||||
|
if ((op.Size & 1) == 0)
|
||||||
|
{
|
||||||
|
Operand signMask = scalar ? X86GetScalar(context, int.MinValue) : X86GetAllElements(context, int.MinValue);
|
||||||
|
signMask = context.AddIntrinsic(Intrinsic.X86Pand, signMask, nCopy);
|
||||||
|
|
||||||
|
// 0x3EFFFFFF == BitConverter.SingleToInt32Bits(0.5f) - 1
|
||||||
|
Operand valueMask = scalar ? X86GetScalar(context, 0x3EFFFFFF) : X86GetAllElements(context, 0x3EFFFFFF);
|
||||||
|
valueMask = context.AddIntrinsic(Intrinsic.X86Por, valueMask, signMask);
|
||||||
|
|
||||||
|
nCopy = context.AddIntrinsic(scalar ? Intrinsic.X86Addss : Intrinsic.X86Addps, nCopy, valueMask);
|
||||||
|
|
||||||
|
nCopy = context.AddIntrinsic(scalar ? Intrinsic.X86Roundss : Intrinsic.X86Roundps, nCopy, rC);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Operand signMask = scalar ? X86GetScalar(context, long.MinValue) : X86GetAllElements(context, long.MinValue);
|
||||||
|
signMask = context.AddIntrinsic(Intrinsic.X86Pand, signMask, nCopy);
|
||||||
|
|
||||||
|
// 0x3FDFFFFFFFFFFFFFL == BitConverter.DoubleToInt64Bits(0.5d) - 1L
|
||||||
|
Operand valueMask = scalar ? X86GetScalar(context, 0x3FDFFFFFFFFFFFFFL) : X86GetAllElements(context, 0x3FDFFFFFFFFFFFFFL);
|
||||||
|
valueMask = context.AddIntrinsic(Intrinsic.X86Por, valueMask, signMask);
|
||||||
|
|
||||||
|
nCopy = context.AddIntrinsic(scalar ? Intrinsic.X86Addsd : Intrinsic.X86Addpd, nCopy, valueMask);
|
||||||
|
|
||||||
|
nCopy = context.AddIntrinsic(scalar ? Intrinsic.X86Roundsd : Intrinsic.X86Roundpd, nCopy, rC);
|
||||||
|
}
|
||||||
|
|
||||||
|
return nCopy;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Operand EmitCountSetBits8(ArmEmitterContext context, Operand op) // "size" is 8 (SIMD&FP Inst.).
|
public static Operand EmitCountSetBits8(ArmEmitterContext context, Operand op) // "size" is 8 (SIMD&FP Inst.).
|
||||||
|
@@ -2,9 +2,10 @@ namespace ARMeilleure.State
|
|||||||
{
|
{
|
||||||
public enum FPRoundingMode
|
public enum FPRoundingMode
|
||||||
{
|
{
|
||||||
ToNearest = 0,
|
ToNearest = 0, // With ties to even.
|
||||||
TowardsPlusInfinity = 1,
|
TowardsPlusInfinity = 1,
|
||||||
TowardsMinusInfinity = 2,
|
TowardsMinusInfinity = 2,
|
||||||
TowardsZero = 3
|
TowardsZero = 3,
|
||||||
|
ToNearestAway = 4 // With ties to away.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -27,7 +27,7 @@ namespace ARMeilleure.Translation.PTC
|
|||||||
private const string OuterHeaderMagicString = "PTCohd\0\0";
|
private const string OuterHeaderMagicString = "PTCohd\0\0";
|
||||||
private const string InnerHeaderMagicString = "PTCihd\0\0";
|
private const string InnerHeaderMagicString = "PTCihd\0\0";
|
||||||
|
|
||||||
private const uint InternalVersion = 3710; //! To be incremented manually for each change to the ARMeilleure project.
|
private const uint InternalVersion = 3713; //! To be incremented manually for each change to the ARMeilleure project.
|
||||||
|
|
||||||
private const string ActualDir = "0";
|
private const string ActualDir = "0";
|
||||||
private const string BackupDir = "1";
|
private const string BackupDir = "1";
|
||||||
|
@@ -36,7 +36,7 @@
|
|||||||
|
|
||||||
## Compatibility
|
## Compatibility
|
||||||
|
|
||||||
As of September 2022, Ryujinx has been tested on approximately 3,600 titles; over 3,400 boot past menus and into gameplay, with roughly 2,700 of those being considered playable. You can check out the compatibility list [here](https://github.com/Ryujinx/Ryujinx-Games-List/issues).
|
As of October 2022, Ryujinx has been tested on approximately 3,600 titles; over 3,500 boot past menus and into gameplay, with roughly 3,000 of those being considered playable. You can check out the compatibility list [here](https://github.com/Ryujinx/Ryujinx-Games-List/issues).
|
||||||
Anyone is free to submit a new game test or update an existing game test entry; simply follow the new issue template and testing guidelines, or post as a reply to the applicable game issue. Use the search function to see if a game has been tested already!
|
Anyone is free to submit a new game test or update an existing game test entry; simply follow the new issue template and testing guidelines, or post as a reply to the applicable game issue. Use the search function to see if a game has been tested already!
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
@@ -588,5 +588,9 @@
|
|||||||
"SettingsTabGraphicsPreferredGpuTooltip": "Wybierz kartę graficzną, która będzie używana z backendem graficznym Vulkan.\n\nNie wpływa na GPU używane przez OpenGL.\n\nW razie wątpliwości ustaw flagę GPU jako \"dGPU\". Jeśli żadnej nie ma, pozostaw nietknięte.",
|
"SettingsTabGraphicsPreferredGpuTooltip": "Wybierz kartę graficzną, która będzie używana z backendem graficznym Vulkan.\n\nNie wpływa na GPU używane przez OpenGL.\n\nW razie wątpliwości ustaw flagę GPU jako \"dGPU\". Jeśli żadnej nie ma, pozostaw nietknięte.",
|
||||||
"SettingsAppRequiredRestartMessage": "Wymagane Zrestartowanie Ryujinx",
|
"SettingsAppRequiredRestartMessage": "Wymagane Zrestartowanie Ryujinx",
|
||||||
"SettingsGpuBackendRestartMessage": "Zmieniono ustawienia Backendu Graficznego lub GPU. Będzie to wymagało ponownego uruchomienia",
|
"SettingsGpuBackendRestartMessage": "Zmieniono ustawienia Backendu Graficznego lub GPU. Będzie to wymagało ponownego uruchomienia",
|
||||||
"SettingsGpuBackendRestartSubMessage": "Czy chcesz zrestartować teraz?"
|
"SettingsGpuBackendRestartSubMessage": "Czy chcesz zrestartować teraz?",
|
||||||
|
"RyujinxUpdaterMessage": "Czy chcesz zaktualizować Ryujinx do najnowszej wersji?",
|
||||||
|
"SettingsTabHotkeysVolumeUpHotkey": "Zwiększ Głośność:",
|
||||||
|
"SettingsTabHotkeysVolumeDownHotkey": "Zmniejsz Głośność:",
|
||||||
|
"VolumeShort": "Głoś"
|
||||||
}
|
}
|
||||||
|
@@ -278,7 +278,7 @@ namespace Ryujinx.Modules
|
|||||||
{
|
{
|
||||||
string ryuName = Path.GetFileName(Environment.ProcessPath);
|
string ryuName = Path.GetFileName(Environment.ProcessPath);
|
||||||
string ryuExe = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ryuName);
|
string ryuExe = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ryuName);
|
||||||
string ryuArg = string.Join(" ", Environment.GetCommandLineArgs().Skip(1).ToArray());
|
var ryuArg = Environment.GetCommandLineArgs().Skip(1);
|
||||||
|
|
||||||
if (!OperatingSystem.IsWindows())
|
if (!OperatingSystem.IsWindows())
|
||||||
{
|
{
|
||||||
|
@@ -295,8 +295,6 @@ namespace Ryujinx.Ava.Ui.ViewModels
|
|||||||
if (_validTzRegions.Contains(location))
|
if (_validTzRegions.Contains(location))
|
||||||
{
|
{
|
||||||
TimeZone = location;
|
TimeZone = location;
|
||||||
|
|
||||||
OnPropertyChanged(nameof(TimeZone));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -164,7 +164,7 @@
|
|||||||
<MenuItem
|
<MenuItem
|
||||||
Command="{ReflectionBinding ChangeLanguage}"
|
Command="{ReflectionBinding ChangeLanguage}"
|
||||||
CommandParameter="pl_PL"
|
CommandParameter="pl_PL"
|
||||||
Header="Polish" />
|
Header="Polski" />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
Command="{ReflectionBinding ChangeLanguage}"
|
Command="{ReflectionBinding ChangeLanguage}"
|
||||||
CommandParameter="ru_RU"
|
CommandParameter="ru_RU"
|
||||||
|
@@ -37,7 +37,7 @@ namespace Ryujinx.Ava.Ui.Windows
|
|||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
Load();
|
Load();
|
||||||
|
|
||||||
FuncMultiValueConverter<string, string> converter = new(parts => string.Format("{0} {1} {2}", parts.ToArray()));
|
FuncMultiValueConverter<string, string> converter = new(parts => string.Format("{0} {1} {2}", parts.ToArray()).Trim());
|
||||||
MultiBinding tzMultiBinding = new() { Converter = converter };
|
MultiBinding tzMultiBinding = new() { Converter = converter };
|
||||||
tzMultiBinding.Bindings.Add(new Binding("UtcDifference"));
|
tzMultiBinding.Bindings.Add(new Binding("UtcDifference"));
|
||||||
tzMultiBinding.Bindings.Add(new Binding("Location"));
|
tzMultiBinding.Bindings.Add(new Binding("Location"));
|
||||||
|
@@ -129,7 +129,7 @@ namespace Ryujinx.Common
|
|||||||
|
|
||||||
private static (Assembly, string) ResolveManifestPath(string filename)
|
private static (Assembly, string) ResolveManifestPath(string filename)
|
||||||
{
|
{
|
||||||
var segments = filename.Split(new[] { '/' }, 2, StringSplitOptions.RemoveEmptyEntries);
|
var segments = filename.Split('/', 2, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
|
||||||
if (segments.Length >= 2)
|
if (segments.Length >= 2)
|
||||||
{
|
{
|
||||||
|
@@ -480,6 +480,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
if (--_viewsCount == 0)
|
if (--_viewsCount == 0)
|
||||||
{
|
{
|
||||||
_gd.PipelineInternal?.FlushCommandsIfWeightExceeding(_imageAuto, _size);
|
_gd.PipelineInternal?.FlushCommandsIfWeightExceeding(_imageAuto, _size);
|
||||||
|
|
||||||
|
Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -515,10 +515,10 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
dst.Info,
|
dst.Info,
|
||||||
srcRegion,
|
srcRegion,
|
||||||
dstRegion,
|
dstRegion,
|
||||||
src.FirstLevel,
|
|
||||||
dst.FirstLevel,
|
|
||||||
src.FirstLayer,
|
src.FirstLayer,
|
||||||
dst.FirstLayer,
|
dst.FirstLayer,
|
||||||
|
src.FirstLevel,
|
||||||
|
dst.FirstLevel,
|
||||||
layers,
|
layers,
|
||||||
levels,
|
levels,
|
||||||
linearFilter,
|
linearFilter,
|
||||||
|
@@ -310,7 +310,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
internal TextureView CreateTextureView(TextureCreateInfo info, float scale)
|
internal TextureView CreateTextureView(TextureCreateInfo info, float scale)
|
||||||
{
|
{
|
||||||
// This should be disposed when all views are destroyed.
|
// This should be disposed when all views are destroyed.
|
||||||
using var storage = CreateTextureStorage(info, scale);
|
var storage = CreateTextureStorage(info, scale);
|
||||||
return storage.CreateView(info, 0, 0);
|
return storage.CreateView(info, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -918,7 +918,7 @@ namespace Ryujinx.HLE.HOS.Diagnostics.Demangler
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return int.Parse(part.Substring(0, numberLength));
|
return int.Parse(part.AsSpan(0, numberLength));
|
||||||
}
|
}
|
||||||
|
|
||||||
private string ParseNumber(bool isSigned = false)
|
private string ParseNumber(bool isSigned = false)
|
||||||
|
@@ -2540,11 +2540,10 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
|
|||||||
|
|
||||||
for (int attempt = 0; attempt < 8; attempt++)
|
for (int attempt = 0; attempt < 8; attempt++)
|
||||||
{
|
{
|
||||||
address = BitUtils.AlignDown(regionStart + GetRandomValue(0, aslrMaxOffset) * (ulong)alignment, alignment);
|
ulong aslrAddress = BitUtils.AlignDown(regionStart + GetRandomValue(0, aslrMaxOffset) * (ulong)alignment, alignment);
|
||||||
|
ulong aslrEndAddr = aslrAddress + totalNeededSize;
|
||||||
|
|
||||||
ulong endAddr = address + totalNeededSize;
|
KMemoryInfo info = _blockManager.FindBlock(aslrAddress).GetInfo();
|
||||||
|
|
||||||
KMemoryInfo info = _blockManager.FindBlock(address).GetInfo();
|
|
||||||
|
|
||||||
if (info.State != MemoryState.Unmapped)
|
if (info.State != MemoryState.Unmapped)
|
||||||
{
|
{
|
||||||
@@ -2554,11 +2553,12 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
|
|||||||
ulong currBaseAddr = info.Address + reservedPagesCount * PageSize;
|
ulong currBaseAddr = info.Address + reservedPagesCount * PageSize;
|
||||||
ulong currEndAddr = info.Address + info.Size;
|
ulong currEndAddr = info.Address + info.Size;
|
||||||
|
|
||||||
if (address >= regionStart &&
|
if (aslrAddress >= regionStart &&
|
||||||
address >= currBaseAddr &&
|
aslrAddress >= currBaseAddr &&
|
||||||
endAddr - 1 <= regionEndAddr - 1 &&
|
aslrEndAddr - 1 <= regionEndAddr - 1 &&
|
||||||
endAddr - 1 <= currEndAddr - 1)
|
aslrEndAddr - 1 <= currEndAddr - 1)
|
||||||
{
|
{
|
||||||
|
address = aslrAddress;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2603,7 +2603,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
|
|||||||
|
|
||||||
ulong totalNeededSize = reservedSize + neededPagesCount * PageSize;
|
ulong totalNeededSize = reservedSize + neededPagesCount * PageSize;
|
||||||
|
|
||||||
ulong regionEndAddr = regionStart + regionPagesCount * PageSize;
|
ulong regionEndAddr = (regionStart + regionPagesCount * PageSize) - 1;
|
||||||
|
|
||||||
KMemoryBlock currBlock = _blockManager.FindBlock(regionStart);
|
KMemoryBlock currBlock = _blockManager.FindBlock(regionStart);
|
||||||
|
|
||||||
|
@@ -12,6 +12,7 @@ using LibHac.Tools.FsSystem.NcaUtils;
|
|||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy;
|
using Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy;
|
||||||
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
using static Ryujinx.HLE.Utilities.StringUtils;
|
using static Ryujinx.HLE.Utilities.StringUtils;
|
||||||
@@ -787,6 +788,26 @@ namespace Ryujinx.HLE.HOS.Services.Fs
|
|||||||
return ResultCode.Success;
|
return ResultCode.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[CommandHipc(205)]
|
||||||
|
// OpenDataStorageWithProgramIndex(u8 program_index) -> object<nn::fssrv::sf::IStorage>
|
||||||
|
public ResultCode OpenDataStorageWithProgramIndex(ServiceCtx context)
|
||||||
|
{
|
||||||
|
byte programIndex = context.RequestData.ReadByte();
|
||||||
|
|
||||||
|
if ((context.Device.Application.TitleId & 0xf) != programIndex)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException($"Accessing storage from other programs is not supported (program index = {programIndex}).");
|
||||||
|
}
|
||||||
|
|
||||||
|
var storage = context.Device.FileSystem.RomFs.AsStorage(true);
|
||||||
|
using var sharedStorage = new SharedRef<LibHac.Fs.IStorage>(storage);
|
||||||
|
using var sfStorage = new SharedRef<IStorage>(new StorageInterfaceAdapter(ref sharedStorage.Ref()));
|
||||||
|
|
||||||
|
MakeObject(context, new FileSystemProxy.IStorage(ref sfStorage.Ref()));
|
||||||
|
|
||||||
|
return ResultCode.Success;
|
||||||
|
}
|
||||||
|
|
||||||
[CommandHipc(400)]
|
[CommandHipc(400)]
|
||||||
// OpenDataStorageByCurrentProcess() -> object<nn::fssrv::sf::IStorage> dataStorage
|
// OpenDataStorageByCurrentProcess() -> object<nn::fssrv::sf::IStorage> dataStorage
|
||||||
public ResultCode OpenDeviceOperator(ServiceCtx context)
|
public ResultCode OpenDeviceOperator(ServiceCtx context)
|
||||||
|
@@ -816,11 +816,11 @@ namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp
|
|||||||
Reserved = new Array57<byte>()
|
Reserved = new Array57<byte>()
|
||||||
};
|
};
|
||||||
|
|
||||||
modelInfo.CharacterId = BinaryPrimitives.ReverseEndianness(ushort.Parse(context.Device.System.NfpDevices[i].AmiiboId.Substring(0, 4), NumberStyles.HexNumber));
|
modelInfo.CharacterId = BinaryPrimitives.ReverseEndianness(ushort.Parse(context.Device.System.NfpDevices[i].AmiiboId.AsSpan(0, 4), NumberStyles.HexNumber));
|
||||||
modelInfo.CharacterVariant = byte.Parse(context.Device.System.NfpDevices[i].AmiiboId.Substring(4, 2), NumberStyles.HexNumber);
|
modelInfo.CharacterVariant = byte.Parse(context.Device.System.NfpDevices[i].AmiiboId.AsSpan(4, 2), NumberStyles.HexNumber);
|
||||||
modelInfo.Series = byte.Parse(context.Device.System.NfpDevices[i].AmiiboId.Substring(12, 2), NumberStyles.HexNumber);
|
modelInfo.Series = byte.Parse(context.Device.System.NfpDevices[i].AmiiboId.AsSpan(12, 2), NumberStyles.HexNumber);
|
||||||
modelInfo.ModelNumber = ushort.Parse(context.Device.System.NfpDevices[i].AmiiboId.Substring(8, 4), NumberStyles.HexNumber);
|
modelInfo.ModelNumber = ushort.Parse(context.Device.System.NfpDevices[i].AmiiboId.AsSpan(8, 4), NumberStyles.HexNumber);
|
||||||
modelInfo.Type = byte.Parse(context.Device.System.NfpDevices[i].AmiiboId.Substring(6, 2), NumberStyles.HexNumber);
|
modelInfo.Type = byte.Parse(context.Device.System.NfpDevices[i].AmiiboId.AsSpan(6, 2), NumberStyles.HexNumber);
|
||||||
|
|
||||||
context.Memory.Write(outputPosition, modelInfo);
|
context.Memory.Write(outputPosition, modelInfo);
|
||||||
|
|
||||||
|
@@ -13,7 +13,7 @@ namespace Ryujinx.HLE.HOS.Tamper.Conditions
|
|||||||
|
|
||||||
public bool Evaluate()
|
public bool Evaluate()
|
||||||
{
|
{
|
||||||
return (_input.Value & _mask) != 0;
|
return (_input.Value & _mask) == _mask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -122,9 +122,8 @@ namespace Ryujinx.HLE.HOS.Tamper
|
|||||||
for (int nybbleIndex = 0; nybbleIndex < wordSize; nybbleIndex++)
|
for (int nybbleIndex = 0; nybbleIndex < wordSize; nybbleIndex++)
|
||||||
{
|
{
|
||||||
int index = wordIndex * wordSize + nybbleIndex;
|
int index = wordIndex * wordSize + nybbleIndex;
|
||||||
string byteData = word.Substring(nybbleIndex, 1);
|
|
||||||
|
|
||||||
instruction[index] = byte.Parse(byteData, NumberStyles.HexNumber, CultureInfo.InvariantCulture);
|
instruction[index] = byte.Parse(word.AsSpan(nybbleIndex, 1), NumberStyles.HexNumber, CultureInfo.InvariantCulture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -132,7 +132,7 @@ namespace Ryujinx.HLE.Loaders.Mods
|
|||||||
{
|
{
|
||||||
if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
|
if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
|
||||||
{
|
{
|
||||||
return int.TryParse(str.Substring(2), System.Globalization.NumberStyles.HexNumber, null, out value);
|
return int.TryParse(str.AsSpan(2), System.Globalization.NumberStyles.HexNumber, null, out value);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@@ -54,7 +54,7 @@ namespace Ryujinx.HLE.Utilities
|
|||||||
|
|
||||||
for (int index = 0; index < bytesInHex; index++)
|
for (int index = 0; index < bytesInHex; index++)
|
||||||
{
|
{
|
||||||
output[index] = byte.Parse(hexString.Substring(index * 2, 2), NumberStyles.HexNumber);
|
output[index] = byte.Parse(hexString.AsSpan(index * 2, 2), NumberStyles.HexNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
|
@@ -48,7 +48,7 @@ namespace Ryujinx.Modules
|
|||||||
{
|
{
|
||||||
string ryuName = OperatingSystem.IsWindows() ? "Ryujinx.exe" : "Ryujinx";
|
string ryuName = OperatingSystem.IsWindows() ? "Ryujinx.exe" : "Ryujinx";
|
||||||
string ryuExe = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ryuName);
|
string ryuExe = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ryuName);
|
||||||
string ryuArg = string.Join(" ", Environment.GetCommandLineArgs().AsEnumerable().Skip(1).ToArray());
|
var ryuArg = Environment.GetCommandLineArgs().AsEnumerable().Skip(1);
|
||||||
|
|
||||||
Process.Start(ryuExe, ryuArg);
|
Process.Start(ryuExe, ryuArg);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user