mirror of
https://git.naxdy.org/Mirror/Ryujinx.git
synced 2025-03-14 22:40:18 +00:00
T16: Implement LSL/LSR/ASR (imm)
This commit is contained in:
parent
cb4ccec421
commit
15ccdff751
6 changed files with 65 additions and 3 deletions
10
ARMeilleure/Decoders/IOpCode32AluRsImm.cs
Normal file
10
ARMeilleure/Decoders/IOpCode32AluRsImm.cs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
namespace ARMeilleure.Decoders
|
||||||
|
{
|
||||||
|
interface IOpCode32AluRsImm : IOpCode32Alu
|
||||||
|
{
|
||||||
|
int Rm { get; }
|
||||||
|
int Immediate { get; }
|
||||||
|
|
||||||
|
ShiftType ShiftType { get; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
namespace ARMeilleure.Decoders
|
namespace ARMeilleure.Decoders
|
||||||
{
|
{
|
||||||
class OpCode32AluRsImm : OpCode32Alu
|
class OpCode32AluRsImm : OpCode32Alu, IOpCode32AluRsImm
|
||||||
{
|
{
|
||||||
public int Rm { get; }
|
public int Rm { get; }
|
||||||
public int Immediate { get; }
|
public int Immediate { get; }
|
||||||
|
|
26
ARMeilleure/Decoders/OpCodeT16ShiftImm.cs
Normal file
26
ARMeilleure/Decoders/OpCodeT16ShiftImm.cs
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
namespace ARMeilleure.Decoders
|
||||||
|
{
|
||||||
|
class OpCodeT16ShiftImm : OpCodeT16, IOpCode32AluRsImm
|
||||||
|
{
|
||||||
|
public int Rd { get; }
|
||||||
|
public int Rn { get; }
|
||||||
|
public int Rm { get; }
|
||||||
|
|
||||||
|
public int Immediate { get; }
|
||||||
|
public ShiftType ShiftType { get; }
|
||||||
|
|
||||||
|
public bool SetFlags { get; }
|
||||||
|
|
||||||
|
public static new OpCode Create(InstDescriptor inst, ulong address, int opCode, bool inITBlock) => new OpCodeT16ShiftImm(inst, address, opCode, inITBlock);
|
||||||
|
|
||||||
|
public OpCodeT16ShiftImm(InstDescriptor inst, ulong address, int opCode, bool inITBlock) : base(inst, address, opCode, inITBlock)
|
||||||
|
{
|
||||||
|
Rd = (opCode >> 0) & 0x7;
|
||||||
|
Rm = (opCode >> 3) & 0x7;
|
||||||
|
Immediate = (opCode >> 6) & 0x1F;
|
||||||
|
ShiftType = (ShiftType)((opCode >> 11) & 3);
|
||||||
|
|
||||||
|
SetFlags = !inITBlock;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -974,6 +974,7 @@ namespace ARMeilleure.Decoders
|
||||||
|
|
||||||
#region "OpCode Table (AArch32, T16/T32)"
|
#region "OpCode Table (AArch32, T16/T32)"
|
||||||
// T16
|
// T16
|
||||||
|
SetT16("000<<xxxxxxxxxxx", InstName.Mov, InstEmit32.Mov, OpCodeT16ShiftImm.Create);
|
||||||
SetT16("010001110xxxx000", InstName.Bx, InstEmit32.Bx, OpCodeT16BReg.Create);
|
SetT16("010001110xxxx000", InstName.Bx, InstEmit32.Bx, OpCodeT16BReg.Create);
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
|
@ -195,7 +195,7 @@ namespace ARMeilleure.Instructions
|
||||||
|
|
||||||
case OpCode32AluImm16 op: return Const(op.Immediate);
|
case OpCode32AluImm16 op: return Const(op.Immediate);
|
||||||
|
|
||||||
case OpCode32AluRsImm op: return GetMShiftedByImmediate(context, op, setCarry);
|
case IOpCode32AluRsImm op: return GetMShiftedByImmediate(context, op, setCarry);
|
||||||
case OpCode32AluRsReg op: return GetMShiftedByReg(context, op, setCarry);
|
case OpCode32AluRsReg op: return GetMShiftedByReg(context, op, setCarry);
|
||||||
|
|
||||||
case IOpCode32AluReg op: return GetIntA32(context, op.Rm);
|
case IOpCode32AluReg op: return GetIntA32(context, op.Rm);
|
||||||
|
@ -247,7 +247,7 @@ namespace ARMeilleure.Instructions
|
||||||
}
|
}
|
||||||
|
|
||||||
// ARM32 helpers.
|
// ARM32 helpers.
|
||||||
public static Operand GetMShiftedByImmediate(ArmEmitterContext context, OpCode32AluRsImm op, bool setCarry)
|
public static Operand GetMShiftedByImmediate(ArmEmitterContext context, IOpCode32AluRsImm op, bool setCarry)
|
||||||
{
|
{
|
||||||
Operand m = GetIntA32(context, op.Rm);
|
Operand m = GetIntA32(context, op.Rm);
|
||||||
|
|
||||||
|
|
|
@ -7,5 +7,30 @@ namespace Ryujinx.Tests.Cpu
|
||||||
public sealed class CpuTestThumb : CpuTest32
|
public sealed class CpuTestThumb : CpuTest32
|
||||||
{
|
{
|
||||||
private const int RndCnt = 2;
|
private const int RndCnt = 2;
|
||||||
|
|
||||||
|
[Test, Pairwise]
|
||||||
|
public void ShiftImm([Range(0u, 2u)] uint shiftType, [Range(1u, 0x1fu)] uint shiftImm, [Random(RndCnt)] uint w1, [Random(RndCnt)] uint w2)
|
||||||
|
{
|
||||||
|
uint opcode = 0x0000; // MOVS <Rd>, <Rm>, <shift> #<amount>
|
||||||
|
|
||||||
|
uint rd = 1;
|
||||||
|
uint rm = 2;
|
||||||
|
opcode |= ((rd & 7) << 0) | ((rm & 7) << 3) | ((shiftImm & 0x1f) << 6) | ((shiftType & 3) << 11);
|
||||||
|
|
||||||
|
SingleThumbOpcode((ushort)opcode, r1: w1, r2: w2, runUnicorn: false);
|
||||||
|
|
||||||
|
switch (shiftType)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
Assert.That(GetContext().GetX(1), Is.EqualTo((w2 << (int)shiftImm) & 0xffffffffu));
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
Assert.That(GetContext().GetX(1), Is.EqualTo((w2 >> (int)shiftImm) & 0xffffffffu));
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
Assert.That(GetContext().GetX(1), Is.EqualTo(((int)w2 >> (int)shiftImm) & 0xffffffffu));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue