mirror of
https://github.com/par274/sharpemu.git
synced 2026-07-28 13:40:58 +08:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9cdc8550ec | |||
| d6fccedab8 | |||
| fed7a6d062 |
@@ -621,6 +621,8 @@ internal static class Gen5ShaderTranslator
|
|||||||
0x10 => "SSendmsg",
|
0x10 => "SSendmsg",
|
||||||
0x16 => "STtraceData",
|
0x16 => "STtraceData",
|
||||||
0x20 => "SInstPrefetch",
|
0x20 => "SInstPrefetch",
|
||||||
|
0x21 => "SClause",
|
||||||
|
0x23 => "SWaitcntDepctr",
|
||||||
_ => string.Empty,
|
_ => string.Empty,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1136,6 +1136,52 @@ internal static partial class Gen5SpirvTranslator
|
|||||||
left,
|
left,
|
||||||
right);
|
right);
|
||||||
break;
|
break;
|
||||||
|
case "SMulHiU32":
|
||||||
|
{
|
||||||
|
var wideLeft = _module.AddInstruction(
|
||||||
|
SpirvOp.UConvert,
|
||||||
|
_ulongType,
|
||||||
|
left);
|
||||||
|
var wideRight = _module.AddInstruction(
|
||||||
|
SpirvOp.UConvert,
|
||||||
|
_ulongType,
|
||||||
|
right);
|
||||||
|
var product = _module.AddInstruction(
|
||||||
|
SpirvOp.IMul,
|
||||||
|
_ulongType,
|
||||||
|
wideLeft,
|
||||||
|
wideRight);
|
||||||
|
result = _module.AddInstruction(
|
||||||
|
SpirvOp.UConvert,
|
||||||
|
_uintType,
|
||||||
|
ShiftRightLogical64(
|
||||||
|
product,
|
||||||
|
_module.Constant64(_ulongType, 32)));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "SMulHiI32":
|
||||||
|
{
|
||||||
|
var wideLeft = _module.AddInstruction(
|
||||||
|
SpirvOp.SConvert,
|
||||||
|
_longType,
|
||||||
|
Bitcast(_intType, left));
|
||||||
|
var wideRight = _module.AddInstruction(
|
||||||
|
SpirvOp.SConvert,
|
||||||
|
_longType,
|
||||||
|
Bitcast(_intType, right));
|
||||||
|
var product = _module.AddInstruction(
|
||||||
|
SpirvOp.IMul,
|
||||||
|
_longType,
|
||||||
|
wideLeft,
|
||||||
|
wideRight);
|
||||||
|
result = _module.AddInstruction(
|
||||||
|
SpirvOp.UConvert,
|
||||||
|
_uintType,
|
||||||
|
ShiftRightLogical64(
|
||||||
|
Bitcast(_ulongType, product),
|
||||||
|
_module.Constant64(_ulongType, 32)));
|
||||||
|
break;
|
||||||
|
}
|
||||||
case "SAndB32":
|
case "SAndB32":
|
||||||
result = BitwiseAnd(left, right);
|
result = BitwiseAnd(left, right);
|
||||||
Store(_scc, IsNotZero(result));
|
Store(_scc, IsNotZero(result));
|
||||||
|
|||||||
@@ -349,7 +349,32 @@ public static class KernelPthreadCompatExports
|
|||||||
ExportName = "pthread_cond_timedwait",
|
ExportName = "pthread_cond_timedwait",
|
||||||
Target = Generation.Gen4 | Generation.Gen5,
|
Target = Generation.Gen4 | Generation.Gen5,
|
||||||
LibraryName = "libKernel")]
|
LibraryName = "libKernel")]
|
||||||
public static int PosixPthreadCondTimedwait(CpuContext ctx) => PthreadCondTimedwait(ctx);
|
public static int PosixPthreadCondTimedwait(CpuContext ctx)
|
||||||
|
{
|
||||||
|
// POSIX passes `const struct timespec *abstime` (absolute deadline), not relative microseconds (#113).
|
||||||
|
var abstimeAddress = ctx[CpuRegister.Rdx];
|
||||||
|
if (abstimeAddress == 0)
|
||||||
|
{
|
||||||
|
return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ctx.TryReadUInt64(abstimeAddress, out var deadlineSeconds) ||
|
||||||
|
!ctx.TryReadUInt64(abstimeAddress + 8, out var deadlineNanoseconds))
|
||||||
|
{
|
||||||
|
return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
var nowMicroseconds = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() * 1000L;
|
||||||
|
var deadlineMicroseconds =
|
||||||
|
deadlineSeconds >= long.MaxValue / 1_000_000UL
|
||||||
|
? long.MaxValue
|
||||||
|
: (long)(deadlineSeconds * 1_000_000UL + Math.Min(deadlineNanoseconds, 999_999_999UL) / 1000UL);
|
||||||
|
var remainingMicroseconds = deadlineMicroseconds - nowMicroseconds;
|
||||||
|
var timeoutUsec = remainingMicroseconds <= 0
|
||||||
|
? 1u
|
||||||
|
: (uint)Math.Min(remainingMicroseconds, uint.MaxValue);
|
||||||
|
return PthreadCondWaitCore(ctx, ctx[CpuRegister.Rdi], ctx[CpuRegister.Rsi], timed: true, timeoutUsec: timeoutUsec);
|
||||||
|
}
|
||||||
|
|
||||||
[SysAbiExport(
|
[SysAbiExport(
|
||||||
Nid = "kDh-NfxgMtE",
|
Nid = "kDh-NfxgMtE",
|
||||||
@@ -1185,10 +1210,19 @@ public static class KernelPthreadCompatExports
|
|||||||
|
|
||||||
if (consumedPendingSignal)
|
if (consumedPendingSignal)
|
||||||
{
|
{
|
||||||
|
// Leave SyncRoot before relocking the mutex to avoid lock-order inversion with cond-signal (#113).
|
||||||
state.Waiters = Math.Max(0, state.Waiters - 1);
|
state.Waiters = Math.Max(0, state.Waiters - 1);
|
||||||
TracePthreadCond("wait-wake-pending", condAddress, mutexAddress, state, timed, waitResult);
|
TracePthreadCond("wait-wake-pending", condAddress, mutexAddress, state, timed, waitResult);
|
||||||
var pendingLockResult = PthreadMutexRelockForCondWait(ctx, mutexAddress, releasedRecursion);
|
Monitor.Exit(state.SyncRoot);
|
||||||
return pendingLockResult != (int)OrbisGen2Result.ORBIS_GEN2_OK ? pendingLockResult : waitResult;
|
try
|
||||||
|
{
|
||||||
|
var pendingLockResult = PthreadMutexRelockForCondWait(ctx, mutexAddress, releasedRecursion);
|
||||||
|
return pendingLockResult != (int)OrbisGen2Result.ORBIS_GEN2_OK ? pendingLockResult : waitResult;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
Monitor.Enter(state.SyncRoot);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var scheduler = GuestThreadExecution.Scheduler;
|
var scheduler = GuestThreadExecution.Scheduler;
|
||||||
|
|||||||
Reference in New Issue
Block a user