OpCode cleanup

This commit is contained in:
riperiperi 2020-01-18 23:36:28 +00:00
commit 4d13cb0446
26 changed files with 159 additions and 82 deletions

View file

@ -46,11 +46,11 @@ namespace ARMeilleure.Decoders
} }
return MoveBit(imm, 7, 31) | MoveBit(~imm, 6, 30) | return MoveBit(imm, 7, 31) | MoveBit(~imm, 6, 30) |
MoveBit(imm, 6, 29) | MoveBit( imm, 6, 28) | MoveBit(imm, 6, 29) | MoveBit(imm, 6, 28) |
MoveBit(imm, 6, 27) | MoveBit( imm, 6, 26) | MoveBit(imm, 6, 27) | MoveBit(imm, 6, 26) |
MoveBit(imm, 6, 25) | MoveBit( imm, 5, 24) | MoveBit(imm, 6, 25) | MoveBit(imm, 5, 24) |
MoveBit(imm, 4, 23) | MoveBit( imm, 3, 22) | MoveBit(imm, 4, 23) | MoveBit(imm, 3, 22) |
MoveBit(imm, 2, 21) | MoveBit( imm, 1, 20) | MoveBit(imm, 2, 21) | MoveBit(imm, 1, 20) |
MoveBit(imm, 0, 19); MoveBit(imm, 0, 19);
} }
@ -63,13 +63,13 @@ namespace ARMeilleure.Decoders
} }
return MoveBit(imm, 7, 63) | MoveBit(~imm, 6, 62) | return MoveBit(imm, 7, 63) | MoveBit(~imm, 6, 62) |
MoveBit(imm, 6, 61) | MoveBit( imm, 6, 60) | MoveBit(imm, 6, 61) | MoveBit(imm, 6, 60) |
MoveBit(imm, 6, 59) | MoveBit( imm, 6, 58) | MoveBit(imm, 6, 59) | MoveBit(imm, 6, 58) |
MoveBit(imm, 6, 57) | MoveBit( imm, 6, 56) | MoveBit(imm, 6, 57) | MoveBit(imm, 6, 56) |
MoveBit(imm, 6, 55) | MoveBit( imm, 6, 54) | MoveBit(imm, 6, 55) | MoveBit(imm, 6, 54) |
MoveBit(imm, 5, 53) | MoveBit( imm, 4, 52) | MoveBit(imm, 5, 53) | MoveBit(imm, 4, 52) |
MoveBit(imm, 3, 51) | MoveBit( imm, 2, 50) | MoveBit(imm, 3, 51) | MoveBit(imm, 2, 50) |
MoveBit(imm, 1, 49) | MoveBit( imm, 0, 48); MoveBit(imm, 1, 49) | MoveBit(imm, 0, 48);
} }
public struct BitMask public struct BitMask
@ -148,5 +148,19 @@ namespace ARMeilleure.Decoders
{ {
return (((long)opCode << 45) >> 48) & ~3; 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;
}
} }
} }

View file

@ -23,6 +23,11 @@ namespace ARMeilleure.Decoders
Vd = ((opCode >> 18) & 0x10) | ((opCode >> 12) & 0xf); Vd = ((opCode >> 18) & 0x10) | ((opCode >> 12) & 0xf);
Vm = ((opCode >> 1) & 0x10) | ((opCode >> 0) & 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);
}
} }
} }
} }

View file

@ -12,6 +12,10 @@ namespace ARMeilleure.Decoders
public OpCode32SimdBinary(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) public OpCode32SimdBinary(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
{ {
Size = 3; Size = 3;
if (DecoderHelper.VectorArgumentsInvalid(Q, Vd, Vm, Vn))
{
Instruction = InstDescriptor.Undefined;
}
} }
} }
} }

View file

@ -9,6 +9,11 @@ namespace ARMeilleure.Decoders
public OpCode32SimdCmpZ(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) public OpCode32SimdCmpZ(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
{ {
Size = (opCode >> 18) & 0x3; //fvector size: 1 for 16 bit Size = (opCode >> 18) & 0x3; //fvector size: 1 for 16 bit
if (DecoderHelper.VectorArgumentsInvalid(Q, Vd, Vm))
{
Instruction = InstDescriptor.Undefined;
}
} }
} }
} }

View file

@ -4,10 +4,8 @@ using System.Text;
namespace ARMeilleure.Decoders namespace ARMeilleure.Decoders
{ {
class OpCode32SimdDupElem : BaseOpCode32Simd class OpCode32SimdDupElem : OpCode32Simd
{ {
public bool Q { get; private set; }
public int Index { get; private set; } public int Index { get; private set; }
public OpCode32SimdDupElem(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) public OpCode32SimdDupElem(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
@ -31,13 +29,18 @@ namespace ARMeilleure.Decoders
} }
else else
{ {
throw new Exception("Undefined"); Instruction = InstDescriptor.Undefined;
} }
Vd = ((opCode >> 18) & 0x10) | ((opCode >> 12) & 0xf); Vd = ((opCode >> 18) & 0x10) | ((opCode >> 12) & 0xf);
Vm = ((opCode >> 1) & 0x10) | ((opCode >> 0) & 0xf); Vm = ((opCode >> 1) & 0x10) | ((opCode >> 0) & 0xf);
Q = (opCode & (1 << 6)) != 0; Q = (opCode & (1 << 6)) != 0;
if (Q) RegisterSize = RegisterSize.Simd128; if (Q) RegisterSize = RegisterSize.Simd128;
if (DecoderHelper.VectorArgumentsInvalid(Q, Vd))
{
Instruction = InstDescriptor.Undefined;
}
} }
} }
} }

View file

@ -4,23 +4,31 @@ using System.Text;
namespace ARMeilleure.Decoders 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 Size { get; private set; }
public int Vd { get; private set; } public int Vd { get; private set; }
public int Rt { get; private set; } public int Rt { get; private set; }
public bool Q { 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. 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; Q = ((opCode >> 21) & 0x1) != 0;
RegisterSize = Q ? RegisterSize.Simd128 : RegisterSize.Simd64; RegisterSize = Q ? RegisterSize.Simd128 : RegisterSize.Simd64;
Vd = ((opCode >> 3) & 0x10) | ((opCode >> 16) & 0xf); Vd = ((opCode >> 3) & 0x10) | ((opCode >> 16) & 0xf);
Rt = ((opCode >> 12) & 0xf); Rt = ((opCode >> 12) & 0xf);
if (DecoderHelper.VectorArgumentsInvalid(Q, Vd))
{
Instruction = InstDescriptor.Undefined;
}
} }
} }
} }

View 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;
}
}
}
}

View file

@ -33,6 +33,11 @@ namespace ARMeilleure.Decoders
Size = parsedImm.Item2; Size = parsedImm.Item2;
RegisterSize = Q ? RegisterSize.Simd128 : RegisterSize.Simd64; RegisterSize = Q ? RegisterSize.Simd128 : RegisterSize.Simd64;
if (DecoderHelper.VectorArgumentsInvalid(Q, Vd))
{
Instruction = InstDescriptor.Undefined;
}
} }
} }
} }

View file

@ -35,7 +35,12 @@ namespace ARMeilleure.Decoders
} }
else else
{ {
throw new Exception("Unknown Encoding"); Instruction = InstDescriptor.Undefined;
}
if (DecoderHelper.VectorArgumentsInvalid(Q, Vd, Vm))
{
Instruction = InstDescriptor.Undefined;
} }
} }
} }

View file

