From 6476b3d24f6d803956b3ca795b53b0fbba2c0fc3 Mon Sep 17 00:00:00 2001 From: riperiperi Date: Sat, 25 Jan 2020 17:57:22 +0000 Subject: [PATCH] Address Feedback --- ARMeilleure/Decoders/Decoder.cs | 1 - ARMeilleure/Decoders/DecoderHelper.cs | 3 +- ARMeilleure/Decoders/IOpCode32AluBf.cs | 6 +- ARMeilleure/Decoders/IOpCode32AluReg.cs | 6 +- ARMeilleure/Decoders/IOpCode32AluUx.cs | 6 +- ARMeilleure/Decoders/IOpCode32MemEx.cs | 6 +- ARMeilleure/Decoders/IOpCode32Simd.cs | 6 +- ARMeilleure/Decoders/IOpCode32SimdImm.cs | 6 +- ARMeilleure/Decoders/OpCode32AluBf.cs | 6 +- ARMeilleure/Decoders/OpCode32AluMla.cs | 6 +- ARMeilleure/Decoders/OpCode32AluReg.cs | 6 +- ARMeilleure/Decoders/OpCode32AluRsReg.cs | 6 +- ARMeilleure/Decoders/OpCode32AluUmull.cs | 6 +- ARMeilleure/Decoders/OpCode32AluUx.cs | 6 +- ARMeilleure/Decoders/OpCode32Exception.cs | 6 +- ARMeilleure/Decoders/OpCode32MemLdEx.cs | 8 +- ARMeilleure/Decoders/OpCode32MemReg.cs | 6 +- ARMeilleure/Decoders/OpCode32MemRsImm.cs | 6 +- ARMeilleure/Decoders/OpCode32MemStEx.cs | 6 +- ARMeilleure/Decoders/OpCode32Simd.cs | 12 +- ...aseOpCode32Simd.cs => OpCode32SimdBase.cs} | 7 +- ARMeilleure/Decoders/OpCode32SimdBinary.cs | 7 +- ARMeilleure/Decoders/OpCode32SimdCmpZ.cs | 8 +- ARMeilleure/Decoders/OpCode32SimdCvtFI.cs | 7 +- ARMeilleure/Decoders/OpCode32SimdDupElem.cs | 8 +- ARMeilleure/Decoders/OpCode32SimdDupGP.cs | 8 +- ARMeilleure/Decoders/OpCode32SimdExt.cs | 7 +- ARMeilleure/Decoders/OpCode32SimdImm.cs | 12 +- ARMeilleure/Decoders/OpCode32SimdImm44.cs | 7 +- ARMeilleure/Decoders/OpCode32SimdImm6.cs | 7 +- ARMeilleure/Decoders/OpCode32SimdMemImm.cs | 6 +- ARMeilleure/Decoders/OpCode32SimdMemMult.cs | 8 +- ARMeilleure/Decoders/OpCode32SimdMemPair.cs | 25 +- ARMeilleure/Decoders/OpCode32SimdMemSingle.cs | 9 +- ARMeilleure/Decoders/OpCode32SimdMovGp.cs | 9 +- .../Decoders/OpCode32SimdMovGpDouble.cs | 9 +- ARMeilleure/Decoders/OpCode32SimdMovGpElem.cs | 7 +- ARMeilleure/Decoders/OpCode32SimdReg.cs | 8 +- ARMeilleure/Decoders/OpCode32SimdRegElem.cs | 6 +- ARMeilleure/Decoders/OpCode32SimdRegS.cs | 6 +- ARMeilleure/Decoders/OpCode32SimdRev.cs | 12 +- ARMeilleure/Decoders/OpCode32SimdS.cs | 6 +- ARMeilleure/Decoders/OpCode32SimdSel.cs | 6 +- ARMeilleure/Decoders/OpCode32SimdSpecial.cs | 6 +- ARMeilleure/Decoders/OpCode32SimdSqrte.cs | 8 +- ARMeilleure/Decoders/OpCode32SimdTbl.cs | 6 +- ARMeilleure/Decoders/OpCode32System.cs | 6 +- ARMeilleure/Decoders/OpCodeSimdHelper.cs | 10 +- ARMeilleure/Decoders/OpCodeTable.cs | 352 +++++++++--------- ARMeilleure/Instructions/InstEmitAlu.cs | 36 +- ARMeilleure/Instructions/InstEmitAlu32.cs | 62 +-- ARMeilleure/Instructions/InstEmitAluHelper.cs | 80 +++- ARMeilleure/Instructions/InstEmitFlow32.cs | 8 +- ARMeilleure/Instructions/InstEmitMemory32.cs | 8 +- .../Instructions/InstEmitMemoryEx32.cs | 13 +- .../Instructions/InstEmitMemoryHelper.cs | 1 - ARMeilleure/Instructions/InstEmitMul32.cs | 55 +-- .../Instructions/InstEmitSimdArithmetic32.cs | 27 +- ARMeilleure/Instructions/InstEmitSimdCmp32.cs | 28 +- ARMeilleure/Instructions/InstEmitSimdCvt32.cs | 39 +- .../Instructions/InstEmitSimdHelper32.cs | 29 +- .../Instructions/InstEmitSimdLogical32.cs | 7 - .../Instructions/InstEmitSimdMemory32.cs | 18 +- .../Instructions/InstEmitSimdMove32.cs | 63 ++-- .../Instructions/InstEmitSimdShift32.cs | 5 +- ARMeilleure/Instructions/InstEmitSystem32.cs | 58 +-- ARMeilleure/Instructions/InstName.cs | 5 +- ARMeilleure/Instructions/SoftFloat.cs | 4 +- ARMeilleure/State/FPCR.cs | 2 +- ARMeilleure/State/FPSR.cs | 2 +- ARMeilleure/State/RegisterAlias.cs | 1 + ARMeilleure/Translation/RegisterUsage.cs | 2 - ARMeilleure/Translation/Translator.cs | 12 +- Ryujinx.Tests.Unicorn/Native/Arm32Register.cs | 2 +- Ryujinx.Tests.Unicorn/UnicornAArch32.cs | 9 +- Ryujinx.Tests/Cpu/CpuTest32.cs | 6 +- Ryujinx.Tests/Cpu/CpuTestAlu32.cs | 2 - Ryujinx.Tests/Cpu/CpuTestBf32.cs | 6 +- Ryujinx.Tests/Cpu/CpuTestSimdLogical32.cs | 3 - Ryujinx.Tests/Cpu/CpuTestSimdMemory32.cs | 69 ++-- Ryujinx.Tests/Cpu/CpuTestSimdMov32.cs | 31 +- Ryujinx.Tests/Cpu/CpuTestSimdReg32.cs | 1 + 82 files changed, 591 insertions(+), 806 deletions(-) rename ARMeilleure/Decoders/{BaseOpCode32Simd.cs => OpCode32SimdBase.cs} (89%) diff --git a/ARMeilleure/Decoders/Decoder.cs b/ARMeilleure/Decoders/Decoder.cs index 139d587e03..913d5082b6 100644 --- a/ARMeilleure/Decoders/Decoder.cs +++ b/ARMeilleure/Decoders/Decoder.cs @@ -292,7 +292,6 @@ namespace ARMeilleure.Decoders private static bool IsCall(OpCode opCode) { - // TODO (CQ): ARM32 support. return opCode.Instruction.Name == InstName.Bl || opCode.Instruction.Name == InstName.Blr || opCode.Instruction.Name == InstName.Blx; diff --git a/ARMeilleure/Decoders/DecoderHelper.cs b/ARMeilleure/Decoders/DecoderHelper.cs index 6d08df1c72..6fe4678f96 100644 --- a/ARMeilleure/Decoders/DecoderHelper.cs +++ b/ARMeilleure/Decoders/DecoderHelper.cs @@ -151,7 +151,8 @@ namespace ARMeilleure.Decoders public static bool VectorArgumentsInvalid(bool q, params int[] args) { - if (q) { + if (q) + { for (int i = 0; i < args.Length; i++) { if ((args[i] & 1) == 1) diff --git a/ARMeilleure/Decoders/IOpCode32AluBf.cs b/ARMeilleure/Decoders/IOpCode32AluBf.cs index c4fd21f3ae..d3a5e0d74f 100644 --- a/ARMeilleure/Decoders/IOpCode32AluBf.cs +++ b/ARMeilleure/Decoders/IOpCode32AluBf.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { interface IOpCode32AluBf { diff --git a/ARMeilleure/Decoders/IOpCode32AluReg.cs b/ARMeilleure/Decoders/IOpCode32AluReg.cs index 57ac14a52a..fa1b959f6b 100644 --- a/ARMeilleure/Decoders/IOpCode32AluReg.cs +++ b/ARMeilleure/Decoders/IOpCode32AluReg.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { interface IOpCode32AluReg : IOpCode32Alu { diff --git a/ARMeilleure/Decoders/IOpCode32AluUx.cs b/ARMeilleure/Decoders/IOpCode32AluUx.cs index e44e73be7b..5d4fd892d7 100644 --- a/ARMeilleure/Decoders/IOpCode32AluUx.cs +++ b/ARMeilleure/Decoders/IOpCode32AluUx.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { interface IOpCode32AluUx : IOpCode32AluReg { diff --git a/ARMeilleure/Decoders/IOpCode32MemEx.cs b/ARMeilleure/Decoders/IOpCode32MemEx.cs index 97959da94b..12ac572f1a 100644 --- a/ARMeilleure/Decoders/IOpCode32MemEx.cs +++ b/ARMeilleure/Decoders/IOpCode32MemEx.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { interface IOpCode32MemEx : IOpCode32Mem { diff --git a/ARMeilleure/Decoders/IOpCode32Simd.cs b/ARMeilleure/Decoders/IOpCode32Simd.cs index 4a00d56ac9..f35bc568cc 100644 --- a/ARMeilleure/Decoders/IOpCode32Simd.cs +++ b/ARMeilleure/Decoders/IOpCode32Simd.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { interface IOpCode32Simd : IOpCode32, IOpCodeSimd { diff --git a/ARMeilleure/Decoders/IOpCode32SimdImm.cs b/ARMeilleure/Decoders/IOpCode32SimdImm.cs index 81cae5d309..9d3f64794c 100644 --- a/ARMeilleure/Decoders/IOpCode32SimdImm.cs +++ b/ARMeilleure/Decoders/IOpCode32SimdImm.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { interface IOpCode32SimdImm : IOpCode32Simd { diff --git a/ARMeilleure/Decoders/OpCode32AluBf.cs b/ARMeilleure/Decoders/OpCode32AluBf.cs index 315e887187..556c1074d5 100644 --- a/ARMeilleure/Decoders/OpCode32AluBf.cs +++ b/ARMeilleure/Decoders/OpCode32AluBf.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32AluBf : OpCode32, IOpCode32AluBf { diff --git a/ARMeilleure/Decoders/OpCode32AluMla.cs b/ARMeilleure/Decoders/OpCode32AluMla.cs index 352ee8ff5e..4570aa4e2a 100644 --- a/ARMeilleure/Decoders/OpCode32AluMla.cs +++ b/ARMeilleure/Decoders/OpCode32AluMla.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32AluMla : OpCode32, IOpCode32AluReg { diff --git a/ARMeilleure/Decoders/OpCode32AluReg.cs b/ARMeilleure/Decoders/OpCode32AluReg.cs index 7bce876c45..e378dd05d7 100644 --- a/ARMeilleure/Decoders/OpCode32AluReg.cs +++ b/ARMeilleure/Decoders/OpCode32AluReg.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32AluReg : OpCode32Alu, IOpCode32AluReg { diff --git a/ARMeilleure/Decoders/OpCode32AluRsReg.cs b/ARMeilleure/Decoders/OpCode32AluRsReg.cs index 740b8a8b51..d195987bf8 100644 --- a/ARMeilleure/Decoders/OpCode32AluRsReg.cs +++ b/ARMeilleure/Decoders/OpCode32AluRsReg.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32AluRsReg : OpCode32Alu { diff --git a/ARMeilleure/Decoders/OpCode32AluUmull.cs b/ARMeilleure/Decoders/OpCode32AluUmull.cs index 007b7507b6..9b14bf5e61 100644 --- a/ARMeilleure/Decoders/OpCode32AluUmull.cs +++ b/ARMeilleure/Decoders/OpCode32AluUmull.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32AluUmull : OpCode32 { diff --git a/ARMeilleure/Decoders/OpCode32AluUx.cs b/ARMeilleure/Decoders/OpCode32AluUx.cs index 8fc111f918..55c10209de 100644 --- a/ARMeilleure/Decoders/OpCode32AluUx.cs +++ b/ARMeilleure/Decoders/OpCode32AluUx.cs @@ -1,6 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; +using ARMeilleure.State; namespace ARMeilleure.Decoders { @@ -8,7 +6,7 @@ namespace ARMeilleure.Decoders { public int Rotate { get; private set; } public int RotateBits => Rotate * 8; - public bool Add => Rn != 15; + public bool Add => Rn != RegisterAlias.Aarch32Pc; public OpCode32AluUx(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) { diff --git a/ARMeilleure/Decoders/OpCode32Exception.cs b/ARMeilleure/Decoders/OpCode32Exception.cs index aa97f64d3b..1acdf5b122 100644 --- a/ARMeilleure/Decoders/OpCode32Exception.cs +++ b/ARMeilleure/Decoders/OpCode32Exception.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32Exception : OpCode32 { diff --git a/ARMeilleure/Decoders/OpCode32MemLdEx.cs b/ARMeilleure/Decoders/OpCode32MemLdEx.cs index 085c4df805..3d3a6772ef 100644 --- a/ARMeilleure/Decoders/OpCode32MemLdEx.cs +++ b/ARMeilleure/Decoders/OpCode32MemLdEx.cs @@ -1,12 +1,8 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32MemLdEx : OpCode32Mem, IOpCode32MemEx { - public int Rd { get; internal set; } + public int Rd { get; private set; } public OpCode32MemLdEx(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) { Rd = opCode & 0xf; diff --git a/ARMeilleure/Decoders/OpCode32MemReg.cs b/ARMeilleure/Decoders/OpCode32MemReg.cs index 2266047d82..dea42823de 100644 --- a/ARMeilleure/Decoders/OpCode32MemReg.cs +++ b/ARMeilleure/Decoders/OpCode32MemReg.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32MemReg : OpCode32Mem { diff --git a/ARMeilleure/Decoders/OpCode32MemRsImm.cs b/ARMeilleure/Decoders/OpCode32MemRsImm.cs index 3cd9668ab3..33f51145d4 100644 --- a/ARMeilleure/Decoders/OpCode32MemRsImm.cs +++ b/ARMeilleure/Decoders/OpCode32MemRsImm.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32MemRsImm : OpCode32Mem { diff --git a/ARMeilleure/Decoders/OpCode32MemStEx.cs b/ARMeilleure/Decoders/OpCode32MemStEx.cs index 6fd8b9472c..1d9b199852 100644 --- a/ARMeilleure/Decoders/OpCode32MemStEx.cs +++ b/ARMeilleure/Decoders/OpCode32MemStEx.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32MemStEx : OpCode32Mem, IOpCode32MemEx { diff --git a/ARMeilleure/Decoders/OpCode32Simd.cs b/ARMeilleure/Decoders/OpCode32Simd.cs index a40098b190..6c14fba616 100644 --- a/ARMeilleure/Decoders/OpCode32Simd.cs +++ b/ARMeilleure/Decoders/OpCode32Simd.cs @@ -1,10 +1,6 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { - class OpCode32Simd : BaseOpCode32Simd + class OpCode32Simd : OpCode32SimdBase { public int Opc { get; protected set; } public bool Q { get; protected set; } @@ -13,7 +9,7 @@ namespace ARMeilleure.Decoders public OpCode32Simd(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) { - Size = (opCode >> 20) & 0x3; //fvector size: 1 for 16 bit + Size = (opCode >> 20) & 0x3; Q = ((opCode >> 6) & 0x1) != 0; F = ((opCode >> 10) & 0x1) != 0; U = ((opCode >> 24) & 0x1) != 0; @@ -24,7 +20,7 @@ namespace ARMeilleure.Decoders Vd = ((opCode >> 18) & 0x10) | ((opCode >> 12) & 0xf); Vm = ((opCode >> 1) & 0x10) | ((opCode >> 0) & 0xf); - if (this.GetType() == typeof(OpCode32Simd)) // subclasses have their own handling of Vx to account for before checking! + if (this.GetType() == typeof(OpCode32Simd)) // Subclasses have their own handling of Vx to account for before checking. { DecoderHelper.VectorArgumentsInvalid(Q, Vd, Vm); } diff --git a/ARMeilleure/Decoders/BaseOpCode32Simd.cs b/ARMeilleure/Decoders/OpCode32SimdBase.cs similarity index 89% rename from ARMeilleure/Decoders/BaseOpCode32Simd.cs rename to ARMeilleure/Decoders/OpCode32SimdBase.cs index 3073d7bf7b..fc601a3522 100644 --- a/ARMeilleure/Decoders/BaseOpCode32Simd.cs +++ b/ARMeilleure/Decoders/OpCode32SimdBase.cs @@ -1,10 +1,8 @@ using System; -using System.Collections.Generic; -using System.Text; namespace ARMeilleure.Decoders { - abstract class BaseOpCode32Simd : OpCode32, IOpCode32Simd + abstract class OpCode32SimdBase : OpCode32, IOpCode32Simd { public int Vd { get; protected set; } public int Vm { get; protected set; } @@ -29,7 +27,6 @@ namespace ARMeilleure.Decoders switch (RegisterSize) { case RegisterSize.Simd128: - return index >> 1; case RegisterSize.Simd64: return index >> 1; } @@ -50,7 +47,7 @@ namespace ARMeilleure.Decoders throw new InvalidOperationException(); } - public BaseOpCode32Simd(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) + public OpCode32SimdBase(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) { } } diff --git a/ARMeilleure/Decoders/OpCode32SimdBinary.cs b/ARMeilleure/Decoders/OpCode32SimdBinary.cs index fe0ec8ad10..66f63dc5a4 100644 --- a/ARMeilleure/Decoders/OpCode32SimdBinary.cs +++ b/ARMeilleure/Decoders/OpCode32SimdBinary.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { /// /// A special alias that always runs in 64 bit int, to speed up binary ops a little. @@ -12,6 +8,7 @@ namespace ARMeilleure.Decoders public OpCode32SimdBinary(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) { Size = 3; + if (DecoderHelper.VectorArgumentsInvalid(Q, Vd, Vm, Vn)) { Instruction = InstDescriptor.Undefined; diff --git a/ARMeilleure/Decoders/OpCode32SimdCmpZ.cs b/ARMeilleure/Decoders/OpCode32SimdCmpZ.cs index eb5b08692f..567147fbe5 100644 --- a/ARMeilleure/Decoders/OpCode32SimdCmpZ.cs +++ b/ARMeilleure/Decoders/OpCode32SimdCmpZ.cs @@ -1,14 +1,10 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdCmpZ : OpCode32Simd { public OpCode32SimdCmpZ(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) { - Size = (opCode >> 18) & 0x3; //fvector size: 1 for 16 bit + Size = (opCode >> 18) & 0x3; if (DecoderHelper.VectorArgumentsInvalid(Q, Vd, Vm)) { diff --git a/ARMeilleure/Decoders/OpCode32SimdCvtFI.cs b/ARMeilleure/Decoders/OpCode32SimdCvtFI.cs index f58a233f60..aaedcb3cfc 100644 --- a/ARMeilleure/Decoders/OpCode32SimdCvtFI.cs +++ b/ARMeilleure/Decoders/OpCode32SimdCvtFI.cs @@ -1,12 +1,9 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdCvtFI : OpCode32SimdS { public int Opc2 { get; private set; } + public OpCode32SimdCvtFI(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) { Opc2 = (opCode >> 16) & 0x7; diff --git a/ARMeilleure/Decoders/OpCode32SimdDupElem.cs b/ARMeilleure/Decoders/OpCode32SimdDupElem.cs index a34f59cc84..fd83aee5f8 100644 --- a/ARMeilleure/Decoders/OpCode32SimdDupElem.cs +++ b/ARMeilleure/Decoders/OpCode32SimdDupElem.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdDupElem : OpCode32Simd { @@ -34,8 +30,6 @@ namespace ARMeilleure.Decoders Vd = ((opCode >> 18) & 0x10) | ((opCode >> 12) & 0xf); Vm = ((opCode >> 1) & 0x10) | ((opCode >> 0) & 0xf); - Q = (opCode & (1 << 6)) != 0; - if (Q) RegisterSize = RegisterSize.Simd128; if (DecoderHelper.VectorArgumentsInvalid(Q, Vd)) { diff --git a/ARMeilleure/Decoders/OpCode32SimdDupGP.cs b/ARMeilleure/Decoders/OpCode32SimdDupGP.cs index ca85143ab6..62e4e9bb16 100644 --- a/ARMeilleure/Decoders/OpCode32SimdDupGP.cs +++ b/ARMeilleure/Decoders/OpCode32SimdDupGP.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdDupGP : OpCode32, IOpCode32Simd { @@ -13,7 +9,7 @@ namespace ARMeilleure.Decoders public OpCode32SimdDupGP(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) { - Size = 2 - (((opCode >> 21) & 0x2) | ((opCode >> 5) & 0x1)); //B:E - 0 for 32, 16 then 8. + Size = 2 - (((opCode >> 21) & 0x2) | ((opCode >> 5) & 0x1)); // B:E - 0 for 32, 16 then 8. if (Size == -1) { Instruction = InstDescriptor.Undefined; diff --git a/ARMeilleure/Decoders/OpCode32SimdExt.cs b/ARMeilleure/Decoders/OpCode32SimdExt.cs index a2c82bfcb4..1ee0485ee3 100644 --- a/ARMeilleure/Decoders/OpCode32SimdExt.cs +++ b/ARMeilleure/Decoders/OpCode32SimdExt.cs @@ -1,12 +1,9 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdExt : OpCode32SimdReg { public int Immediate { get; private set; } + public OpCode32SimdExt(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) { Immediate = (opCode >> 8) & 0xf; diff --git a/ARMeilleure/Decoders/OpCode32SimdImm.cs b/ARMeilleure/Decoders/OpCode32SimdImm.cs index 6aaa8af67b..72fca59ca6 100644 --- a/ARMeilleure/Decoders/OpCode32SimdImm.cs +++ b/ARMeilleure/Decoders/OpCode32SimdImm.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdImm : OpCode32, IOpCode32SimdImm { @@ -11,6 +7,7 @@ namespace ARMeilleure.Decoders public long Immediate { get; private set; } public int Size { get; private set; } public int Elems => GetBytesCount() >> Size; + public OpCode32SimdImm(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) { Vd = (opCode >> 12) & 0xf; @@ -27,10 +24,7 @@ namespace ARMeilleure.Decoders imm |= ((uint)opCode >> 12) & 0x70; imm |= ((uint)opCode >> 17) & 0x80; - Tuple parsedImm = OpCodeSimdHelper.GetSimdImmediateAndSize(cMode, op, imm, fpBaseSize: 2); - - Immediate = parsedImm.Item1; - Size = parsedImm.Item2; + (Immediate, Size) = OpCodeSimdHelper.GetSimdImmediateAndSize(cMode, op, imm, fpBaseSize: 2); RegisterSize = Q ? RegisterSize.Simd128 : RegisterSize.Simd64; diff --git a/ARMeilleure/Decoders/OpCode32SimdImm44.cs b/ARMeilleure/Decoders/OpCode32SimdImm44.cs index 19de1a4bcd..0334595492 100644 --- a/ARMeilleure/Decoders/OpCode32SimdImm44.cs +++ b/ARMeilleure/Decoders/OpCode32SimdImm44.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdImm44 : OpCode32, IOpCode32SimdImm { @@ -10,6 +6,7 @@ namespace ARMeilleure.Decoders public long Immediate { get; private set; } public int Size { get; private set; } public int Elems { get; private set; } + public OpCode32SimdImm44(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) { Size = (opCode >> 8) & 0x3; diff --git a/ARMeilleure/Decoders/OpCode32SimdImm6.cs b/ARMeilleure/Decoders/OpCode32SimdImm6.cs index 184af7eaa3..7ae4800d96 100644 --- a/ARMeilleure/Decoders/OpCode32SimdImm6.cs +++ b/ARMeilleure/Decoders/OpCode32SimdImm6.cs @@ -1,13 +1,10 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdShift : OpCode32Simd { public int Immediate { get; private set; } public int Shift { get; private set; } + public OpCode32SimdShift(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) { Immediate = (opCode >> 16) & 0x3f; diff --git a/ARMeilleure/Decoders/OpCode32SimdMemImm.cs b/ARMeilleure/Decoders/OpCode32SimdMemImm.cs index 6951603dd7..5063b5bce2 100644 --- a/ARMeilleure/Decoders/OpCode32SimdMemImm.cs +++ b/ARMeilleure/Decoders/OpCode32SimdMemImm.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdMemImm : OpCode32, IOpCode32Simd { diff --git a/ARMeilleure/Decoders/OpCode32SimdMemMult.cs b/ARMeilleure/Decoders/OpCode32SimdMemMult.cs index 4449e59ed8..b855010557 100644 --- a/ARMeilleure/Decoders/OpCode32SimdMemMult.cs +++ b/ARMeilleure/Decoders/OpCode32SimdMemMult.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdMemMult : OpCode32 { @@ -45,7 +41,7 @@ namespace ARMeilleure.Decoders RegisterRange = opCode & 0xff; - int regsSize = RegisterRange * 4; // double mode is still measured in single register size + int regsSize = RegisterRange * 4; // Double mode is still measured in single register size. if (!u) { diff --git a/ARMeilleure/Decoders/OpCode32SimdMemPair.cs b/ARMeilleure/Decoders/OpCode32SimdMemPair.cs index 3b361b71f4..0fd307cfff 100644 --- a/ARMeilleure/Decoders/OpCode32SimdMemPair.cs +++ b/ARMeilleure/Decoders/OpCode32SimdMemPair.cs @@ -1,22 +1,17 @@ using System; -using System.Collections.Generic; -using System.Text; namespace ARMeilleure.Decoders { class OpCode32SimdMemPair : OpCode32, IOpCode32Simd { - private static Dictionary RegsMap = new Dictionary() + private static int[] RegsMap = { - { 0b0111, 1 }, - { 0b1010, 2 }, - { 0b0110, 3 }, - { 0b0010, 4 }, - - { 0b1000, 1 }, - { 0b1001, 1 }, - { 0b0011, 2 }, + 1, 1, 4, 2, + 1, 1, 3, 1, + 1, 1, 2, 1, + 1, 1, 1, 1 }; + public int Vd { get; private set; } public int Rn { get; private set; } public int Rm { get; private set; } @@ -27,6 +22,7 @@ namespace ARMeilleure.Decoders public int Elems => 8 >> Size; public int Regs { get; private set; } public int Increment { get; private set; } + public OpCode32SimdMemPair(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) { Vd = (opCode >> 12) & 0xf; @@ -41,12 +37,7 @@ namespace ARMeilleure.Decoders WBack = Rm != 15; RegisterIndex = (Rm != 15 && Rm != 13); - int regs; - if (!RegsMap.TryGetValue((opCode >> 8) & 0xf, out regs)) - { - regs = 1; - } - Regs = regs; + Regs = RegsMap[(opCode >> 8) & 0xf]; Increment = Math.Min(Regs, ((opCode >> 8) & 0x1) + 1); } diff --git a/ARMeilleure/Decoders/OpCode32SimdMemSingle.cs b/ARMeilleure/Decoders/OpCode32SimdMemSingle.cs index 6c80bf31a8..0f8979a90a 100644 --- a/ARMeilleure/Decoders/OpCode32SimdMemSingle.cs +++ b/ARMeilleure/Decoders/OpCode32SimdMemSingle.cs @@ -1,6 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; +using ARMeilleure.State; namespace ARMeilleure.Decoders { @@ -16,6 +14,7 @@ namespace ARMeilleure.Decoders public int Size { get; private set; } public bool Replicate { get; private set; } public int Increment { get; private set; } + public OpCode32SimdMemSingle(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) { Vd = (opCode >> 12) & 0xf; @@ -40,8 +39,8 @@ namespace ARMeilleure.Decoders Rm = (opCode >> 0) & 0xf; Rn = (opCode >> 16) & 0xf; - WBack = Rm != 15; - RegisterIndex = (Rm != 15 && Rm != 13); + WBack = Rm != RegisterAlias.Aarch32Pc; + RegisterIndex = (Rm != RegisterAlias.Aarch32Pc && Rm != RegisterAlias.Aarch32Sp); } } } diff --git a/ARMeilleure/Decoders/OpCode32SimdMovGp.cs b/ARMeilleure/Decoders/OpCode32SimdMovGp.cs index 2b8e92dad6..aa608c1e0b 100644 --- a/ARMeilleure/Decoders/OpCode32SimdMovGp.cs +++ b/ARMeilleure/Decoders/OpCode32SimdMovGp.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdMovGp : OpCode32, IOpCode32Simd { @@ -14,9 +10,10 @@ namespace ARMeilleure.Decoders public int Opc1 { get; private set; } public int Opc2 { get; private set; } + public OpCode32SimdMovGp(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) { - // which one is used is instruction dependant + // Which one is used is instruction dependant. Op = ((opCode >> 20) & 0x1); Opc1 = ((opCode >> 21) & 0x3); diff --git a/ARMeilleure/Decoders/OpCode32SimdMovGpDouble.cs b/ARMeilleure/Decoders/OpCode32SimdMovGpDouble.cs index dc7eb7a438..81ed623d3e 100644 --- a/ARMeilleure/Decoders/OpCode32SimdMovGpDouble.cs +++ b/ARMeilleure/Decoders/OpCode32SimdMovGpDouble.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdMovGpDouble : OpCode32, IOpCode32Simd { @@ -12,9 +8,10 @@ namespace ARMeilleure.Decoders public int Rt { get; private set; } public int Rt2 { get; private set; } public int Op { get; private set; } + public OpCode32SimdMovGpDouble(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) { - // which one is used is instruction dependant + // Which one is used is instruction dependant. Op = ((opCode >> 20) & 0x1); Rt = (opCode >> 12) & 0xf; diff --git a/ARMeilleure/Decoders/OpCode32SimdMovGpElem.cs b/ARMeilleure/Decoders/OpCode32SimdMovGpElem.cs index 1110a7d369..c05d250a35 100644 --- a/ARMeilleure/Decoders/OpCode32SimdMovGpElem.cs +++ b/ARMeilleure/Decoders/OpCode32SimdMovGpElem.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdMovGpElem : OpCode32, IOpCode32Simd { @@ -15,7 +11,6 @@ namespace ARMeilleure.Decoders public int Index { get; private set; } - public OpCode32SimdMovGpElem(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) { Op = ((opCode >> 20) & 0x1); diff --git a/ARMeilleure/Decoders/OpCode32SimdReg.cs b/ARMeilleure/Decoders/OpCode32SimdReg.cs index 9e286d7e9b..cb32b6c9bb 100644 --- a/ARMeilleure/Decoders/OpCode32SimdReg.cs +++ b/ARMeilleure/Decoders/OpCode32SimdReg.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdReg : OpCode32Simd { @@ -16,7 +12,7 @@ namespace ARMeilleure.Decoders { Vn = ((opCode >> 3) & 0x10) | ((opCode >> 16) & 0xf); - // subclasses have their own handling of Vx to account for before checking! + // Subclasses have their own handling of Vx to account for before checking. if (this.GetType() == typeof(OpCode32SimdReg) && DecoderHelper.VectorArgumentsInvalid(Q, Vd, Vm, Vn)) { Instruction = InstDescriptor.Undefined; diff --git a/ARMeilleure/Decoders/OpCode32SimdRegElem.cs b/ARMeilleure/Decoders/OpCode32SimdRegElem.cs index df4bbe058f..7ac9b5b485 100644 --- a/ARMeilleure/Decoders/OpCode32SimdRegElem.cs +++ b/ARMeilleure/Decoders/OpCode32SimdRegElem.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdRegElem : OpCode32SimdReg { diff --git a/ARMeilleure/Decoders/OpCode32SimdRegS.cs b/ARMeilleure/Decoders/OpCode32SimdRegS.cs index f6cb508862..893ecff6dc 100644 --- a/ARMeilleure/Decoders/OpCode32SimdRegS.cs +++ b/ARMeilleure/Decoders/OpCode32SimdRegS.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdRegS : OpCode32SimdS { diff --git a/ARMeilleure/Decoders/OpCode32SimdRev.cs b/ARMeilleure/Decoders/OpCode32SimdRev.cs index 064d7bfc42..6cdf9f5773 100644 --- a/ARMeilleure/Decoders/OpCode32SimdRev.cs +++ b/ARMeilleure/Decoders/OpCode32SimdRev.cs @@ -1,17 +1,13 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdRev : OpCode32SimdCmpZ { public OpCode32SimdRev(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) { - // Currently, this instruction is treated as though it's OPCODE is the true size. - // which lets us deal with reversing vectors on a single element basis (eg. math magic an I64 rather than insert lots of I8s) + // Currently, this instruction is treated as though it's OPCODE is the true size, + // which lets us deal with reversing vectors on a single element basis (eg. math magic an I64 rather than insert lots of I8s). int tempSize = Size; - Size = 3 - Opc; //op 0 is 64 bit, 1 is 32 and so on. + Size = 3 - Opc; // Op 0 is 64 bit, 1 is 32 and so on. Opc = tempSize; } } diff --git a/ARMeilleure/Decoders/OpCode32SimdS.cs b/ARMeilleure/Decoders/OpCode32SimdS.cs index 6762d75060..fc11269f3a 100644 --- a/ARMeilleure/Decoders/OpCode32SimdS.cs +++ b/ARMeilleure/Decoders/OpCode32SimdS.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdS : OpCode32, IOpCode32Simd { diff --git a/ARMeilleure/Decoders/OpCode32SimdSel.cs b/ARMeilleure/Decoders/OpCode32SimdSel.cs index 93cb4d0c14..aefe138fa7 100644 --- a/ARMeilleure/Decoders/OpCode32SimdSel.cs +++ b/ARMeilleure/Decoders/OpCode32SimdSel.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdSel : OpCode32SimdRegS { diff --git a/ARMeilleure/Decoders/OpCode32SimdSpecial.cs b/ARMeilleure/Decoders/OpCode32SimdSpecial.cs index d7fad13d5b..986afcf94e 100644 --- a/ARMeilleure/Decoders/OpCode32SimdSpecial.cs +++ b/ARMeilleure/Decoders/OpCode32SimdSpecial.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdSpecial : OpCode32 { diff --git a/ARMeilleure/Decoders/OpCode32SimdSqrte.cs b/ARMeilleure/Decoders/OpCode32SimdSqrte.cs index fe8cac1085..9eb7f775d9 100644 --- a/ARMeilleure/Decoders/OpCode32SimdSqrte.cs +++ b/ARMeilleure/Decoders/OpCode32SimdSqrte.cs @@ -1,14 +1,10 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdSqrte : OpCode32Simd { public OpCode32SimdSqrte(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) { - Size = (opCode >> 18) & 0x1; //fvector size: 1 for 16 bit + Size = (opCode >> 18) & 0x1; F = ((opCode >> 8) & 0x1) != 0; if (DecoderHelper.VectorArgumentsInvalid(Q, Vd, Vm)) diff --git a/ARMeilleure/Decoders/OpCode32SimdTbl.cs b/ARMeilleure/Decoders/OpCode32SimdTbl.cs index bf9f3ef8ed..e59627c300 100644 --- a/ARMeilleure/Decoders/OpCode32SimdTbl.cs +++ b/ARMeilleure/Decoders/OpCode32SimdTbl.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32SimdTbl : OpCode32SimdReg { diff --git a/ARMeilleure/Decoders/OpCode32System.cs b/ARMeilleure/Decoders/OpCode32System.cs index 8721834466..bf4383017a 100644 --- a/ARMeilleure/Decoders/OpCode32System.cs +++ b/ARMeilleure/Decoders/OpCode32System.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { class OpCode32System : OpCode32 { diff --git a/ARMeilleure/Decoders/OpCodeSimdHelper.cs b/ARMeilleure/Decoders/OpCodeSimdHelper.cs index 58ad6860ec..086e4b9c29 100644 --- a/ARMeilleure/Decoders/OpCodeSimdHelper.cs +++ b/ARMeilleure/Decoders/OpCodeSimdHelper.cs @@ -1,12 +1,8 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace ARMeilleure.Decoders +namespace ARMeilleure.Decoders { public static class OpCodeSimdHelper { - public static Tuple GetSimdImmediateAndSize(int cMode, int op, long imm, int fpBaseSize = 0) + public static (long Immediate, int Size) GetSimdImmediateAndSize(int cMode, int op, long imm, int fpBaseSize = 0) { int modeLow = cMode & 1; int modeHigh = cMode >> 1; @@ -74,7 +70,7 @@ namespace ARMeilleure.Decoders size = 0; } - return new Tuple(imm, size); + return (imm, size); } public static long VFPExpandImm(long imm, int n) diff --git a/ARMeilleure/Decoders/OpCodeTable.cs b/ARMeilleure/Decoders/OpCodeTable.cs index 1c102b4de0..00e8401d92 100644 --- a/ARMeilleure/Decoders/OpCodeTable.cs +++ b/ARMeilleure/Decoders/OpCodeTable.cs @@ -599,147 +599,147 @@ namespace ARMeilleure.Decoders #region "OpCode Table (AArch32)" // Base - SetA32("<<<<0010101xxxxxxxxxxxxxxxxxxxxx", InstName.Adc, InstEmit32.Adc, typeof(OpCode32AluImm)); - SetA32("<<<<0000101xxxxxxxxxxxxxxxx0xxxx", InstName.Adc, InstEmit32.Adc, typeof(OpCode32AluRsImm)); - SetA32("<<<<0000101xxxxxxxxxxxxx0xx1xxxx", InstName.Adc, InstEmit32.Adc, typeof(OpCode32AluRsReg)); - SetA32("<<<<0010100xxxxxxxxxxxxxxxxxxxxx", InstName.Add, InstEmit32.Add, typeof(OpCode32AluImm)); - SetA32("<<<<0000100xxxxxxxxxxxxxxxx0xxxx", InstName.Add, InstEmit32.Add, typeof(OpCode32AluRsImm)); - SetA32("<<<<0000100xxxxxxxxxxxxx0xx1xxxx", InstName.Add, InstEmit32.Add, typeof(OpCode32AluRsReg)); - SetA32("<<<<0010000xxxxxxxxxxxxxxxxxxxxx", InstName.And, InstEmit32.And, typeof(OpCode32AluImm)); - SetA32("<<<<0000000xxxxxxxxxxxxxxxx0xxxx", InstName.And, InstEmit32.And, typeof(OpCode32AluRsImm)); - SetA32("<<<<0000000xxxxxxxxxxxxx0xx1xxxx", InstName.And, InstEmit32.And, typeof(OpCode32AluRsReg)); - SetA32("<<<<1010xxxxxxxxxxxxxxxxxxxxxxxx", InstName.B, InstEmit32.B, typeof(OpCode32BImm)); - SetA32("<<<<0111110xxxxxxxxxxxxxx0011111", InstName.Bfc, InstEmit32.Bfc, typeof(OpCode32AluBf)); - SetA32("<<<<0111110xxxxxxxxxxxxxx001xxxx", InstName.Bfi, InstEmit32.Bfi, typeof(OpCode32AluBf)); - SetA32("<<<<0011110xxxxxxxxxxxxxxxxxxxxx", InstName.Bic, InstEmit32.Bic, typeof(OpCode32AluImm)); - SetA32("<<<<0001110xxxxxxxxxxxxxxxx0xxxx", InstName.Bic, InstEmit32.Bic, typeof(OpCode32AluRsImm)); - SetA32("<<<<0001110xxxxxxxxxxxxx0xx1xxxx", InstName.Bic, InstEmit32.Bic, typeof(OpCode32AluRsReg)); - SetA32("<<<<1011xxxxxxxxxxxxxxxxxxxxxxxx", InstName.Bl, InstEmit32.Bl, typeof(OpCode32BImm)); - SetA32("1111101xxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Blx, InstEmit32.Blx, typeof(OpCode32BImm)); - SetA32("<<<<000100101111111111110011xxxx", InstName.Blx, InstEmit32.Blxr, typeof(OpCode32BReg)); - SetA32("<<<<000100101111111111110001xxxx", InstName.Bx, InstEmit32.Bx, typeof(OpCode32BReg)); - SetT32("xxxxxxxxxxxxxxxx010001110xxxx000", InstName.Bx, InstEmit32.Bx, typeof(OpCodeT16BReg)); - SetA32("11110101011111111111000000011111", InstName.Clrex, InstEmit32.Clrex, typeof(OpCode32)); - SetA32("<<<<000101101111xxxx11110001xxxx", InstName.Clz, InstEmit32.Clz, typeof(OpCode32AluReg)); - SetA32("<<<<00110111xxxx0000xxxxxxxxxxxx", InstName.Cmn, InstEmit32.Cmn, typeof(OpCode32AluImm)); - SetA32("<<<<00010111xxxx0000xxxxxxx0xxxx", InstName.Cmn, InstEmit32.Cmn, typeof(OpCode32AluRsImm)); - SetA32("<<<<00110101xxxx0000xxxxxxxxxxxx", InstName.Cmp, InstEmit32.Cmp, typeof(OpCode32AluImm)); - SetA32("<<<<00010101xxxx0000xxxxxxx0xxxx", InstName.Cmp, InstEmit32.Cmp, typeof(OpCode32AluRsImm)); - SetA32("<<<<00010101xxxx0000xxxx0xx1xxxx", InstName.Cmp, InstEmit32.Cmp, typeof(OpCode32AluRsReg)); - SetA32("1111010101111111111100000101xxxx", InstName.Dmb, InstEmit32.Dmb, typeof(OpCode32)); - SetA32("1111010101111111111100000100xxxx", InstName.Dsb, InstEmit32.Dsb, typeof(OpCode32)); - SetA32("<<<<0010001xxxxxxxxxxxxxxxxxxxxx", InstName.Eor, InstEmit32.Eor, typeof(OpCode32AluImm)); - SetA32("<<<<0000001xxxxxxxxxxxxxxxx0xxxx", InstName.Eor, InstEmit32.Eor, typeof(OpCode32AluRsImm)); - SetA32("<<<<0000001xxxxxxxxxxxxx0xx1xxxx", InstName.Eor, InstEmit32.Eor, typeof(OpCode32AluRsReg)); - SetA32("1111010101111111111100000110xxxx", InstName.Isb, InstEmit32.Nop, typeof(OpCode32)); - SetA32("<<<<00011001xxxxxxxx110010011111", InstName.Lda, InstEmit32.Lda, typeof(OpCode32MemLdEx)); - SetA32("<<<<00011101xxxxxxxx110010011111", InstName.Ldab, InstEmit32.Ldab, typeof(OpCode32MemLdEx)); - SetA32("<<<<00011001xxxxxxxx111010011111", InstName.Ldaex, InstEmit32.Ldaex, typeof(OpCode32MemLdEx)); - SetA32("<<<<00011101xxxxxxxx111010011111", InstName.Ldaexb,InstEmit32.Ldaexb,typeof(OpCode32MemLdEx)); - SetA32("<<<<00011011xxxxxxxx111010011111", InstName.Ldaexd,InstEmit32.Ldaexd,typeof(OpCode32MemLdEx)); - SetA32("<<<<00011111xxxxxxxx111010011111", InstName.Ldaexh,InstEmit32.Ldaexh,typeof(OpCode32MemLdEx)); - SetA32("<<<<00011111xxxxxxxx110010011111", InstName.Ldah, InstEmit32.Ldah, typeof(OpCode32MemLdEx)); - SetA32("<<<<100xx0x1xxxxxxxxxxxxxxxxxxxx", InstName.Ldm, InstEmit32.Ldm, typeof(OpCode32MemMult)); - SetA32("<<<<010xx0x1xxxxxxxxxxxxxxxxxxxx", InstName.Ldr, InstEmit32.Ldr, typeof(OpCode32MemImm)); - SetA32("<<<<011xx0x1xxxxxxxxxxxxxxx0xxxx", InstName.Ldr, InstEmit32.Ldr, typeof(OpCode32MemRsImm)); - SetA32("<<<<010xx1x1xxxxxxxxxxxxxxxxxxxx", InstName.Ldrb, InstEmit32.Ldrb, typeof(OpCode32MemImm)); - SetA32("<<<<011xx1x1xxxxxxxxxxxxxxx0xxxx", InstName.Ldrb, InstEmit32.Ldrb, typeof(OpCode32MemRsImm)); - SetA32("<<<<000xx1x0xxxxxxxxxxxx1101xxxx", InstName.Ldrd, InstEmit32.Ldrd, typeof(OpCode32MemImm8)); - SetA32("<<<<000xx0x0xxxxxxxx00001101xxxx", InstName.Ldrd, InstEmit32.Ldrd, typeof(OpCode32MemReg)); - SetA32("<<<<00011001xxxxxxxx111110011111", InstName.Ldrex, InstEmit32.Ldrex, typeof(OpCode32MemLdEx)); - SetA32("<<<<00011101xxxxxxxx111110011111", InstName.Ldrexb,InstEmit32.Ldrexb,typeof(OpCode32MemLdEx)); - SetA32("<<<<00011011xxxxxxxx111110011111", InstName.Ldrexd,InstEmit32.Ldrexd,typeof(OpCode32MemLdEx)); - SetA32("<<<<00011111xxxxxxxx111110011111", InstName.Ldrexh,InstEmit32.Ldrexh,typeof(OpCode32MemLdEx)); - SetA32("<<<<000xx1x1xxxxxxxxxxxx1011xxxx", InstName.Ldrh, InstEmit32.Ldrh, typeof(OpCode32MemImm8)); - SetA32("<<<<000xx0x1xxxxxxxx00001011xxxx", InstName.Ldrh, InstEmit32.Ldrh, typeof(OpCode32MemReg)); - 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("<<<<000xx0x1xxxxxxxx00001111xxxx", InstName.Ldrsh, InstEmit32.Ldrsh, typeof(OpCode32MemReg)); - SetA32("<<<<1110xxx0xxxxxxxx111xxxx1xxxx", InstName.Mcr, InstEmit32.Mcr, typeof(OpCode32System)); - SetA32("<<<<0000001xxxxxxxxxxxxx1001xxxx", InstName.Mla, InstEmit32.Mla, typeof(OpCode32AluMla)); - SetA32("<<<<00000110xxxxxxxxxxxx1001xxxx", InstName.Mls, InstEmit32.Mls, typeof(OpCode32AluMla)); - SetA32("<<<<0011101x0000xxxxxxxxxxxxxxxx", InstName.Mov, InstEmit32.Mov, typeof(OpCode32AluImm)); - SetA32("<<<<0001101x0000xxxxxxxxxxx0xxxx", InstName.Mov, InstEmit32.Mov, typeof(OpCode32AluRsImm)); - SetA32("<<<<0001101x0000xxxxxxxx0xx1xxxx", InstName.Mov, InstEmit32.Mov, typeof(OpCode32AluRsReg)); - SetA32("<<<<00110000xxxxxxxxxxxxxxxxxxxx", InstName.Mov, InstEmit32.Mov, typeof(OpCode32AluImm16)); - SetT32("xxxxxxxxxxxxxxxx00100xxxxxxxxxxx", InstName.Mov, InstEmit32.Mov, typeof(OpCodeT16AluImm8)); - SetA32("<<<<00110100xxxxxxxxxxxxxxxxxxxx", InstName.Movt, InstEmit32.Movt, typeof(OpCode32AluImm16)); - SetA32("<<<<1110xxx1xxxxxxxx111xxxx1xxxx", InstName.Mrc, InstEmit32.Mrc, typeof(OpCode32System)); - SetA32("<<<<11000101xxxxxxxx111xxxxxxxxx", InstName.Mrrc, InstEmit32.Mrrc, typeof(OpCode32System)); - SetA32("<<<<0000000xxxxx0000xxxx1001xxxx", InstName.Mul, InstEmit32.Mul, typeof(OpCode32AluMla)); - SetA32("<<<<0011111x0000xxxxxxxxxxxxxxxx", InstName.Mvn, InstEmit32.Mvn, typeof(OpCode32AluImm)); - SetA32("<<<<0001111x0000xxxxxxxxxxx0xxxx", InstName.Mvn, InstEmit32.Mvn, typeof(OpCode32AluRsImm)); - SetA32("<<<<0001111x0000xxxxxxxx0xx1xxxx", InstName.Mvn, InstEmit32.Mvn, typeof(OpCode32AluRsReg)); - SetA32("<<<<0011100xxxxxxxxxxxxxxxxxxxxx", InstName.Orr, InstEmit32.Orr, typeof(OpCode32AluImm)); - SetA32("<<<<0001100xxxxxxxxxxxxxxxx0xxxx", InstName.Orr, InstEmit32.Orr, typeof(OpCode32AluRsImm)); - SetA32("<<<<0001100xxxxxxxxxxxxx0xx1xxxx", InstName.Orr, InstEmit32.Orr, typeof(OpCode32AluRsReg)); - SetA32("<<<<01101000xxxxxxxxxxxxxx01xxxx", InstName.Pkh, InstEmit32.Pkh, typeof(OpCode32AluRsImm)); - SetA32("11110101xx01xxxx1111xxxxxxxxxxxx", InstName.Pld, InstEmit32.Nop, typeof(OpCode32)); //preload hint for cache - nop - SetA32("11110111xx01xxxx1111xxxxxxx0xxxx", InstName.Pld, InstEmit32.Nop, typeof(OpCode32)); //rs imm, but nop - SetA32("<<<<011011111111xxxx11110011xxxx", InstName.Rbit, InstEmit32.Rbit, typeof(OpCode32AluReg)); - SetA32("<<<<011010111111xxxx11110011xxxx", InstName.Rev, InstEmit32.Rev, typeof(OpCode32AluReg)); - SetA32("<<<<011010111111xxxx11111011xxxx", InstName.Rev16, InstEmit32.Rev16, typeof(OpCode32AluReg)); - SetA32("<<<<011011111111xxxx11111011xxxx", InstName.Revsh, InstEmit32.Revsh, typeof(OpCode32AluReg)); - SetA32("<<<<0010011xxxxxxxxxxxxxxxxxxxxx", InstName.Rsb, InstEmit32.Rsb, typeof(OpCode32AluImm)); - SetA32("<<<<0000011xxxxxxxxxxxxxxxx0xxxx", InstName.Rsb, InstEmit32.Rsb, typeof(OpCode32AluRsImm)); - SetA32("<<<<0000011xxxxxxxxxxxxx0xx1xxxx", InstName.Rsb, InstEmit32.Rsb, typeof(OpCode32AluRsReg)); - SetA32("<<<<0010111xxxxxxxxxxxxxxxxxxxxx", InstName.Rsc, InstEmit32.Rsc, typeof(OpCode32AluImm)); - SetA32("<<<<0000111xxxxxxxxxxxxxxxx0xxxx", InstName.Rsc, InstEmit32.Rsc, typeof(OpCode32AluRsImm)); - SetA32("<<<<0000111xxxxxxxxxxxxx0xx1xxxx", InstName.Rsc, InstEmit32.Rsc, typeof(OpCode32AluRsReg)); - SetA32("<<<<0010110xxxxxxxxxxxxxxxxxxxxx", InstName.Sbc, InstEmit32.Sbc, typeof(OpCode32AluImm)); - SetA32("<<<<0000110xxxxxxxxxxxxxxxx0xxxx", InstName.Sbc, InstEmit32.Sbc, typeof(OpCode32AluRsImm)); - SetA32("<<<<0000110xxxxxxxxxxxxx0xx1xxxx", InstName.Sbc, InstEmit32.Sbc, typeof(OpCode32AluRsReg)); - SetA32("<<<<0111101xxxxxxxxxxxxxx101xxxx", InstName.Sbfx, InstEmit32.Sbfx, typeof(OpCode32AluBf)); - SetA32("<<<<01110001xxxx1111xxxx0001xxxx", InstName.Sdiv, InstEmit32.Sdiv, typeof(OpCode32AluMla)); - SetA32("<<<<00010000xxxxxxxxxxxx1xx0xxxx", InstName.Smlab, InstEmit32.Smlab, typeof(OpCode32AluMla)); - SetA32("<<<<0000111xxxxxxxxxxxxx1001xxxx", InstName.Smlal, InstEmit32.Smlal, typeof(OpCode32AluUmull)); - SetA32("<<<<00010100xxxxxxxxxxxx1xx0xxxx", InstName.Smlalh,InstEmit32.Smlalh,typeof(OpCode32AluUmull)); - SetA32("<<<<01110101xxxxxxxxxxxx00x1xxxx", InstName.Smmla, InstEmit32.Smmla, typeof(OpCode32AluMla)); - SetA32("<<<<01110101xxxxxxxxxxxx11x1xxxx", InstName.Smmls, InstEmit32.Smmls, typeof(OpCode32AluMla)); - SetA32("<<<<00010110xxxxxxxxxxxx1xx0xxxx", InstName.Smulh, InstEmit32.Smulh, typeof(OpCode32AluMla)); - SetA32("<<<<0000110xxxxxxxxxxxxx1001xxxx", InstName.Smull, InstEmit32.Smull, typeof(OpCode32AluUmull)); - SetA32("<<<<00011000xxxx111111001001xxxx", InstName.Stl, InstEmit32.Stl, typeof(OpCode32MemStEx)); - SetA32("<<<<00011100xxxx111111001001xxxx", InstName.Stlb, InstEmit32.Stlb, typeof(OpCode32MemStEx)); - SetA32("<<<<00011000xxxxxxxx11101001xxxx", InstName.Stlex, InstEmit32.Stlex, typeof(OpCode32MemStEx)); - SetA32("<<<<00011100xxxxxxxx11101001xxxx", InstName.Stlexb,InstEmit32.Stlexb,typeof(OpCode32MemStEx)); - SetA32("<<<<00011010xxxxxxxx11101001xxxx", InstName.Stlexd,InstEmit32.Stlexd,typeof(OpCode32MemStEx)); - SetA32("<<<<00011110xxxxxxxx11101001xxxx", InstName.Stlexh,InstEmit32.Stlexh,typeof(OpCode32MemStEx)); - SetA32("<<<<00011110xxxx111111001001xxxx", InstName.Stlh, InstEmit32.Stlh, typeof(OpCode32MemStEx)); - SetA32("<<<<100xx0x0xxxxxxxxxxxxxxxxxxxx", InstName.Stm, InstEmit32.Stm, typeof(OpCode32MemMult)); - SetA32("<<<<010xx0x0xxxxxxxxxxxxxxxxxxxx", InstName.Str, InstEmit32.Str, typeof(OpCode32MemImm)); - SetA32("<<<<011xx0x0xxxxxxxxxxxxxxx0xxxx", InstName.Str, InstEmit32.Str, typeof(OpCode32MemRsImm)); - SetA32("<<<<010xx1x0xxxxxxxxxxxxxxxxxxxx", InstName.Strb, InstEmit32.Strb, typeof(OpCode32MemImm)); - SetA32("<<<<011xx1x0xxxxxxxxxxxxxxx0xxxx", InstName.Strb, InstEmit32.Strb, typeof(OpCode32MemRsImm)); - SetA32("<<<<000xx1x0xxxxxxxxxxxx1111xxxx", InstName.Strd, InstEmit32.Strd, typeof(OpCode32MemImm8)); - SetA32("<<<<000xx0x0xxxxxxxx00001111xxxx", InstName.Strd, InstEmit32.Strd, typeof(OpCode32MemReg)); - SetA32("<<<<00011000xxxxxxxx11111001xxxx", InstName.Strex, InstEmit32.Strex, typeof(OpCode32MemStEx)); - SetA32("<<<<00011100xxxxxxxx11111001xxxx", InstName.Strexb,InstEmit32.Strexb,typeof(OpCode32MemStEx)); - SetA32("<<<<00011010xxxxxxxx11111001xxxx", InstName.Strexd,InstEmit32.Strexd,typeof(OpCode32MemStEx)); - SetA32("<<<<00011110xxxxxxxx11111001xxxx", InstName.Strexh,InstEmit32.Strexh,typeof(OpCode32MemStEx)); - SetA32("<<<<000xx1x0xxxxxxxxxxxx1011xxxx", InstName.Strh, InstEmit32.Strh, typeof(OpCode32MemImm8)); - SetA32("<<<<000xx0x0xxxxxxxx00001011xxxx", InstName.Strh, InstEmit32.Strh, typeof(OpCode32MemReg)); - SetA32("<<<<0010010xxxxxxxxxxxxxxxxxxxxx", InstName.Sub, InstEmit32.Sub, typeof(OpCode32AluImm)); - SetA32("<<<<0000010xxxxxxxxxxxxxxxx0xxxx", InstName.Sub, InstEmit32.Sub, typeof(OpCode32AluRsImm)); - SetA32("<<<<0000010xxxxxxxxxxxxx0xx1xxxx", InstName.Sub, InstEmit32.Sub, typeof(OpCode32AluRsReg)); - SetA32("<<<<1111xxxxxxxxxxxxxxxxxxxxxxxx", InstName.Svc, InstEmit32.Svc, typeof(OpCode32Exception)); - 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("<<<<00110011xxxx0000xxxxxxxxxxxx", InstName.Teq, InstEmit32.Teq, typeof(OpCode32AluImm)); - SetA32("<<<<00010011xxxx0000xxxxxxx0xxxx", InstName.Teq, InstEmit32.Teq, typeof(OpCode32AluRsImm)); - SetA32("<<<<00010011xxxx0000xxxx0xx1xxxx", InstName.Teq, InstEmit32.Teq, typeof(OpCode32AluRsReg)); - SetA32("<<<<0111111111111101111011111110", InstName.Trap, InstEmit32.Trap, typeof(OpCode32Exception)); - SetA32("<<<<00110001xxxx0000xxxxxxxxxxxx", InstName.Tst, InstEmit32.Tst, typeof(OpCode32AluImm)); - SetA32("<<<<00010001xxxx0000xxxxxxx0xxxx", InstName.Tst, InstEmit32.Tst, typeof(OpCode32AluRsImm)); - SetA32("<<<<00010001xxxx0000xxxx0xx1xxxx", InstName.Tst, InstEmit32.Tst, typeof(OpCode32AluRsReg)); - SetA32("<<<<0111111xxxxxxxxxxxxxx101xxxx", InstName.Ubfx, InstEmit32.Ubfx, typeof(OpCode32AluBf)); - SetA32("<<<<01110011xxxx1111xxxx0001xxxx", InstName.Udiv, InstEmit32.Udiv, typeof(OpCode32AluMla)); - SetA32("<<<<0000101xxxxxxxxxxxxx1001xxxx", InstName.Umlal, InstEmit32.Umlal, typeof(OpCode32AluUmull)); - SetA32("<<<<0000100xxxxxxxxxxxxx1001xxxx", InstName.Umull, InstEmit32.Umull, typeof(OpCode32AluUmull)); - 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("<<<<0010101xxxxxxxxxxxxxxxxxxxxx", InstName.Adc, InstEmit32.Adc, typeof(OpCode32AluImm)); + SetA32("<<<<0000101xxxxxxxxxxxxxxxx0xxxx", InstName.Adc, InstEmit32.Adc, typeof(OpCode32AluRsImm)); + SetA32("<<<<0000101xxxxxxxxxxxxx0xx1xxxx", InstName.Adc, InstEmit32.Adc, typeof(OpCode32AluRsReg)); + SetA32("<<<<0010100xxxxxxxxxxxxxxxxxxxxx", InstName.Add, InstEmit32.Add, typeof(OpCode32AluImm)); + SetA32("<<<<0000100xxxxxxxxxxxxxxxx0xxxx", InstName.Add, InstEmit32.Add, typeof(OpCode32AluRsImm)); + SetA32("<<<<0000100xxxxxxxxxxxxx0xx1xxxx", InstName.Add, InstEmit32.Add, typeof(OpCode32AluRsReg)); + SetA32("<<<<0010000xxxxxxxxxxxxxxxxxxxxx", InstName.And, InstEmit32.And, typeof(OpCode32AluImm)); + SetA32("<<<<0000000xxxxxxxxxxxxxxxx0xxxx", InstName.And, InstEmit32.And, typeof(OpCode32AluRsImm)); + SetA32("<<<<0000000xxxxxxxxxxxxx0xx1xxxx", InstName.And, InstEmit32.And, typeof(OpCode32AluRsReg)); + SetA32("<<<<1010xxxxxxxxxxxxxxxxxxxxxxxx", InstName.B, InstEmit32.B, typeof(OpCode32BImm)); + SetA32("<<<<0111110xxxxxxxxxxxxxx0011111", InstName.Bfc, InstEmit32.Bfc, typeof(OpCode32AluBf)); + SetA32("<<<<0111110xxxxxxxxxxxxxx001xxxx", InstName.Bfi, InstEmit32.Bfi, typeof(OpCode32AluBf)); + SetA32("<<<<0011110xxxxxxxxxxxxxxxxxxxxx", InstName.Bic, InstEmit32.Bic, typeof(OpCode32AluImm)); + SetA32("<<<<0001110xxxxxxxxxxxxxxxx0xxxx", InstName.Bic, InstEmit32.Bic, typeof(OpCode32AluRsImm)); + SetA32("<<<<0001110xxxxxxxxxxxxx0xx1xxxx", InstName.Bic, InstEmit32.Bic, typeof(OpCode32AluRsReg)); + SetA32("<<<<1011xxxxxxxxxxxxxxxxxxxxxxxx", InstName.Bl, InstEmit32.Bl, typeof(OpCode32BImm)); + SetA32("1111101xxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Blx, InstEmit32.Blx, typeof(OpCode32BImm)); + SetA32("<<<<000100101111111111110011xxxx", InstName.Blx, InstEmit32.Blxr, typeof(OpCode32BReg)); + SetA32("<<<<000100101111111111110001xxxx", InstName.Bx, InstEmit32.Bx, typeof(OpCode32BReg)); + SetT32("xxxxxxxxxxxxxxxx010001110xxxx000", InstName.Bx, InstEmit32.Bx, typeof(OpCodeT16BReg)); + SetA32("11110101011111111111000000011111", InstName.Clrex, InstEmit32.Clrex, typeof(OpCode32)); + SetA32("<<<<000101101111xxxx11110001xxxx", InstName.Clz, InstEmit32.Clz, typeof(OpCode32AluReg)); + SetA32("<<<<00110111xxxx0000xxxxxxxxxxxx", InstName.Cmn, InstEmit32.Cmn, typeof(OpCode32AluImm)); + SetA32("<<<<00010111xxxx0000xxxxxxx0xxxx", InstName.Cmn, InstEmit32.Cmn, typeof(OpCode32AluRsImm)); + SetA32("<<<<00110101xxxx0000xxxxxxxxxxxx", InstName.Cmp, InstEmit32.Cmp, typeof(OpCode32AluImm)); + SetA32("<<<<00010101xxxx0000xxxxxxx0xxxx", InstName.Cmp, InstEmit32.Cmp, typeof(OpCode32AluRsImm)); + SetA32("<<<<00010101xxxx0000xxxx0xx1xxxx", InstName.Cmp, InstEmit32.Cmp, typeof(OpCode32AluRsReg)); + SetA32("1111010101111111111100000101xxxx", InstName.Dmb, InstEmit32.Dmb, typeof(OpCode32)); + SetA32("1111010101111111111100000100xxxx", InstName.Dsb, InstEmit32.Dsb, typeof(OpCode32)); + SetA32("<<<<0010001xxxxxxxxxxxxxxxxxxxxx", InstName.Eor, InstEmit32.Eor, typeof(OpCode32AluImm)); + SetA32("<<<<0000001xxxxxxxxxxxxxxxx0xxxx", InstName.Eor, InstEmit32.Eor, typeof(OpCode32AluRsImm)); + SetA32("<<<<0000001xxxxxxxxxxxxx0xx1xxxx", InstName.Eor, InstEmit32.Eor, typeof(OpCode32AluRsReg)); + SetA32("1111010101111111111100000110xxxx", InstName.Isb, InstEmit32.Nop, typeof(OpCode32)); + SetA32("<<<<00011001xxxxxxxx110010011111", InstName.Lda, InstEmit32.Lda, typeof(OpCode32MemLdEx)); + SetA32("<<<<00011101xxxxxxxx110010011111", InstName.Ldab, InstEmit32.Ldab, typeof(OpCode32MemLdEx)); + SetA32("<<<<00011001xxxxxxxx111010011111", InstName.Ldaex, InstEmit32.Ldaex, typeof(OpCode32MemLdEx)); + SetA32("<<<<00011101xxxxxxxx111010011111", InstName.Ldaexb, InstEmit32.Ldaexb, typeof(OpCode32MemLdEx)); + SetA32("<<<<00011011xxxxxxxx111010011111", InstName.Ldaexd, InstEmit32.Ldaexd, typeof(OpCode32MemLdEx)); + SetA32("<<<<00011111xxxxxxxx111010011111", InstName.Ldaexh, InstEmit32.Ldaexh, typeof(OpCode32MemLdEx)); + SetA32("<<<<00011111xxxxxxxx110010011111", InstName.Ldah, InstEmit32.Ldah, typeof(OpCode32MemLdEx)); + SetA32("<<<<100xx0x1xxxxxxxxxxxxxxxxxxxx", InstName.Ldm, InstEmit32.Ldm, typeof(OpCode32MemMult)); + SetA32("<<<<010xx0x1xxxxxxxxxxxxxxxxxxxx", InstName.Ldr, InstEmit32.Ldr, typeof(OpCode32MemImm)); + SetA32("<<<<011xx0x1xxxxxxxxxxxxxxx0xxxx", InstName.Ldr, InstEmit32.Ldr, typeof(OpCode32MemRsImm)); + SetA32("<<<<010xx1x1xxxxxxxxxxxxxxxxxxxx", InstName.Ldrb, InstEmit32.Ldrb, typeof(OpCode32MemImm)); + SetA32("<<<<011xx1x1xxxxxxxxxxxxxxx0xxxx", InstName.Ldrb, InstEmit32.Ldrb, typeof(OpCode32MemRsImm)); + SetA32("<<<<000xx1x0xxxxxxxxxxxx1101xxxx", InstName.Ldrd, InstEmit32.Ldrd, typeof(OpCode32MemImm8)); + SetA32("<<<<000xx0x0xxxxxxxx00001101xxxx", InstName.Ldrd, InstEmit32.Ldrd, typeof(OpCode32MemReg)); + SetA32("<<<<00011001xxxxxxxx111110011111", InstName.Ldrex, InstEmit32.Ldrex, typeof(OpCode32MemLdEx)); + SetA32("<<<<00011101xxxxxxxx111110011111", InstName.Ldrexb, InstEmit32.Ldrexb, typeof(OpCode32MemLdEx)); + SetA32("<<<<00011011xxxxxxxx111110011111", InstName.Ldrexd, InstEmit32.Ldrexd, typeof(OpCode32MemLdEx)); + SetA32("<<<<00011111xxxxxxxx111110011111", InstName.Ldrexh, InstEmit32.Ldrexh, typeof(OpCode32MemLdEx)); + SetA32("<<<<000xx1x1xxxxxxxxxxxx1011xxxx", InstName.Ldrh, InstEmit32.Ldrh, typeof(OpCode32MemImm8)); + SetA32("<<<<000xx0x1xxxxxxxx00001011xxxx", InstName.Ldrh, InstEmit32.Ldrh, typeof(OpCode32MemReg)); + 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("<<<<000xx0x1xxxxxxxx00001111xxxx", InstName.Ldrsh, InstEmit32.Ldrsh, typeof(OpCode32MemReg)); + SetA32("<<<<1110xxx0xxxxxxxx111xxxx1xxxx", InstName.Mcr, InstEmit32.Mcr, typeof(OpCode32System)); + SetA32("<<<<0000001xxxxxxxxxxxxx1001xxxx", InstName.Mla, InstEmit32.Mla, typeof(OpCode32AluMla)); + SetA32("<<<<00000110xxxxxxxxxxxx1001xxxx", InstName.Mls, InstEmit32.Mls, typeof(OpCode32AluMla)); + SetA32("<<<<0011101x0000xxxxxxxxxxxxxxxx", InstName.Mov, InstEmit32.Mov, typeof(OpCode32AluImm)); + SetA32("<<<<0001101x0000xxxxxxxxxxx0xxxx", InstName.Mov, InstEmit32.Mov, typeof(OpCode32AluRsImm)); + SetA32("<<<<0001101x0000xxxxxxxx0xx1xxxx", InstName.Mov, InstEmit32.Mov, typeof(OpCode32AluRsReg)); + SetA32("<<<<00110000xxxxxxxxxxxxxxxxxxxx", InstName.Mov, InstEmit32.Mov, typeof(OpCode32AluImm16)); + SetT32("xxxxxxxxxxxxxxxx00100xxxxxxxxxxx", InstName.Mov, InstEmit32.Mov, typeof(OpCodeT16AluImm8)); + SetA32("<<<<00110100xxxxxxxxxxxxxxxxxxxx", InstName.Movt, InstEmit32.Movt, typeof(OpCode32AluImm16)); + SetA32("<<<<1110xxx1xxxxxxxx111xxxx1xxxx", InstName.Mrc, InstEmit32.Mrc, typeof(OpCode32System)); + SetA32("<<<<11000101xxxxxxxx111xxxxxxxxx", InstName.Mrrc, InstEmit32.Mrrc, typeof(OpCode32System)); + SetA32("<<<<0000000xxxxx0000xxxx1001xxxx", InstName.Mul, InstEmit32.Mul, typeof(OpCode32AluMla)); + SetA32("<<<<0011111x0000xxxxxxxxxxxxxxxx", InstName.Mvn, InstEmit32.Mvn, typeof(OpCode32AluImm)); + SetA32("<<<<0001111x0000xxxxxxxxxxx0xxxx", InstName.Mvn, InstEmit32.Mvn, typeof(OpCode32AluRsImm)); + SetA32("<<<<0001111x0000xxxxxxxx0xx1xxxx", InstName.Mvn, InstEmit32.Mvn, typeof(OpCode32AluRsReg)); + SetA32("<<<<0011100xxxxxxxxxxxxxxxxxxxxx", InstName.Orr, InstEmit32.Orr, typeof(OpCode32AluImm)); + SetA32("<<<<0001100xxxxxxxxxxxxxxxx0xxxx", InstName.Orr, InstEmit32.Orr, typeof(OpCode32AluRsImm)); + SetA32("<<<<0001100xxxxxxxxxxxxx0xx1xxxx", InstName.Orr, InstEmit32.Orr, typeof(OpCode32AluRsReg)); + SetA32("<<<<01101000xxxxxxxxxxxxxx01xxxx", InstName.Pkh, InstEmit32.Pkh, typeof(OpCode32AluRsImm)); + SetA32("11110101xx01xxxx1111xxxxxxxxxxxx", InstName.Pld, InstEmit32.Nop, typeof(OpCode32)); + SetA32("11110111xx01xxxx1111xxxxxxx0xxxx", InstName.Pld, InstEmit32.Nop, typeof(OpCode32)); + SetA32("<<<<011011111111xxxx11110011xxxx", InstName.Rbit, InstEmit32.Rbit, typeof(OpCode32AluReg)); + SetA32("<<<<011010111111xxxx11110011xxxx", InstName.Rev, InstEmit32.Rev, typeof(OpCode32AluReg)); + SetA32("<<<<011010111111xxxx11111011xxxx", InstName.Rev16, InstEmit32.Rev16, typeof(OpCode32AluReg)); + SetA32("<<<<011011111111xxxx11111011xxxx", InstName.Revsh, InstEmit32.Revsh, typeof(OpCode32AluReg)); + SetA32("<<<<0010011xxxxxxxxxxxxxxxxxxxxx", InstName.Rsb, InstEmit32.Rsb, typeof(OpCode32AluImm)); + SetA32("<<<<0000011xxxxxxxxxxxxxxxx0xxxx", InstName.Rsb, InstEmit32.Rsb, typeof(OpCode32AluRsImm)); + SetA32("<<<<0000011xxxxxxxxxxxxx0xx1xxxx", InstName.Rsb, InstEmit32.Rsb, typeof(OpCode32AluRsReg)); + SetA32("<<<<0010111xxxxxxxxxxxxxxxxxxxxx", InstName.Rsc, InstEmit32.Rsc, typeof(OpCode32AluImm)); + SetA32("<<<<0000111xxxxxxxxxxxxxxxx0xxxx", InstName.Rsc, InstEmit32.Rsc, typeof(OpCode32AluRsImm)); + SetA32("<<<<0000111xxxxxxxxxxxxx0xx1xxxx", InstName.Rsc, InstEmit32.Rsc, typeof(OpCode32AluRsReg)); + SetA32("<<<<0010110xxxxxxxxxxxxxxxxxxxxx", InstName.Sbc, InstEmit32.Sbc, typeof(OpCode32AluImm)); + SetA32("<<<<0000110xxxxxxxxxxxxxxxx0xxxx", InstName.Sbc, InstEmit32.Sbc, typeof(OpCode32AluRsImm)); + SetA32("<<<<0000110xxxxxxxxxxxxx0xx1xxxx", InstName.Sbc, InstEmit32.Sbc, typeof(OpCode32AluRsReg)); + SetA32("<<<<0111101xxxxxxxxxxxxxx101xxxx", InstName.Sbfx, InstEmit32.Sbfx, typeof(OpCode32AluBf)); + SetA32("<<<<01110001xxxx1111xxxx0001xxxx", InstName.Sdiv, InstEmit32.Sdiv, typeof(OpCode32AluMla)); + SetA32("<<<<00010000xxxxxxxxxxxx1xx0xxxx", InstName.Smlab, InstEmit32.Smlab, typeof(OpCode32AluMla)); + SetA32("<<<<0000111xxxxxxxxxxxxx1001xxxx", InstName.Smlal, InstEmit32.Smlal, typeof(OpCode32AluUmull)); + SetA32("<<<<00010100xxxxxxxxxxxx1xx0xxxx", InstName.Smlalh, InstEmit32.Smlalh, typeof(OpCode32AluUmull)); + SetA32("<<<<01110101xxxxxxxxxxxx00x1xxxx", InstName.Smmla, InstEmit32.Smmla, typeof(OpCode32AluMla)); + SetA32("<<<<01110101xxxxxxxxxxxx11x1xxxx", InstName.Smmls, InstEmit32.Smmls, typeof(OpCode32AluMla)); + SetA32("<<<<00010110xxxxxxxxxxxx1xx0xxxx", InstName.Smulh, InstEmit32.Smulh, typeof(OpCode32AluMla)); + SetA32("<<<<0000110xxxxxxxxxxxxx1001xxxx", InstName.Smull, InstEmit32.Smull, typeof(OpCode32AluUmull)); + SetA32("<<<<00011000xxxx111111001001xxxx", InstName.Stl, InstEmit32.Stl, typeof(OpCode32MemStEx)); + SetA32("<<<<00011100xxxx111111001001xxxx", InstName.Stlb, InstEmit32.Stlb, typeof(OpCode32MemStEx)); + SetA32("<<<<00011000xxxxxxxx11101001xxxx", InstName.Stlex, InstEmit32.Stlex, typeof(OpCode32MemStEx)); + SetA32("<<<<00011100xxxxxxxx11101001xxxx", InstName.Stlexb, InstEmit32.Stlexb, typeof(OpCode32MemStEx)); + SetA32("<<<<00011010xxxxxxxx11101001xxxx", InstName.Stlexd, InstEmit32.Stlexd, typeof(OpCode32MemStEx)); + SetA32("<<<<00011110xxxxxxxx11101001xxxx", InstName.Stlexh, InstEmit32.Stlexh, typeof(OpCode32MemStEx)); + SetA32("<<<<00011110xxxx111111001001xxxx", InstName.Stlh, InstEmit32.Stlh, typeof(OpCode32MemStEx)); + SetA32("<<<<100xx0x0xxxxxxxxxxxxxxxxxxxx", InstName.Stm, InstEmit32.Stm, typeof(OpCode32MemMult)); + SetA32("<<<<010xx0x0xxxxxxxxxxxxxxxxxxxx", InstName.Str, InstEmit32.Str, typeof(OpCode32MemImm)); + SetA32("<<<<011xx0x0xxxxxxxxxxxxxxx0xxxx", InstName.Str, InstEmit32.Str, typeof(OpCode32MemRsImm)); + SetA32("<<<<010xx1x0xxxxxxxxxxxxxxxxxxxx", InstName.Strb, InstEmit32.Strb, typeof(OpCode32MemImm)); + SetA32("<<<<011xx1x0xxxxxxxxxxxxxxx0xxxx", InstName.Strb, InstEmit32.Strb, typeof(OpCode32MemRsImm)); + SetA32("<<<<000xx1x0xxxxxxxxxxxx1111xxxx", InstName.Strd, InstEmit32.Strd, typeof(OpCode32MemImm8)); + SetA32("<<<<000xx0x0xxxxxxxx00001111xxxx", InstName.Strd, InstEmit32.Strd, typeof(OpCode32MemReg)); + SetA32("<<<<00011000xxxxxxxx11111001xxxx", InstName.Strex, InstEmit32.Strex, typeof(OpCode32MemStEx)); + SetA32("<<<<00011100xxxxxxxx11111001xxxx", InstName.Strexb, InstEmit32.Strexb, typeof(OpCode32MemStEx)); + SetA32("<<<<00011010xxxxxxxx11111001xxxx", InstName.Strexd, InstEmit32.Strexd, typeof(OpCode32MemStEx)); + SetA32("<<<<00011110xxxxxxxx11111001xxxx", InstName.Strexh, InstEmit32.Strexh, typeof(OpCode32MemStEx)); + SetA32("<<<<000xx1x0xxxxxxxxxxxx1011xxxx", InstName.Strh, InstEmit32.Strh, typeof(OpCode32MemImm8)); + SetA32("<<<<000xx0x0xxxxxxxx00001011xxxx", InstName.Strh, InstEmit32.Strh, typeof(OpCode32MemReg)); + SetA32("<<<<0010010xxxxxxxxxxxxxxxxxxxxx", InstName.Sub, InstEmit32.Sub, typeof(OpCode32AluImm)); + SetA32("<<<<0000010xxxxxxxxxxxxxxxx0xxxx", InstName.Sub, InstEmit32.Sub, typeof(OpCode32AluRsImm)); + SetA32("<<<<0000010xxxxxxxxxxxxx0xx1xxxx", InstName.Sub, InstEmit32.Sub, typeof(OpCode32AluRsReg)); + SetA32("<<<<1111xxxxxxxxxxxxxxxxxxxxxxxx", InstName.Svc, InstEmit32.Svc, typeof(OpCode32Exception)); + 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("<<<<00110011xxxx0000xxxxxxxxxxxx", InstName.Teq, InstEmit32.Teq, typeof(OpCode32AluImm)); + SetA32("<<<<00010011xxxx0000xxxxxxx0xxxx", InstName.Teq, InstEmit32.Teq, typeof(OpCode32AluRsImm)); + SetA32("<<<<00010011xxxx0000xxxx0xx1xxxx", InstName.Teq, InstEmit32.Teq, typeof(OpCode32AluRsReg)); + SetA32("<<<<0111111111111101111011111110", InstName.Trap, InstEmit32.Trap, typeof(OpCode32Exception)); + SetA32("<<<<00110001xxxx0000xxxxxxxxxxxx", InstName.Tst, InstEmit32.Tst, typeof(OpCode32AluImm)); + SetA32("<<<<00010001xxxx0000xxxxxxx0xxxx", InstName.Tst, InstEmit32.Tst, typeof(OpCode32AluRsImm)); + SetA32("<<<<00010001xxxx0000xxxx0xx1xxxx", InstName.Tst, InstEmit32.Tst, typeof(OpCode32AluRsReg)); + SetA32("<<<<0111111xxxxxxxxxxxxxx101xxxx", InstName.Ubfx, InstEmit32.Ubfx, typeof(OpCode32AluBf)); + SetA32("<<<<01110011xxxx1111xxxx0001xxxx", InstName.Udiv, InstEmit32.Udiv, typeof(OpCode32AluMla)); + SetA32("<<<<0000101xxxxxxxxxxxxx1001xxxx", InstName.Umlal, InstEmit32.Umlal, typeof(OpCode32AluUmull)); + SetA32("<<<<0000100xxxxxxxxxxxxx1001xxxx", InstName.Umull, InstEmit32.Umull, typeof(OpCode32AluUmull)); + SetA32("<<<<01101110xxxxxxxxxx000111xxxx", InstName.Uxtb, InstEmit32.Uxtb, typeof(OpCode32AluUx)); + SetA32("<<<<01101100xxxxxxxxxx000111xxxx", InstName.Uxtb16, InstEmit32.Uxtb16, typeof(OpCode32AluUx)); + SetA32("<<<<01101111xxxxxxxxxx000111xxxx", InstName.Uxth, InstEmit32.Uxth, typeof(OpCode32AluUx)); // FP & SIMD (AArch32) @@ -757,15 +757,15 @@ namespace ARMeilleure.Decoders SetA32("111100110x01xxxxxxxx0001xxx1xxxx", InstName.Vbsl, InstEmit32.Vbsl, typeof(OpCode32SimdBinary)); SetA32("111100111x11xx01xxxx0x010xx0xxxx", InstName.Vceq, InstEmit32.Vceq_Z, typeof(OpCode32SimdCmpZ)); - SetA32("111100100x00xxxxxxxx1110xxx0xxxx", InstName.Vceq, InstEmit32.Vceq_V, typeof(OpCode32SimdReg)); //note: size is 16/32 only + SetA32("111100100x00xxxxxxxx1110xxx0xxxx", InstName.Vceq, InstEmit32.Vceq_V, typeof(OpCode32SimdReg)); SetA32("111100110x<>x1x0xxxx", InstName.Vcvt, InstEmit32.Vcvt_R, typeof(OpCode32SimdCvtFI)); // the many fp32 to int encodings (fp) + SetA32("111100111x11xx11xxxx011xxxx0xxxx", InstName.Vcvt, InstEmit32.Vcvt_V, typeof(OpCode32SimdCmpZ)); // FP and integer, vector. + SetA32("<<<<11101x110111xxxx101x11x0xxxx", InstName.Vcvt, InstEmit32.Vcvt_FD, typeof(OpCode32SimdS)); // FP 32 and 64, scalar. + SetA32("<<<<11101x11110xxxxx10xx11x0xxxx", InstName.Vcvt, InstEmit32.Vcvt_FI, typeof(OpCode32SimdCvtFI)); // FP32 to int. + SetA32("<<<<11101x111000xxxx10xxx1x0xxxx", InstName.Vcvt, InstEmit32.Vcvt_FI, typeof(OpCode32SimdCvtFI)); // Int to FP32. + SetA32("111111101x1111xxxxxx10>>x1x0xxxx", InstName.Vcvt, InstEmit32.Vcvt_R, typeof(OpCode32SimdCvtFI)); // The many FP32 to int encodings (fp). SetA32("<<<<11101x00xxxxxxxx101xx0x0xxxx", InstName.Vdiv, InstEmit32.Vdiv_S, typeof(OpCode32SimdRegS)); SetA32("<<<<11101xx0xxxxxxxx1011x0x10000", InstName.Vdup, InstEmit32.Vdup, typeof(OpCode32SimdDupGP)); @@ -787,20 +787,20 @@ namespace ARMeilleure.Decoders SetA32("111100101x11xxxxxxxxxxxxxxx0xxxx", InstName.Vext, InstEmit32.Vext, typeof(OpCode32SimdExt)); SetA32("111101001x10xxxxxxxxxx00xxxxxxxx", InstName.Vld1, InstEmit32.Vld1, typeof(OpCode32SimdMemSingle)); - SetA32("111101000x10xxxxxxxx0111xxxxxxxx", InstName.Vld1, InstEmit32.Vld1, typeof(OpCode32SimdMemPair)); //regs = 1 - SetA32("111101000x10xxxxxxxx1010xxxxxxxx", InstName.Vld1, InstEmit32.Vld1, typeof(OpCode32SimdMemPair)); //regs = 2 - SetA32("111101000x10xxxxxxxx0110xxxxxxxx", InstName.Vld1, InstEmit32.Vld1, typeof(OpCode32SimdMemPair)); //regs = 3 - SetA32("111101000x10xxxxxxxx0010xxxxxxxx", InstName.Vld1, InstEmit32.Vld1, typeof(OpCode32SimdMemPair)); //regs = 4 + SetA32("111101000x10xxxxxxxx0111xxxxxxxx", InstName.Vld1, InstEmit32.Vld1, typeof(OpCode32SimdMemPair)); // Regs = 1. + SetA32("111101000x10xxxxxxxx1010xxxxxxxx", InstName.Vld1, InstEmit32.Vld1, typeof(OpCode32SimdMemPair)); // Regs = 2. + SetA32("111101000x10xxxxxxxx0110xxxxxxxx", InstName.Vld1, InstEmit32.Vld1, typeof(OpCode32SimdMemPair)); // Regs = 3. + SetA32("111101000x10xxxxxxxx0010xxxxxxxx", InstName.Vld1, InstEmit32.Vld1, typeof(OpCode32SimdMemPair)); // Regs = 4. SetA32("111101001x10xxxxxxxxxx01xxxxxxxx", InstName.Vld2, InstEmit32.Vld2, typeof(OpCode32SimdMemSingle)); - SetA32("111101000x10xxxxxxxx100xxxxxxxxx", InstName.Vld2, InstEmit32.Vld2, typeof(OpCode32SimdMemPair)); //regs = 1, inc = 1/2 (itype) - SetA32("111101000x10xxxxxxxx0011xxxxxxxx", InstName.Vld2, InstEmit32.Vld2, typeof(OpCode32SimdMemPair)); //regs = 2, inc = 2 + SetA32("111101000x10xxxxxxxx100xxxxxxxxx", InstName.Vld2, InstEmit32.Vld2, typeof(OpCode32SimdMemPair)); // Regs = 1, inc = 1/2 (itype). + SetA32("111101000x10xxxxxxxx0011xxxxxxxx", InstName.Vld2, InstEmit32.Vld2, typeof(OpCode32SimdMemPair)); // Regs = 2, inc = 2. SetA32("111101001x10xxxxxxxxxx10xxxxxxxx", InstName.Vld3, InstEmit32.Vld3, typeof(OpCode32SimdMemSingle)); - SetA32("111101000x10xxxxxxxx010xxxxxxxxx", InstName.Vld3, InstEmit32.Vld3, typeof(OpCode32SimdMemPair)); //inc = 1/2 (itype) + SetA32("111101000x10xxxxxxxx010xxxxxxxxx", InstName.Vld3, InstEmit32.Vld3, typeof(OpCode32SimdMemPair)); // Inc = 1/2 (itype). SetA32("111101001x10xxxxxxxxxx11xxxxxxxx", InstName.Vld4, InstEmit32.Vld4, typeof(OpCode32SimdMemSingle)); - SetA32("111101000x10xxxxxxxx000xxxxxxxxx", InstName.Vld4, InstEmit32.Vld4, typeof(OpCode32SimdMemPair)); //inc = 1/2 (itype) + SetA32("111101000x10xxxxxxxx000xxxxxxxxx", InstName.Vld4, InstEmit32.Vld4, typeof(OpCode32SimdMemPair)); // Inc = 1/2 (itype). SetA32("<<<<11001x01xxxxxxxx1011xxxxxxx0", InstName.Vldm, InstEmit32.Vldm, typeof(OpCode32SimdMemMult)); SetA32("<<<<11001x11xxxxxxxx1011xxxxxxx0", InstName.Vldm, InstEmit32.Vldm, typeof(OpCode32SimdMemMult)); @@ -832,18 +832,18 @@ namespace ARMeilleure.Decoders SetA32("111100110xxxxxxxxxxx1001xxx0xxxx", InstName.Vmls, InstEmit32.Vmls_I, typeof(OpCode32SimdReg)); SetA32("1111001x1x<>>xxxxxxx0101>xx1xxxx", InstName.Vshl, InstEmit32.Vshl, typeof(OpCode32SimdShift)); SetA32("111101001x00xxxxxxxx<<00xxxxxxxx", InstName.Vst1, InstEmit32.Vst1, typeof(OpCode32SimdMemSingle)); - SetA32("111101000x00xxxxxxxx0111xxxxxxxx", InstName.Vst1, InstEmit32.Vst1, typeof(OpCode32SimdMemPair)); //regs = 1 - SetA32("111101000x00xxxxxxxx1010xxxxxxxx", InstName.Vst1, InstEmit32.Vst1, typeof(OpCode32SimdMemPair)); //regs = 2 - SetA32("111101000x00xxxxxxxx0110xxxxxxxx", InstName.Vst1, InstEmit32.Vst1, typeof(OpCode32SimdMemPair)); //regs = 3 - SetA32("111101000x00xxxxxxxx0010xxxxxxxx", InstName.Vst1, InstEmit32.Vst1, typeof(OpCode32SimdMemPair)); //regs = 4 + SetA32("111101000x00xxxxxxxx0111xxxxxxxx", InstName.Vst1, InstEmit32.Vst1, typeof(OpCode32SimdMemPair)); // Regs = 1. + SetA32("111101000x00xxxxxxxx1010xxxxxxxx", InstName.Vst1, InstEmit32.Vst1, typeof(OpCode32SimdMemPair)); // Regs = 2. + SetA32("111101000x00xxxxxxxx0110xxxxxxxx", InstName.Vst1, InstEmit32.Vst1, typeof(OpCode32SimdMemPair)); // Regs = 3. + SetA32("111101000x00xxxxxxxx0010xxxxxxxx", InstName.Vst1, InstEmit32.Vst1, typeof(OpCode32SimdMemPair)); // Regs = 4. SetA32("111101001x00xxxxxxxx<<01xxxxxxxx", InstName.Vst2, InstEmit32.Vst2, typeof(OpCode32SimdMemSingle)); - SetA32("111101000x00xxxxxxxx100xxxxxxxxx", InstName.Vst2, InstEmit32.Vst2, typeof(OpCode32SimdMemPair)); //regs = 1, inc = 1/2 (itype) - SetA32("111101000x00xxxxxxxx0011xxxxxxxx", InstName.Vst2, InstEmit32.Vst2, typeof(OpCode32SimdMemPair)); //regs = 2, inc = 2 + SetA32("111101000x00xxxxxxxx100xxxxxxxxx", InstName.Vst2, InstEmit32.Vst2, typeof(OpCode32SimdMemPair)); // Regs = 1, inc = 1/2 (itype). + SetA32("111101000x00xxxxxxxx0011xxxxxxxx", InstName.Vst2, InstEmit32.Vst2, typeof(OpCode32SimdMemPair)); // Regs = 2, inc = 2. SetA32("111101001x00xxxxxxxx<<10xxxxxxxx", InstName.Vst3, InstEmit32.Vst3, typeof(OpCode32SimdMemSingle)); - SetA32("111101000x00xxxxxxxx010xxxxxxxxx", InstName.Vst3, InstEmit32.Vst3, typeof(OpCode32SimdMemPair)); //inc = 1/2 (itype) + SetA32("111101000x00xxxxxxxx010xxxxxxxxx", InstName.Vst3, InstEmit32.Vst3, typeof(OpCode32SimdMemPair)); // Inc = 1/2 (itype). SetA32("111101001x00xxxxxxxx<<11xxxxxxxx", InstName.Vst4, InstEmit32.Vst4, typeof(OpCode32SimdMemSingle)); - SetA32("111101000x00xxxxxxxx000xxxxxxxxx", InstName.Vst4, InstEmit32.Vst4, typeof(OpCode32SimdMemPair)); //inc = 1/2 (itype) + SetA32("111101000x00xxxxxxxx000xxxxxxxxx", InstName.Vst4, InstEmit32.Vst4, typeof(OpCode32SimdMemPair)); // Inc = 1/2 (itype). SetA32("<<<<11001x00xxxxxxxx1011xxxxxxx0", InstName.Vstm, InstEmit32.Vstm, typeof(OpCode32SimdMemMult)); SetA32("<<<<11001x10xxxxxxxx1011xxxxxxx0", InstName.Vstm, InstEmit32.Vstm, typeof(OpCode32SimdMemMult)); diff --git a/ARMeilleure/Instructions/InstEmitAlu.cs b/ARMeilleure/Instructions/InstEmitAlu.cs index 501aff3251..6e2875e649 100644 --- a/ARMeilleure/Instructions/InstEmitAlu.cs +++ b/ARMeilleure/Instructions/InstEmitAlu.cs @@ -276,23 +276,6 @@ namespace ARMeilleure.Instructions SetAluDOrZR(context, d); } - public static Operand EmitReverseBits32Op(ArmEmitterContext context, Operand op) - { - Debug.Assert(op.Type == OperandType.I32); - - Operand val = context.BitwiseOr(context.ShiftRightUI(context.BitwiseAnd(op, Const(0xaaaaaaaau)), Const(1)), - context.ShiftLeft (context.BitwiseAnd(op, Const(0x55555555u)), Const(1))); - - val = context.BitwiseOr(context.ShiftRightUI(context.BitwiseAnd(val, Const(0xccccccccu)), Const(2)), - context.ShiftLeft (context.BitwiseAnd(val, Const(0x33333333u)), Const(2))); - val = context.BitwiseOr(context.ShiftRightUI(context.BitwiseAnd(val, Const(0xf0f0f0f0u)), Const(4)), - context.ShiftLeft (context.BitwiseAnd(val, Const(0x0f0f0f0fu)), Const(4))); - val = context.BitwiseOr(context.ShiftRightUI(context.BitwiseAnd(val, Const(0xff00ff00u)), Const(8)), - context.ShiftLeft (context.BitwiseAnd(val, Const(0x00ff00ffu)), Const(8))); - - return context.BitwiseOr(context.ShiftRightUI(val, Const(16)), context.ShiftLeft(val, Const(16))); - } - private static Operand EmitReverseBits64Op(ArmEmitterContext context, Operand op) { Debug.Assert(op.Type == OperandType.I64); @@ -331,23 +314,6 @@ namespace ARMeilleure.Instructions SetAluDOrZR(context, d); } - public static Operand EmitReverseBytes16_32Op(ArmEmitterContext context, Operand op) - { - Debug.Assert(op.Type == OperandType.I32); - - Operand val = EmitReverseBytes16_64Op(context, context.ZeroExtend32(OperandType.I64, op)); - - return context.ConvertI64ToI32(val); - } - - private static Operand EmitReverseBytes16_64Op(ArmEmitterContext context, Operand op) - { - Debug.Assert(op.Type == OperandType.I64); - - return context.BitwiseOr(context.ShiftRightUI(context.BitwiseAnd(op, Const(0xff00ff00ff00ff00ul)), Const(8)), - context.ShiftLeft (context.BitwiseAnd(op, Const(0x00ff00ff00ff00fful)), Const(8))); - } - public static void Rev32(ArmEmitterContext context) { OpCodeAlu op = (OpCodeAlu)context.CurrOp; @@ -367,7 +333,7 @@ namespace ARMeilleure.Instructions SetAluDOrZR(context, d); } - public static Operand EmitReverseBytes32_64Op(ArmEmitterContext context, Operand op) + private static Operand EmitReverseBytes32_64Op(ArmEmitterContext context, Operand op) { Debug.Assert(op.Type == OperandType.I64); diff --git a/ARMeilleure/Instructions/InstEmitAlu32.cs b/ARMeilleure/Instructions/InstEmitAlu32.cs index 7068ed307c..169ebb9c26 100644 --- a/ARMeilleure/Instructions/InstEmitAlu32.cs +++ b/ARMeilleure/Instructions/InstEmitAlu32.cs @@ -124,6 +124,7 @@ namespace ARMeilleure.Instructions EmitAddsCCheck(context, n, res); EmitAddsVCheck(context, n, m, res); } + public static void Eor(ArmEmitterContext context) { IOpCode32Alu op = (IOpCode32Alu)context.CurrOp; @@ -365,8 +366,7 @@ namespace ARMeilleure.Instructions res = context.BitwiseOr( context.ZeroExtend16(OperandType.I32, low16), - context.ShiftLeft(context.ZeroExtend16(OperandType.I32, high16), Const(16)) - ); + context.ShiftLeft(context.ZeroExtend16(OperandType.I32, high16), Const(16))); EmitAluStore(context, res); } @@ -427,7 +427,7 @@ namespace ARMeilleure.Instructions if (!unsigned) { // If Rn == INT_MIN && Rm == -1, Rd = INT_MIN (overflow). - // assume this is the same as ARM64 for now - tests to follow. + // Assume this is the same as ARM64 for now - tests to follow. Operand intMin = Const(int.MinValue); Operand minus1 = Const(-1); @@ -466,7 +466,7 @@ namespace ARMeilleure.Instructions OpCode32AluImm16 op = (OpCode32AluImm16)context.CurrOp; Operand d = GetIntA32(context, op.Rd); - Operand imm = Const(op.Immediate << 16); //immeditate value as top halfword + Operand imm = Const(op.Immediate << 16); // Immeditate value as top halfword. Operand res = context.BitwiseAnd(d, Const(0x0000ffff)); res = context.BitwiseOr(res, imm); @@ -512,7 +512,7 @@ namespace ARMeilleure.Instructions Operand n = GetAluN(context); Operand m = GetAluM(context); - Operand res = InstEmit.EmitReverseBits32Op(context, m); + Operand res; bool tbform = op.ShiftType == ShiftType.Asr; if (tbform) @@ -531,7 +531,7 @@ namespace ARMeilleure.Instructions { Operand m = GetAluM(context); - Operand res = InstEmit.EmitReverseBits32Op(context, m); + Operand res = EmitReverseBits32Op(context, m); EmitAluStore(context, res); } @@ -549,7 +549,7 @@ namespace ARMeilleure.Instructions { Operand m = GetAluM(context); - Operand res = InstEmit.EmitReverseBytes16_32Op(context, m); + Operand res = EmitReverseBytes16_32Op(context, m); EmitAluStore(context, res); } @@ -558,7 +558,7 @@ namespace ARMeilleure.Instructions { Operand m = GetAluM(context); - Operand res = InstEmit.EmitReverseBytes16_32Op(context, m); + Operand res = EmitReverseBytes16_32Op(context, m); EmitAluStore(context, context.SignExtend16(OperandType.I32, res)); } @@ -591,7 +591,7 @@ namespace ARMeilleure.Instructions { OpCode32AluBf op = (OpCode32AluBf)context.CurrOp; - var msb = op.Lsb + op.Msb; //for this instruction, the msb is actually a width + var msb = op.Lsb + op.Msb; // For this instruction, the msb is actually a width. Operand n = GetIntA32(context, op.Rn); Operand res = context.ShiftRightUI(context.ShiftLeft(n, Const(31 - msb)), Const(31 - op.Msb)); @@ -603,7 +603,7 @@ namespace ARMeilleure.Instructions { OpCode32AluBf op = (OpCode32AluBf)context.CurrOp; - var msb = op.Lsb + op.Msb; //for this instruction, the msb is actually a width + var msb = op.Lsb + op.Msb; // For this instruction, the msb is actually a width. Operand n = GetIntA32(context, op.Rn); Operand res = context.ShiftRightSI(context.ShiftLeft(n, Const(31 - msb)), Const(31 - op.Msb)); @@ -614,47 +614,7 @@ namespace ARMeilleure.Instructions private static void EmitAluStore(ArmEmitterContext context, Operand value) { IOpCode32Alu op = (IOpCode32Alu)context.CurrOp; - - if (op.Rd == RegisterAlias.Aarch32Pc) - { - if (op.SetFlags) - { - // TODO: Load SPSR etc. - Operand isThumb = GetFlag(PState.TFlag); - - Operand lblThumb = Label(); - - context.BranchIfTrue(lblThumb, isThumb); - - context.Return(context.ZeroExtend32(OperandType.I64, context.BitwiseAnd(value, Const(~3)))); - - context.MarkLabel(lblThumb); - - context.Return(context.ZeroExtend32(OperandType.I64, context.BitwiseAnd(value, Const(~1)))); - } - else - { - EmitAluWritePc(context, value); - } - } - else - { - SetIntA32(context, op.Rd, value); - } - } - - private static void EmitAluWritePc(ArmEmitterContext context, Operand value) - { - context.StoreToContext(); - - if (IsThumb(context.CurrOp)) - { - context.Return(context.ZeroExtend32(OperandType.I64, context.BitwiseAnd(value, Const(~1)))); - } - else - { - EmitBxWritePc(context, value); - } + EmitGenericAluStoreA32(context, op.Rd, op.SetFlags, value); } } } \ No newline at end of file diff --git a/ARMeilleure/Instructions/InstEmitAluHelper.cs b/ARMeilleure/Instructions/InstEmitAluHelper.cs index 664b8e0063..b25ecd2b55 100644 --- a/ARMeilleure/Instructions/InstEmitAluHelper.cs +++ b/ARMeilleure/Instructions/InstEmitAluHelper.cs @@ -3,7 +3,7 @@ using ARMeilleure.IntermediateRepresentation; using ARMeilleure.State; using ARMeilleure.Translation; using System; - +using System.Diagnostics; using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.IntermediateRepresentation.OperandHelper; @@ -77,6 +77,83 @@ namespace ARMeilleure.Instructions SetFlag(context, PState.VFlag, vOut); } + public static Operand EmitReverseBits32Op(ArmEmitterContext context, Operand op) + { + Debug.Assert(op.Type == OperandType.I32); + + Operand val = context.BitwiseOr(context.ShiftRightUI(context.BitwiseAnd(op, Const(0xaaaaaaaau)), Const(1)), + context.ShiftLeft(context.BitwiseAnd(op, Const(0x55555555u)), Const(1))); + + val = context.BitwiseOr(context.ShiftRightUI(context.BitwiseAnd(val, Const(0xccccccccu)), Const(2)), + context.ShiftLeft(context.BitwiseAnd(val, Const(0x33333333u)), Const(2))); + val = context.BitwiseOr(context.ShiftRightUI(context.BitwiseAnd(val, Const(0xf0f0f0f0u)), Const(4)), + context.ShiftLeft(context.BitwiseAnd(val, Const(0x0f0f0f0fu)), Const(4))); + val = context.BitwiseOr(context.ShiftRightUI(context.BitwiseAnd(val, Const(0xff00ff00u)), Const(8)), + context.ShiftLeft(context.BitwiseAnd(val, Const(0x00ff00ffu)), Const(8))); + + return context.BitwiseOr(context.ShiftRightUI(val, Const(16)), context.ShiftLeft(val, Const(16))); + } + + public static Operand EmitReverseBytes16_64Op(ArmEmitterContext context, Operand op) + { + Debug.Assert(op.Type == OperandType.I64); + + return context.BitwiseOr(context.ShiftRightUI(context.BitwiseAnd(op, Const(0xff00ff00ff00ff00ul)), Const(8)), + context.ShiftLeft(context.BitwiseAnd(op, Const(0x00ff00ff00ff00fful)), Const(8))); + } + + public static Operand EmitReverseBytes16_32Op(ArmEmitterContext context, Operand op) + { + Debug.Assert(op.Type == OperandType.I32); + + Operand val = EmitReverseBytes16_64Op(context, context.ZeroExtend32(OperandType.I64, op)); + + return context.ConvertI64ToI32(val); + } + + private static void EmitAluWritePc(ArmEmitterContext context, Operand value) + { + context.StoreToContext(); + + if (IsThumb(context.CurrOp)) + { + context.Return(context.ZeroExtend32(OperandType.I64, context.BitwiseAnd(value, Const(~1)))); + } + else + { + EmitBxWritePc(context, value); + } + } + + public static void EmitGenericAluStoreA32(ArmEmitterContext context, int rd, bool setFlags, Operand value) + { + if (rd == RegisterAlias.Aarch32Pc && setFlags) + { + if (setFlags) + { + // TODO: Load SPSR etc. + Operand isThumb = GetFlag(PState.TFlag); + + Operand lblThumb = Label(); + + context.BranchIfTrue(lblThumb, isThumb); + + context.Return(context.ZeroExtend32(OperandType.I64, context.BitwiseAnd(value, Const(~3)))); + + context.MarkLabel(lblThumb); + + context.Return(context.ZeroExtend32(OperandType.I64, context.BitwiseAnd(value, Const(~1)))); + } + else + { + EmitAluWritePc(context, value); + } + } + else + { + SetIntA32(context, rd, value); + } + } public static Operand GetAluN(ArmEmitterContext context) { @@ -256,7 +333,6 @@ namespace ARMeilleure.Instructions public static Operand EmitLslC(ArmEmitterContext context, Operand m, bool setCarry, Operand shift, Operand shiftIsZero) { Operand shiftLarge = context.ICompareGreaterOrEqual(shift, Const(32)); - Operand result = context.ShiftLeft(m, shift); if (setCarry) { diff --git a/ARMeilleure/Instructions/InstEmitFlow32.cs b/ARMeilleure/Instructions/InstEmitFlow32.cs index 15be0e462d..f3239498a4 100644 --- a/ARMeilleure/Instructions/InstEmitFlow32.cs +++ b/ARMeilleure/Instructions/InstEmitFlow32.cs @@ -76,7 +76,7 @@ namespace ARMeilleure.Instructions Operand addr = GetIntA32(context, op.Rm); Operand bitOne = context.BitwiseAnd(addr, Const(1)); - addr = context.BitwiseOr(addr, Const(1)); // set call flag + addr = context.BitwiseOr(addr, Const(1)); // Set call flag. bool isThumb = IsThumb(context.CurrOp); @@ -88,11 +88,7 @@ namespace ARMeilleure.Instructions SetFlag(context, PState.TFlag, bitOne); - context.Return(addr); // call - } - - public static void Nop(ArmEmitterContext context) - { + context.Return(addr); // Call. } } } \ No newline at end of file diff --git a/ARMeilleure/Instructions/InstEmitMemory32.cs b/ARMeilleure/Instructions/InstEmitMemory32.cs index b871908a0e..27c37d8cde 100644 --- a/ARMeilleure/Instructions/InstEmitMemory32.cs +++ b/ARMeilleure/Instructions/InstEmitMemory32.cs @@ -21,10 +21,10 @@ namespace ARMeilleure.Instructions [Flags] enum AccessType { - Store = 0, - Signed = 1, - Load = 2, - Ordered = 4, + Store = 0, + Signed = 1, + Load = 2, + Ordered = 4, Exclusive = 8, LoadZx = Load, diff --git a/ARMeilleure/Instructions/InstEmitMemoryEx32.cs b/ARMeilleure/Instructions/InstEmitMemoryEx32.cs index 8fb92f16b9..9f56401d05 100644 --- a/ARMeilleure/Instructions/InstEmitMemoryEx32.cs +++ b/ARMeilleure/Instructions/InstEmitMemoryEx32.cs @@ -36,6 +36,7 @@ namespace ARMeilleure.Instructions { EmitExLoadOrStore(context, HWordSizeLog2, AccessType.LoadZx | AccessType.Exclusive); } + public static void Lda(ArmEmitterContext context) { EmitExLoadOrStore(context, WordSizeLog2, AccessType.LoadZx | AccessType.Ordered); @@ -71,7 +72,7 @@ namespace ARMeilleure.Instructions EmitExLoadOrStore(context, HWordSizeLog2, AccessType.LoadZx | AccessType.Ordered); } - // stores + // Stores. public static void Strex(ArmEmitterContext context) { @@ -149,7 +150,7 @@ namespace ARMeilleure.Instructions { if (size == DWordSizeLog2) { - // keep loads atomic - make the call to get the whole region and then decompose it into parts + // Keep loads atomic - make the call to get the whole region and then decompose it into parts // for the registers. Operand value = EmitExLoad(context, address, exclusive, size); @@ -184,15 +185,12 @@ namespace ARMeilleure.Instructions } else { - Operand s = null; - if (size == DWordSizeLog2) { - //split the result into 2 words (based on endianness) + // Split the result into 2 words (based on endianness) Operand lo = context.ZeroExtend32(OperandType.I64, GetIntA32(context, op.Rt)); Operand hi = context.ZeroExtend32(OperandType.I64, GetIntA32(context, op.Rt | 1)); - Operand toStore = Local(OperandType.I64); Operand lblBigEndian = Label(); Operand lblEnd = Label(); @@ -215,8 +213,7 @@ namespace ARMeilleure.Instructions } else { - - s = EmitExStore(context, address, context.ZeroExtend32(OperandType.I64, GetIntA32(context, op.Rt)), exclusive, size); + Operand s = EmitExStore(context, address, context.ZeroExtend32(OperandType.I64, GetIntA32(context, op.Rt)), exclusive, size); // This is only needed for exclusive stores. The function returns 0 // when the store is successful, and 1 otherwise. if (exclusive) SetIntA32(context, op.Rd, s); diff --git a/ARMeilleure/Instructions/InstEmitMemoryHelper.cs b/ARMeilleure/Instructions/InstEmitMemoryHelper.cs index 5b72095e74..70861d1634 100644 --- a/ARMeilleure/Instructions/InstEmitMemoryHelper.cs +++ b/ARMeilleure/Instructions/InstEmitMemoryHelper.cs @@ -511,7 +511,6 @@ namespace ARMeilleure.Instructions { switch (context.CurrOp) { - // ARM32. case OpCode32MemRsImm op: return GetMShiftedByImmediate(context, op, setCarry); case OpCode32MemReg op: return GetIntA32(context, op.Rm); diff --git a/ARMeilleure/Instructions/InstEmitMul32.cs b/ARMeilleure/Instructions/InstEmitMul32.cs index faf27983a3..7dba004989 100644 --- a/ARMeilleure/Instructions/InstEmitMul32.cs +++ b/ARMeilleure/Instructions/InstEmitMul32.cs @@ -71,8 +71,8 @@ namespace ARMeilleure.Instructions EmitNZFlagsCheck(context, res); } - EmitGenericStore(context, op.RdHi, op.SetFlags, hi); - EmitGenericStore(context, op.RdLo, op.SetFlags, lo); + EmitGenericAluStoreA32(context, op.RdHi, op.SetFlags, hi); + EmitGenericAluStoreA32(context, op.RdLo, op.SetFlags, lo); } public static void Smull(ArmEmitterContext context) @@ -92,8 +92,8 @@ namespace ARMeilleure.Instructions EmitNZFlagsCheck(context, res); } - EmitGenericStore(context, op.RdHi, op.SetFlags, hi); - EmitGenericStore(context, op.RdLo, op.SetFlags, lo); + EmitGenericAluStoreA32(context, op.RdHi, op.SetFlags, hi); + EmitGenericAluStoreA32(context, op.RdLo, op.SetFlags, lo); } public static void Smmla(ArmEmitterContext context) @@ -136,10 +136,9 @@ namespace ARMeilleure.Instructions Operand hi = context.ConvertI64ToI32(context.ShiftRightSI(res, Const(32))); - EmitGenericStore(context, op.Rd, false, hi); + EmitGenericAluStoreA32(context, op.Rd, false, hi); } - public static void Smlab(ArmEmitterContext context) { OpCode32AluMla op = (OpCode32AluMla)context.CurrOp; @@ -170,9 +169,9 @@ namespace ARMeilleure.Instructions Operand a = GetIntA32(context, op.Ra); res = context.Add(res, a); - //todo: set Q flag when last addition overflows (saturation)? + // TODO: set Q flag when last addition overflows (saturation)? - EmitGenericStore(context, op.Rd, false, res); + EmitGenericAluStoreA32(context, op.Rd, false, res); } public static void Smlal(ArmEmitterContext context) @@ -217,8 +216,8 @@ namespace ARMeilleure.Instructions EmitNZFlagsCheck(context, res); } - EmitGenericStore(context, op.RdHi, op.SetFlags, hi); - EmitGenericStore(context, op.RdLo, op.SetFlags, lo); + EmitGenericAluStoreA32(context, op.RdHi, op.SetFlags, hi); + EmitGenericAluStoreA32(context, op.RdLo, op.SetFlags, lo); } public static void Smlalh(ArmEmitterContext context) @@ -255,8 +254,8 @@ namespace ARMeilleure.Instructions Operand hi = context.ConvertI64ToI32(context.ShiftRightUI(res, Const(32))); Operand lo = context.ConvertI64ToI32(res); - EmitGenericStore(context, op.RdHi, false, hi); - EmitGenericStore(context, op.RdLo, false, lo); + EmitGenericAluStoreA32(context, op.RdHi, false, hi); + EmitGenericAluStoreA32(context, op.RdLo, false, lo); } public static void Smulh(ArmEmitterContext context) @@ -286,37 +285,7 @@ namespace ARMeilleure.Instructions Operand res = context.Multiply(n, m); - EmitGenericStore(context, op.Rd, false, res); - } - - private static void EmitGenericStore(ArmEmitterContext context, int Rd, bool setFlags, Operand value) - { - if (Rd == RegisterAlias.Aarch32Pc) - { - if (setFlags) - { - // TODO: Load SPSR etc. - Operand isThumb = GetFlag(PState.TFlag); - - Operand lblThumb = Label(); - - context.BranchIfTrue(lblThumb, isThumb); - - context.Return(context.ZeroExtend32(OperandType.I64, context.BitwiseAnd(value, Const(~3)))); - - context.MarkLabel(lblThumb); - - context.Return(context.ZeroExtend32(OperandType.I64, context.BitwiseAnd(value, Const(~1)))); - } - else - { - EmitAluWritePc(context, value); - } - } - else - { - SetIntA32(context, Rd, value); - } + EmitGenericAluStoreA32(context, op.Rd, false, res); } } } diff --git a/ARMeilleure/Instructions/InstEmitSimdArithmetic32.cs b/ARMeilleure/Instructions/InstEmitSimdArithmetic32.cs index e7a331bd5c..7077323e25 100644 --- a/ARMeilleure/Instructions/InstEmitSimdArithmetic32.cs +++ b/ARMeilleure/Instructions/InstEmitSimdArithmetic32.cs @@ -21,6 +21,7 @@ namespace ARMeilleure.Instructions public static void Vabs_V(ArmEmitterContext context) { OpCode32Simd op = (OpCode32Simd)context.CurrOp; + if (op.F) { EmitVectorUnaryOpF32(context, (op1) => EmitUnaryMathCall(context, MathF.Abs, Math.Abs, op1)); @@ -73,7 +74,7 @@ namespace ARMeilleure.Instructions Operand insert = GetIntA32(context, op.Rt); - // zero extend into an I64, then replicate. Saves the most time over elementwise inserts + // Zero extend into an I64, then replicate. Saves the most time over elementwise inserts. switch (op.Size) { case 2: @@ -86,7 +87,7 @@ namespace ARMeilleure.Instructions insert = context.Multiply(context.ZeroExtend8(OperandType.I64, insert), Const(0x0101010101010101u)); break; default: - throw new Exception("Unknown Vdup Size!"); + throw new ArgumentOutOfRangeException("Unknown Vdup Size!"); } InsertScalar(context, op.Vd, insert); @@ -102,7 +103,7 @@ namespace ARMeilleure.Instructions Operand insert = EmitVectorExtractZx32(context, op.Vm >> 1, ((op.Vm & 1) << (3 - op.Size)) + op.Index, op.Size); - // zero extend into an I64, then replicate. Saves the most time over elementwise inserts + // Zero extend into an I64, then replicate. Saves the most time over elementwise inserts. switch (op.Size) { case 2: @@ -115,7 +116,7 @@ namespace ARMeilleure.Instructions insert = context.Multiply(context.ZeroExtend8(OperandType.I64, insert), Const(0x0101010101010101u)); break; default: - throw new Exception("Unknown Vdup Size!"); + throw new ArgumentOutOfRangeException("Unknown Vdup Size!"); } InsertScalar(context, op.Vd, insert); @@ -124,6 +125,7 @@ namespace ARMeilleure.Instructions InsertScalar(context, op.Vd | 1, insert); } } + public static void Vext(ArmEmitterContext context) { OpCode32SimdExt op = (OpCode32SimdExt)context.CurrOp; @@ -244,7 +246,7 @@ namespace ARMeilleure.Instructions public static void VmaxminNm_V(ArmEmitterContext context) { OpCode32SimdReg op = (OpCode32SimdReg)context.CurrOp; - bool max = (op.Size & 2) == 0; // op is high bit of size (not used for fp) + bool max = (op.Size & 2) == 0; // Op is high bit of size (not used for fp). _F32_F32_F32_Bool f32 = max ? new _F32_F32_F32_Bool(SoftFloat32.FPMaxNumFpscr) : new _F32_F32_F32_Bool(SoftFloat32.FPMinNumFpscr); _F64_F64_F64_Bool f64 = max ? new _F64_F64_F64_Bool(SoftFloat64.FPMaxNumFpscr) : new _F64_F64_F64_Bool(SoftFloat64.FPMinNumFpscr); @@ -332,6 +334,7 @@ namespace ARMeilleure.Instructions public static void Vmul_1(ArmEmitterContext context) { OpCode32SimdRegElem op = (OpCode32SimdRegElem)context.CurrOp; + if (op.F) { if (Optimizations.FastFP) @@ -390,6 +393,7 @@ namespace ARMeilleure.Instructions public static void Vmla_1(ArmEmitterContext context) { OpCode32SimdRegElem op = (OpCode32SimdRegElem)context.CurrOp; + if (op.F) { if (Optimizations.FastFP) @@ -448,6 +452,7 @@ namespace ARMeilleure.Instructions public static void Vmls_1(ArmEmitterContext context) { OpCode32SimdRegElem op = (OpCode32SimdRegElem)context.CurrOp; + if (op.F) { if (Optimizations.FastFP) @@ -479,17 +484,18 @@ namespace ARMeilleure.Instructions public static void Vrev(ArmEmitterContext context) { OpCode32Simd op = (OpCode32Simd)context.CurrOp; + EmitVectorUnaryOpZx32(context, (op1) => { switch (op.Opc) { case 0: - switch (op.Size) //swap bytes + switch (op.Size) // Swap bytes. { default: return op1; case 1: - return InstEmit.EmitReverseBytes16_32Op(context, op1); + return InstEmitAluHelper.EmitReverseBytes16_32Op(context, op1); case 2: case 3: return context.ByteSwap(op1); @@ -511,7 +517,7 @@ namespace ARMeilleure.Instructions ); } case 2: - //swap upper and lower + // Swap upper and lower halves. return context.BitwiseOr(context.ShiftRightUI(context.BitwiseAnd(op1, Const(0xffffffff00000000ul)), Const(32)), context.ShiftLeft(context.BitwiseAnd(op1, Const(0x00000000fffffffful)), Const(32))); @@ -523,6 +529,7 @@ namespace ARMeilleure.Instructions public static void Vrecpe(ArmEmitterContext context) { OpCode32SimdSqrte op = (OpCode32SimdSqrte)context.CurrOp; + if (op.F) { EmitVectorUnaryOpF32(context, (op1) => @@ -547,6 +554,7 @@ namespace ARMeilleure.Instructions public static void Vrsqrte(ArmEmitterContext context) { OpCode32SimdSqrte op = (OpCode32SimdSqrte)context.CurrOp; + if (op.F) { EmitVectorUnaryOpF32(context, (op1) => @@ -569,7 +577,8 @@ namespace ARMeilleure.Instructions public static void Vsel(ArmEmitterContext context) { - var op = (OpCode32SimdSel)context.CurrOp; + OpCode32SimdSel op = (OpCode32SimdSel)context.CurrOp; + Operand condition = null; switch (op.Cc) { diff --git a/ARMeilleure/Instructions/InstEmitSimdCmp32.cs b/ARMeilleure/Instructions/InstEmitSimdCmp32.cs index dd61166fba..26264ea6f7 100644 --- a/ARMeilleure/Instructions/InstEmitSimdCmp32.cs +++ b/ARMeilleure/Instructions/InstEmitSimdCmp32.cs @@ -22,13 +22,13 @@ namespace ARMeilleure.Instructions public static void Vceq_I(ArmEmitterContext context) { - OpCode32SimdReg op = (OpCode32SimdReg)context.CurrOp; EmitCmpOpI32(context, context.ICompareEqual, context.ICompareEqual, false, false); } public static void Vceq_Z(ArmEmitterContext context) { OpCode32Simd op = (OpCode32Simd)context.CurrOp; + if (op.F) { EmitCmpOpF32(context, SoftFloat32.FPCompareEQFpscr, SoftFloat64.FPCompareEQFpscr, true); @@ -47,12 +47,14 @@ namespace ARMeilleure.Instructions public static void Vcge_I(ArmEmitterContext context) { OpCode32SimdReg op = (OpCode32SimdReg)context.CurrOp; + EmitCmpOpI32(context, context.ICompareGreaterOrEqual, context.ICompareGreaterOrEqualUI, false, !op.U); } public static void Vcge_Z(ArmEmitterContext context) { OpCode32Simd op = (OpCode32Simd)context.CurrOp; + if (op.F) { EmitCmpOpF32(context, SoftFloat32.FPCompareGEFpscr, SoftFloat64.FPCompareGEFpscr, true); @@ -71,12 +73,14 @@ namespace ARMeilleure.Instructions public static void Vcgt_I(ArmEmitterContext context) { OpCode32SimdReg op = (OpCode32SimdReg)context.CurrOp; + EmitCmpOpI32(context, context.ICompareGreater, context.ICompareGreaterUI, false, !op.U); } public static void Vcgt_Z(ArmEmitterContext context) { OpCode32Simd op = (OpCode32Simd)context.CurrOp; + if (op.F) { EmitCmpOpF32(context, SoftFloat32.FPCompareGTFpscr, SoftFloat64.FPCompareGTFpscr, true); @@ -90,6 +94,7 @@ namespace ARMeilleure.Instructions public static void Vcle_Z(ArmEmitterContext context) { OpCode32Simd op = (OpCode32Simd)context.CurrOp; + if (op.F) { EmitCmpOpF32(context, SoftFloat32.FPCompareLEFpscr, SoftFloat64.FPCompareLEFpscr, true); @@ -103,6 +108,7 @@ namespace ARMeilleure.Instructions public static void Vclt_Z(ArmEmitterContext context) { OpCode32Simd op = (OpCode32Simd)context.CurrOp; + if (op.F) { EmitCmpOpF32(context, SoftFloat32.FPCompareLTFpscr, SoftFloat64.FPCompareLTFpscr, true); @@ -126,8 +132,14 @@ namespace ARMeilleure.Instructions { OperandType type = m.Type; - if (type == OperandType.FP64) return context.Call(f64, m, new Operand(0.0), one); - else return context.Call(f32, m, new Operand(0.0), one); + if (type == OperandType.FP64) + { + return context.Call(f64, m, new Operand(0.0), one); + } + else + { + return context.Call(f32, m, new Operand(0.0f), one); + } }); } else @@ -136,8 +148,14 @@ namespace ARMeilleure.Instructions { OperandType type = n.Type; - if (type == OperandType.FP64) return context.Call(f64, n, m, one); - else return context.Call(f32, n, m, one); + if (type == OperandType.FP64) + { + return context.Call(f64, n, m, one); + } + else + { + return context.Call(f32, n, m, one); + } }); } } diff --git a/ARMeilleure/Instructions/InstEmitSimdCvt32.cs b/ARMeilleure/Instructions/InstEmitSimdCvt32.cs index 19a315af33..40982b2755 100644 --- a/ARMeilleure/Instructions/InstEmitSimdCvt32.cs +++ b/ARMeilleure/Instructions/InstEmitSimdCvt32.cs @@ -17,12 +17,12 @@ namespace ARMeilleure.Instructions { if (lowBit) { - //move the low bit to the top + // Move the low bit to the top. return ((vd & 0x1) << 4) | (vd >> 1); } else { - //move the high bit to the bottom + // Move the high bit to the bottom. return ((vd & 0xf) << 1) | (vd >> 4); } } @@ -30,11 +30,12 @@ namespace ARMeilleure.Instructions public static void Vcvt_V(ArmEmitterContext context) { OpCode32Simd op = (OpCode32Simd)context.CurrOp; + bool unsigned = (op.Opc & 1) != 0; bool toInteger = (op.Opc & 2) != 0; OperandType floatSize = (op.Size == 2) ? OperandType.FP32 : OperandType.FP64; - - if (op.Size != 2) throw new Exception("CVT vector mode only currently defined for 32-bit"); + + if (op.Size != 2) throw new InvalidOperationException("CVT vector mode only defined for 32-bit."); if (toInteger) { EmitVectorUnaryOpF32(context, (op1) => @@ -87,7 +88,7 @@ namespace ARMeilleure.Instructions if (op.Size == 3) { vd = FlipVdBits(op.Vd, false); - // double to single + // Double to single. Operand fp = ExtractScalar(context, OperandType.FP64, vm); Operand res = context.ConvertToFP(OperandType.FP32, fp); @@ -97,7 +98,7 @@ namespace ARMeilleure.Instructions else { vd = FlipVdBits(op.Vd, true); - // single to double + // Single to double. Operand fp = ExtractScalar(context, OperandType.FP32, vm); Operand res = context.ConvertToFP(OperandType.FP64, fp); @@ -123,10 +124,10 @@ namespace ARMeilleure.Instructions Operand asInteger; - // TODO: Fast Path + // TODO: Fast Path. if (roundWithFpscr) { - // these need to get the FPSCR value, so it's worth noting we'd need to do a c# call at some point. + // These need to get the FPSCR value, so it's worth noting we'd need to do a c# call at some point. if (floatSize == OperandType.FP64) { if (unsigned) @@ -154,7 +155,7 @@ namespace ARMeilleure.Instructions } else { - // round towards zero + // Round towards zero. if (floatSize == OperandType.FP64) { if (unsigned) @@ -236,16 +237,16 @@ namespace ARMeilleure.Instructions switch (op.Opc2) { - case 0b00: //away + case 0b00: // Away toConvert = EmitRoundMathCall(context, MidpointRounding.AwayFromZero, toConvert); break; - case 0b01: //nearest + case 0b01: // Nearest toConvert = EmitRoundMathCall(context, MidpointRounding.ToEven, toConvert); break; - case 0b10: //+infinity + case 0b10: // Towards positive infinity toConvert = EmitUnaryMathCall(context, MathF.Ceiling, Math.Ceiling, toConvert); break; - case 0b11: //negative + case 0b11: // Towards negative infinity toConvert = EmitUnaryMathCall(context, MathF.Floor, Math.Floor, toConvert); break; } @@ -262,7 +263,6 @@ namespace ARMeilleure.Instructions { asInteger = context.Call(new _S32_F64(CastDoubleToInt32), toConvert); } - } else { @@ -279,7 +279,6 @@ namespace ARMeilleure.Instructions InsertScalar(context, op.Vd, asInteger); } - public static void Vrint_RM(ArmEmitterContext context) { OpCode32SimdCvtFI op = (OpCode32SimdCvtFI)context.CurrOp; @@ -290,16 +289,16 @@ namespace ARMeilleure.Instructions switch (op.Opc2) { - case 0b00: //away + case 0b00: // Away toConvert = EmitRoundMathCall(context, MidpointRounding.AwayFromZero, toConvert); break; - case 0b01: //nearest + case 0b01: // Nearest toConvert = EmitRoundMathCall(context, MidpointRounding.ToEven, toConvert); break; - case 0b10: //+infinity + case 0b10: // Towards positive infinity toConvert = EmitUnaryMathCall(context, MathF.Ceiling, Math.Ceiling, toConvert); break; - case 0b11: //negative + case 0b11: // Towards negative infinity toConvert = EmitUnaryMathCall(context, MathF.Floor, Math.Floor, toConvert); break; } @@ -321,10 +320,12 @@ namespace ARMeilleure.Instructions { return (uint)value; } + private static int CastFloatToInt32(float value) { return (int)value; } + private static uint CastFloatToUInt32(float value) { return (uint)value; diff --git a/ARMeilleure/Instructions/InstEmitSimdHelper32.cs b/ARMeilleure/Instructions/InstEmitSimdHelper32.cs index 670219cced..14ab0dc606 100644 --- a/ARMeilleure/Instructions/InstEmitSimdHelper32.cs +++ b/ARMeilleure/Instructions/InstEmitSimdHelper32.cs @@ -28,19 +28,19 @@ namespace ARMeilleure.Instructions return (index >> 2, index & 3); } - throw new NotImplementedException("Unrecognized Vector Register Size!"); + throw new NotImplementedException("Unrecognized Vector Register Size."); } public static Operand ExtractScalar(ArmEmitterContext context, OperandType type, int reg) { if (type == OperandType.FP64 || type == OperandType.I64) { - // from dreg + // From dreg. return context.VectorExtract(type, GetVecA32(reg >> 1), reg & 1); } else { - // from sreg + // From sreg. return context.VectorExtract(type, GetVecA32(reg >> 2), reg & 3); } } @@ -50,14 +50,14 @@ namespace ARMeilleure.Instructions Operand vec, insert; if (value.Type == OperandType.FP64 || value.Type == OperandType.I64) { - // from dreg + // From dreg. vec = GetVecA32(reg >> 1); insert = context.VectorInsert(vec, value, reg & 1); } else { - // from sreg + // From sreg. vec = GetVecA32(reg >> 2); insert = context.VectorInsert(vec, value, reg & 3); } @@ -203,7 +203,7 @@ namespace ARMeilleure.Instructions context.Copy(GetVecA32(op.Qd), res); } - // INTEGER + // Integer public static void EmitVectorUnaryOpI32(ArmEmitterContext context, Func1I emit, bool signed) { @@ -292,7 +292,7 @@ namespace ARMeilleure.Instructions EmitVectorTernaryOpI32(context, emit, false); } - // VEC BY SCALAR + // Vector by scalar public static void EmitVectorByScalarOpF32(ArmEmitterContext context, Func2I emit) { @@ -323,7 +323,6 @@ namespace ARMeilleure.Instructions { OpCode32SimdRegElem op = (OpCode32SimdRegElem)context.CurrOp; - if (op.Size < 1) throw new Exception("Undefined"); Operand m = EmitVectorExtract32(context, op.Vm >> (4 - op.Size), op.Vm & ((1 << (4 - op.Size)) - 1), op.Size, signed); Operand res = GetVecA32(op.Qd); @@ -347,7 +346,6 @@ namespace ARMeilleure.Instructions int sizeF = op.Size & 1; OperandType type = sizeF != 0 ? OperandType.FP64 : OperandType.FP32; - if (op.Size < 2) throw new Exception("FP ops <32 bit unimplemented!"); int elems = op.GetBytesCount() >> sizeF + 2; @@ -370,7 +368,6 @@ namespace ARMeilleure.Instructions { OpCode32SimdRegElem op = (OpCode32SimdRegElem)context.CurrOp; - if (op.Size < 1) throw new Exception("Undefined"); Operand m = EmitVectorExtract32(context, op.Vm >> (4 - op.Size), op.Vm & ((1 << (4 - op.Size)) - 1), op.Size, signed); Operand res = GetVecA32(op.Qd); @@ -388,16 +385,12 @@ namespace ARMeilleure.Instructions context.Copy(GetVecA32(op.Qd), res); } - // PAIRWISE + // Pairwise public static void EmitVectorPairwiseOpF32(ArmEmitterContext context, Func2I emit) { OpCode32SimdReg op = (OpCode32SimdReg)context.CurrOp; - if (op.Q) - { - throw new Exception("Q mode not supported for pairwise"); - } int sizeF = op.Size & 1; OperandType type = sizeF != 0 ? OperandType.FP64 : OperandType.FP32; @@ -431,11 +424,6 @@ namespace ARMeilleure.Instructions { OpCode32SimdReg op = (OpCode32SimdReg)context.CurrOp; - if (op.Q) - { - throw new Exception("Q mode not supported for pairwise"); - } - int elems = op.GetBytesCount() >> op.Size; int pairs = elems >> 1; @@ -561,6 +549,5 @@ namespace ARMeilleure.Instructions return res; } - } } diff --git a/ARMeilleure/Instructions/InstEmitSimdLogical32.cs b/ARMeilleure/Instructions/InstEmitSimdLogical32.cs index 26ed3b2911..8f91cea848 100644 --- a/ARMeilleure/Instructions/InstEmitSimdLogical32.cs +++ b/ARMeilleure/Instructions/InstEmitSimdLogical32.cs @@ -1,16 +1,9 @@ using ARMeilleure.Decoders; -using ARMeilleure.IntermediateRepresentation; using ARMeilleure.Translation; -using System; -using System.Collections.Generic; -using System.Text; using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.Instructions.InstEmitSimdHelper; using static ARMeilleure.Instructions.InstEmitSimdHelper32; -using static ARMeilleure.Instructions.InstEmitFlowHelper; -using static ARMeilleure.IntermediateRepresentation.OperandHelper; -using System.Diagnostics; namespace ARMeilleure.Instructions { diff --git a/ARMeilleure/Instructions/InstEmitSimdMemory32.cs b/ARMeilleure/Instructions/InstEmitSimdMemory32.cs index 2718ddfdb2..d15bd63622 100644 --- a/ARMeilleure/Instructions/InstEmitSimdMemory32.cs +++ b/ARMeilleure/Instructions/InstEmitSimdMemory32.cs @@ -16,14 +16,17 @@ namespace ARMeilleure.Instructions { EmitVStoreOrLoadN(context, 1, false); } + public static void Vst2(ArmEmitterContext context) { EmitVStoreOrLoadN(context, 2, false); } + public static void Vst3(ArmEmitterContext context) { EmitVStoreOrLoadN(context, 3, false); } + public static void Vst4(ArmEmitterContext context) { EmitVStoreOrLoadN(context, 4, false); @@ -33,14 +36,17 @@ namespace ARMeilleure.Instructions { EmitVStoreOrLoadN(context, 1, true); } + public static void Vld2(ArmEmitterContext context) { EmitVStoreOrLoadN(context, 2, true); } + public static void Vld3(ArmEmitterContext context) { EmitVStoreOrLoadN(context, 3, true); } + public static void Vld4(ArmEmitterContext context) { EmitVStoreOrLoadN(context, 4, true); @@ -52,18 +58,17 @@ namespace ARMeilleure.Instructions { OpCode32SimdMemSingle op = (OpCode32SimdMemSingle)context.CurrOp; - if (op.Replicate && !load) throw new Exception("Replicate+Store is undefined for STn"); int eBytes = 1 << op.Size; Operand n = context.Copy(GetIntA32(context, op.Rn)); - //check alignment (?) + // TODO: Check alignment. int offset = 0; int d = op.Vd; - for (int i=0; i> 2); if (op.Op == 1) { - // to general purpose + // To general purpose. Operand value = context.VectorExtract(OperandType.I32, vec, op.Vn & 0x3); SetIntA32(context, op.Rt, value); } else { - // from general purpose + // From general purpose. Operand value = GetIntA32(context, op.Rt); context.Copy(vec, context.VectorInsert(vec, value, op.Vn & 0x3)); } @@ -44,16 +44,17 @@ namespace ARMeilleure.Instructions public static void Vmov_G1(ArmEmitterContext context) { OpCode32SimdMovGpElem op = (OpCode32SimdMovGpElem)context.CurrOp; + int index = op.Index + ((op.Vd & 1) << (3 - op.Size)); if (op.Op == 1) { - // to general purpose + // To general purpose. Operand value = EmitVectorExtract32(context, op.Vd >> 1, index, op.Size, !op.U); SetIntA32(context, op.Rt, value); } else { - // from general purpose + // From general purpose. Operand vec = GetVecA32(op.Vd >> 1); Operand value = GetIntA32(context, op.Rt); context.Copy(vec, EmitVectorInsert(context, vec, value, index, op.Size)); @@ -63,13 +64,14 @@ namespace ARMeilleure.Instructions public static void Vmov_G2(ArmEmitterContext context) { OpCode32SimdMovGpDouble op = (OpCode32SimdMovGpDouble)context.CurrOp; + Operand vec = GetVecA32(op.Vm >> 2); int vm1 = (op.Vm + 1); bool sameOwnerVec = (op.Vm >> 2) == (vm1 >> 2); Operand vec2 = sameOwnerVec ? vec : GetVecA32(vm1 >> 2); if (op.Op == 1) { - // to general purpose + // To general purpose. Operand lowValue = context.VectorExtract(OperandType.I32, vec, op.Vm & 3); SetIntA32(context, op.Rt, lowValue); @@ -78,7 +80,7 @@ namespace ARMeilleure.Instructions } else { - // from general purpose + // From general purpose. Operand lowValue = GetIntA32(context, op.Rt); Operand resultVec = context.VectorInsert(vec, lowValue, op.Vm & 3); @@ -93,31 +95,30 @@ namespace ARMeilleure.Instructions context.Copy(vec, resultVec); context.Copy(vec2, context.VectorInsert(vec2, highValue, vm1 & 3)); } - } } public static void Vmov_GD(ArmEmitterContext context) { OpCode32SimdMovGpDouble op = (OpCode32SimdMovGpDouble)context.CurrOp; + Operand vec = GetVecA32(op.Vm >> 1); if (op.Op == 1) { - // to general purpose + // To general purpose. Operand value = context.VectorExtract(OperandType.I64, vec, op.Vm & 1); SetIntA32(context, op.Rt, context.ConvertI64ToI32(value)); SetIntA32(context, op.Rt2, context.ConvertI64ToI32(context.ShiftRightUI(value, Const(32)))); } else { - // from general purpose + // From general purpose. Operand lowValue = GetIntA32(context, op.Rt); Operand highValue = GetIntA32(context, op.Rt2); Operand value = context.BitwiseOr( context.ZeroExtend32(OperandType.I64, lowValue), - context.ShiftLeft(context.ZeroExtend32(OperandType.I64, highValue), Const(32)) - ); + context.ShiftLeft(context.ZeroExtend32(OperandType.I64, highValue), Const(32))); context.Copy(vec, context.VectorInsert(vec, value, op.Vm & 1)); } @@ -133,11 +134,11 @@ namespace ARMeilleure.Instructions int length = op.Length + 1; - Tuple[] tableTuples = new Tuple[length]; + (int Qx, int Ix)[] tableTuples = new (int qx, int ix)[length]; for (int i=0; i< length; i++) { (int vn, int en) = GetQuadwordAndSubindex(op.Vn + i, op.RegisterSize); - tableTuples[i] = new Tuple(vn, en); + tableTuples[i] = (vn, en); } int byteLength = length * 8; @@ -151,41 +152,39 @@ namespace ARMeilleure.Instructions Operand end = Label(); Operand inRange = context.ICompareLess(selectedIndex, Const(byteLength)); - Operand elemRes = null; // note: this is I64 for ease of calculation + Operand elemRes = null; // Note: This is I64 for ease of calculation. - // for some reason this branch ruins everything so we do an extract + conditional select instead - // granted that is slower - // --- context.BranchIfFalse(end, inRange); --- + // TODO: Branching rather than conditional select. - // get indexed byte - // to simplify (ha) the il, we get bytes from every vector and use a nested conditional select to choose the right result - // does have to extract `length` times for every element but certainly not as bad as it could be + // Get indexed byte. + // To simplify (ha) the il, we get bytes from every vector and use a nested conditional select to choose the right result. + // This does have to extract `length` times for every element but certainly not as bad as it could be. - // which vector number is the index on + // Which vector number is the index on. Operand vecIndex = context.ShiftRightUI(selectedIndex, Const(3)); - // what should we shift by to extract it + // What should we shift by to extract it. Operand subVecIndexShift = context.ShiftLeft(context.BitwiseAnd(selectedIndex, Const(7)), Const(3)); - for (int i=0; i < length; i++) + for (int i = 0; i < length; i++) { - Tuple vectorLocation = tableTuples[i]; - // get the whole vector, we'll get a byte out of it + (int qx, int ix) = tableTuples[i]; + // Get the whole vector, we'll get a byte out of it. Operand lookupResult; - if (vectorLocation.Item1 == op.Qd) + if (qx == op.Qd) { - // result contains the current state of the vector - lookupResult = context.VectorExtract(OperandType.I64, res, vectorLocation.Item2); + // Result contains the current state of the vector. + lookupResult = context.VectorExtract(OperandType.I64, res, ix); } else { - lookupResult = EmitVectorExtract32(context, vectorLocation.Item1, vectorLocation.Item2, 3, false); //I64 + lookupResult = EmitVectorExtract32(context, qx, ix, 3, false); // I64 } - lookupResult = context.ShiftRightUI(lookupResult, subVecIndexShift); // get the relevant byte from this vector + lookupResult = context.ShiftRightUI(lookupResult, subVecIndexShift); // Get the relevant byte from this vector. if (i == 0) { - elemRes = lookupResult; //first result is always default + elemRes = lookupResult; // First result is always default. } else { diff --git a/ARMeilleure/Instructions/InstEmitSimdShift32.cs b/ARMeilleure/Instructions/InstEmitSimdShift32.cs index bacd9b93f1..e312ddf3bc 100644 --- a/ARMeilleure/Instructions/InstEmitSimdShift32.cs +++ b/ARMeilleure/Instructions/InstEmitSimdShift32.cs @@ -15,12 +15,14 @@ namespace ARMeilleure.Instructions public static void Vshl(ArmEmitterContext context) { OpCode32SimdShift op = (OpCode32SimdShift)context.CurrOp; + EmitVectorUnaryOpZx32(context, (op1) => context.ShiftLeft(op1, Const(op1.Type, op.Shift))); } public static void Vshl_I(ArmEmitterContext context) { OpCode32SimdReg op = (OpCode32SimdReg)context.CurrOp; + if (op.U) { EmitVectorBinaryOpZx32(context, (op1, op2) => EmitShlRegOp(context, op2, op1, op.Size, true)); @@ -59,7 +61,7 @@ namespace ARMeilleure.Instructions Operand isOutOfRange0 = context.ICompareGreaterOrEqual(shiftLsB, Const(8 << size)); Operand isOutOfRangeN = context.ICompareGreaterOrEqual(negShiftLsB, Const(8 << size)); - //also zero if shift is too negative, but value was positive + // Also zero if shift is too negative, but value was positive. isOutOfRange0 = context.BitwiseOr(isOutOfRange0, context.BitwiseAnd(isOutOfRangeN, context.ICompareGreaterOrEqual(op, Const(op.Type, 0)))); Operand min = (op.Type == OperandType.I64) ? Const(-1L) : Const(-1); @@ -67,6 +69,5 @@ namespace ARMeilleure.Instructions return context.ConditionalSelect(isOutOfRange0, Const(op.Type, 0), context.ConditionalSelect(isOutOfRangeN, min, res)); } } - } } diff --git a/ARMeilleure/Instructions/InstEmitSystem32.cs b/ARMeilleure/Instructions/InstEmitSystem32.cs index 52a4679a9c..d89ddfcb4a 100644 --- a/ARMeilleure/Instructions/InstEmitSystem32.cs +++ b/ARMeilleure/Instructions/InstEmitSystem32.cs @@ -14,11 +14,11 @@ namespace ARMeilleure.Instructions { public static void Vmrs(ArmEmitterContext context) { - var op = (OpCode32SimdSpecial)context.CurrOp; + OpCode32SimdSpecial op = (OpCode32SimdSpecial)context.CurrOp; - if (op.Rt == 15 && op.Sreg == 0b0001) + if (op.Rt == RegisterAlias.Aarch32Pc && op.Sreg == 0b0001) { - //special behavior: copy NZCV flags into APSR + // Special behavior: copy NZCV flags into APSR. SetFlag(context, PState.VFlag, GetFpFlag(FPState.VFlag)); SetFlag(context, PState.CFlag, GetFpFlag(FPState.CFlag)); SetFlag(context, PState.ZFlag, GetFpFlag(FPState.ZFlag)); @@ -29,17 +29,17 @@ namespace ARMeilleure.Instructions Delegate dlg; switch (op.Sreg) { - case 0b0000: //FPSID + case 0b0000: // FPSID throw new NotImplementedException("Supervisor Only"); - case 0b0001: //FPSCR + case 0b0001: // FPSCR dlg = new _U32(NativeInterface.GetFpscr); break; - case 0b0101: //MVFR2 + case 0b0101: // MVFR2 throw new NotImplementedException("MVFR2"); - case 0b0110: //MVFR1 + case 0b0110: // MVFR1 throw new NotImplementedException("MVFR1"); - case 0b0111: //MVFR0 + case 0b0111: // MVFR0 throw new NotImplementedException("MVFR0"); - case 0b1000: //FPEXC + case 0b1000: // FPEXC throw new NotImplementedException("Supervisor Only"); default: throw new NotImplementedException($"Unknown VMRS 0x{op.RawOpCode:X8} at 0x{op.Address:X16}."); } @@ -49,22 +49,22 @@ namespace ARMeilleure.Instructions public static void Vmsr(ArmEmitterContext context) { - var op = (OpCode32SimdSpecial)context.CurrOp; + OpCode32SimdSpecial op = (OpCode32SimdSpecial)context.CurrOp; Delegate dlg; switch (op.Sreg) { - case 0b0000: //FPSID + case 0b0000: // FPSID throw new NotImplementedException("Supervisor Only"); - case 0b0001: //FPSCR + case 0b0001: // FPSCR dlg = new _Void_U32(NativeInterface.SetFpscr); break; - case 0b0101: //MVFR2 + case 0b0101: // MVFR2 throw new NotImplementedException("MVFR2"); - case 0b0110: //MVFR1 + case 0b0110: // MVFR1 throw new NotImplementedException("MVFR1"); - case 0b0111: //MVFR0 + case 0b0111: // MVFR0 throw new NotImplementedException("MVFR0"); - case 0b1000: //FPEXC + case 0b1000: // FPEXC throw new NotImplementedException("Supervisor Only"); default: throw new NotImplementedException($"Unknown VMSR 0x{op.RawOpCode:X8} at 0x{op.Address:X16}."); } @@ -74,7 +74,7 @@ namespace ARMeilleure.Instructions public static void Mrc(ArmEmitterContext context) { - var op = (OpCode32System)context.CurrOp; + OpCode32System op = (OpCode32System)context.CurrOp; if (op.Coproc != 15) { @@ -89,7 +89,7 @@ namespace ARMeilleure.Instructions Delegate dlg; switch (op.CRn) { - case 13: // Process and Thread Info + case 13: // Process and Thread Info. if (op.CRm != 0) { throw new NotImplementedException($"Unknown MRC CRm 0x{op.CRm:X16} at 0x{op.Address:X16}."); @@ -107,9 +107,9 @@ namespace ARMeilleure.Instructions default: throw new NotImplementedException($"Unknown MRC 0x{op.RawOpCode:X8} at 0x{op.Address:X16}."); } - if (op.Rt == 15) + if (op.Rt == RegisterAlias.Aarch32Pc) { - //special behavior: copy NZCV flags into APSR + // Special behavior: copy NZCV flags into APSR. EmitSetNzcv(context, context.Call(dlg)); return; } @@ -121,7 +121,7 @@ namespace ARMeilleure.Instructions public static void Mcr(ArmEmitterContext context) { - var op = (OpCode32System)context.CurrOp; + OpCode32System op = (OpCode32System)context.CurrOp; if (op.Coproc != 15) { @@ -136,7 +136,7 @@ namespace ARMeilleure.Instructions Delegate dlg; switch (op.CRn) { - case 13: // Process and Thread Info + case 13: // Process and Thread Info. if (op.CRm != 0) { throw new NotImplementedException($"Unknown MRC CRm 0x{op.CRm:X16} at 0x{op.Address:X16}."); @@ -151,13 +151,13 @@ namespace ARMeilleure.Instructions break; case 7: - switch (op.CRm) // Cache and Memory barrier + switch (op.CRm) // Cache and Memory barrier. { case 10: switch (op.Opc2) { - case 5: // Data Memory Barrier Register - return; // no-op + case 5: // Data Memory Barrier Register. + return; // No-op. default: throw new NotImplementedException($"Unknown MRC Opc2 0x{op.Opc2:X16} at 0x{op.Address:X16}."); } @@ -193,7 +193,7 @@ namespace ARMeilleure.Instructions public static void Mrrc(ArmEmitterContext context) { - var op = (OpCode32System)context.CurrOp; + OpCode32System op = (OpCode32System)context.CurrOp; if (op.Coproc != 15) { @@ -205,7 +205,7 @@ namespace ARMeilleure.Instructions Delegate dlg; switch (op.CRm) { - case 14: // Timer + case 14: // Timer. switch (opc) { case 0: @@ -222,5 +222,9 @@ namespace ARMeilleure.Instructions SetIntA32(context, op.Rt, context.ConvertI64ToI32(result)); SetIntA32(context, op.CRn, context.ConvertI64ToI32(context.ShiftRightUI(result, Const(32)))); } + + public static void Nop(ArmEmitterContext context) + { + } } } diff --git a/ARMeilleure/Instructions/InstName.cs b/ARMeilleure/Instructions/InstName.cs index 8590247dd3..fd667fedcd 100644 --- a/ARMeilleure/Instructions/InstName.cs +++ b/ARMeilleure/Instructions/InstName.cs @@ -545,9 +545,10 @@ namespace ARMeilleure.Instructions Vldr, Vmax, Vmin, - VMMmn, Vmla, Vmls, + VMMmn, + Vmov, Vmrs, Vmsr, Vmul, @@ -578,7 +579,5 @@ namespace ARMeilleure.Instructions Vtrn, Vuzp, Vzip, - - Vmov } } diff --git a/ARMeilleure/Instructions/SoftFloat.cs b/ARMeilleure/Instructions/SoftFloat.cs index 38edbba300..6cca80da75 100644 --- a/ARMeilleure/Instructions/SoftFloat.cs +++ b/ARMeilleure/Instructions/SoftFloat.cs @@ -1535,6 +1535,7 @@ namespace ARMeilleure.Instructions } } } + return result; } @@ -2826,6 +2827,7 @@ namespace ARMeilleure.Instructions } } } + return result; } @@ -3026,7 +3028,7 @@ namespace ARMeilleure.Instructions private static double FPThree(bool sign) { - return sign ? -2d : +2d; + return sign ? -3d : +3d; } private static double FPOnePointFive(bool sign) diff --git a/ARMeilleure/State/FPCR.cs b/ARMeilleure/State/FPCR.cs index 42f061aca5..913065ea32 100644 --- a/ARMeilleure/State/FPCR.cs +++ b/ARMeilleure/State/FPCR.cs @@ -3,7 +3,7 @@ using System; namespace ARMeilleure.State { [Flags] - public enum FPCR : ulong + public enum FPCR : uint { Ufe = 1 << 11, Fz = 1 << 24, diff --git a/ARMeilleure/State/FPSR.cs b/ARMeilleure/State/FPSR.cs index 4268a94658..47323b35c5 100644 --- a/ARMeilleure/State/FPSR.cs +++ b/ARMeilleure/State/FPSR.cs @@ -3,7 +3,7 @@ using System; namespace ARMeilleure.State { [Flags] - public enum FPSR : ulong + public enum FPSR : uint { Ufc = 1 << 3, Qc = 1 << 27, diff --git a/ARMeilleure/State/RegisterAlias.cs b/ARMeilleure/State/RegisterAlias.cs index ae0d456283..7ebfa27535 100644 --- a/ARMeilleure/State/RegisterAlias.cs +++ b/ARMeilleure/State/RegisterAlias.cs @@ -32,6 +32,7 @@ namespace ARMeilleure.State public const int SpFiq = 29; public const int LrFiq = 30; + public const int Aarch32Sp = 13; public const int Aarch32Lr = 14; public const int Aarch32Pc = 15; diff --git a/ARMeilleure/Translation/RegisterUsage.cs b/ARMeilleure/Translation/RegisterUsage.cs index 3a550100b0..770c385846 100644 --- a/ARMeilleure/Translation/RegisterUsage.cs +++ b/ARMeilleure/Translation/RegisterUsage.cs @@ -403,7 +403,6 @@ namespace ARMeilleure.Translation private static long ClearCallerSavedIntRegs(long mask) { - // TODO: ARM32 support. mask &= ~(CallerSavedIntRegistersMask | PStateNzcvFlagsMask); return mask; @@ -411,7 +410,6 @@ namespace ARMeilleure.Translation private static long ClearCallerSavedVecRegs(long mask) { - // TODO: ARM32 support. mask &= ~(CallerSavedVecRegistersMask | FpStateNzcvFlagsMask); return mask; diff --git a/ARMeilleure/Translation/Translator.cs b/ARMeilleure/Translation/Translator.cs index e538b7e756..fbb1c33a4a 100644 --- a/ARMeilleure/Translation/Translator.cs +++ b/ARMeilleure/Translation/Translator.cs @@ -20,7 +20,7 @@ namespace ARMeilleure.Translation private ConcurrentDictionary _funcs; - private PriorityQueue> _backgroundQueue; + private PriorityQueue<(ulong Address, ExecutionMode Mode)> _backgroundQueue; private AutoResetEvent _backgroundTranslatorEvent; @@ -32,7 +32,7 @@ namespace ARMeilleure.Translation _funcs = new ConcurrentDictionary(); - _backgroundQueue = new PriorityQueue>(2); + _backgroundQueue = new PriorityQueue<(ulong, ExecutionMode)>(2); _backgroundTranslatorEvent = new AutoResetEvent(false); } @@ -41,11 +41,11 @@ namespace ARMeilleure.Translation { while (_threadCount != 0) { - if (_backgroundQueue.TryDequeue(out Tuple request)) + if (_backgroundQueue.TryDequeue(out (ulong Address, ExecutionMode Mode) request)) { - TranslatedFunction func = Translate(request.Item1, request.Item2, highCq: true); + TranslatedFunction func = Translate(request.Address, request.Mode, highCq: true); - _funcs.AddOrUpdate(request.Item1, func, (key, oldFunc) => func); + _funcs.AddOrUpdate(request.Address, func, (key, oldFunc) => func); } else { @@ -114,7 +114,7 @@ namespace ARMeilleure.Translation } else if (isCallTarget && func.ShouldRejit()) { - _backgroundQueue.Enqueue(0, new Tuple(address, mode)); + _backgroundQueue.Enqueue(0, (address, mode)); _backgroundTranslatorEvent.Set(); } diff --git a/Ryujinx.Tests.Unicorn/Native/Arm32Register.cs b/Ryujinx.Tests.Unicorn/Native/Arm32Register.cs index 7e33a1229e..f34b42a917 100644 --- a/Ryujinx.Tests.Unicorn/Native/Arm32Register.cs +++ b/Ryujinx.Tests.Unicorn/Native/Arm32Register.cs @@ -127,7 +127,7 @@ namespace Ryujinx.Tests.Unicorn.Native CONTROL, ENDING, - // alias registers + // Alias registers. R13 = SP, R14 = LR, R15 = PC, diff --git a/Ryujinx.Tests.Unicorn/UnicornAArch32.cs b/Ryujinx.Tests.Unicorn/UnicornAArch32.cs index f66dd9e7c7..846f5fc457 100644 --- a/Ryujinx.Tests.Unicorn/UnicornAArch32.cs +++ b/Ryujinx.Tests.Unicorn/UnicornAArch32.cs @@ -1,7 +1,5 @@ using Ryujinx.Tests.Unicorn.Native; using System; -using System.Collections.Generic; -using System.Text; namespace Ryujinx.Tests.Unicorn { @@ -148,7 +146,7 @@ namespace Ryujinx.Tests.Unicorn public uint GetX(int index) { - if ((uint)index > 30) + if ((uint)index > 15) { throw new ArgumentOutOfRangeException(nameof(index)); } @@ -158,7 +156,7 @@ namespace Ryujinx.Tests.Unicorn public void SetX(int index, uint value) { - if ((uint)index > 30) + if ((uint)index > 15) { throw new ArgumentOutOfRangeException(nameof(index)); } @@ -173,7 +171,8 @@ namespace Ryujinx.Tests.Unicorn throw new ArgumentOutOfRangeException(nameof(index)); } - return GetVector((Arm32Register)((int)Arm32Register.D0 + index * 2)); //QRegisters[index]); + // Getting quadword registers from Unicorn A32 seems to be broken, so we combine its 2 doubleword registers instead. + return GetVector((Arm32Register)((int)Arm32Register.D0 + index * 2)); } public void SetQ(int index, SimdValue value) diff --git a/Ryujinx.Tests/Cpu/CpuTest32.cs b/Ryujinx.Tests/Cpu/CpuTest32.cs index 83a82ff7d0..ed1d23d37b 100644 --- a/Ryujinx.Tests/Cpu/CpuTest32.cs +++ b/Ryujinx.Tests/Cpu/CpuTest32.cs @@ -4,10 +4,7 @@ using ARMeilleure.Translation; using NUnit.Framework; using Ryujinx.Tests.Unicorn; using System; -using System.Collections.Generic; -using System.Linq; using System.Runtime.InteropServices; -using System.Text; namespace Ryujinx.Tests.Cpu { @@ -361,7 +358,8 @@ namespace Ryujinx.Tests.Cpu byte[] meilleureMem = _memory.ReadBytes((long)(0x2000), _size); byte[] unicornMem = _unicornEmu.MemoryRead((ulong)(0x2000), (ulong)_size); - for (int i = 0; i < _size; i++) { + for (int i = 0; i < _size; i++) + { Assert.AreEqual(meilleureMem[i], unicornMem[i]); } } diff --git a/Ryujinx.Tests/Cpu/CpuTestAlu32.cs b/Ryujinx.Tests/Cpu/CpuTestAlu32.cs index 7efbcd8602..266ec9dd40 100644 --- a/Ryujinx.Tests/Cpu/CpuTestAlu32.cs +++ b/Ryujinx.Tests/Cpu/CpuTestAlu32.cs @@ -1,8 +1,6 @@ #define Alu32 using NUnit.Framework; using System; -using System.Collections.Generic; -using System.Text; namespace Ryujinx.Tests.Cpu { diff --git a/Ryujinx.Tests/Cpu/CpuTestBf32.cs b/Ryujinx.Tests/Cpu/CpuTestBf32.cs index 4f0d2a2c9a..acc70a5971 100644 --- a/Ryujinx.Tests/Cpu/CpuTestBf32.cs +++ b/Ryujinx.Tests/Cpu/CpuTestBf32.cs @@ -1,7 +1,5 @@ using NUnit.Framework; using System; -using System.Collections.Generic; -using System.Text; namespace Ryujinx.Tests.Cpu { @@ -19,7 +17,7 @@ namespace Ryujinx.Tests.Cpu [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint lsb, [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImms)] uint msb) { - msb = Math.Max(lsb, msb); // don't test unpredictable for now + msb = Math.Max(lsb, msb); // Don't test unpredictable for now. uint opcode = 0xe7c0001fu; // BFC R0, #0, #1 opcode |= ((rd & 0xf) << 12); opcode |= ((msb & 31) << 16) | ((lsb & 31) << 7); @@ -40,7 +38,7 @@ namespace Ryujinx.Tests.Cpu [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImmr)] uint lsb, [Values(0u, 15u, 16u, 31u)] [Random(0u, 31u, RndCntImms)] uint msb) { - msb = Math.Max(lsb, msb); // don't test unpredictable for now + msb = Math.Max(lsb, msb); // Don't test unpredictable for now. uint opcode = 0xe7c00010u; // BFI R0, R0, #0, #1 opcode |= ((rd & 0xf) << 12); opcode |= ((rn & 0xf) << 0); diff --git a/Ryujinx.Tests/Cpu/CpuTestSimdLogical32.cs b/Ryujinx.Tests/Cpu/CpuTestSimdLogical32.cs index 67da4a61fd..2c9dfb6b6a 100644 --- a/Ryujinx.Tests/Cpu/CpuTestSimdLogical32.cs +++ b/Ryujinx.Tests/Cpu/CpuTestSimdLogical32.cs @@ -1,10 +1,7 @@ #define SimdLogical32 using ARMeilleure.State; using NUnit.Framework; - using System; -using System.Collections.Generic; -using System.Text; namespace Ryujinx.Tests.Cpu { diff --git a/Ryujinx.Tests/Cpu/CpuTestSimdMemory32.cs b/Ryujinx.Tests/Cpu/CpuTestSimdMemory32.cs index 92ffe8869a..4751833b2f 100644 --- a/Ryujinx.Tests/Cpu/CpuTestSimdMemory32.cs +++ b/Ryujinx.Tests/Cpu/CpuTestSimdMemory32.cs @@ -3,9 +3,6 @@ using ARMeilleure.State; using NUnit.Framework; using System; -using System.Collections.Generic; -using System.Runtime.InteropServices; -using System.Text; namespace Ryujinx.Tests.Cpu { @@ -16,26 +13,26 @@ namespace Ryujinx.Tests.Cpu private const int RndCntImm = 2; private uint[] LDSTModes = - { - //LD1 - 0b0111, - 0b1010, - 0b0110, - 0b0010, + { + // LD1 + 0b0111, + 0b1010, + 0b0110, + 0b0010, - //LD2 - 0b1000, - 0b1001, - 0b0011, + // LD2 + 0b1000, + 0b1001, + 0b0011, - //LD3 - 0b0100, - 0b0101, + // LD3 + 0b0100, + 0b0101, - //LD4 - 0b0000, - 0b0001 - }; + // LD4 + 0b0000, + 0b0001 + }; [Test, Pairwise, Description("VLDn. , [ {:}]{ /!/, } (single n element structure)")] public void Vldn_Single([Values(0u, 1u, 2u)] uint size, @@ -60,7 +57,7 @@ namespace Ryujinx.Tests.Cpu opcode |= ((vd & 0x10) << 18); opcode |= ((vd & 0xf) << 12); - opcode |= (n & 3) << 8; //LD1 is 0, LD2 is 1 etc + opcode |= (n & 3) << 8; // LD1 is 0, LD2 is 1 etc. SingleOpcode(opcode, r0: 0x2500, r1: offset, sp: 0x2500); @@ -86,8 +83,8 @@ namespace Ryujinx.Tests.Cpu opcode |= ((vd & 0x10) << 18); opcode |= ((vd & 0xf) << 12); - opcode |= (n & 3) << 8; //LD1 is 0, LD2 is 1 etc - if (t) opcode |= 1 << 5; //LD1 is 0, LD2 is 1 etc + opcode |= (n & 3) << 8; // LD1 is 0, LD2 is 1 etc. + if (t) opcode |= 1 << 5; SingleOpcode(opcode, r0: 0x2500, r1: offset, sp: 0x2500); @@ -142,7 +139,7 @@ namespace Ryujinx.Tests.Cpu opcode |= ((vd & 0x10) << 18); opcode |= ((vd & 0xf) << 12); - opcode |= (n & 3) << 8; //ST1 is 0, ST2 is 1 etc + opcode |= (n & 3) << 8; // ST1 is 0, ST2 is 1 etc. SingleOpcode(opcode, r0: 0x2500, r1: offset, v1: vec1, v2: vec2, v3: vec3, v4: vec4, sp: 0x2500); @@ -187,10 +184,10 @@ namespace Ryujinx.Tests.Cpu uint opcode = 0xec100a00u; // VST4.8 {D0, D1, D2, D3}, [R0], R0 uint[] vldmModes = { - //note: 3rd 0 leaves a space for "D" - 0b0100, // increment after - 0b0101, // increment after ! - 0b1001 // decrement before ! + // Note: 3rd 0 leaves a space for "D". + 0b0100, // Increment after. + 0b0101, // Increment after. (!) + 0b1001 // Decrement before. (!) }; opcode |= ((vldmModes[mode] & 15) << 21); @@ -201,15 +198,15 @@ namespace Ryujinx.Tests.Cpu opcode |= ((uint)(single ? 0 : 1) << 8); - if (!single) regs = (regs << 1); //low bit must be 0 - must be even number of registers. + if (!single) regs = (regs << 1); // Low bit must be 0 - must be even number of registers. uint regSize = single ? 1u : 2u; - if (vd + (regs / regSize) > 32) //can't address further than s31 or d31 + if (vd + (regs / regSize) > 32) // Can't address further than S31 or D31. { regs -= (vd + (regs / regSize)) - 32; } - if (regs / regSize > 16) //can't do more than 16 registers at a time + if (regs / regSize > 16) // Can't do more than 16 registers at a time. { regs = 16 * regSize; } @@ -222,7 +219,7 @@ namespace Ryujinx.Tests.Cpu } [Test, Pairwise, Description("VLDR. , [ {, #{+/-}}]")] - public void Vldr([Values(2u, 3u)] uint size, //fp16 is not supported for now + public void Vldr([Values(2u, 3u)] uint size, // FP16 is not supported for now [Values(0u)] uint rn, [Values(0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u)] uint sd, [Values(0x0u)] [Random(0u, 0xffu, RndCntImm)] uint imm, @@ -249,7 +246,7 @@ namespace Ryujinx.Tests.Cpu opcode |= ((sd & 0x10) << 18); opcode |= ((sd & 0xf) << 12); } - opcode |= (uint)imm & 0xff; + opcode |= imm & 0xff; SingleOpcode(opcode, r0: 0x2500); @@ -257,7 +254,7 @@ namespace Ryujinx.Tests.Cpu } [Test, Pairwise, Description("VSTR. , [ {, #{+/-}}]")] - public void Vstr([Values(2u, 3u)] uint size, //fp16 is not supported for now + public void Vstr([Values(2u, 3u)] uint size, // FP16 is not supported for now [Values(0u)] uint rn, [Values(0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u)] uint sd, [Values(0x0u)] [Random(0u, 0xffu, RndCntImm)] uint imm, @@ -284,7 +281,7 @@ namespace Ryujinx.Tests.Cpu opcode |= ((sd & 0x10) << 18); opcode |= ((sd & 0xf) << 12); } - opcode |= (uint)imm & 0xff; + opcode |= imm & 0xff; (V128 vec1, V128 vec2, _, _) = GenerateTestVectors(); @@ -308,7 +305,7 @@ namespace Ryujinx.Tests.Cpu int floatLength = length >> 2; float[] data = new float[floatLength]; - for (int i=0; i> 1; opcode |= (rt & 0xf) << 12; @@ -216,7 +215,7 @@ namespace Ryujinx.Tests.Cpu uint opcode = 0xf3b20080u; // VTRN.8 D0, D0 if (vm == vd) { - return; //undefined + return; // Undefined. } if (q) @@ -246,10 +245,10 @@ namespace Ryujinx.Tests.Cpu [Values(0u, 1u, 2u)] uint size, [Values] bool q) { - uint opcode = 0xf3b20180u; // VZIP.8 d0, d0 + uint opcode = 0xf3b20180u; // VZIP.8 D0, D0 if (vm == vd || (size == 2 && !q)) { - return; //undefined + return; // Undefined. } if (q) @@ -282,7 +281,7 @@ namespace Ryujinx.Tests.Cpu uint opcode = 0xf3b20100u; // VUZP.8 d0, d0 if (vm == vd || (size == 2 && !q)) { - return; //undefined + return; // Undefined. } if (q) @@ -307,16 +306,16 @@ namespace Ryujinx.Tests.Cpu } [Test, Combinatorial, Description("VTBL.8
, {list}, ")] - public void Vtbl([Range(0u, 6u)] uint vm, //indices, include potentially invalid - [Range(4u, 12u)] uint vn, //selection - [Values(0u, 1u)] uint vd, //destinations + public void Vtbl([Range(0u, 6u)] uint vm, // Indices, include potentially invalid. + [Range(4u, 12u)] uint vn, // Selection. + [Values(0u, 1u)] uint vd, // Destinations. [Range(0u, 3u)] uint length, [Values] bool x) { uint opcode = 0xf3b00800u; // VTBL.8 D0, {D0}, D0 if (vn + length > 31) { - return; //undefined + return; // Undefined. } if (x) @@ -371,7 +370,7 @@ namespace Ryujinx.Tests.Cpu } else if (imm4 > 7) { - return; //undefined + return; // Undefined. } opcode |= (vm & 0x10) << 1; opcode |= (vm & 0xf); @@ -412,8 +411,8 @@ namespace Ryujinx.Tests.Cpu opcode |= (vd & 0xf) << 16; opcode |= (rt & 0xf) << 12; - opcode |= (size & 1) << 5; // e - opcode |= (size & 2) << 21; // b + opcode |= (size & 1) << 5; // E + opcode |= (size & 2) << 21; // B V128 v1 = new V128(TestContext.CurrentContext.Random.NextULong(), TestContext.CurrentContext.Random.NextULong()); diff --git a/Ryujinx.Tests/Cpu/CpuTestSimdReg32.cs b/Ryujinx.Tests/Cpu/CpuTestSimdReg32.cs index 2f13ee718e..80cdf11a84 100644 --- a/Ryujinx.Tests/Cpu/CpuTestSimdReg32.cs +++ b/Ryujinx.Tests/Cpu/CpuTestSimdReg32.cs @@ -208,6 +208,7 @@ namespace Ryujinx.Tests.Cpu private static readonly bool NoInfs = false; private static readonly bool NoNaNs = false; + [Explicit] [Test, Pairwise, Description("VADD.f32 V0, V0, V0")] public void Vadd_f32([Values(0u)] uint rd, [Values(0u, 1u)] uint rn,