Fix ~3500 analyser issues

See merge request ryubing/ryujinx!44
This commit is contained in:
MrKev 2025-05-30 17:08:34 -05:00 committed by LotP
parent 417df486b1
commit 361d0c5632
622 changed files with 3080 additions and 2652 deletions

View file

@ -254,7 +254,7 @@ namespace ARMeilleure.CodeGen.Arm64
private static bool IsMemoryLoadOrStore(Instruction inst)
{
return inst == Instruction.Load || inst == Instruction.Store;
return inst is Instruction.Load or Instruction.Store;
}
private static bool ConstTooLong(Operand constOp, OperandType accessType)

View file

@ -774,6 +774,7 @@ namespace ARMeilleure.CodeGen.Arm64
instI |= 1 << 22; // sh flag
imm >>= 12;
}
WriteInstructionAuto(instI | (EncodeUImm12(imm, 0) << 10), rd, rn);
}
else

View file

@ -52,7 +52,7 @@ namespace ARMeilleure.CodeGen.Arm64
// Any value AND all ones will be equal itself, so it's effectively a no-op.
// Any value OR all ones will be equal all ones, so one can just use MOV.
// Any value XOR all ones will be equal its inverse, so one can just use MVN.
if (value == 0 || value == ulong.MaxValue)
if (value is 0 or ulong.MaxValue)
{
immN = 0;
immS = 0;

View file

@ -1,6 +1,7 @@
using ARMeilleure.CodeGen.Linking;
using ARMeilleure.CodeGen.RegisterAllocators;
using ARMeilleure.IntermediateRepresentation;
using Microsoft.IO;
using Ryujinx.Common.Memory;
using System;
using System.Collections.Generic;
@ -14,7 +15,7 @@ namespace ARMeilleure.CodeGen.Arm64
private const int CbnzInstLength = 4;
private const int LdrLitInstLength = 4;
private readonly Stream _stream;
private readonly RecyclableMemoryStream _stream;
public int StreamOffset => (int)_stream.Length;

View file

@ -189,8 +189,8 @@ namespace ARMeilleure.CodeGen.Arm64
// The only blocks which can have 0 successors are exit blocks.
Operation last = block.Operations.Last;
Debug.Assert(last.Instruction == Instruction.Tailcall ||
last.Instruction == Instruction.Return);
Debug.Assert(last.Instruction is Instruction.Tailcall or
Instruction.Return);
}
else
{
@ -464,7 +464,7 @@ namespace ARMeilleure.CodeGen.Arm64
Operand dest = operation.Destination;
Operand source = operation.GetSource(0);
Debug.Assert(dest.Type == OperandType.FP32 || dest.Type == OperandType.FP64);
Debug.Assert(dest.Type is OperandType.FP32 or OperandType.FP64);
Debug.Assert(dest.Type != source.Type);
Debug.Assert(source.Type != OperandType.V128);
@ -483,7 +483,7 @@ namespace ARMeilleure.CodeGen.Arm64
Operand dest = operation.Destination;
Operand source = operation.GetSource(0);
Debug.Assert(dest.Type == OperandType.FP32 || dest.Type == OperandType.FP64);
Debug.Assert(dest.Type is OperandType.FP32 or OperandType.FP64);
Debug.Assert(dest.Type != source.Type);
Debug.Assert(source.Type.IsInteger());
@ -1463,7 +1463,7 @@ namespace ARMeilleure.CodeGen.Arm64
private static bool IsLoadOrStore(Operation operation)
{
return operation.Instruction == Instruction.Load || operation.Instruction == Instruction.Store;
return operation.Instruction is Instruction.Load or Instruction.Store;
}
private static OperandType GetMemOpValueType(Operation operation)
@ -1499,6 +1499,7 @@ namespace ARMeilleure.CodeGen.Arm64
return false;
}
}
if (memOp.Index != default)
{
return false;
@ -1553,7 +1554,7 @@ namespace ARMeilleure.CodeGen.Arm64
private static void EnsureSameReg(Operand op1, Operand op2)
{
Debug.Assert(op1.Kind == OperandKind.Register || op1.Kind == OperandKind.Memory);
Debug.Assert(op1.Kind is OperandKind.Register or OperandKind.Memory);
Debug.Assert(op1.Kind == op2.Kind);
Debug.Assert(op1.Value == op2.Value);
}

View file

@ -509,7 +509,6 @@ namespace ARMeilleure.CodeGen.Arm64
context.Assembler.WriteInstruction(instruction, rd, rn);
}
}
private static void GenerateScalarTernary(

View file

@ -137,6 +137,7 @@ namespace ARMeilleure.CodeGen.Arm64
{
return val != 0;
}
return false;
}

View file

@ -736,19 +736,19 @@ namespace ARMeilleure.CodeGen.Arm64
{
IntrinsicInfo info = IntrinsicTable.GetInfo(intrinsic & ~(Intrinsic.Arm64VTypeMask | Intrinsic.Arm64VSizeMask));
return info.Type == IntrinsicType.ScalarBinaryRd ||
info.Type == IntrinsicType.ScalarTernaryFPRdByElem ||
info.Type == IntrinsicType.ScalarTernaryShlRd ||
info.Type == IntrinsicType.ScalarTernaryShrRd ||
info.Type == IntrinsicType.Vector128BinaryRd ||
info.Type == IntrinsicType.VectorBinaryRd ||
info.Type == IntrinsicType.VectorInsertByElem ||
info.Type == IntrinsicType.VectorTernaryRd ||
info.Type == IntrinsicType.VectorTernaryRdBitwise ||
info.Type == IntrinsicType.VectorTernaryFPRdByElem ||
info.Type == IntrinsicType.VectorTernaryRdByElem ||
info.Type == IntrinsicType.VectorTernaryShlRd ||
info.Type == IntrinsicType.VectorTernaryShrRd;
return info.Type is IntrinsicType.ScalarBinaryRd or
IntrinsicType.ScalarTernaryFPRdByElem or
IntrinsicType.ScalarTernaryShlRd or
IntrinsicType.ScalarTernaryShrRd or
IntrinsicType.Vector128BinaryRd or
IntrinsicType.VectorBinaryRd or
IntrinsicType.VectorInsertByElem or
IntrinsicType.VectorTernaryRd or
IntrinsicType.VectorTernaryRdBitwise or
IntrinsicType.VectorTernaryFPRdByElem or
IntrinsicType.VectorTernaryRdByElem or
IntrinsicType.VectorTernaryShlRd or
IntrinsicType.VectorTernaryShrRd;
}
private static bool HasConstSrc1(Operation node, ulong value)
@ -849,7 +849,7 @@ namespace ARMeilleure.CodeGen.Arm64
Comparison compType = (Comparison)comp.AsInt32();
return compType == Comparison.Equal || compType == Comparison.NotEqual;
return compType is Comparison.Equal or Comparison.NotEqual;
}
}
@ -871,9 +871,9 @@ namespace ARMeilleure.CodeGen.Arm64
IntrinsicInfo info = IntrinsicTable.GetInfo(intrinsic & ~(Intrinsic.Arm64VTypeMask | Intrinsic.Arm64VSizeMask));
// Those have integer inputs that don't support consts.
return info.Type != IntrinsicType.ScalarFPConvGpr &&
info.Type != IntrinsicType.ScalarFPConvFixedGpr &&
info.Type != IntrinsicType.SetRegister;
return info.Type is not IntrinsicType.ScalarFPConvGpr and
not IntrinsicType.ScalarFPConvFixedGpr and
not IntrinsicType.SetRegister;
}
return false;

View file

@ -37,6 +37,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{
EvaluateBinaryI64(operation, (x, y) => x + y);
}
break;
case Instruction.BitwiseAnd:
@ -48,6 +49,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{
EvaluateBinaryI64(operation, (x, y) => x & y);
}
break;
case Instruction.BitwiseExclusiveOr:
@ -59,6 +61,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{
EvaluateBinaryI64(operation, (x, y) => x ^ y);
}
break;
case Instruction.BitwiseNot:
@ -70,6 +73,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{
EvaluateUnaryI64(operation, (x) => ~x);
}
break;
case Instruction.BitwiseOr:
@ -81,6 +85,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{
EvaluateBinaryI64(operation, (x, y) => x | y);
}
break;
case Instruction.ConvertI64ToI32:
@ -88,6 +93,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{
EvaluateUnaryI32(operation, (x) => x);
}
break;
case Instruction.Compare:
@ -129,6 +135,7 @@ namespace ARMeilleure.CodeGen.Optimizations
break;
}
}
break;
case Instruction.Copy:
@ -140,6 +147,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{
EvaluateUnaryI64(operation, (x) => x);
}
break;
case Instruction.Divide:
@ -151,6 +159,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{
EvaluateBinaryI64(operation, (x, y) => y != 0 ? x / y : 0);
}
break;
case Instruction.DivideUI:
@ -162,6 +171,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{
EvaluateBinaryI64(operation, (x, y) => y != 0 ? (long)((ulong)x / (ulong)y) : 0);
}
break;
case Instruction.Multiply:
@ -173,6 +183,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{
EvaluateBinaryI64(operation, (x, y) => x * y);
}
break;
case Instruction.Negate:
@ -184,6 +195,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{
EvaluateUnaryI64(operation, (x) => -x);
}
break;
case Instruction.ShiftLeft:
@ -195,6 +207,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{
EvaluateBinaryI64(operation, (x, y) => x << (int)y);
}
break;
case Instruction.ShiftRightSI:
@ -206,6 +219,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{
EvaluateBinaryI64(operation, (x, y) => x >> (int)y);
}
break;
case Instruction.ShiftRightUI:
@ -217,6 +231,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{
EvaluateBinaryI64(operation, (x, y) => (long)((ulong)x >> (int)y));
}
break;
case Instruction.SignExtend16:
@ -228,6 +243,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{
EvaluateUnaryI64(operation, (x) => (short)x);
}
break;
case Instruction.SignExtend32:
@ -239,6 +255,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{
EvaluateUnaryI64(operation, (x) => (int)x);
}
break;
case Instruction.SignExtend8:
@ -250,6 +267,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{
EvaluateUnaryI64(operation, (x) => (sbyte)x);
}
break;
case Instruction.ZeroExtend16:
@ -261,6 +279,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{
EvaluateUnaryI64(operation, (x) => (ushort)x);
}
break;
case Instruction.ZeroExtend32:
@ -272,6 +291,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{
EvaluateUnaryI64(operation, (x) => (uint)x);
}
break;
case Instruction.ZeroExtend8:
@ -283,6 +303,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{
EvaluateUnaryI64(operation, (x) => (byte)x);
}
break;
case Instruction.Subtract:
@ -294,6 +315,7 @@ namespace ARMeilleure.CodeGen.Optimizations
{
EvaluateBinaryI64(operation, (x, y) => x - y);
}
break;
}
}

View file

@ -227,11 +227,11 @@ namespace ARMeilleure.CodeGen.Optimizations
private static bool HasSideEffects(Operation node)
{
return node.Instruction == Instruction.Call
|| node.Instruction == Instruction.Tailcall
|| node.Instruction == Instruction.CompareAndSwap
|| node.Instruction == Instruction.CompareAndSwap16
|| node.Instruction == Instruction.CompareAndSwap8;
return node.Instruction is Instruction.Call
or Instruction.Tailcall
or Instruction.CompareAndSwap
or Instruction.CompareAndSwap16
or Instruction.CompareAndSwap8;
}
private static bool IsPropagableCompare(Operation operation)

View file

@ -847,7 +847,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
// If this is a copy (or copy-like operation), set the copy source interval as well.
// This is used for register preferencing later on, which allows the copy to be eliminated
// in some cases.
if (node.Instruction == Instruction.Copy || node.Instruction == Instruction.ZeroExtend32)
if (node.Instruction is Instruction.Copy or Instruction.ZeroExtend32)
{
Operand source = node.GetSource(0);
@ -1120,8 +1120,8 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
private static bool IsLocalOrRegister(OperandKind kind)
{
return kind == OperandKind.LocalVariable ||
kind == OperandKind.Register;
return kind is OperandKind.LocalVariable or
OperandKind.Register;
}
}
}

View file

@ -1478,7 +1478,7 @@ namespace ARMeilleure.CodeGen.X86
private static bool Is64Bits(OperandType type)
{
return type == OperandType.I64 || type == OperandType.FP64;
return type is OperandType.I64 or OperandType.FP64;
}
private static bool IsImm8(ulong immediate, OperandType type)

View file

@ -13,7 +13,6 @@ namespace ARMeilleure.CodeGen.X86
private const int BadOp = 0;
[Flags]
[SuppressMessage("Design", "CA1069: Enums values should not be duplicated")]
private enum InstructionFlags
{
None = 0,

View file

@ -1,5 +1,6 @@
using ARMeilleure.CodeGen.RegisterAllocators;
using ARMeilleure.IntermediateRepresentation;
using Microsoft.IO;
using Ryujinx.Common.Memory;
using System.IO;
using System.Numerics;
@ -8,7 +9,7 @@ namespace ARMeilleure.CodeGen.X86
{
class CodeGenContext
{
private readonly Stream _stream;
private readonly RecyclableMemoryStream _stream;
private readonly Operand[] _blockLabels;
public int StreamOffset => (int)_stream.Length;

View file

@ -175,8 +175,8 @@ namespace ARMeilleure.CodeGen.X86
// The only blocks which can have 0 successors are exit blocks.
Operation last = block.Operations.Last;
Debug.Assert(last.Instruction == Instruction.Tailcall ||
last.Instruction == Instruction.Return);
Debug.Assert(last.Instruction is Instruction.Tailcall or
Instruction.Return);
}
else
{
@ -478,7 +478,7 @@ namespace ARMeilleure.CodeGen.X86
Debug.Assert(HardwareCapabilities.SupportsVexEncoding);
Debug.Assert(dest.Kind == OperandKind.Register && src1.Kind == OperandKind.Register && src2.Kind == OperandKind.Register);
Debug.Assert(src3.Kind == OperandKind.Register || src3.Kind == OperandKind.Memory);
Debug.Assert(src3.Kind is OperandKind.Register or OperandKind.Memory);
EnsureSameType(dest, src1, src2, src3);
Debug.Assert(dest.Type == OperandType.V128);
@ -788,7 +788,7 @@ namespace ARMeilleure.CodeGen.X86
Operand dest = operation.Destination;
Operand source = operation.GetSource(0);
Debug.Assert(dest.Type == OperandType.FP32 || dest.Type == OperandType.FP64);
Debug.Assert(dest.Type is OperandType.FP32 or OperandType.FP64);
if (dest.Type == OperandType.FP32)
{
@ -1723,7 +1723,7 @@ namespace ARMeilleure.CodeGen.X86
return;
}
Debug.Assert(op1.Kind == OperandKind.Register || op1.Kind == OperandKind.Memory);
Debug.Assert(op1.Kind is OperandKind.Register or OperandKind.Memory);
Debug.Assert(op1.Kind == op2.Kind);
Debug.Assert(op1.Value == op2.Value);
}

View file

@ -66,6 +66,7 @@ namespace ARMeilleure.CodeGen.X86
{
PreAllocatorSystemV.InsertCallCopies(block.Operations, node);
}
break;
case Instruction.ConvertToFPUI:
@ -81,6 +82,7 @@ namespace ARMeilleure.CodeGen.X86
{
nextNode = PreAllocatorSystemV.InsertLoadArgumentCopy(cctx, ref buffer, block.Operations, preservedArgs, node);
}
break;
case Instruction.Negate:
@ -88,6 +90,7 @@ namespace ARMeilleure.CodeGen.X86
{
GenerateNegate(block.Operations, node);
}
break;
case Instruction.Return:
@ -99,6 +102,7 @@ namespace ARMeilleure.CodeGen.X86
{
PreAllocatorSystemV.InsertReturnCopy(block.Operations, node);
}
break;
case Instruction.Tailcall:
@ -110,6 +114,7 @@ namespace ARMeilleure.CodeGen.X86
{
PreAllocatorSystemV.InsertTailcallCopies(block.Operations, node);
}
break;
case Instruction.VectorInsert8:
@ -117,6 +122,7 @@ namespace ARMeilleure.CodeGen.X86
{
GenerateVectorInsert8(block.Operations, node);
}
break;
case Instruction.Extended:
@ -132,6 +138,7 @@ namespace ARMeilleure.CodeGen.X86
node.SetSources([Const(stackOffset)]);
}
break;
}
}
@ -312,9 +319,9 @@ namespace ARMeilleure.CodeGen.X86
case Instruction.Extended:
{
bool isBlend = node.Intrinsic == Intrinsic.X86Blendvpd ||
node.Intrinsic == Intrinsic.X86Blendvps ||
node.Intrinsic == Intrinsic.X86Pblendvb;
bool isBlend = node.Intrinsic is Intrinsic.X86Blendvpd or
Intrinsic.X86Blendvps or
Intrinsic.X86Pblendvb;
// BLENDVPD, BLENDVPS, PBLENDVB last operand is always implied to be XMM0 when VEX is not supported.
// SHA256RNDS2 always has an implied XMM0 as a last operand.
@ -513,8 +520,8 @@ namespace ARMeilleure.CodeGen.X86
Operand dest = node.Destination;
Operand source = node.GetSource(0);
Debug.Assert(dest.Type == OperandType.FP32 ||
dest.Type == OperandType.FP64, $"Invalid destination type \"{dest.Type}\".");
Debug.Assert(dest.Type is OperandType.FP32 or
OperandType.FP64, $"Invalid destination type \"{dest.Type}\".");
Operation currentNode = node;
@ -761,7 +768,7 @@ namespace ARMeilleure.CodeGen.X86
Comparison compType = (Comparison)comp.AsInt32();
return compType == Comparison.Equal || compType == Comparison.NotEqual;
return compType is Comparison.Equal or Comparison.NotEqual;
}
}

View file

@ -248,12 +248,12 @@ namespace ARMeilleure.CodeGen.X86
private static bool IsMemoryLoadOrStore(Instruction inst)
{
return inst == Instruction.Load ||
inst == Instruction.Load16 ||
inst == Instruction.Load8 ||
inst == Instruction.Store ||
inst == Instruction.Store16 ||
inst == Instruction.Store8;
return inst is Instruction.Load or
Instruction.Load16 or
Instruction.Load8 or
Instruction.Store or
Instruction.Store16 or
Instruction.Store8;
}
}
}

View file

@ -2,7 +2,6 @@ using System.Diagnostics.CodeAnalysis;
namespace ARMeilleure.CodeGen.X86
{
[SuppressMessage("Design", "CA1069: Enums values should not be duplicated")]
enum X86Register
{
Invalid = -1,

View file

@ -254,8 +254,8 @@ namespace ARMeilleure.Decoders
}
// Compare and branch instructions are always conditional.
if (opCode.Instruction.Name == InstName.Cbz ||
opCode.Instruction.Name == InstName.Cbnz)
if (opCode.Instruction.Name is InstName.Cbz or
InstName.Cbnz)
{
return false;
}
@ -274,9 +274,10 @@ namespace ARMeilleure.Decoders
{
if (opCode is OpCodeT32)
{
return opCode.Instruction.Name != InstName.Tst && opCode.Instruction.Name != InstName.Teq &&
opCode.Instruction.Name != InstName.Cmp && opCode.Instruction.Name != InstName.Cmn;
return opCode.Instruction.Name is not InstName.Tst and not InstName.Teq and
not InstName.Cmp and not InstName.Cmn;
}
return true;
}
@ -284,7 +285,7 @@ namespace ARMeilleure.Decoders
// register (Rt == 15 or (mask & (1 << 15)) != 0), and cases where there is
// a write back to PC (wback == true && Rn == 15), however the later may
// be "undefined" depending on the CPU, so compilers should not produce that.
if (opCode is IOpCode32Mem || opCode is IOpCode32MemMult)
if (opCode is IOpCode32Mem or IOpCode32MemMult)
{
int rt, rn;
@ -326,15 +327,15 @@ namespace ARMeilleure.Decoders
}
// Explicit branch instructions.
return opCode is IOpCode32BImm ||
opCode is IOpCode32BReg;
return opCode is IOpCode32BImm or
IOpCode32BReg;
}
private static bool IsCall(OpCode opCode)
{
return opCode.Instruction.Name == InstName.Bl ||
opCode.Instruction.Name == InstName.Blr ||
opCode.Instruction.Name == InstName.Blx;
return opCode.Instruction.Name is InstName.Bl or
InstName.Blr or
InstName.Blx;
}
private static bool IsException(OpCode opCode)
@ -344,9 +345,9 @@ namespace ARMeilleure.Decoders
private static bool IsTrap(OpCode opCode)
{
return opCode.Instruction.Name == InstName.Brk ||
opCode.Instruction.Name == InstName.Trap ||
opCode.Instruction.Name == InstName.Und;
return opCode.Instruction.Name is InstName.Brk or
InstName.Trap or
InstName.Und;
}
public static OpCode DecodeOpCode(IMemoryManager memory, ulong address, ExecutionMode mode)

View file

@ -162,6 +162,7 @@ namespace ARMeilleure.Decoders
}
}
}
return false;
}
}

View file

@ -20,6 +20,7 @@ namespace ARMeilleure.Decoders
Instruction = InstDescriptor.Undefined;
return;
}
Q = ((opCode >> 21) & 0x1) != 0;
RegisterSize = Q ? RegisterSize.Simd128 : RegisterSize.Simd64;

View file

@ -40,7 +40,7 @@ namespace ARMeilleure.Decoders
Rn = (opCode >> 16) & 0xf;
WBack = Rm != RegisterAlias.Aarch32Pc;
RegisterIndex = Rm != RegisterAlias.Aarch32Pc && Rm != RegisterAlias.Aarch32Sp;
RegisterIndex = Rm is not RegisterAlias.Aarch32Pc and not RegisterAlias.Aarch32Sp;
Regs = _regsMap[(opCode >> 8) & 0xf];

View file

@ -45,7 +45,7 @@ namespace ARMeilleure.Decoders
Rn = (opCode >> 16) & 0xf;
WBack = Rm != RegisterAlias.Aarch32Pc;
RegisterIndex = Rm != RegisterAlias.Aarch32Pc && Rm != RegisterAlias.Aarch32Sp;
RegisterIndex = Rm is not RegisterAlias.Aarch32Pc and not RegisterAlias.Aarch32Sp;
}
}
}

View file

@ -28,8 +28,8 @@ namespace ARMeilleure.Decoders
MemOp type = WBack ? (MemOp)((opCode >> 10) & 3) : MemOp.Unsigned;
PostIdx = type == MemOp.PostIndexed;
Unscaled = type == MemOp.Unscaled ||
type == MemOp.Unprivileged;
Unscaled = type is MemOp.Unscaled or
MemOp.Unprivileged;
// Unscaled and Unprivileged doesn't write back,
// but they do use the 9-bits Signed Immediate.

View file

@ -1381,6 +1381,7 @@ namespace ARMeilleure.Decoders
{
thumbEncoding = $"1110{thumbEncoding.AsSpan(4)}";
}
SetT32(thumbEncoding, name, emitter, makeOpT32);
}
@ -1409,6 +1410,7 @@ namespace ARMeilleure.Decoders
{
throw new ArgumentException("Invalid ASIMD instruction encoding");
}
SetT32(thumbEncoding, name, emitter, makeOpT32);
}

View file

@ -9,7 +9,7 @@ namespace ARMeilleure.Diagnostics
{
class IRDumper
{
private const string Indentation = " ";
private const char Indentation = ' ';
private int _indentLevel;
@ -30,14 +30,11 @@ namespace ARMeilleure.Diagnostics
private void Indent()
{
_builder.EnsureCapacity(_builder.Capacity + _indentLevel * Indentation.Length);
if (_indentLevel == 0)
return;
for (int index = 0; index < _indentLevel; index++)
{
#pragma warning disable CA1834 // Use StringBuilder.Append(char) for single character strings
_builder.Append(Indentation);
#pragma warning restore CA1834
}
_builder.EnsureCapacity(_builder.Capacity + _indentLevel);
_builder.Append(Indentation, _indentLevel);
}
private void IncreaseIndentation()
@ -235,8 +232,8 @@ namespace ARMeilleure.Diagnostics
{
_builder.Append('.').Append(operation.Intrinsic);
}
else if (operation.Instruction == Instruction.BranchIf ||
operation.Instruction == Instruction.Compare)
else if (operation.Instruction is Instruction.BranchIf or
Instruction.Compare)
{
comparison = true;
}
@ -262,6 +259,7 @@ namespace ARMeilleure.Diagnostics
DumpOperand(source);
}
}
break;
}

View file

@ -899,6 +899,7 @@ namespace ARMeilleure.Instructions
{
n = context.ShiftLeft(n, Const(shift));
}
break;
case ShiftType.Asr:
if (shift == 32)
@ -909,6 +910,7 @@ namespace ARMeilleure.Instructions
{
n = context.ShiftRightSI(n, Const(shift));
}
break;
}

View file

@ -266,7 +266,7 @@ namespace ARMeilleure.Instructions
}
}
private static Exception InvalidOpCodeType(OpCode opCode)
private static InvalidOperationException InvalidOpCodeType(OpCode opCode)
{
return new InvalidOperationException($"Invalid OpCode type \"{opCode?.GetType().Name ?? "null"}\".");
}
@ -318,6 +318,7 @@ namespace ARMeilleure.Instructions
{
m = GetRrxC(context, m, setCarry);
}
break;
}
}

View file

@ -17,7 +17,7 @@ namespace ARMeilleure.Instructions
public static Operand EmitCrc32(ArmEmitterContext context, Operand crc, Operand value, int size, bool castagnoli)
{
Debug.Assert(crc.Type.IsInteger() && value.Type.IsInteger());
Debug.Assert(size >= 0 && size < 4);
Debug.Assert(size is >= 0 and < 4);
Debug.Assert((size < 3) || (value.Type == OperandType.I64));
if (castagnoli && Optimizations.UseSse42)

View file

@ -90,6 +90,7 @@ namespace ARMeilleure.Instructions
{
value = context.ConvertI64ToI32(value);
}
Operand reg = Register(GetRegisterAlias(context.Mode, regIndex), RegisterType.Integer, OperandType.I32);
context.Copy(reg, value);

View file

@ -140,7 +140,7 @@ namespace ARMeilleure.Instructions
if (pair)
{
Debug.Assert(op.Size == 2 || op.Size == 3, "Invalid size for pairwise store.");
Debug.Assert(op.Size is 2 or 3, "Invalid size for pairwise store.");
Operand t2 = GetIntOrZR(context, op.Rt2);

View file

@ -42,6 +42,7 @@ namespace ARMeilleure.Instructions
{
context.Store(exValuePtr, Const(0UL));
}
if (size < 4)
{
context.Store(context.Add(exValuePtr, Const(exValuePtr.Type, 8L)), Const(0UL));

View file

@ -59,7 +59,7 @@ namespace ARMeilleure.Instructions
{
Operand value = GetInt(context, rt);
if (ext == Extension.Sx32 || ext == Extension.Sx64)
if (ext is Extension.Sx32 or Extension.Sx64)
{
OperandType destType = ext == Extension.Sx64 ? OperandType.I64 : OperandType.I32;
@ -123,9 +123,9 @@ namespace ARMeilleure.Instructions
private static bool IsSimd(ArmEmitterContext context)
{
return context.CurrOp is IOpCodeSimd &&
!(context.CurrOp is OpCodeSimdMemMs ||
context.CurrOp is OpCodeSimdMemSs);
return context.CurrOp is IOpCodeSimd and
not (OpCodeSimdMemMs or
OpCodeSimdMemSs);
}
public static Operand EmitReadInt(ArmEmitterContext context, Operand address, int size)
@ -717,7 +717,7 @@ namespace ARMeilleure.Instructions
};
}
private static Exception InvalidOpCodeType(OpCode opCode)
private static InvalidOperationException InvalidOpCodeType(OpCode opCode)
{
return new InvalidOperationException($"Invalid OpCode type \"{opCode?.GetType().Name ?? "null"}\".");
}
@ -768,6 +768,7 @@ namespace ARMeilleure.Instructions
{
m = InstEmitAluHelper.GetRrxC(context, m, setCarry);
}
break;
}
}

View file

@ -33,7 +33,6 @@ namespace ARMeilleure.Instructions
public static void Umsubl(ArmEmitterContext context) => EmitMull(context, MullFlags.Subtract);
[Flags]
[SuppressMessage("Design", "CA1069: Enums values should not be duplicated")]
private enum MullFlags
{
Subtract = 0,

View file

@ -5266,7 +5266,7 @@ namespace ARMeilleure.Instructions
private static Operand EmitSse2Sll_128(ArmEmitterContext context, Operand op, int shift)
{
// The upper part of op is assumed to be zero.
Debug.Assert(shift >= 0 && shift < 64);
Debug.Assert(shift is >= 0 and < 64);
if (shift == 0)
{

View file

@ -231,10 +231,12 @@ namespace ARMeilleure.Instructions
{
result |= (long)((i >= end || i < start) ? 0x80 : b++) << (i * 8);
}
for (int i = 8; i < 16; i++)
{
result2 |= (long)((i >= end || i < start) ? 0x80 : b++) << ((i - 8) * 8);
}
return (result2, result);
}
@ -261,6 +263,7 @@ namespace ARMeilleure.Instructions
nMaskHigh = nMaskLow + 0x0808080808080808L;
mMaskHigh = mMaskLow + 0x0808080808080808L;
}
nMask = X86GetElements(context, nMaskHigh, nMaskLow);
mMask = X86GetElements(context, mMaskHigh, mMaskLow);
Operand nPart = context.AddIntrinsic(Intrinsic.X86Pshufb, n, nMask);
@ -285,6 +288,7 @@ namespace ARMeilleure.Instructions
{
extract = EmitVectorExtractZx32(context, op.Qn, op.In + byteOff, op.Size);
}
byteOff++;
res = EmitVectorInsert(context, res, extract, op.Id + index, op.Size);
@ -1304,6 +1308,7 @@ namespace ARMeilleure.Instructions
case 2:
return context.AddIntrinsic(Intrinsic.X86Shufps, op1, op1, Const(1 | (0 << 2) | (3 << 4) | (2 << 6)));
}
break;
case 2:
// Rev32
@ -1316,6 +1321,7 @@ namespace ARMeilleure.Instructions
mask = X86GetElements(context, 0x0d0c0f0e_09080b0aL, 0x05040706_01000302L);
return context.AddIntrinsic(Intrinsic.X86Pshufb, op1, mask);
}
break;
case 1:
// Rev16
@ -1341,6 +1347,7 @@ namespace ARMeilleure.Instructions
case 3:
return context.ByteSwap(op1);
}
break;
case 1:
switch (op.Size)
@ -1355,6 +1362,7 @@ namespace ARMeilleure.Instructions
context.BitwiseOr(context.ShiftRightUI(context.BitwiseAnd(op1, Const(0x0000ffff00000000ul)), Const(16)),
context.ShiftLeft(context.BitwiseAnd(op1, Const(0x00000000ffff0000ul)), Const(16))));
}
break;
case 2:
// Swap upper and lower halves.

View file

@ -1119,7 +1119,7 @@ namespace ARMeilleure.Instructions
private static Operand EmitFPConvert(ArmEmitterContext context, Operand value, int size, bool signed)
{
Debug.Assert(value.Type == OperandType.I32 || value.Type == OperandType.I64);
Debug.Assert(value.Type is OperandType.I32 or OperandType.I64);
Debug.Assert((uint)size < 2);
OperandType type = size == 0 ? OperandType.FP32 : OperandType.FP64;
@ -1136,7 +1136,7 @@ namespace ARMeilleure.Instructions
private static Operand EmitScalarFcvts(ArmEmitterContext context, Operand value, int fBits)
{
Debug.Assert(value.Type == OperandType.FP32 || value.Type == OperandType.FP64);
Debug.Assert(value.Type is OperandType.FP32 or OperandType.FP64);
value = EmitF2iFBitsMul(context, value, fBits);
@ -1160,7 +1160,7 @@ namespace ARMeilleure.Instructions
private static Operand EmitScalarFcvtu(ArmEmitterContext context, Operand value, int fBits)
{
Debug.Assert(value.Type == OperandType.FP32 || value.Type == OperandType.FP64);
Debug.Assert(value.Type is OperandType.FP32 or OperandType.FP64);
value = EmitF2iFBitsMul(context, value, fBits);
@ -1184,7 +1184,7 @@ namespace ARMeilleure.Instructions
private static Operand EmitF2iFBitsMul(ArmEmitterContext context, Operand value, int fBits)
{
Debug.Assert(value.Type == OperandType.FP32 || value.Type == OperandType.FP64);
Debug.Assert(value.Type is OperandType.FP32 or OperandType.FP64);
if (fBits == 0)
{
@ -1203,7 +1203,7 @@ namespace ARMeilleure.Instructions
private static Operand EmitI2fFBitsMul(ArmEmitterContext context, Operand value, int fBits)
{
Debug.Assert(value.Type == OperandType.FP32 || value.Type == OperandType.FP64);
Debug.Assert(value.Type is OperandType.FP32 or OperandType.FP64);
if (fBits == 0)
{

View file

@ -385,6 +385,7 @@ namespace ARMeilleure.Instructions
{
res = context.AddIntrinsic(Intrinsic.X86Cvtsd2ss, context.VectorZero(), res);
}
res = context.AddIntrinsic(Intrinsic.X86Vcvtps2ph, res, Const(X86GetRoundControl(FPRoundingMode.ToNearest)));
res = context.VectorExtract16(res, 0);
InsertScalar16(context, op.Vd, op.T, res);
@ -397,6 +398,7 @@ namespace ARMeilleure.Instructions
{
res = context.AddIntrinsic(Intrinsic.X86Cvtss2sd, context.VectorZero(), res);
}
res = context.VectorExtract(op.Size == 1 ? OperandType.I64 : OperandType.I32, res, 0);
InsertScalar(context, op.Vd, res);
}
@ -635,7 +637,7 @@ namespace ARMeilleure.Instructions
private static Operand EmitFPConvert(ArmEmitterContext context, Operand value, OperandType type, bool signed)
{
Debug.Assert(value.Type == OperandType.I32 || value.Type == OperandType.I64);
Debug.Assert(value.Type is OperandType.I32 or OperandType.I64);
if (signed)
{

View file

@ -363,7 +363,7 @@ namespace ARMeilleure.Instructions
public static Operand EmitCountSetBits8(ArmEmitterContext context, Operand op) // "size" is 8 (SIMD&FP Inst.).
{
Debug.Assert(op.Type == OperandType.I32 || op.Type == OperandType.I64);
Debug.Assert(op.Type is OperandType.I32 or OperandType.I64);
Operand op0 = context.Subtract(op, context.BitwiseAnd(context.ShiftRightUI(op, Const(1)), Const(op.Type, 0x55L)));
@ -489,7 +489,7 @@ namespace ARMeilleure.Instructions
public static Operand EmitRoundByRMode(ArmEmitterContext context, Operand op)
{
Debug.Assert(op.Type == OperandType.FP32 || op.Type == OperandType.FP64);
Debug.Assert(op.Type is OperandType.FP32 or OperandType.FP64);
Operand lbl1 = Label();
Operand lbl2 = Label();
@ -1676,7 +1676,7 @@ namespace ARMeilleure.Instructions
int eSize = 8 << size;
Debug.Assert(op.Type == OperandType.I64);
Debug.Assert(eSize == 8 || eSize == 16 || eSize == 32 || eSize == 64);
Debug.Assert(eSize is 8 or 16 or 32 or 64);
Operand lbl1 = Label();
Operand lblEnd = Label();
@ -1709,7 +1709,7 @@ namespace ARMeilleure.Instructions
int eSize = 8 << size;
Debug.Assert(op.Type == OperandType.I64);
Debug.Assert(eSize == 8 || eSize == 16 || eSize == 32 || eSize == 64);
Debug.Assert(eSize is 8 or 16 or 32 or 64);
Operand lblEnd = Label();
@ -1735,7 +1735,7 @@ namespace ARMeilleure.Instructions
int eSizeDst = 8 << sizeDst;
Debug.Assert(op.Type == OperandType.I64);
Debug.Assert(eSizeDst == 8 || eSizeDst == 16 || eSizeDst == 32);
Debug.Assert(eSizeDst is 8 or 16 or 32);
Operand lbl1 = Label();
Operand lblEnd = Label();
@ -1768,7 +1768,7 @@ namespace ARMeilleure.Instructions
int eSizeDst = 8 << sizeDst;
Debug.Assert(op.Type == OperandType.I64);
Debug.Assert(eSizeDst == 8 || eSizeDst == 16 || eSizeDst == 32);
Debug.Assert(eSizeDst is 8 or 16 or 32);
Operand lblEnd = Label();

View file

@ -31,7 +31,7 @@ namespace ARMeilleure.Instructions
{
Debug.Assert(type != OperandType.V128);
if (type == OperandType.FP64 || type == OperandType.I64)
if (type is OperandType.FP64 or OperandType.I64)
{
// From dreg.
return context.VectorExtract(type, GetVecA32(reg >> 1), reg & 1);
@ -48,7 +48,7 @@ namespace ARMeilleure.Instructions
Debug.Assert(value.Type != OperandType.V128);
Operand vec, insert;
if (value.Type == OperandType.FP64 || value.Type == OperandType.I64)
if (value.Type is OperandType.FP64 or OperandType.I64)
{
// From dreg.
vec = GetVecA32(reg >> 1);
@ -71,7 +71,7 @@ namespace ARMeilleure.Instructions
public static void InsertScalar16(ArmEmitterContext context, int reg, bool top, Operand value)
{
Debug.Assert(value.Type == OperandType.FP32 || value.Type == OperandType.I32);
Debug.Assert(value.Type is OperandType.FP32 or OperandType.I32);
Operand vec, insert;
vec = GetVecA32(reg >> 2);
@ -880,6 +880,7 @@ namespace ARMeilleure.Instructions
{
res = EmitMoveDoubleWordToSide(context, res, side, op.Vd);
}
res = EmitDoubleWordInsert(context, d, res, op.Vd);
}

View file

@ -146,6 +146,7 @@ namespace ARMeilleure.Instructions
{
res = EmitMoveDoubleWordToSide(context, res, side, op.Vd);
}
res = EmitDoubleWordInsert(context, d, res, op.Vd);
}

View file

@ -268,6 +268,7 @@ namespace ARMeilleure.Instructions
{
m = context.BitwiseNot(m);
}
return context.BitwiseExclusiveOr(
context.BitwiseAnd(m,
context.BitwiseExclusiveOr(d, n)), d);

View file

@ -110,6 +110,7 @@ namespace ARMeilleure.Instructions
EmitStoreSimd(context, address, d >> 1, index, op.Size);
}
}
offset += eBytes;
d += op.Increment;
}

View file

@ -1634,7 +1634,7 @@ namespace ARMeilleure.Instructions
int eSize = 8 << size;
Debug.Assert(op.Type == OperandType.I64);
Debug.Assert(eSize == 8 || eSize == 16 || eSize == 32 || eSize == 64);
Debug.Assert(eSize is 8 or 16 or 32 or 64);
Operand res = context.AllocateLocal(OperandType.I64);
@ -1657,7 +1657,7 @@ namespace ARMeilleure.Instructions
int eSize = 8 << size;
Debug.Assert(op.Type == OperandType.I64);
Debug.Assert(eSize == 8 || eSize == 16 || eSize == 32 || eSize == 64);
Debug.Assert(eSize is 8 or 16 or 32 or 64);
Operand lblEnd = Label();
@ -1732,7 +1732,7 @@ namespace ARMeilleure.Instructions
Debug.Assert(op.Type == OperandType.I64);
Debug.Assert(shiftLsB.Type == OperandType.I32);
Debug.Assert(eSize == 8 || eSize == 16 || eSize == 32 || eSize == 64);
Debug.Assert(eSize is 8 or 16 or 32 or 64);
Operand lbl1 = Label();
Operand lblEnd = Label();
@ -1769,7 +1769,7 @@ namespace ARMeilleure.Instructions
Debug.Assert(op.Type == OperandType.I64);
Debug.Assert(shiftLsB.Type == OperandType.I32);
Debug.Assert(eSize == 8 || eSize == 16 || eSize == 32 || eSize == 64);
Debug.Assert(eSize is 8 or 16 or 32 or 64);
Operand lbl1 = Label();
Operand lbl2 = Label();
@ -1813,6 +1813,7 @@ namespace ARMeilleure.Instructions
? EmitSignedSrcSatQ(context, shl, size, signedDst: true)
: EmitUnsignedSrcSatQ(context, shl, size, signedDst: false));
}
context.Branch(lblEnd);
context.MarkLabel(lblEnd);
@ -1850,6 +1851,7 @@ namespace ARMeilleure.Instructions
{
context.Copy(res, sar);
}
context.Branch(lblEnd);
context.MarkLabel(lblEnd);
@ -1906,6 +1908,7 @@ namespace ARMeilleure.Instructions
Operand right = context.BitwiseOr(shr, context.ShiftRightUI(oneShl63UL, context.Subtract(shift, one)));
context.Copy(res, context.ConditionalSelect(isEqual, oneUL, right));
}
context.Branch(lblEnd);
context.MarkLabel(lblEnd);

View file

@ -69,13 +69,13 @@ namespace ARMeilleure.Instructions
[UnmanagedCallersOnly]
public static ulong GetCtrEl0()
{
return GetContext().CtrEl0;
return ExecutionContext.CtrEl0;
}
[UnmanagedCallersOnly]
public static ulong GetDczidEl0()
{
return GetContext().DczidEl0;
return ExecutionContext.DczidEl0;
}
[UnmanagedCallersOnly]

View file

@ -24,7 +24,7 @@ namespace ARMeilleure.Instructions
{
uint src = (uint)idx + 256u;
Debug.Assert(256u <= src && src < 512u);
Debug.Assert(src is >= 256u and < 512u);
src = (src << 1) + 1u;
@ -32,7 +32,7 @@ namespace ARMeilleure.Instructions
uint dst = (aux + 1u) >> 1;
Debug.Assert(256u <= dst && dst < 512u);
Debug.Assert(dst is >= 256u and < 512u);
tbl[idx] = (byte)(dst - 256u);
}
@ -48,7 +48,7 @@ namespace ARMeilleure.Instructions
{
uint src = (uint)idx + 128u;
Debug.Assert(128u <= src && src < 512u);
Debug.Assert(src is >= 128u and < 512u);
if (src < 256u)
{
@ -69,7 +69,7 @@ namespace ARMeilleure.Instructions
uint dst = (aux + 1u) >> 1;
Debug.Assert(256u <= dst && dst < 512u);
Debug.Assert(dst is >= 256u and < 512u);
tbl[idx] = (byte)(dst - 256u);
}
@ -322,7 +322,7 @@ namespace ARMeilleure.Instructions
float result;
if (type == FPType.SNaN || type == FPType.QNaN)
if (type is FPType.SNaN or FPType.QNaN)
{
if ((context.Fpcr & FPCR.Dn) != 0)
{
@ -498,7 +498,7 @@ namespace ARMeilleure.Instructions
double result;
if (type == FPType.SNaN || type == FPType.QNaN)
if (type is FPType.SNaN or FPType.QNaN)
{
if ((context.Fpcr & FPCR.Dn) != 0)
{
@ -676,7 +676,7 @@ namespace ARMeilleure.Instructions
ushort resultBits;
if (type == FPType.SNaN || type == FPType.QNaN)
if (type is FPType.SNaN or FPType.QNaN)
{
if (altHp)
{
@ -1086,7 +1086,7 @@ namespace ARMeilleure.Instructions
{
return FPMaxFpscrImpl(value1, value2, standardFpscr == 1);
}
private static float FPMaxFpscrImpl(float value1, float value2, bool standardFpscr)
{
ExecutionContext context = NativeInterface.GetContext();
@ -1522,7 +1522,7 @@ namespace ARMeilleure.Instructions
float result;
if (type == FPType.SNaN || type == FPType.QNaN)
if (type is FPType.SNaN or FPType.QNaN)
{
result = FPProcessNaN(type, op, context, fpcr);
}
@ -1689,7 +1689,7 @@ namespace ARMeilleure.Instructions
float result;
if (type == FPType.SNaN || type == FPType.QNaN)
if (type is FPType.SNaN or FPType.QNaN)
{
result = FPProcessNaN(type, op, context, fpcr);
}
@ -1726,7 +1726,7 @@ namespace ARMeilleure.Instructions
float result;
if (type == FPType.SNaN || type == FPType.QNaN)
if (type is FPType.SNaN or FPType.QNaN)
{
result = FPProcessNaN(type, op, context, fpcr);
}
@ -1920,7 +1920,7 @@ namespace ARMeilleure.Instructions
float result;
if (type == FPType.SNaN || type == FPType.QNaN)
if (type is FPType.SNaN or FPType.QNaN)
{
result = FPProcessNaN(type, op, context, fpcr);
}
@ -2211,7 +2211,7 @@ namespace ARMeilleure.Instructions
ushort resultBits;
if (type == FPType.SNaN || type == FPType.QNaN)
if (type is FPType.SNaN or FPType.QNaN)
{
if (altHp)
{
@ -3057,7 +3057,7 @@ namespace ARMeilleure.Instructions
double result;
if (type == FPType.SNaN || type == FPType.QNaN)
if (type is FPType.SNaN or FPType.QNaN)
{
result = FPProcessNaN(type, op, context, fpcr);
}
@ -3224,7 +3224,7 @@ namespace ARMeilleure.Instructions
double result;
if (type == FPType.SNaN || type == FPType.QNaN)
if (type is FPType.SNaN or FPType.QNaN)
{
result = FPProcessNaN(type, op, context, fpcr);
}
@ -3261,7 +3261,7 @@ namespace ARMeilleure.Instructions
double result;
if (type == FPType.SNaN || type == FPType.QNaN)
if (type is FPType.SNaN or FPType.QNaN)
{
result = FPProcessNaN(type, op, context, fpcr);
}
@ -3455,7 +3455,7 @@ namespace ARMeilleure.Instructions
double result;
if (type == FPType.SNaN || type == FPType.QNaN)
if (type is FPType.SNaN or FPType.QNaN)
{
result = FPProcessNaN(type, op, context, fpcr);
}

View file

@ -4,7 +4,6 @@ using System.Diagnostics.CodeAnalysis;
namespace ARMeilleure.IntermediateRepresentation
{
[Flags]
[SuppressMessage("Design", "CA1069: Enums values should not be duplicated")]
enum Intrinsic : ushort
{
// X86 (SSE and AVX)

View file

@ -446,7 +446,7 @@ namespace ARMeilleure.IntermediateRepresentation
Data* data = null;
// If constant or register, then try to look up in the intern table before allocating.
if (kind == OperandKind.Constant || kind == OperandKind.Register)
if (kind is OperandKind.Constant or OperandKind.Register)
{
uint hash = (uint)HashCode.Combine(kind, type, value);

View file

@ -16,8 +16,8 @@ namespace ARMeilleure.IntermediateRepresentation
{
public static bool IsInteger(this OperandType type)
{
return type == OperandType.I32 ||
type == OperandType.I64;
return type is OperandType.I32 or
OperandType.I64;
}
public static RegisterType ToRegisterType(this OperandType type)

View file

@ -47,12 +47,12 @@ namespace ARMeilleure.Memory
{
public static bool IsHostMapped(this MemoryManagerType type)
{
return type == MemoryManagerType.HostMapped || type == MemoryManagerType.HostMappedUnsafe;
return type is MemoryManagerType.HostMapped or MemoryManagerType.HostMappedUnsafe;
}
public static bool IsHostTracked(this MemoryManagerType type)
{
return type == MemoryManagerType.HostTracked || type == MemoryManagerType.HostTrackedUnsafe;
return type is MemoryManagerType.HostTracked or MemoryManagerType.HostTrackedUnsafe;
}
public static bool IsHostMappedOrTracked(this MemoryManagerType type)

View file

@ -16,10 +16,8 @@ namespace ARMeilleure.State
public ulong Pc => _nativeContext.GetPc();
#pragma warning disable CA1822 // Mark member as static
public uint CtrEl0 => 0x8444c004;
public uint DczidEl0 => 0x00000004;
#pragma warning restore CA1822
public static uint CtrEl0 => 0x8444c004;
public static uint DczidEl0 => 0x00000004;
public ulong CntfrqEl0 => _counter.Frequency;
public ulong CntpctEl0 => _counter.Counter;

View file

@ -111,6 +111,7 @@ namespace ARMeilleure.State
{
value |= GetStorage().Flags[flag] != 0 ? 1u << flag : 0u;
}
return value;
}
@ -155,6 +156,7 @@ namespace ARMeilleure.State
value |= GetStorage().FpFlags[flag] != 0 ? bit : 0u;
}
}
return value;
}

View file

@ -24,7 +24,7 @@ namespace ARMeilleure.Translation.Cache
private static JitCacheInvalidation _jitCacheInvalidator;
private static List<CacheMemoryAllocator> _cacheAllocators = [];
private static readonly List<CacheMemoryAllocator> _cacheAllocators = [];
private static readonly List<CacheEntry> _cacheEntries = [];
@ -205,7 +205,6 @@ namespace ARMeilleure.Translation.Cache
return allocOffsetNew;
}
private static int AlignCodeSize(int codeSize)
{
return checked(codeSize + (CodeAlignment - 1)) & ~(CodeAlignment - 1);

View file

@ -32,7 +32,7 @@ namespace ARMeilleure.Translation
return _delegates.Values[index].FuncPtr; // O(1).
}
public static int GetDelegateIndex(MethodInfo info)
{
ArgumentNullException.ThrowIfNull(info);
@ -48,7 +48,7 @@ namespace ARMeilleure.Translation
return index;
}
private static void SetDelegateInfo(MethodInfo method)
{
string key = GetKey(method);

View file

@ -77,7 +77,7 @@ namespace ARMeilleure.Translation
{
continue;
}
for (int pBlkIndex = 0; pBlkIndex < block.Predecessors.Count; pBlkIndex++)
{
BasicBlock current = block.Predecessors[pBlkIndex];

View file

@ -124,7 +124,7 @@ namespace ARMeilleure.Translation
/// </summary>
/// <param name="node">The node to search for values within</param>
/// <param name="list">The list to add values to</param>
private void AddToList(IntervalTreeNode<TK, TV> node, List<TV> list)
private static void AddToList(IntervalTreeNode<TK, TV> node, List<TV> list)
{
if (node == null)
{
@ -165,6 +165,7 @@ namespace ARMeilleure.Translation
return node;
}
}
return null;
}
@ -175,7 +176,7 @@ namespace ARMeilleure.Translation
/// <param name="end">End of the range</param>
/// <param name="overlaps">Overlaps array to place results in</param>
/// <param name="overlapCount">Overlaps count to update</param>
private void GetKeys(IntervalTreeNode<TK, TV> node, TK start, TK end, ref TK[] overlaps, ref int overlapCount)
private static void GetKeys(IntervalTreeNode<TK, TV> node, TK start, TK end, ref TK[] overlaps, ref int overlapCount)
{
if (node == null || start.CompareTo(node.Max) >= 0)
{
@ -311,6 +312,7 @@ namespace ARMeilleure.Translation
return false;
}
}
IntervalTreeNode<TK, TV> newNode = new(start, end, value, parent);
if (newNode.Parent == null)
{
@ -422,12 +424,14 @@ namespace ARMeilleure.Translation
{
return Maximum(node.Left);
}
IntervalTreeNode<TK, TV> parent = node.Parent;
while (parent != null && node == parent.Left)
{
node = parent;
parent = parent.Parent;
}
return parent;
}
@ -452,6 +456,7 @@ namespace ARMeilleure.Translation
RotateLeft(ParentOf(ptr));
sibling = RightOf(ParentOf(ptr));
}
if (ColorOf(LeftOf(sibling)) == Black && ColorOf(RightOf(sibling)) == Black)
{
SetColor(sibling, Red);
@ -466,6 +471,7 @@ namespace ARMeilleure.Translation
RotateRight(sibling);
sibling = RightOf(ParentOf(ptr));
}
SetColor(sibling, ColorOf(ParentOf(ptr)));
SetColor(ParentOf(ptr), Black);
SetColor(RightOf(sibling), Black);
@ -484,6 +490,7 @@ namespace ARMeilleure.Translation
RotateRight(ParentOf(ptr));
sibling = LeftOf(ParentOf(ptr));
}
if (ColorOf(RightOf(sibling)) == Black && ColorOf(LeftOf(sibling)) == Black)
{
SetColor(sibling, Red);
@ -498,6 +505,7 @@ namespace ARMeilleure.Translation
RotateLeft(sibling);
sibling = LeftOf(ParentOf(ptr));
}
SetColor(sibling, ColorOf(ParentOf(ptr)));
SetColor(ParentOf(ptr), Black);
SetColor(LeftOf(sibling), Black);
@ -506,6 +514,7 @@ namespace ARMeilleure.Translation
}
}
}
SetColor(ptr, Black);
}
@ -532,6 +541,7 @@ namespace ARMeilleure.Translation
balanceNode = ParentOf(balanceNode);
RotateLeft(balanceNode);
}
SetColor(ParentOf(balanceNode), Black);
SetColor(ParentOf(ParentOf(balanceNode)), Red);
RotateRight(ParentOf(ParentOf(balanceNode)));
@ -555,12 +565,14 @@ namespace ARMeilleure.Translation
balanceNode = ParentOf(balanceNode);
RotateRight(balanceNode);
}
SetColor(ParentOf(balanceNode), Black);
SetColor(ParentOf(ParentOf(balanceNode)), Red);
RotateLeft(ParentOf(ParentOf(balanceNode)));
}
}
}
SetColor(_root, Black);
}
@ -574,6 +586,7 @@ namespace ARMeilleure.Translation
{
node.Right.Parent = node;
}
IntervalTreeNode<TK, TV> nodeParent = ParentOf(node);
right.Parent = nodeParent;
if (nodeParent == null)
@ -588,6 +601,7 @@ namespace ARMeilleure.Translation
{
nodeParent.Right = right;
}
right.Left = node;
node.Parent = right;
@ -605,6 +619,7 @@ namespace ARMeilleure.Translation
{
node.Left.Parent = node;
}
IntervalTreeNode<TK, TV> nodeParent = ParentOf(node);
left.Parent = nodeParent;
if (nodeParent == null)
@ -619,6 +634,7 @@ namespace ARMeilleure.Translation
{
nodeParent.Left = left;
}
left.Right = node;
node.Parent = left;

View file

@ -835,8 +835,6 @@ namespace ARMeilleure.Translation.PTC
return;
}
int degreeOfParallelism = Environment.ProcessorCount;
if (Optimizations.LowPower)
@ -896,13 +894,12 @@ namespace ARMeilleure.Translation.PTC
}
}
List<Thread> threads = Enumerable.Range(0, degreeOfParallelism)
.Select(idx =>
.Select(idx =>
new Thread(TranslateFuncs)
{
IsBackground = true,
Name = "Ptc.TranslateThread." + idx
IsBackground = true,
Name = "Ptc.TranslateThread." + idx
}
).ToList();
@ -912,6 +909,7 @@ namespace ARMeilleure.Translation.PTC
{
thread.Start();
}
foreach (Thread thread in threads)
{
thread.Join();
@ -925,8 +923,8 @@ namespace ARMeilleure.Translation.PTC
sw.Stop();
PtcStateChanged?.Invoke(PtcLoadingState.Loaded, _translateCount, _translateTotalCount);
Logger.Info?.Print(LogClass.Ptc,
Logger.Info?.Print(LogClass.Ptc,
$"{_translateCount} of {_translateTotalCount} functions translated in {sw.Elapsed.TotalSeconds} seconds " +
$"| {"function".ToQuantity(_translateTotalCount - _translateCount)} blacklisted " +
$"| Thread count: {degreeOfParallelism}");
@ -1164,8 +1162,8 @@ namespace ARMeilleure.Translation.PTC
public void Close()
{
if (State == PtcState.Enabled ||
State == PtcState.Continuing)
if (State is PtcState.Enabled or
PtcState.Continuing)
{
State = PtcState.Closing;
}

View file

@ -1,5 +1,6 @@
using ARMeilleure.State;
using Humanizer;
using Microsoft.IO;
using Ryujinx.Common;
using Ryujinx.Common.Logging;
using Ryujinx.Common.Memory;
@ -26,7 +27,7 @@ namespace ARMeilleure.Translation.PTC
private const uint InternalVersion = 7007; //! Not to be incremented manually for each change to the ARMeilleure project.
private static readonly uint[] _migrateInternalVersions =
private static readonly uint[] _migrateInternalVersions =
[
1866,
5518,
@ -75,7 +76,7 @@ namespace ARMeilleure.Translation.PTC
Enabled = false;
}
private void TimerElapsed(object _, ElapsedEventArgs __)
private void TimerElapsed(object _, ElapsedEventArgs __)
=> new Thread(PreSave) { Name = "Ptc.DiskWriter" }.Start();
public void AddEntry(ulong address, ExecutionMode mode, bool highCq, bool blacklist = false)
@ -151,7 +152,7 @@ namespace ARMeilleure.Translation.PTC
if (!funcProfile.Blacklist)
continue;
if (!funcs.Contains(ptr))
if (!funcs.Contains(ptr))
funcs.Add(ptr);
}
@ -219,7 +220,7 @@ namespace ARMeilleure.Translation.PTC
return false;
}
using MemoryStream stream = MemoryStreamManager.Shared.GetStream();
using RecyclableMemoryStream stream = MemoryStreamManager.Shared.GetStream();
Debug.Assert(stream.Seek(0L, SeekOrigin.Begin) == 0L && stream.Length == 0L);
try
@ -293,10 +294,10 @@ namespace ARMeilleure.Translation.PTC
{
if (migrateEntryFunc != null)
{
return DeserializeAndUpdateDictionary(stream, (Stream stream) => { return new FuncProfile(DeserializeStructure<FuncProfilePreBlacklist>(stream)); }, migrateEntryFunc);
return DeserializeAndUpdateDictionary(stream, stream => { return new FuncProfile(DeserializeStructure<FuncProfilePreBlacklist>(stream)); }, migrateEntryFunc);
}
return DeserializeDictionary<ulong, FuncProfile>(stream, (Stream stream) => { return new FuncProfile(DeserializeStructure<FuncProfilePreBlacklist>(stream)); });
return DeserializeDictionary<ulong, FuncProfile>(stream, stream => { return new FuncProfile(DeserializeStructure<FuncProfilePreBlacklist>(stream)); });
}
private static ReadOnlySpan<byte> GetReadOnlySpan(MemoryStream memoryStream)
@ -467,8 +468,8 @@ namespace ARMeilleure.Translation.PTC
public void Start()
{
if (_ptc.State == PtcState.Enabled ||
_ptc.State == PtcState.Continuing)
if (_ptc.State is PtcState.Enabled or
PtcState.Continuing)
{
Enabled = true;