@ -11,7 +11,6 @@ namespace ARMeilleure.Decoders
public int Size { get; private set; } public int Size { get; private set; }
public bool Add { get; private set; } public bool Add { get; private set; }
public int Immediate { 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) public OpCode32SimdMemImm(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
{ {
@ -27,8 +26,6 @@ namespace ARMeilleure.Decoders
var single = Size != 0b11; var single = Size != 0b11;
//RegisterSize = single ? RegisterSize.Simd32 : RegisterSize.Simd64;
if (single) if (single)
{ {
Vd = ((opCode >> 22) & 0x1) | ((opCode >> 11) & 0x1e); Vd = ((opCode >> 22) & 0x1) | ((opCode >> 11) & 0x1e);

View file

@ -9,13 +9,10 @@ namespace ARMeilleure.Decoders
public int Rn { get; private set; } public int Rn { get; private set; }
public int Vd { get; private set; } public int Vd { get; private set; }
public int RegisterRange public int RegisterRange { get; private set; }
{ get; private set; }
public int Offset { get; private set; } public int Offset { get; private set; }
public int PostOffset { get; private set; } public int PostOffset { get; private set; }
public bool IsLoad { get; private set; } public bool IsLoad { get; private set; }
public bool DoubleWidth { get; private set; } public bool DoubleWidth { get; private set; }
public bool Add { get; private set; } public bool Add { get; private set; }
@ -28,6 +25,11 @@ namespace ARMeilleure.Decoders
bool u = (opCode & (1 << 23)) != 0; bool u = (opCode & (1 << 23)) != 0;
bool p = (opCode & (1 << 24)) != 0; bool p = (opCode & (1 << 24)) != 0;
if (p == u && w)
{
Instruction = InstDescriptor.Undefined;
}
DoubleWidth = (opCode & (1 << 8)) != 0; DoubleWidth = (opCode & (1 << 8)) != 0;
if (!DoubleWidth) if (!DoubleWidth)
@ -60,6 +62,13 @@ namespace ARMeilleure.Decoders
} }
IsLoad = isLoad; IsLoad = isLoad;
int regs = DoubleWidth ? RegisterRange / 2 : RegisterRange;
if (RegisterRange == 0 || RegisterRange > 32 || Vd + regs > 32)
{
Instruction = InstDescriptor.Undefined;
}
} }
} }
} }

View file

@ -15,7 +15,6 @@ namespace ARMeilleure.Decoders
public bool RegisterIndex { get; private set; } public bool RegisterIndex { get; private set; }
public int Size { get; private set; } public int Size { get; private set; }
public bool Replicate { get; private set; } public bool Replicate { get; private set; }
public int Elems => GetBytesCount() >> Size;
public int Increment { get; private set; } public int Increment { get; private set; }
public OpCode32SimdMemSingle(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) public OpCode32SimdMemSingle(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
{ {

View file

@ -7,7 +7,6 @@ namespace ARMeilleure.Decoders
class OpCode32SimdMovGp : OpCode32, IOpCode32Simd class OpCode32SimdMovGp : OpCode32, IOpCode32Simd
{ {
public int Size => 2; public int Size => 2;
public int Elems => 1;
public int Vn { get; private set; } public int Vn { get; private set; }
public int Rt { get; private set; } public int Rt { get; private set; }

View file

@ -7,7 +7,6 @@ namespace ARMeilleure.Decoders
class OpCode32SimdMovGpDouble : OpCode32, IOpCode32Simd class OpCode32SimdMovGpDouble : OpCode32, IOpCode32Simd
{ {
public int Size => 3; public int Size => 3;
public int Elems => 1;
public int Vm { get; private set; } public int Vm { get; private set; }
public int Rt { get; private set; } public int Rt { get; private set; }

View file

@ -7,7 +7,6 @@ namespace ARMeilleure.Decoders
class OpCode32SimdMovGpElem : OpCode32, IOpCode32Simd class OpCode32SimdMovGpElem : OpCode32, IOpCode32Simd
{ {
public int Size { get; private set; } public int Size { get; private set; }
public int Elems => 1;
public int Vd { get; private set; } public int Vd { get; private set; }
public int Rt { get; private set; } public int Rt { get; private set; }
@ -41,7 +40,7 @@ namespace ARMeilleure.Decoders
} }
else else
{ {
throw new Exception("Undefined"); Instruction = InstDescriptor.Undefined;
} }
Vd = ((opCode >> 3) & 0x10) | ((opCode >> 16) & 0xf); Vd = ((opCode >> 3) & 0x10) | ((opCode >> 16) & 0xf);

View file

@ -15,6 +15,12 @@ namespace ARMeilleure.Decoders
public OpCode32SimdReg(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) public OpCode32SimdReg(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
{ {
Vn = ((opCode >> 3) & 0x10) | ((opCode >> 16) & 0xf); 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;
}
} }
} }
} }

View file

@ -14,9 +14,12 @@ namespace ARMeilleure.Decoders
RegisterSize = Q ? RegisterSize.Simd128 : RegisterSize.Simd64; RegisterSize = Q ? RegisterSize.Simd128 : RegisterSize.Simd64;
if (Size == 0b11) throw new Exception("Unknown Encoding!");
Vm = ((opCode >> 5) & 0x1) | ((opCode << 1) & 0x1e); Vm = ((opCode >> 5) & 0x1) | ((opCode << 1) & 0x1e);
if (DecoderHelper.VectorArgumentsInvalid(Q, Vd, Vn) || (Size == 0 || (Size == 1 && F)))
{
Instruction = InstDescriptor.Undefined;
}
} }
} }
} }

View file

@ -10,8 +10,6 @@ namespace ARMeilleure.Decoders
public int Vm { get; private set; } public int Vm { get; private set; }
public int Opc { get; protected set; } public int Opc { get; protected set; }
public int Size { 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) public OpCode32SimdS(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
{ {

View file

@ -10,6 +10,11 @@ namespace ARMeilleure.Decoders
{ {
Size = (opCode >> 18) & 0x1; //fvector size: 1 for 16 bit Size = (opCode >> 18) & 0x1; //fvector size: 1 for 16 bit
F = ((opCode >> 8) & 0x1) != 0; F = ((opCode >> 8) & 0x1) != 0;
if (DecoderHelper.VectorArgumentsInvalid(Q, Vd, Vm))
{
Instruction = InstDescriptor.Undefined;
}
} }
} }
} }

View file

@ -7,6 +7,7 @@ namespace ARMeilleure.Decoders
class OpCode32SimdTbl : OpCode32SimdReg class OpCode32SimdTbl : OpCode32SimdReg
{ {
public int Length { get; private set; } public int Length { get; private set; }
public OpCode32SimdTbl(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) public OpCode32SimdTbl(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
{ {
Length = (opCode >> 8) & 3; Length = (opCode >> 8) & 3;
@ -14,6 +15,11 @@ namespace ARMeilleure.Decoders
Opc = Q ? 1 : 0; Opc = Q ? 1 : 0;
Q = false; Q = false;
RegisterSize = RegisterSize.Simd64; RegisterSize = RegisterSize.Simd64;
if (Vn + Length + 1 > 32)
{
Instruction = InstDescriptor.Undefined;
}
} }
} }
} }

View file

@ -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;
}
}
}

View file

@ -6,13 +6,14 @@ namespace ARMeilleure.Decoders
{ {
class OpCode32System : OpCode32 class OpCode32System : OpCode32
{ {
public int Opc1 { get; internal set; } public int Opc1 { get; private set; }
public int CRn { get; internal set; } public int CRn { get; private set; }
public int Rt { get; internal set; } public int Rt { get; private set; }
public int Opc2 { get; internal set; } public int Opc2 { get; private set; }
public int CRm { get; internal 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) public OpCode32System(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
{ {
@ -21,6 +22,7 @@ namespace ARMeilleure.Decoders
Rt = (opCode >> 12) & 0xf; Rt = (opCode >> 12) & 0xf;
Opc2 = (opCode >> 5) & 0x7; Opc2 = (opCode >> 5) & 0x7;
CRm = (opCode >> 0) & 0xf; CRm = (opCode >> 0) & 0xf;
MrrcOp = (opCode >> 4) & 0xf;
Coproc = (opCode >> 8) & 0xf; Coproc = (opCode >> 8) & 0xf;
} }

View file

@ -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("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("<<<<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("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("111101001x10xxxxxxxxxx00xxxxxxxx", InstName.Vld1, InstEmit32.Vld1, typeof(OpCode32SimdMemSingle));
SetA32("111101000x10xxxxxxxx0111xxxxxxxx", InstName.Vld1, InstEmit32.Vld1, typeof(OpCode32SimdMemPair)); //regs = 1 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("111100100x10xxxxxxxx1111xxx0xxxx", InstName.Vmin, InstEmit32.Vmin_V, typeof(OpCode32SimdReg));
SetA32("1111001x0x<<xxxxxxxx0110xxx1xxxx", InstName.Vmin, InstEmit32.Vmin_I, 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("111100110xxxxxxxxxxx1111xxx1xxxx", InstName.VMMmn, InstEmit32.VmaxminNm_V, typeof(OpCode32SimdReg));
SetA32("<<<<11100x00xxxxxxxx101xx0x0xxxx", InstName.Vmla, InstEmit32.Vmla_S, typeof(OpCode32SimdRegS)); SetA32("<<<<11100x00xxxxxxxx101xx0x0xxxx", InstName.Vmla, InstEmit32.Vmla_S, typeof(OpCode32SimdRegS));

View file

@ -55,7 +55,7 @@ namespace ARMeilleure.Instructions
public static void Vdup(ArmEmitterContext context) public static void Vdup(ArmEmitterContext context)
{ {
OpCode32SimdVdupGP op = (OpCode32SimdVdupGP)context.CurrOp; OpCode32SimdDupGP op = (OpCode32SimdDupGP)context.CurrOp;
Operand insert = GetIntA32(context, op.Rt); Operand insert = GetIntA32(context, op.Rt);
@ -112,7 +112,7 @@ namespace ARMeilleure.Instructions
} }
public static void Vext(ArmEmitterContext context) public static void Vext(ArmEmitterContext context)
{ {
OpCode32SimdVext op = (OpCode32SimdVext)context.CurrOp; OpCode32SimdExt op = (OpCode32SimdExt)context.CurrOp;
int elems = op.GetBytesCount(); int elems = op.GetBytesCount();
int byteOff = op.Immediate; 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; EmitScalarBinaryOpF32(context, (op1, op2) => EmitSoftFloatCall(context, SoftFloat32.FPMaxNum, SoftFloat64.FPMaxNum, op1, op2));
_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, 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) 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); _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); _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) 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)); EmitVectorBinaryOpSx32(context, (op1, op2) => context.Multiply(op1, op2));
} }

View file

@ -202,7 +202,7 @@ namespace ARMeilleure.Instructions
{ {
OpCode32SimdS op = (OpCode32SimdS)context.CurrOp; OpCode32SimdS op = (OpCode32SimdS)context.CurrOp;
bool cmpWithZero = (op.RawOpCode & (1 << 16)) != 0; bool cmpWithZero = (op.Opc & 2) != 0;
{ {
int fSize = op.Size & 1; int fSize = op.Size & 1;
OperandType type = fSize != 0 ? OperandType.FP64 : OperandType.FP32; OperandType type = fSize != 0 ? OperandType.FP64 : OperandType.FP32;

View file

@ -56,11 +56,11 @@ namespace ARMeilleure.Instructions
case 0b0001: //FPSCR case 0b0001: //FPSCR
dlg = new _Void_U32(NativeInterface.SetFpscr); break; dlg = new _Void_U32(NativeInterface.SetFpscr); break;
case 0b0101: //MVFR2 case 0b0101: //MVFR2
throw new Exception("MVFR2"); throw new NotImplementedException("MVFR2");
case 0b0110: //MVFR1 case 0b0110: //MVFR1
throw new Exception("MVFR1"); throw new NotImplementedException("MVFR1");
case 0b0111: //MVFR0 case 0b0111: //MVFR0
throw new Exception("MVFR0"); throw new NotImplementedException("MVFR0");
case 0b1000: //FPEXC case 0b1000: //FPEXC
throw new NotImplementedException("Supervisor Only"); throw new NotImplementedException("Supervisor Only");
default: throw new NotImplementedException($"Unknown VMSR 0x{op.RawOpCode:X8} at 0x{op.Address:X16}."); 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) switch (op.Opc2)
{ {
case 5: // Data Memory Barrier Register case 5: // Data Memory Barrier Register
return; // SUPER TODO: DO NOT KNOW HOW TO IMPLEMENT THIS
default: default:
throw new NotImplementedException($"Unknown MRC Opc2 0x{op.Opc2:X16} at 0x{op.Address:X16}."); 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}."); 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; Delegate dlg;
switch (op.CRm) switch (op.CRm)