Fix incorrect opcode decoders and a few more instructions.
This commit is contained in:
parent
9e2e45f852
commit
8068eb23e5
10 changed files with 159 additions and 9 deletions
24
ARMeilleure/Decoders/OpCode32SimdSel.cs
Normal file
24
ARMeilleure/Decoders/OpCode32SimdSel.cs
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace ARMeilleure.Decoders
|
||||||
|
{
|
||||||
|
class OpCode32SimdSel : OpCode32SimdRegS
|
||||||
|
{
|
||||||
|
public OpCode32SimdSelMode Cc { get; private set; }
|
||||||
|
|
||||||
|
public OpCode32SimdSel(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
||||||
|
{
|
||||||
|
Cc = (OpCode32SimdSelMode)((opCode >> 20) & 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum OpCode32SimdSelMode : int
|
||||||
|
{
|
||||||
|
Eq = 0,
|
||||||
|
Vs,
|
||||||
|
Ge,
|
||||||
|
Gt
|
||||||
|
}
|
||||||
|
}
|
|
@ -683,8 +683,9 @@ namespace ARMeilleure.Decoders
|
||||||
SetA32("<<<<00010100xxxxxxxxxxxx1xx0xxxx", InstName.Smlal, InstEmit32.Smlal, typeof(OpCode32AluUmull));
|
SetA32("<<<<00010100xxxxxxxxxxxx1xx0xxxx", InstName.Smlal, InstEmit32.Smlal, typeof(OpCode32AluUmull));
|
||||||
SetA32("<<<<01110101xxxx1111xxxx00x1xxxx", InstName.Smmul, InstEmit32.Smmul, typeof(OpCode32AluMla));
|
SetA32("<<<<01110101xxxx1111xxxx00x1xxxx", InstName.Smmul, InstEmit32.Smmul, 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(OpCode32AluRsReg));
|
SetA32("<<<<0000110xxxxxxxxxxxxxxxx0xxxx", InstName.Sbc, InstEmit32.Sbc, typeof(OpCode32AluRsImm));
|
||||||
SetA32("<<<<0000110xxxxxxxxxxxxx0xx1xxxx", InstName.Sbc, InstEmit32.Sbc, typeof(OpCode32AluRsReg));
|
SetA32("<<<<0000110xxxxxxxxxxxxx0xx1xxxx", InstName.Sbc, InstEmit32.Sbc, typeof(OpCode32AluRsReg));
|
||||||
|
SetA32("<<<<0111101xxxxxxxxxxxxxx101xxxx", InstName.Sbfx, InstEmit32.Sbfx, typeof(OpCode32AluBf));
|
||||||
SetA32("<<<<00011000xxxx111111001001xxxx", InstName.Stl, InstEmit32.Stl, typeof(OpCode32MemStEx));
|
SetA32("<<<<00011000xxxx111111001001xxxx", InstName.Stl, InstEmit32.Stl, typeof(OpCode32MemStEx));
|
||||||
SetA32("<<<<00011100xxxx111111001001xxxx", InstName.Stlb, InstEmit32.Stlb, typeof(OpCode32MemStEx));
|
SetA32("<<<<00011100xxxx111111001001xxxx", InstName.Stlb, InstEmit32.Stlb, typeof(OpCode32MemStEx));
|
||||||
SetA32("<<<<00011000xxxxxxxx11101001xxxx", InstName.Stlex, InstEmit32.Stlex, typeof(OpCode32MemStEx));
|
SetA32("<<<<00011000xxxxxxxx11101001xxxx", InstName.Stlex, InstEmit32.Stlex, typeof(OpCode32MemStEx));
|
||||||
|
@ -708,17 +709,17 @@ namespace ARMeilleure.Decoders
|
||||||
SetA32("<<<<000xx0x0xxxxxxxx00001011xxxx", InstName.Strh, InstEmit32.Strh, typeof(OpCode32MemReg));
|
SetA32("<<<<000xx0x0xxxxxxxx00001011xxxx", InstName.Strh, InstEmit32.Strh, typeof(OpCode32MemReg));
|
||||||
SetA32("<<<<0010010xxxxxxxxxxxxxxxxxxxxx", InstName.Sub, InstEmit32.Sub, typeof(OpCode32AluImm));
|
SetA32("<<<<0010010xxxxxxxxxxxxxxxxxxxxx", InstName.Sub, InstEmit32.Sub, typeof(OpCode32AluImm));
|
||||||
SetA32("<<<<0000010xxxxxxxxxxxxxxxx0xxxx", InstName.Sub, InstEmit32.Sub, typeof(OpCode32AluRsImm));
|
SetA32("<<<<0000010xxxxxxxxxxxxxxxx0xxxx", InstName.Sub, InstEmit32.Sub, typeof(OpCode32AluRsImm));
|
||||||
SetA32("<<<<0000010xxxxxxxxxxxxx0xx1xxxx", InstName.Sub, InstEmit32.Sub, typeof(OpCode32AluRsImm));
|
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("<<<<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));
|
||||||
SetA32("<<<<00010011xxxx0000xxxx0xx1xxxx", InstName.Teq, InstEmit32.Teq, typeof(OpCode32AluRsImm));
|
SetA32("<<<<00010011xxxx0000xxxx0xx1xxxx", InstName.Teq, InstEmit32.Teq, typeof(OpCode32AluRsReg));
|
||||||
SetA32("<<<<0111111111111101111011111110", InstName.Trap, InstEmit32.Trap, typeof(OpCode32Exception));
|
SetA32("<<<<0111111111111101111011111110", InstName.Trap, InstEmit32.Trap, typeof(OpCode32Exception));
|
||||||
SetA32("<<<<00110001xxxx0000xxxxxxxxxxxx", InstName.Tst, InstEmit32.Tst, typeof(OpCode32AluImm));
|
SetA32("<<<<00110001xxxx0000xxxxxxxxxxxx", InstName.Tst, InstEmit32.Tst, typeof(OpCode32AluImm));
|
||||||
SetA32("<<<<00010001xxxx0000xxxxxxx0xxxx", InstName.Tst, InstEmit32.Tst, typeof(OpCode32AluRsImm));
|
SetA32("<<<<00010001xxxx0000xxxxxxx0xxxx", InstName.Tst, InstEmit32.Tst, typeof(OpCode32AluRsImm));
|
||||||
SetA32("<<<<00010001xxxx0000xxxx0xx1xxxx", InstName.Tst, InstEmit32.Tst, typeof(OpCode32AluRsImm));
|
SetA32("<<<<00010001xxxx0000xxxx0xx1xxxx", InstName.Tst, InstEmit32.Tst, typeof(OpCode32AluRsReg));
|
||||||
SetA32("<<<<0111111xxxxxxxxxxxxxx101xxxx", InstName.Ubfx, InstEmit32.Ubfx, typeof(OpCode32AluBf));
|
SetA32("<<<<0111111xxxxxxxxxxxxxx101xxxx", InstName.Ubfx, InstEmit32.Ubfx, typeof(OpCode32AluBf));
|
||||||
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));
|
||||||
|
@ -773,6 +774,9 @@ namespace ARMeilleure.Decoders
|
||||||
|
|
||||||
SetA32("<<<<1101xx01xxxxxxxx10xxxxxxxxxx", InstName.Vldr, InstEmit32.Vldr, typeof(OpCode32SimdMemImm));
|
SetA32("<<<<1101xx01xxxxxxxx10xxxxxxxxxx", InstName.Vldr, InstEmit32.Vldr, typeof(OpCode32SimdMemImm));
|
||||||
|
|
||||||
|
SetA32("111111101x00xxxxxxxx10xxxxx0xxxx", InstName.VMMmn, InstEmit32.VmaxminNm_S, typeof(OpCode32SimdRegS));
|
||||||
|
SetA32("111100110xxxxxxxxxxx1111xxx1xxxx", InstName.VMMmn, InstEmit32.VmaxminNm_V, typeof(OpCode32SimdReg));
|
||||||
|
|
||||||
SetA32("<<<<11100x00xxxxxxxx10xxx0x0xxxx", InstName.Vmla, InstEmit32.Vmla_S, typeof(OpCode32SimdRegS));
|
SetA32("<<<<11100x00xxxxxxxx10xxx0x0xxxx", InstName.Vmla, InstEmit32.Vmla_S, typeof(OpCode32SimdRegS));
|
||||||
SetA32("111100100x0xxxxxxxxx1101xxx1xxxx", InstName.Vmla, InstEmit32.Vmla_V, typeof(OpCode32SimdReg));
|
SetA32("111100100x0xxxxxxxxx1101xxx1xxxx", InstName.Vmla, InstEmit32.Vmla_V, typeof(OpCode32SimdReg));
|
||||||
SetA32("111100100xxxxxxxxxxx1001xxx0xxxx", InstName.Vmla, InstEmit32.Vmla_I, typeof(OpCode32SimdReg));
|
SetA32("111100100xxxxxxxxxxx1001xxx0xxxx", InstName.Vmla, InstEmit32.Vmla_I, typeof(OpCode32SimdReg));
|
||||||
|
@ -803,6 +807,8 @@ namespace ARMeilleure.Decoders
|
||||||
SetA32("111100111x11xx01xxxx0x111xx0xxxx", InstName.Vneg, InstEmit32.Vneg_V, typeof(OpCode32Simd));
|
SetA32("111100111x11xx01xxxx0x111xx0xxxx", InstName.Vneg, InstEmit32.Vneg_V, typeof(OpCode32Simd));
|
||||||
SetA32("<<<<11101x110001xxxx10xx01x0xxxx", InstName.Vneg, InstEmit32.Vneg_S, typeof(OpCode32SimdS));
|
SetA32("<<<<11101x110001xxxx10xx01x0xxxx", InstName.Vneg, InstEmit32.Vneg_S, typeof(OpCode32SimdS));
|
||||||
|
|
||||||
|
SetA32("111111100xxxxxxxxxxx10xxx0x0xxxx", InstName.Vsel, InstEmit32.Vsel, typeof(OpCode32SimdSel));
|
||||||
|
|
||||||
SetA32("111101001x00xxxxxxxx0000xxxxxxxx", InstName.Vst1, InstEmit32.Vst1, typeof(OpCode32SimdMemSingle));
|
SetA32("111101001x00xxxxxxxx0000xxxxxxxx", InstName.Vst1, InstEmit32.Vst1, typeof(OpCode32SimdMemSingle));
|
||||||
SetA32("111101001x00xxxxxxxx0100xxxxxxxx", InstName.Vst1, InstEmit32.Vst1, typeof(OpCode32SimdMemSingle));
|
SetA32("111101001x00xxxxxxxx0100xxxxxxxx", InstName.Vst1, InstEmit32.Vst1, typeof(OpCode32SimdMemSingle));
|
||||||
SetA32("111101001x00xxxxxxxx1000xxxxxxxx", InstName.Vst1, InstEmit32.Vst1, typeof(OpCode32SimdMemSingle));
|
SetA32("111101001x00xxxxxxxx1000xxxxxxxx", InstName.Vst1, InstEmit32.Vst1, typeof(OpCode32SimdMemSingle));
|
||||||
|
|
|
@ -523,6 +523,19 @@ namespace ARMeilleure.Instructions
|
||||||
SetIntA32(context, op.Rd, res);
|
SetIntA32(context, op.Rd, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void Sbfx(ArmEmitterContext context)
|
||||||
|
{
|
||||||
|
OpCode32AluBf op = (OpCode32AluBf)context.CurrOp;
|
||||||
|
|
||||||
|
var msb = op.Lsb + op.Msb; //for this instruction, the msb is actually a width
|
||||||
|
var mask = (int)(0xFFFFFFFF >> (31 - msb)) << op.Lsb;
|
||||||
|
|
||||||
|
Operand n = GetIntOrZR(context, op.Rn);
|
||||||
|
Operand res = context.ShiftRightSI(context.ShiftLeft(n, Const(31 - msb)), Const(31 - op.Msb));
|
||||||
|
|
||||||
|
SetIntA32(context, op.Rd, res);
|
||||||
|
}
|
||||||
|
|
||||||
private static void EmitAluStore(ArmEmitterContext context, Operand value)
|
private static void EmitAluStore(ArmEmitterContext context, Operand value)
|
||||||
{
|
{
|
||||||
IOpCode32Alu op = (IOpCode32Alu)context.CurrOp;
|
IOpCode32Alu op = (IOpCode32Alu)context.CurrOp;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using ARMeilleure.Decoders;
|
using ARMeilleure.Decoders;
|
||||||
|
using ARMeilleure.IntermediateRepresentation;
|
||||||
using ARMeilleure.Translation;
|
using ARMeilleure.Translation;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
@ -7,6 +8,7 @@ using System.Text;
|
||||||
using static ARMeilleure.Instructions.InstEmitHelper;
|
using static ARMeilleure.Instructions.InstEmitHelper;
|
||||||
using static ARMeilleure.Instructions.InstEmitSimdHelper;
|
using static ARMeilleure.Instructions.InstEmitSimdHelper;
|
||||||
using static ARMeilleure.Instructions.InstEmitSimdHelper32;
|
using static ARMeilleure.Instructions.InstEmitSimdHelper32;
|
||||||
|
using static ARMeilleure.Instructions.InstEmitFlowHelper;
|
||||||
using static ARMeilleure.IntermediateRepresentation.OperandHelper;
|
using static ARMeilleure.IntermediateRepresentation.OperandHelper;
|
||||||
|
|
||||||
namespace ARMeilleure.Instructions
|
namespace ARMeilleure.Instructions
|
||||||
|
@ -81,6 +83,23 @@ namespace ARMeilleure.Instructions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//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)
|
||||||
|
{
|
||||||
|
bool max = (context.CurrOp.RawOpCode & (1 << 6)) == 0;
|
||||||
|
Delegate dlg = max ? new _F32_F32_F32(Math.Max) : new _F32_F32_F32(Math.Min);
|
||||||
|
|
||||||
|
EmitScalarBinaryOpF32(context, (op1, op2) => context.Call(dlg, op1, op2));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void VmaxminNm_V(ArmEmitterContext context)
|
||||||
|
{
|
||||||
|
bool max = (context.CurrOp.RawOpCode & (1 << 21)) == 0;
|
||||||
|
Delegate dlg = max ? new _F32_F32_F32(Math.Max) : new _F32_F32_F32(Math.Min);
|
||||||
|
|
||||||
|
EmitVectorBinaryOpSx32(context, (op1, op2) => context.Call(dlg, op1, op2));
|
||||||
|
}
|
||||||
|
|
||||||
public static void Vmul_S(ArmEmitterContext context)
|
public static void Vmul_S(ArmEmitterContext context)
|
||||||
{
|
{
|
||||||
if (Optimizations.FastFP)
|
if (Optimizations.FastFP)
|
||||||
|
@ -192,6 +211,31 @@ namespace ARMeilleure.Instructions
|
||||||
EmitVectorTernaryOpZx32(context, (op1, op2, op3) => context.Subtract(op1, context.Multiply(op2, op3)));
|
EmitVectorTernaryOpZx32(context, (op1, op2, op3) => context.Subtract(op1, context.Multiply(op2, op3)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void Vsel(ArmEmitterContext context)
|
||||||
|
{
|
||||||
|
var op = (OpCode32SimdSel)context.CurrOp;
|
||||||
|
EmitScalarBinaryOpI32(context, (op1, op2) =>
|
||||||
|
{
|
||||||
|
Operand condition = null;
|
||||||
|
switch (op.Cc)
|
||||||
|
{
|
||||||
|
case OpCode32SimdSelMode.Eq:
|
||||||
|
condition = GetCondTrue(context, Condition.Eq);
|
||||||
|
break;
|
||||||
|
case OpCode32SimdSelMode.Ge:
|
||||||
|
condition = GetCondTrue(context, Condition.Ge);
|
||||||
|
break;
|
||||||
|
case OpCode32SimdSelMode.Gt:
|
||||||
|
condition = GetCondTrue(context, Condition.Gt);
|
||||||
|
break;
|
||||||
|
case OpCode32SimdSelMode.Vs:
|
||||||
|
condition = GetCondTrue(context, Condition.Vs);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return context.ConditionalSelect(condition, op1, op2);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public static void Vsqrt_S(ArmEmitterContext context)
|
public static void Vsqrt_S(ArmEmitterContext context)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -34,7 +34,7 @@ namespace ARMeilleure.Instructions
|
||||||
|
|
||||||
public static Operand ExtractScalar(ArmEmitterContext context, OperandType type, int reg)
|
public static Operand ExtractScalar(ArmEmitterContext context, OperandType type, int reg)
|
||||||
{
|
{
|
||||||
if (type == OperandType.FP64)
|
if (type == OperandType.FP64 || type == OperandType.I64)
|
||||||
{
|
{
|
||||||
// from dreg
|
// from dreg
|
||||||
return context.VectorExtract(type, GetVecA32(reg >> 1), reg & 1);
|
return context.VectorExtract(type, GetVecA32(reg >> 1), reg & 1);
|
||||||
|
@ -49,7 +49,7 @@ namespace ARMeilleure.Instructions
|
||||||
public static void InsertScalar(ArmEmitterContext context, int reg, Operand value)
|
public static void InsertScalar(ArmEmitterContext context, int reg, Operand value)
|
||||||
{
|
{
|
||||||
Operand vec, insert;
|
Operand vec, insert;
|
||||||
if (value.Type == OperandType.FP64)
|
if (value.Type == OperandType.FP64 || value.Type == OperandType.I64)
|
||||||
{
|
{
|
||||||
// from dreg
|
// from dreg
|
||||||
vec = GetVecA32(reg >> 1);
|
vec = GetVecA32(reg >> 1);
|
||||||
|
@ -107,6 +107,19 @@ namespace ARMeilleure.Instructions
|
||||||
|
|
||||||
InsertScalar(context, op.Vd, emit(n, m));
|
InsertScalar(context, op.Vd, emit(n, m));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void EmitScalarBinaryOpI32(ArmEmitterContext context, Func2I emit)
|
||||||
|
{
|
||||||
|
OpCode32SimdRegS op = (OpCode32SimdRegS)context.CurrOp;
|
||||||
|
|
||||||
|
OperandType type = (op.Size & 1) != 0 ? OperandType.I64 : OperandType.I32;
|
||||||
|
|
||||||
|
Operand n = ExtractScalar(context, type, op.Vn);
|
||||||
|
Operand m = ExtractScalar(context, type, op.Vm);
|
||||||
|
|
||||||
|
InsertScalar(context, op.Vd, emit(n, m));
|
||||||
|
}
|
||||||
|
|
||||||
public static void EmitScalarTernaryOpF32(ArmEmitterContext context, Func3I emit)
|
public static void EmitScalarTernaryOpF32(ArmEmitterContext context, Func3I emit)
|
||||||
{
|
{
|
||||||
OpCode32SimdRegS op = (OpCode32SimdRegS)context.CurrOp;
|
OpCode32SimdRegS op = (OpCode32SimdRegS)context.CurrOp;
|
||||||
|
|
|
@ -481,6 +481,7 @@ namespace ARMeilleure.Instructions
|
||||||
Mvn,
|
Mvn,
|
||||||
Rsb,
|
Rsb,
|
||||||
Rsc,
|
Rsc,
|
||||||
|
Sbfx,
|
||||||
Smlab,
|
Smlab,
|
||||||
Smlal,
|
Smlal,
|
||||||
Smmul,
|
Smmul,
|
||||||
|
@ -519,12 +520,14 @@ namespace ARMeilleure.Instructions
|
||||||
Vld4,
|
Vld4,
|
||||||
Vldm,
|
Vldm,
|
||||||
Vldr,
|
Vldr,
|
||||||
|
VMMmn,
|
||||||
Vmla,
|
Vmla,
|
||||||
Vmls,
|
Vmls,
|
||||||
Vmrs,
|
Vmrs,
|
||||||
Vmsr,
|
Vmsr,
|
||||||
Vmul,
|
Vmul,
|
||||||
Vneg,
|
Vneg,
|
||||||
|
Vsel,
|
||||||
Vst1,
|
Vst1,
|
||||||
Vst2,
|
Vst2,
|
||||||
Vst3,
|
Vst3,
|
||||||
|
|
|
@ -205,6 +205,11 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
||||||
return MapSharedMemory(handle, address, size, permission);
|
return MapSharedMemory(handle, address, size, permission);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public KernelResult MapSharedMemory32([R(0)] int handle, [R(1)] uint address, [R(2)] uint size, [R(3)] MemoryPermission permission)
|
||||||
|
{
|
||||||
|
return MapSharedMemory(handle, address, size, permission);
|
||||||
|
}
|
||||||
|
|
||||||
private KernelResult MapSharedMemory(int handle, ulong address, ulong size, MemoryPermission permission)
|
private KernelResult MapSharedMemory(int handle, ulong address, ulong size, MemoryPermission permission)
|
||||||
{
|
{
|
||||||
if (!PageAligned(address))
|
if (!PageAligned(address))
|
||||||
|
@ -256,6 +261,11 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
||||||
return UnmapSharedMemory(handle, address, size);
|
return UnmapSharedMemory(handle, address, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public KernelResult UnmapSharedMemory32([R(0)] int handle, [R(1)] uint address, [R(2)] uint size)
|
||||||
|
{
|
||||||
|
return UnmapSharedMemory(handle, address, size);
|
||||||
|
}
|
||||||
|
|
||||||
private KernelResult UnmapSharedMemory(int handle, ulong address, ulong size)
|
private KernelResult UnmapSharedMemory(int handle, ulong address, ulong size)
|
||||||
{
|
{
|
||||||
if (!PageAligned(address))
|
if (!PageAligned(address))
|
||||||
|
|
|
@ -659,5 +659,16 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
||||||
|
|
||||||
return KernelResult.Success;
|
return KernelResult.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public KernelResult FlushProcessDataCache32(
|
||||||
|
[R(0)] uint processHandle,
|
||||||
|
[R(2)] uint addressLow,
|
||||||
|
[R(3)] uint addressHigh,
|
||||||
|
[R(1)] uint sizeLow,
|
||||||
|
[R(4)] uint sizeHigh)
|
||||||
|
{
|
||||||
|
_process.CpuMemory.WriteBytes(addressLow, new byte[sizeLow]);
|
||||||
|
return KernelResult.Success;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,16 +99,23 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
||||||
{ 0x0d, nameof(SvcHandler.SetThreadPriority32) },
|
{ 0x0d, nameof(SvcHandler.SetThreadPriority32) },
|
||||||
{ 0x0f, nameof(SvcHandler.SetThreadCoreMask32) },
|
{ 0x0f, nameof(SvcHandler.SetThreadCoreMask32) },
|
||||||
{ 0x10, nameof(SvcHandler.GetCurrentProcessorNumber32) },
|
{ 0x10, nameof(SvcHandler.GetCurrentProcessorNumber32) },
|
||||||
|
{ 0x13, nameof(SvcHandler.MapSharedMemory32) },
|
||||||
|
{ 0x14, nameof(SvcHandler.UnmapSharedMemory32) },
|
||||||
{ 0x15, nameof(SvcHandler.CreateTransferMemory32) },
|
{ 0x15, nameof(SvcHandler.CreateTransferMemory32) },
|
||||||
{ 0x16, nameof(SvcHandler.CloseHandle32) },
|
{ 0x16, nameof(SvcHandler.CloseHandle32) },
|
||||||
{ 0x18, nameof(SvcHandler.WaitSynchronization32) },
|
{ 0x18, nameof(SvcHandler.WaitSynchronization32) },
|
||||||
|
{ 0x1a, nameof(SvcHandler.ArbitrateLock32) },
|
||||||
|
{ 0x1b, nameof(SvcHandler.ArbitrateUnlock32) },
|
||||||
|
{ 0x1c, nameof(SvcHandler.WaitProcessWideKeyAtomic32) },
|
||||||
{ 0x1d, nameof(SvcHandler.SignalProcessWideKey32) },
|
{ 0x1d, nameof(SvcHandler.SignalProcessWideKey32) },
|
||||||
{ 0x1f, nameof(SvcHandler.ConnectToNamedPort32) },
|
{ 0x1f, nameof(SvcHandler.ConnectToNamedPort32) },
|
||||||
{ 0x21, nameof(SvcHandler.SendSyncRequest32) },
|
{ 0x21, nameof(SvcHandler.SendSyncRequest32) },
|
||||||
{ 0x25, nameof(SvcHandler.GetThreadId32) },
|
{ 0x25, nameof(SvcHandler.GetThreadId32) },
|
||||||
{ 0x26, nameof(SvcHandler.Break32) },
|
{ 0x26, nameof(SvcHandler.Break32) },
|
||||||
{ 0x27, nameof(SvcHandler.OutputDebugString32) },
|
{ 0x27, nameof(SvcHandler.OutputDebugString32) },
|
||||||
{ 0x29, nameof(SvcHandler.GetInfo32) }
|
{ 0x29, nameof(SvcHandler.GetInfo32) },
|
||||||
|
|
||||||
|
{ 0x5F, nameof(SvcHandler.FlushProcessDataCache32) }
|
||||||
};
|
};
|
||||||
|
|
||||||
_svcTable64 = new Action<SvcHandler, ExecutionContext>[0x80];
|
_svcTable64 = new Action<SvcHandler, ExecutionContext>[0x80];
|
||||||
|
@ -126,8 +133,6 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
||||||
Dictionary<int, string> funcTable = aarch32 ? _svcFuncs32 : _svcFuncs64;
|
Dictionary<int, string> funcTable = aarch32 ? _svcFuncs32 : _svcFuncs64;
|
||||||
if (funcTable.TryGetValue(svcId, out string svcName))
|
if (funcTable.TryGetValue(svcId, out string svcName))
|
||||||
{
|
{
|
||||||
if (svcId == 0x08) { }
|
|
||||||
|
|
||||||
Action<SvcHandler, ExecutionContext> svcFunc;
|
Action<SvcHandler, ExecutionContext> svcFunc;
|
||||||
|
|
||||||
if (aarch32)
|
if (aarch32)
|
||||||
|
|
|
@ -76,6 +76,11 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
||||||
return ArbitrateLock(ownerHandle, mutexAddress, requesterHandle);
|
return ArbitrateLock(ownerHandle, mutexAddress, requesterHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public KernelResult ArbitrateLock32([R(0)] int ownerHandle, [R(1)] ulong mutexAddress, [R(2)] int requesterHandle)
|
||||||
|
{
|
||||||
|
return ArbitrateLock(ownerHandle, mutexAddress, requesterHandle);
|
||||||
|
}
|
||||||
|
|
||||||
private KernelResult ArbitrateLock(int ownerHandle, ulong mutexAddress, int requesterHandle)
|
private KernelResult ArbitrateLock(int ownerHandle, ulong mutexAddress, int requesterHandle)
|
||||||
{
|
{
|
||||||
if (IsPointingInsideKernel(mutexAddress))
|
if (IsPointingInsideKernel(mutexAddress))
|
||||||
|
@ -98,6 +103,11 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
||||||
return ArbitrateUnlock(mutexAddress);
|
return ArbitrateUnlock(mutexAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public KernelResult ArbitrateUnlock32([R(0)] uint mutexAddress)
|
||||||
|
{
|
||||||
|
return ArbitrateUnlock(mutexAddress);
|
||||||
|
}
|
||||||
|
|
||||||
private KernelResult ArbitrateUnlock(ulong mutexAddress)
|
private KernelResult ArbitrateUnlock(ulong mutexAddress)
|
||||||
{
|
{
|
||||||
if (IsPointingInsideKernel(mutexAddress))
|
if (IsPointingInsideKernel(mutexAddress))
|
||||||
|
@ -124,6 +134,17 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
||||||
return WaitProcessWideKeyAtomic(mutexAddress, condVarAddress, handle, timeout);
|
return WaitProcessWideKeyAtomic(mutexAddress, condVarAddress, handle, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public KernelResult WaitProcessWideKeyAtomic32(
|
||||||
|
[R(0)] uint mutexAddress,
|
||||||
|
[R(1)] uint condVarAddress,
|
||||||
|
[R(2)] int handle,
|
||||||
|
[R(3)] uint timeoutLow,
|
||||||
|
[R(4)] uint timeoutHigh)
|
||||||
|
{
|
||||||
|
long timeout = (long)(timeoutLow | ((ulong)timeoutHigh << 32));
|
||||||
|
return WaitProcessWideKeyAtomic(mutexAddress, condVarAddress, handle, timeout);
|
||||||
|
}
|
||||||
|
|
||||||
private KernelResult WaitProcessWideKeyAtomic(
|
private KernelResult WaitProcessWideKeyAtomic(
|
||||||
ulong mutexAddress,
|
ulong mutexAddress,
|
||||||
ulong condVarAddress,
|
ulong condVarAddress,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue