mirror of
https://github.com/par274/sharpemu.git
synced 2026-07-26 04:39:17 +08:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9cdc8550ec | |||
| d6fccedab8 | |||
| fed7a6d062 |
@@ -621,6 +621,8 @@ internal static class Gen5ShaderTranslator
|
||||
0x10 => "SSendmsg",
|
||||
0x16 => "STtraceData",
|
||||
0x20 => "SInstPrefetch",
|
||||
0x21 => "SClause",
|
||||
0x23 => "SWaitcntDepctr",
|
||||
_ => string.Empty,
|
||||
};
|
||||
|
||||
|
||||
@@ -1136,6 +1136,52 @@ internal static partial class Gen5SpirvTranslator
|
||||
left,
|
||||
right);
|
||||
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":
|
||||
result = BitwiseAnd(left, right);
|
||||
Store(_scc, IsNotZero(result));
|
||||
|
||||
@@ -349,7 +349,32 @@ public static class KernelPthreadCompatExports
|
||||
ExportName = "pthread_cond_timedwait",
|
||||
Target = Generation.Gen4 | Generation.Gen5,
|
||||
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(
|
||||
Nid = "kDh-NfxgMtE",
|
||||
@@ -1185,10 +1210,19 @@ public static class KernelPthreadCompatExports
|
||||
|
||||
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);
|
||||
TracePthreadCond("wait-wake-pending", condAddress, mutexAddress, state, timed, waitResult);
|
||||
var pendingLockResult = PthreadMutexRelockForCondWait(ctx, mutexAddress, releasedRecursion);
|
||||
return pendingLockResult != (int)OrbisGen2Result.ORBIS_GEN2_OK ? pendingLockResult : waitResult;
|
||||
Monitor.Exit(state.SyncRoot);
|
||||
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;
|
||||
|
||||
Reference in New Issue
Block a user