Adding BLX_REG
This commit is contained in:
parent
241b46540d
commit
584148de0a
3 changed files with 68 additions and 3 deletions
|
@ -17,6 +17,7 @@ namespace ChocolArm64
|
|||
SetA32("<<<<1010xxxxxxxxxxxxxxxxxxxxxxxx", A32InstInterpret.B, typeof(A32OpCodeBImmAl));
|
||||
SetA32("<<<<1011xxxxxxxxxxxxxxxxxxxxxxxx", A32InstInterpret.Bl, typeof(A32OpCodeBImmAl));
|
||||
SetA32("1111101xxxxxxxxxxxxxxxxxxxxxxxxx", A32InstInterpret.Blx, typeof(A32OpCodeBImmAl));
|
||||
SetA32("<<<<000100101111111111110011xxxx", A32InstInterpret.Blx, typeof(A32OpCodeBReg));
|
||||
#endregion
|
||||
|
||||
#region "OpCode Table (AArch64)"
|
||||
|
|
14
ChocolArm64/Decoder32/A32OpCodeBReg.cs
Normal file
14
ChocolArm64/Decoder32/A32OpCodeBReg.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
using ChocolArm64.Instruction;
|
||||
|
||||
namespace ChocolArm64.Decoder32
|
||||
{
|
||||
class A32OpCodeBReg : A32OpCode
|
||||
{
|
||||
public int Rm { get; private set; }
|
||||
|
||||
public A32OpCodeBReg(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
|
||||
{
|
||||
Rm = (OpCode >> 0) & 0xf;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -21,15 +21,23 @@ namespace ChocolArm64.Instruction32
|
|||
|
||||
public static void Bl(AThreadState State, AMemory Memory, AOpCode OpCode)
|
||||
{
|
||||
Blx(State, Memory, OpCode, false);
|
||||
Blx_Imm(State, Memory, OpCode, false);
|
||||
}
|
||||
|
||||
public static void Blx(AThreadState State, AMemory Memory, AOpCode 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(AThreadState State, AMemory Memory, AOpCode OpCode, bool X)
|
||||
private static void Blx_Imm(AThreadState State, AMemory Memory, AOpCode OpCode, bool X)
|
||||
{
|
||||
A32OpCodeBImmAl Op = (A32OpCodeBImmAl)OpCode;
|
||||
|
||||
|
@ -60,11 +68,53 @@ namespace ChocolArm64.Instruction32
|
|||
}
|
||||
}
|
||||
|
||||
private static void Blx_Reg(AThreadState State, AMemory Memory, AOpCode 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(AThreadState State, uint Pc)
|
||||
{
|
||||
State.R15 = State.Thumb
|
||||
? Pc & ~1U
|
||||
: Pc & ~3U;
|
||||
}
|
||||
|
||||
private static void BXWritePC(AThreadState 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue