OpCode cleanup
This commit is contained in:
parent
969f197028
commit
4d13cb0446
26 changed files with 159 additions and 82 deletions
|
@ -10,7 +10,7 @@ namespace ARMeilleure.Decoders
|
|||
Imm8ToFP64Table = BuildImm8ToFP64Table();
|
||||
}
|
||||
|
||||
public static readonly uint[] Imm8ToFP32Table;
|
||||
public static readonly uint[] Imm8ToFP32Table;
|
||||
public static readonly ulong[] Imm8ToFP64Table;
|
||||
|
||||
private static uint[] BuildImm8ToFP32Table()
|
||||
|
@ -46,11 +46,11 @@ namespace ARMeilleure.Decoders
|
|||
}
|
||||
|
||||
return MoveBit(imm, 7, 31) | MoveBit(~imm, 6, 30) |
|
||||
MoveBit(imm, 6, 29) | MoveBit( imm, 6, 28) |
|
||||
MoveBit(imm, 6, 27) | MoveBit( imm, 6, 26) |
|
||||
MoveBit(imm, 6, 25) | MoveBit( imm, 5, 24) |
|
||||
MoveBit(imm, 4, 23) | MoveBit( imm, 3, 22) |
|
||||
MoveBit(imm, 2, 21) | MoveBit( imm, 1, 20) |
|
||||
MoveBit(imm, 6, 29) | MoveBit(imm, 6, 28) |
|
||||
MoveBit(imm, 6, 27) | MoveBit(imm, 6, 26) |
|
||||
MoveBit(imm, 6, 25) | MoveBit(imm, 5, 24) |
|
||||
MoveBit(imm, 4, 23) | MoveBit(imm, 3, 22) |
|
||||
MoveBit(imm, 2, 21) | MoveBit(imm, 1, 20) |
|
||||
MoveBit(imm, 0, 19);
|
||||
}
|
||||
|
||||
|
@ -63,21 +63,21 @@ namespace ARMeilleure.Decoders
|
|||
}
|
||||
|
||||
return MoveBit(imm, 7, 63) | MoveBit(~imm, 6, 62) |
|
||||
MoveBit(imm, 6, 61) | MoveBit( imm, 6, 60) |
|
||||
MoveBit(imm, 6, 59) | MoveBit( imm, 6, 58) |
|
||||
MoveBit(imm, 6, 57) | MoveBit( imm, 6, 56) |
|
||||
MoveBit(imm, 6, 55) | MoveBit( imm, 6, 54) |
|
||||
MoveBit(imm, 5, 53) | MoveBit( imm, 4, 52) |
|
||||
MoveBit(imm, 3, 51) | MoveBit( imm, 2, 50) |
|
||||
MoveBit(imm, 1, 49) | MoveBit( imm, 0, 48);
|
||||
MoveBit(imm, 6, 61) | MoveBit(imm, 6, 60) |
|
||||
MoveBit(imm, 6, 59) | MoveBit(imm, 6, 58) |
|
||||
MoveBit(imm, 6, 57) | MoveBit(imm, 6, 56) |
|
||||
MoveBit(imm, 6, 55) | MoveBit(imm, 6, 54) |
|
||||
MoveBit(imm, 5, 53) | MoveBit(imm, 4, 52) |
|
||||
MoveBit(imm, 3, 51) | MoveBit(imm, 2, 50) |
|
||||
MoveBit(imm, 1, 49) | MoveBit(imm, 0, 48);
|
||||
}
|
||||
|
||||
public struct BitMask
|
||||
{
|
||||
public long WMask;
|
||||
public long TMask;
|
||||
public int Pos;
|
||||
public int Shift;
|
||||
public int Pos;
|
||||
public int Shift;
|
||||
public bool IsUndefined;
|
||||
|
||||
public static BitMask Invalid => new BitMask { IsUndefined = true };
|
||||
|
@ -88,7 +88,7 @@ namespace ARMeilleure.Decoders
|
|||
int immS = (opCode >> 10) & 0x3f;
|
||||
int immR = (opCode >> 16) & 0x3f;
|
||||
|
||||
int n = (opCode >> 22) & 1;
|
||||
int n = (opCode >> 22) & 1;
|
||||
int sf = (opCode >> 31) & 1;
|
||||
|
||||
int length = BitUtils.HighestBitSet((~immS & 0x3f) | (n << 6));
|
||||
|
@ -115,7 +115,7 @@ namespace ARMeilleure.Decoders
|
|||
|
||||
if (r > 0)
|
||||
{
|
||||
wMask = BitUtils.RotateRight(wMask, r, size);
|
||||
wMask = BitUtils.RotateRight(wMask, r, size);
|
||||
wMask &= BitUtils.FillWithOnes(size);
|
||||
}
|
||||
|
||||
|
@ -124,7 +124,7 @@ namespace ARMeilleure.Decoders
|
|||
WMask = BitUtils.Replicate(wMask, size),
|
||||
TMask = BitUtils.Replicate(tMask, size),
|
||||
|
||||
Pos = immS,
|
||||
Pos = immS,
|
||||
Shift = immR
|
||||
};
|
||||
}
|
||||
|
@ -148,5 +148,19 @@ namespace ARMeilleure.Decoders
|
|||
{
|
||||
return (((long)opCode << 45) >> 48) & ~3;
|
||||
}
|
||||
|
||||
public static bool VectorArgumentsInvalid(bool q, params int[] args)
|
||||
{
|
||||
if (q) {
|
||||
for (int i = 0; i < args.Length; i++)
|
||||
{
|
||||
if ((args[i] & 1) == 1)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -23,6 +23,11 @@ namespace ARMeilleure.Decoders
|
|||
|
||||
Vd = ((opCode >> 18) & 0x10) | ((opCode >> 12) & 0xf);
|
||||
Vm = ((opCode >> 1) & 0x10) | ((opCode >> 0) & 0xf);
|
||||
|
||||
if (this.GetType() == typeof(OpCode32Simd)) // subclasses have their own handling of Vx to account for before checking!
|
||||
{
|
||||
DecoderHelper.VectorArgumentsInvalid(Q, Vd, Vm);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,10 @@ namespace ARMeilleure.Decoders
|
|||
public OpCode32SimdBinary(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
||||
{
|
||||
Size = 3;
|
||||
if (DecoderHelper.VectorArgumentsInvalid(Q, Vd, Vm, Vn))
|
||||
{
|
||||
Instruction = InstDescriptor.Undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,11 @@ namespace ARMeilleure.Decoders
|
|||
public OpCode32SimdCmpZ(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
||||
{
|
||||
Size = (opCode >> 18) & 0x3; //fvector size: 1 for 16 bit
|
||||
|
||||
if (DecoderHelper.VectorArgumentsInvalid(Q, Vd, Vm))
|
||||
{
|
||||
Instruction = InstDescriptor.Undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,10 +4,8 @@ using System.Text;
|
|||
|
||||
namespace ARMeilleure.Decoders
|
||||
{
|
||||
class OpCode32SimdDupElem : BaseOpCode32Simd
|
||||
class OpCode32SimdDupElem : OpCode32Simd
|
||||
{
|
||||
public bool Q { get; private set; }
|
||||
|
||||
public int Index { get; private set; }
|
||||
|
||||
public OpCode32SimdDupElem(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
||||
|
@ -31,13 +29,18 @@ namespace ARMeilleure.Decoders
|
|||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Undefined");
|
||||
Instruction = InstDescriptor.Undefined;
|
||||
}
|
||||
|
||||
Vd = ((opCode >> 18) & 0x10) | ((opCode >> 12) & 0xf);
|
||||
Vm = ((opCode >> 1) & 0x10) | ((opCode >> 0) & 0xf);
|
||||
Q = (opCode & (1 << 6)) != 0;
|
||||
if (Q) RegisterSize = RegisterSize.Simd128;
|
||||
|
||||
if (DecoderHelper.VectorArgumentsInvalid(Q, Vd))
|
||||
{
|
||||
Instruction = InstDescriptor.Undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,23 +4,31 @@ using System.Text;
|
|||
|
||||
namespace ARMeilleure.Decoders
|
||||
{
|
||||
class OpCode32SimdVdupGP : OpCode32, IOpCode32Simd
|
||||
class OpCode32SimdDupGP : OpCode32, IOpCode32Simd
|
||||
{
|
||||
public int Elems => GetBytesCount() >> ((Size == 1) ? 1 : 2);
|
||||
public int Size { get; private set; }
|
||||
public int Vd { get; private set; }
|
||||
public int Rt { get; private set; }
|
||||
public bool Q { get; private set; }
|
||||
|
||||
public OpCode32SimdVdupGP(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
||||
public OpCode32SimdDupGP(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
||||
{
|
||||
Size = 2 - (((opCode >> 21) & 0x2) | ((opCode >> 5) & 0x1)); //B:E - 0 for 32, 16 then 8.
|
||||
if (Size == -1)
|
||||
{
|
||||
Instruction = InstDescriptor.Undefined;
|
||||
}
|
||||
Q = ((opCode >> 21) & 0x1) != 0;
|
||||
|
||||
RegisterSize = Q ? RegisterSize.Simd128 : RegisterSize.Simd64;
|
||||
|
||||
Vd = ((opCode >> 3) & 0x10) | ((opCode >> 16) & 0xf);
|
||||
Rt = ((opCode >> 12) & 0xf);
|
||||
|
||||
if (DecoderHelper.VectorArgumentsInvalid(Q, Vd))
|
||||
{
|
||||
Instruction = InstDescriptor.Undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
20
ARMeilleure/Decoders/OpCode32SimdExt.cs
Normal file
20
ARMeilleure/Decoders/OpCode32SimdExt.cs
Normal file
|
@ -0,0 +1,20 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace ARMeilleure.Decoders
|
||||
{
|
||||
class OpCode32SimdExt : OpCode32SimdReg
|
||||
{
|
||||
public int Immediate { get; private set; }
|
||||
public OpCode32SimdExt(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
||||
{
|
||||
Immediate = (opCode >> 8) & 0xf;
|
||||
Size = 0;
|
||||
if (DecoderHelper.VectorArgumentsInvalid(Q, Vd, Vm, Vn) || (!Q && Immediate > 7))
|
||||
{
|
||||
Instruction = InstDescriptor.Undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -33,6 +33,11 @@ namespace ARMeilleure.Decoders
|
|||
Size = parsedImm.Item2;
|
||||
|
||||
RegisterSize = Q ? RegisterSize.Simd128 : RegisterSize.Simd64;
|
||||
|
||||
if (DecoderHelper.VectorArgumentsInvalid(Q, Vd))
|
||||
{
|
||||
Instruction = InstDescriptor.Undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,12 @@ namespace ARMeilleure.Decoders
|
|||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Unknown Encoding");
|
||||
Instruction = InstDescriptor.Undefined;
|
||||
}
|
||||
|
||||
if (DecoderHelper.VectorArgumentsInvalid(Q, Vd, Vm))
|
||||
{
|
||||
Instruction = InstDescriptor.Undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,6 @@ namespace ARMeilleure.Decoders
|
|||
public int Size { get; private set; }
|
||||
public bool Add { get; private set; }
|
||||
public int Immediate { get; private set; }
|
||||
public int Elems => 1;
|
||||
|
||||
public OpCode32SimdMemImm(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
||||
{
|
||||
|
@ -27,8 +26,6 @@ namespace ARMeilleure.Decoders
|
|||
|
||||
var single = Size != 0b11;
|
||||
|
||||
//RegisterSize = single ? RegisterSize.Simd32 : RegisterSize.Simd64;
|
||||
|
||||
if (single)
|
||||
{
|
||||
Vd = ((opCode >> 22) & 0x1) | ((opCode >> 11) & 0x1e);
|
||||
|
|
|
@ -9,13 +9,10 @@ namespace ARMeilleure.Decoders
|
|||
public int Rn { get; private set; }
|
||||
public int Vd { get; private set; }
|
||||
|
||||
public int RegisterRange
|
||||
{ get; private set; }
|
||||
public int RegisterRange { get; private set; }
|
||||
public int Offset { get; private set; }
|
||||
public int PostOffset { get; private set; }
|
||||
|
||||
public bool IsLoad { get; private set; }
|
||||
|
||||
public bool DoubleWidth { get; private set; }
|
||||
public bool Add { get; private set; }
|
||||
|
||||
|
@ -28,6 +25,11 @@ namespace ARMeilleure.Decoders
|
|||
bool u = (opCode & (1 << 23)) != 0;
|
||||
bool p = (opCode & (1 << 24)) != 0;
|
||||
|
||||
if (p == u && w)
|
||||
{
|
||||
Instruction = InstDescriptor.Undefined;
|
||||
}
|
||||
|
||||
DoubleWidth = (opCode & (1 << 8)) != 0;
|
||||
|
||||
if (!DoubleWidth)
|
||||
|
@ -60,6 +62,13 @@ namespace ARMeilleure.Decoders
|
|||
}
|
||||
|
||||
IsLoad = isLoad;
|
||||
|
||||
int regs = DoubleWidth ? RegisterRange / 2 : RegisterRange;
|
||||
|
||||
if (RegisterRange == 0 || RegisterRange > 32 || Vd + regs > 32)
|
||||
{
|
||||
Instruction = InstDescriptor.Undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@ namespace ARMeilleure.Decoders
|
|||
public bool RegisterIndex { get; private set; }
|
||||
public int Size { get; private set; }
|
||||
public bool Replicate { get; private set; }
|
||||
public int Elems => GetBytesCount() >> Size;
|
||||
public int Increment { get; private set; }
|
||||
public OpCode32SimdMemSingle(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
||||
{
|
||||
|
|
|
@ -7,7 +7,6 @@ namespace ARMeilleure.Decoders
|
|||
class OpCode32SimdMovGp : OpCode32, IOpCode32Simd
|
||||
{
|
||||
public int Size => 2;
|
||||
public int Elems => 1;
|
||||
|
||||
public int Vn { get; private set; }
|
||||
public int Rt { get; private set; }
|
||||
|
|
|
@ -7,7 +7,6 @@ namespace ARMeilleure.Decoders
|
|||
class OpCode32SimdMovGpDouble : OpCode32, IOpCode32Simd
|
||||
{
|
||||
public int Size => 3;
|
||||
public int Elems => 1;
|
||||
|
||||
public int Vm { get; private set; }
|
||||
public int Rt { get; private set; }
|
||||
|
|
|
@ -7,7 +7,6 @@ namespace ARMeilleure.Decoders
|
|||
class OpCode32SimdMovGpElem : OpCode32, IOpCode32Simd
|
||||
{
|
||||
public int Size { get; private set; }
|
||||
public int Elems => 1;
|
||||
|
||||
public int Vd { get; private set; }
|
||||
public int Rt { get; private set; }
|
||||
|
@ -41,7 +40,7 @@ namespace ARMeilleure.Decoders
|
|||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("Undefined");
|
||||
Instruction = InstDescriptor.Undefined;
|
||||
}
|
||||
|
||||
Vd = ((opCode >> 3) & 0x10) | ((opCode >> 16) & 0xf);
|
||||
|
|
|
@ -15,6 +15,12 @@ namespace ARMeilleure.Decoders
|
|||
public OpCode32SimdReg(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
||||
{
|
||||
Vn = ((opCode >> 3) & 0x10) | ((opCode >> 16) & 0xf);
|
||||
|
||||
// subclasses have their own handling of Vx to account for before checking!
|
||||
if (this.GetType() == typeof(OpCode32SimdReg) && DecoderHelper.VectorArgumentsInvalid(Q, Vd, Vm, Vn))
|
||||
{
|
||||
Instruction = InstDescriptor.Undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,9 +14,12 @@ namespace ARMeilleure.Decoders
|
|||
|
||||
RegisterSize = Q ? RegisterSize.Simd128 : RegisterSize.Simd64;
|
||||
|
||||
if (Size == 0b11) throw new Exception("Unknown Encoding!");
|
||||
|
||||
Vm = ((opCode >> 5) & 0x1) | ((opCode << 1) & 0x1e);
|
||||
|
||||
if (DecoderHelper.VectorArgumentsInvalid(Q, Vd, Vn) || (Size == 0 || (Size == 1 && F)))
|
||||
{
|
||||
Instruction = InstDescriptor.Undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,8 +10,6 @@ namespace ARMeilleure.Decoders
|
|||
public int Vm { get; private set; }
|
||||
public int Opc { get; protected set; }
|
||||
public int Size { get; protected set; }
|
||||
public bool Q { get; private set; }
|
||||
public int Elems => 1;
|
||||
|
||||
public OpCode32SimdS(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
||||
{
|
||||
|
|
|
@ -10,6 +10,11 @@ namespace ARMeilleure.Decoders
|
|||
{
|
||||
Size = (opCode >> 18) & 0x1; //fvector size: 1 for 16 bit
|
||||
F = ((opCode >> 8) & 0x1) != 0;
|
||||
|
||||
if (DecoderHelper.VectorArgumentsInvalid(Q, Vd, Vm))
|
||||
{
|
||||
Instruction = InstDescriptor.Undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ namespace ARMeilleure.Decoders
|
|||
class OpCode32SimdTbl : OpCode32SimdReg
|
||||
{
|
||||
public int Length { get; private set; }
|
||||
|
||||
public OpCode32SimdTbl(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
||||
{
|
||||
Length = (opCode >> 8) & 3;
|
||||
|
@ -14,6 +15,11 @@ namespace ARMeilleure.Decoders
|
|||
Opc = Q ? 1 : 0;
|
||||
Q = false;
|
||||
RegisterSize = RegisterSize.Simd64;
|
||||
|
||||
if (Vn + Length + 1 > 32)
|
||||
{
|
||||
Instruction = InstDescriptor.Undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace ARMeilleure.Decoders
|
||||
{
|
||||
class OpCode32SimdVext : OpCode32SimdReg
|
||||
{
|
||||
public int Immediate { get; private set; }
|
||||
public OpCode32SimdVext(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
||||
{
|
||||
Immediate = (opCode >> 8) & 0xf;
|
||||
Size = 0;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,13 +6,14 @@ namespace ARMeilleure.Decoders
|
|||
{
|
||||
class OpCode32System : OpCode32
|
||||
{
|
||||
public int Opc1 { get; internal set; }
|
||||
public int CRn { get; internal set; }
|
||||
public int Rt { get; internal set; }
|
||||
public int Opc2 { get; internal set; }
|
||||
public int CRm { get; internal set; }
|
||||
public int Opc1 { get; private set; }
|
||||
public int CRn { get; private set; }
|
||||
public int Rt { get; private set; }
|
||||
public int Opc2 { get; private set; }
|
||||
public int CRm { get; private set; }
|
||||
public int MrrcOp { get; private set; }
|
||||
|
||||
public int Coproc { get; internal set; }
|
||||
public int Coproc { get; private set; }
|
||||
|
||||
public OpCode32System(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
|
||||
{
|
||||
|
@ -21,6 +22,7 @@ namespace ARMeilleure.Decoders
|
|||
Rt = (opCode >> 12) & 0xf;
|
||||
Opc2 = (opCode >> 5) & 0x7;
|
||||
CRm = (opCode >> 0) & 0xf;
|
||||
MrrcOp = (opCode >> 4) & 0xf;
|
||||
|
||||
Coproc = (opCode >> 8) & 0xf;
|
||||
}
|
||||
|
|
|
@ -781,10 +781,10 @@ namespace ARMeilleure.Decoders
|
|||
SetA32("111111101x1111xxxxxx10>>x1x0xxxx", InstName.Vcvt, InstEmit32.Vcvt_R, typeof(OpCode32SimdCvtFI)); // the many fp32 to int encodings (fp)
|
||||
|
||||
SetA32("<<<<11101x00xxxxxxxx101xx0x0xxxx", InstName.Vdiv, InstEmit32.Vdiv_S, typeof(OpCode32SimdRegS));
|
||||
SetA32("<<<<11101xx0xxxxxxxx1011x0x10000", InstName.Vdup, InstEmit32.Vdup, typeof(OpCode32SimdVdupGP));
|
||||
SetA32("<<<<11101xx0xxxxxxxx1011x0x10000", InstName.Vdup, InstEmit32.Vdup, typeof(OpCode32SimdDupGP));
|
||||
SetA32("111100111x11xxxxxxxx11000xx0xxxx", InstName.Vdup, InstEmit32.Vdup_1, typeof(OpCode32SimdDupElem));
|
||||
|
||||
SetA32("111100101x11xxxxxxxxxxxxxxx0xxxx", InstName.Vext, InstEmit32.Vext, typeof(OpCode32SimdVext));
|
||||
SetA32("111100101x11xxxxxxxxxxxxxxx0xxxx", InstName.Vext, InstEmit32.Vext, typeof(OpCode32SimdExt));
|
||||
|
||||
SetA32("111101001x10xxxxxxxxxx00xxxxxxxx", InstName.Vld1, InstEmit32.Vld1, typeof(OpCode32SimdMemSingle));
|
||||
SetA32("111101000x10xxxxxxxx0111xxxxxxxx", InstName.Vld1, InstEmit32.Vld1, typeof(OpCode32SimdMemPair)); //regs = 1
|
||||
|
@ -818,7 +818,8 @@ namespace ARMeilleure.Decoders
|
|||
SetA32("111100100x10xxxxxxxx1111xxx0xxxx", InstName.Vmin, InstEmit32.Vmin_V, typeof(OpCode32SimdReg));
|
||||
SetA32("1111001x0x<<xxxxxxxx0110xxx1xxxx", InstName.Vmin, InstEmit32.Vmin_I, typeof(OpCode32SimdReg));
|
||||
|
||||
SetA32("111111101x00xxxxxxxx10>>xxx0xxxx", InstName.VMMmn, InstEmit32.VmaxminNm_S, typeof(OpCode32SimdRegS));
|
||||
SetA32("111111101x00xxxxxxxx10>>x0x0xxxx", InstName.VMMmn, InstEmit32.VmaxNm_S, typeof(OpCode32SimdRegS));
|
||||
SetA32("111111101x00xxxxxxxx10>>x1x0xxxx", InstName.VMMmn, InstEmit32.VminNm_S, typeof(OpCode32SimdRegS));
|
||||
SetA32("111100110xxxxxxxxxxx1111xxx1xxxx", InstName.VMMmn, InstEmit32.VmaxminNm_V, typeof(OpCode32SimdReg));
|
||||
|
||||
SetA32("<<<<11100x00xxxxxxxx101xx0x0xxxx", InstName.Vmla, InstEmit32.Vmla_S, typeof(OpCode32SimdRegS));
|
||||
|
|
|
@ -55,7 +55,7 @@ namespace ARMeilleure.Instructions
|
|||
|
||||
public static void Vdup(ArmEmitterContext context)
|
||||
{
|
||||
OpCode32SimdVdupGP op = (OpCode32SimdVdupGP)context.CurrOp;
|
||||
OpCode32SimdDupGP op = (OpCode32SimdDupGP)context.CurrOp;
|
||||
|
||||
Operand insert = GetIntA32(context, op.Rt);
|
||||
|
||||
|
@ -112,7 +112,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
public static void Vext(ArmEmitterContext context)
|
||||
{
|
||||
OpCode32SimdVext op = (OpCode32SimdVext)context.CurrOp;
|
||||
OpCode32SimdExt op = (OpCode32SimdExt)context.CurrOp;
|
||||
|
||||
int elems = op.GetBytesCount();
|
||||
int byteOff = op.Immediate;
|
||||
|
@ -217,18 +217,20 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void VmaxminNm_S(ArmEmitterContext context)
|
||||
public static void VmaxNm_S(ArmEmitterContext context)
|
||||
{
|
||||
bool max = (context.CurrOp.RawOpCode & (1 << 6)) == 0;
|
||||
_F32_F32_F32 f32 = max ? new _F32_F32_F32(SoftFloat32.FPMaxNum) : new _F32_F32_F32(SoftFloat32.FPMinNum);
|
||||
_F64_F64_F64 f64 = max ? new _F64_F64_F64(SoftFloat64.FPMaxNum) : new _F64_F64_F64(SoftFloat64.FPMinNum);
|
||||
EmitScalarBinaryOpF32(context, (op1, op2) => EmitSoftFloatCall(context, SoftFloat32.FPMaxNum, SoftFloat64.FPMaxNum, op1, op2));
|
||||
}
|
||||
|
||||
EmitScalarBinaryOpF32(context, (op1, op2) => EmitSoftFloatCall(context, f32, f64, op1, op2));
|
||||
public static void VminNm_S(ArmEmitterContext context)
|
||||
{
|
||||
EmitScalarBinaryOpF32(context, (op1, op2) => EmitSoftFloatCall(context, SoftFloat32.FPMinNum, SoftFloat64.FPMinNum, op1, op2));
|
||||
}
|
||||
|
||||
public static void VmaxminNm_V(ArmEmitterContext context)
|
||||
{
|
||||
bool max = (context.CurrOp.RawOpCode & (1 << 21)) == 0;
|
||||
OpCode32SimdReg op = (OpCode32SimdReg)context.CurrOp;
|
||||
bool max = (op.Size & 2) == 0; // op is high bit of size (not used for fp)
|
||||
_F32_F32_F32_Bool f32 = max ? new _F32_F32_F32_Bool(SoftFloat32.FPMaxNumFpscr) : new _F32_F32_F32_Bool(SoftFloat32.FPMinNumFpscr);
|
||||
_F64_F64_F64_Bool f64 = max ? new _F64_F64_F64_Bool(SoftFloat64.FPMaxNumFpscr) : new _F64_F64_F64_Bool(SoftFloat64.FPMinNumFpscr);
|
||||
|
||||
|
@ -309,7 +311,7 @@ namespace ARMeilleure.Instructions
|
|||
|
||||
public static void Vmul_I(ArmEmitterContext context)
|
||||
{
|
||||
if (((context.CurrOp.RawOpCode >> 24) & 1) != 0) throw new Exception("Polynomial mode not supported");
|
||||
if ((context.CurrOp as OpCode32SimdReg).U) throw new NotImplementedException("Polynomial mode not implemented");
|
||||
EmitVectorBinaryOpSx32(context, (op1, op2) => context.Multiply(op1, op2));
|
||||
}
|
||||
|
||||
|
|
|
@ -202,7 +202,7 @@ namespace ARMeilleure.Instructions
|
|||
{
|
||||
OpCode32SimdS op = (OpCode32SimdS)context.CurrOp;
|
||||
|
||||
bool cmpWithZero = (op.RawOpCode & (1 << 16)) != 0;
|
||||
bool cmpWithZero = (op.Opc & 2) != 0;
|
||||
{
|
||||
int fSize = op.Size & 1;
|
||||
OperandType type = fSize != 0 ? OperandType.FP64 : OperandType.FP32;
|
||||
|
|
|
@ -56,11 +56,11 @@ namespace ARMeilleure.Instructions
|
|||
case 0b0001: //FPSCR
|
||||
dlg = new _Void_U32(NativeInterface.SetFpscr); break;
|
||||
case 0b0101: //MVFR2
|
||||
throw new Exception("MVFR2");
|
||||
throw new NotImplementedException("MVFR2");
|
||||
case 0b0110: //MVFR1
|
||||
throw new Exception("MVFR1");
|
||||
throw new NotImplementedException("MVFR1");
|
||||
case 0b0111: //MVFR0
|
||||
throw new Exception("MVFR0");
|
||||
throw new NotImplementedException("MVFR0");
|
||||
case 0b1000: //FPEXC
|
||||
throw new NotImplementedException("Supervisor Only");
|
||||
default: throw new NotImplementedException($"Unknown VMSR 0x{op.RawOpCode:X8} at 0x{op.Address:X16}.");
|
||||
|
@ -154,7 +154,6 @@ namespace ARMeilleure.Instructions
|
|||
switch (op.Opc2)
|
||||
{
|
||||
case 5: // Data Memory Barrier Register
|
||||
return; // SUPER TODO: DO NOT KNOW HOW TO IMPLEMENT THIS
|
||||
default:
|
||||
throw new NotImplementedException($"Unknown MRC Opc2 0x{op.Opc2:X16} at 0x{op.Address:X16}.");
|
||||
}
|
||||
|
@ -197,7 +196,7 @@ namespace ARMeilleure.Instructions
|
|||
throw new NotImplementedException($"Unknown MRC Coprocessor ID 0x{op.Coproc:X16} at 0x{op.Address:X16}.");
|
||||
}
|
||||
|
||||
var opc = (op.RawOpCode >> 4) & 0xf;
|
||||
var opc = op.MrrcOp;
|
||||
|
||||
Delegate dlg;
|
||||
switch (op.CRm)
|
||||
|
|
Loading…
Add table
Reference in a new issue