mirror of
https://git.naxdy.org/Mirror/Ryujinx.git
synced 2025-03-14 22:40:18 +00:00
T16: Implement MOVS, CMP, ADDS, SUBS (8-bit immediate)
This commit is contained in:
parent
7a09aea0dc
commit
284272854b
3 changed files with 70 additions and 1 deletions
26
ARMeilleure/Decoders/OpCodeT16AluImm8.cs
Normal file
26
ARMeilleure/Decoders/OpCodeT16AluImm8.cs
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
namespace ARMeilleure.Decoders
|
||||||
|
{
|
||||||
|
class OpCodeT16AluImm8 : OpCodeT16, IOpCode32AluImm
|
||||||
|
{
|
||||||
|
public int Rd { get; }
|
||||||
|
public int Rn { get; }
|
||||||
|
|
||||||
|
public bool SetFlags { get; }
|
||||||
|
|
||||||
|
public int Immediate { get; }
|
||||||
|
|
||||||
|
public bool IsRotated { get; }
|
||||||
|
|
||||||
|
public static new OpCode Create(InstDescriptor inst, ulong address, int opCode, bool inITBlock) => new OpCodeT16AluImm8(inst, address, opCode, inITBlock);
|
||||||
|
|
||||||
|
public OpCodeT16AluImm8(InstDescriptor inst, ulong address, int opCode, bool inITBlock) : base(inst, address, opCode, inITBlock)
|
||||||
|
{
|
||||||
|
Rd = (opCode >> 8) & 0x7;
|
||||||
|
Rn = (opCode >> 8) & 0x7;
|
||||||
|
Immediate = (opCode >> 0) & 0xff;
|
||||||
|
IsRotated = false;
|
||||||
|
|
||||||
|
SetFlags = !inITBlock;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -979,6 +979,10 @@ namespace ARMeilleure.Decoders
|
||||||
SetT16("0001101xxxxxxxxx", InstName.Sub, InstEmit32.Sub, OpCodeT16AddSubReg.Create);
|
SetT16("0001101xxxxxxxxx", InstName.Sub, InstEmit32.Sub, OpCodeT16AddSubReg.Create);
|
||||||
SetT16("0001110xxxxxxxxx", InstName.Add, InstEmit32.Add, OpCodeT16AddSubImm3.Create);
|
SetT16("0001110xxxxxxxxx", InstName.Add, InstEmit32.Add, OpCodeT16AddSubImm3.Create);
|
||||||
SetT16("0001111xxxxxxxxx", InstName.Sub, InstEmit32.Sub, OpCodeT16AddSubImm3.Create);
|
SetT16("0001111xxxxxxxxx", InstName.Sub, InstEmit32.Sub, OpCodeT16AddSubImm3.Create);
|
||||||
|
SetT16("00100xxxxxxxxxxx", InstName.Mov, InstEmit32.Mov, OpCodeT16AluImm8.Create);
|
||||||
|
SetT16("00101xxxxxxxxxxx", InstName.Cmp, InstEmit32.Cmp, OpCodeT16AluImm8.Create);
|
||||||
|
SetT16("00110xxxxxxxxxxx", InstName.Add, InstEmit32.Add, OpCodeT16AluImm8.Create);
|
||||||
|
SetT16("00111xxxxxxxxxxx", InstName.Sub, InstEmit32.Sub, OpCodeT16AluImm8.Create);
|
||||||
SetT16("010001110xxxx000", InstName.Bx, InstEmit32.Bx, OpCodeT16BReg.Create);
|
SetT16("010001110xxxx000", InstName.Bx, InstEmit32.Bx, OpCodeT16BReg.Create);
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using NUnit.Framework;
|
using ARMeilleure.State;
|
||||||
|
using NUnit.Framework;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Ryujinx.Tests.Cpu
|
namespace Ryujinx.Tests.Cpu
|
||||||
|
@ -77,5 +78,43 @@ namespace Ryujinx.Tests.Cpu
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test, Pairwise]
|
||||||
|
public void AluImm8([Range(0u, 3u)] uint op, [Random(RndCnt)] uint imm, [Random(RndCnt)] uint w1)
|
||||||
|
{
|
||||||
|
imm &= 0xff;
|
||||||
|
|
||||||
|
uint opcode = 0x2000; // MOVS <Rdn>, #<imm8>
|
||||||
|
|
||||||
|
uint rdn = 1;
|
||||||
|
opcode |= ((imm & 0xff) << 0) | ((rdn & 7) << 8) | ((op & 3) << 11);
|
||||||
|
|
||||||
|
SingleThumbOpcode((ushort)opcode, r1: w1, runUnicorn: false);
|
||||||
|
|
||||||
|
switch (op)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
Assert.That(GetContext().GetX(1), Is.EqualTo(imm));
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
Assert.That(GetContext().GetX(1), Is.EqualTo(w1));
|
||||||
|
cmpFlags:
|
||||||
|
{
|
||||||
|
uint result = w1 - imm;
|
||||||
|
uint overflow = (result ^ w1) & (w1 ^ imm);
|
||||||
|
Assert.That(GetContext().GetPstateFlag(PState.NFlag), Is.EqualTo((result >> 31) != 0));
|
||||||
|
Assert.That(GetContext().GetPstateFlag(PState.ZFlag), Is.EqualTo(result == 0));
|
||||||
|
Assert.That(GetContext().GetPstateFlag(PState.CFlag), Is.EqualTo(w1 >= imm));
|
||||||
|
Assert.That(GetContext().GetPstateFlag(PState.VFlag), Is.EqualTo((overflow >> 31) != 0));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
Assert.That(GetContext().GetX(1), Is.EqualTo((w1 + imm) & 0xffffffffu));
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
Assert.That(GetContext().GetX(1), Is.EqualTo((w1 - imm) & 0xffffffffu));
|
||||||
|
goto cmpFlags;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue