Split main project into core,graphics and chocolarm4 subproject (#29)
This commit is contained in:
parent
cb665bb715
commit
62b827f474
257 changed files with 415 additions and 285 deletions
35
ChocolArm64/Decoder/ABlock.cs
Normal file
35
ChocolArm64/Decoder/ABlock.cs
Normal file
|
@ -0,0 +1,35 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
class ABlock
|
||||
{
|
||||
public long Position { get; set; }
|
||||
public long EndPosition { get; set; }
|
||||
|
||||
public ABlock Next { get; set; }
|
||||
public ABlock Branch { get; set; }
|
||||
|
||||
public List<AOpCode> OpCodes { get; private set; }
|
||||
|
||||
public ABlock()
|
||||
{
|
||||
OpCodes = new List<AOpCode>();
|
||||
}
|
||||
|
||||
public ABlock(long Position) : this()
|
||||
{
|
||||
this.Position = Position;
|
||||
}
|
||||
|
||||
public AOpCode GetLastOp()
|
||||
{
|
||||
if (OpCodes.Count > 0)
|
||||
{
|
||||
return OpCodes[OpCodes.Count - 1];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
22
ChocolArm64/Decoder/ACond.cs
Normal file
22
ChocolArm64/Decoder/ACond.cs
Normal file
|
@ -0,0 +1,22 @@
|
|||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
enum ACond
|
||||
{
|
||||
Eq = 0,
|
||||
Ne = 1,
|
||||
Ge_Un = 2,
|
||||
Lt_Un = 3,
|
||||
Mi = 4,
|
||||
Pl = 5,
|
||||
Vs = 6,
|
||||
Vc = 7,
|
||||
Gt_Un = 8,
|
||||
Le_Un = 9,
|
||||
Ge = 10,
|
||||
Lt = 11,
|
||||
Gt = 12,
|
||||
Le = 13,
|
||||
Al = 14,
|
||||
Nv = 15
|
||||
}
|
||||
}
|
10
ChocolArm64/Decoder/ADataOp.cs
Normal file
10
ChocolArm64/Decoder/ADataOp.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
enum ADataOp
|
||||
{
|
||||
Adr = 0,
|
||||
Arithmetic = 1,
|
||||
Logical = 2,
|
||||
BitField = 3
|
||||
}
|
||||
}
|
207
ChocolArm64/Decoder/ADecoder.cs
Normal file
207
ChocolArm64/Decoder/ADecoder.cs
Normal file
|
@ -0,0 +1,207 @@
|
|||
using ChocolArm64.Instruction;
|
||||
using ChocolArm64.Memory;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection.Emit;
|
||||
|
||||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
static class ADecoder
|
||||
{
|
||||
public static (ABlock[] Graph, ABlock Root) DecodeSubroutine(ATranslator Translator, long Start)
|
||||
{
|
||||
Dictionary<long, ABlock> Visited = new Dictionary<long, ABlock>();
|
||||
Dictionary<long, ABlock> VisitedEnd = new Dictionary<long, ABlock>();
|
||||
|
||||
Queue<ABlock> Blocks = new Queue<ABlock>();
|
||||
|
||||
ABlock Enqueue(long Position)
|
||||
{
|
||||
if (!Visited.TryGetValue(Position, out ABlock Output))
|
||||
{
|
||||
Output = new ABlock(Position);
|
||||
|
||||
Blocks.Enqueue(Output);
|
||||
|
||||
Visited.Add(Position, Output);
|
||||
}
|
||||
|
||||
return Output;
|
||||
}
|
||||
|
||||
ABlock Root = Enqueue(Start);
|
||||
|
||||
while (Blocks.Count > 0)
|
||||
{
|
||||
ABlock Current = Blocks.Dequeue();
|
||||
|
||||
FillBlock(Translator.Thread.Memory, Current);
|
||||
|
||||
//Set child blocks. "Branch" is the block the branch instruction
|
||||
//points to (when taken), "Next" is the block at the next address,
|
||||
//executed when the branch is not taken. For Unconditional Branches
|
||||
//(except BL/BLR that are sub calls) or end of executable, Next is null.
|
||||
if (Current.OpCodes.Count > 0)
|
||||
{
|
||||
bool HasCachedSub = false;
|
||||
|
||||
AOpCode LastOp = Current.GetLastOp();
|
||||
|
||||
if (LastOp is AOpCodeBImm Op)
|
||||
{
|
||||
if (Op.Emitter == AInstEmit.Bl)
|
||||
{
|
||||
HasCachedSub = Translator.HasCachedSub(Op.Imm);
|
||||
}
|
||||
else
|
||||
{
|
||||
Current.Branch = Enqueue(Op.Imm);
|
||||
}
|
||||
}
|
||||
|
||||
if ((!(LastOp is AOpCodeBImmAl) &&
|
||||
!(LastOp is AOpCodeBReg)) || HasCachedSub)
|
||||
{
|
||||
Current.Next = Enqueue(Current.EndPosition);
|
||||
}
|
||||
}
|
||||
|
||||
//If we have on the tree two blocks with the same end position,
|
||||
//then we need to split the bigger block and have two small blocks,
|
||||
//the end position of the bigger "Current" block should then be == to
|
||||
//the position of the "Smaller" block.
|
||||
while (VisitedEnd.TryGetValue(Current.EndPosition, out ABlock Smaller))
|
||||
{
|
||||
if (Current.Position > Smaller.Position)
|
||||
{
|
||||
ABlock Temp = Smaller;
|
||||
|
||||
Smaller = Current;
|
||||
Current = Temp;
|
||||
}
|
||||
|
||||
Current.EndPosition = Smaller.Position;
|
||||
Current.Next = Smaller;
|
||||
Current.Branch = null;
|
||||
|
||||
Current.OpCodes.RemoveRange(
|
||||
Current.OpCodes.Count - Smaller.OpCodes.Count,
|
||||
Smaller.OpCodes.Count);
|
||||
|
||||
VisitedEnd[Smaller.EndPosition] = Smaller;
|
||||
}
|
||||
|
||||
VisitedEnd.Add(Current.EndPosition, Current);
|
||||
}
|
||||
|
||||
//Make and sort Graph blocks array by position.
|
||||
ABlock[] Graph = new ABlock[Visited.Count];
|
||||
|
||||
while (Visited.Count > 0)
|
||||
{
|
||||
ulong FirstPos = ulong.MaxValue;
|
||||
|
||||
foreach (ABlock Block in Visited.Values)
|
||||
{
|
||||
if (FirstPos > (ulong)Block.Position)
|
||||
FirstPos = (ulong)Block.Position;
|
||||
}
|
||||
|
||||
ABlock Current = Visited[(long)FirstPos];
|
||||
|
||||
do
|
||||
{
|
||||
Graph[Graph.Length - Visited.Count] = Current;
|
||||
|
||||
Visited.Remove(Current.Position);
|
||||
|
||||
Current = Current.Next;
|
||||
}
|
||||
while (Current != null);
|
||||
}
|
||||
|
||||
return (Graph, Root);
|
||||
}
|
||||
|
||||
private static void FillBlock(AMemory Memory, ABlock Block)
|
||||
{
|
||||
long Position = Block.Position;
|
||||
|
||||
AOpCode OpCode;
|
||||
|
||||
do
|
||||
{
|
||||
OpCode = DecodeOpCode(Memory, Position);
|
||||
|
||||
Block.OpCodes.Add(OpCode);
|
||||
|
||||
Position += 4;
|
||||
}
|
||||
while (!(IsBranch(OpCode) || IsException(OpCode)));
|
||||
|
||||
Block.EndPosition = Position;
|
||||
}
|
||||
|
||||
private static bool IsBranch(AOpCode OpCode)
|
||||
{
|
||||
return OpCode is AOpCodeBImm ||
|
||||
OpCode is AOpCodeBReg;
|
||||
}
|
||||
|
||||
private static bool IsException(AOpCode OpCode)
|
||||
{
|
||||
return OpCode.Emitter == AInstEmit.Brk ||
|
||||
OpCode.Emitter == AInstEmit.Svc ||
|
||||
OpCode.Emitter == AInstEmit.Und;
|
||||
}
|
||||
|
||||
public static AOpCode DecodeOpCode(AMemory Memory, long Position)
|
||||
{
|
||||
int OpCode = Memory.ReadInt32(Position);
|
||||
|
||||
AInst Inst = AOpCodeTable.GetInst(OpCode);
|
||||
|
||||
AOpCode DecodedOpCode = new AOpCode(AInst.Undefined, Position, OpCode);
|
||||
|
||||
if (Inst.Type != null)
|
||||
{
|
||||
DecodedOpCode = CreateOpCode(Inst.Type, Inst, Position, OpCode);
|
||||
}
|
||||
|
||||
return DecodedOpCode;
|
||||
}
|
||||
|
||||
private delegate object OpActivator(AInst Inst, long Position, int OpCode);
|
||||
|
||||
private static Dictionary<Type, OpActivator> Activators = new Dictionary<Type, OpActivator>();
|
||||
|
||||
private static AOpCode CreateOpCode(Type Type, AInst Inst, long Position, int OpCode)
|
||||
{
|
||||
if (Type == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(Type));
|
||||
}
|
||||
|
||||
if (!Activators.TryGetValue(Type, out OpActivator CreateInstance))
|
||||
{
|
||||
Type[] ArgTypes = new Type[] { typeof(AInst), typeof(long), typeof(int) };
|
||||
|
||||
DynamicMethod Mthd = new DynamicMethod($"{Type.Name}_Create", Type, ArgTypes);
|
||||
|
||||
ILGenerator Generator = Mthd.GetILGenerator();
|
||||
|
||||
Generator.Emit(OpCodes.Ldarg_0);
|
||||
Generator.Emit(OpCodes.Ldarg_1);
|
||||
Generator.Emit(OpCodes.Ldarg_2);
|
||||
Generator.Emit(OpCodes.Newobj, Type.GetConstructor(ArgTypes));
|
||||
Generator.Emit(OpCodes.Ret);
|
||||
|
||||
CreateInstance = (OpActivator)Mthd.CreateDelegate(typeof(OpActivator));
|
||||
|
||||
Activators.Add(Type, CreateInstance);
|
||||
}
|
||||
|
||||
return (AOpCode)CreateInstance(Inst, Position, OpCode);
|
||||
}
|
||||
}
|
||||
}
|
107
ChocolArm64/Decoder/ADecoderHelper.cs
Normal file
107
ChocolArm64/Decoder/ADecoderHelper.cs
Normal file
|
@ -0,0 +1,107 @@
|
|||
using System;
|
||||
|
||||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
static class ADecoderHelper
|
||||
{
|
||||
public struct BitMask
|
||||
{
|
||||
public long WMask;
|
||||
public long TMask;
|
||||
public int Pos;
|
||||
public int Shift;
|
||||
public bool IsUndefined;
|
||||
|
||||
public static BitMask Invalid => new BitMask { IsUndefined = true };
|
||||
}
|
||||
|
||||
public static BitMask DecodeBitMask(int OpCode, bool Immediate)
|
||||
{
|
||||
int ImmS = (OpCode >> 10) & 0x3f;
|
||||
int ImmR = (OpCode >> 16) & 0x3f;
|
||||
|
||||
int N = (OpCode >> 22) & 1;
|
||||
int SF = (OpCode >> 31) & 1;
|
||||
|
||||
int Length = ABitUtils.HighestBitSet32((~ImmS & 0x3f) | (N << 6));
|
||||
|
||||
if (Length < 1 || (SF == 0 && N != 0))
|
||||
{
|
||||
return BitMask.Invalid;
|
||||
}
|
||||
|
||||
int Size = 1 << Length;
|
||||
|
||||
int Levels = Size - 1;
|
||||
|
||||
int S = ImmS & Levels;
|
||||
int R = ImmR & Levels;
|
||||
|
||||
if (Immediate && S == Levels)
|
||||
{
|
||||
return BitMask.Invalid;
|
||||
}
|
||||
|
||||
long WMask = ABitUtils.FillWithOnes(S + 1);
|
||||
long TMask = ABitUtils.FillWithOnes(((S - R) & Levels) + 1);
|
||||
|
||||
if (R > 0)
|
||||
{
|
||||
WMask = ABitUtils.RotateRight(WMask, R, Size);
|
||||
WMask &= ABitUtils.FillWithOnes(Size);
|
||||
}
|
||||
|
||||
return new BitMask()
|
||||
{
|
||||
WMask = ABitUtils.Replicate(WMask, Size),
|
||||
TMask = ABitUtils.Replicate(TMask, Size),
|
||||
|
||||
Pos = ImmS,
|
||||
Shift = ImmR
|
||||
};
|
||||
}
|
||||
|
||||
public static long DecodeImm8Float(long Imm, int Size)
|
||||
{
|
||||
int E = 0, F = 0;
|
||||
|
||||
switch (Size)
|
||||
{
|
||||
case 0: E = 8; F = 23; break;
|
||||
case 1: E = 11; F = 52; break;
|
||||
|
||||
default: throw new ArgumentOutOfRangeException(nameof(Size));
|
||||
}
|
||||
|
||||
long Value = (Imm & 0x3f) << F - 4;
|
||||
|
||||
long EBit = (Imm >> 6) & 1;
|
||||
long SBit = (Imm >> 7) & 1;
|
||||
|
||||
if (EBit != 0)
|
||||
{
|
||||
Value |= (1L << E - 3) - 1 << F + 2;
|
||||
}
|
||||
|
||||
Value |= (EBit ^ 1) << F + E - 1;
|
||||
Value |= SBit << F + E;
|
||||
|
||||
return Value;
|
||||
}
|
||||
|
||||
public static long DecodeImm26_2(int OpCode)
|
||||
{
|
||||
return ((long)OpCode << 38) >> 36;
|
||||
}
|
||||
|
||||
public static long DecodeImmS19_2(int OpCode)
|
||||
{
|
||||
return (((long)OpCode << 40) >> 43) & ~3;
|
||||
}
|
||||
|
||||
public static long DecodeImmS14_2(int OpCode)
|
||||
{
|
||||
return (((long)OpCode << 45) >> 48) & ~3;
|
||||
}
|
||||
}
|
||||
}
|
14
ChocolArm64/Decoder/AIntType.cs
Normal file
14
ChocolArm64/Decoder/AIntType.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
enum AIntType
|
||||
{
|
||||
UInt8 = 0,
|
||||
UInt16 = 1,
|
||||
UInt32 = 2,
|
||||
UInt64 = 3,
|
||||
Int8 = 4,
|
||||
Int16 = 5,
|
||||
Int32 = 6,
|
||||
Int64 = 7
|
||||
}
|
||||
}
|
38
ChocolArm64/Decoder/AOpCode.cs
Normal file
38
ChocolArm64/Decoder/AOpCode.cs
Normal file
|
@ -0,0 +1,38 @@
|
|||
using ChocolArm64.Instruction;
|
||||
using ChocolArm64.State;
|
||||
using System;
|
||||
|
||||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
class AOpCode : IAOpCode
|
||||
{
|
||||
public long Position { get; private set; }
|
||||
public int RawOpCode { get; private set; }
|
||||
|
||||
public AInstEmitter Emitter { get; protected set; }
|
||||
public ARegisterSize RegisterSize { get; protected set; }
|
||||
|
||||
public AOpCode(AInst Inst, long Position, int OpCode)
|
||||
{
|
||||
this.Position = Position;
|
||||
this.RawOpCode = OpCode;
|
||||
|
||||
RegisterSize = ARegisterSize.Int64;
|
||||
|
||||
Emitter = Inst.Emitter;
|
||||
}
|
||||
|
||||
public int GetBitsCount()
|
||||
{
|
||||
switch (RegisterSize)
|
||||
{
|
||||
case ARegisterSize.Int32: return 32;
|
||||
case ARegisterSize.Int64: return 64;
|
||||
case ARegisterSize.SIMD64: return 64;
|
||||
case ARegisterSize.SIMD128: return 128;
|
||||
}
|
||||
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
}
|
||||
}
|
18
ChocolArm64/Decoder/AOpCodeAdr.cs
Normal file
18
ChocolArm64/Decoder/AOpCodeAdr.cs
Normal file
|
@ -0,0 +1,18 @@
|
|||
using ChocolArm64.Instruction;
|
||||
|
||||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
class AOpCodeAdr : AOpCode
|
||||
{
|
||||
public int Rd { get; private set; }
|
||||
public long Imm { get; private set; }
|
||||
|
||||
public AOpCodeAdr(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
|
||||
{
|
||||
Rd = OpCode & 0x1f;
|
||||
|
||||
Imm = ADecoderHelper.DecodeImmS19_2(OpCode);
|
||||
Imm |= ((long)OpCode >> 29) & 3;
|
||||
}
|
||||
}
|
||||
}
|
24
ChocolArm64/Decoder/AOpCodeAlu.cs
Normal file
24
ChocolArm64/Decoder/AOpCodeAlu.cs
Normal file
|
@ -0,0 +1,24 @@
|
|||
using ChocolArm64.Instruction;
|
||||
using ChocolArm64.State;
|
||||
|
||||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
class AOpCodeAlu : AOpCode, IAOpCodeAlu
|
||||
{
|
||||
public int Rd { get; protected set; }
|
||||
public int Rn { get; private set; }
|
||||
|
||||
public ADataOp DataOp { get; private set; }
|
||||
|
||||
public AOpCodeAlu(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
|
||||
{
|
||||
Rd = (OpCode >> 0) & 0x1f;
|
||||
Rn = (OpCode >> 5) & 0x1f;
|
||||
DataOp = (ADataOp)((OpCode >> 24) & 0x3);
|
||||
|
||||
RegisterSize = (OpCode >> 31) != 0
|
||||
? ARegisterSize.Int64
|
||||
: ARegisterSize.Int32;
|
||||
}
|
||||
}
|
||||
}
|
39
ChocolArm64/Decoder/AOpCodeAluImm.cs
Normal file
39
ChocolArm64/Decoder/AOpCodeAluImm.cs
Normal file
|
@ -0,0 +1,39 @@
|
|||
using ChocolArm64.Instruction;
|
||||
using System;
|
||||
|
||||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
class AOpCodeAluImm : AOpCodeAlu, IAOpCodeAluImm
|
||||
{
|
||||
public long Imm { get; private set; }
|
||||
|
||||
public AOpCodeAluImm(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
|
||||
{
|
||||
if (DataOp == ADataOp.Arithmetic)
|
||||
{
|
||||
Imm = (OpCode >> 10) & 0xfff;
|
||||
|
||||
int Shift = (OpCode >> 22) & 3;
|
||||
|
||||
Imm <<= Shift * 12;
|
||||
}
|
||||
else if (DataOp == ADataOp.Logical)
|
||||
{
|
||||
var BM = ADecoderHelper.DecodeBitMask(OpCode, true);
|
||||
|
||||
if (BM.IsUndefined)
|
||||
{
|
||||
Emitter = AInstEmit.Und;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Imm = BM.WMask;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ArgumentException(nameof(OpCode));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
29
ChocolArm64/Decoder/AOpCodeAluRs.cs
Normal file
29
ChocolArm64/Decoder/AOpCodeAluRs.cs
Normal file
|
@ -0,0 +1,29 @@
|
|||
using ChocolArm64.Instruction;
|
||||
|
||||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
class AOpCodeAluRs : AOpCodeAlu, IAOpCodeAluRs
|
||||
{
|
||||
public int Shift { get; private set; }
|
||||
public int Rm { get; private set; }
|
||||
|
||||
public AShiftType ShiftType { get; private set; }
|
||||
|
||||
public AOpCodeAluRs(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
|
||||
{
|
||||
int Shift = (OpCode >> 10) & 0x3f;
|
||||
|
||||
if (Shift >= GetBitsCount())
|
||||
{
|
||||
Emitter = AInstEmit.Und;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.Shift = Shift;
|
||||
|
||||
Rm = (OpCode >> 16) & 0x1f;
|
||||
ShiftType = (AShiftType)((OpCode >> 22) & 0x3);
|
||||
}
|
||||
}
|
||||
}
|
19
ChocolArm64/Decoder/AOpCodeAluRx.cs
Normal file
19
ChocolArm64/Decoder/AOpCodeAluRx.cs
Normal file
|
@ -0,0 +1,19 @@
|
|||
using ChocolArm64.Instruction;
|
||||
|
||||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
class AOpCodeAluRx : AOpCodeAlu, IAOpCodeAluRx
|
||||
{
|
||||
public int Shift { get; private set; }
|
||||
public int Rm { get; private set; }
|
||||
|
||||
public AIntType IntType { get; private set; }
|
||||
|
||||
public AOpCodeAluRx(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
|
||||
{
|
||||
Shift = (OpCode >> 10) & 0x7;
|
||||
IntType = (AIntType)((OpCode >> 13) & 0x7);
|
||||
Rm = (OpCode >> 16) & 0x1f;
|
||||
}
|
||||
}
|
||||
}
|
11
ChocolArm64/Decoder/AOpCodeBImm.cs
Normal file
11
ChocolArm64/Decoder/AOpCodeBImm.cs
Normal file
|
@ -0,0 +1,11 @@
|
|||
using ChocolArm64.Instruction;
|
||||
|
||||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
class AOpCodeBImm : AOpCode
|
||||
{
|
||||
public long Imm { get; protected set; }
|
||||
|
||||
public AOpCodeBImm(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode) { }
|
||||
}
|
||||
}
|
12
ChocolArm64/Decoder/AOpCodeBImmAl.cs
Normal file
12
ChocolArm64/Decoder/AOpCodeBImmAl.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
using ChocolArm64.Instruction;
|
||||
|
||||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
class AOpCodeBImmAl : AOpCodeBImm
|
||||
{
|
||||
public AOpCodeBImmAl(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
|
||||
{
|
||||
Imm = Position + ADecoderHelper.DecodeImm26_2(OpCode);
|
||||
}
|
||||
}
|
||||
}
|
16
ChocolArm64/Decoder/AOpCodeBImmCmp.cs
Normal file
16
ChocolArm64/Decoder/AOpCodeBImmCmp.cs
Normal file
|
@ -0,0 +1,16 @@
|
|||
using ChocolArm64.Instruction;
|
||||
|
||||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
class AOpCodeBImmCmp : AOpCodeBImm
|
||||
{
|
||||
public int Rt { get; private set; }
|
||||
|
||||
public AOpCodeBImmCmp(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
|
||||
{
|
||||
Rt = OpCode & 0x1f;
|
||||
|
||||
Imm = Position + ADecoderHelper.DecodeImmS19_2(OpCode);
|
||||
}
|
||||
}
|
||||
}
|
25
ChocolArm64/Decoder/AOpCodeBImmCond.cs
Normal file
25
ChocolArm64/Decoder/AOpCodeBImmCond.cs
Normal file
|
@ -0,0 +1,25 @@
|
|||
using ChocolArm64.Instruction;
|
||||
|
||||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
class AOpCodeBImmCond : AOpCodeBImm, IAOpCodeCond
|
||||
{
|
||||
public ACond Cond { get; private set; }
|
||||
|
||||
public AOpCodeBImmCond(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
|
||||
{
|
||||
int O0 = (OpCode >> 4) & 1;
|
||||
|
||||
if (O0 != 0)
|
||||
{
|
||||
Emitter = AInstEmit.Und;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Cond = (ACond)(OpCode & 0xf);
|
||||
|
||||
Imm = Position + ADecoderHelper.DecodeImmS19_2(OpCode);
|
||||
}
|
||||
}
|
||||
}
|
20
ChocolArm64/Decoder/AOpCodeBImmTest.cs
Normal file
20
ChocolArm64/Decoder/AOpCodeBImmTest.cs
Normal file
|
@ -0,0 +1,20 @@
|
|||
using ChocolArm64.Instruction;
|
||||
|
||||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
class AOpCodeBImmTest : AOpCodeBImm
|
||||
{
|
||||
public int Rt { get; private set; }
|
||||
public int Pos { get; private set; }
|
||||
|
||||
public AOpCodeBImmTest(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
|
||||
{
|
||||
Rt = OpCode & 0x1f;
|
||||
|
||||
Imm = Position + ADecoderHelper.DecodeImmS14_2(OpCode);
|
||||
|
||||
Pos = (OpCode >> 19) & 0x1f;
|
||||
Pos |= (OpCode >> 26) & 0x20;
|
||||
}
|
||||
}
|
||||
}
|
24
ChocolArm64/Decoder/AOpCodeBReg.cs
Normal file
24
ChocolArm64/Decoder/AOpCodeBReg.cs
Normal file
|
@ -0,0 +1,24 @@
|
|||
using ChocolArm64.Instruction;
|
||||
|
||||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
class AOpCodeBReg : AOpCode
|
||||
{
|
||||
public int Rn { get; private set; }
|
||||
|
||||
public AOpCodeBReg(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
|
||||
{
|
||||
int Op4 = (OpCode >> 0) & 0x1f;
|
||||
int Op2 = (OpCode >> 16) & 0x1f;
|
||||
|
||||
if (Op2 != 0b11111 || Op4 != 0b00000)
|
||||
{
|
||||
Emitter = AInstEmit.Und;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Rn = (OpCode >> 5) & 0x1f;
|
||||
}
|
||||
}
|
||||
}
|
29
ChocolArm64/Decoder/AOpCodeBfm.cs
Normal file
29
ChocolArm64/Decoder/AOpCodeBfm.cs
Normal file
|
@ -0,0 +1,29 @@
|
|||
using ChocolArm64.Instruction;
|
||||
|
||||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
class AOpCodeBfm : AOpCodeAlu
|
||||
{
|
||||
public long WMask { get; private set; }
|
||||
public long TMask { get; private set; }
|
||||
public int Pos { get; private set; }
|
||||
public int Shift { get; private set; }
|
||||
|
||||
public AOpCodeBfm(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
|
||||
{
|
||||
var BM = ADecoderHelper.DecodeBitMask(OpCode, false);
|
||||
|
||||
if (BM.IsUndefined)
|
||||
{
|
||||
Emitter = AInstEmit.Und;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
WMask = BM.WMask;
|
||||
TMask = BM.TMask;
|
||||
Pos = BM.Pos;
|
||||
Shift = BM.Shift;
|
||||
}
|
||||
}
|
||||
}
|
31
ChocolArm64/Decoder/AOpCodeCcmp.cs
Normal file
31
ChocolArm64/Decoder/AOpCodeCcmp.cs
Normal file
|
@ -0,0 +1,31 @@
|
|||
using ChocolArm64.Instruction;
|
||||
using ChocolArm64.State;
|
||||
|
||||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
class AOpCodeCcmp : AOpCodeAlu, IAOpCodeCond
|
||||
{
|
||||
public int NZCV { get; private set; }
|
||||
protected int RmImm;
|
||||
|
||||
public ACond Cond { get; private set; }
|
||||
|
||||
public AOpCodeCcmp(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
|
||||
{
|
||||
int O3 = (OpCode >> 4) & 1;
|
||||
|
||||
if (O3 != 0)
|
||||
{
|
||||
Emitter = AInstEmit.Und;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
NZCV = (OpCode >> 0) & 0xf;
|
||||
Cond = (ACond)((OpCode >> 12) & 0xf);
|
||||
RmImm = (OpCode >> 16) & 0x1f;
|
||||
|
||||
Rd = AThreadState.ZRIndex;
|
||||
}
|
||||
}
|
||||
}
|
11
ChocolArm64/Decoder/AOpCodeCcmpImm.cs
Normal file
11
ChocolArm64/Decoder/AOpCodeCcmpImm.cs
Normal file
|
@ -0,0 +1,11 @@
|
|||
using ChocolArm64.Instruction;
|
||||
|
||||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
class AOpCodeCcmpImm : AOpCodeCcmp, IAOpCodeAluImm
|
||||
{
|
||||
public long Imm => RmImm;
|
||||
|
||||
public AOpCodeCcmpImm(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode) { }
|
||||
}
|
||||
}
|
15
ChocolArm64/Decoder/AOpCodeCcmpReg.cs
Normal file
15
ChocolArm64/Decoder/AOpCodeCcmpReg.cs
Normal file
|
@ -0,0 +1,15 @@
|
|||
using ChocolArm64.Instruction;
|
||||
|
||||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
class AOpCodeCcmpReg : AOpCodeCcmp, IAOpCodeAluRs
|
||||
{
|
||||
public int Rm => RmImm;
|
||||
|
||||
public int Shift => 0;
|
||||
|
||||
public AShiftType ShiftType => AShiftType.Lsl;
|
||||
|
||||
public AOpCodeCcmpReg(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode) { }
|
||||
}
|
||||
}
|
17
ChocolArm64/Decoder/AOpCodeCsel.cs
Normal file
17
ChocolArm64/Decoder/AOpCodeCsel.cs
Normal file
|
@ -0,0 +1,17 @@
|
|||
using ChocolArm64.Instruction;
|
||||
|
||||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
class AOpCodeCsel : AOpCodeAlu, IAOpCodeCond
|
||||
{
|
||||
public int Rm { get; private set; }
|
||||
|
||||
public ACond Cond { get; private set; }
|
||||
|
||||
public AOpCodeCsel(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
|
||||
{
|
||||
Rm = (OpCode >> 16) & 0x1f;
|
||||
Cond = (ACond)((OpCode >> 12) & 0xf);
|
||||
}
|
||||
}
|
||||
}
|
14
ChocolArm64/Decoder/AOpCodeException.cs
Normal file
14
ChocolArm64/Decoder/AOpCodeException.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
using ChocolArm64.Instruction;
|
||||
|
||||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
class AOpCodeException : AOpCode
|
||||
{
|
||||
public int Id { get; private set; }
|
||||
|
||||
public AOpCodeException(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
|
||||
{
|
||||
Id = (OpCode >> 5) & 0xffff;
|
||||
}
|
||||
}
|
||||
}
|
19
ChocolArm64/Decoder/AOpCodeMem.cs
Normal file
19
ChocolArm64/Decoder/AOpCodeMem.cs
Normal file
|
@ -0,0 +1,19 @@
|
|||
using ChocolArm64.Instruction;
|
||||
|
||||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
class AOpCodeMem : AOpCode
|
||||
{
|
||||
public int Rt { get; protected set; }
|
||||
public int Rn { get; protected set; }
|
||||
public int Size { get; protected set; }
|
||||
public bool Extend64 { get; protected set; }
|
||||
|
||||
public AOpCodeMem(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
|
||||
{
|
||||
Rt = (OpCode >> 0) & 0x1f;
|
||||
Rn = (OpCode >> 5) & 0x1f;
|
||||
Size = (OpCode >> 30) & 0x3;
|
||||
}
|
||||
}
|
||||
}
|
16
ChocolArm64/Decoder/AOpCodeMemEx.cs
Normal file
16
ChocolArm64/Decoder/AOpCodeMemEx.cs
Normal file
|
@ -0,0 +1,16 @@
|
|||
using ChocolArm64.Instruction;
|
||||
|
||||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
class AOpCodeMemEx : AOpCodeMem
|
||||
{
|
||||
public int Rt2 { get; private set; }
|
||||
public int Rs { get; private set; }
|
||||
|
||||
public AOpCodeMemEx(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
|
||||
{
|
||||
Rt2 = (OpCode >> 10) & 0x1f;
|
||||
Rs = (OpCode >> 16) & 0x1f;
|
||||
}
|
||||
}
|
||||
}
|
53
ChocolArm64/Decoder/AOpCodeMemImm.cs
Normal file
53
ChocolArm64/Decoder/AOpCodeMemImm.cs
Normal file
|
@ -0,0 +1,53 @@
|
|||
using ChocolArm64.Instruction;
|
||||
|
||||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
class AOpCodeMemImm : AOpCodeMem
|
||||
{
|
||||
public long Imm { get; protected set; }
|
||||
public bool WBack { get; protected set; }
|
||||
public bool PostIdx { get; protected set; }
|
||||
protected bool Unscaled { get; private set; }
|
||||
|
||||
private enum MemOp
|
||||
{
|
||||
Unscaled = 0,
|
||||
PostIndexed = 1,
|
||||
Unprivileged = 2,
|
||||
PreIndexed = 3,
|
||||
Unsigned
|
||||
}
|
||||
|
||||
public AOpCodeMemImm(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
|
||||
{
|
||||
Extend64 = ((OpCode >> 22) & 3) == 2;
|
||||
WBack = ((OpCode >> 24) & 1) == 0;
|
||||
|
||||
//The type is not valid for the Unsigned Immediate 12-bits encoding,
|
||||
//because the bits 11:10 are used for the larger Immediate offset.
|
||||
MemOp Type = WBack ? (MemOp)((OpCode >> 10) & 3) : MemOp.Unsigned;
|
||||
|
||||
PostIdx = Type == MemOp.PostIndexed;
|
||||
Unscaled = Type == MemOp.Unscaled ||
|
||||
Type == MemOp.Unprivileged;
|
||||
|
||||
//Unscaled and Unprivileged doesn't write back,
|
||||
//but they do use the 9-bits Signed Immediate.
|
||||
if (Unscaled)
|
||||
{
|
||||
WBack = false;
|
||||
}
|
||||
|
||||
if (WBack || Unscaled)
|
||||
{
|
||||
//9-bits Signed Immediate.
|
||||
Imm = (OpCode << 43) >> 55;
|
||||
}
|
||||
else
|
||||
{
|
||||
//12-bits Unsigned Immediate.
|
||||
Imm = ((OpCode >> 10) & 0xfff) << Size;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
28
ChocolArm64/Decoder/AOpCodeMemLit.cs
Normal file
28
ChocolArm64/Decoder/AOpCodeMemLit.cs
Normal file
|
@ -0,0 +1,28 @@
|
|||
using ChocolArm64.Instruction;
|
||||
|
||||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
class AOpCodeMemLit : AOpCode, IAOpCodeLit
|
||||
{
|
||||
public int Rt { get; private set; }
|
||||
public long Imm { get; private set; }
|
||||
public int Size { get; private set; }
|
||||
public bool Signed { get; private set; }
|
||||
public bool Prefetch { get; private set; }
|
||||
|
||||
public AOpCodeMemLit(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
|
||||
{
|
||||
Rt = OpCode & 0x1f;
|
||||
|
||||
Imm = Position + ADecoderHelper.DecodeImmS19_2(OpCode);
|
||||
|
||||
switch ((OpCode >> 30) & 3)
|
||||
{
|
||||
case 0: Size = 2; Signed = false; Prefetch = false; break;
|
||||
case 1: Size = 3; Signed = false; Prefetch = false; break;
|
||||
case 2: Size = 2; Signed = true; Prefetch = false; break;
|
||||
case 3: Size = 0; Signed = false; Prefetch = true; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
25
ChocolArm64/Decoder/AOpCodeMemPair.cs
Normal file
25
ChocolArm64/Decoder/AOpCodeMemPair.cs
Normal file
|
@ -0,0 +1,25 @@
|
|||
using ChocolArm64.Instruction;
|
||||
|
||||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
class AOpCodeMemPair : AOpCodeMemImm
|
||||
{
|
||||
public int Rt2 { get; private set; }
|
||||
|
||||
public AOpCodeMemPair(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
|
||||
{
|
||||
Rt2 = (OpCode >> 10) & 0x1f;
|
||||
WBack = ((OpCode >> 23) & 0x1) != 0;
|
||||
PostIdx = ((OpCode >> 23) & 0x3) == 1;
|
||||
Extend64 = ((OpCode >> 30) & 0x3) == 1;
|
||||
Size = ((OpCode >> 31) & 0x1) | 2;
|
||||
|
||||
DecodeImm(OpCode);
|
||||
}
|
||||
|
||||
protected void DecodeImm(int OpCode)
|
||||
{
|
||||
Imm = ((long)(OpCode >> 15) << 57) >> (57 - Size);
|
||||
}
|
||||
}
|
||||
}
|
20
ChocolArm64/Decoder/AOpCodeMemReg.cs
Normal file
20
ChocolArm64/Decoder/AOpCodeMemReg.cs
Normal file
|
@ -0,0 +1,20 @@
|
|||
using ChocolArm64.Instruction;
|
||||
|
||||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
class AOpCodeMemReg : AOpCodeMem
|
||||
{
|
||||
public bool Shift { get; private set; }
|
||||
public int Rm { get; private set; }
|
||||
|
||||
public AIntType IntType { get; private set; }
|
||||
|
||||
public AOpCodeMemReg(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
|
||||
{
|
||||
Shift = ((OpCode >> 12) & 0x1) != 0;
|
||||
IntType = (AIntType)((OpCode >> 13) & 0x7);
|
||||
Rm = (OpCode >> 16) & 0x1f;
|
||||
Extend64 = ((OpCode >> 22) & 0x3) == 2;
|
||||
}
|
||||
}
|
||||
}
|
36
ChocolArm64/Decoder/AOpCodeMov.cs
Normal file
36
ChocolArm64/Decoder/AOpCodeMov.cs
Normal file
|
@ -0,0 +1,36 @@
|
|||
using ChocolArm64.Instruction;
|
||||
using ChocolArm64.State;
|
||||
|
||||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
class AOpCodeMov : AOpCode
|
||||
{
|
||||
public int Rd { get; private set; }
|
||||
public long Imm { get; private set; }
|
||||
public int Pos { get; private set; }
|
||||
|
||||
public AOpCodeMov(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
|
||||
{
|
||||
int P1 = (OpCode >> 22) & 1;
|
||||
int SF = (OpCode >> 31) & 1;
|
||||
|
||||
if (SF == 0 && P1 != 0)
|
||||
{
|
||||
Emitter = AInstEmit.Und;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Rd = (OpCode >> 0) & 0x1f;
|
||||
Imm = (OpCode >> 5) & 0xffff;
|
||||
Pos = (OpCode >> 21) & 0x3;
|
||||
|
||||
Pos <<= 4;
|
||||
Imm <<= Pos;
|
||||
|
||||
RegisterSize = (OpCode >> 31) != 0
|
||||
? ARegisterSize.Int64
|
||||
: ARegisterSize.Int32;
|
||||
}
|
||||
}
|
||||
}
|
16
ChocolArm64/Decoder/AOpCodeMul.cs
Normal file
16
ChocolArm64/Decoder/AOpCodeMul.cs
Normal file
|
@ -0,0 +1,16 @@
|
|||
using ChocolArm64.Instruction;
|
||||
|
||||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
class AOpCodeMul : AOpCodeAlu
|
||||
{
|
||||
public int Rm { get; private set; }
|
||||
public int Ra { get; private set; }
|
||||
|
||||
public AOpCodeMul(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
|
||||
{
|
||||
Ra = (OpCode >> 10) & 0x1f;
|
||||
Rm = (OpCode >> 16) & 0x1f;
|
||||
}
|
||||
}
|
||||
}
|
27
ChocolArm64/Decoder/AOpCodeSimd.cs
Normal file
27
ChocolArm64/Decoder/AOpCodeSimd.cs
Normal file
|
@ -0,0 +1,27 @@
|
|||
using ChocolArm64.Instruction;
|
||||
using ChocolArm64.State;
|
||||
|
||||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
class AOpCodeSimd : AOpCode, IAOpCodeSimd
|
||||
{
|
||||
public int Rd { get; private set; }
|
||||
public int Rn { get; private set; }
|
||||
public int Opc { get; private set; }
|
||||
public int Size { get; protected set; }
|
||||
|
||||
public int SizeF => Size & 1;
|
||||
|
||||
public AOpCodeSimd(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
|
||||
{
|
||||
Rd = (OpCode >> 0) & 0x1f;
|
||||
Rn = (OpCode >> 5) & 0x1f;
|
||||
Opc = (OpCode >> 15) & 0x3;
|
||||
Size = (OpCode >> 22) & 0x3;
|
||||
|
||||
RegisterSize = ((OpCode >> 30) & 1) != 0
|
||||
? ARegisterSize.SIMD128
|
||||
: ARegisterSize.SIMD64;
|
||||
}
|
||||
}
|
||||
}
|
31
ChocolArm64/Decoder/AOpCodeSimdCvt.cs
Normal file
31
ChocolArm64/Decoder/AOpCodeSimdCvt.cs
Normal file
|
@ -0,0 +1,31 @@
|
|||
using ChocolArm64.Instruction;
|
||||
using ChocolArm64.State;
|
||||
|
||||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
class AOpCodeSimdCvt : AOpCodeSimd
|
||||
{
|
||||
public int FBits { get; private set; }
|
||||
|
||||
public AOpCodeSimdCvt(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
|
||||
{
|
||||
//TODO:
|
||||
//Und of Fixed Point variants.
|
||||
int Scale = (OpCode >> 10) & 0x3f;
|
||||
int SF = (OpCode >> 31) & 0x1;
|
||||
|
||||
/*if (Type != SF && !(Type == 2 && SF == 1))
|
||||
{
|
||||
Emitter = AInstEmit.Und;
|
||||
|
||||
return;
|
||||
}*/
|
||||
|
||||
FBits = 64 - Scale;
|
||||
|
||||
RegisterSize = SF != 0
|
||||
? ARegisterSize.Int64
|
||||
: ARegisterSize.Int32;
|
||||
}
|
||||
}
|
||||
}
|
17
ChocolArm64/Decoder/AOpCodeSimdFcond.cs
Normal file
17
ChocolArm64/Decoder/AOpCodeSimdFcond.cs
Normal file
|
@ -0,0 +1,17 @@
|
|||
using ChocolArm64.Instruction;
|
||||
|
||||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
class AOpCodeSimdFcond : AOpCodeSimdReg, IAOpCodeCond
|
||||
{
|
||||
public int NZCV { get; private set; }
|
||||
|
||||
public ACond Cond { get; private set; }
|
||||
|
||||
public AOpCodeSimdFcond(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
|
||||
{
|
||||
NZCV = (OpCode >> 0) & 0xf;
|
||||
Cond = (ACond)((OpCode >> 12) & 0xf);
|
||||
}
|
||||
}
|
||||
}
|
33
ChocolArm64/Decoder/AOpCodeSimdFmov.cs
Normal file
33
ChocolArm64/Decoder/AOpCodeSimdFmov.cs
Normal file
|
@ -0,0 +1,33 @@
|
|||
using ChocolArm64.Instruction;
|
||||
|
||||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
class AOpCodeSimdFmov : AOpCode, IAOpCodeSimd
|
||||
{
|
||||
public int Rd { get; private set; }
|
||||
public long Imm { get; private set; }
|
||||
public int Size { get; private set; }
|
||||
|
||||
public AOpCodeSimdFmov(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
|
||||
{
|
||||
int Imm5 = (OpCode >> 5) & 0x1f;
|
||||
int Type = (OpCode >> 22) & 0x3;
|
||||
|
||||
if (Imm5 != 0b00000 || Type > 1)
|
||||
{
|
||||
Emitter = AInstEmit.Und;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Size = Type;
|
||||
|
||||
long Imm;
|
||||
|
||||
Rd = (OpCode >> 0) & 0x1f;
|
||||
Imm = (OpCode >> 13) & 0xff;
|
||||
|
||||
this.Imm = ADecoderHelper.DecodeImm8Float(Imm, Type);
|
||||
}
|
||||
}
|
||||
}
|
94
ChocolArm64/Decoder/AOpCodeSimdImm.cs
Normal file
94
ChocolArm64/Decoder/AOpCodeSimdImm.cs
Normal file
|
@ -0,0 +1,94 @@
|
|||
using ChocolArm64.Instruction;
|
||||
using ChocolArm64.State;
|
||||
|
||||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
class AOpCodeSimdImm : AOpCode, IAOpCodeSimd
|
||||
{
|
||||
public int Rd { get; private set; }
|
||||
public long Imm { get; private set; }
|
||||
public int Size { get; private set; }
|
||||
|
||||
public AOpCodeSimdImm(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
|
||||
{
|
||||
Rd = OpCode & 0x1f;
|
||||
|
||||
int CMode = (OpCode >> 12) & 0xf;
|
||||
int Op = (OpCode >> 29) & 0x1;
|
||||
|
||||
int ModeLow = CMode & 1;
|
||||
int ModeHigh = CMode >> 1;
|
||||
|
||||
long Imm;
|
||||
|
||||
Imm = ((uint)OpCode >> 5) & 0x1f;
|
||||
Imm |= ((uint)OpCode >> 11) & 0xe0;
|
||||
|
||||
if (ModeHigh == 0b111)
|
||||
{
|
||||
Size = ModeLow != 0 ? Op : 3;
|
||||
|
||||
switch (Op | (ModeLow << 1))
|
||||
{
|
||||
case 0:
|
||||
//64-bits Immediate.
|
||||
//Transform abcd efgh into abcd efgh abcd efgh ...
|
||||
Imm = (long)((ulong)Imm * 0x0101010101010101);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
//64-bits Immediate.
|
||||
//Transform abcd efgh into aaaa aaaa bbbb bbbb ...
|
||||
Imm = (Imm & 0xf0) >> 4 | (Imm & 0x0f) << 4;
|
||||
Imm = (Imm & 0xcc) >> 2 | (Imm & 0x33) << 2;
|
||||
Imm = (Imm & 0xaa) >> 1 | (Imm & 0x55) << 1;
|
||||
|
||||
Imm = (long)((ulong)Imm * 0x8040201008040201);
|
||||
Imm = (long)((ulong)Imm & 0x8080808080808080);
|
||||
|
||||
Imm |= Imm >> 4;
|
||||
Imm |= Imm >> 2;
|
||||
Imm |= Imm >> 1;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
case 3:
|
||||
//Floating point Immediate.
|
||||
Imm = ADecoderHelper.DecodeImm8Float(Imm, Size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if ((ModeHigh & 0b110) == 0b100)
|
||||
{
|
||||
//16-bits shifted Immediate.
|
||||
Size = 1; Imm <<= (ModeHigh & 1) << 3;
|
||||
}
|
||||
else if ((ModeHigh & 0b100) == 0b000)
|
||||
{
|
||||
//32-bits shifted Immediate.
|
||||
Size = 2; Imm <<= ModeHigh << 3;
|
||||
}
|
||||
else if ((ModeHigh & 0b111) == 0b110)
|
||||
{
|
||||
//32-bits shifted Immediate (fill with ones).
|
||||
Size = 2; Imm = ShlOnes(Imm, 8 << ModeLow);
|
||||
}
|
||||
else
|
||||
{
|
||||
//8 bits without shift.
|
||||
Size = 0;
|
||||
}
|
||||
|
||||
this.Imm = Imm;
|
||||
|
||||
RegisterSize = ((OpCode >> 30) & 1) != 0
|
||||
? ARegisterSize.SIMD128
|
||||
: ARegisterSize.SIMD64;
|
||||
}
|
||||
|
||||
private static long ShlOnes(long Value, int Shift)
|
||||
{
|
||||
return Value << Shift | (long)(ulong.MaxValue >> (64 - Shift));
|
||||
}
|
||||
}
|
||||
}
|
36
ChocolArm64/Decoder/AOpCodeSimdIns.cs
Normal file
36
ChocolArm64/Decoder/AOpCodeSimdIns.cs
Normal file
|
@ -0,0 +1,36 @@
|
|||
using ChocolArm64.Instruction;
|
||||
|
||||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
class AOpCodeSimdIns : AOpCodeSimd
|
||||
{
|
||||
public int SrcIndex { get; private set; }
|
||||
public int DstIndex { get; private set; }
|
||||
|
||||
public AOpCodeSimdIns(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
|
||||
{
|
||||
int Imm4 = (OpCode >> 11) & 0xf;
|
||||
int Imm5 = (OpCode >> 16) & 0x1f;
|
||||
|
||||
if (Imm5 == 0b10000)
|
||||
{
|
||||
Emitter = AInstEmit.Und;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Size = Imm5 & -Imm5;
|
||||
|
||||
switch (Size)
|
||||
{
|
||||
case 1: Size = 0; break;
|
||||
case 2: Size = 1; break;
|
||||
case 4: Size = 2; break;
|
||||
case 8: Size = 3; break;
|
||||
}
|
||||
|
||||
SrcIndex = Imm4 >> Size;
|
||||
DstIndex = Imm5 >> (Size + 1);
|
||||
}
|
||||
}
|
||||
}
|
19
ChocolArm64/Decoder/AOpCodeSimdMemImm.cs
Normal file
19
ChocolArm64/Decoder/AOpCodeSimdMemImm.cs
Normal file
|
@ -0,0 +1,19 @@
|
|||
using ChocolArm64.Instruction;
|
||||
|
||||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
class AOpCodeSimdMemImm : AOpCodeMemImm, IAOpCodeSimd
|
||||
{
|
||||
public AOpCodeSimdMemImm(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
|
||||
{
|
||||
Size |= (OpCode >> 21) & 4;
|
||||
|
||||
if (!WBack && !Unscaled && Size >= 4)
|
||||
{
|
||||
Imm <<= 4;
|
||||
}
|
||||
|
||||
Extend64 = false;
|
||||
}
|
||||
}
|
||||
}
|
31
ChocolArm64/Decoder/AOpCodeSimdMemLit.cs
Normal file
31
ChocolArm64/Decoder/AOpCodeSimdMemLit.cs
Normal file
|
@ -0,0 +1,31 @@
|
|||
using ChocolArm64.Instruction;
|
||||
|
||||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
class AOpCodeSimdMemLit : AOpCode, IAOpCodeSimd, IAOpCodeLit
|
||||
{
|
||||
public int Rt { get; private set; }
|
||||
public long Imm { get; private set; }
|
||||
public int Size { get; private set; }
|
||||
public bool Signed => false;
|
||||
public bool Prefetch => false;
|
||||
|
||||
public AOpCodeSimdMemLit(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
|
||||
{
|
||||
int Opc = (OpCode >> 30) & 3;
|
||||
|
||||
if (Opc == 3)
|
||||
{
|
||||
Emitter = AInstEmit.Und;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Rt = OpCode & 0x1f;
|
||||
|
||||
Imm = Position + ADecoderHelper.DecodeImmS19_2(OpCode);
|
||||
|
||||
Size = Opc + 2;
|
||||
}
|
||||
}
|
||||
}
|
49
ChocolArm64/Decoder/AOpCodeSimdMemMs.cs
Normal file
49
ChocolArm64/Decoder/AOpCodeSimdMemMs.cs
Normal file
|
@ -0,0 +1,49 @@
|
|||
using ChocolArm64.Instruction;
|
||||
using ChocolArm64.State;
|
||||
|
||||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
class AOpCodeSimdMemMs : AOpCodeMemReg, IAOpCodeSimd
|
||||
{
|
||||
public int Reps { get; private set; }
|
||||
public int SElems { get; private set; }
|
||||
public int Elems { get; private set; }
|
||||
public bool WBack { get; private set; }
|
||||
|
||||
public AOpCodeSimdMemMs(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
|
||||
{
|
||||
switch ((OpCode >> 12) & 0xf)
|
||||
{
|
||||
case 0b0000: Reps = 1; SElems = 4; break;
|
||||
case 0b0010: Reps = 4; SElems = 1; break;
|
||||
case 0b0100: Reps = 1; SElems = 3; break;
|
||||
case 0b0110: Reps = 3; SElems = 1; break;
|
||||
case 0b0111: Reps = 1; SElems = 1; break;
|
||||
case 0b1000: Reps = 1; SElems = 2; break;
|
||||
case 0b1010: Reps = 2; SElems = 1; break;
|
||||
|
||||
default: Inst = AInst.Undefined; return;
|
||||
}
|
||||
|
||||
Size = (OpCode >> 10) & 0x3;
|
||||
WBack = ((OpCode >> 23) & 0x1) != 0;
|
||||
|
||||
bool Q = ((OpCode >> 30) & 1) != 0;
|
||||
|
||||
if (!Q && Size == 3 && SElems != 1)
|
||||
{
|
||||
Inst = AInst.Undefined;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Extend64 = false;
|
||||
|
||||
RegisterSize = Q
|
||||
? ARegisterSize.SIMD128
|
||||
: ARegisterSize.SIMD64;
|
||||
|
||||
Elems = (GetBitsCount() >> 3) >> Size;
|
||||
}
|
||||
}
|
||||
}
|
16
ChocolArm64/Decoder/AOpCodeSimdMemPair.cs
Normal file
16
ChocolArm64/Decoder/AOpCodeSimdMemPair.cs
Normal file
|
@ -0,0 +1,16 @@
|
|||
using ChocolArm64.Instruction;
|
||||
|
||||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
class AOpCodeSimdMemPair : AOpCodeMemPair, IAOpCodeSimd
|
||||
{
|
||||
public AOpCodeSimdMemPair(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
|
||||
{
|
||||
Size = ((OpCode >> 30) & 3) + 2;
|
||||
|
||||
Extend64 = false;
|
||||
|
||||
DecodeImm(OpCode);
|
||||
}
|
||||
}
|
||||
}
|
14
ChocolArm64/Decoder/AOpCodeSimdMemReg.cs
Normal file
14
ChocolArm64/Decoder/AOpCodeSimdMemReg.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
using ChocolArm64.Instruction;
|
||||
|
||||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
class AOpCodeSimdMemReg : AOpCodeMemReg, IAOpCodeSimd
|
||||
{
|
||||
public AOpCodeSimdMemReg(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
|
||||
{
|
||||
Size |= (OpCode >> 21) & 4;
|
||||
|
||||
Extend64 = false;
|
||||
}
|
||||
}
|
||||
}
|
97
ChocolArm64/Decoder/AOpCodeSimdMemSs.cs
Normal file
97
ChocolArm64/Decoder/AOpCodeSimdMemSs.cs
Normal file
|
@ -0,0 +1,97 @@
|
|||
using ChocolArm64.Instruction;
|
||||
using ChocolArm64.State;
|
||||
|
||||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
class AOpCodeSimdMemSs : AOpCodeMemReg, IAOpCodeSimd
|
||||
{
|
||||
public int SElems { get; private set; }
|
||||
public int Index { get; private set; }
|
||||
public bool Replicate { get; private set; }
|
||||
public bool WBack { get; private set; }
|
||||
|
||||
public AOpCodeSimdMemSs(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
|
||||
{
|
||||
int Size = (OpCode >> 10) & 3;
|
||||
int S = (OpCode >> 12) & 1;
|
||||
int SElems = (OpCode >> 12) & 2;
|
||||
int Scale = (OpCode >> 14) & 3;
|
||||
int L = (OpCode >> 22) & 1;
|
||||
int Q = (OpCode >> 30) & 1;
|
||||
|
||||
SElems |= (OpCode >> 21) & 1;
|
||||
|
||||
SElems++;
|
||||
|
||||
int Index = (Q << 3) | (S << 2) | Size;
|
||||
|
||||
switch (Scale)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
if ((Size & 1) != 0)
|
||||
{
|
||||
Inst = AInst.Undefined;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Index >>= 1;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
if ((Size & 2) != 0 ||
|
||||
((Size & 1) != 0 && S != 0))
|
||||
{
|
||||
Inst = AInst.Undefined;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ((Size & 1) != 0)
|
||||
{
|
||||
Index >>= 3;
|
||||
|
||||
Scale = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
Index >>= 2;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 3:
|
||||
{
|
||||
if (L == 0 || S != 0)
|
||||
{
|
||||
Inst = AInst.Undefined;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Scale = Size;
|
||||
|
||||
Replicate = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this.SElems = SElems;
|
||||
this.Size = Scale;
|
||||
|
||||
Extend64 = false;
|
||||
|
||||
WBack = ((OpCode >> 23) & 0x1) != 0;
|
||||
|
||||
RegisterSize = Q != 0
|
||||
? ARegisterSize.SIMD128
|
||||
: ARegisterSize.SIMD64;
|
||||
}
|
||||
}
|
||||
}
|
18
ChocolArm64/Decoder/AOpCodeSimdReg.cs
Normal file
18
ChocolArm64/Decoder/AOpCodeSimdReg.cs
Normal file
|
@ -0,0 +1,18 @@
|
|||
using ChocolArm64.Instruction;
|
||||
|
||||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
class AOpCodeSimdReg : AOpCodeSimd
|
||||
{
|
||||
public bool Bit3 { get; private set; }
|
||||
public int Ra { get; private set; }
|
||||
public int Rm { get; private set; }
|
||||
|
||||
public AOpCodeSimdReg(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
|
||||
{
|
||||
Bit3 = ((OpCode >> 3) & 0x1) != 0;
|
||||
Ra = (OpCode >> 10) & 0x1f;
|
||||
Rm = (OpCode >> 16) & 0x1f;
|
||||
}
|
||||
}
|
||||
}
|
22
ChocolArm64/Decoder/AOpCodeSimdRegElem.cs
Normal file
22
ChocolArm64/Decoder/AOpCodeSimdRegElem.cs
Normal file
|
@ -0,0 +1,22 @@
|
|||
using ChocolArm64.Instruction;
|
||||
|
||||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
class AOpCodeSimdRegElem : AOpCodeSimdReg
|
||||
{
|
||||
public int Index { get; private set; }
|
||||
|
||||
public AOpCodeSimdRegElem(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
|
||||
{
|
||||
if ((Size & 1) != 0)
|
||||
{
|
||||
Index = (OpCode >> 11) & 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
Index = (OpCode >> 21) & 1 |
|
||||
(OpCode >> 10) & 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
16
ChocolArm64/Decoder/AOpCodeSimdShImm.cs
Normal file
16
ChocolArm64/Decoder/AOpCodeSimdShImm.cs
Normal file
|
@ -0,0 +1,16 @@
|
|||
using ChocolArm64.Instruction;
|
||||
|
||||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
class AOpCodeSimdShImm : AOpCodeSimd
|
||||
{
|
||||
public int Imm { get; private set; }
|
||||
|
||||
public AOpCodeSimdShImm(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
|
||||
{
|
||||
Imm = (OpCode >> 16) & 0x7f;
|
||||
|
||||
Size = ABitUtils.HighestBitSet32(Imm >> 3);
|
||||
}
|
||||
}
|
||||
}
|
12
ChocolArm64/Decoder/AOpCodeSimdTbl.cs
Normal file
12
ChocolArm64/Decoder/AOpCodeSimdTbl.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
using ChocolArm64.Instruction;
|
||||
|
||||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
class AOpCodeSimdTbl : AOpCodeSimdReg
|
||||
{
|
||||
public AOpCodeSimdTbl(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
|
||||
{
|
||||
Size = ((OpCode >> 13) & 3) + 1;
|
||||
}
|
||||
}
|
||||
}
|
24
ChocolArm64/Decoder/AOpCodeSystem.cs
Normal file
24
ChocolArm64/Decoder/AOpCodeSystem.cs
Normal file
|
@ -0,0 +1,24 @@
|
|||
using ChocolArm64.Instruction;
|
||||
|
||||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
class AOpCodeSystem : AOpCode
|
||||
{
|
||||
public int Rt { get; private set; }
|
||||
public int Op2 { get; private set; }
|
||||
public int CRm { get; private set; }
|
||||
public int CRn { get; private set; }
|
||||
public int Op1 { get; private set; }
|
||||
public int Op0 { get; private set; }
|
||||
|
||||
public AOpCodeSystem(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
|
||||
{
|
||||
Rt = (OpCode >> 0) & 0x1f;
|
||||
Op2 = (OpCode >> 5) & 0x7;
|
||||
CRm = (OpCode >> 8) & 0xf;
|
||||
CRn = (OpCode >> 12) & 0xf;
|
||||
Op1 = (OpCode >> 16) & 0x7;
|
||||
Op0 = ((OpCode >> 19) & 0x1) | 2;
|
||||
}
|
||||
}
|
||||
}
|
10
ChocolArm64/Decoder/AShiftType.cs
Normal file
10
ChocolArm64/Decoder/AShiftType.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
enum AShiftType
|
||||
{
|
||||
Lsl,
|
||||
Lsr,
|
||||
Asr,
|
||||
Ror
|
||||
}
|
||||
}
|
13
ChocolArm64/Decoder/IAOpCode.cs
Normal file
13
ChocolArm64/Decoder/IAOpCode.cs
Normal file
|
@ -0,0 +1,13 @@
|
|||
using ChocolArm64.Instruction;
|
||||
using ChocolArm64.State;
|
||||
|
||||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
interface IAOpCode
|
||||
{
|
||||
long Position { get; }
|
||||
|
||||
AInstEmitter Emitter { get; }
|
||||
ARegisterSize RegisterSize { get; }
|
||||
}
|
||||
}
|
10
ChocolArm64/Decoder/IAOpCodeAlu.cs
Normal file
10
ChocolArm64/Decoder/IAOpCodeAlu.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
interface IAOpCodeAlu : IAOpCode
|
||||
{
|
||||
int Rd { get; }
|
||||
int Rn { get; }
|
||||
|
||||
ADataOp DataOp { get; }
|
||||
}
|
||||
}
|
7
ChocolArm64/Decoder/IAOpCodeAluImm.cs
Normal file
7
ChocolArm64/Decoder/IAOpCodeAluImm.cs
Normal file
|
@ -0,0 +1,7 @@
|
|||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
interface IAOpCodeAluImm : IAOpCodeAlu
|
||||
{
|
||||
long Imm { get; }
|
||||
}
|
||||
}
|
10
ChocolArm64/Decoder/IAOpCodeAluRs.cs
Normal file
10
ChocolArm64/Decoder/IAOpCodeAluRs.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
interface IAOpCodeAluRs : IAOpCodeAlu
|
||||
{
|
||||
int Shift { get; }
|
||||
int Rm { get; }
|
||||
|
||||
AShiftType ShiftType { get; }
|
||||
}
|
||||
}
|
10
ChocolArm64/Decoder/IAOpCodeAluRx.cs
Normal file
10
ChocolArm64/Decoder/IAOpCodeAluRx.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
interface IAOpCodeAluRx : IAOpCodeAlu
|
||||
{
|
||||
int Shift { get; }
|
||||
int Rm { get; }
|
||||
|
||||
AIntType IntType { get; }
|
||||
}
|
||||
}
|
7
ChocolArm64/Decoder/IAOpCodeCond.cs
Normal file
7
ChocolArm64/Decoder/IAOpCodeCond.cs
Normal file
|
@ -0,0 +1,7 @@
|
|||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
interface IAOpCodeCond : IAOpCode
|
||||
{
|
||||
ACond Cond { get; }
|
||||
}
|
||||
}
|
11
ChocolArm64/Decoder/IAOpCodeLit.cs
Normal file
11
ChocolArm64/Decoder/IAOpCodeLit.cs
Normal file
|
@ -0,0 +1,11 @@
|
|||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
interface IAOpCodeLit : IAOpCode
|
||||
{
|
||||
int Rt { get; }
|
||||
long Imm { get; }
|
||||
int Size { get; }
|
||||
bool Signed { get; }
|
||||
bool Prefetch { get; }
|
||||
}
|
||||
}
|
7
ChocolArm64/Decoder/IAOpCodeSimd.cs
Normal file
7
ChocolArm64/Decoder/IAOpCodeSimd.cs
Normal file
|
@ -0,0 +1,7 @@
|
|||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
interface IAOpCodeSimd : IAOpCode
|
||||
{
|
||||
int Size { get; }
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue