mirror of
https://git.naxdy.org/Mirror/Ryujinx.git
synced 2025-03-14 17:00:17 +00:00
T16: Implement ADD, CMP, MOV (high reg)
This commit is contained in:
parent
43feb68b11
commit
2876344cca
3 changed files with 69 additions and 0 deletions
22
ARMeilleure/Decoders/OpCodeT16AluRegHigh.cs
Normal file
22
ARMeilleure/Decoders/OpCodeT16AluRegHigh.cs
Normal file
|
@ -0,0 +1,22 @@
|
|||
namespace ARMeilleure.Decoders
|
||||
{
|
||||
class OpCodeT16AluRegHigh : OpCodeT16, IOpCode32AluReg
|
||||
{
|
||||
public int Rm { get; }
|
||||
public int Rd { get; }
|
||||
public int Rn { get; }
|
||||
|
||||
public bool SetFlags { get; }
|
||||
|
||||
public static new OpCode Create(InstDescriptor inst, ulong address, int opCode, bool inITBlock) => new OpCodeT16AluRegHigh(inst, address, opCode, inITBlock);
|
||||
|
||||
public OpCodeT16AluRegHigh(InstDescriptor inst, ulong address, int opCode, bool inITBlock) : base(inst, address, opCode, inITBlock)
|
||||
{
|
||||
Rd = ((opCode >> 0) & 0x7) | ((opCode >> 4) & 0x8);
|
||||
Rn = ((opCode >> 0) & 0x7) | ((opCode >> 4) & 0x8);
|
||||
Rm = (opCode >> 3) & 0xf;
|
||||
|
||||
SetFlags = false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -999,6 +999,9 @@ namespace ARMeilleure.Decoders
|
|||
SetT16("0100001101xxxxxx", InstName.Mul, InstEmit32.Mul, OpCodeT16AluRegLow.Create);
|
||||
SetT16("0100001110xxxxxx", InstName.Bic, InstEmit32.Bic, OpCodeT16AluRegLow.Create);
|
||||
SetT16("0100001111xxxxxx", InstName.Mvn, InstEmit32.Mvn, OpCodeT16AluRegLow.Create);
|
||||
SetT16("01000100xxxxxxxx", InstName.Add, InstEmit32.Add, OpCodeT16AluRegHigh.Create);
|
||||
SetT16("01000101xxxxxxxx", InstName.Cmp, InstEmit32.Cmp, OpCodeT16AluRegHigh.Create);
|
||||
SetT16("01000110xxxxxxxx", InstName.Mov, InstEmit32.Mov, OpCodeT16AluRegHigh.Create);
|
||||
SetT16("010001110xxxx000", InstName.Bx, InstEmit32.Bx, OpCodeT16BReg.Create);
|
||||
#endregion
|
||||
|
||||
|
|
|
@ -207,5 +207,49 @@ namespace Ryujinx.Tests.Cpu
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
[Test, Pairwise]
|
||||
public void AluRegHigh([Range(0u, 2u)] uint op, [Range(0u, 13u)] uint rd, [Range(0u, 13u)] uint rm, [Random(RndCnt)] uint w1, [Random(RndCnt)] uint w2)
|
||||
{
|
||||
if (rd == rm)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
uint opcode = 0x4400; // ADDS <Rdn>, <Rm>
|
||||
|
||||
opcode |= ((rd & 7) << 0) | ((rm & 0xf) << 3) | ((rd & 8) << 4) | ((op & 3) << 8);
|
||||
|
||||
ThumbOpcode((ushort)opcode);
|
||||
ThumbOpcode(0x4770); // BX LR
|
||||
|
||||
GetContext().SetX((int)rd, w1);
|
||||
GetContext().SetX((int)rm, w2);
|
||||
GetContext().SetPstateFlag(PState.TFlag, true);
|
||||
|
||||
ExecuteOpcodes(runUnicorn: false);
|
||||
|
||||
switch (op)
|
||||
{
|
||||
case 0:
|
||||
Assert.That(GetContext().GetX((int)rd), Is.EqualTo(w1 + w2));
|
||||
break;
|
||||
case 1:
|
||||
Assert.That(GetContext().GetX((int)rd), Is.EqualTo(w1));
|
||||
Assert.That(GetContext().GetX((int)rm), Is.EqualTo(w2));
|
||||
{
|
||||
uint result = w1 - w2;
|
||||
uint overflow = (result ^ w1) & (w1 ^ w2);
|
||||
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 >= w2));
|
||||
Assert.That(GetContext().GetPstateFlag(PState.VFlag), Is.EqualTo((overflow >> 31) != 0));
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
Assert.That(GetContext().GetX((int)rd), Is.EqualTo(w2));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue