add blx_reg for A32
This commit is contained in:
parent
437962a65d
commit
a22b30c294
3 changed files with 65 additions and 3 deletions
14
ChocolArm64/Decoders32/A32OpCodeBReg.cs
Normal file
14
ChocolArm64/Decoders32/A32OpCodeBReg.cs
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
using ChocolArm64.Instructions;
|
||||||
|
|
||||||
|
namespace ChocolArm64.Decoders32
|
||||||
|
{
|
||||||
|
class A32OpCodeBReg : A32OpCode
|
||||||
|
{
|
||||||
|
public int Rm { get; private set; }
|
||||||
|
|
||||||
|
public A32OpCodeBReg(Inst inst, long position, int opCode) : base(inst, position, opCode)
|
||||||
|
{
|
||||||
|
Rm = (opCode >> 0) & 0xf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -21,15 +21,23 @@ namespace ChocolArm64.Instructions32
|
||||||
|
|
||||||
public static void Bl(CpuThreadState state, MemoryManager memory, OpCode64 opCode)
|
public static void Bl(CpuThreadState state, MemoryManager memory, OpCode64 opCode)
|
||||||
{
|
{
|
||||||
Blx(state, memory, opCode, false);
|
Blx_Imm(state, memory, opCode, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Blx(CpuThreadState state, MemoryManager memory, OpCode64 opCode)
|
public static void Blx(CpuThreadState state, MemoryManager memory, OpCode64 opCode)
|
||||||
{
|
{
|
||||||
Blx(state, memory, opCode, true);
|
switch (opCode)
|
||||||
|
{
|
||||||
|
case A32OpCodeBImmAl op:
|
||||||
|
Blx_Imm(state, memory, op, true);
|
||||||
|
break;
|
||||||
|
case A32OpCodeBReg op:
|
||||||
|
Blx_Reg(state, memory, op);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Blx(CpuThreadState state, MemoryManager memory, OpCode64 opCode, bool x)
|
private static void Blx_Imm(CpuThreadState state, MemoryManager memory, OpCode64 opCode, bool x)
|
||||||
{
|
{
|
||||||
A32OpCodeBImmAl op = (A32OpCodeBImmAl)opCode;
|
A32OpCodeBImmAl op = (A32OpCodeBImmAl)opCode;
|
||||||
|
|
||||||
|
@ -60,11 +68,50 @@ namespace ChocolArm64.Instructions32
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void Blx_Reg(CpuThreadState state, MemoryManager memory, OpCode64 opCode)
|
||||||
|
{
|
||||||
|
A32OpCodeBReg op = (A32OpCodeBReg)opCode;
|
||||||
|
if (IsConditionTrue(state, op.Cond))
|
||||||
|
{
|
||||||
|
uint pc = GetPc(state);
|
||||||
|
if (state.Thumb)
|
||||||
|
{
|
||||||
|
state.R14 = (pc - 2U) | 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
state.R14 = pc - 4U;
|
||||||
|
}
|
||||||
|
BXWritePC(state, GetReg(state, op.Rm));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static void BranchWritePc(CpuThreadState state, uint pc)
|
private static void BranchWritePc(CpuThreadState state, uint pc)
|
||||||
{
|
{
|
||||||
state.R15 = state.Thumb
|
state.R15 = state.Thumb
|
||||||
? pc & ~1U
|
? pc & ~1U
|
||||||
: pc & ~3U;
|
: pc & ~3U;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void BXWritePC(CpuThreadState state, uint pc)
|
||||||
|
{
|
||||||
|
if ((pc & 1U) == 1)
|
||||||
|
{
|
||||||
|
state.Thumb = true;
|
||||||
|
state.R15 = pc & ~1U;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
state.Thumb = false;
|
||||||
|
// For branches to an unaligned PC counter in A32 state, the processor takes the branch
|
||||||
|
// and does one of:
|
||||||
|
// * Forces the address to be aligned
|
||||||
|
// * Leaves the PC unaligned, meaning the target generates a PC Alignment fault.
|
||||||
|
if ((pc & 2U) == 2 /*&& ConstrainUnpredictableBool()*/)
|
||||||
|
{
|
||||||
|
state.R15 = pc & ~2U;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -17,6 +17,7 @@ namespace ChocolArm64
|
||||||
SetA32("<<<<1010xxxxxxxxxxxxxxxxxxxxxxxx", A32InstInterpret.B, typeof(A32OpCodeBImmAl));
|
SetA32("<<<<1010xxxxxxxxxxxxxxxxxxxxxxxx", A32InstInterpret.B, typeof(A32OpCodeBImmAl));
|
||||||
SetA32("<<<<1011xxxxxxxxxxxxxxxxxxxxxxxx", A32InstInterpret.Bl, typeof(A32OpCodeBImmAl));
|
SetA32("<<<<1011xxxxxxxxxxxxxxxxxxxxxxxx", A32InstInterpret.Bl, typeof(A32OpCodeBImmAl));
|
||||||
SetA32("1111101xxxxxxxxxxxxxxxxxxxxxxxxx", A32InstInterpret.Blx, typeof(A32OpCodeBImmAl));
|
SetA32("1111101xxxxxxxxxxxxxxxxxxxxxxxxx", A32InstInterpret.Blx, typeof(A32OpCodeBImmAl));
|
||||||
|
SetA32("<<<<000100101111111111110011xxxx", A32InstInterpret.Blx, typeof(A32OpCodeBReg));
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region "OpCode Table (AArch64)"
|
#region "OpCode Table (AArch64)"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue