Implement some more instructions, fix others.
Uxtab16/Sxtab16 are untested.
This commit is contained in:
parent
fc2d482616
commit
3d9d492b22
9 changed files with 169 additions and 10 deletions
|
@ -13,6 +13,7 @@ namespace ARMeilleure.Decoders
|
||||||
|
|
||||||
public bool NHigh { get; private set; }
|
public bool NHigh { get; private set; }
|
||||||
public bool MHigh { get; private set; }
|
public bool MHigh { get; private set; }
|
||||||
|
public bool R { get; private set; }
|
||||||
public bool SetFlags { get; private set; }
|
public bool SetFlags { get; private set; }
|
||||||
|
|
||||||
public OpCode32AluMla(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
public OpCode32AluMla(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
||||||
|
@ -21,6 +22,7 @@ namespace ARMeilleure.Decoders
|
||||||
Rm = (opCode >> 8) & 0xf;
|
Rm = (opCode >> 8) & 0xf;
|
||||||
Ra = (opCode >> 12) & 0xf;
|
Ra = (opCode >> 12) & 0xf;
|
||||||
Rd = (opCode >> 16) & 0xf;
|
Rd = (opCode >> 16) & 0xf;
|
||||||
|
R = (opCode & (1 << 5)) != 0;
|
||||||
|
|
||||||
NHigh = ((opCode >> 5) * 0x1) == 1;
|
NHigh = ((opCode >> 5) * 0x1) == 1;
|
||||||
MHigh = ((opCode >> 6) * 0x1) == 1;
|
MHigh = ((opCode >> 6) * 0x1) == 1;
|
||||||
|
|
|
@ -652,7 +652,9 @@ namespace ARMeilleure.Decoders
|
||||||
SetA32("<<<<000xx1x1xxxxxxxxxxxx1011xxxx", InstName.Ldrh, InstEmit32.Ldrh, typeof(OpCode32MemImm8));
|
SetA32("<<<<000xx1x1xxxxxxxxxxxx1011xxxx", InstName.Ldrh, InstEmit32.Ldrh, typeof(OpCode32MemImm8));
|
||||||
SetA32("<<<<000xx0x1xxxxxxxx00001011xxxx", InstName.Ldrh, InstEmit32.Ldrh, typeof(OpCode32MemReg));
|
SetA32("<<<<000xx0x1xxxxxxxx00001011xxxx", InstName.Ldrh, InstEmit32.Ldrh, typeof(OpCode32MemReg));
|
||||||
SetA32("<<<<000xx1x1xxxxxxxxxxxx1101xxxx", InstName.Ldrsb, InstEmit32.Ldrsb, typeof(OpCode32MemImm8));
|
SetA32("<<<<000xx1x1xxxxxxxxxxxx1101xxxx", InstName.Ldrsb, InstEmit32.Ldrsb, typeof(OpCode32MemImm8));
|
||||||
|
SetA32("<<<<000xx0x1xxxxxxxx00001101xxxx", InstName.Ldrsb, InstEmit32.Ldrsb, typeof(OpCode32MemReg));
|
||||||
SetA32("<<<<000xx1x1xxxxxxxxxxxx1111xxxx", InstName.Ldrsh, InstEmit32.Ldrsh, typeof(OpCode32MemImm8));
|
SetA32("<<<<000xx1x1xxxxxxxxxxxx1111xxxx", InstName.Ldrsh, InstEmit32.Ldrsh, typeof(OpCode32MemImm8));
|
||||||
|
SetA32("<<<<000xx0x1xxxxxxxx00001111xxxx", InstName.Ldrsh, InstEmit32.Ldrsh, typeof(OpCode32MemReg));
|
||||||
SetA32("<<<<1110xxx0xxxxxxxx111xxxx1xxxx", InstName.Mcr, InstEmit32.Mcr, typeof(OpCode32System));
|
SetA32("<<<<1110xxx0xxxxxxxx111xxxx1xxxx", InstName.Mcr, InstEmit32.Mcr, typeof(OpCode32System));
|
||||||
SetA32("<<<<0000001xxxxxxxxxxxxx1001xxxx", InstName.Mla, InstEmit32.Mla, typeof(OpCode32AluMla));
|
SetA32("<<<<0000001xxxxxxxxxxxxx1001xxxx", InstName.Mla, InstEmit32.Mla, typeof(OpCode32AluMla));
|
||||||
SetA32("<<<<00000110xxxxxxxxxxxx1001xxxx", InstName.Mls, InstEmit32.Mls, typeof(OpCode32AluMla));
|
SetA32("<<<<00000110xxxxxxxxxxxx1001xxxx", InstName.Mls, InstEmit32.Mls, typeof(OpCode32AluMla));
|
||||||
|
@ -688,7 +690,8 @@ namespace ARMeilleure.Decoders
|
||||||
SetA32("<<<<00010000xxxxxxxxxxxx1xx0xxxx", InstName.Smlab, InstEmit32.Smlab, typeof(OpCode32AluMla));
|
SetA32("<<<<00010000xxxxxxxxxxxx1xx0xxxx", InstName.Smlab, InstEmit32.Smlab, typeof(OpCode32AluMla));
|
||||||
SetA32("<<<<0000111xxxxxxxxxxxxx1001xxxx", InstName.Smlal, InstEmit32.Smlal, typeof(OpCode32AluUmull));
|
SetA32("<<<<0000111xxxxxxxxxxxxx1001xxxx", InstName.Smlal, InstEmit32.Smlal, typeof(OpCode32AluUmull));
|
||||||
SetA32("<<<<00010100xxxxxxxxxxxx1xx0xxxx", InstName.Smlalh,InstEmit32.Smlalh,typeof(OpCode32AluUmull));
|
SetA32("<<<<00010100xxxxxxxxxxxx1xx0xxxx", InstName.Smlalh,InstEmit32.Smlalh,typeof(OpCode32AluUmull));
|
||||||
SetA32("<<<<01110101xxxx1111xxxx00x1xxxx", InstName.Smmul, InstEmit32.Smmul, typeof(OpCode32AluMla));
|
SetA32("<<<<01110101xxxxxxxxxxxx00x1xxxx", InstName.Smmla, InstEmit32.Smmla, typeof(OpCode32AluMla));
|
||||||
|
SetA32("<<<<01110101xxxxxxxxxxxx11x1xxxx", InstName.Smmls, InstEmit32.Smmls, typeof(OpCode32AluMla));
|
||||||
SetA32("<<<<0010110xxxxxxxxxxxxxxxxxxxxx", InstName.Sbc, InstEmit32.Sbc, typeof(OpCode32AluImm));
|
SetA32("<<<<0010110xxxxxxxxxxxxxxxxxxxxx", InstName.Sbc, InstEmit32.Sbc, typeof(OpCode32AluImm));
|
||||||
SetA32("<<<<0000110xxxxxxxxxxxxxxxx0xxxx", InstName.Sbc, InstEmit32.Sbc, typeof(OpCode32AluRsImm));
|
SetA32("<<<<0000110xxxxxxxxxxxxxxxx0xxxx", InstName.Sbc, InstEmit32.Sbc, typeof(OpCode32AluRsImm));
|
||||||
SetA32("<<<<0000110xxxxxxxxxxxxx0xx1xxxx", InstName.Sbc, InstEmit32.Sbc, typeof(OpCode32AluRsReg));
|
SetA32("<<<<0000110xxxxxxxxxxxxx0xx1xxxx", InstName.Sbc, InstEmit32.Sbc, typeof(OpCode32AluRsReg));
|
||||||
|
@ -719,6 +722,7 @@ namespace ARMeilleure.Decoders
|
||||||
SetA32("<<<<0000010xxxxxxxxxxxxx0xx1xxxx", InstName.Sub, InstEmit32.Sub, typeof(OpCode32AluRsReg));
|
SetA32("<<<<0000010xxxxxxxxxxxxx0xx1xxxx", InstName.Sub, InstEmit32.Sub, typeof(OpCode32AluRsReg));
|
||||||
SetA32("<<<<1111xxxxxxxxxxxxxxxxxxxxxxxx", InstName.Svc, InstEmit32.Svc, typeof(OpCode32Exception));
|
SetA32("<<<<1111xxxxxxxxxxxxxxxxxxxxxxxx", InstName.Svc, InstEmit32.Svc, typeof(OpCode32Exception));
|
||||||
SetA32("<<<<01101010xxxxxxxxxx000111xxxx", InstName.Sxtb, InstEmit32.Sxtb, typeof(OpCode32AluUx));
|
SetA32("<<<<01101010xxxxxxxxxx000111xxxx", InstName.Sxtb, InstEmit32.Sxtb, typeof(OpCode32AluUx));
|
||||||
|
SetA32("<<<<01101000xxxxxxxxxx000111xxxx", InstName.Sxtb16,InstEmit32.Sxtb16,typeof(OpCode32AluUx));
|
||||||
SetA32("<<<<01101011xxxxxxxxxx000111xxxx", InstName.Sxth, InstEmit32.Sxth, typeof(OpCode32AluUx));
|
SetA32("<<<<01101011xxxxxxxxxx000111xxxx", InstName.Sxth, InstEmit32.Sxth, typeof(OpCode32AluUx));
|
||||||
SetA32("<<<<00110011xxxx0000xxxxxxxxxxxx", InstName.Teq, InstEmit32.Teq, typeof(OpCode32AluImm));
|
SetA32("<<<<00110011xxxx0000xxxxxxxxxxxx", InstName.Teq, InstEmit32.Teq, typeof(OpCode32AluImm));
|
||||||
SetA32("<<<<00010011xxxx0000xxxxxxx0xxxx", InstName.Teq, InstEmit32.Teq, typeof(OpCode32AluRsImm));
|
SetA32("<<<<00010011xxxx0000xxxxxxx0xxxx", InstName.Teq, InstEmit32.Teq, typeof(OpCode32AluRsImm));
|
||||||
|
@ -731,6 +735,7 @@ namespace ARMeilleure.Decoders
|
||||||
SetA32("<<<<01110011xxxx1111xxxx0001xxxx", InstName.Udiv, InstEmit32.Udiv, typeof(OpCode32AluMla));
|
SetA32("<<<<01110011xxxx1111xxxx0001xxxx", InstName.Udiv, InstEmit32.Udiv, typeof(OpCode32AluMla));
|
||||||
SetA32("<<<<0000100xxxxxxxxxxxxx1001xxxx", InstName.Umull, InstEmit32.Umull, typeof(OpCode32AluUmull));
|
SetA32("<<<<0000100xxxxxxxxxxxxx1001xxxx", InstName.Umull, InstEmit32.Umull, typeof(OpCode32AluUmull));
|
||||||
SetA32("<<<<01101110xxxxxxxxxx000111xxxx", InstName.Uxtb, InstEmit32.Uxtb, typeof(OpCode32AluUx));
|
SetA32("<<<<01101110xxxxxxxxxx000111xxxx", InstName.Uxtb, InstEmit32.Uxtb, typeof(OpCode32AluUx));
|
||||||
|
SetA32("<<<<01101100xxxxxxxxxx000111xxxx", InstName.Uxtb16,InstEmit32.Uxtb16,typeof(OpCode32AluUx));
|
||||||
SetA32("<<<<01101111xxxxxxxxxx000111xxxx", InstName.Uxth, InstEmit32.Uxth, typeof(OpCode32AluUx));
|
SetA32("<<<<01101111xxxxxxxxxx000111xxxx", InstName.Uxth, InstEmit32.Uxth, typeof(OpCode32AluUx));
|
||||||
|
|
||||||
// FP & SIMD (AArch32)
|
// FP & SIMD (AArch32)
|
||||||
|
@ -805,6 +810,12 @@ namespace ARMeilleure.Decoders
|
||||||
|
|
||||||
SetA32("<<<<1101xx01xxxxxxxx10xxxxxxxxxx", InstName.Vldr, InstEmit32.Vldr, typeof(OpCode32SimdMemImm));
|
SetA32("<<<<1101xx01xxxxxxxx10xxxxxxxxxx", InstName.Vldr, InstEmit32.Vldr, typeof(OpCode32SimdMemImm));
|
||||||
|
|
||||||
|
SetA32("111100100x0xxxxxxxxx1111xxx0xxxx", InstName.Vmax, InstEmit32.Vmax_V, typeof(OpCode32SimdReg));
|
||||||
|
SetA32("1111001x0xxxxxxxxxxx0110xxx0xxxx", InstName.Vmax, InstEmit32.Vmax_I, typeof(OpCode32SimdReg));
|
||||||
|
|
||||||
|
SetA32("111100100x1xxxxxxxxx1111xxx0xxxx", InstName.Vmin, InstEmit32.Vmin_V, typeof(OpCode32SimdReg));
|
||||||
|
SetA32("1111001x0xxxxxxxxxxx0110xxx1xxxx", InstName.Vmin, InstEmit32.Vmin_I, typeof(OpCode32SimdReg));
|
||||||
|
|
||||||
SetA32("111111101x00xxxxxxxx10xxxxx0xxxx", InstName.VMMmn, InstEmit32.VmaxminNm_S, typeof(OpCode32SimdRegS));
|
SetA32("111111101x00xxxxxxxx10xxxxx0xxxx", InstName.VMMmn, InstEmit32.VmaxminNm_S, typeof(OpCode32SimdRegS));
|
||||||
SetA32("111100110xxxxxxxxxxx1111xxx1xxxx", InstName.VMMmn, InstEmit32.VmaxminNm_V, typeof(OpCode32SimdReg));
|
SetA32("111100110xxxxxxxxxxx1111xxx1xxxx", InstName.VMMmn, InstEmit32.VmaxminNm_V, typeof(OpCode32SimdReg));
|
||||||
|
|
||||||
|
|
|
@ -322,11 +322,72 @@ namespace ARMeilleure.Instructions
|
||||||
EmitAluStore(context, res);
|
EmitAluStore(context, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void EmitExtend16(ArmEmitterContext context, bool signed)
|
||||||
|
{
|
||||||
|
IOpCode32AluUx op = (IOpCode32AluUx)context.CurrOp;
|
||||||
|
|
||||||
|
Operand m = GetAluM(context);
|
||||||
|
Operand res;
|
||||||
|
|
||||||
|
if (op.RotateBits == 0)
|
||||||
|
{
|
||||||
|
res = m;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Operand rotate = Const(op.RotateBits);
|
||||||
|
res = context.RotateRight(m, rotate);
|
||||||
|
}
|
||||||
|
|
||||||
|
Operand low16, high16;
|
||||||
|
if (signed)
|
||||||
|
{
|
||||||
|
low16 = context.SignExtend8(OperandType.I32, res);
|
||||||
|
high16 = context.SignExtend8(OperandType.I32, context.ShiftRightUI(res, Const(16)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
low16 = context.ZeroExtend8(OperandType.I32, res);
|
||||||
|
high16 = context.ZeroExtend8(OperandType.I32, context.ShiftRightUI(res, Const(16)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (op.Add)
|
||||||
|
{
|
||||||
|
Operand n = GetAluN(context);
|
||||||
|
Operand lowAdd, highAdd;
|
||||||
|
if (signed)
|
||||||
|
{
|
||||||
|
lowAdd = context.SignExtend16(OperandType.I32, n);
|
||||||
|
highAdd = context.SignExtend16(OperandType.I32, context.ShiftRightUI(n, Const(16)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lowAdd = context.ZeroExtend16(OperandType.I32, n);
|
||||||
|
highAdd = context.ZeroExtend16(OperandType.I32, context.ShiftRightUI(n, Const(16)));
|
||||||
|
}
|
||||||
|
|
||||||
|
low16 = context.Add(low16, lowAdd);
|
||||||
|
high16 = context.Add(high16, highAdd);
|
||||||
|
}
|
||||||
|
|
||||||
|
res = context.BitwiseOr(
|
||||||
|
context.ZeroExtend16(OperandType.I32, low16),
|
||||||
|
context.ShiftLeft(context.ZeroExtend16(OperandType.I32, high16), Const(16))
|
||||||
|
);
|
||||||
|
|
||||||
|
EmitAluStore(context, res);
|
||||||
|
}
|
||||||
|
|
||||||
public static void Uxtb(ArmEmitterContext context)
|
public static void Uxtb(ArmEmitterContext context)
|
||||||
{
|
{
|
||||||
EmitSignExtend(context, false, 8);
|
EmitSignExtend(context, false, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void Uxtb16(ArmEmitterContext context)
|
||||||
|
{
|
||||||
|
EmitExtend16(context, false);
|
||||||
|
}
|
||||||
|
|
||||||
public static void Uxth(ArmEmitterContext context)
|
public static void Uxth(ArmEmitterContext context)
|
||||||
{
|
{
|
||||||
EmitSignExtend(context, false, 16);
|
EmitSignExtend(context, false, 16);
|
||||||
|
@ -337,6 +398,11 @@ namespace ARMeilleure.Instructions
|
||||||
EmitSignExtend(context, true, 8);
|
EmitSignExtend(context, true, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void Sxtb16(ArmEmitterContext context)
|
||||||
|
{
|
||||||
|
EmitExtend16(context, true);
|
||||||
|
}
|
||||||
|
|
||||||
public static void Sxth(ArmEmitterContext context)
|
public static void Sxth(ArmEmitterContext context)
|
||||||
{
|
{
|
||||||
EmitSignExtend(context, true, 16);
|
EmitSignExtend(context, true, 16);
|
||||||
|
|
|
@ -71,7 +71,7 @@ namespace ARMeilleure.Instructions
|
||||||
|
|
||||||
public static void Ldah(ArmEmitterContext context)
|
public static void Ldah(ArmEmitterContext context)
|
||||||
{
|
{
|
||||||
EmitExLoadOrStore(context, ByteSizeLog2, AccessType.LoadZx | AccessType.Ordered);
|
EmitExLoadOrStore(context, HWordSizeLog2, AccessType.LoadZx | AccessType.Ordered);
|
||||||
}
|
}
|
||||||
|
|
||||||
// stores
|
// stores
|
||||||
|
|
|
@ -15,9 +15,9 @@ namespace ARMeilleure.Instructions
|
||||||
[Flags]
|
[Flags]
|
||||||
private enum MullFlags
|
private enum MullFlags
|
||||||
{
|
{
|
||||||
Subtract = 0,
|
Subtract = 1,
|
||||||
Add = 1 << 0,
|
Add = 1 << 1,
|
||||||
Signed = 1 << 1,
|
Signed = 1 << 2,
|
||||||
|
|
||||||
SignedAdd = Signed | Add,
|
SignedAdd = Signed | Add,
|
||||||
SignedSubtract = Signed | Subtract
|
SignedSubtract = Signed | Subtract
|
||||||
|
@ -44,7 +44,22 @@ namespace ARMeilleure.Instructions
|
||||||
EmitGenericStore(context, op.RdLo, op.SetFlags, lo);
|
EmitGenericStore(context, op.RdLo, op.SetFlags, lo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void Smmla(ArmEmitterContext context)
|
||||||
|
{
|
||||||
|
EmitSmmul(context, MullFlags.SignedAdd);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Smmls(ArmEmitterContext context)
|
||||||
|
{
|
||||||
|
EmitSmmul(context, MullFlags.SignedSubtract);
|
||||||
|
}
|
||||||
|
|
||||||
public static void Smmul(ArmEmitterContext context)
|
public static void Smmul(ArmEmitterContext context)
|
||||||
|
{
|
||||||
|
EmitSmmul(context, MullFlags.Signed);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void EmitSmmul(ArmEmitterContext context, MullFlags flags)
|
||||||
{
|
{
|
||||||
OpCode32AluMla op = (OpCode32AluMla)context.CurrOp;
|
OpCode32AluMla op = (OpCode32AluMla)context.CurrOp;
|
||||||
|
|
||||||
|
@ -53,7 +68,16 @@ namespace ARMeilleure.Instructions
|
||||||
|
|
||||||
Operand res = context.Multiply(n, m);
|
Operand res = context.Multiply(n, m);
|
||||||
|
|
||||||
if ((op.RawOpCode & (1 << 5)) != 0)
|
if (flags.HasFlag(MullFlags.Add) && op.Ra != 0xf)
|
||||||
|
{
|
||||||
|
res = context.Add(context.ShiftLeft(context.ZeroExtend32(OperandType.I64, GetIntA32(context, op.Ra)), Const(32)), res);
|
||||||
|
}
|
||||||
|
else if (flags.HasFlag(MullFlags.Subtract))
|
||||||
|
{
|
||||||
|
res = context.Subtract(context.ShiftLeft(context.ZeroExtend32(OperandType.I64, GetIntA32(context, op.Ra)), Const(32)), res);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (op.R)
|
||||||
{
|
{
|
||||||
res = context.Add(res, Const(0x80000000L));
|
res = context.Add(res, Const(0x80000000L));
|
||||||
}
|
}
|
||||||
|
|
|
@ -163,21 +163,65 @@ namespace ARMeilleure.Instructions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void Vmax_V(ArmEmitterContext context)
|
||||||
|
{
|
||||||
|
EmitVectorBinaryOpF32(context, (op1, op2) =>
|
||||||
|
{
|
||||||
|
return EmitSoftFloatCall(context, SoftFloat32.FPMax, SoftFloat64.FPMax, op1, op2);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Vmax_I(ArmEmitterContext context)
|
||||||
|
{
|
||||||
|
OpCode32SimdReg op = (OpCode32SimdReg)context.CurrOp;
|
||||||
|
if (op.U)
|
||||||
|
{
|
||||||
|
EmitVectorBinaryOpZx32(context, (op1, op2) => context.ConditionalSelect(context.ICompareGreaterUI(op1, op2), op1, op2));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EmitVectorBinaryOpSx32(context, (op1, op2) => context.ConditionalSelect(context.ICompareGreater(op1, op2), op1, op2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Vmin_V(ArmEmitterContext context)
|
||||||
|
{
|
||||||
|
EmitVectorBinaryOpF32(context, (op1, op2) =>
|
||||||
|
{
|
||||||
|
return EmitSoftFloatCall(context, SoftFloat32.FPMin, SoftFloat64.FPMin, op1, op2);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Vmin_I(ArmEmitterContext context)
|
||||||
|
{
|
||||||
|
OpCode32SimdReg op = (OpCode32SimdReg)context.CurrOp;
|
||||||
|
if (op.U)
|
||||||
|
{
|
||||||
|
EmitVectorBinaryOpZx32(context, (op1, op2) => context.ConditionalSelect(context.ICompareLessUI(op1, op2), op1, op2));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EmitVectorBinaryOpSx32(context, (op1, op2) => context.ConditionalSelect(context.ICompareLess(op1, op2), op1, op2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//TODO: probably important to have a fast path for these instead of calling fucking standard math min/max
|
//TODO: probably important to have a fast path for these instead of calling fucking standard math min/max
|
||||||
public static void VmaxminNm_S(ArmEmitterContext context)
|
public static void VmaxminNm_S(ArmEmitterContext context)
|
||||||
{
|
{
|
||||||
bool max = (context.CurrOp.RawOpCode & (1 << 6)) == 0;
|
bool max = (context.CurrOp.RawOpCode & (1 << 6)) == 0;
|
||||||
Delegate dlg = max ? new _F32_F32_F32(Math.Max) : new _F32_F32_F32(Math.Min);
|
_F32_F32_F32 f32 = max ? new _F32_F32_F32(SoftFloat32.FPMaxNum) : new _F32_F32_F32(SoftFloat32.FPMinNum);
|
||||||
|
_F64_F64_F64 f64 = max ? new _F64_F64_F64(SoftFloat64.FPMaxNum) : new _F64_F64_F64(SoftFloat64.FPMinNum);
|
||||||
|
|
||||||
EmitScalarBinaryOpF32(context, (op1, op2) => context.Call(dlg, op1, op2));
|
EmitScalarBinaryOpF32(context, (op1, op2) => EmitSoftFloatCall(context, f32, f64, op1, op2));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void VmaxminNm_V(ArmEmitterContext context)
|
public static void VmaxminNm_V(ArmEmitterContext context)
|
||||||
{
|
{
|
||||||
bool max = (context.CurrOp.RawOpCode & (1 << 21)) == 0;
|
bool max = (context.CurrOp.RawOpCode & (1 << 21)) == 0;
|
||||||
Delegate dlg = max ? new _F32_F32_F32(Math.Max) : new _F32_F32_F32(Math.Min);
|
_F32_F32_F32 f32 = max ? new _F32_F32_F32(SoftFloat32.FPMaxNum) : new _F32_F32_F32(SoftFloat32.FPMinNum);
|
||||||
|
_F64_F64_F64 f64 = max ? new _F64_F64_F64(SoftFloat64.FPMaxNum) : new _F64_F64_F64(SoftFloat64.FPMinNum);
|
||||||
|
|
||||||
EmitVectorBinaryOpSx32(context, (op1, op2) => context.Call(dlg, op1, op2));
|
EmitVectorBinaryOpSx32(context, (op1, op2) => EmitSoftFloatCall(context, f32, f64, op1, op2));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Vmul_S(ArmEmitterContext context)
|
public static void Vmul_S(ArmEmitterContext context)
|
||||||
|
|
|
@ -489,6 +489,8 @@ namespace ARMeilleure.Instructions
|
||||||
Smlab,
|
Smlab,
|
||||||
Smlal,
|
Smlal,
|
||||||
Smlalh,
|
Smlalh,
|
||||||
|
Smmla,
|
||||||
|
Smmls,
|
||||||
Smmul,
|
Smmul,
|
||||||
Stl,
|
Stl,
|
||||||
Stlb,
|
Stlb,
|
||||||
|
@ -505,12 +507,14 @@ namespace ARMeilleure.Instructions
|
||||||
Strexd,
|
Strexd,
|
||||||
Strexh,
|
Strexh,
|
||||||
Strh,
|
Strh,
|
||||||
|
Sxtb16,
|
||||||
Teq,
|
Teq,
|
||||||
Trap,
|
Trap,
|
||||||
Tst,
|
Tst,
|
||||||
Ubfx,
|
Ubfx,
|
||||||
Umull,
|
Umull,
|
||||||
Uxtb,
|
Uxtb,
|
||||||
|
Uxtb16,
|
||||||
Uxth,
|
Uxth,
|
||||||
|
|
||||||
// FP & SIMD (AArch32)
|
// FP & SIMD (AArch32)
|
||||||
|
@ -532,6 +536,8 @@ namespace ARMeilleure.Instructions
|
||||||
Vld4,
|
Vld4,
|
||||||
Vldm,
|
Vldm,
|
||||||
Vldr,
|
Vldr,
|
||||||
|
Vmax,
|
||||||
|
Vmin,
|
||||||
VMMmn,
|
VMMmn,
|
||||||
Vmla,
|
Vmla,
|
||||||
Vmls,
|
Vmls,
|
||||||
|
|
|
@ -149,6 +149,11 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
||||||
return ResetSignal(handle);
|
return ResetSignal(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public KernelResult ResetSignal32([R(0)] int handle)
|
||||||
|
{
|
||||||
|
return ResetSignal(handle);
|
||||||
|
}
|
||||||
|
|
||||||
private KernelResult ResetSignal(int handle)
|
private KernelResult ResetSignal(int handle)
|
||||||
{
|
{
|
||||||
KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
|
KProcess currentProcess = _system.Scheduler.GetCurrentProcess();
|
||||||
|
|
|
@ -103,6 +103,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
||||||
{ 0x14, nameof(SvcHandler.UnmapSharedMemory32) },
|
{ 0x14, nameof(SvcHandler.UnmapSharedMemory32) },
|
||||||
{ 0x15, nameof(SvcHandler.CreateTransferMemory32) },
|
{ 0x15, nameof(SvcHandler.CreateTransferMemory32) },
|
||||||
{ 0x16, nameof(SvcHandler.CloseHandle32) },
|
{ 0x16, nameof(SvcHandler.CloseHandle32) },
|
||||||
|
{ 0x17, nameof(SvcHandler.ResetSignal32) },
|
||||||
{ 0x18, nameof(SvcHandler.WaitSynchronization32) },
|
{ 0x18, nameof(SvcHandler.WaitSynchronization32) },
|
||||||
{ 0x1a, nameof(SvcHandler.ArbitrateLock32) },
|
{ 0x1a, nameof(SvcHandler.ArbitrateLock32) },
|
||||||
{ 0x1b, nameof(SvcHandler.ArbitrateUnlock32) },
|
{ 0x1b, nameof(SvcHandler.ArbitrateUnlock32) },
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue