Stop using GetFunctionPointer as that can't be called from native code, misc. fixes and tweaks
This commit is contained in:
parent
70970b4c22
commit
686f7f4ff2
48 changed files with 1952 additions and 2888 deletions
|
@ -67,12 +67,24 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
|||
fixedIntervals[0] = new List<LiveInterval>();
|
||||
fixedIntervals[1] = new List<LiveInterval>();
|
||||
|
||||
int intUsedRegisters = 0;
|
||||
int vecUsedRegisters = 0;
|
||||
|
||||
for (int index = 0; index < RegistersCount * 2; index++)
|
||||
{
|
||||
LiveInterval interval = _intervals[index];
|
||||
|
||||
if (!interval.IsEmpty)
|
||||
{
|
||||
if (interval.Register.Type == RegisterType.Integer)
|
||||
{
|
||||
intUsedRegisters |= 1 << interval.Register.Index;
|
||||
}
|
||||
else /* if (interval.Register.Type == RegisterType.Vector) */
|
||||
{
|
||||
vecUsedRegisters |= 1 << interval.Register.Index;
|
||||
}
|
||||
|
||||
InsertSorted(fixedIntervals[index & 1], interval);
|
||||
}
|
||||
}
|
||||
|
@ -84,9 +96,6 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
|||
int intFreeRegisters = regMasks.IntAvailableRegisters;
|
||||
int vecFreeRegisters = regMasks.VecAvailableRegisters;
|
||||
|
||||
int intUsedRegisters = 0;
|
||||
int vecUsedRegisters = 0;
|
||||
|
||||
intFreeRegisters = ReserveSpillTemps(ref _intSpillTemps, intFreeRegisters);
|
||||
vecFreeRegisters = ReserveSpillTemps(ref _vecSpillTemps, vecFreeRegisters);
|
||||
|
||||
|
@ -413,29 +422,10 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
|||
|
||||
Operation operation = node.Value as Operation;
|
||||
|
||||
Operand dest = operation.Dest;
|
||||
|
||||
if (dest != null)
|
||||
{
|
||||
if (dest.Kind == OperandKind.LocalVariable)
|
||||
{
|
||||
LiveInterval interval = GetOrAddInterval(dest);
|
||||
|
||||
if (interval.IsEmpty)
|
||||
{
|
||||
interval.SetStart(operationPos + 1);
|
||||
}
|
||||
|
||||
interval.AddUsePosition(operationPos);
|
||||
}
|
||||
else if (dest.Kind == OperandKind.Register)
|
||||
{
|
||||
int iIndex = GetRegisterId(dest.GetRegister());
|
||||
|
||||
_intervals[iIndex].AddRange(operationPos + 1, operationPos + InstructionGap);
|
||||
}
|
||||
}
|
||||
|
||||
// Note: For fixed intervals, we must process sources first, in
|
||||
// order to extend the live range of the fixed interval to the last
|
||||
// use, in case the register is both used and assigned on the same
|
||||
// instruction.
|
||||
for (int srcIndex = 0; srcIndex < operation.SourcesCount; srcIndex++)
|
||||
{
|
||||
Operand source = operation.GetSource(srcIndex);
|
||||
|
@ -466,6 +456,29 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
|||
}
|
||||
}
|
||||
|
||||
Operand dest = operation.Dest;
|
||||
|
||||
if (dest != null)
|
||||
{
|
||||
if (dest.Kind == OperandKind.LocalVariable)
|
||||
{
|
||||
LiveInterval interval = GetOrAddInterval(dest);
|
||||
|
||||
if (interval.IsEmpty)
|
||||
{
|
||||
interval.SetStart(operationPos + 1);
|
||||
}
|
||||
|
||||
interval.AddUsePosition(operationPos);
|
||||
}
|
||||
else if (dest.Kind == OperandKind.Register)
|
||||
{
|
||||
int iIndex = GetRegisterId(dest.GetRegister());
|
||||
|
||||
_intervals[iIndex].AddRange(operationPos + 1, operationPos + InstructionGap);
|
||||
}
|
||||
}
|
||||
|
||||
if (operation.Inst == Instruction.Call)
|
||||
{
|
||||
AddIntervalCallerSavedReg(masks.IntCallerSavedRegisters, operationPos, RegisterType.Integer);
|
||||
|
|
|
@ -91,6 +91,15 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
|||
{
|
||||
context.Active.Set(index);
|
||||
|
||||
if (current.Register.Type == RegisterType.Integer)
|
||||
{
|
||||
context.IntUsedRegisters |= 1 << current.Register.Index;
|
||||
}
|
||||
else /* if (interval.Register.Type == RegisterType.Vector) */
|
||||
{
|
||||
context.VecUsedRegisters |= 1 << current.Register.Index;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -84,7 +84,6 @@ namespace ARMeilleure.CodeGen.X86
|
|||
Add(X86Instruction.Cmpps, new InstInfo(BadOp, BadOp, BadOp, BadOp, 0x00000fc2, InstFlags.Vex | InstFlags.NoRexW));
|
||||
Add(X86Instruction.Cmpsd, new InstInfo(BadOp, BadOp, BadOp, BadOp, 0x00000fc2, InstFlags.Vex | InstFlags.NoRexW | InstFlags.PrefixF2));
|
||||
Add(X86Instruction.Cmpss, new InstInfo(BadOp, BadOp, BadOp, BadOp, 0x00000fc2, InstFlags.Vex | InstFlags.NoRexW | InstFlags.PrefixF3));
|
||||
Add(X86Instruction.Cmpxchg8b, new InstInfo(0x01000fc7, BadOp, BadOp, BadOp, BadOp, InstFlags.NoRexW));
|
||||
Add(X86Instruction.Cmpxchg16b, new InstInfo(0x01000fc7, BadOp, BadOp, BadOp, BadOp, InstFlags.RexW));
|
||||
Add(X86Instruction.Comisd, new InstInfo(BadOp, BadOp, BadOp, BadOp, 0x00000f2f, InstFlags.Vex | InstFlags.NoRexW | InstFlags.Prefix66));
|
||||
Add(X86Instruction.Comiss, new InstInfo(BadOp, BadOp, BadOp, BadOp, 0x00000f2f, InstFlags.Vex | InstFlags.NoRexW));
|
||||
|
@ -263,16 +262,6 @@ namespace ARMeilleure.CodeGen.X86
|
|||
WriteInstruction(dest, source, X86Instruction.Add);
|
||||
}
|
||||
|
||||
public void Addpd(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Addpd, source1);
|
||||
}
|
||||
|
||||
public void Addps(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Addps, source1);
|
||||
}
|
||||
|
||||
public void Addsd(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Addsd, source1);
|
||||
|
@ -288,16 +277,6 @@ namespace ARMeilleure.CodeGen.X86
|
|||
WriteInstruction(dest, source, X86Instruction.And);
|
||||
}
|
||||
|
||||
public void Andnpd(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Andnpd, source1);
|
||||
}
|
||||
|
||||
public void Andnps(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Andnps, source1);
|
||||
}
|
||||
|
||||
public void Bsr(Operand dest, Operand source)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Bsr);
|
||||
|
@ -336,34 +315,6 @@ namespace ARMeilleure.CodeGen.X86
|
|||
WriteByte(0x99);
|
||||
}
|
||||
|
||||
public void Cmppd(Operand dest, Operand source, Operand source1, byte imm)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Cmppd, source1);
|
||||
|
||||
WriteByte(imm);
|
||||
}
|
||||
|
||||
public void Cmpps(Operand dest, Operand source, Operand source1, byte imm)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Cmpps, source1);
|
||||
|
||||
WriteByte(imm);
|
||||
}
|
||||
|
||||
public void Cmpsd(Operand dest, Operand source, Operand source1, byte imm)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Cmpsd, source1);
|
||||
|
||||
WriteByte(imm);
|
||||
}
|
||||
|
||||
public void Cmpss(Operand dest, Operand source, Operand source1, byte imm)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Cmpss, source1);
|
||||
|
||||
WriteByte(imm);
|
||||
}
|
||||
|
||||
public void Cmpxchg16b(X86MemoryOperand memOp)
|
||||
{
|
||||
WriteByte(LockPrefix);
|
||||
|
@ -371,13 +322,6 @@ namespace ARMeilleure.CodeGen.X86
|
|||
WriteInstruction(memOp, null, X86Instruction.Cmpxchg16b);
|
||||
}
|
||||
|
||||
public void Cmpxchg8b(X86MemoryOperand memOp)
|
||||
{
|
||||
WriteByte(LockPrefix);
|
||||
|
||||
WriteInstruction(memOp, null, X86Instruction.Cmpxchg8b);
|
||||
}
|
||||
|
||||
public void Comisd(Operand source1, Operand source2)
|
||||
{
|
||||
WriteInstruction(source1, source2, X86Instruction.Comisd);
|
||||
|
@ -388,41 +332,6 @@ namespace ARMeilleure.CodeGen.X86
|
|||
WriteInstruction(source1, source2, X86Instruction.Comiss);
|
||||
}
|
||||
|
||||
public void Cvtdq2pd(Operand dest, Operand source)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Cvtdq2pd);
|
||||
}
|
||||
|
||||
public void Cvtdq2ps(Operand dest, Operand source)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Cvtdq2ps);
|
||||
}
|
||||
|
||||
public void Cvtpd2dq(Operand dest, Operand source)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Cvtpd2dq);
|
||||
}
|
||||
|
||||
public void Cvtpd2ps(Operand dest, Operand source)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Cvtpd2ps);
|
||||
}
|
||||
|
||||
public void Cvtps2dq(Operand dest, Operand source)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Cvtps2dq);
|
||||
}
|
||||
|
||||
public void Cvtps2pd(Operand dest, Operand source)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Cvtps2pd);
|
||||
}
|
||||
|
||||
public void Cvtsd2si(Operand dest, Operand source)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Cvtsd2si);
|
||||
}
|
||||
|
||||
public void Cvtsd2ss(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Cvtsd2ss, source1);
|
||||
|
@ -448,16 +357,6 @@ namespace ARMeilleure.CodeGen.X86
|
|||
WriteInstruction(null, source, X86Instruction.Div);
|
||||
}
|
||||
|
||||
public void Divpd(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Divpd, source1);
|
||||
}
|
||||
|
||||
public void Divps(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Divps, source1);
|
||||
}
|
||||
|
||||
public void Divsd(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Divsd, source1);
|
||||
|
@ -468,16 +367,6 @@ namespace ARMeilleure.CodeGen.X86
|
|||
WriteInstruction(dest, source, X86Instruction.Divss, source1);
|
||||
}
|
||||
|
||||
public void Haddpd(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Haddpd, source1);
|
||||
}
|
||||
|
||||
public void Haddps(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Haddps, source1);
|
||||
}
|
||||
|
||||
public void Idiv(Operand source)
|
||||
{
|
||||
WriteInstruction(null, source, X86Instruction.Idiv);
|
||||
|
@ -578,46 +467,6 @@ namespace ARMeilleure.CodeGen.X86
|
|||
WriteInstruction(dest, source, X86Instruction.Lea);
|
||||
}
|
||||
|
||||
public void Maxpd(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Maxpd, source1);
|
||||
}
|
||||
|
||||
public void Maxps(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Maxps, source1);
|
||||
}
|
||||
|
||||
public void Maxsd(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Maxsd, source1);
|
||||
}
|
||||
|
||||
public void Maxss(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Maxss, source1);
|
||||
}
|
||||
|
||||
public void Minpd(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Minpd, source1);
|
||||
}
|
||||
|
||||
public void Minps(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Minps, source1);
|
||||
}
|
||||
|
||||
public void Minsd(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Minsd, source1);
|
||||
}
|
||||
|
||||
public void Minss(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Minss, source1);
|
||||
}
|
||||
|
||||
public void Mov(Operand dest, Operand source)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Mov);
|
||||
|
@ -707,16 +556,6 @@ namespace ARMeilleure.CodeGen.X86
|
|||
WriteInstruction(null, source, X86Instruction.Mul128);
|
||||
}
|
||||
|
||||
public void Mulpd(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Mulpd, source1);
|
||||
}
|
||||
|
||||
public void Mulps(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Mulps, source1);
|
||||
}
|
||||
|
||||
public void Mulsd(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Mulsd, source1);
|
||||
|
@ -742,94 +581,11 @@ namespace ARMeilleure.CodeGen.X86
|
|||
WriteInstruction(dest, source, X86Instruction.Or);
|
||||
}
|
||||
|
||||
public void Paddb(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Paddb, source1);
|
||||
}
|
||||
|
||||
public void Paddd(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Paddd, source1);
|
||||
}
|
||||
|
||||
public void Paddq(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Paddq, source1);
|
||||
}
|
||||
|
||||
public void Paddw(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Paddw, source1);
|
||||
}
|
||||
|
||||
public void Pand(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Pand, source1);
|
||||
}
|
||||
|
||||
public void Pandn(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Pandn, source1);
|
||||
}
|
||||
|
||||
public void Pavgb(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Pavgb, source1);
|
||||
}
|
||||
|
||||
public void Pavgw(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Pavgw, source1);
|
||||
}
|
||||
|
||||
public void Pblendvb(Operand dest, Operand source1, Operand source2, Operand source3)
|
||||
{
|
||||
//TODO: Non-VEX version.
|
||||
WriteInstruction(dest, source2, X86Instruction.Pblendvb, source1);
|
||||
|
||||
WriteByte((byte)(source3.AsByte() << 4));
|
||||
}
|
||||
|
||||
public void Pcmpeqb(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Pcmpeqb, source1);
|
||||
}
|
||||
|
||||
public void Pcmpeqd(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Pcmpeqd, source1);
|
||||
}
|
||||
|
||||
public void Pcmpeqq(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Pcmpeqq, source1);
|
||||
}
|
||||
|
||||
public void Pcmpeqw(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Pcmpeqw, source1);
|
||||
}
|
||||
|
||||
public void Pcmpgtb(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Pcmpgtb, source1);
|
||||
}
|
||||
|
||||
public void Pcmpgtd(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Pcmpgtd, source1);
|
||||
}
|
||||
|
||||
public void Pcmpgtq(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Pcmpgtq, source1);
|
||||
}
|
||||
|
||||
public void Pcmpgtw(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Pcmpgtw, source1);
|
||||
}
|
||||
|
||||
public void Pextrb(Operand dest, Operand source, byte imm)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Pextrb);
|
||||
|
@ -872,106 +628,6 @@ namespace ARMeilleure.CodeGen.X86
|
|||
WriteByte(imm);
|
||||
}
|
||||
|
||||
public void Pmaxsb(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Pmaxsb, source1);
|
||||
}
|
||||
|
||||
public void Pmaxsd(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Pmaxsd, source1);
|
||||
}
|
||||
|
||||
public void Pmaxsw(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Pmaxsw, source1);
|
||||
}
|
||||
|
||||
public void Pmaxub(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Pmaxub, source1);
|
||||
}
|
||||
|
||||
public void Pmaxud(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Pmaxud, source1);
|
||||
}
|
||||
|
||||
public void Pmaxuw(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Pmaxuw, source1);
|
||||
}
|
||||
|
||||
public void Pminsb(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Pminsb, source1);
|
||||
}
|
||||
|
||||
public void Pminsd(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Pminsd, source1);
|
||||
}
|
||||
|
||||
public void Pminsw(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Pminsw, source1);
|
||||
}
|
||||
|
||||
public void Pminub(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Pminub, source1);
|
||||
}
|
||||
|
||||
public void Pminud(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Pminud, source1);
|
||||
}
|
||||
|
||||
public void Pminuw(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Pminuw, source1);
|
||||
}
|
||||
|
||||
public void Pmovsxbw(Operand dest, Operand source)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Pmovsxbw);
|
||||
}
|
||||
|
||||
public void Pmovsxdq(Operand dest, Operand source)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Pmovsxdq);
|
||||
}
|
||||
|
||||
public void Pmovsxwd(Operand dest, Operand source)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Pmovsxwd);
|
||||
}
|
||||
|
||||
public void Pmovzxbw(Operand dest, Operand source)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Pmovzxbw);
|
||||
}
|
||||
|
||||
public void Pmovzxdq(Operand dest, Operand source)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Pmovzxdq);
|
||||
}
|
||||
|
||||
public void Pmovzxwd(Operand dest, Operand source)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Pmovzxwd);
|
||||
}
|
||||
|
||||
public void Pmulld(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Pmulld, source1);
|
||||
}
|
||||
|
||||
public void Pmullw(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Pmullw, source1);
|
||||
}
|
||||
|
||||
public void Pop(Operand dest)
|
||||
{
|
||||
if (dest.Kind == OperandKind.Register)
|
||||
|
@ -989,16 +645,6 @@ namespace ARMeilleure.CodeGen.X86
|
|||
WriteInstruction(dest, source, X86Instruction.Popcnt);
|
||||
}
|
||||
|
||||
public void Por(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Por, source1);
|
||||
}
|
||||
|
||||
public void Pshufb(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Pshufb, source1);
|
||||
}
|
||||
|
||||
public void Pshufd(Operand dest, Operand source, byte imm)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Pshufd);
|
||||
|
@ -1006,116 +652,6 @@ namespace ARMeilleure.CodeGen.X86
|
|||
WriteByte(imm);
|
||||
}
|
||||
|
||||
public void Pslld(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(source1, source, X86Instruction.Pslld, dest);
|
||||
}
|
||||
|
||||
public void Pslldq(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(source1, source, X86Instruction.Pslldq, dest);
|
||||
}
|
||||
|
||||
public void Psllq(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(source1, source, X86Instruction.Psllq, dest);
|
||||
}
|
||||
|
||||
public void Psllw(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(source1, source, X86Instruction.Psllw, dest);
|
||||
}
|
||||
|
||||
public void Psrad(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(source1, source, X86Instruction.Psrad, dest);
|
||||
}
|
||||
|
||||
public void Psraw(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(source1, source, X86Instruction.Psraw, dest);
|
||||
}
|
||||
|
||||
public void Psrld(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(source1, source, X86Instruction.Psrld, dest);
|
||||
}
|
||||
|
||||
public void Psrlq(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(source1, source, X86Instruction.Psrlq, dest);
|
||||
}
|
||||
|
||||
public void Psrldq(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(source1, source, X86Instruction.Psrldq, dest);
|
||||
}
|
||||
|
||||
public void Psrlw(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(source1, source, X86Instruction.Psrlw, dest);
|
||||
}
|
||||
|
||||
public void Psubb(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Psubb, source1);
|
||||
}
|
||||
|
||||
public void Psubd(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Psubd, source1);
|
||||
}
|
||||
|
||||
public void Psubq(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Psubq, source1);
|
||||
}
|
||||
|
||||
public void Psubw(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Psubw, source1);
|
||||
}
|
||||
|
||||
public void Punpckhbw(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Punpckhbw, source1);
|
||||
}
|
||||
|
||||
public void Punpckhdq(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Punpckhdq, source1);
|
||||
}
|
||||
|
||||
public void Punpckhqdq(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Punpckhqdq, source1);
|
||||
}
|
||||
|
||||
public void Punpckhwd(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Punpckhwd, source1);
|
||||
}
|
||||
|
||||
public void Punpcklbw(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Punpcklbw, source1);
|
||||
}
|
||||
|
||||
public void Punpckldq(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Punpckldq, source1);
|
||||
}
|
||||
|
||||
public void Punpcklqdq(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Punpcklqdq, source1);
|
||||
}
|
||||
|
||||
public void Punpcklwd(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Punpcklwd, source1);
|
||||
}
|
||||
|
||||
public void Push(Operand source)
|
||||
{
|
||||
if (source.Kind == OperandKind.Register)
|
||||
|
@ -1128,21 +664,6 @@ namespace ARMeilleure.CodeGen.X86
|
|||
}
|
||||
}
|
||||
|
||||
public void Pxor(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Pxor, source1);
|
||||
}
|
||||
|
||||
public void Rcpps(Operand dest, Operand source)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Rcpps);
|
||||
}
|
||||
|
||||
public void Rcpss(Operand dest, Operand source)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Rcpss);
|
||||
}
|
||||
|
||||
public void Return()
|
||||
{
|
||||
WriteByte(0xc3);
|
||||
|
@ -1153,44 +674,6 @@ namespace ARMeilleure.CodeGen.X86
|
|||
WriteShiftInst(dest, source, X86Instruction.Ror);
|
||||
}
|
||||
|
||||
public void Roundpd(Operand dest, Operand source, byte imm)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Roundpd);
|
||||
|
||||
WriteByte(imm);
|
||||
}
|
||||
|
||||
public void Roundps(Operand dest, Operand source, byte imm)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Roundps);
|
||||
|
||||
WriteByte(imm);
|
||||
}
|
||||
|
||||
public void Roundsd(Operand dest, Operand source, byte imm)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Roundsd);
|
||||
|
||||
WriteByte(imm);
|
||||
}
|
||||
|
||||
public void Roundss(Operand dest, Operand source, byte imm)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Roundss);
|
||||
|
||||
WriteByte(imm);
|
||||
}
|
||||
|
||||
public void Rsqrtps(Operand dest, Operand source)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Rsqrtps);
|
||||
}
|
||||
|
||||
public void Rsqrtss(Operand dest, Operand source)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Rsqrtss);
|
||||
}
|
||||
|
||||
public void Sar(Operand dest, Operand source)
|
||||
{
|
||||
WriteShiftInst(dest, source, X86Instruction.Sar);
|
||||
|
@ -1206,20 +689,6 @@ namespace ARMeilleure.CodeGen.X86
|
|||
WriteShiftInst(dest, source, X86Instruction.Shr);
|
||||
}
|
||||
|
||||
public void Shufpd(Operand dest, Operand source, byte imm, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Shufpd, source1);
|
||||
|
||||
WriteByte(imm);
|
||||
}
|
||||
|
||||
public void Shufps(Operand dest, Operand source, byte imm, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Shufps, source1);
|
||||
|
||||
WriteByte(imm);
|
||||
}
|
||||
|
||||
public void Setcc(Operand dest, X86Condition condition)
|
||||
{
|
||||
InstInfo info = _instTable[(int)X86Instruction.Setcc];
|
||||
|
@ -1227,41 +696,11 @@ namespace ARMeilleure.CodeGen.X86
|
|||
WriteOpCode(dest, null, info.Flags, info.OpRRM | (int)condition);
|
||||
}
|
||||
|
||||
public void Sqrtpd(Operand dest, Operand source)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Sqrtpd);
|
||||
}
|
||||
|
||||
public void Sqrtps(Operand dest, Operand source)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Sqrtps);
|
||||
}
|
||||
|
||||
public void Sqrtsd(Operand dest, Operand source)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Sqrtsd);
|
||||
}
|
||||
|
||||
public void Sqrtss(Operand dest, Operand source)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Sqrtss);
|
||||
}
|
||||
|
||||
public void Sub(Operand dest, Operand source)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Sub);
|
||||
}
|
||||
|
||||
public void Subpd(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Subpd, source1);
|
||||
}
|
||||
|
||||
public void Subps(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Subps, source1);
|
||||
}
|
||||
|
||||
public void Subsd(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Subsd, source1);
|
||||
|
@ -1277,41 +716,65 @@ namespace ARMeilleure.CodeGen.X86
|
|||
WriteInstruction(src1, src2, X86Instruction.Test);
|
||||
}
|
||||
|
||||
public void Unpckhpd(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Unpckhpd, source1);
|
||||
}
|
||||
|
||||
public void Unpckhps(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Unpckhps, source1);
|
||||
}
|
||||
|
||||
public void Unpcklpd(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Unpcklpd, source1);
|
||||
}
|
||||
|
||||
public void Unpcklps(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Unpcklps, source1);
|
||||
}
|
||||
|
||||
public void Xor(Operand dest, Operand source)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Xor);
|
||||
}
|
||||
|
||||
public void Xorpd(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Xorpd, source1);
|
||||
}
|
||||
|
||||
public void Xorps(Operand dest, Operand source, Operand source1)
|
||||
{
|
||||
WriteInstruction(dest, source, X86Instruction.Xorps, source1);
|
||||
}
|
||||
|
||||
public void WriteInstruction(X86Instruction inst, Operand dest, Operand source)
|
||||
{
|
||||
WriteInstruction(dest, source, inst);
|
||||
}
|
||||
|
||||
public void WriteInstruction(X86Instruction inst, Operand dest, Operand src1, Operand src2)
|
||||
{
|
||||
if (src2.Kind == OperandKind.Constant)
|
||||
{
|
||||
WriteInstruction(src1, src2, inst, dest);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteInstruction(dest, src2, inst, src1);
|
||||
}
|
||||
}
|
||||
|
||||
public void WriteInstruction(X86Instruction inst, Operand dest, Operand source, byte imm)
|
||||
{
|
||||
WriteInstruction(dest, source, inst);
|
||||
|
||||
WriteByte(imm);
|
||||
}
|
||||
|
||||
public void WriteInstruction(
|
||||
X86Instruction inst,
|
||||
Operand dest,
|
||||
Operand src1,
|
||||
Operand src2,
|
||||
Operand src3)
|
||||
{
|
||||
//TODO: Non-VEX version.
|
||||
WriteInstruction(dest, src2, inst, src1);
|
||||
|
||||
WriteByte((byte)(src3.AsByte() << 4));
|
||||
}
|
||||
|
||||
public void WriteInstruction(
|
||||
X86Instruction inst,
|
||||
Operand dest,
|
||||
Operand src1,
|
||||
Operand src2,
|
||||
byte imm)
|
||||
{
|
||||
WriteInstruction(dest, src2, inst, src1);
|
||||
|
||||
WriteByte(imm);
|
||||
}
|
||||
|
||||
private void WriteShiftInst(Operand dest, Operand source, X86Instruction inst)
|
||||
{
|
||||
if (source.Kind == OperandKind.Register)
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -101,8 +101,6 @@ namespace ARMeilleure.CodeGen.X86
|
|||
|
||||
if (src1.Kind == OperandKind.Constant)
|
||||
{
|
||||
bool isVecCopy = inst == Instruction.Copy && !dest.Type.IsInteger();
|
||||
|
||||
if (!src1.Type.IsInteger())
|
||||
{
|
||||
//Handle non-integer types (FP32, FP64 and V128).
|
||||
|
@ -114,7 +112,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||
|
||||
operation.SetSource(0, src1);
|
||||
}
|
||||
else if (!HasConstSrc1(inst) || isVecCopy)
|
||||
else if (!HasConstSrc1(inst))
|
||||
{
|
||||
//Handle integer types.
|
||||
//Most ALU instructions accepts a 32-bits immediate on the second operand.
|
||||
|
@ -330,8 +328,8 @@ namespace ARMeilleure.CodeGen.X86
|
|||
Operand rax = Gpr(X86Register.Rax, OperandType.I64);
|
||||
Operand rdx = Gpr(X86Register.Rdx, OperandType.I64);
|
||||
|
||||
node.List.AddAfter(node, new Operation(Instruction.VectorInsert, dest, dest, rdx, Const(1)));
|
||||
node.List.AddAfter(node, new Operation(Instruction.Copy, dest, rax));
|
||||
node.List.AddAfter(node, new Operation(Instruction.VectorInsert, dest, dest, rdx, Const(1)));
|
||||
node.List.AddAfter(node, new Operation(Instruction.VectorCreateScalar, dest, rax));
|
||||
|
||||
operation.SetSource(1, Undef());
|
||||
operation.SetSource(2, Undef());
|
||||
|
@ -661,7 +659,9 @@ namespace ARMeilleure.CodeGen.X86
|
|||
{
|
||||
Operand temp = Local(source.Type);
|
||||
|
||||
Operation copyOp = new Operation(Instruction.Copy, temp, AddCopy(node, GetIntConst(source)));
|
||||
Operand intConst = AddCopy(node, GetIntConst(source));
|
||||
|
||||
Operation copyOp = new Operation(Instruction.VectorCreateScalar, temp, intConst);
|
||||
|
||||
node.List.AddBefore(node, copyOp);
|
||||
|
||||
|
|
|
@ -20,7 +20,6 @@ namespace ARMeilleure.CodeGen.X86
|
|||
Cmpsd,
|
||||
Cmpss,
|
||||
Cmpxchg16b,
|
||||
Cmpxchg8b,
|
||||
Comisd,
|
||||
Comiss,
|
||||
Cvtdq2pd,
|
||||
|
|
|
@ -314,23 +314,18 @@ namespace ARMeilleure.Decoders
|
|||
}
|
||||
}
|
||||
|
||||
OpCode decodedOpCode = new OpCode(inst, address, opCode);
|
||||
|
||||
if (type != null)
|
||||
{
|
||||
decodedOpCode = MakeOpCode(inst, type, address, opCode);
|
||||
return MakeOpCode(inst, type, address, opCode);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new OpCode(inst, address, opCode);
|
||||
}
|
||||
|
||||
return decodedOpCode;
|
||||
}
|
||||
|
||||
private static OpCode MakeOpCode(InstDescriptor inst, Type type, ulong address, int opCode)
|
||||
{
|
||||
if (type == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(type));
|
||||
}
|
||||
|
||||
MakeOp createInstance = _opActivators.GetOrAdd(type, CacheOpActivator);
|
||||
|
||||
return (OpCode)createInstance(inst, address, opCode);
|
||||
|
|
|
@ -2,5 +2,5 @@ using ARMeilleure.Translation;
|
|||
|
||||
namespace ARMeilleure.Decoders
|
||||
{
|
||||
delegate void InstEmitter(EmitterContext context);
|
||||
delegate void InstEmitter(ArmEmitterContext context);
|
||||
}
|
|
@ -15,11 +15,9 @@ namespace ARMeilleure.Diagnostics
|
|||
_accumulatedTime = new long[(int)PassName.Count];
|
||||
}
|
||||
|
||||
public static bool DoLog;
|
||||
|
||||
public static void StartPass(PassName name)
|
||||
{
|
||||
#if M_DEBUG
|
||||
#if DEBUG
|
||||
WriteOutput(name + " pass started...");
|
||||
|
||||
_startTime = Stopwatch.GetTimestamp();
|
||||
|
@ -28,7 +26,7 @@ namespace ARMeilleure.Diagnostics
|
|||
|
||||
public static void EndPass(PassName name, ControlFlowGraph cfg)
|
||||
{
|
||||
#if M_DEBUG
|
||||
#if DEBUG
|
||||
EndPass(name);
|
||||
|
||||
WriteOutput("IR after " + name + " pass:");
|
||||
|
@ -39,7 +37,7 @@ namespace ARMeilleure.Diagnostics
|
|||
|
||||
public static void EndPass(PassName name)
|
||||
{
|
||||
#if M_DEBUG
|
||||
#if DEBUG
|
||||
long elapsedTime = Stopwatch.GetTimestamp() - _startTime;
|
||||
|
||||
_accumulatedTime[(int)name] += elapsedTime;
|
||||
|
|
78
ARMeilleure/Instructions/DelegateTypes.cs
Normal file
78
ARMeilleure/Instructions/DelegateTypes.cs
Normal file
|
@ -0,0 +1,78 @@
|
|||
using ARMeilleure.State;
|
||||
using System;
|
||||
|
||||
namespace ARMeilleure.Instructions
|
||||
{
|
||||
delegate double _F64_F64(double a1);
|
||||
delegate double _F64_F64_F64(double a1, double a2);
|
||||
delegate double _F64_F64_F64_F64(double a1, double a2, double a3);
|
||||
delegate double _F64_F64_MidpointRounding(double a1, MidpointRounding a2);
|
||||
|
||||
delegate float _F32_F32(float a1);
|
||||
delegate float _F32_F32_F32(float a1, float a2);
|
||||
delegate float _F32_F32_F32_F32(float a1, float a2, float a3);
|
||||
delegate float _F32_F32_MidpointRounding(float a1, MidpointRounding a2);
|
||||
delegate float _F32_U16(ushort a1);
|
||||
|
||||
delegate int _S32_F32(float a1);
|
||||
delegate int _S32_F32_F32_Bool(float a1, float a2, bool a3);
|
||||
delegate int _S32_F64(double a1);
|
||||
delegate int _S32_F64_F64_Bool(double a1, double a2, bool a3);
|
||||
delegate int _S32_U64_U16(ulong a1, ushort a2);
|
||||
delegate int _S32_U64_U32(ulong a1, uint a2);
|
||||
delegate int _S32_U64_U64(ulong a1, ulong a2);
|
||||
delegate int _S32_U64_U8(ulong a1, byte a2);
|
||||
delegate int _S32_U64_V128(ulong a1, V128 a2);
|
||||
|
||||
delegate long _S64_F32(float a1);
|
||||
delegate long _S64_F64(double a1);
|
||||
delegate long _S64_S64(long a1);
|
||||
delegate long _S64_S64_S32(long a1, int a2);
|
||||
delegate long _S64_S64_S64(long a1, long a2);
|
||||
delegate long _S64_S64_S64_Bool_S32(long a1, long a2, bool a3, int a4);
|
||||
delegate long _S64_S64_S64_S32(long a1, long a2, int a3);
|
||||
delegate long _S64_U64_S32(ulong a1, int a2);
|
||||
delegate long _S64_U64_S64(ulong a1, long a2);
|
||||
|
||||
delegate ushort _U16_F32(float a1);
|
||||
delegate ushort _U16_U64(ulong a1);
|
||||
|
||||
delegate uint _U32_F32(float a1);
|
||||
delegate uint _U32_F64(double a1);
|
||||
delegate uint _U32_U32(uint a1);
|
||||
delegate uint _U32_U32_U16(uint a1, ushort a2);
|
||||
delegate uint _U32_U32_U32(uint a1, uint a2);
|
||||
delegate uint _U32_U32_U64(uint a1, ulong a2);
|
||||
delegate uint _U32_U32_U8(uint a1, byte a2);
|
||||
delegate uint _U32_U64(ulong a1);
|
||||
|
||||
delegate ulong _U64();
|
||||
delegate ulong _U64_F32(float a1);
|
||||
delegate ulong _U64_F64(double a1);
|
||||
delegate ulong _U64_S64_S32(long a1, int a2);
|
||||
delegate ulong _U64_S64_U64(long a1, ulong a2);
|
||||
delegate ulong _U64_U64(ulong a1);
|
||||
delegate ulong _U64_U64_S32(ulong a1, int a2);
|
||||
delegate ulong _U64_U64_S64_S32(ulong a1, long a2, int a3);
|
||||
delegate ulong _U64_U64_U64(ulong a1, ulong a2);
|
||||
delegate ulong _U64_U64_U64_Bool_S32(ulong a1, ulong a2, bool a3, int a4);
|
||||
|
||||
delegate byte _U8_U64(ulong a1);
|
||||
|
||||
delegate V128 _V128_U64(ulong a1);
|
||||
delegate V128 _V128_V128(V128 a1);
|
||||
delegate V128 _V128_V128_U32_V128(V128 a1, uint a2, V128 a3);
|
||||
delegate V128 _V128_V128_V128(V128 a1, V128 a2);
|
||||
delegate V128 _V128_V128_V128_V128(V128 a1, V128 a2, V128 a3);
|
||||
delegate V128 _V128_V128_V128_V128_V128(V128 a1, V128 a2, V128 a3, V128 a4);
|
||||
delegate V128 _V128_V128_V128_V128_V128_V128(V128 a1, V128 a2, V128 a3, V128 a4, V128 a5);
|
||||
|
||||
delegate void _Void();
|
||||
delegate void _Void_U64(ulong a1);
|
||||
delegate void _Void_U64_S32(ulong a1, int a2);
|
||||
delegate void _Void_U64_U16(ulong a1, ushort a2);
|
||||
delegate void _Void_U64_U32(ulong a1, uint a2);
|
||||
delegate void _Void_U64_U64(ulong a1, ulong a2);
|
||||
delegate void _Void_U64_U8(ulong a1, byte a2);
|
||||
delegate void _Void_U64_V128(ulong a1, V128 a2);
|
||||
}
|
|
@ -11,10 +11,10 @@ namespace ARMeilleure.Instructions
|
|||
{
|
||||
static partial class InstEmit
|
||||
{
|
||||
public static void Adc(EmitterContext context) => EmitAdc(context, setFlags: false);
|
||||
public static void Adcs(EmitterContext context) => EmitAdc(context, setFlags: true);
|
||||
public static void Adc(ArmEmitterContext context) => EmitAdc(context, setFlags: false);
|
||||
public static void Adcs(ArmEmitterContext context) => EmitAdc(context, setFlags: true);
|
||||
|
||||
private static void EmitAdc(EmitterContext context, bool setFlags)
|
||||
private static void EmitAdc(ArmEmitterContext context, bool setFlags)
|
||||
{
|
||||
Operand n = GetAluN(context);
|
||||
Operand m = GetAluM(context);
|
||||
|
@ -41,16 +41,18 @@ namespace ARMeilleure.Instructions
|
|||
SetAluDOrZR(context, d);
|
||||
}
|
||||
|
||||
public static void Add(EmitterContext context)
|
||||
public static void Add(ArmEmitterContext context)
|
||||
{
|
||||
SetAluD(context, context.Add(GetAluN(context), GetAluM(context)));
|
||||
}
|
||||
|
||||
public static void Adds(EmitterContext context)
|
||||
public static void Adds(ArmEmitterContext context)
|
||||
{
|
||||
Operand n = GetAluN(context);
|
||||
Operand m = GetAluM(context);
|
||||
|
||||
context.MarkComparison(n, m);
|
||||
|
||||
Operand d = context.Add(n, m);
|
||||
|
||||
EmitNZFlagsCheck(context, d);
|
||||
|
@ -61,12 +63,12 @@ namespace ARMeilleure.Instructions
|
|||
SetAluDOrZR(context, d);
|
||||
}
|
||||
|
||||
public static void And(EmitterContext context)
|
||||
public static void And(ArmEmitterContext context)
|
||||
{
|
||||
SetAluD(context, context.BitwiseAnd(GetAluN(context), GetAluM(context)));
|
||||
}
|
||||
|
||||
public static void Ands(EmitterContext context)
|
||||
public static void Ands(ArmEmitterContext context)
|
||||
{
|
||||
Operand n = GetAluN(context);
|
||||
Operand m = GetAluM(context);
|
||||
|
@ -79,15 +81,15 @@ namespace ARMeilleure.Instructions
|
|||
SetAluDOrZR(context, d);
|
||||
}
|
||||
|
||||
public static void Asrv(EmitterContext context)
|
||||
public static void Asrv(ArmEmitterContext context)
|
||||
{
|
||||
SetAluDOrZR(context, context.ShiftRightSI(GetAluN(context), GetAluMShift(context)));
|
||||
}
|
||||
|
||||
public static void Bic(EmitterContext context) => EmitBic(context, setFlags: false);
|
||||
public static void Bics(EmitterContext context) => EmitBic(context, setFlags: true);
|
||||
public static void Bic(ArmEmitterContext context) => EmitBic(context, setFlags: false);
|
||||
public static void Bics(ArmEmitterContext context) => EmitBic(context, setFlags: true);
|
||||
|
||||
private static void EmitBic(EmitterContext context, bool setFlags)
|
||||
private static void EmitBic(ArmEmitterContext context, bool setFlags)
|
||||
{
|
||||
Operand n = GetAluN(context);
|
||||
Operand m = GetAluM(context);
|
||||
|
@ -103,7 +105,7 @@ namespace ARMeilleure.Instructions
|
|||
SetAluD(context, d, setFlags);
|
||||
}
|
||||
|
||||
public static void Cls(EmitterContext context)
|
||||
public static void Cls(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeAlu op = (OpCodeAlu)context.CurrOp;
|
||||
|
||||
|
@ -124,7 +126,7 @@ namespace ARMeilleure.Instructions
|
|||
SetAluDOrZR(context, res);
|
||||
}
|
||||
|
||||
public static void Clz(EmitterContext context)
|
||||
public static void Clz(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeAlu op = (OpCodeAlu)context.CurrOp;
|
||||
|
||||
|
@ -135,7 +137,7 @@ namespace ARMeilleure.Instructions
|
|||
SetAluDOrZR(context, d);
|
||||
}
|
||||
|
||||
public static void Eon(EmitterContext context)
|
||||
public static void Eon(ArmEmitterContext context)
|
||||
{
|
||||
Operand n = GetAluN(context);
|
||||
Operand m = GetAluM(context);
|
||||
|
@ -145,12 +147,12 @@ namespace ARMeilleure.Instructions
|
|||
SetAluD(context, d);
|
||||
}
|
||||
|
||||
public static void Eor(EmitterContext context)
|
||||
public static void Eor(ArmEmitterContext context)
|
||||
{
|
||||
SetAluD(context, context.BitwiseExclusiveOr(GetAluN(context), GetAluM(context)));
|
||||
}
|
||||
|
||||
public static void Extr(EmitterContext context)
|
||||
public static void Extr(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeAluRs op = (OpCodeAluRs)context.CurrOp;
|
||||
|
||||
|
@ -177,20 +179,20 @@ namespace ARMeilleure.Instructions
|
|||
SetAluDOrZR(context, res);
|
||||
}
|
||||
|
||||
public static void Lslv(EmitterContext context)
|
||||
public static void Lslv(ArmEmitterContext context)
|
||||
{
|
||||
SetAluDOrZR(context, context.ShiftLeft(GetAluN(context), GetAluMShift(context)));
|
||||
}
|
||||
|
||||
public static void Lsrv(EmitterContext context)
|
||||
public static void Lsrv(ArmEmitterContext context)
|
||||
{
|
||||
SetAluDOrZR(context, context.ShiftRightUI(GetAluN(context), GetAluMShift(context)));
|
||||
}
|
||||
|
||||
public static void Sbc(EmitterContext context) => EmitSbc(context, setFlags: false);
|
||||
public static void Sbcs(EmitterContext context) => EmitSbc(context, setFlags: true);
|
||||
public static void Sbc(ArmEmitterContext context) => EmitSbc(context, setFlags: false);
|
||||
public static void Sbcs(ArmEmitterContext context) => EmitSbc(context, setFlags: true);
|
||||
|
||||
private static void EmitSbc(EmitterContext context, bool setFlags)
|
||||
private static void EmitSbc(ArmEmitterContext context, bool setFlags)
|
||||
{
|
||||
Operand n = GetAluN(context);
|
||||
Operand m = GetAluM(context);
|
||||
|
@ -217,16 +219,18 @@ namespace ARMeilleure.Instructions
|
|||
SetAluDOrZR(context, d);
|
||||
}
|
||||
|
||||
public static void Sub(EmitterContext context)
|
||||
public static void Sub(ArmEmitterContext context)
|
||||
{
|
||||
SetAluD(context, context.Subtract(GetAluN(context), GetAluM(context)));
|
||||
}
|
||||
|
||||
public static void Subs(EmitterContext context)
|
||||
public static void Subs(ArmEmitterContext context)
|
||||
{
|
||||
Operand n = GetAluN(context);
|
||||
Operand m = GetAluM(context);
|
||||
|
||||
context.MarkComparison(n, m);
|
||||
|
||||
Operand d = context.Subtract(n, m);
|
||||
|
||||
EmitNZFlagsCheck(context, d);
|
||||
|
@ -237,7 +241,7 @@ namespace ARMeilleure.Instructions
|
|||
SetAluDOrZR(context, d);
|
||||
}
|
||||
|
||||
public static void Orn(EmitterContext context)
|
||||
public static void Orn(ArmEmitterContext context)
|
||||
{
|
||||
Operand n = GetAluN(context);
|
||||
Operand m = GetAluM(context);
|
||||
|
@ -247,20 +251,50 @@ namespace ARMeilleure.Instructions
|
|||
SetAluD(context, d);
|
||||
}
|
||||
|
||||
public static void Orr(EmitterContext context)
|
||||
public static void Orr(ArmEmitterContext context)
|
||||
{
|
||||
SetAluD(context, context.BitwiseOr(GetAluN(context), GetAluM(context)));
|
||||
}
|
||||
|
||||
public static void Rbit(EmitterContext context) => EmitCall32_64(context,
|
||||
nameof(SoftFallback.ReverseBits32),
|
||||
nameof(SoftFallback.ReverseBits64));
|
||||
public static void Rbit(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeAlu op = (OpCodeAlu)context.CurrOp;
|
||||
|
||||
public static void Rev16(EmitterContext context) => EmitCall32_64(context,
|
||||
nameof(SoftFallback.ReverseBytes16_32),
|
||||
nameof(SoftFallback.ReverseBytes16_64));
|
||||
Operand n = GetIntOrZR(context, op.Rn);
|
||||
Operand d;
|
||||
|
||||
public static void Rev32(EmitterContext context)
|
||||
if (op.RegisterSize == RegisterSize.Int32)
|
||||
{
|
||||
d = context.Call(new _U32_U32(SoftFallback.ReverseBits32), n);
|
||||
}
|
||||
else
|
||||
{
|
||||
d = context.Call(new _U64_U64(SoftFallback.ReverseBits64), n);
|
||||
}
|
||||
|
||||
SetAluDOrZR(context, d);
|
||||
}
|
||||
|
||||
public static void Rev16(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeAlu op = (OpCodeAlu)context.CurrOp;
|
||||
|
||||
Operand n = GetIntOrZR(context, op.Rn);
|
||||
Operand d;
|
||||
|
||||
if (op.RegisterSize == RegisterSize.Int32)
|
||||
{
|
||||
d = context.Call(new _U32_U32(SoftFallback.ReverseBytes16_32), n);
|
||||
}
|
||||
else
|
||||
{
|
||||
d = context.Call(new _U64_U64(SoftFallback.ReverseBytes16_64), n);
|
||||
}
|
||||
|
||||
SetAluDOrZR(context, d);
|
||||
}
|
||||
|
||||
public static void Rev32(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeAlu op = (OpCodeAlu)context.CurrOp;
|
||||
|
||||
|
@ -272,42 +306,25 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
else
|
||||
{
|
||||
EmitCall32_64(context, null, nameof(SoftFallback.ReverseBytes32_64));
|
||||
Operand d = context.Call(new _U64_U64(SoftFallback.ReverseBytes32_64), n);
|
||||
|
||||
SetAluDOrZR(context, d);
|
||||
}
|
||||
}
|
||||
|
||||
private static void EmitCall32_64(EmitterContext context, string name32, string name64)
|
||||
{
|
||||
OpCodeAlu op = (OpCodeAlu)context.CurrOp;
|
||||
|
||||
Operand n = GetIntOrZR(context, op.Rn);
|
||||
Operand d;
|
||||
|
||||
if (op.RegisterSize == RegisterSize.Int32)
|
||||
{
|
||||
d = context.Call(typeof(SoftFallback).GetMethod(name32), n);
|
||||
}
|
||||
else
|
||||
{
|
||||
d = context.Call(typeof(SoftFallback).GetMethod(name64), n);
|
||||
}
|
||||
|
||||
SetAluDOrZR(context, d);
|
||||
}
|
||||
|
||||
public static void Rev64(EmitterContext context)
|
||||
public static void Rev64(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeAlu op = (OpCodeAlu)context.CurrOp;
|
||||
|
||||
SetAluDOrZR(context, context.ByteSwap(GetIntOrZR(context, op.Rn)));
|
||||
}
|
||||
|
||||
public static void Rorv(EmitterContext context)
|
||||
public static void Rorv(ArmEmitterContext context)
|
||||
{
|
||||
SetAluDOrZR(context, context.RotateRight(GetAluN(context), GetAluMShift(context)));
|
||||
}
|
||||
|
||||
private static Operand GetAluMShift(EmitterContext context)
|
||||
private static Operand GetAluMShift(ArmEmitterContext context)
|
||||
{
|
||||
IOpCodeAluRs op = (IOpCodeAluRs)context.CurrOp;
|
||||
|
||||
|
@ -321,29 +338,29 @@ namespace ARMeilleure.Instructions
|
|||
return context.BitwiseAnd(m, Const(context.CurrOp.GetBitsCount() - 1));
|
||||
}
|
||||
|
||||
private static void EmitNZFlagsCheck(EmitterContext context, Operand d)
|
||||
private static void EmitNZFlagsCheck(ArmEmitterContext context, Operand d)
|
||||
{
|
||||
context.Copy(GetFlag(PState.NFlag), context.ICompareLess (d, Const(d.Type, 0)));
|
||||
context.Copy(GetFlag(PState.ZFlag), context.ICompareEqual(d, Const(d.Type, 0)));
|
||||
SetFlag(context, PState.NFlag, context.ICompareLess (d, Const(d.Type, 0)));
|
||||
SetFlag(context, PState.ZFlag, context.ICompareEqual(d, Const(d.Type, 0)));
|
||||
}
|
||||
|
||||
private static void EmitCVFlagsClear(EmitterContext context)
|
||||
private static void EmitCVFlagsClear(ArmEmitterContext context)
|
||||
{
|
||||
context.Copy(GetFlag(PState.CFlag), Const(0));
|
||||
context.Copy(GetFlag(PState.VFlag), Const(0));
|
||||
SetFlag(context, PState.CFlag, Const(0));
|
||||
SetFlag(context, PState.VFlag, Const(0));
|
||||
}
|
||||
|
||||
public static void SetAluD(EmitterContext context, Operand d)
|
||||
public static void SetAluD(ArmEmitterContext context, Operand d)
|
||||
{
|
||||
SetAluD(context, d, x31IsZR: false);
|
||||
}
|
||||
|
||||
public static void SetAluDOrZR(EmitterContext context, Operand d)
|
||||
public static void SetAluDOrZR(ArmEmitterContext context, Operand d)
|
||||
{
|
||||
SetAluD(context, d, x31IsZR: true);
|
||||
}
|
||||
|
||||
public static void SetAluD(EmitterContext context, Operand d, bool x31IsZR)
|
||||
public static void SetAluD(ArmEmitterContext context, Operand d, bool x31IsZR)
|
||||
{
|
||||
IOpCodeAlu op = (IOpCodeAlu)context.CurrOp;
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ namespace ARMeilleure.Instructions
|
|||
{
|
||||
static class InstEmitAluHelper
|
||||
{
|
||||
public static void EmitAdcsCCheck(EmitterContext context, Operand n, Operand d)
|
||||
public static void EmitAdcsCCheck(ArmEmitterContext context, Operand n, Operand d)
|
||||
{
|
||||
//C = (Rd == Rn && CIn) || Rd < Rn
|
||||
Operand cIn = GetFlag(PState.CFlag);
|
||||
|
@ -20,16 +20,16 @@ namespace ARMeilleure.Instructions
|
|||
|
||||
cOut = context.BitwiseOr(cOut, context.ICompareLessUI(d, n));
|
||||
|
||||
context.Copy(GetFlag(PState.CFlag), cOut);
|
||||
SetFlag(context, PState.CFlag, cOut);
|
||||
}
|
||||
|
||||
public static void EmitAddsCCheck(EmitterContext context, Operand n, Operand d)
|
||||
public static void EmitAddsCCheck(ArmEmitterContext context, Operand n, Operand d)
|
||||
{
|
||||
//C = Rd < Rn
|
||||
context.Copy(GetFlag(PState.CFlag), context.ICompareLessUI(d, n));
|
||||
SetFlag(context, PState.CFlag, context.ICompareLessUI(d, n));
|
||||
}
|
||||
|
||||
public static void EmitAddsVCheck(EmitterContext context, Operand n, Operand m, Operand d)
|
||||
public static void EmitAddsVCheck(ArmEmitterContext context, Operand n, Operand m, Operand d)
|
||||
{
|
||||
//V = (Rd ^ Rn) & ~(Rn ^ Rm) < 0
|
||||
Operand vOut = context.BitwiseExclusiveOr(d, n);
|
||||
|
@ -38,10 +38,10 @@ namespace ARMeilleure.Instructions
|
|||
|
||||
vOut = context.ICompareLess(vOut, Const(vOut.Type, 0));
|
||||
|
||||
context.Copy(GetFlag(PState.VFlag), vOut);
|
||||
SetFlag(context, PState.VFlag, vOut);
|
||||
}
|
||||
|
||||
public static void EmitSbcsCCheck(EmitterContext context, Operand n, Operand m)
|
||||
public static void EmitSbcsCCheck(ArmEmitterContext context, Operand n, Operand m)
|
||||
{
|
||||
//C = (Rn == Rm && CIn) || Rn > Rm
|
||||
Operand cIn = GetFlag(PState.CFlag);
|
||||
|
@ -50,16 +50,16 @@ namespace ARMeilleure.Instructions
|
|||
|
||||
cOut = context.BitwiseOr(cOut, context.ICompareGreaterUI(n, m));
|
||||
|
||||
context.Copy(GetFlag(PState.CFlag), cOut);
|
||||
SetFlag(context, PState.CFlag, cOut);
|
||||
}
|
||||
|
||||
public static void EmitSubsCCheck(EmitterContext context, Operand n, Operand m)
|
||||
public static void EmitSubsCCheck(ArmEmitterContext context, Operand n, Operand m)
|
||||
{
|
||||
//C = Rn >= Rm
|
||||
context.Copy(GetFlag(PState.CFlag), context.ICompareGreaterOrEqualUI(n, m));
|
||||
SetFlag(context, PState.CFlag, context.ICompareGreaterOrEqualUI(n, m));
|
||||
}
|
||||
|
||||
public static void EmitSubsVCheck(EmitterContext context, Operand n, Operand m, Operand d)
|
||||
public static void EmitSubsVCheck(ArmEmitterContext context, Operand n, Operand m, Operand d)
|
||||
{
|
||||
//V = (Rd ^ Rn) & (Rn ^ Rm) < 0
|
||||
Operand vOut = context.BitwiseExclusiveOr(d, n);
|
||||
|
@ -68,10 +68,10 @@ namespace ARMeilleure.Instructions
|
|||
|
||||
vOut = context.ICompareLess(vOut, Const(vOut.Type, 0));
|
||||
|
||||
context.Copy(GetFlag(PState.VFlag), vOut);
|
||||
SetFlag(context, PState.VFlag, vOut);
|
||||
}
|
||||
|
||||
public static Operand GetAluN(EmitterContext context)
|
||||
public static Operand GetAluN(ArmEmitterContext context)
|
||||
{
|
||||
if (context.CurrOp is IOpCodeAlu op)
|
||||
{
|
||||
|
@ -94,7 +94,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static Operand GetAluM(EmitterContext context, bool setCarry = true)
|
||||
public static Operand GetAluM(ArmEmitterContext context, bool setCarry = true)
|
||||
{
|
||||
switch (context.CurrOp)
|
||||
{
|
||||
|
@ -103,7 +103,7 @@ namespace ARMeilleure.Instructions
|
|||
{
|
||||
if (op.SetFlags && op.IsRotated)
|
||||
{
|
||||
context.Copy(GetFlag(PState.CFlag), Const((uint)op.Immediate >> 31));
|
||||
SetFlag(context, PState.CFlag, Const((uint)op.Immediate >> 31));
|
||||
}
|
||||
|
||||
return Const(op.Immediate);
|
||||
|
@ -160,7 +160,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
|
||||
//ARM32 helpers.
|
||||
private static Operand GetMShiftedByImmediate(EmitterContext context, OpCode32AluRsImm op, bool setCarry)
|
||||
private static Operand GetMShiftedByImmediate(ArmEmitterContext context, OpCode32AluRsImm op, bool setCarry)
|
||||
{
|
||||
Operand m = GetIntA32(context, op.Rm);
|
||||
|
||||
|
@ -201,7 +201,7 @@ namespace ARMeilleure.Instructions
|
|||
return m;
|
||||
}
|
||||
|
||||
private static Operand GetLslC(EmitterContext context, Operand m, bool setCarry, int shift)
|
||||
private static Operand GetLslC(ArmEmitterContext context, Operand m, bool setCarry, int shift)
|
||||
{
|
||||
if ((uint)shift > 32)
|
||||
{
|
||||
|
@ -224,14 +224,14 @@ namespace ARMeilleure.Instructions
|
|||
|
||||
cOut = context.BitwiseAnd(cOut, Const(1));
|
||||
|
||||
context.Copy(GetFlag(PState.CFlag), cOut);
|
||||
SetFlag(context, PState.CFlag, cOut);
|
||||
}
|
||||
|
||||
return context.ShiftLeft(m, Const(shift));
|
||||
}
|
||||
}
|
||||
|
||||
private static Operand GetLsrC(EmitterContext context, Operand m, bool setCarry, int shift)
|
||||
private static Operand GetLsrC(ArmEmitterContext context, Operand m, bool setCarry, int shift)
|
||||
{
|
||||
if ((uint)shift > 32)
|
||||
{
|
||||
|
@ -257,17 +257,17 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
private static Operand GetShiftByMoreThan32(EmitterContext context, bool setCarry)
|
||||
private static Operand GetShiftByMoreThan32(ArmEmitterContext context, bool setCarry)
|
||||
{
|
||||
if (setCarry)
|
||||
{
|
||||
context.Copy(GetFlag(PState.CFlag), Const(0));;
|
||||
SetFlag(context, PState.CFlag, Const(0));;
|
||||
}
|
||||
|
||||
return Const(0);
|
||||
}
|
||||
|
||||
private static Operand GetAsrC(EmitterContext context, Operand m, bool setCarry, int shift)
|
||||
private static Operand GetAsrC(ArmEmitterContext context, Operand m, bool setCarry, int shift)
|
||||
{
|
||||
if ((uint)shift >= 32)
|
||||
{
|
||||
|
@ -291,7 +291,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
private static Operand GetRorC(EmitterContext context, Operand m, bool setCarry, int shift)
|
||||
private static Operand GetRorC(ArmEmitterContext context, Operand m, bool setCarry, int shift)
|
||||
{
|
||||
shift &= 0x1f;
|
||||
|
||||
|
@ -305,7 +305,7 @@ namespace ARMeilleure.Instructions
|
|||
return m;
|
||||
}
|
||||
|
||||
private static Operand GetRrxC(EmitterContext context, Operand m, bool setCarry)
|
||||
private static Operand GetRrxC(ArmEmitterContext context, Operand m, bool setCarry)
|
||||
{
|
||||
//Rotate right by 1 with carry.
|
||||
Operand cIn = context.Copy(GetFlag(PState.CFlag));
|
||||
|
@ -322,23 +322,23 @@ namespace ARMeilleure.Instructions
|
|||
return m;
|
||||
}
|
||||
|
||||
private static void SetCarryMLsb(EmitterContext context, Operand m)
|
||||
private static void SetCarryMLsb(ArmEmitterContext context, Operand m)
|
||||
{
|
||||
context.Copy(GetFlag(PState.CFlag), context.BitwiseAnd(m, Const(1)));
|
||||
SetFlag(context, PState.CFlag, context.BitwiseAnd(m, Const(1)));
|
||||
}
|
||||
|
||||
private static void SetCarryMMsb(EmitterContext context, Operand m)
|
||||
private static void SetCarryMMsb(ArmEmitterContext context, Operand m)
|
||||
{
|
||||
context.Copy(GetFlag(PState.CFlag), context.ShiftRightUI(m, Const(31)));
|
||||
SetFlag(context, PState.CFlag, context.ShiftRightUI(m, Const(31)));
|
||||
}
|
||||
|
||||
private static void SetCarryMShrOut(EmitterContext context, Operand m, int shift)
|
||||
private static void SetCarryMShrOut(ArmEmitterContext context, Operand m, int shift)
|
||||
{
|
||||
Operand cOut = context.ShiftRightUI(m, Const(shift - 1));
|
||||
|
||||
cOut = context.BitwiseAnd(cOut, Const(1));
|
||||
|
||||
context.Copy(GetFlag(PState.CFlag), cOut);
|
||||
SetFlag(context, PState.CFlag, cOut);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace ARMeilleure.Instructions
|
|||
{
|
||||
static partial class InstEmit
|
||||
{
|
||||
public static void Bfm(EmitterContext context)
|
||||
public static void Bfm(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeBfm op = (OpCodeBfm)context.CurrOp;
|
||||
|
||||
|
@ -48,7 +48,7 @@ namespace ARMeilleure.Instructions
|
|||
SetIntOrZR(context, op.Rd, res);
|
||||
}
|
||||
|
||||
public static void Sbfm(EmitterContext context)
|
||||
public static void Sbfm(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeBfm op = (OpCodeBfm)context.CurrOp;
|
||||
|
||||
|
@ -94,7 +94,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Ubfm(EmitterContext context)
|
||||
public static void Ubfm(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeBfm op = (OpCodeBfm)context.CurrOp;
|
||||
|
||||
|
@ -128,10 +128,10 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
private static void EmitSbfiz(EmitterContext context) => EmitBfiz(context, signed: true);
|
||||
private static void EmitUbfiz(EmitterContext context) => EmitBfiz(context, signed: false);
|
||||
private static void EmitSbfiz(ArmEmitterContext context) => EmitBfiz(context, signed: true);
|
||||
private static void EmitUbfiz(ArmEmitterContext context) => EmitBfiz(context, signed: false);
|
||||
|
||||
private static void EmitBfiz(EmitterContext context, bool signed)
|
||||
private static void EmitBfiz(ArmEmitterContext context, bool signed)
|
||||
{
|
||||
OpCodeBfm op = (OpCodeBfm)context.CurrOp;
|
||||
|
||||
|
@ -148,17 +148,17 @@ namespace ARMeilleure.Instructions
|
|||
SetIntOrZR(context, op.Rd, res);
|
||||
}
|
||||
|
||||
private static void EmitSbfmShift(EmitterContext context)
|
||||
private static void EmitSbfmShift(ArmEmitterContext context)
|
||||
{
|
||||
EmitBfmShift(context, signed: true);
|
||||
}
|
||||
|
||||
private static void EmitUbfmShift(EmitterContext context)
|
||||
private static void EmitUbfmShift(ArmEmitterContext context)
|
||||
{
|
||||
EmitBfmShift(context, signed: false);
|
||||
}
|
||||
|
||||
private static void EmitBfmShift(EmitterContext context, bool signed)
|
||||
private static void EmitBfmShift(ArmEmitterContext context, bool signed)
|
||||
{
|
||||
OpCodeBfm op = (OpCodeBfm)context.CurrOp;
|
||||
|
||||
|
@ -171,7 +171,7 @@ namespace ARMeilleure.Instructions
|
|||
SetIntOrZR(context, op.Rd, res);
|
||||
}
|
||||
|
||||
private static void EmitBfmLsl(EmitterContext context)
|
||||
private static void EmitBfmLsl(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeBfm op = (OpCodeBfm)context.CurrOp;
|
||||
|
||||
|
@ -182,7 +182,7 @@ namespace ARMeilleure.Instructions
|
|||
SetIntOrZR(context, op.Rd, context.ShiftLeft(res, Const(shift)));
|
||||
}
|
||||
|
||||
private static Operand GetBfmN(EmitterContext context)
|
||||
private static Operand GetBfmN(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeBfm op = (OpCodeBfm)context.CurrOp;
|
||||
|
||||
|
|
|
@ -12,10 +12,10 @@ namespace ARMeilleure.Instructions
|
|||
{
|
||||
static partial class InstEmit
|
||||
{
|
||||
public static void Ccmn(EmitterContext context) => EmitCcmp(context, isNegated: true);
|
||||
public static void Ccmp(EmitterContext context) => EmitCcmp(context, isNegated: false);
|
||||
public static void Ccmn(ArmEmitterContext context) => EmitCcmp(context, isNegated: true);
|
||||
public static void Ccmp(ArmEmitterContext context) => EmitCcmp(context, isNegated: false);
|
||||
|
||||
private static void EmitCcmp(EmitterContext context, bool isNegated)
|
||||
private static void EmitCcmp(ArmEmitterContext context, bool isNegated)
|
||||
{
|
||||
OpCodeCcmp op = (OpCodeCcmp)context.CurrOp;
|
||||
|
||||
|
@ -24,10 +24,10 @@ namespace ARMeilleure.Instructions
|
|||
|
||||
EmitCondBranch(context, lblTrue, op.Cond);
|
||||
|
||||
context.Copy(GetFlag(PState.VFlag), Const((op.Nzcv >> 0) & 1));
|
||||
context.Copy(GetFlag(PState.CFlag), Const((op.Nzcv >> 1) & 1));
|
||||
context.Copy(GetFlag(PState.ZFlag), Const((op.Nzcv >> 2) & 1));
|
||||
context.Copy(GetFlag(PState.NFlag), Const((op.Nzcv >> 3) & 1));
|
||||
SetFlag(context, PState.VFlag, Const((op.Nzcv >> 0) & 1));
|
||||
SetFlag(context, PState.CFlag, Const((op.Nzcv >> 1) & 1));
|
||||
SetFlag(context, PState.ZFlag, Const((op.Nzcv >> 2) & 1));
|
||||
SetFlag(context, PState.NFlag, Const((op.Nzcv >> 3) & 1));
|
||||
|
||||
context.Branch(lblEnd);
|
||||
|
||||
|
|
|
@ -18,12 +18,12 @@ namespace ARMeilleure.Instructions
|
|||
Negate
|
||||
}
|
||||
|
||||
public static void Csel(EmitterContext context) => EmitCsel(context, CselOperation.None);
|
||||
public static void Csinc(EmitterContext context) => EmitCsel(context, CselOperation.Increment);
|
||||
public static void Csinv(EmitterContext context) => EmitCsel(context, CselOperation.Invert);
|
||||
public static void Csneg(EmitterContext context) => EmitCsel(context, CselOperation.Negate);
|
||||
public static void Csel(ArmEmitterContext context) => EmitCsel(context, CselOperation.None);
|
||||
public static void Csinc(ArmEmitterContext context) => EmitCsel(context, CselOperation.Increment);
|
||||
public static void Csinv(ArmEmitterContext context) => EmitCsel(context, CselOperation.Invert);
|
||||
public static void Csneg(ArmEmitterContext context) => EmitCsel(context, CselOperation.Negate);
|
||||
|
||||
private static void EmitCsel(EmitterContext context, CselOperation cselOp)
|
||||
private static void EmitCsel(ArmEmitterContext context, CselOperation cselOp)
|
||||
{
|
||||
OpCodeCsel op = (OpCodeCsel)context.CurrOp;
|
||||
|
||||
|
|
|
@ -9,10 +9,10 @@ namespace ARMeilleure.Instructions
|
|||
{
|
||||
static partial class InstEmit
|
||||
{
|
||||
public static void Sdiv(EmitterContext context) => EmitDiv(context, unsigned: false);
|
||||
public static void Udiv(EmitterContext context) => EmitDiv(context, unsigned: true);
|
||||
public static void Sdiv(ArmEmitterContext context) => EmitDiv(context, unsigned: false);
|
||||
public static void Udiv(ArmEmitterContext context) => EmitDiv(context, unsigned: true);
|
||||
|
||||
private static void EmitDiv(EmitterContext context, bool unsigned)
|
||||
private static void EmitDiv(ArmEmitterContext context, bool unsigned)
|
||||
{
|
||||
OpCodeAluBinary op = (OpCodeAluBinary)context.CurrOp;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using ARMeilleure.Decoders;
|
||||
using ARMeilleure.Translation;
|
||||
using System.Reflection;
|
||||
using System;
|
||||
|
||||
using static ARMeilleure.IntermediateRepresentation.OperandHelper;
|
||||
|
||||
|
@ -8,25 +8,23 @@ namespace ARMeilleure.Instructions
|
|||
{
|
||||
static partial class InstEmit
|
||||
{
|
||||
public static void Brk(EmitterContext context)
|
||||
public static void Brk(ArmEmitterContext context)
|
||||
{
|
||||
EmitExceptionCall(context, nameof(NativeInterface.Break));
|
||||
EmitExceptionCall(context, NativeInterface.Break);
|
||||
}
|
||||
|
||||
public static void Svc(EmitterContext context)
|
||||
public static void Svc(ArmEmitterContext context)
|
||||
{
|
||||
EmitExceptionCall(context, nameof(NativeInterface.SupervisorCall));
|
||||
EmitExceptionCall(context, NativeInterface.SupervisorCall);
|
||||
}
|
||||
|
||||
private static void EmitExceptionCall(EmitterContext context, string mthdName)
|
||||
private static void EmitExceptionCall(ArmEmitterContext context, _Void_U64_S32 func)
|
||||
{
|
||||
OpCodeException op = (OpCodeException)context.CurrOp;
|
||||
|
||||
MethodInfo info = typeof(NativeInterface).GetMethod(mthdName);
|
||||
|
||||
context.StoreToContext();
|
||||
|
||||
context.Call(info, Const(op.Address), Const(op.Id));
|
||||
context.Call(func, Const(op.Address), Const(op.Id));
|
||||
|
||||
context.LoadFromContext();
|
||||
|
||||
|
@ -36,15 +34,15 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Und(EmitterContext context)
|
||||
public static void Und(ArmEmitterContext context)
|
||||
{
|
||||
OpCode op = context.CurrOp;
|
||||
|
||||
MethodInfo info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.Undefined));
|
||||
Delegate dlg = new _Void_U64_S32(NativeInterface.Undefined);
|
||||
|
||||
context.StoreToContext();
|
||||
|
||||
context.Call(info, Const(op.Address), Const(op.RawOpCode));
|
||||
context.Call(dlg, Const(op.Address), Const(op.RawOpCode));
|
||||
|
||||
context.LoadFromContext();
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ namespace ARMeilleure.Instructions
|
|||
{
|
||||
static partial class InstEmit
|
||||
{
|
||||
public static void B(EmitterContext context)
|
||||
public static void B(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeBImmAl op = (OpCodeBImmAl)context.CurrOp;
|
||||
|
||||
|
@ -25,14 +25,14 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void B_Cond(EmitterContext context)
|
||||
public static void B_Cond(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeBImmCond op = (OpCodeBImmCond)context.CurrOp;
|
||||
|
||||
EmitBranch(context, op.Cond);
|
||||
}
|
||||
|
||||
public static void Bl(EmitterContext context)
|
||||
public static void Bl(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeBImmAl op = (OpCodeBImmAl)context.CurrOp;
|
||||
|
||||
|
@ -41,7 +41,7 @@ namespace ARMeilleure.Instructions
|
|||
EmitCall(context, (ulong)op.Immediate);
|
||||
}
|
||||
|
||||
public static void Blr(EmitterContext context)
|
||||
public static void Blr(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeBReg op = (OpCodeBReg)context.CurrOp;
|
||||
|
||||
|
@ -52,32 +52,32 @@ namespace ARMeilleure.Instructions
|
|||
EmitVirtualCall(context, n);
|
||||
}
|
||||
|
||||
public static void Br(EmitterContext context)
|
||||
public static void Br(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeBReg op = (OpCodeBReg)context.CurrOp;
|
||||
|
||||
EmitVirtualJump(context, GetIntOrZR(context, op.Rn));
|
||||
}
|
||||
|
||||
public static void Cbnz(EmitterContext context) => EmitCb(context, onNotZero: true);
|
||||
public static void Cbz(EmitterContext context) => EmitCb(context, onNotZero: false);
|
||||
public static void Cbnz(ArmEmitterContext context) => EmitCb(context, onNotZero: true);
|
||||
public static void Cbz(ArmEmitterContext context) => EmitCb(context, onNotZero: false);
|
||||
|
||||
private static void EmitCb(EmitterContext context, bool onNotZero)
|
||||
private static void EmitCb(ArmEmitterContext context, bool onNotZero)
|
||||
{
|
||||
OpCodeBImmCmp op = (OpCodeBImmCmp)context.CurrOp;
|
||||
|
||||
EmitBranch(context, GetIntOrZR(context, op.Rt), onNotZero);
|
||||
}
|
||||
|
||||
public static void Ret(EmitterContext context)
|
||||
public static void Ret(ArmEmitterContext context)
|
||||
{
|
||||
context.Return(GetIntOrZR(context, RegisterAlias.Lr));
|
||||
}
|
||||
|
||||
public static void Tbnz(EmitterContext context) => EmitTb(context, onNotZero: true);
|
||||
public static void Tbz(EmitterContext context) => EmitTb(context, onNotZero: false);
|
||||
public static void Tbnz(ArmEmitterContext context) => EmitTb(context, onNotZero: true);
|
||||
public static void Tbz(ArmEmitterContext context) => EmitTb(context, onNotZero: false);
|
||||
|
||||
private static void EmitTb(EmitterContext context, bool onNotZero)
|
||||
private static void EmitTb(ArmEmitterContext context, bool onNotZero)
|
||||
{
|
||||
OpCodeBImmTest op = (OpCodeBImmTest)context.CurrOp;
|
||||
|
||||
|
@ -86,7 +86,7 @@ namespace ARMeilleure.Instructions
|
|||
EmitBranch(context, value, onNotZero);
|
||||
}
|
||||
|
||||
private static void EmitBranch(EmitterContext context, Condition cond)
|
||||
private static void EmitBranch(ArmEmitterContext context, Condition cond)
|
||||
{
|
||||
OpCodeBImm op = (OpCodeBImm)context.CurrOp;
|
||||
|
||||
|
@ -113,7 +113,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
private static void EmitBranch(EmitterContext context, Operand value, bool onNotZero)
|
||||
private static void EmitBranch(ArmEmitterContext context, Operand value, bool onNotZero)
|
||||
{
|
||||
OpCodeBImm op = (OpCodeBImm)context.CurrOp;
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ namespace ARMeilleure.Instructions
|
|||
{
|
||||
static class InstEmitFlowHelper
|
||||
{
|
||||
public static void EmitCondBranch(EmitterContext context, Operand target, Condition cond)
|
||||
public static void EmitCondBranch(ArmEmitterContext context, Operand target, Condition cond)
|
||||
{
|
||||
if (cond != Condition.Al)
|
||||
{
|
||||
|
@ -22,8 +22,15 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static Operand GetCondTrue(EmitterContext context, Condition condition)
|
||||
public static Operand GetCondTrue(ArmEmitterContext context, Condition condition)
|
||||
{
|
||||
Operand cmpResult = context.TryGetComparisonResult(condition);
|
||||
|
||||
if (cmpResult != null)
|
||||
{
|
||||
return cmpResult;
|
||||
}
|
||||
|
||||
Operand value = Const(1);
|
||||
|
||||
Operand Inverse(Operand val)
|
||||
|
@ -131,27 +138,27 @@ namespace ARMeilleure.Instructions
|
|||
return value;
|
||||
}
|
||||
|
||||
public static void EmitCall(EmitterContext context, ulong immediate)
|
||||
public static void EmitCall(ArmEmitterContext context, ulong immediate)
|
||||
{
|
||||
context.Return(Const(immediate));
|
||||
}
|
||||
|
||||
public static void EmitVirtualCall(EmitterContext context, Operand target)
|
||||
public static void EmitVirtualCall(ArmEmitterContext context, Operand target)
|
||||
{
|
||||
EmitVirtualCallOrJump(context, target, isJump: false);
|
||||
}
|
||||
|
||||
public static void EmitVirtualJump(EmitterContext context, Operand target)
|
||||
public static void EmitVirtualJump(ArmEmitterContext context, Operand target)
|
||||
{
|
||||
EmitVirtualCallOrJump(context, target, isJump: true);
|
||||
}
|
||||
|
||||
private static void EmitVirtualCallOrJump(EmitterContext context, Operand target, bool isJump)
|
||||
private static void EmitVirtualCallOrJump(ArmEmitterContext context, Operand target, bool isJump)
|
||||
{
|
||||
context.Return(target);
|
||||
}
|
||||
|
||||
private static void EmitContinueOrReturnCheck(EmitterContext context, Operand retVal)
|
||||
private static void EmitContinueOrReturnCheck(ArmEmitterContext context, Operand retVal)
|
||||
{
|
||||
//Note: The return value of the called method will be placed
|
||||
//at the Stack, the return value is always a Int64 with the
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
using ARMeilleure.Decoders;
|
||||
using ARMeilleure.IntermediateRepresentation;
|
||||
using ARMeilleure.Translation;
|
||||
using System.Reflection;
|
||||
using System;
|
||||
|
||||
using static ARMeilleure.Instructions.InstEmitHelper;
|
||||
|
||||
|
@ -9,56 +9,54 @@ namespace ARMeilleure.Instructions
|
|||
{
|
||||
static partial class InstEmit
|
||||
{
|
||||
public static void Crc32b(EmitterContext context)
|
||||
public static void Crc32b(ArmEmitterContext context)
|
||||
{
|
||||
EmitCrc32Call(context, nameof(SoftFallback.Crc32b));
|
||||
EmitCrc32Call(context, new _U32_U32_U8(SoftFallback.Crc32b));
|
||||
}
|
||||
|
||||
public static void Crc32h(EmitterContext context)
|
||||
public static void Crc32h(ArmEmitterContext context)
|
||||
{
|
||||
EmitCrc32Call(context, nameof(SoftFallback.Crc32h));
|
||||
EmitCrc32Call(context, new _U32_U32_U16(SoftFallback.Crc32h));
|
||||
}
|
||||
|
||||
public static void Crc32w(EmitterContext context)
|
||||
public static void Crc32w(ArmEmitterContext context)
|
||||
{
|
||||
EmitCrc32Call(context, nameof(SoftFallback.Crc32w));
|
||||
EmitCrc32Call(context, new _U32_U32_U32(SoftFallback.Crc32w));
|
||||
}
|
||||
|
||||
public static void Crc32x(EmitterContext context)
|
||||
public static void Crc32x(ArmEmitterContext context)
|
||||
{
|
||||
EmitCrc32Call(context, nameof(SoftFallback.Crc32x));
|
||||
EmitCrc32Call(context, new _U32_U32_U64(SoftFallback.Crc32x));
|
||||
}
|
||||
|
||||
public static void Crc32cb(EmitterContext context)
|
||||
public static void Crc32cb(ArmEmitterContext context)
|
||||
{
|
||||
EmitCrc32Call(context, nameof(SoftFallback.Crc32cb));
|
||||
EmitCrc32Call(context, new _U32_U32_U8(SoftFallback.Crc32cb));
|
||||
}
|
||||
|
||||
public static void Crc32ch(EmitterContext context)
|
||||
public static void Crc32ch(ArmEmitterContext context)
|
||||
{
|
||||
EmitCrc32Call(context, nameof(SoftFallback.Crc32ch));
|
||||
EmitCrc32Call(context, new _U32_U32_U16(SoftFallback.Crc32ch));
|
||||
}
|
||||
|
||||
public static void Crc32cw(EmitterContext context)
|
||||
public static void Crc32cw(ArmEmitterContext context)
|
||||
{
|
||||
EmitCrc32Call(context, nameof(SoftFallback.Crc32cw));
|
||||
EmitCrc32Call(context, new _U32_U32_U32(SoftFallback.Crc32cw));
|
||||
}
|
||||
|
||||
public static void Crc32cx(EmitterContext context)
|
||||
public static void Crc32cx(ArmEmitterContext context)
|
||||
{
|
||||
EmitCrc32Call(context, nameof(SoftFallback.Crc32cx));
|
||||
EmitCrc32Call(context, new _U32_U32_U64(SoftFallback.Crc32cx));
|
||||
}
|
||||
|
||||
private static void EmitCrc32Call(EmitterContext context, string name)
|
||||
private static void EmitCrc32Call(ArmEmitterContext context, Delegate dlg)
|
||||
{
|
||||
OpCodeAluBinary op = (OpCodeAluBinary)context.CurrOp;
|
||||
|
||||
MethodInfo info = typeof(SoftFallback).GetMethod(name);
|
||||
|
||||
Operand n = GetIntOrZR(context, op.Rn);
|
||||
Operand m = GetIntOrZR(context, op.Rm);
|
||||
|
||||
Operand d = context.Call(info, n, m);
|
||||
Operand d = context.Call(dlg, n, m);
|
||||
|
||||
SetIntOrZR(context, op.Rd, d);
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ using ARMeilleure.IntermediateRepresentation;
|
|||
using ARMeilleure.State;
|
||||
using ARMeilleure.Translation;
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
using static ARMeilleure.IntermediateRepresentation.OperandHelper;
|
||||
|
||||
|
@ -16,7 +15,7 @@ namespace ARMeilleure.Instructions
|
|||
return op is OpCodeT16;
|
||||
}
|
||||
|
||||
public static Operand GetExtendedM(EmitterContext context, int rm, IntType type)
|
||||
public static Operand GetExtendedM(ArmEmitterContext context, int rm, IntType type)
|
||||
{
|
||||
Operand value = GetIntOrZR(context, rm);
|
||||
|
||||
|
@ -34,7 +33,7 @@ namespace ARMeilleure.Instructions
|
|||
return value;
|
||||
}
|
||||
|
||||
public static Operand GetIntA32(EmitterContext context, int register)
|
||||
public static Operand GetIntA32(ArmEmitterContext context, int register)
|
||||
{
|
||||
if (register == RegisterAlias.Aarch32Pc)
|
||||
{
|
||||
|
@ -132,7 +131,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static Operand GetIntOrZR(EmitterContext context, int regIndex)
|
||||
public static Operand GetIntOrZR(ArmEmitterContext context, int regIndex)
|
||||
{
|
||||
if (regIndex == RegisterConsts.ZeroIndex)
|
||||
{
|
||||
|
@ -146,9 +145,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static bool FullDebug = false;
|
||||
|
||||
public static void SetIntOrZR(EmitterContext context, int regIndex, Operand value)
|
||||
public static void SetIntOrZR(ArmEmitterContext context, int regIndex, Operand value)
|
||||
{
|
||||
if (regIndex == RegisterConsts.ZeroIndex)
|
||||
{
|
||||
|
@ -158,7 +155,7 @@ namespace ARMeilleure.Instructions
|
|||
SetIntOrSP(context, regIndex, value);
|
||||
}
|
||||
|
||||
public static Operand GetIntOrSP(EmitterContext context, int regIndex)
|
||||
public static Operand GetIntOrSP(ArmEmitterContext context, int regIndex)
|
||||
{
|
||||
Operand value = Register(regIndex, RegisterType.Integer, OperandType.I64);
|
||||
|
||||
|
@ -170,7 +167,7 @@ namespace ARMeilleure.Instructions
|
|||
return value;
|
||||
}
|
||||
|
||||
public static void SetIntOrSP(EmitterContext context, int regIndex, Operand value)
|
||||
public static void SetIntOrSP(ArmEmitterContext context, int regIndex, Operand value)
|
||||
{
|
||||
Operand reg = Register(regIndex, RegisterType.Integer, OperandType.I64);
|
||||
|
||||
|
@ -191,5 +188,12 @@ namespace ARMeilleure.Instructions
|
|||
{
|
||||
return Register((int)stateFlag, RegisterType.Flag, OperandType.I32);
|
||||
}
|
||||
|
||||
public static void SetFlag(ArmEmitterContext context, PState stateFlag, Operand value)
|
||||
{
|
||||
context.Copy(GetFlag(stateFlag), value);
|
||||
|
||||
context.MarkFlagSet(stateFlag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,14 +10,14 @@ namespace ARMeilleure.Instructions
|
|||
{
|
||||
static partial class InstEmit
|
||||
{
|
||||
public static void Adr(EmitterContext context)
|
||||
public static void Adr(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeAdr op = (OpCodeAdr)context.CurrOp;
|
||||
|
||||
SetIntOrZR(context, op.Rd, Const(op.Address + (ulong)op.Immediate));
|
||||
}
|
||||
|
||||
public static void Adrp(EmitterContext context)
|
||||
public static void Adrp(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeAdr op = (OpCodeAdr)context.CurrOp;
|
||||
|
||||
|
@ -26,10 +26,10 @@ namespace ARMeilleure.Instructions
|
|||
SetIntOrZR(context, op.Rd, Const(address));
|
||||
}
|
||||
|
||||
public static void Ldr(EmitterContext context) => EmitLdr(context, signed: false);
|
||||
public static void Ldrs(EmitterContext context) => EmitLdr(context, signed: true);
|
||||
public static void Ldr(ArmEmitterContext context) => EmitLdr(context, signed: false);
|
||||
public static void Ldrs(ArmEmitterContext context) => EmitLdr(context, signed: true);
|
||||
|
||||
private static void EmitLdr(EmitterContext context, bool signed)
|
||||
private static void EmitLdr(ArmEmitterContext context, bool signed)
|
||||
{
|
||||
OpCodeMem op = (OpCodeMem)context.CurrOp;
|
||||
|
||||
|
@ -51,7 +51,7 @@ namespace ARMeilleure.Instructions
|
|||
EmitWBackIfNeeded(context, address);
|
||||
}
|
||||
|
||||
public static void Ldr_Literal(EmitterContext context)
|
||||
public static void Ldr_Literal(ArmEmitterContext context)
|
||||
{
|
||||
IOpCodeLit op = (IOpCodeLit)context.CurrOp;
|
||||
|
||||
|
@ -70,7 +70,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Ldp(EmitterContext context)
|
||||
public static void Ldp(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeMemPair op = (OpCodeMemPair)context.CurrOp;
|
||||
|
||||
|
@ -96,7 +96,7 @@ namespace ARMeilleure.Instructions
|
|||
EmitWBackIfNeeded(context, address);
|
||||
}
|
||||
|
||||
public static void Str(EmitterContext context)
|
||||
public static void Str(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeMem op = (OpCodeMem)context.CurrOp;
|
||||
|
||||
|
@ -107,7 +107,7 @@ namespace ARMeilleure.Instructions
|
|||
EmitWBackIfNeeded(context, address);
|
||||
}
|
||||
|
||||
public static void Stp(EmitterContext context)
|
||||
public static void Stp(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeMemPair op = (OpCodeMemPair)context.CurrOp;
|
||||
|
||||
|
@ -121,7 +121,7 @@ namespace ARMeilleure.Instructions
|
|||
EmitWBackIfNeeded(context, address);
|
||||
}
|
||||
|
||||
private static Operand GetAddress(EmitterContext context)
|
||||
private static Operand GetAddress(ArmEmitterContext context)
|
||||
{
|
||||
Operand address = null;
|
||||
|
||||
|
@ -160,7 +160,7 @@ namespace ARMeilleure.Instructions
|
|||
return address;
|
||||
}
|
||||
|
||||
private static void EmitWBackIfNeeded(EmitterContext context, Operand address)
|
||||
private static void EmitWBackIfNeeded(ArmEmitterContext context, Operand address)
|
||||
{
|
||||
//Check whenever the current OpCode has post-indexed write back, if so write it.
|
||||
if (context.CurrOp is OpCodeMemImm op && op.WBack)
|
||||
|
|
|
@ -3,7 +3,6 @@ using ARMeilleure.IntermediateRepresentation;
|
|||
using ARMeilleure.Translation;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
|
||||
using static ARMeilleure.Instructions.InstEmitHelper;
|
||||
using static ARMeilleure.IntermediateRepresentation.OperandHelper;
|
||||
|
@ -21,33 +20,31 @@ namespace ARMeilleure.Instructions
|
|||
OrderedEx = Ordered | Exclusive
|
||||
}
|
||||
|
||||
public static void Clrex(EmitterContext context)
|
||||
public static void Clrex(ArmEmitterContext context)
|
||||
{
|
||||
MethodInfo info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.ClearExclusive));
|
||||
|
||||
context.Call(info);
|
||||
context.Call(new _Void(NativeInterface.ClearExclusive));
|
||||
}
|
||||
|
||||
public static void Dmb(EmitterContext context) => EmitBarrier(context);
|
||||
public static void Dsb(EmitterContext context) => EmitBarrier(context);
|
||||
public static void Dmb(ArmEmitterContext context) => EmitBarrier(context);
|
||||
public static void Dsb(ArmEmitterContext context) => EmitBarrier(context);
|
||||
|
||||
public static void Ldar(EmitterContext context) => EmitLdr(context, AccessType.Ordered);
|
||||
public static void Ldaxr(EmitterContext context) => EmitLdr(context, AccessType.OrderedEx);
|
||||
public static void Ldxr(EmitterContext context) => EmitLdr(context, AccessType.Exclusive);
|
||||
public static void Ldxp(EmitterContext context) => EmitLdp(context, AccessType.Exclusive);
|
||||
public static void Ldaxp(EmitterContext context) => EmitLdp(context, AccessType.OrderedEx);
|
||||
public static void Ldar(ArmEmitterContext context) => EmitLdr(context, AccessType.Ordered);
|
||||
public static void Ldaxr(ArmEmitterContext context) => EmitLdr(context, AccessType.OrderedEx);
|
||||
public static void Ldxr(ArmEmitterContext context) => EmitLdr(context, AccessType.Exclusive);
|
||||
public static void Ldxp(ArmEmitterContext context) => EmitLdp(context, AccessType.Exclusive);
|
||||
public static void Ldaxp(ArmEmitterContext context) => EmitLdp(context, AccessType.OrderedEx);
|
||||
|
||||
private static void EmitLdr(EmitterContext context, AccessType accType)
|
||||
private static void EmitLdr(ArmEmitterContext context, AccessType accType)
|
||||
{
|
||||
EmitLoadEx(context, accType, pair: false);
|
||||
}
|
||||
|
||||
private static void EmitLdp(EmitterContext context, AccessType accType)
|
||||
private static void EmitLdp(ArmEmitterContext context, AccessType accType)
|
||||
{
|
||||
EmitLoadEx(context, accType, pair: true);
|
||||
}
|
||||
|
||||
private static void EmitLoadEx(EmitterContext context, AccessType accType, bool pair)
|
||||
private static void EmitLoadEx(ArmEmitterContext context, AccessType accType, bool pair)
|
||||
{
|
||||
OpCodeMemEx op = (OpCodeMemEx)context.CurrOp;
|
||||
|
||||
|
@ -105,63 +102,61 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
|
||||
private static Operand EmitLoad(
|
||||
EmitterContext context,
|
||||
ArmEmitterContext context,
|
||||
Operand address,
|
||||
bool exclusive,
|
||||
int size)
|
||||
{
|
||||
string fallbackMethodName = null;
|
||||
Delegate fallbackMethodDlg = null;
|
||||
|
||||
if (exclusive)
|
||||
{
|
||||
switch (size)
|
||||
{
|
||||
case 0: fallbackMethodName = nameof(NativeInterface.ReadByteExclusive); break;
|
||||
case 1: fallbackMethodName = nameof(NativeInterface.ReadUInt16Exclusive); break;
|
||||
case 2: fallbackMethodName = nameof(NativeInterface.ReadUInt32Exclusive); break;
|
||||
case 3: fallbackMethodName = nameof(NativeInterface.ReadUInt64Exclusive); break;
|
||||
case 4: fallbackMethodName = nameof(NativeInterface.ReadVector128Exclusive); break;
|
||||
case 0: fallbackMethodDlg = new _U8_U64 (NativeInterface.ReadByteExclusive); break;
|
||||
case 1: fallbackMethodDlg = new _U16_U64 (NativeInterface.ReadUInt16Exclusive); break;
|
||||
case 2: fallbackMethodDlg = new _U32_U64 (NativeInterface.ReadUInt32Exclusive); break;
|
||||
case 3: fallbackMethodDlg = new _U64_U64 (NativeInterface.ReadUInt64Exclusive); break;
|
||||
case 4: fallbackMethodDlg = new _V128_U64(NativeInterface.ReadVector128Exclusive); break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (size)
|
||||
{
|
||||
case 0: fallbackMethodName = nameof(NativeInterface.ReadByte); break;
|
||||
case 1: fallbackMethodName = nameof(NativeInterface.ReadUInt16); break;
|
||||
case 2: fallbackMethodName = nameof(NativeInterface.ReadUInt32); break;
|
||||
case 3: fallbackMethodName = nameof(NativeInterface.ReadUInt64); break;
|
||||
case 4: fallbackMethodName = nameof(NativeInterface.ReadVector128); break;
|
||||
case 0: fallbackMethodDlg = new _U8_U64 (NativeInterface.ReadByte); break;
|
||||
case 1: fallbackMethodDlg = new _U16_U64 (NativeInterface.ReadUInt16); break;
|
||||
case 2: fallbackMethodDlg = new _U32_U64 (NativeInterface.ReadUInt32); break;
|
||||
case 3: fallbackMethodDlg = new _U64_U64 (NativeInterface.ReadUInt64); break;
|
||||
case 4: fallbackMethodDlg = new _V128_U64(NativeInterface.ReadVector128); break;
|
||||
}
|
||||
}
|
||||
|
||||
MethodInfo info = typeof(NativeInterface).GetMethod(fallbackMethodName);
|
||||
|
||||
return context.Call(info, address);
|
||||
return context.Call(fallbackMethodDlg, address);
|
||||
}
|
||||
|
||||
public static void Pfrm(EmitterContext context)
|
||||
public static void Pfrm(ArmEmitterContext context)
|
||||
{
|
||||
//Memory Prefetch, execute as no-op.
|
||||
}
|
||||
|
||||
public static void Stlr(EmitterContext context) => EmitStr(context, AccessType.Ordered);
|
||||
public static void Stlxr(EmitterContext context) => EmitStr(context, AccessType.OrderedEx);
|
||||
public static void Stxr(EmitterContext context) => EmitStr(context, AccessType.Exclusive);
|
||||
public static void Stxp(EmitterContext context) => EmitStp(context, AccessType.Exclusive);
|
||||
public static void Stlxp(EmitterContext context) => EmitStp(context, AccessType.OrderedEx);
|
||||
public static void Stlr(ArmEmitterContext context) => EmitStr(context, AccessType.Ordered);
|
||||
public static void Stlxr(ArmEmitterContext context) => EmitStr(context, AccessType.OrderedEx);
|
||||
public static void Stxr(ArmEmitterContext context) => EmitStr(context, AccessType.Exclusive);
|
||||
public static void Stxp(ArmEmitterContext context) => EmitStp(context, AccessType.Exclusive);
|
||||
public static void Stlxp(ArmEmitterContext context) => EmitStp(context, AccessType.OrderedEx);
|
||||
|
||||
private static void EmitStr(EmitterContext context, AccessType accType)
|
||||
private static void EmitStr(ArmEmitterContext context, AccessType accType)
|
||||
{
|
||||
EmitStoreEx(context, accType, pair: false);
|
||||
}
|
||||
|
||||
private static void EmitStp(EmitterContext context, AccessType accType)
|
||||
private static void EmitStp(ArmEmitterContext context, AccessType accType)
|
||||
{
|
||||
EmitStoreEx(context, accType, pair: true);
|
||||
}
|
||||
|
||||
private static void EmitStoreEx(EmitterContext context, AccessType accType, bool pair)
|
||||
private static void EmitStoreEx(ArmEmitterContext context, AccessType accType, bool pair)
|
||||
{
|
||||
OpCodeMemEx op = (OpCodeMemEx)context.CurrOp;
|
||||
|
||||
|
@ -213,7 +208,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
|
||||
private static Operand EmitStore(
|
||||
EmitterContext context,
|
||||
ArmEmitterContext context,
|
||||
Operand address,
|
||||
Operand value,
|
||||
bool exclusive,
|
||||
|
@ -224,43 +219,39 @@ namespace ARMeilleure.Instructions
|
|||
value = context.ConvertI64ToI32(value);
|
||||
}
|
||||
|
||||
string fallbackMethodName = null;
|
||||
Delegate fallbackMethodDlg = null;
|
||||
|
||||
if (exclusive)
|
||||
{
|
||||
switch (size)
|
||||
{
|
||||
case 0: fallbackMethodName = nameof(NativeInterface.WriteByteExclusive); break;
|
||||
case 1: fallbackMethodName = nameof(NativeInterface.WriteUInt16Exclusive); break;
|
||||
case 2: fallbackMethodName = nameof(NativeInterface.WriteUInt32Exclusive); break;
|
||||
case 3: fallbackMethodName = nameof(NativeInterface.WriteUInt64Exclusive); break;
|
||||
case 4: fallbackMethodName = nameof(NativeInterface.WriteVector128Exclusive); break;
|
||||
case 0: fallbackMethodDlg = new _S32_U64_U8 (NativeInterface.WriteByteExclusive); break;
|
||||
case 1: fallbackMethodDlg = new _S32_U64_U16 (NativeInterface.WriteUInt16Exclusive); break;
|
||||
case 2: fallbackMethodDlg = new _S32_U64_U32 (NativeInterface.WriteUInt32Exclusive); break;
|
||||
case 3: fallbackMethodDlg = new _S32_U64_U64 (NativeInterface.WriteUInt64Exclusive); break;
|
||||
case 4: fallbackMethodDlg = new _S32_U64_V128(NativeInterface.WriteVector128Exclusive); break;
|
||||
}
|
||||
|
||||
MethodInfo info = typeof(NativeInterface).GetMethod(fallbackMethodName);
|
||||
|
||||
return context.Call(info, address, value);
|
||||
return context.Call(fallbackMethodDlg, address, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (size)
|
||||
{
|
||||
case 0: fallbackMethodName = nameof(NativeInterface.WriteByte); break;
|
||||
case 1: fallbackMethodName = nameof(NativeInterface.WriteUInt16); break;
|
||||
case 2: fallbackMethodName = nameof(NativeInterface.WriteUInt32); break;
|
||||
case 3: fallbackMethodName = nameof(NativeInterface.WriteUInt64); break;
|
||||
case 4: fallbackMethodName = nameof(NativeInterface.WriteVector128); break;
|
||||
case 0: fallbackMethodDlg = new _Void_U64_U8 (NativeInterface.WriteByte); break;
|
||||
case 1: fallbackMethodDlg = new _Void_U64_U16 (NativeInterface.WriteUInt16); break;
|
||||
case 2: fallbackMethodDlg = new _Void_U64_U32 (NativeInterface.WriteUInt32); break;
|
||||
case 3: fallbackMethodDlg = new _Void_U64_U64 (NativeInterface.WriteUInt64); break;
|
||||
case 4: fallbackMethodDlg = new _Void_U64_V128(NativeInterface.WriteVector128); break;
|
||||
}
|
||||
|
||||
MethodInfo info = typeof(NativeInterface).GetMethod(fallbackMethodName);
|
||||
|
||||
context.Call(info, address, value);
|
||||
context.Call(fallbackMethodDlg, address, value);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static void EmitBarrier(EmitterContext context)
|
||||
private static void EmitBarrier(ArmEmitterContext context)
|
||||
{
|
||||
//Note: This barrier is most likely not necessary, and probably
|
||||
//doesn't make any difference since we need to do a ton of stuff
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
using ARMeilleure.Decoders;
|
||||
using ARMeilleure.IntermediateRepresentation;
|
||||
using ARMeilleure.Memory;
|
||||
using ARMeilleure.State;
|
||||
using ARMeilleure.Translation;
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
using static ARMeilleure.Instructions.InstEmitHelper;
|
||||
using static ARMeilleure.IntermediateRepresentation.OperandHelper;
|
||||
|
@ -20,22 +18,22 @@ namespace ARMeilleure.Instructions
|
|||
Sx64
|
||||
}
|
||||
|
||||
public static void EmitLoadZx(EmitterContext context, Operand address, int rt, int size)
|
||||
public static void EmitLoadZx(ArmEmitterContext context, Operand address, int rt, int size)
|
||||
{
|
||||
EmitLoad(context, address, Extension.Zx, rt, size);
|
||||
}
|
||||
|
||||
public static void EmitLoadSx32(EmitterContext context, Operand address, int rt, int size)
|
||||
public static void EmitLoadSx32(ArmEmitterContext context, Operand address, int rt, int size)
|
||||
{
|
||||
EmitLoad(context, address, Extension.Sx32, rt, size);
|
||||
}
|
||||
|
||||
public static void EmitLoadSx64(EmitterContext context, Operand address, int rt, int size)
|
||||
public static void EmitLoadSx64(ArmEmitterContext context, Operand address, int rt, int size)
|
||||
{
|
||||
EmitLoad(context, address, Extension.Sx64, rt, size);
|
||||
}
|
||||
|
||||
private static void EmitLoad(EmitterContext context, Operand address, Extension ext, int rt, int size)
|
||||
private static void EmitLoad(ArmEmitterContext context, Operand address, Extension ext, int rt, int size)
|
||||
{
|
||||
bool isSimd = IsSimd(context);
|
||||
|
||||
|
@ -74,7 +72,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
|
||||
public static void EmitLoadSimd(
|
||||
EmitterContext context,
|
||||
ArmEmitterContext context,
|
||||
Operand address,
|
||||
Operand vector,
|
||||
int rt,
|
||||
|
@ -84,7 +82,7 @@ namespace ARMeilleure.Instructions
|
|||
EmitReadVector(context, address, vector, rt, elem, size);
|
||||
}
|
||||
|
||||
public static void EmitStore(EmitterContext context, Operand address, int rt, int size)
|
||||
public static void EmitStore(ArmEmitterContext context, Operand address, int rt, int size)
|
||||
{
|
||||
bool isSimd = IsSimd(context);
|
||||
|
||||
|
@ -104,7 +102,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
|
||||
public static void EmitStoreSimd(
|
||||
EmitterContext context,
|
||||
ArmEmitterContext context,
|
||||
Operand address,
|
||||
int rt,
|
||||
int elem,
|
||||
|
@ -113,14 +111,14 @@ namespace ARMeilleure.Instructions
|
|||
EmitWriteVector(context, address, rt, elem, size);
|
||||
}
|
||||
|
||||
private static bool IsSimd(EmitterContext context)
|
||||
private static bool IsSimd(ArmEmitterContext context)
|
||||
{
|
||||
return context.CurrOp is IOpCodeSimd &&
|
||||
!(context.CurrOp is OpCodeSimdMemMs ||
|
||||
context.CurrOp is OpCodeSimdMemSs);
|
||||
}
|
||||
|
||||
private static void EmitReadInt(EmitterContext context, Operand address, int rt, int size)
|
||||
private static void EmitReadInt(ArmEmitterContext context, Operand address, int rt, int size)
|
||||
{
|
||||
Operand isUnalignedAddr = EmitAddressCheck(context, address, size);
|
||||
|
||||
|
@ -167,7 +165,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
|
||||
private static void EmitReadVector(
|
||||
EmitterContext context,
|
||||
ArmEmitterContext context,
|
||||
Operand address,
|
||||
Operand vector,
|
||||
int rt,
|
||||
|
@ -222,12 +220,12 @@ namespace ARMeilleure.Instructions
|
|||
context.MarkLabel(lblEnd);
|
||||
}
|
||||
|
||||
private static Operand VectorCreate(EmitterContext context, Operand value)
|
||||
private static Operand VectorCreate(ArmEmitterContext context, Operand value)
|
||||
{
|
||||
return context.VectorInsert(context.VectorZero(), value, 0);
|
||||
}
|
||||
|
||||
private static void EmitWriteInt(EmitterContext context, Operand address, int rt, int size)
|
||||
private static void EmitWriteInt(ArmEmitterContext context, Operand address, int rt, int size)
|
||||
{
|
||||
Operand isUnalignedAddr = EmitAddressCheck(context, address, size);
|
||||
|
||||
|
@ -266,7 +264,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
|
||||
private static void EmitWriteVector(
|
||||
EmitterContext context,
|
||||
ArmEmitterContext context,
|
||||
Operand address,
|
||||
int rt,
|
||||
int elem,
|
||||
|
@ -318,7 +316,7 @@ namespace ARMeilleure.Instructions
|
|||
context.MarkLabel(lblEnd);
|
||||
}
|
||||
|
||||
private static Operand EmitAddressCheck(EmitterContext context, Operand address, int size)
|
||||
private static Operand EmitAddressCheck(ArmEmitterContext context, Operand address, int size)
|
||||
{
|
||||
long addressCheckMask = ~(context.Memory.AddressSpaceSize - 1);
|
||||
|
||||
|
@ -327,7 +325,7 @@ namespace ARMeilleure.Instructions
|
|||
return context.BitwiseAnd(address, Const(addressCheckMask));
|
||||
}
|
||||
|
||||
private static Operand EmitPtPointerLoad(EmitterContext context, Operand address, Operand lblFallbackPath)
|
||||
private static Operand EmitPtPointerLoad(ArmEmitterContext context, Operand address, Operand lblFallbackPath)
|
||||
{
|
||||
Operand pte = Const(context.Memory.PageTable.ToInt64());
|
||||
|
||||
|
@ -366,45 +364,41 @@ namespace ARMeilleure.Instructions
|
|||
return physAddr;
|
||||
}
|
||||
|
||||
private static void EmitReadIntFallback(EmitterContext context, Operand address, int rt, int size)
|
||||
private static void EmitReadIntFallback(ArmEmitterContext context, Operand address, int rt, int size)
|
||||
{
|
||||
string fallbackMethodName = null;
|
||||
Delegate fallbackMethodDlg = null;
|
||||
|
||||
switch (size)
|
||||
{
|
||||
case 0: fallbackMethodName = nameof(NativeInterface.ReadByte); break;
|
||||
case 1: fallbackMethodName = nameof(NativeInterface.ReadUInt16); break;
|
||||
case 2: fallbackMethodName = nameof(NativeInterface.ReadUInt32); break;
|
||||
case 3: fallbackMethodName = nameof(NativeInterface.ReadUInt64); break;
|
||||
case 0: fallbackMethodDlg = new _U8_U64 (NativeInterface.ReadByte); break;
|
||||
case 1: fallbackMethodDlg = new _U16_U64(NativeInterface.ReadUInt16); break;
|
||||
case 2: fallbackMethodDlg = new _U32_U64(NativeInterface.ReadUInt32); break;
|
||||
case 3: fallbackMethodDlg = new _U64_U64(NativeInterface.ReadUInt64); break;
|
||||
}
|
||||
|
||||
MethodInfo info = typeof(NativeInterface).GetMethod(fallbackMethodName);
|
||||
|
||||
SetIntOrZR(context, rt, context.Call(info, address));
|
||||
SetIntOrZR(context, rt, context.Call(fallbackMethodDlg, address));
|
||||
}
|
||||
|
||||
private static void EmitReadVectorFallback(
|
||||
EmitterContext context,
|
||||
ArmEmitterContext context,
|
||||
Operand address,
|
||||
Operand vector,
|
||||
int rt,
|
||||
int elem,
|
||||
int size)
|
||||
{
|
||||
string fallbackMethodName = null;
|
||||
Delegate fallbackMethodDlg = null;
|
||||
|
||||
switch (size)
|
||||
{
|
||||
case 0: fallbackMethodName = nameof(NativeInterface.ReadByte); break;
|
||||
case 1: fallbackMethodName = nameof(NativeInterface.ReadUInt16); break;
|
||||
case 2: fallbackMethodName = nameof(NativeInterface.ReadUInt32); break;
|
||||
case 3: fallbackMethodName = nameof(NativeInterface.ReadUInt64); break;
|
||||
case 4: fallbackMethodName = nameof(NativeInterface.ReadVector128); break;
|
||||
case 0: fallbackMethodDlg = new _U8_U64 (NativeInterface.ReadByte); break;
|
||||
case 1: fallbackMethodDlg = new _U16_U64 (NativeInterface.ReadUInt16); break;
|
||||
case 2: fallbackMethodDlg = new _U32_U64 (NativeInterface.ReadUInt32); break;
|
||||
case 3: fallbackMethodDlg = new _U64_U64 (NativeInterface.ReadUInt64); break;
|
||||
case 4: fallbackMethodDlg = new _V128_U64(NativeInterface.ReadVector128); break;
|
||||
}
|
||||
|
||||
MethodInfo info = typeof(NativeInterface).GetMethod(fallbackMethodName);
|
||||
|
||||
Operand value = context.Call(info, address);
|
||||
Operand value = context.Call(fallbackMethodDlg, address);
|
||||
|
||||
if (size < 3)
|
||||
{
|
||||
|
@ -422,20 +416,18 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(rt), value);
|
||||
}
|
||||
|
||||
private static void EmitWriteIntFallback(EmitterContext context, Operand address, int rt, int size)
|
||||
private static void EmitWriteIntFallback(ArmEmitterContext context, Operand address, int rt, int size)
|
||||
{
|
||||
string fallbackMethodName = null;
|
||||
Delegate fallbackMethodDlg = null;
|
||||
|
||||
switch (size)
|
||||
{
|
||||
case 0: fallbackMethodName = nameof(NativeInterface.WriteByte); break;
|
||||
case 1: fallbackMethodName = nameof(NativeInterface.WriteUInt16); break;
|
||||
case 2: fallbackMethodName = nameof(NativeInterface.WriteUInt32); break;
|
||||
case 3: fallbackMethodName = nameof(NativeInterface.WriteUInt64); break;
|
||||
case 0: fallbackMethodDlg = new _Void_U64_U8 (NativeInterface.WriteByte); break;
|
||||
case 1: fallbackMethodDlg = new _Void_U64_U16(NativeInterface.WriteUInt16); break;
|
||||
case 2: fallbackMethodDlg = new _Void_U64_U32(NativeInterface.WriteUInt32); break;
|
||||
case 3: fallbackMethodDlg = new _Void_U64_U64(NativeInterface.WriteUInt64); break;
|
||||
}
|
||||
|
||||
MethodInfo info = typeof(NativeInterface).GetMethod(fallbackMethodName);
|
||||
|
||||
Operand value = GetIntOrZR(context, rt);
|
||||
|
||||
if (size < 3)
|
||||
|
@ -443,29 +435,27 @@ namespace ARMeilleure.Instructions
|
|||
value = context.ConvertI64ToI32(value);
|
||||
}
|
||||
|
||||
context.Call(info, address, value);
|
||||
context.Call(fallbackMethodDlg, address, value);
|
||||
}
|
||||
|
||||
private static void EmitWriteVectorFallback(
|
||||
EmitterContext context,
|
||||
ArmEmitterContext context,
|
||||
Operand address,
|
||||
int rt,
|
||||
int elem,
|
||||
int size)
|
||||
{
|
||||
string fallbackMethodName = null;
|
||||
Delegate fallbackMethodDlg = null;
|
||||
|
||||
switch (size)
|
||||
{
|
||||
case 0: fallbackMethodName = nameof(NativeInterface.WriteByte); break;
|
||||
case 1: fallbackMethodName = nameof(NativeInterface.WriteUInt16); break;
|
||||
case 2: fallbackMethodName = nameof(NativeInterface.WriteUInt32); break;
|
||||
case 3: fallbackMethodName = nameof(NativeInterface.WriteUInt64); break;
|
||||
case 4: fallbackMethodName = nameof(NativeInterface.WriteVector128); break;
|
||||
case 0: fallbackMethodDlg = new _Void_U64_U8 (NativeInterface.WriteByte); break;
|
||||
case 1: fallbackMethodDlg = new _Void_U64_U16 (NativeInterface.WriteUInt16); break;
|
||||
case 2: fallbackMethodDlg = new _Void_U64_U32 (NativeInterface.WriteUInt32); break;
|
||||
case 3: fallbackMethodDlg = new _Void_U64_U64 (NativeInterface.WriteUInt64); break;
|
||||
case 4: fallbackMethodDlg = new _Void_U64_V128(NativeInterface.WriteVector128); break;
|
||||
}
|
||||
|
||||
MethodInfo info = typeof(NativeInterface).GetMethod(fallbackMethodName);
|
||||
|
||||
Operand value = null;
|
||||
|
||||
if (size < 4)
|
||||
|
@ -494,7 +484,7 @@ namespace ARMeilleure.Instructions
|
|||
value = GetVec(rt);
|
||||
}
|
||||
|
||||
context.Call(info, address, value);
|
||||
context.Call(fallbackMethodDlg, address, value);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,7 +9,7 @@ namespace ARMeilleure.Instructions
|
|||
{
|
||||
static partial class InstEmit
|
||||
{
|
||||
public static void Movk(EmitterContext context)
|
||||
public static void Movk(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeMov op = (OpCodeMov)context.CurrOp;
|
||||
|
||||
|
@ -24,14 +24,14 @@ namespace ARMeilleure.Instructions
|
|||
SetIntOrZR(context, op.Rd, res);
|
||||
}
|
||||
|
||||
public static void Movn(EmitterContext context)
|
||||
public static void Movn(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeMov op = (OpCodeMov)context.CurrOp;
|
||||
|
||||
SetIntOrZR(context, op.Rd, Const(op.GetOperandType(), ~op.Immediate));
|
||||
}
|
||||
|
||||
public static void Movz(EmitterContext context)
|
||||
public static void Movz(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeMov op = (OpCodeMov)context.CurrOp;
|
||||
|
||||
|
|
|
@ -9,10 +9,10 @@ namespace ARMeilleure.Instructions
|
|||
{
|
||||
static partial class InstEmit
|
||||
{
|
||||
public static void Madd(EmitterContext context) => EmitMul(context, isAdd: true);
|
||||
public static void Msub(EmitterContext context) => EmitMul(context, isAdd: false);
|
||||
public static void Madd(ArmEmitterContext context) => EmitMul(context, isAdd: true);
|
||||
public static void Msub(ArmEmitterContext context) => EmitMul(context, isAdd: false);
|
||||
|
||||
private static void EmitMul(EmitterContext context, bool isAdd)
|
||||
private static void EmitMul(ArmEmitterContext context, bool isAdd)
|
||||
{
|
||||
OpCodeMul op = (OpCodeMul)context.CurrOp;
|
||||
|
||||
|
@ -27,10 +27,10 @@ namespace ARMeilleure.Instructions
|
|||
SetIntOrZR(context, op.Rd, res);
|
||||
}
|
||||
|
||||
public static void Smaddl(EmitterContext context) => EmitMull(context, MullFlags.SignedAdd);
|
||||
public static void Smsubl(EmitterContext context) => EmitMull(context, MullFlags.SignedSubtract);
|
||||
public static void Umaddl(EmitterContext context) => EmitMull(context, MullFlags.Add);
|
||||
public static void Umsubl(EmitterContext context) => EmitMull(context, MullFlags.Subtract);
|
||||
public static void Smaddl(ArmEmitterContext context) => EmitMull(context, MullFlags.SignedAdd);
|
||||
public static void Smsubl(ArmEmitterContext context) => EmitMull(context, MullFlags.SignedSubtract);
|
||||
public static void Umaddl(ArmEmitterContext context) => EmitMull(context, MullFlags.Add);
|
||||
public static void Umsubl(ArmEmitterContext context) => EmitMull(context, MullFlags.Subtract);
|
||||
|
||||
[Flags]
|
||||
private enum MullFlags
|
||||
|
@ -43,7 +43,7 @@ namespace ARMeilleure.Instructions
|
|||
SignedSubtract = Signed | Subtract
|
||||
}
|
||||
|
||||
private static void EmitMull(EmitterContext context, MullFlags flags)
|
||||
private static void EmitMull(ArmEmitterContext context, MullFlags flags)
|
||||
{
|
||||
OpCodeMul op = (OpCodeMul)context.CurrOp;
|
||||
|
||||
|
@ -73,7 +73,7 @@ namespace ARMeilleure.Instructions
|
|||
SetIntOrZR(context, op.Rd, res);
|
||||
}
|
||||
|
||||
public static void Smulh(EmitterContext context)
|
||||
public static void Smulh(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeMul op = (OpCodeMul)context.CurrOp;
|
||||
|
||||
|
@ -85,7 +85,7 @@ namespace ARMeilleure.Instructions
|
|||
SetIntOrZR(context, op.Rd, d);
|
||||
}
|
||||
|
||||
public static void Umulh(EmitterContext context)
|
||||
public static void Umulh(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeMul op = (OpCodeMul)context.CurrOp;
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -14,12 +14,12 @@ namespace ARMeilleure.Instructions
|
|||
|
||||
static partial class InstEmit
|
||||
{
|
||||
public static void Cmeq_S(EmitterContext context)
|
||||
public static void Cmeq_S(ArmEmitterContext context)
|
||||
{
|
||||
EmitCmpOp(context, (op1, op2) => context.ICompareEqual(op1, op2), scalar: true);
|
||||
}
|
||||
|
||||
public static void Cmeq_V(EmitterContext context)
|
||||
public static void Cmeq_V(ArmEmitterContext context)
|
||||
{
|
||||
if (Optimizations.UseSse41)
|
||||
{
|
||||
|
@ -54,12 +54,12 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Cmge_S(EmitterContext context)
|
||||
public static void Cmge_S(ArmEmitterContext context)
|
||||
{
|
||||
EmitCmpOp(context, (op1, op2) => context.ICompareGreaterOrEqual(op1, op2), scalar: true);
|
||||
}
|
||||
|
||||
public static void Cmge_V(EmitterContext context)
|
||||
public static void Cmge_V(ArmEmitterContext context)
|
||||
{
|
||||
if (Optimizations.UseSse42)
|
||||
{
|
||||
|
@ -98,12 +98,12 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Cmgt_S(EmitterContext context)
|
||||
public static void Cmgt_S(ArmEmitterContext context)
|
||||
{
|
||||
EmitCmpOp(context, (op1, op2) => context.ICompareGreater(op1, op2), scalar: true);
|
||||
}
|
||||
|
||||
public static void Cmgt_V(EmitterContext context)
|
||||
public static void Cmgt_V(ArmEmitterContext context)
|
||||
{
|
||||
if (Optimizations.UseSse42)
|
||||
{
|
||||
|
@ -138,12 +138,12 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Cmhi_S(EmitterContext context)
|
||||
public static void Cmhi_S(ArmEmitterContext context)
|
||||
{
|
||||
EmitCmpOp(context, (op1, op2) => context.ICompareGreaterUI(op1, op2), scalar: true);
|
||||
}
|
||||
|
||||
public static void Cmhi_V(EmitterContext context)
|
||||
public static void Cmhi_V(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
||||
|
||||
|
@ -177,12 +177,12 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Cmhs_S(EmitterContext context)
|
||||
public static void Cmhs_S(ArmEmitterContext context)
|
||||
{
|
||||
EmitCmpOp(context, (op1, op2) => context.ICompareGreaterOrEqualUI(op1, op2), scalar: true);
|
||||
}
|
||||
|
||||
public static void Cmhs_V(EmitterContext context)
|
||||
public static void Cmhs_V(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
||||
|
||||
|
@ -212,12 +212,12 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Cmle_S(EmitterContext context)
|
||||
public static void Cmle_S(ArmEmitterContext context)
|
||||
{
|
||||
EmitCmpOp(context, (op1, op2) => context.ICompareLessOrEqual(op1, op2), scalar: true);
|
||||
}
|
||||
|
||||
public static void Cmle_V(EmitterContext context)
|
||||
public static void Cmle_V(ArmEmitterContext context)
|
||||
{
|
||||
if (Optimizations.UseSse42)
|
||||
{
|
||||
|
@ -246,12 +246,12 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Cmlt_S(EmitterContext context)
|
||||
public static void Cmlt_S(ArmEmitterContext context)
|
||||
{
|
||||
EmitCmpOp(context, (op1, op2) => context.ICompareLess(op1, op2), scalar: true);
|
||||
}
|
||||
|
||||
public static void Cmlt_V(EmitterContext context)
|
||||
public static void Cmlt_V(ArmEmitterContext context)
|
||||
{
|
||||
if (Optimizations.UseSse42)
|
||||
{
|
||||
|
@ -276,27 +276,27 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Cmtst_S(EmitterContext context)
|
||||
public static void Cmtst_S(ArmEmitterContext context)
|
||||
{
|
||||
EmitCmtstOp(context, scalar: true);
|
||||
}
|
||||
|
||||
public static void Cmtst_V(EmitterContext context)
|
||||
public static void Cmtst_V(ArmEmitterContext context)
|
||||
{
|
||||
EmitCmtstOp(context, scalar: false);
|
||||
}
|
||||
|
||||
public static void Fccmp_S(EmitterContext context)
|
||||
public static void Fccmp_S(ArmEmitterContext context)
|
||||
{
|
||||
EmitFccmpOrFccmpe(context, signalNaNs: false);
|
||||
}
|
||||
|
||||
public static void Fccmpe_S(EmitterContext context)
|
||||
public static void Fccmpe_S(ArmEmitterContext context)
|
||||
{
|
||||
EmitFccmpOrFccmpe(context, signalNaNs: true);
|
||||
}
|
||||
|
||||
public static void Fcmeq_S(EmitterContext context)
|
||||
public static void Fcmeq_S(ArmEmitterContext context)
|
||||
{
|
||||
if (Optimizations.FastFP && Optimizations.UseSse2)
|
||||
{
|
||||
|
@ -304,11 +304,11 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
else
|
||||
{
|
||||
EmitCmpOpF(context, nameof(SoftFloat32.FPCompareEQ), scalar: true);
|
||||
EmitCmpOpF(context, SoftFloat32.FPCompareEQ, SoftFloat64.FPCompareEQ, scalar: true);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Fcmeq_V(EmitterContext context)
|
||||
public static void Fcmeq_V(ArmEmitterContext context)
|
||||
{
|
||||
if (Optimizations.FastFP && Optimizations.UseSse2)
|
||||
{
|
||||
|
@ -316,11 +316,11 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
else
|
||||
{
|
||||
EmitCmpOpF(context, nameof(SoftFloat32.FPCompareEQ), scalar: false);
|
||||
EmitCmpOpF(context, SoftFloat32.FPCompareEQ, SoftFloat64.FPCompareEQ, scalar: false);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Fcmge_S(EmitterContext context)
|
||||
public static void Fcmge_S(ArmEmitterContext context)
|
||||
{
|
||||
if (Optimizations.FastFP && Optimizations.UseSse2)
|
||||
{
|
||||
|
@ -328,11 +328,11 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
else
|
||||
{
|
||||
EmitCmpOpF(context, nameof(SoftFloat32.FPCompareGE), scalar: true);
|
||||
EmitCmpOpF(context, SoftFloat32.FPCompareGE, SoftFloat64.FPCompareGE, scalar: true);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Fcmge_V(EmitterContext context)
|
||||
public static void Fcmge_V(ArmEmitterContext context)
|
||||
{
|
||||
if (Optimizations.FastFP && Optimizations.UseSse2)
|
||||
{
|
||||
|
@ -340,11 +340,11 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
else
|
||||
{
|
||||
EmitCmpOpF(context, nameof(SoftFloat32.FPCompareGE), scalar: false);
|
||||
EmitCmpOpF(context, SoftFloat32.FPCompareGE, SoftFloat64.FPCompareGE, scalar: false);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Fcmgt_S(EmitterContext context)
|
||||
public static void Fcmgt_S(ArmEmitterContext context)
|
||||
{
|
||||
if (Optimizations.FastFP && Optimizations.UseSse2)
|
||||
{
|
||||
|
@ -352,11 +352,11 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
else
|
||||
{
|
||||
EmitCmpOpF(context, nameof(SoftFloat32.FPCompareGT), scalar: true);
|
||||
EmitCmpOpF(context, SoftFloat32.FPCompareGT, SoftFloat64.FPCompareGT, scalar: true);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Fcmgt_V(EmitterContext context)
|
||||
public static void Fcmgt_V(ArmEmitterContext context)
|
||||
{
|
||||
if (Optimizations.FastFP && Optimizations.UseSse2)
|
||||
{
|
||||
|
@ -364,11 +364,11 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
else
|
||||
{
|
||||
EmitCmpOpF(context, nameof(SoftFloat32.FPCompareGT), scalar: false);
|
||||
EmitCmpOpF(context, SoftFloat32.FPCompareGT, SoftFloat64.FPCompareGT, scalar: false);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Fcmle_S(EmitterContext context)
|
||||
public static void Fcmle_S(ArmEmitterContext context)
|
||||
{
|
||||
if (Optimizations.FastFP && Optimizations.UseSse2)
|
||||
{
|
||||
|
@ -376,11 +376,11 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
else
|
||||
{
|
||||
EmitCmpOpF(context, nameof(SoftFloat32.FPCompareLE), scalar: true);
|
||||
EmitCmpOpF(context, SoftFloat32.FPCompareLE, SoftFloat64.FPCompareLE, scalar: true);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Fcmle_V(EmitterContext context)
|
||||
public static void Fcmle_V(ArmEmitterContext context)
|
||||
{
|
||||
if (Optimizations.FastFP && Optimizations.UseSse2)
|
||||
{
|
||||
|
@ -388,11 +388,11 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
else
|
||||
{
|
||||
EmitCmpOpF(context, nameof(SoftFloat32.FPCompareLE), scalar: false);
|
||||
EmitCmpOpF(context, SoftFloat32.FPCompareLE, SoftFloat64.FPCompareLE, scalar: false);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Fcmlt_S(EmitterContext context)
|
||||
public static void Fcmlt_S(ArmEmitterContext context)
|
||||
{
|
||||
if (Optimizations.FastFP && Optimizations.UseSse2)
|
||||
{
|
||||
|
@ -400,11 +400,11 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
else
|
||||
{
|
||||
EmitCmpOpF(context, nameof(SoftFloat32.FPCompareLT), scalar: true);
|
||||
EmitCmpOpF(context, SoftFloat32.FPCompareLT, SoftFloat64.FPCompareLT, scalar: true);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Fcmlt_V(EmitterContext context)
|
||||
public static void Fcmlt_V(ArmEmitterContext context)
|
||||
{
|
||||
if (Optimizations.FastFP && Optimizations.UseSse2)
|
||||
{
|
||||
|
@ -412,21 +412,21 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
else
|
||||
{
|
||||
EmitCmpOpF(context, nameof(SoftFloat32.FPCompareLT), scalar: false);
|
||||
EmitCmpOpF(context, SoftFloat32.FPCompareLT, SoftFloat64.FPCompareLT, scalar: false);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Fcmp_S(EmitterContext context)
|
||||
public static void Fcmp_S(ArmEmitterContext context)
|
||||
{
|
||||
EmitFcmpOrFcmpe(context, signalNaNs: false);
|
||||
}
|
||||
|
||||
public static void Fcmpe_S(EmitterContext context)
|
||||
public static void Fcmpe_S(ArmEmitterContext context)
|
||||
{
|
||||
EmitFcmpOrFcmpe(context, signalNaNs: true);
|
||||
}
|
||||
|
||||
public static void EmitFccmpOrFccmpe(EmitterContext context, bool signalNaNs)
|
||||
public static void EmitFccmpOrFccmpe(ArmEmitterContext context, bool signalNaNs)
|
||||
{
|
||||
OpCodeSimdFcond op = (OpCodeSimdFcond)context.CurrOp;
|
||||
|
||||
|
@ -446,7 +446,7 @@ namespace ARMeilleure.Instructions
|
|||
context.MarkLabel(lblEnd);
|
||||
}
|
||||
|
||||
private static void EmitFcmpOrFcmpe(EmitterContext context, bool signalNaNs)
|
||||
private static void EmitFcmpOrFcmpe(ArmEmitterContext context, bool signalNaNs)
|
||||
{
|
||||
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
||||
|
||||
|
@ -474,10 +474,10 @@ namespace ARMeilleure.Instructions
|
|||
Operand zf = context.AddIntrinsicInt(Instruction.X86Comisseq, n, m);
|
||||
Operand nf = context.AddIntrinsicInt(Instruction.X86Comisslt, n, m);
|
||||
|
||||
context.Copy(GetFlag(PState.VFlag), Const(0));
|
||||
context.Copy(GetFlag(PState.CFlag), cf);
|
||||
context.Copy(GetFlag(PState.ZFlag), zf);
|
||||
context.Copy(GetFlag(PState.NFlag), nf);
|
||||
SetFlag(context, PState.VFlag, Const(0));
|
||||
SetFlag(context, PState.CFlag, cf);
|
||||
SetFlag(context, PState.ZFlag, zf);
|
||||
SetFlag(context, PState.NFlag, nf);
|
||||
}
|
||||
else /* if (op.Size == 1) */
|
||||
{
|
||||
|
@ -491,20 +491,20 @@ namespace ARMeilleure.Instructions
|
|||
Operand zf = context.AddIntrinsicInt(Instruction.X86Comisdeq, n, m);
|
||||
Operand nf = context.AddIntrinsicInt(Instruction.X86Comisdlt, n, m);
|
||||
|
||||
context.Copy(GetFlag(PState.VFlag), Const(0));
|
||||
context.Copy(GetFlag(PState.CFlag), cf);
|
||||
context.Copy(GetFlag(PState.ZFlag), zf);
|
||||
context.Copy(GetFlag(PState.NFlag), nf);
|
||||
SetFlag(context, PState.VFlag, Const(0));
|
||||
SetFlag(context, PState.CFlag, cf);
|
||||
SetFlag(context, PState.ZFlag, zf);
|
||||
SetFlag(context, PState.NFlag, nf);
|
||||
}
|
||||
|
||||
context.Branch(lblEnd);
|
||||
|
||||
context.MarkLabel(lblNaN);
|
||||
|
||||
context.Copy(GetFlag(PState.VFlag), Const(1));
|
||||
context.Copy(GetFlag(PState.CFlag), Const(1));
|
||||
context.Copy(GetFlag(PState.ZFlag), Const(0));
|
||||
context.Copy(GetFlag(PState.NFlag), Const(0));
|
||||
SetFlag(context, PState.VFlag, Const(1));
|
||||
SetFlag(context, PState.CFlag, Const(1));
|
||||
SetFlag(context, PState.ZFlag, Const(0));
|
||||
SetFlag(context, PState.NFlag, Const(0));
|
||||
|
||||
context.MarkLabel(lblEnd);
|
||||
}
|
||||
|
@ -524,13 +524,17 @@ namespace ARMeilleure.Instructions
|
|||
me = context.VectorExtract(type, GetVec(op.Rm), 0);
|
||||
}
|
||||
|
||||
Operand nzcv = EmitSoftFloatCall(context, nameof(SoftFloat32.FPCompare), ne, me, Const(signalNaNs));
|
||||
Delegate dlg = op.Size != 0
|
||||
? (Delegate)new _S32_F64_F64_Bool(SoftFloat64.FPCompare)
|
||||
: (Delegate)new _S32_F32_F32_Bool(SoftFloat32.FPCompare);
|
||||
|
||||
Operand nzcv = context.Call(dlg, ne, me, Const(signalNaNs));
|
||||
|
||||
EmitSetNzcv(context, nzcv);
|
||||
}
|
||||
}
|
||||
|
||||
private static void EmitSetNzcv(EmitterContext context, Operand nzcv)
|
||||
private static void EmitSetNzcv(ArmEmitterContext context, Operand nzcv)
|
||||
{
|
||||
Operand Extract(Operand value, int bit)
|
||||
{
|
||||
|
@ -544,13 +548,13 @@ namespace ARMeilleure.Instructions
|
|||
return value;
|
||||
}
|
||||
|
||||
context.Copy(GetFlag(PState.VFlag), Extract(nzcv, 0));
|
||||
context.Copy(GetFlag(PState.CFlag), Extract(nzcv, 1));
|
||||
context.Copy(GetFlag(PState.ZFlag), Extract(nzcv, 2));
|
||||
context.Copy(GetFlag(PState.NFlag), Extract(nzcv, 3));
|
||||
SetFlag(context, PState.VFlag, Extract(nzcv, 0));
|
||||
SetFlag(context, PState.CFlag, Extract(nzcv, 1));
|
||||
SetFlag(context, PState.ZFlag, Extract(nzcv, 2));
|
||||
SetFlag(context, PState.NFlag, Extract(nzcv, 3));
|
||||
}
|
||||
|
||||
private static void EmitCmpOp(EmitterContext context, Func2I emitCmp, bool scalar)
|
||||
private static void EmitCmpOp(ArmEmitterContext context, Func2I emitCmp, bool scalar)
|
||||
{
|
||||
OpCodeSimd op = (OpCodeSimd)context.CurrOp;
|
||||
|
||||
|
@ -584,7 +588,7 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
||||
private static void EmitCmtstOp(EmitterContext context, bool scalar)
|
||||
private static void EmitCmtstOp(ArmEmitterContext context, bool scalar)
|
||||
{
|
||||
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
||||
|
||||
|
@ -611,7 +615,11 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
||||
private static void EmitCmpOpF(EmitterContext context, string name, bool scalar)
|
||||
private static void EmitCmpOpF(
|
||||
ArmEmitterContext context,
|
||||
_F32_F32_F32 f32,
|
||||
_F64_F64_F64 f64,
|
||||
bool scalar)
|
||||
{
|
||||
OpCodeSimd op = (OpCodeSimd)context.CurrOp;
|
||||
|
||||
|
@ -637,7 +645,7 @@ namespace ARMeilleure.Instructions
|
|||
me = sizeF == 0 ? ConstF(0f) : ConstF(0d);
|
||||
}
|
||||
|
||||
Operand e = EmitSoftFloatCall(context, name, ne, me);
|
||||
Operand e = EmitSoftFloatCall(context, f32, f64, ne, me);
|
||||
|
||||
res = context.VectorInsert(res, e, index);
|
||||
}
|
||||
|
@ -653,7 +661,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
|
||||
private static void EmitCmpSseOrSse2OpF(
|
||||
EmitterContext context,
|
||||
ArmEmitterContext context,
|
||||
CmpCondition cond,
|
||||
bool scalar,
|
||||
bool isLeOrLt = false)
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
using ARMeilleure.Decoders;
|
||||
using ARMeilleure.IntermediateRepresentation;
|
||||
using ARMeilleure.Translation;
|
||||
using System.Reflection;
|
||||
|
||||
using static ARMeilleure.Instructions.InstEmitHelper;
|
||||
|
||||
|
@ -9,50 +8,42 @@ namespace ARMeilleure.Instructions
|
|||
{
|
||||
static partial class InstEmit
|
||||
{
|
||||
public static void Aesd_V(EmitterContext context)
|
||||
public static void Aesd_V(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimd op = (OpCodeSimd)context.CurrOp;
|
||||
|
||||
Operand d = GetVec(op.Rd);
|
||||
Operand n = GetVec(op.Rn);
|
||||
|
||||
MethodInfo info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.Decrypt));
|
||||
|
||||
context.Copy(d, context.Call(info, d, n));
|
||||
context.Copy(d, context.Call(new _V128_V128_V128(SoftFallback.Decrypt), d, n));
|
||||
}
|
||||
|
||||
public static void Aese_V(EmitterContext context)
|
||||
public static void Aese_V(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimd op = (OpCodeSimd)context.CurrOp;
|
||||
|
||||
Operand d = GetVec(op.Rd);
|
||||
Operand n = GetVec(op.Rn);
|
||||
|
||||
MethodInfo info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.Encrypt));
|
||||
|
||||
context.Copy(d, context.Call(info, d, n));
|
||||
context.Copy(d, context.Call(new _V128_V128_V128(SoftFallback.Encrypt), d, n));
|
||||
}
|
||||
|
||||
public static void Aesimc_V(EmitterContext context)
|
||||
public static void Aesimc_V(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimd op = (OpCodeSimd)context.CurrOp;
|
||||
|
||||
Operand n = GetVec(op.Rn);
|
||||
|
||||
MethodInfo info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.InverseMixColumns));
|
||||
|
||||
context.Copy(GetVec(op.Rd), context.Call(info, n));
|
||||
context.Copy(GetVec(op.Rd), context.Call(new _V128_V128(SoftFallback.InverseMixColumns), n));
|
||||
}
|
||||
|
||||
public static void Aesmc_V(EmitterContext context)
|
||||
public static void Aesmc_V(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimd op = (OpCodeSimd)context.CurrOp;
|
||||
|
||||
Operand n = GetVec(op.Rn);
|
||||
|
||||
MethodInfo info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.MixColumns));
|
||||
|
||||
context.Copy(GetVec(op.Rd), context.Call(info, n));
|
||||
context.Copy(GetVec(op.Rd), context.Call(new _V128_V128(SoftFallback.MixColumns), n));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ using ARMeilleure.State;
|
|||
using ARMeilleure.Translation;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
|
||||
using static ARMeilleure.Instructions.InstEmitHelper;
|
||||
using static ARMeilleure.Instructions.InstEmitSimdHelper;
|
||||
|
@ -16,7 +15,7 @@ namespace ARMeilleure.Instructions
|
|||
|
||||
static partial class InstEmit
|
||||
{
|
||||
public static void Fcvt_S(EmitterContext context)
|
||||
public static void Fcvt_S(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimd op = (OpCodeSimd)context.CurrOp;
|
||||
|
||||
|
@ -62,9 +61,9 @@ namespace ARMeilleure.Instructions
|
|||
{
|
||||
Operand ne = context.VectorExtract(OperandType.FP32, GetVec(op.Rn), 0);
|
||||
|
||||
MethodInfo info = typeof(SoftFloat32_16).GetMethod(nameof(SoftFloat32_16.FPConvert));
|
||||
Delegate dlg = new _U16_F32(SoftFloat32_16.FPConvert);
|
||||
|
||||
Operand res = context.Call(info, ne);
|
||||
Operand res = context.Call(dlg, ne);
|
||||
|
||||
res = context.ZeroExtend16(OperandType.I64, res);
|
||||
|
||||
|
@ -74,9 +73,9 @@ namespace ARMeilleure.Instructions
|
|||
{
|
||||
Operand ne = EmitVectorExtractZx(context, op.Rn, 0, 1);
|
||||
|
||||
MethodInfo info = typeof(SoftFloat16_32).GetMethod(nameof(SoftFloat16_32.FPConvert));
|
||||
Delegate dlg = new _F32_U16(SoftFloat16_32.FPConvert);
|
||||
|
||||
Operand res = context.Call(info, ne);
|
||||
Operand res = context.Call(dlg, ne);
|
||||
|
||||
context.Copy(GetVec(op.Rd), context.VectorInsert(context.VectorZero(), res, 0));
|
||||
}
|
||||
|
@ -94,17 +93,17 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Fcvtas_Gp(EmitterContext context)
|
||||
public static void Fcvtas_Gp(ArmEmitterContext context)
|
||||
{
|
||||
EmitFcvt_s_Gp(context, (op1) => EmitRoundMathCall(context, MidpointRounding.AwayFromZero, op1));
|
||||
}
|
||||
|
||||
public static void Fcvtau_Gp(EmitterContext context)
|
||||
public static void Fcvtau_Gp(ArmEmitterContext context)
|
||||
{
|
||||
EmitFcvt_u_Gp(context, (op1) => EmitRoundMathCall(context, MidpointRounding.AwayFromZero, op1));
|
||||
}
|
||||
|
||||
public static void Fcvtl_V(EmitterContext context)
|
||||
public static void Fcvtl_V(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimd op = (OpCodeSimd)context.CurrOp;
|
||||
|
||||
|
@ -142,9 +141,9 @@ namespace ARMeilleure.Instructions
|
|||
{
|
||||
Operand ne = EmitVectorExtractZx(context, op.Rn, part + index, 1);
|
||||
|
||||
MethodInfo info = typeof(SoftFloat16_32).GetMethod(nameof(SoftFloat16_32.FPConvert));
|
||||
Delegate dlg = new _F32_U16(SoftFloat16_32.FPConvert);
|
||||
|
||||
Operand e = context.Call(info, ne);
|
||||
Operand e = context.Call(dlg, ne);
|
||||
|
||||
res = context.VectorInsert(res, e, index);
|
||||
}
|
||||
|
@ -162,17 +161,17 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Fcvtms_Gp(EmitterContext context)
|
||||
public static void Fcvtms_Gp(ArmEmitterContext context)
|
||||
{
|
||||
EmitFcvt_s_Gp(context, (op1) => EmitUnaryMathCall(context, nameof(Math.Floor), op1));
|
||||
EmitFcvt_s_Gp(context, (op1) => EmitUnaryMathCall(context, MathF.Floor, Math.Floor, op1));
|
||||
}
|
||||
|
||||
public static void Fcvtmu_Gp(EmitterContext context)
|
||||
public static void Fcvtmu_Gp(ArmEmitterContext context)
|
||||
{
|
||||
EmitFcvt_u_Gp(context, (op1) => EmitUnaryMathCall(context, nameof(Math.Floor), op1));
|
||||
EmitFcvt_u_Gp(context, (op1) => EmitUnaryMathCall(context, MathF.Floor, Math.Floor, op1));
|
||||
}
|
||||
|
||||
public static void Fcvtn_V(EmitterContext context)
|
||||
public static void Fcvtn_V(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimd op = (OpCodeSimd)context.CurrOp;
|
||||
|
||||
|
@ -213,9 +212,9 @@ namespace ARMeilleure.Instructions
|
|||
|
||||
if (sizeF == 0)
|
||||
{
|
||||
MethodInfo info = typeof(SoftFloat32_16).GetMethod(nameof(SoftFloat32_16.FPConvert));
|
||||
Delegate dlg = new _U16_F32(SoftFloat32_16.FPConvert);
|
||||
|
||||
Operand e = context.Call(info, ne);
|
||||
Operand e = context.Call(dlg, ne);
|
||||
|
||||
e = context.ZeroExtend16(OperandType.I64, e);
|
||||
|
||||
|
@ -233,7 +232,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Fcvtns_S(EmitterContext context)
|
||||
public static void Fcvtns_S(ArmEmitterContext context)
|
||||
{
|
||||
if (Optimizations.UseSse41)
|
||||
{
|
||||
|
@ -245,7 +244,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Fcvtns_V(EmitterContext context)
|
||||
public static void Fcvtns_V(ArmEmitterContext context)
|
||||
{
|
||||
if (Optimizations.UseSse41)
|
||||
{
|
||||
|
@ -257,7 +256,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Fcvtnu_S(EmitterContext context)
|
||||
public static void Fcvtnu_S(ArmEmitterContext context)
|
||||
{
|
||||
if (Optimizations.UseSse41)
|
||||
{
|
||||
|
@ -269,7 +268,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Fcvtnu_V(EmitterContext context)
|
||||
public static void Fcvtnu_V(ArmEmitterContext context)
|
||||
{
|
||||
if (Optimizations.UseSse41)
|
||||
{
|
||||
|
@ -281,27 +280,27 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Fcvtps_Gp(EmitterContext context)
|
||||
public static void Fcvtps_Gp(ArmEmitterContext context)
|
||||
{
|
||||
EmitFcvt_s_Gp(context, (op1) => EmitUnaryMathCall(context, nameof(Math.Ceiling), op1));
|
||||
EmitFcvt_s_Gp(context, (op1) => EmitUnaryMathCall(context, MathF.Ceiling, Math.Ceiling, op1));
|
||||
}
|
||||
|
||||
public static void Fcvtpu_Gp(EmitterContext context)
|
||||
public static void Fcvtpu_Gp(ArmEmitterContext context)
|
||||
{
|
||||
EmitFcvt_u_Gp(context, (op1) => EmitUnaryMathCall(context, nameof(Math.Ceiling), op1));
|
||||
EmitFcvt_u_Gp(context, (op1) => EmitUnaryMathCall(context, MathF.Ceiling, Math.Ceiling, op1));
|
||||
}
|
||||
|
||||
public static void Fcvtzs_Gp(EmitterContext context)
|
||||
public static void Fcvtzs_Gp(ArmEmitterContext context)
|
||||
{
|
||||
EmitFcvt_s_Gp(context, (op1) => op1);
|
||||
}
|
||||
|
||||
public static void Fcvtzs_Gp_Fixed(EmitterContext context)
|
||||
public static void Fcvtzs_Gp_Fixed(ArmEmitterContext context)
|
||||
{
|
||||
EmitFcvtzs_Gp_Fixed(context);
|
||||
}
|
||||
|
||||
public static void Fcvtzs_S(EmitterContext context)
|
||||
public static void Fcvtzs_S(ArmEmitterContext context)
|
||||
{
|
||||
if (Optimizations.UseSse41)
|
||||
{
|
||||
|
@ -313,7 +312,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Fcvtzs_V(EmitterContext context)
|
||||
public static void Fcvtzs_V(ArmEmitterContext context)
|
||||
{
|
||||
if (Optimizations.UseSse41)
|
||||
{
|
||||
|
@ -325,7 +324,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Fcvtzs_V_Fixed(EmitterContext context)
|
||||
public static void Fcvtzs_V_Fixed(ArmEmitterContext context)
|
||||
{
|
||||
if (Optimizations.UseSse41)
|
||||
{
|
||||
|
@ -337,17 +336,17 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Fcvtzu_Gp(EmitterContext context)
|
||||
public static void Fcvtzu_Gp(ArmEmitterContext context)
|
||||
{
|
||||
EmitFcvt_u_Gp(context, (op1) => op1);
|
||||
}
|
||||
|
||||
public static void Fcvtzu_Gp_Fixed(EmitterContext context)
|
||||
public static void Fcvtzu_Gp_Fixed(ArmEmitterContext context)
|
||||
{
|
||||
EmitFcvtzu_Gp_Fixed(context);
|
||||
}
|
||||
|
||||
public static void Fcvtzu_S(EmitterContext context)
|
||||
public static void Fcvtzu_S(ArmEmitterContext context)
|
||||
{
|
||||
if (Optimizations.UseSse41)
|
||||
{
|
||||
|
@ -359,7 +358,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Fcvtzu_V(EmitterContext context)
|
||||
public static void Fcvtzu_V(ArmEmitterContext context)
|
||||
{
|
||||
if (Optimizations.UseSse41)
|
||||
{
|
||||
|
@ -371,7 +370,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Fcvtzu_V_Fixed(EmitterContext context)
|
||||
public static void Fcvtzu_V_Fixed(ArmEmitterContext context)
|
||||
{
|
||||
if (Optimizations.UseSse41)
|
||||
{
|
||||
|
@ -383,7 +382,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Scvtf_Gp(EmitterContext context)
|
||||
public static void Scvtf_Gp(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimdCvt op = (OpCodeSimdCvt)context.CurrOp;
|
||||
|
||||
|
@ -399,7 +398,7 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), context.VectorInsert(context.VectorZero(), res, 0));
|
||||
}
|
||||
|
||||
public static void Scvtf_Gp_Fixed(EmitterContext context)
|
||||
public static void Scvtf_Gp_Fixed(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimdCvt op = (OpCodeSimdCvt)context.CurrOp;
|
||||
|
||||
|
@ -417,7 +416,7 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), context.VectorInsert(context.VectorZero(), res, 0));
|
||||
}
|
||||
|
||||
public static void Scvtf_S(EmitterContext context)
|
||||
public static void Scvtf_S(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimd op = (OpCodeSimd)context.CurrOp;
|
||||
|
||||
|
@ -437,7 +436,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Scvtf_V(EmitterContext context)
|
||||
public static void Scvtf_V(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimd op = (OpCodeSimd)context.CurrOp;
|
||||
|
||||
|
@ -453,7 +452,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Scvtf_V_Fixed(EmitterContext context)
|
||||
public static void Scvtf_V_Fixed(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimd op = (OpCodeSimd)context.CurrOp;
|
||||
|
||||
|
@ -470,7 +469,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Ucvtf_Gp(EmitterContext context)
|
||||
public static void Ucvtf_Gp(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimdCvt op = (OpCodeSimdCvt)context.CurrOp;
|
||||
|
||||
|
@ -481,7 +480,7 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), context.VectorInsert(context.VectorZero(), res, 0));
|
||||
}
|
||||
|
||||
public static void Ucvtf_Gp_Fixed(EmitterContext context)
|
||||
public static void Ucvtf_Gp_Fixed(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimdCvt op = (OpCodeSimdCvt)context.CurrOp;
|
||||
|
||||
|
@ -494,7 +493,7 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), context.VectorInsert(context.VectorZero(), res, 0));
|
||||
}
|
||||
|
||||
public static void Ucvtf_S(EmitterContext context)
|
||||
public static void Ucvtf_S(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimd op = (OpCodeSimd)context.CurrOp;
|
||||
|
||||
|
@ -514,7 +513,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Ucvtf_V(EmitterContext context)
|
||||
public static void Ucvtf_V(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimd op = (OpCodeSimd)context.CurrOp;
|
||||
|
||||
|
@ -530,7 +529,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Ucvtf_V_Fixed(EmitterContext context)
|
||||
public static void Ucvtf_V_Fixed(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimd op = (OpCodeSimd)context.CurrOp;
|
||||
|
||||
|
@ -547,7 +546,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
private static void EmitFcvtn(EmitterContext context, bool signed, bool scalar)
|
||||
private static void EmitFcvtn(ArmEmitterContext context, bool signed, bool scalar)
|
||||
{
|
||||
OpCodeSimd op = (OpCodeSimd)context.CurrOp;
|
||||
|
||||
|
@ -570,25 +569,21 @@ namespace ARMeilleure.Instructions
|
|||
|
||||
if (sizeF == 0)
|
||||
{
|
||||
string name = signed
|
||||
? nameof(SoftFallback.SatF32ToS32)
|
||||
: nameof(SoftFallback.SatF32ToU32);
|
||||
Delegate dlg = signed
|
||||
? (Delegate)new _S32_F32(SoftFallback.SatF32ToS32)
|
||||
: (Delegate)new _U32_F32(SoftFallback.SatF32ToU32);
|
||||
|
||||
MethodInfo info = typeof(SoftFallback).GetMethod(name);
|
||||
|
||||
e = context.Call(info, e);
|
||||
e = context.Call(dlg, e);
|
||||
|
||||
e = context.ZeroExtend32(OperandType.I64, e);
|
||||
}
|
||||
else /* if (sizeF == 1) */
|
||||
{
|
||||
string name = signed
|
||||
? nameof(SoftFallback.SatF64ToS64)
|
||||
: nameof(SoftFallback.SatF64ToU64);
|
||||
Delegate dlg = signed
|
||||
? (Delegate)new _S64_F64(SoftFallback.SatF64ToS64)
|
||||
: (Delegate)new _U64_F64(SoftFallback.SatF64ToU64);
|
||||
|
||||
MethodInfo info = typeof(SoftFallback).GetMethod(name);
|
||||
|
||||
e = context.Call(info, e);
|
||||
e = context.Call(dlg, e);
|
||||
}
|
||||
|
||||
res = EmitVectorInsert(context, res, e, index, sizeI);
|
||||
|
@ -597,7 +592,7 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
||||
private static void EmitFcvtz(EmitterContext context, bool signed, bool scalar)
|
||||
private static void EmitFcvtz(ArmEmitterContext context, bool signed, bool scalar)
|
||||
{
|
||||
OpCodeSimd op = (OpCodeSimd)context.CurrOp;
|
||||
|
||||
|
@ -622,25 +617,21 @@ namespace ARMeilleure.Instructions
|
|||
|
||||
if (sizeF == 0)
|
||||
{
|
||||
string name = signed
|
||||
? nameof(SoftFallback.SatF32ToS32)
|
||||
: nameof(SoftFallback.SatF32ToU32);
|
||||
Delegate dlg = signed
|
||||
? (Delegate)new _S32_F32(SoftFallback.SatF32ToS32)
|
||||
: (Delegate)new _U32_F32(SoftFallback.SatF32ToU32);
|
||||
|
||||
MethodInfo info = typeof(SoftFallback).GetMethod(name);
|
||||
|
||||
e = context.Call(info, e);
|
||||
e = context.Call(dlg, e);
|
||||
|
||||
e = context.ZeroExtend32(OperandType.I64, e);
|
||||
}
|
||||
else /* if (sizeF == 1) */
|
||||
{
|
||||
string name = signed
|
||||
? nameof(SoftFallback.SatF64ToS64)
|
||||
: nameof(SoftFallback.SatF64ToU64);
|
||||
Delegate dlg = signed
|
||||
? (Delegate)new _S64_F64(SoftFallback.SatF64ToS64)
|
||||
: (Delegate)new _U64_F64(SoftFallback.SatF64ToU64);
|
||||
|
||||
MethodInfo info = typeof(SoftFallback).GetMethod(name);
|
||||
|
||||
e = context.Call(info, e);
|
||||
e = context.Call(dlg, e);
|
||||
}
|
||||
|
||||
res = EmitVectorInsert(context, res, e, index, sizeI);
|
||||
|
@ -649,17 +640,17 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
||||
private static void EmitFcvt_s_Gp(EmitterContext context, Func1I emit)
|
||||
private static void EmitFcvt_s_Gp(ArmEmitterContext context, Func1I emit)
|
||||
{
|
||||
EmitFcvt___Gp(context, emit, signed: true);
|
||||
}
|
||||
|
||||
private static void EmitFcvt_u_Gp(EmitterContext context, Func1I emit)
|
||||
private static void EmitFcvt_u_Gp(ArmEmitterContext context, Func1I emit)
|
||||
{
|
||||
EmitFcvt___Gp(context, emit, signed: false);
|
||||
}
|
||||
|
||||
private static void EmitFcvt___Gp(EmitterContext context, Func1I emit, bool signed)
|
||||
private static void EmitFcvt___Gp(ArmEmitterContext context, Func1I emit, bool signed)
|
||||
{
|
||||
OpCodeSimdCvt op = (OpCodeSimdCvt)context.CurrOp;
|
||||
|
||||
|
@ -674,17 +665,17 @@ namespace ARMeilleure.Instructions
|
|||
SetIntOrZR(context, op.Rd, res);
|
||||
}
|
||||
|
||||
private static void EmitFcvtzs_Gp_Fixed(EmitterContext context)
|
||||
private static void EmitFcvtzs_Gp_Fixed(ArmEmitterContext context)
|
||||
{
|
||||
EmitFcvtz__Gp_Fixed(context, signed: true);
|
||||
}
|
||||
|
||||
private static void EmitFcvtzu_Gp_Fixed(EmitterContext context)
|
||||
private static void EmitFcvtzu_Gp_Fixed(ArmEmitterContext context)
|
||||
{
|
||||
EmitFcvtz__Gp_Fixed(context, signed: false);
|
||||
}
|
||||
|
||||
private static void EmitFcvtz__Gp_Fixed(EmitterContext context, bool signed)
|
||||
private static void EmitFcvtz__Gp_Fixed(ArmEmitterContext context, bool signed)
|
||||
{
|
||||
OpCodeSimdCvt op = (OpCodeSimdCvt)context.CurrOp;
|
||||
|
||||
|
@ -699,7 +690,7 @@ namespace ARMeilleure.Instructions
|
|||
SetIntOrZR(context, op.Rd, res);
|
||||
}
|
||||
|
||||
private static void EmitVectorCvtf(EmitterContext context, bool signed)
|
||||
private static void EmitVectorCvtf(ArmEmitterContext context, bool signed)
|
||||
{
|
||||
OpCodeSimd op = (OpCodeSimd)context.CurrOp;
|
||||
|
||||
|
@ -726,7 +717,7 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
||||
private static int GetFBits(EmitterContext context)
|
||||
private static int GetFBits(ArmEmitterContext context)
|
||||
{
|
||||
if (context.CurrOp is OpCodeSimdShImm op)
|
||||
{
|
||||
|
@ -736,7 +727,7 @@ namespace ARMeilleure.Instructions
|
|||
return 0;
|
||||
}
|
||||
|
||||
private static Operand EmitFPConvert(EmitterContext context, Operand value, int size, bool signed)
|
||||
private static Operand EmitFPConvert(ArmEmitterContext context, Operand value, int size, bool signed)
|
||||
{
|
||||
Debug.Assert(value.Type == OperandType.I32 || value.Type == OperandType.I64);
|
||||
Debug.Assert((uint)size < 2);
|
||||
|
@ -754,7 +745,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
private static Operand EmitScalarFcvts(EmitterContext context, Operand value, int fBits)
|
||||
private static Operand EmitScalarFcvts(ArmEmitterContext context, Operand value, int fBits)
|
||||
{
|
||||
Debug.Assert(value.Type == OperandType.FP32 || value.Type == OperandType.FP64);
|
||||
|
||||
|
@ -762,27 +753,23 @@ namespace ARMeilleure.Instructions
|
|||
|
||||
if (context.CurrOp.RegisterSize == RegisterSize.Int32)
|
||||
{
|
||||
string name = value.Type == OperandType.FP32
|
||||
? nameof(SoftFallback.SatF32ToS32)
|
||||
: nameof(SoftFallback.SatF64ToS32);
|
||||
Delegate dlg = value.Type == OperandType.FP32
|
||||
? (Delegate)new _S32_F32(SoftFallback.SatF32ToS32)
|
||||
: (Delegate)new _S32_F64(SoftFallback.SatF64ToS32);
|
||||
|
||||
MethodInfo info = typeof(SoftFallback).GetMethod(name);
|
||||
|
||||
return context.Call(info, value);
|
||||
return context.Call(dlg, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
string name = value.Type == OperandType.FP32
|
||||
? nameof(SoftFallback.SatF32ToS64)
|
||||
: nameof(SoftFallback.SatF64ToS64);
|
||||
Delegate dlg = value.Type == OperandType.FP32
|
||||
? (Delegate)new _S64_F32(SoftFallback.SatF32ToS64)
|
||||
: (Delegate)new _S64_F64(SoftFallback.SatF64ToS64);
|
||||
|
||||
MethodInfo info = typeof(SoftFallback).GetMethod(name);
|
||||
|
||||
return context.Call(info, value);
|
||||
return context.Call(dlg, value);
|
||||
}
|
||||
}
|
||||
|
||||
private static Operand EmitScalarFcvtu(EmitterContext context, Operand value, int fBits)
|
||||
private static Operand EmitScalarFcvtu(ArmEmitterContext context, Operand value, int fBits)
|
||||
{
|
||||
Debug.Assert(value.Type == OperandType.FP32 || value.Type == OperandType.FP64);
|
||||
|
||||
|
@ -790,27 +777,23 @@ namespace ARMeilleure.Instructions
|
|||
|
||||
if (context.CurrOp.RegisterSize == RegisterSize.Int32)
|
||||
{
|
||||
string name = value.Type == OperandType.FP32
|
||||
? nameof(SoftFallback.SatF32ToU32)
|
||||
: nameof(SoftFallback.SatF64ToU32);
|
||||
Delegate dlg = value.Type == OperandType.FP32
|
||||
? (Delegate)new _U32_F32(SoftFallback.SatF32ToU32)
|
||||
: (Delegate)new _U32_F64(SoftFallback.SatF64ToU32);
|
||||
|
||||
MethodInfo info = typeof(SoftFallback).GetMethod(name);
|
||||
|
||||
return context.Call(info, value);
|
||||
return context.Call(dlg, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
string name = value.Type == OperandType.FP32
|
||||
? nameof(SoftFallback.SatF32ToU64)
|
||||
: nameof(SoftFallback.SatF64ToU64);
|
||||
Delegate dlg = value.Type == OperandType.FP32
|
||||
? (Delegate)new _U64_F32(SoftFallback.SatF32ToU64)
|
||||
: (Delegate)new _U64_F64(SoftFallback.SatF64ToU64);
|
||||
|
||||
MethodInfo info = typeof(SoftFallback).GetMethod(name);
|
||||
|
||||
return context.Call(info, value);
|
||||
return context.Call(dlg, value);
|
||||
}
|
||||
}
|
||||
|
||||
private static Operand EmitF2iFBitsMul(EmitterContext context, Operand value, int fBits)
|
||||
private static Operand EmitF2iFBitsMul(ArmEmitterContext context, Operand value, int fBits)
|
||||
{
|
||||
Debug.Assert(value.Type == OperandType.FP32 || value.Type == OperandType.FP64);
|
||||
|
||||
|
@ -829,7 +812,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
private static Operand EmitI2fFBitsMul(EmitterContext context, Operand value, int fBits)
|
||||
private static Operand EmitI2fFBitsMul(ArmEmitterContext context, Operand value, int fBits)
|
||||
{
|
||||
Debug.Assert(value.Type == OperandType.FP32 || value.Type == OperandType.FP64);
|
||||
|
||||
|
@ -848,7 +831,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
private static void EmitSse41Fcvts(EmitterContext context, FPRoundingMode roundMode, bool scalar)
|
||||
private static void EmitSse41Fcvts(ArmEmitterContext context, FPRoundingMode roundMode, bool scalar)
|
||||
{
|
||||
OpCodeSimd op = (OpCodeSimd)context.CurrOp;
|
||||
|
||||
|
@ -950,7 +933,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
private static void EmitSse41Fcvtu(EmitterContext context, FPRoundingMode roundMode, bool scalar)
|
||||
private static void EmitSse41Fcvtu(ArmEmitterContext context, FPRoundingMode roundMode, bool scalar)
|
||||
{
|
||||
OpCodeSimd op = (OpCodeSimd)context.CurrOp;
|
||||
|
||||
|
@ -1087,7 +1070,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
private static void EmitSse2Scvtf(EmitterContext context, bool scalar)
|
||||
private static void EmitSse2Scvtf(ArmEmitterContext context, bool scalar)
|
||||
{
|
||||
OpCodeSimd op = (OpCodeSimd)context.CurrOp;
|
||||
|
||||
|
@ -1119,7 +1102,7 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
||||
private static void EmitSse2Ucvtf(EmitterContext context, bool scalar)
|
||||
private static void EmitSse2Ucvtf(ArmEmitterContext context, bool scalar)
|
||||
{
|
||||
OpCodeSimd op = (OpCodeSimd)context.CurrOp;
|
||||
|
||||
|
@ -1164,16 +1147,16 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
||||
private static Operand EmitVectorLongExtract(EmitterContext context, int reg, int index, int size)
|
||||
private static Operand EmitVectorLongExtract(ArmEmitterContext context, int reg, int index, int size)
|
||||
{
|
||||
OperandType type = size == 3 ? OperandType.I64 : OperandType.I32;
|
||||
|
||||
return context.VectorExtract(type, GetVec(reg), index);
|
||||
}
|
||||
|
||||
private static Operand EmitVectorLongCreate(EmitterContext context, Operand low, Operand high)
|
||||
private static Operand EmitVectorLongCreate(ArmEmitterContext context, Operand low, Operand high)
|
||||
{
|
||||
Operand vector = context.Copy(Local(OperandType.V128), low);
|
||||
Operand vector = context.VectorCreateScalar(low);
|
||||
|
||||
vector = context.VectorInsert(vector, high, 1);
|
||||
|
||||
|
|
|
@ -1,17 +1,15 @@
|
|||
using ARMeilleure.Decoders;
|
||||
using ARMeilleure.IntermediateRepresentation;
|
||||
using ARMeilleure.Translation;
|
||||
using System.Reflection;
|
||||
|
||||
using static ARMeilleure.Instructions.InstEmitHelper;
|
||||
using static ARMeilleure.IntermediateRepresentation.OperandHelper;
|
||||
|
||||
namespace ARMeilleure.Instructions
|
||||
{
|
||||
static partial class InstEmit
|
||||
{
|
||||
#region "Sha1"
|
||||
public static void Sha1c_V(EmitterContext context)
|
||||
public static void Sha1c_V(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
||||
|
||||
|
@ -21,27 +19,23 @@ namespace ARMeilleure.Instructions
|
|||
|
||||
Operand m = GetVec(op.Rm);
|
||||
|
||||
MethodInfo info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.HashChoose));
|
||||
|
||||
Operand res = context.Call(info, d, ne, m);
|
||||
Operand res = context.Call(new _V128_V128_U32_V128(SoftFallback.HashChoose), d, ne, m);
|
||||
|
||||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
||||
public static void Sha1h_V(EmitterContext context)
|
||||
public static void Sha1h_V(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimd op = (OpCodeSimd)context.CurrOp;
|
||||
|
||||
Operand ne = context.VectorExtract(OperandType.I32, GetVec(op.Rn), 0);
|
||||
|
||||
MethodInfo info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.FixedRotate));
|
||||
|
||||
Operand res = context.Call(info, ne);
|
||||
Operand res = context.Call(new _U32_U32(SoftFallback.FixedRotate), ne);
|
||||
|
||||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
||||
public static void Sha1m_V(EmitterContext context)
|
||||
public static void Sha1m_V(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
||||
|
||||
|
@ -51,14 +45,12 @@ namespace ARMeilleure.Instructions
|
|||
|
||||
Operand m = GetVec(op.Rm);
|
||||
|
||||
MethodInfo info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.HashMajority));
|
||||
|
||||
Operand res = context.Call(info, d, ne, m);
|
||||
Operand res = context.Call(new _V128_V128_U32_V128(SoftFallback.HashMajority), d, ne, m);
|
||||
|
||||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
||||
public static void Sha1p_V(EmitterContext context)
|
||||
public static void Sha1p_V(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
||||
|
||||
|
@ -68,14 +60,12 @@ namespace ARMeilleure.Instructions
|
|||
|
||||
Operand m = GetVec(op.Rm);
|
||||
|
||||
MethodInfo info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.HashParity));
|
||||
|
||||
Operand res = context.Call(info, d, ne, m);
|
||||
Operand res = context.Call(new _V128_V128_U32_V128(SoftFallback.HashParity), d, ne, m);
|
||||
|
||||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
||||
public static void Sha1su0_V(EmitterContext context)
|
||||
public static void Sha1su0_V(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
||||
|
||||
|
@ -83,30 +73,26 @@ namespace ARMeilleure.Instructions
|
|||
Operand n = GetVec(op.Rn);
|
||||
Operand m = GetVec(op.Rm);
|
||||
|
||||
MethodInfo info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.Sha1SchedulePart1));
|
||||
|
||||
Operand res = context.Call(info, d, n, m);
|
||||
Operand res = context.Call(new _V128_V128_V128_V128(SoftFallback.Sha1SchedulePart1), d, n, m);
|
||||
|
||||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
||||
public static void Sha1su1_V(EmitterContext context)
|
||||
public static void Sha1su1_V(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimd op = (OpCodeSimd)context.CurrOp;
|
||||
|
||||
Operand d = GetVec(op.Rd);
|
||||
Operand n = GetVec(op.Rn);
|
||||
|
||||
MethodInfo info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.Sha1SchedulePart2));
|
||||
|
||||
Operand res = context.Call(info, d, n);
|
||||
Operand res = context.Call(new _V128_V128_V128(SoftFallback.Sha1SchedulePart2), d, n);
|
||||
|
||||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region "Sha256"
|
||||
public static void Sha256h_V(EmitterContext context)
|
||||
public static void Sha256h_V(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
||||
|
||||
|
@ -114,14 +100,12 @@ namespace ARMeilleure.Instructions
|
|||
Operand n = GetVec(op.Rn);
|
||||
Operand m = GetVec(op.Rm);
|
||||
|
||||
MethodInfo info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.HashLower));
|
||||
|
||||
Operand res = context.Call(info, d, n, m);
|
||||
Operand res = context.Call(new _V128_V128_V128_V128(SoftFallback.HashLower), d, n, m);
|
||||
|
||||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
||||
public static void Sha256h2_V(EmitterContext context)
|
||||
public static void Sha256h2_V(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
||||
|
||||
|
@ -129,28 +113,24 @@ namespace ARMeilleure.Instructions
|
|||
Operand n = GetVec(op.Rn);
|
||||
Operand m = GetVec(op.Rm);
|
||||
|
||||
MethodInfo info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.HashUpper));
|
||||
|
||||
Operand res = context.Call(info, d, n, m);
|
||||
Operand res = context.Call(new _V128_V128_V128_V128(SoftFallback.HashUpper), d, n, m);
|
||||
|
||||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
||||
public static void Sha256su0_V(EmitterContext context)
|
||||
public static void Sha256su0_V(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimd op = (OpCodeSimd)context.CurrOp;
|
||||
|
||||
Operand d = GetVec(op.Rd);
|
||||
Operand n = GetVec(op.Rn);
|
||||
|
||||
MethodInfo info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.Sha256SchedulePart1));
|
||||
|
||||
Operand res = context.Call(info, d, n);
|
||||
Operand res = context.Call(new _V128_V128_V128(SoftFallback.Sha256SchedulePart1), d, n);
|
||||
|
||||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
||||
public static void Sha256su1_V(EmitterContext context)
|
||||
public static void Sha256su1_V(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
||||
|
||||
|
@ -158,9 +138,7 @@ namespace ARMeilleure.Instructions
|
|||
Operand n = GetVec(op.Rn);
|
||||
Operand m = GetVec(op.Rm);
|
||||
|
||||
MethodInfo info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.Sha256SchedulePart2));
|
||||
|
||||
Operand res = context.Call(info, d, n, m);
|
||||
Operand res = context.Call(new _V128_V128_V128_V128(SoftFallback.Sha256SchedulePart2), d, n, m);
|
||||
|
||||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ using ARMeilleure.State;
|
|||
using ARMeilleure.Translation;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
|
||||
using static ARMeilleure.Instructions.InstEmitHelper;
|
||||
using static ARMeilleure.IntermediateRepresentation.OperandHelper;
|
||||
|
@ -142,48 +141,48 @@ namespace ARMeilleure.Instructions
|
|||
return (8 << (op.Size + 1)) - op.Imm;
|
||||
}
|
||||
|
||||
public static Operand X86GetScalar(EmitterContext context, float value)
|
||||
public static Operand X86GetScalar(ArmEmitterContext context, float value)
|
||||
{
|
||||
return X86GetScalar(context, BitConverter.SingleToInt32Bits(value));
|
||||
}
|
||||
|
||||
public static Operand X86GetScalar(EmitterContext context, double value)
|
||||
public static Operand X86GetScalar(ArmEmitterContext context, double value)
|
||||
{
|
||||
return X86GetScalar(context, BitConverter.DoubleToInt64Bits(value));
|
||||
}
|
||||
|
||||
public static Operand X86GetScalar(EmitterContext context, int value)
|
||||
public static Operand X86GetScalar(ArmEmitterContext context, int value)
|
||||
{
|
||||
return context.Copy(Local(OperandType.V128), Const(value));
|
||||
return context.VectorCreateScalar(Const(value));
|
||||
}
|
||||
|
||||
public static Operand X86GetScalar(EmitterContext context, long value)
|
||||
public static Operand X86GetScalar(ArmEmitterContext context, long value)
|
||||
{
|
||||
return context.Copy(Local(OperandType.V128), Const(value));
|
||||
return context.VectorCreateScalar(Const(value));
|
||||
}
|
||||
|
||||
public static Operand X86GetAllElements(EmitterContext context, float value)
|
||||
public static Operand X86GetAllElements(ArmEmitterContext context, float value)
|
||||
{
|
||||
return X86GetAllElements(context, BitConverter.SingleToInt32Bits(value));
|
||||
}
|
||||
|
||||
public static Operand X86GetAllElements(EmitterContext context, double value)
|
||||
public static Operand X86GetAllElements(ArmEmitterContext context, double value)
|
||||
{
|
||||
return X86GetAllElements(context, BitConverter.DoubleToInt64Bits(value));
|
||||
}
|
||||
|
||||
public static Operand X86GetAllElements(EmitterContext context, int value)
|
||||
public static Operand X86GetAllElements(ArmEmitterContext context, int value)
|
||||
{
|
||||
Operand vector = context.Copy(Local(OperandType.V128), Const(value));
|
||||
Operand vector = context.VectorCreateScalar(Const(value));
|
||||
|
||||
vector = context.AddIntrinsic(Instruction.X86Shufps, vector, vector, Const(0));
|
||||
|
||||
return vector;
|
||||
}
|
||||
|
||||
public static Operand X86GetAllElements(EmitterContext context, long value)
|
||||
public static Operand X86GetAllElements(ArmEmitterContext context, long value)
|
||||
{
|
||||
Operand vector = context.Copy(Local(OperandType.V128), Const(value));
|
||||
Operand vector = context.VectorCreateScalar(Const(value));
|
||||
|
||||
vector = context.AddIntrinsic(Instruction.X86Movlhps, vector, vector);
|
||||
|
||||
|
@ -203,10 +202,7 @@ namespace ARMeilleure.Instructions
|
|||
throw new ArgumentException($"Invalid rounding mode \"{roundMode}\".");
|
||||
}
|
||||
|
||||
public static void EmitScalarUnaryOpF(
|
||||
EmitterContext context,
|
||||
Instruction inst32,
|
||||
Instruction inst64)
|
||||
public static void EmitScalarUnaryOpF(ArmEmitterContext context, Instruction inst32, Instruction inst64)
|
||||
{
|
||||
OpCodeSimd op = (OpCodeSimd)context.CurrOp;
|
||||
|
||||
|
@ -228,10 +224,7 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
||||
public static void EmitScalarBinaryOpF(
|
||||
EmitterContext context,
|
||||
Instruction inst32,
|
||||
Instruction inst64)
|
||||
public static void EmitScalarBinaryOpF(ArmEmitterContext context, Instruction inst32, Instruction inst64)
|
||||
{
|
||||
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
||||
|
||||
|
@ -254,10 +247,7 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
||||
public static void EmitVectorUnaryOpF(
|
||||
EmitterContext context,
|
||||
Instruction inst32,
|
||||
Instruction inst64)
|
||||
public static void EmitVectorUnaryOpF(ArmEmitterContext context, Instruction inst32, Instruction inst64)
|
||||
{
|
||||
OpCodeSimd op = (OpCodeSimd)context.CurrOp;
|
||||
|
||||
|
@ -275,10 +265,7 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
||||
public static void EmitVectorBinaryOpF(
|
||||
EmitterContext context,
|
||||
Instruction inst32,
|
||||
Instruction inst64)
|
||||
public static void EmitVectorBinaryOpF(ArmEmitterContext context, Instruction inst32, Instruction inst64)
|
||||
{
|
||||
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
||||
|
||||
|
@ -297,79 +284,71 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
||||
public static Operand EmitUnaryMathCall(EmitterContext context, string name, Operand n)
|
||||
public static Operand EmitUnaryMathCall(ArmEmitterContext context, _F32_F32 f32, _F64_F64 f64, Operand n)
|
||||
{
|
||||
IOpCodeSimd op = (IOpCodeSimd)context.CurrOp;
|
||||
|
||||
int sizeF = op.Size & 1;
|
||||
|
||||
MethodInfo info;
|
||||
|
||||
if (sizeF == 0)
|
||||
{
|
||||
info = typeof(MathF).GetMethod(name, new Type[] { typeof(float) });
|
||||
}
|
||||
else /* if (sizeF == 1) */
|
||||
{
|
||||
info = typeof(Math).GetMethod(name, new Type[] { typeof(double) });
|
||||
}
|
||||
|
||||
return context.Call(info, n);
|
||||
return (op.Size & 1) == 0 ? context.Call(f32, n) : context.Call(f64, n);
|
||||
}
|
||||
|
||||
public static Operand EmitBinaryMathCall(EmitterContext context, string name, Operand n)
|
||||
public static Operand EmitRoundMathCall(ArmEmitterContext context, MidpointRounding roundMode, Operand n)
|
||||
{
|
||||
IOpCodeSimd op = (IOpCodeSimd)context.CurrOp;
|
||||
|
||||
int sizeF = op.Size & 1;
|
||||
Delegate dlg;
|
||||
|
||||
MethodInfo info;
|
||||
|
||||
if (sizeF == 0)
|
||||
if ((op.Size & 1) == 0)
|
||||
{
|
||||
info = typeof(MathF).GetMethod(name, new Type[] { typeof(float), typeof(float) });
|
||||
dlg = new _F32_F32_MidpointRounding(MathF.Round);
|
||||
}
|
||||
else /* if (sizeF == 1) */
|
||||
else /* if ((op.Size & 1) == 1) */
|
||||
{
|
||||
info = typeof(Math).GetMethod(name, new Type[] { typeof(double), typeof(double) });
|
||||
dlg = new _F64_F64_MidpointRounding(Math.Round);
|
||||
}
|
||||
|
||||
return context.Call(info, n);
|
||||
return context.Call(dlg, n, Const((int)roundMode));
|
||||
}
|
||||
|
||||
public static Operand EmitRoundMathCall(EmitterContext context, MidpointRounding roundMode, Operand n)
|
||||
public static Operand EmitSoftFloatCall(
|
||||
ArmEmitterContext context,
|
||||
_F32_F32 f32,
|
||||
_F64_F64 f64,
|
||||
params Operand[] callArgs)
|
||||
{
|
||||
IOpCodeSimd op = (IOpCodeSimd)context.CurrOp;
|
||||
|
||||
int sizeF = op.Size & 1;
|
||||
Delegate dlg = (op.Size & 1) == 0 ? (Delegate)f32 : (Delegate)f64;
|
||||
|
||||
MethodInfo info;
|
||||
|
||||
if (sizeF == 0)
|
||||
{
|
||||
info = typeof(MathF).GetMethod(nameof(MathF.Round), new Type[] { typeof(float), typeof(MidpointRounding) });
|
||||
}
|
||||
else /* if (sizeF == 1) */
|
||||
{
|
||||
info = typeof(Math).GetMethod(nameof(Math.Round), new Type[] { typeof(double), typeof(MidpointRounding) });
|
||||
}
|
||||
|
||||
return context.Call(info, n, Const((int)roundMode));
|
||||
return context.Call(dlg, callArgs);
|
||||
}
|
||||
|
||||
public static Operand EmitSoftFloatCall(EmitterContext context, string name, params Operand[] callArgs)
|
||||
public static Operand EmitSoftFloatCall(
|
||||
ArmEmitterContext context,
|
||||
_F32_F32_F32 f32,
|
||||
_F64_F64_F64 f64,
|
||||
params Operand[] callArgs)
|
||||
{
|
||||
IOpCodeSimd op = (IOpCodeSimd)context.CurrOp;
|
||||
|
||||
int sizeF = op.Size & 1;
|
||||
Delegate dlg = (op.Size & 1) == 0 ? (Delegate)f32 : (Delegate)f64;
|
||||
|
||||
Type type = sizeF == 0 ? typeof(SoftFloat32)
|
||||
: typeof(SoftFloat64);
|
||||
|
||||
return context.Call(type.GetMethod(name), callArgs);
|
||||
return context.Call(dlg, callArgs);
|
||||
}
|
||||
|
||||
public static void EmitScalarBinaryOpByElemF(EmitterContext context, Func2I emit)
|
||||
public static Operand EmitSoftFloatCall(
|
||||
ArmEmitterContext context,
|
||||
_F32_F32_F32_F32 f32,
|
||||
_F64_F64_F64_F64 f64,
|
||||
params Operand[] callArgs)
|
||||
{
|
||||
IOpCodeSimd op = (IOpCodeSimd)context.CurrOp;
|
||||
|
||||
Delegate dlg = (op.Size & 1) == 0 ? (Delegate)f32 : (Delegate)f64;
|
||||
|
||||
return context.Call(dlg, callArgs);
|
||||
}
|
||||
|
||||
public static void EmitScalarBinaryOpByElemF(ArmEmitterContext context, Func2I emit)
|
||||
{
|
||||
OpCodeSimdRegElemF op = (OpCodeSimdRegElemF)context.CurrOp;
|
||||
|
||||
|
@ -381,7 +360,7 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), context.VectorInsert(context.VectorZero(), emit(n, m), 0));
|
||||
}
|
||||
|
||||
public static void EmitScalarTernaryOpByElemF(EmitterContext context, Func3I emit)
|
||||
public static void EmitScalarTernaryOpByElemF(ArmEmitterContext context, Func3I emit)
|
||||
{
|
||||
OpCodeSimdRegElemF op = (OpCodeSimdRegElemF)context.CurrOp;
|
||||
|
||||
|
@ -394,7 +373,7 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), context.VectorInsert(context.VectorZero(), emit(d, n, m), 0));
|
||||
}
|
||||
|
||||
public static void EmitScalarUnaryOpSx(EmitterContext context, Func1I emit)
|
||||
public static void EmitScalarUnaryOpSx(ArmEmitterContext context, Func1I emit)
|
||||
{
|
||||
OpCodeSimd op = (OpCodeSimd)context.CurrOp;
|
||||
|
||||
|
@ -405,7 +384,7 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), d);
|
||||
}
|
||||
|
||||
public static void EmitScalarBinaryOpSx(EmitterContext context, Func2I emit)
|
||||
public static void EmitScalarBinaryOpSx(ArmEmitterContext context, Func2I emit)
|
||||
{
|
||||
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
||||
|
||||
|
@ -417,7 +396,7 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), d);
|
||||
}
|
||||
|
||||
public static void EmitScalarUnaryOpZx(EmitterContext context, Func1I emit)
|
||||
public static void EmitScalarUnaryOpZx(ArmEmitterContext context, Func1I emit)
|
||||
{
|
||||
OpCodeSimd op = (OpCodeSimd)context.CurrOp;
|
||||
|
||||
|
@ -428,7 +407,7 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), d);
|
||||
}
|
||||
|
||||
public static void EmitScalarBinaryOpZx(EmitterContext context, Func2I emit)
|
||||
public static void EmitScalarBinaryOpZx(ArmEmitterContext context, Func2I emit)
|
||||
{
|
||||
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
||||
|
||||
|
@ -440,7 +419,7 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), d);
|
||||
}
|
||||
|
||||
public static void EmitScalarTernaryOpZx(EmitterContext context, Func3I emit)
|
||||
public static void EmitScalarTernaryOpZx(ArmEmitterContext context, Func3I emit)
|
||||
{
|
||||
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
||||
|
||||
|
@ -453,7 +432,7 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), d);
|
||||
}
|
||||
|
||||
public static void EmitScalarUnaryOpF(EmitterContext context, Func1I emit)
|
||||
public static void EmitScalarUnaryOpF(ArmEmitterContext context, Func1I emit)
|
||||
{
|
||||
OpCodeSimd op = (OpCodeSimd)context.CurrOp;
|
||||
|
||||
|
@ -464,7 +443,7 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), context.VectorInsert(context.VectorZero(), emit(n), 0));
|
||||
}
|
||||
|
||||
public static void EmitScalarBinaryOpF(EmitterContext context, Func2I emit)
|
||||
public static void EmitScalarBinaryOpF(ArmEmitterContext context, Func2I emit)
|
||||
{
|
||||
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
||||
|
||||
|
@ -476,7 +455,7 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), context.VectorInsert(context.VectorZero(), emit(n, m), 0));
|
||||
}
|
||||
|
||||
public static void EmitScalarTernaryRaOpF(EmitterContext context, Func3I emit)
|
||||
public static void EmitScalarTernaryRaOpF(ArmEmitterContext context, Func3I emit)
|
||||
{
|
||||
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
||||
|
||||
|
@ -489,7 +468,7 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), context.VectorInsert(context.VectorZero(), emit(a, n, m), 0));
|
||||
}
|
||||
|
||||
public static void EmitVectorUnaryOpF(EmitterContext context, Func1I emit)
|
||||
public static void EmitVectorUnaryOpF(ArmEmitterContext context, Func1I emit)
|
||||
{
|
||||
OpCodeSimd op = (OpCodeSimd)context.CurrOp;
|
||||
|
||||
|
@ -511,7 +490,7 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
||||
public static void EmitVectorBinaryOpF(EmitterContext context, Func2I emit)
|
||||
public static void EmitVectorBinaryOpF(ArmEmitterContext context, Func2I emit)
|
||||
{
|
||||
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
||||
|
||||
|
@ -534,7 +513,7 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
||||
public static void EmitVectorTernaryOpF(EmitterContext context, Func3I emit)
|
||||
public static void EmitVectorTernaryOpF(ArmEmitterContext context, Func3I emit)
|
||||
{
|
||||
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
||||
|
||||
|
@ -558,7 +537,7 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
||||
public static void EmitVectorBinaryOpByElemF(EmitterContext context, Func2I emit)
|
||||
public static void EmitVectorBinaryOpByElemF(ArmEmitterContext context, Func2I emit)
|
||||
{
|
||||
OpCodeSimdRegElemF op = (OpCodeSimdRegElemF)context.CurrOp;
|
||||
|
||||
|
@ -581,7 +560,7 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
||||
public static void EmitVectorTernaryOpByElemF(EmitterContext context, Func3I emit)
|
||||
public static void EmitVectorTernaryOpByElemF(ArmEmitterContext context, Func3I emit)
|
||||
{
|
||||
OpCodeSimdRegElemF op = (OpCodeSimdRegElemF)context.CurrOp;
|
||||
|
||||
|
@ -605,7 +584,7 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
||||
public static void EmitVectorUnaryOpSx(EmitterContext context, Func1I emit)
|
||||
public static void EmitVectorUnaryOpSx(ArmEmitterContext context, Func1I emit)
|
||||
{
|
||||
OpCodeSimd op = (OpCodeSimd)context.CurrOp;
|
||||
|
||||
|
@ -623,7 +602,7 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
||||
public static void EmitVectorBinaryOpSx(EmitterContext context, Func2I emit)
|
||||
public static void EmitVectorBinaryOpSx(ArmEmitterContext context, Func2I emit)
|
||||
{
|
||||
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
||||
|
||||
|
@ -642,7 +621,7 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
||||
public static void EmitVectorTernaryOpSx(EmitterContext context, Func3I emit)
|
||||
public static void EmitVectorTernaryOpSx(ArmEmitterContext context, Func3I emit)
|
||||
{
|
||||
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
||||
|
||||
|
@ -662,7 +641,7 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
||||
public static void EmitVectorUnaryOpZx(EmitterContext context, Func1I emit)
|
||||
public static void EmitVectorUnaryOpZx(ArmEmitterContext context, Func1I emit)
|
||||
{
|
||||
OpCodeSimd op = (OpCodeSimd)context.CurrOp;
|
||||
|
||||
|
@ -680,7 +659,7 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
||||
public static void EmitVectorBinaryOpZx(EmitterContext context, Func2I emit)
|
||||
public static void EmitVectorBinaryOpZx(ArmEmitterContext context, Func2I emit)
|
||||
{
|
||||
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
||||
|
||||
|
@ -699,7 +678,7 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
||||
public static void EmitVectorTernaryOpZx(EmitterContext context, Func3I emit)
|
||||
public static void EmitVectorTernaryOpZx(ArmEmitterContext context, Func3I emit)
|
||||
{
|
||||
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
||||
|
||||
|
@ -719,7 +698,7 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
||||
public static void EmitVectorBinaryOpByElemSx(EmitterContext context, Func2I emit)
|
||||
public static void EmitVectorBinaryOpByElemSx(ArmEmitterContext context, Func2I emit)
|
||||
{
|
||||
OpCodeSimdRegElem op = (OpCodeSimdRegElem)context.CurrOp;
|
||||
|
||||
|
@ -739,7 +718,7 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
||||
public static void EmitVectorBinaryOpByElemZx(EmitterContext context, Func2I emit)
|
||||
public static void EmitVectorBinaryOpByElemZx(ArmEmitterContext context, Func2I emit)
|
||||
{
|
||||
OpCodeSimdRegElem op = (OpCodeSimdRegElem)context.CurrOp;
|
||||
|
||||
|
@ -759,7 +738,7 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
||||
public static void EmitVectorTernaryOpByElemZx(EmitterContext context, Func3I emit)
|
||||
public static void EmitVectorTernaryOpByElemZx(ArmEmitterContext context, Func3I emit)
|
||||
{
|
||||
OpCodeSimdRegElem op = (OpCodeSimdRegElem)context.CurrOp;
|
||||
|
||||
|
@ -780,7 +759,7 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
||||
public static void EmitVectorImmUnaryOp(EmitterContext context, Func1I emit)
|
||||
public static void EmitVectorImmUnaryOp(ArmEmitterContext context, Func1I emit)
|
||||
{
|
||||
OpCodeSimdImm op = (OpCodeSimdImm)context.CurrOp;
|
||||
|
||||
|
@ -798,7 +777,7 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
||||
public static void EmitVectorImmBinaryOp(EmitterContext context, Func2I emit)
|
||||
public static void EmitVectorImmBinaryOp(ArmEmitterContext context, Func2I emit)
|
||||
{
|
||||
OpCodeSimdImm op = (OpCodeSimdImm)context.CurrOp;
|
||||
|
||||
|
@ -818,17 +797,17 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
||||
public static void EmitVectorWidenRmBinaryOpSx(EmitterContext context, Func2I emit)
|
||||
public static void EmitVectorWidenRmBinaryOpSx(ArmEmitterContext context, Func2I emit)
|
||||
{
|
||||
EmitVectorWidenRmBinaryOp(context, emit, signed: true);
|
||||
}
|
||||
|
||||
public static void EmitVectorWidenRmBinaryOpZx(EmitterContext context, Func2I emit)
|
||||
public static void EmitVectorWidenRmBinaryOpZx(ArmEmitterContext context, Func2I emit)
|
||||
{
|
||||
EmitVectorWidenRmBinaryOp(context, emit, signed: false);
|
||||
}
|
||||
|
||||
private static void EmitVectorWidenRmBinaryOp(EmitterContext context, Func2I emit, bool signed)
|
||||
private static void EmitVectorWidenRmBinaryOp(ArmEmitterContext context, Func2I emit, bool signed)
|
||||
{
|
||||
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
||||
|
||||
|
@ -849,17 +828,17 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
||||
public static void EmitVectorWidenRnRmBinaryOpSx(EmitterContext context, Func2I emit)
|
||||
public static void EmitVectorWidenRnRmBinaryOpSx(ArmEmitterContext context, Func2I emit)
|
||||
{
|
||||
EmitVectorWidenRnRmBinaryOp(context, emit, signed: true);
|
||||
}
|
||||
|
||||
public static void EmitVectorWidenRnRmBinaryOpZx(EmitterContext context, Func2I emit)
|
||||
public static void EmitVectorWidenRnRmBinaryOpZx(ArmEmitterContext context, Func2I emit)
|
||||
{
|
||||
EmitVectorWidenRnRmBinaryOp(context, emit, signed: false);
|
||||
}
|
||||
|
||||
private static void EmitVectorWidenRnRmBinaryOp(EmitterContext context, Func2I emit, bool signed)
|
||||
private static void EmitVectorWidenRnRmBinaryOp(ArmEmitterContext context, Func2I emit, bool signed)
|
||||
{
|
||||
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
||||
|
||||
|
@ -880,17 +859,17 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
||||
public static void EmitVectorWidenRnRmTernaryOpSx(EmitterContext context, Func3I emit)
|
||||
public static void EmitVectorWidenRnRmTernaryOpSx(ArmEmitterContext context, Func3I emit)
|
||||
{
|
||||
EmitVectorWidenRnRmTernaryOp(context, emit, signed: true);
|
||||
}
|
||||
|
||||
public static void EmitVectorWidenRnRmTernaryOpZx(EmitterContext context, Func3I emit)
|
||||
public static void EmitVectorWidenRnRmTernaryOpZx(ArmEmitterContext context, Func3I emit)
|
||||
{
|
||||
EmitVectorWidenRnRmTernaryOp(context, emit, signed: false);
|
||||
}
|
||||
|
||||
private static void EmitVectorWidenRnRmTernaryOp(EmitterContext context, Func3I emit, bool signed)
|
||||
private static void EmitVectorWidenRnRmTernaryOp(ArmEmitterContext context, Func3I emit, bool signed)
|
||||
{
|
||||
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
||||
|
||||
|
@ -912,17 +891,17 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
||||
public static void EmitVectorWidenBinaryOpByElemSx(EmitterContext context, Func2I emit)
|
||||
public static void EmitVectorWidenBinaryOpByElemSx(ArmEmitterContext context, Func2I emit)
|
||||
{
|
||||
EmitVectorWidenBinaryOpByElem(context, emit, signed: true);
|
||||
}
|
||||
|
||||
public static void EmitVectorWidenBinaryOpByElemZx(EmitterContext context, Func2I emit)
|
||||
public static void EmitVectorWidenBinaryOpByElemZx(ArmEmitterContext context, Func2I emit)
|
||||
{
|
||||
EmitVectorWidenBinaryOpByElem(context, emit, signed: false);
|
||||
}
|
||||
|
||||
private static void EmitVectorWidenBinaryOpByElem(EmitterContext context, Func2I emit, bool signed)
|
||||
private static void EmitVectorWidenBinaryOpByElem(ArmEmitterContext context, Func2I emit, bool signed)
|
||||
{
|
||||
OpCodeSimdRegElem op = (OpCodeSimdRegElem)context.CurrOp;
|
||||
|
||||
|
@ -944,17 +923,17 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
||||
public static void EmitVectorWidenTernaryOpByElemSx(EmitterContext context, Func3I emit)
|
||||
public static void EmitVectorWidenTernaryOpByElemSx(ArmEmitterContext context, Func3I emit)
|
||||
{
|
||||
EmitVectorWidenTernaryOpByElem(context, emit, signed: true);
|
||||
}
|
||||
|
||||
public static void EmitVectorWidenTernaryOpByElemZx(EmitterContext context, Func3I emit)
|
||||
public static void EmitVectorWidenTernaryOpByElemZx(ArmEmitterContext context, Func3I emit)
|
||||
{
|
||||
EmitVectorWidenTernaryOpByElem(context, emit, signed: false);
|
||||
}
|
||||
|
||||
private static void EmitVectorWidenTernaryOpByElem(EmitterContext context, Func3I emit, bool signed)
|
||||
private static void EmitVectorWidenTernaryOpByElem(ArmEmitterContext context, Func3I emit, bool signed)
|
||||
{
|
||||
OpCodeSimdRegElem op = (OpCodeSimdRegElem)context.CurrOp;
|
||||
|
||||
|
@ -977,17 +956,17 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
||||
public static void EmitVectorPairwiseOpSx(EmitterContext context, Func2I emit)
|
||||
public static void EmitVectorPairwiseOpSx(ArmEmitterContext context, Func2I emit)
|
||||
{
|
||||
EmitVectorPairwiseOp(context, emit, signed: true);
|
||||
}
|
||||
|
||||
public static void EmitVectorPairwiseOpZx(EmitterContext context, Func2I emit)
|
||||
public static void EmitVectorPairwiseOpZx(ArmEmitterContext context, Func2I emit)
|
||||
{
|
||||
EmitVectorPairwiseOp(context, emit, signed: false);
|
||||
}
|
||||
|
||||
private static void EmitVectorPairwiseOp(EmitterContext context, Func2I emit, bool signed)
|
||||
private static void EmitVectorPairwiseOp(ArmEmitterContext context, Func2I emit, bool signed)
|
||||
{
|
||||
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
||||
|
||||
|
@ -1012,28 +991,28 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
||||
public static void EmitVectorAcrossVectorOpSx(EmitterContext context, Func2I emit)
|
||||
public static void EmitVectorAcrossVectorOpSx(ArmEmitterContext context, Func2I emit)
|
||||
{
|
||||
EmitVectorAcrossVectorOp(context, emit, signed: true, isLong: false);
|
||||
}
|
||||
|
||||
public static void EmitVectorAcrossVectorOpZx(EmitterContext context, Func2I emit)
|
||||
public static void EmitVectorAcrossVectorOpZx(ArmEmitterContext context, Func2I emit)
|
||||
{
|
||||
EmitVectorAcrossVectorOp(context, emit, signed: false, isLong: false);
|
||||
}
|
||||
|
||||
public static void EmitVectorLongAcrossVectorOpSx(EmitterContext context, Func2I emit)
|
||||
public static void EmitVectorLongAcrossVectorOpSx(ArmEmitterContext context, Func2I emit)
|
||||
{
|
||||
EmitVectorAcrossVectorOp(context, emit, signed: true, isLong: true);
|
||||
}
|
||||
|
||||
public static void EmitVectorLongAcrossVectorOpZx(EmitterContext context, Func2I emit)
|
||||
public static void EmitVectorLongAcrossVectorOpZx(ArmEmitterContext context, Func2I emit)
|
||||
{
|
||||
EmitVectorAcrossVectorOp(context, emit, signed: false, isLong: true);
|
||||
}
|
||||
|
||||
private static void EmitVectorAcrossVectorOp(
|
||||
EmitterContext context,
|
||||
ArmEmitterContext context,
|
||||
Func2I emit,
|
||||
bool signed,
|
||||
bool isLong)
|
||||
|
@ -1058,7 +1037,7 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), d);
|
||||
}
|
||||
|
||||
public static void EmitVectorPairwiseOpF(EmitterContext context, Func2I emit)
|
||||
public static void EmitVectorPairwiseOpF(ArmEmitterContext context, Func2I emit)
|
||||
{
|
||||
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
||||
|
||||
|
@ -1087,7 +1066,7 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
||||
public static void EmitVectorPairwiseOpF(EmitterContext context, Instruction inst32, Instruction inst64)
|
||||
public static void EmitVectorPairwiseOpF(ArmEmitterContext context, Instruction inst32, Instruction inst64)
|
||||
{
|
||||
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
||||
|
||||
|
@ -1148,17 +1127,17 @@ namespace ARMeilleure.Instructions
|
|||
VectorZx = 0
|
||||
}
|
||||
|
||||
public static void EmitScalarSaturatingUnaryOpSx(EmitterContext context, Func1I emit)
|
||||
public static void EmitScalarSaturatingUnaryOpSx(ArmEmitterContext context, Func1I emit)
|
||||
{
|
||||
EmitSaturatingUnaryOpSx(context, emit, SaturatingFlags.ScalarSx);
|
||||
}
|
||||
|
||||
public static void EmitVectorSaturatingUnaryOpSx(EmitterContext context, Func1I emit)
|
||||
public static void EmitVectorSaturatingUnaryOpSx(ArmEmitterContext context, Func1I emit)
|
||||
{
|
||||
EmitSaturatingUnaryOpSx(context, emit, SaturatingFlags.VectorSx);
|
||||
}
|
||||
|
||||
private static void EmitSaturatingUnaryOpSx(EmitterContext context, Func1I emit, SaturatingFlags flags)
|
||||
private static void EmitSaturatingUnaryOpSx(ArmEmitterContext context, Func1I emit, SaturatingFlags flags)
|
||||
{
|
||||
OpCodeSimd op = (OpCodeSimd)context.CurrOp;
|
||||
|
||||
|
@ -1188,27 +1167,27 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
||||
public static void EmitScalarSaturatingBinaryOpSx(EmitterContext context, SaturatingFlags flags)
|
||||
public static void EmitScalarSaturatingBinaryOpSx(ArmEmitterContext context, SaturatingFlags flags)
|
||||
{
|
||||
EmitSaturatingBinaryOp(context, null, SaturatingFlags.ScalarSx | flags);
|
||||
}
|
||||
|
||||
public static void EmitScalarSaturatingBinaryOpZx(EmitterContext context, SaturatingFlags flags)
|
||||
public static void EmitScalarSaturatingBinaryOpZx(ArmEmitterContext context, SaturatingFlags flags)
|
||||
{
|
||||
EmitSaturatingBinaryOp(context, null, SaturatingFlags.ScalarZx | flags);
|
||||
}
|
||||
|
||||
public static void EmitVectorSaturatingBinaryOpSx(EmitterContext context, SaturatingFlags flags)
|
||||
public static void EmitVectorSaturatingBinaryOpSx(ArmEmitterContext context, SaturatingFlags flags)
|
||||
{
|
||||
EmitSaturatingBinaryOp(context, null, SaturatingFlags.VectorSx | flags);
|
||||
}
|
||||
|
||||
public static void EmitVectorSaturatingBinaryOpZx(EmitterContext context, SaturatingFlags flags)
|
||||
public static void EmitVectorSaturatingBinaryOpZx(ArmEmitterContext context, SaturatingFlags flags)
|
||||
{
|
||||
EmitSaturatingBinaryOp(context, null, SaturatingFlags.VectorZx | flags);
|
||||
}
|
||||
|
||||
public static void EmitSaturatingBinaryOp(EmitterContext context, Func2I emit, SaturatingFlags flags)
|
||||
public static void EmitSaturatingBinaryOp(ArmEmitterContext context, Func2I emit, SaturatingFlags flags)
|
||||
{
|
||||
OpCodeSimd op = (OpCodeSimd)context.CurrOp;
|
||||
|
||||
|
@ -1309,7 +1288,7 @@ namespace ARMeilleure.Instructions
|
|||
VectorZxZx = 0
|
||||
}
|
||||
|
||||
public static void EmitSaturatingNarrowOp(EmitterContext context, SaturatingNarrowFlags flags)
|
||||
public static void EmitSaturatingNarrowOp(ArmEmitterContext context, SaturatingNarrowFlags flags)
|
||||
{
|
||||
OpCodeSimd op = (OpCodeSimd)context.CurrOp;
|
||||
|
||||
|
@ -1336,83 +1315,86 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
|
||||
// TSrc (16bit, 32bit, 64bit; signed, unsigned) > TDst (8bit, 16bit, 32bit; signed, unsigned).
|
||||
public static Operand EmitSatQ(EmitterContext context, Operand op, int sizeDst, bool signedSrc, bool signedDst)
|
||||
public static Operand EmitSatQ(ArmEmitterContext context, Operand op, int sizeDst, bool signedSrc, bool signedDst)
|
||||
{
|
||||
if ((uint)sizeDst > 2u)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(sizeDst));
|
||||
}
|
||||
|
||||
string name;
|
||||
Delegate dlg;
|
||||
|
||||
if (signedSrc)
|
||||
{
|
||||
name = signedDst ? nameof(SoftFallback.SignedSrcSignedDstSatQ)
|
||||
: nameof(SoftFallback.SignedSrcUnsignedDstSatQ);
|
||||
dlg = signedDst
|
||||
? (Delegate)new _S64_S64_S32(SoftFallback.SignedSrcSignedDstSatQ)
|
||||
: (Delegate)new _U64_S64_S32(SoftFallback.SignedSrcUnsignedDstSatQ);
|
||||
}
|
||||
else
|
||||
{
|
||||
name = signedDst ? nameof(SoftFallback.UnsignedSrcSignedDstSatQ)
|
||||
: nameof(SoftFallback.UnsignedSrcUnsignedDstSatQ);
|
||||
dlg = signedDst
|
||||
? (Delegate)new _S64_U64_S32(SoftFallback.UnsignedSrcSignedDstSatQ)
|
||||
: (Delegate)new _U64_U64_S32(SoftFallback.UnsignedSrcUnsignedDstSatQ);
|
||||
}
|
||||
|
||||
MethodInfo info = typeof(SoftFallback).GetMethod(name);
|
||||
|
||||
return context.Call(info, op, Const(sizeDst));
|
||||
return context.Call(dlg, op, Const(sizeDst));
|
||||
}
|
||||
|
||||
// TSrc (64bit) == TDst (64bit); signed.
|
||||
public static Operand EmitUnarySignedSatQAbsOrNeg(EmitterContext context, Operand op)
|
||||
public static Operand EmitUnarySignedSatQAbsOrNeg(ArmEmitterContext context, Operand op)
|
||||
{
|
||||
Debug.Assert(((OpCodeSimd)context.CurrOp).Size == 3, "Invalid element size.");
|
||||
|
||||
return context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.UnarySignedSatQAbsOrNeg)), op);
|
||||
return context.Call(new _S64_S64(SoftFallback.UnarySignedSatQAbsOrNeg), op);
|
||||
}
|
||||
|
||||
// TSrcs (64bit) == TDst (64bit); signed, unsigned.
|
||||
public static Operand EmitBinarySatQAdd(EmitterContext context, Operand op1, Operand op2, bool signed)
|
||||
public static Operand EmitBinarySatQAdd(ArmEmitterContext context, Operand op1, Operand op2, bool signed)
|
||||
{
|
||||
Debug.Assert(((OpCodeSimd)context.CurrOp).Size == 3, "Invalid element size.");
|
||||
|
||||
string name = signed ? nameof(SoftFallback.BinarySignedSatQAdd)
|
||||
: nameof(SoftFallback.BinaryUnsignedSatQAdd);
|
||||
Delegate dlg = signed
|
||||
? (Delegate)new _S64_S64_S64(SoftFallback.BinarySignedSatQAdd)
|
||||
: (Delegate)new _U64_U64_U64(SoftFallback.BinaryUnsignedSatQAdd);
|
||||
|
||||
return context.Call(typeof(SoftFallback).GetMethod(name), op1, op2);
|
||||
return context.Call(dlg, op1, op2);
|
||||
}
|
||||
|
||||
// TSrcs (64bit) == TDst (64bit); signed, unsigned.
|
||||
public static Operand EmitBinarySatQSub(EmitterContext context, Operand op1, Operand op2, bool signed)
|
||||
public static Operand EmitBinarySatQSub(ArmEmitterContext context, Operand op1, Operand op2, bool signed)
|
||||
{
|
||||
Debug.Assert(((OpCodeSimd)context.CurrOp).Size == 3, "Invalid element size.");
|
||||
|
||||
string name = signed ? nameof(SoftFallback.BinarySignedSatQSub)
|
||||
: nameof(SoftFallback.BinaryUnsignedSatQSub);
|
||||
Delegate dlg = signed
|
||||
? (Delegate)new _S64_S64_S64(SoftFallback.BinarySignedSatQSub)
|
||||
: (Delegate)new _U64_U64_U64(SoftFallback.BinaryUnsignedSatQSub);
|
||||
|
||||
return context.Call(typeof(SoftFallback).GetMethod(name), op1, op2);
|
||||
return context.Call(dlg, op1, op2);
|
||||
}
|
||||
|
||||
// TSrcs (64bit) == TDst (64bit); signed, unsigned.
|
||||
public static Operand EmitBinarySatQAccumulate(EmitterContext context, Operand op1, Operand op2, bool signed)
|
||||
public static Operand EmitBinarySatQAccumulate(ArmEmitterContext context, Operand op1, Operand op2, bool signed)
|
||||
{
|
||||
Debug.Assert(((OpCodeSimd)context.CurrOp).Size == 3, "Invalid element size.");
|
||||
|
||||
string name = signed ? nameof(SoftFallback.BinarySignedSatQAcc)
|
||||
: nameof(SoftFallback.BinaryUnsignedSatQAcc);
|
||||
Delegate dlg = signed
|
||||
? (Delegate)new _S64_U64_S64(SoftFallback.BinarySignedSatQAcc)
|
||||
: (Delegate)new _U64_S64_U64(SoftFallback.BinaryUnsignedSatQAcc);
|
||||
|
||||
return context.Call(typeof(SoftFallback).GetMethod(name), op1, op2);
|
||||
return context.Call(dlg, op1, op2);
|
||||
}
|
||||
|
||||
public static Operand EmitVectorExtractSx(EmitterContext context, int reg, int index, int size)
|
||||
public static Operand EmitVectorExtractSx(ArmEmitterContext context, int reg, int index, int size)
|
||||
{
|
||||
return EmitVectorExtract(context, reg, index, size, true);
|
||||
}
|
||||
|
||||
public static Operand EmitVectorExtractZx(EmitterContext context, int reg, int index, int size)
|
||||
public static Operand EmitVectorExtractZx(ArmEmitterContext context, int reg, int index, int size)
|
||||
{
|
||||
return EmitVectorExtract(context, reg, index, size, false);
|
||||
}
|
||||
|
||||
public static Operand EmitVectorExtract(EmitterContext context, int reg, int index, int size, bool signed)
|
||||
public static Operand EmitVectorExtract(ArmEmitterContext context, int reg, int index, int size, bool signed)
|
||||
{
|
||||
ThrowIfInvalid(index, size);
|
||||
|
||||
|
@ -1459,7 +1441,7 @@ namespace ARMeilleure.Instructions
|
|||
return res;
|
||||
}
|
||||
|
||||
public static Operand EmitVectorInsert(EmitterContext context, Operand vector, Operand value, int index, int size)
|
||||
public static Operand EmitVectorInsert(ArmEmitterContext context, Operand vector, Operand value, int index, int size)
|
||||
{
|
||||
ThrowIfInvalid(index, size);
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
using ARMeilleure.Decoders;
|
||||
using ARMeilleure.IntermediateRepresentation;
|
||||
using ARMeilleure.Translation;
|
||||
using System.Reflection;
|
||||
|
||||
using static ARMeilleure.Instructions.InstEmitHelper;
|
||||
using static ARMeilleure.Instructions.InstEmitSimdHelper;
|
||||
|
@ -11,7 +10,7 @@ namespace ARMeilleure.Instructions
|
|||
{
|
||||
static partial class InstEmit
|
||||
{
|
||||
public static void And_V(EmitterContext context)
|
||||
public static void And_V(ArmEmitterContext context)
|
||||
{
|
||||
if (Optimizations.UseSse2)
|
||||
{
|
||||
|
@ -35,7 +34,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Bic_V(EmitterContext context)
|
||||
public static void Bic_V(ArmEmitterContext context)
|
||||
{
|
||||
if (Optimizations.UseSse2)
|
||||
{
|
||||
|
@ -62,7 +61,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Bic_Vi(EmitterContext context)
|
||||
public static void Bic_Vi(ArmEmitterContext context)
|
||||
{
|
||||
EmitVectorImmBinaryOp(context, (op1, op2) =>
|
||||
{
|
||||
|
@ -70,17 +69,17 @@ namespace ARMeilleure.Instructions
|
|||
});
|
||||
}
|
||||
|
||||
public static void Bif_V(EmitterContext context)
|
||||
public static void Bif_V(ArmEmitterContext context)
|
||||
{
|
||||
EmitBifBit(context, notRm: true);
|
||||
}
|
||||
|
||||
public static void Bit_V(EmitterContext context)
|
||||
public static void Bit_V(ArmEmitterContext context)
|
||||
{
|
||||
EmitBifBit(context, notRm: false);
|
||||
}
|
||||
|
||||
private static void EmitBifBit(EmitterContext context, bool notRm)
|
||||
private static void EmitBifBit(ArmEmitterContext context, bool notRm)
|
||||
{
|
||||
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
||||
|
||||
|
@ -139,7 +138,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Bsl_V(EmitterContext context)
|
||||
public static void Bsl_V(ArmEmitterContext context)
|
||||
{
|
||||
if (Optimizations.UseSse2)
|
||||
{
|
||||
|
@ -172,7 +171,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Eor_V(EmitterContext context)
|
||||
public static void Eor_V(ArmEmitterContext context)
|
||||
{
|
||||
if (Optimizations.UseSse2)
|
||||
{
|
||||
|
@ -196,7 +195,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Not_V(EmitterContext context)
|
||||
public static void Not_V(ArmEmitterContext context)
|
||||
{
|
||||
if (Optimizations.UseSse2)
|
||||
{
|
||||
|
@ -221,7 +220,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Orn_V(EmitterContext context)
|
||||
public static void Orn_V(ArmEmitterContext context)
|
||||
{
|
||||
if (Optimizations.UseSse2)
|
||||
{
|
||||
|
@ -252,7 +251,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Orr_V(EmitterContext context)
|
||||
public static void Orr_V(ArmEmitterContext context)
|
||||
{
|
||||
if (Optimizations.UseSse2)
|
||||
{
|
||||
|
@ -276,12 +275,12 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Orr_Vi(EmitterContext context)
|
||||
public static void Orr_Vi(ArmEmitterContext context)
|
||||
{
|
||||
EmitVectorImmBinaryOp(context, (op1, op2) => context.BitwiseOr(op1, op2));
|
||||
}
|
||||
|
||||
public static void Rbit_V(EmitterContext context)
|
||||
public static void Rbit_V(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimd op = (OpCodeSimd)context.CurrOp;
|
||||
|
||||
|
@ -295,9 +294,7 @@ namespace ARMeilleure.Instructions
|
|||
|
||||
ne = context.ConvertI64ToI32(ne);
|
||||
|
||||
MethodInfo info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.ReverseBits8));
|
||||
|
||||
Operand de = context.Call(info, ne);
|
||||
Operand de = context.Call(new _U32_U32(SoftFallback.ReverseBits8), ne);
|
||||
|
||||
de = context.ZeroExtend32(OperandType.I64, de);
|
||||
|
||||
|
@ -307,7 +304,7 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
||||
public static void Rev16_V(EmitterContext context)
|
||||
public static void Rev16_V(ArmEmitterContext context)
|
||||
{
|
||||
if (Optimizations.UseSsse3)
|
||||
{
|
||||
|
@ -337,7 +334,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Rev32_V(EmitterContext context)
|
||||
public static void Rev32_V(ArmEmitterContext context)
|
||||
{
|
||||
if (Optimizations.UseSsse3)
|
||||
{
|
||||
|
@ -381,7 +378,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Rev64_V(EmitterContext context)
|
||||
public static void Rev64_V(ArmEmitterContext context)
|
||||
{
|
||||
if (Optimizations.UseSsse3)
|
||||
{
|
||||
|
@ -434,7 +431,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
private static void EmitRev_V(EmitterContext context, int containerSize)
|
||||
private static void EmitRev_V(ArmEmitterContext context, int containerSize)
|
||||
{
|
||||
OpCodeSimd op = (OpCodeSimd)context.CurrOp;
|
||||
|
||||
|
|
|
@ -12,27 +12,27 @@ namespace ARMeilleure.Instructions
|
|||
{
|
||||
static partial class InstEmit
|
||||
{
|
||||
public static void Ld__Vms(EmitterContext context)
|
||||
public static void Ld__Vms(ArmEmitterContext context)
|
||||
{
|
||||
EmitSimdMemMs(context, isLoad: true);
|
||||
}
|
||||
|
||||
public static void Ld__Vss(EmitterContext context)
|
||||
public static void Ld__Vss(ArmEmitterContext context)
|
||||
{
|
||||
EmitSimdMemSs(context, isLoad: true);
|
||||
}
|
||||
|
||||
public static void St__Vms(EmitterContext context)
|
||||
public static void St__Vms(ArmEmitterContext context)
|
||||
{
|
||||
EmitSimdMemMs(context, isLoad: false);
|
||||
}
|
||||
|
||||
public static void St__Vss(EmitterContext context)
|
||||
public static void St__Vss(ArmEmitterContext context)
|
||||
{
|
||||
EmitSimdMemSs(context, isLoad: false);
|
||||
}
|
||||
|
||||
private static void EmitSimdMemMs(EmitterContext context, bool isLoad)
|
||||
private static void EmitSimdMemMs(ArmEmitterContext context, bool isLoad)
|
||||
{
|
||||
OpCodeSimdMemMs op = (OpCodeSimdMemMs)context.CurrOp;
|
||||
|
||||
|
@ -73,7 +73,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
private static void EmitSimdMemSs(EmitterContext context, bool isLoad)
|
||||
private static void EmitSimdMemSs(ArmEmitterContext context, bool isLoad)
|
||||
{
|
||||
OpCodeSimdMemSs op = (OpCodeSimdMemSs)context.CurrOp;
|
||||
|
||||
|
@ -138,7 +138,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
private static void EmitSimdMemWBack(EmitterContext context, long offset)
|
||||
private static void EmitSimdMemWBack(ArmEmitterContext context, long offset)
|
||||
{
|
||||
OpCodeMemReg op = (OpCodeMemReg)context.CurrOp;
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using ARMeilleure.Decoders;
|
||||
using ARMeilleure.IntermediateRepresentation;
|
||||
using ARMeilleure.Translation;
|
||||
using System;
|
||||
|
||||
using static ARMeilleure.Instructions.InstEmitHelper;
|
||||
using static ARMeilleure.Instructions.InstEmitSimdHelper;
|
||||
|
@ -38,7 +39,7 @@ namespace ARMeilleure.Instructions
|
|||
};
|
||||
#endregion
|
||||
|
||||
public static void Dup_Gp(EmitterContext context)
|
||||
public static void Dup_Gp(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimdIns op = (OpCodeSimdIns)context.CurrOp;
|
||||
|
||||
|
@ -88,7 +89,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Dup_S(EmitterContext context)
|
||||
public static void Dup_S(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimdIns op = (OpCodeSimdIns)context.CurrOp;
|
||||
|
||||
|
@ -97,7 +98,7 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), EmitVectorInsert(context, context.VectorZero(), ne, 0, op.Size));
|
||||
}
|
||||
|
||||
public static void Dup_V(EmitterContext context)
|
||||
public static void Dup_V(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimdIns op = (OpCodeSimdIns)context.CurrOp;
|
||||
|
||||
|
@ -165,7 +166,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Ext_V(EmitterContext context)
|
||||
public static void Ext_V(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimdExt op = (OpCodeSimdExt)context.CurrOp;
|
||||
|
||||
|
@ -216,7 +217,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Fcsel_S(EmitterContext context)
|
||||
public static void Fcsel_S(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimdFcond op = (OpCodeSimdFcond)context.CurrOp;
|
||||
|
||||
|
@ -244,7 +245,7 @@ namespace ARMeilleure.Instructions
|
|||
context.MarkLabel(lblEnd);
|
||||
}
|
||||
|
||||
public static void Fmov_Ftoi(EmitterContext context)
|
||||
public static void Fmov_Ftoi(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimd op = (OpCodeSimd)context.CurrOp;
|
||||
|
||||
|
@ -253,7 +254,7 @@ namespace ARMeilleure.Instructions
|
|||
SetIntOrZR(context, op.Rd, ne);
|
||||
}
|
||||
|
||||
public static void Fmov_Ftoi1(EmitterContext context)
|
||||
public static void Fmov_Ftoi1(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimd op = (OpCodeSimd)context.CurrOp;
|
||||
|
||||
|
@ -262,7 +263,7 @@ namespace ARMeilleure.Instructions
|
|||
SetIntOrZR(context, op.Rd, ne);
|
||||
}
|
||||
|
||||
public static void Fmov_Itof(EmitterContext context)
|
||||
public static void Fmov_Itof(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimd op = (OpCodeSimd)context.CurrOp;
|
||||
|
||||
|
@ -271,7 +272,7 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), EmitVectorInsert(context, context.VectorZero(), n, 0, op.Size + 2));
|
||||
}
|
||||
|
||||
public static void Fmov_Itof1(EmitterContext context)
|
||||
public static void Fmov_Itof1(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimd op = (OpCodeSimd)context.CurrOp;
|
||||
|
||||
|
@ -280,7 +281,7 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), EmitVectorInsert(context, GetVec(op.Rd), n, 1, 3));
|
||||
}
|
||||
|
||||
public static void Fmov_S(EmitterContext context)
|
||||
public static void Fmov_S(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimd op = (OpCodeSimd)context.CurrOp;
|
||||
|
||||
|
@ -291,7 +292,7 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), context.VectorInsert(context.VectorZero(), ne, 0));
|
||||
}
|
||||
|
||||
public static void Fmov_Si(EmitterContext context)
|
||||
public static void Fmov_Si(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimdFmov op = (OpCodeSimdFmov)context.CurrOp;
|
||||
|
||||
|
@ -305,7 +306,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Fmov_Vi(EmitterContext context)
|
||||
public static void Fmov_Vi(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimdImm op = (OpCodeSimdImm)context.CurrOp;
|
||||
|
||||
|
@ -323,7 +324,7 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
||||
public static void Ins_Gp(EmitterContext context)
|
||||
public static void Ins_Gp(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimdIns op = (OpCodeSimdIns)context.CurrOp;
|
||||
|
||||
|
@ -333,7 +334,7 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(d, EmitVectorInsert(context, d, n, op.DstIndex, op.Size));
|
||||
}
|
||||
|
||||
public static void Ins_V(EmitterContext context)
|
||||
public static void Ins_V(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimdIns op = (OpCodeSimdIns)context.CurrOp;
|
||||
|
||||
|
@ -343,7 +344,7 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(d, EmitVectorInsert(context, d, ne, op.DstIndex, op.Size));
|
||||
}
|
||||
|
||||
public static void Movi_V(EmitterContext context)
|
||||
public static void Movi_V(ArmEmitterContext context)
|
||||
{
|
||||
if (Optimizations.UseSse2)
|
||||
{
|
||||
|
@ -355,7 +356,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Mvni_V(EmitterContext context)
|
||||
public static void Mvni_V(ArmEmitterContext context)
|
||||
{
|
||||
if (Optimizations.UseSse2)
|
||||
{
|
||||
|
@ -367,7 +368,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Smov_S(EmitterContext context)
|
||||
public static void Smov_S(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimdIns op = (OpCodeSimdIns)context.CurrOp;
|
||||
|
||||
|
@ -381,7 +382,7 @@ namespace ARMeilleure.Instructions
|
|||
SetIntOrZR(context, op.Rd, ne);
|
||||
}
|
||||
|
||||
public static void Tbl_V(EmitterContext context)
|
||||
public static void Tbl_V(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimdTbl op = (OpCodeSimdTbl)context.CurrOp;
|
||||
|
||||
|
@ -433,42 +434,42 @@ namespace ARMeilleure.Instructions
|
|||
args[1 + index] = GetVec((op.Rn + index) & 0x1f);
|
||||
}
|
||||
|
||||
string name = null;
|
||||
Delegate dlg = null;
|
||||
|
||||
switch (op.Size)
|
||||
{
|
||||
case 1: name = op.RegisterSize == RegisterSize.Simd64
|
||||
? nameof(SoftFallback.Tbl1_V64)
|
||||
: nameof(SoftFallback.Tbl1_V128); break;
|
||||
case 1: dlg = op.RegisterSize == RegisterSize.Simd64
|
||||
? (Delegate)new _V128_V128_V128(SoftFallback.Tbl1_V64)
|
||||
: (Delegate)new _V128_V128_V128(SoftFallback.Tbl1_V128); break;
|
||||
|
||||
case 2: name = op.RegisterSize == RegisterSize.Simd64
|
||||
? nameof(SoftFallback.Tbl2_V64)
|
||||
: nameof(SoftFallback.Tbl2_V128); break;
|
||||
case 2: dlg = op.RegisterSize == RegisterSize.Simd64
|
||||
? (Delegate)new _V128_V128_V128_V128(SoftFallback.Tbl2_V64)
|
||||
: (Delegate)new _V128_V128_V128_V128(SoftFallback.Tbl2_V128); break;
|
||||
|
||||
case 3: name = op.RegisterSize == RegisterSize.Simd64
|
||||
? nameof(SoftFallback.Tbl3_V64)
|
||||
: nameof(SoftFallback.Tbl3_V128); break;
|
||||
case 3: dlg = op.RegisterSize == RegisterSize.Simd64
|
||||
? (Delegate)new _V128_V128_V128_V128_V128(SoftFallback.Tbl3_V64)
|
||||
: (Delegate)new _V128_V128_V128_V128_V128(SoftFallback.Tbl3_V128); break;
|
||||
|
||||
case 4: name = op.RegisterSize == RegisterSize.Simd64
|
||||
? nameof(SoftFallback.Tbl4_V64)
|
||||
: nameof(SoftFallback.Tbl4_V128); break;
|
||||
case 4: dlg = op.RegisterSize == RegisterSize.Simd64
|
||||
? (Delegate)new _V128_V128_V128_V128_V128_V128(SoftFallback.Tbl4_V64)
|
||||
: (Delegate)new _V128_V128_V128_V128_V128_V128(SoftFallback.Tbl4_V128); break;
|
||||
}
|
||||
|
||||
context.Copy(GetVec(op.Rd), context.Call(typeof(SoftFallback).GetMethod(name), args));
|
||||
context.Copy(GetVec(op.Rd), context.Call(dlg, args));
|
||||
}
|
||||
}
|
||||
|
||||
public static void Trn1_V(EmitterContext context)
|
||||
public static void Trn1_V(ArmEmitterContext context)
|
||||
{
|
||||
EmitVectorTranspose(context, part: 0);
|
||||
}
|
||||
|
||||
public static void Trn2_V(EmitterContext context)
|
||||
public static void Trn2_V(ArmEmitterContext context)
|
||||
{
|
||||
EmitVectorTranspose(context, part: 1);
|
||||
}
|
||||
|
||||
public static void Umov_S(EmitterContext context)
|
||||
public static void Umov_S(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimdIns op = (OpCodeSimdIns)context.CurrOp;
|
||||
|
||||
|
@ -477,17 +478,17 @@ namespace ARMeilleure.Instructions
|
|||
SetIntOrZR(context, op.Rd, ne);
|
||||
}
|
||||
|
||||
public static void Uzp1_V(EmitterContext context)
|
||||
public static void Uzp1_V(ArmEmitterContext context)
|
||||
{
|
||||
EmitVectorUnzip(context, part: 0);
|
||||
}
|
||||
|
||||
public static void Uzp2_V(EmitterContext context)
|
||||
public static void Uzp2_V(ArmEmitterContext context)
|
||||
{
|
||||
EmitVectorUnzip(context, part: 1);
|
||||
}
|
||||
|
||||
public static void Xtn_V(EmitterContext context)
|
||||
public static void Xtn_V(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimd op = (OpCodeSimd)context.CurrOp;
|
||||
|
||||
|
@ -530,17 +531,17 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Zip1_V(EmitterContext context)
|
||||
public static void Zip1_V(ArmEmitterContext context)
|
||||
{
|
||||
EmitVectorZip(context, part: 0);
|
||||
}
|
||||
|
||||
public static void Zip2_V(EmitterContext context)
|
||||
public static void Zip2_V(ArmEmitterContext context)
|
||||
{
|
||||
EmitVectorZip(context, part: 1);
|
||||
}
|
||||
|
||||
private static void EmitMoviMvni(EmitterContext context, bool not)
|
||||
private static void EmitMoviMvni(ArmEmitterContext context, bool not)
|
||||
{
|
||||
OpCodeSimdImm op = (OpCodeSimdImm)context.CurrOp;
|
||||
|
||||
|
@ -576,7 +577,7 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), mask);
|
||||
}
|
||||
|
||||
private static void EmitVectorTranspose(EmitterContext context, int part)
|
||||
private static void EmitVectorTranspose(ArmEmitterContext context, int part)
|
||||
{
|
||||
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
||||
|
||||
|
@ -642,7 +643,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
private static void EmitVectorUnzip(EmitterContext context, int part)
|
||||
private static void EmitVectorUnzip(ArmEmitterContext context, int part)
|
||||
{
|
||||
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
||||
|
||||
|
@ -735,7 +736,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
private static void EmitVectorZip(EmitterContext context, int part)
|
||||
private static void EmitVectorZip(ArmEmitterContext context, int part)
|
||||
{
|
||||
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@ using ARMeilleure.Decoders;
|
|||
using ARMeilleure.IntermediateRepresentation;
|
||||
using ARMeilleure.Translation;
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
using static ARMeilleure.Instructions.InstEmitHelper;
|
||||
using static ARMeilleure.Instructions.InstEmitSimdHelper;
|
||||
|
@ -25,7 +24,7 @@ namespace ARMeilleure.Instructions
|
|||
};
|
||||
#endregion
|
||||
|
||||
public static void Rshrn_V(EmitterContext context)
|
||||
public static void Rshrn_V(ArmEmitterContext context)
|
||||
{
|
||||
if (Optimizations.UseSsse3)
|
||||
{
|
||||
|
@ -75,7 +74,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Shl_S(EmitterContext context)
|
||||
public static void Shl_S(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimdShImm op = (OpCodeSimdShImm)context.CurrOp;
|
||||
|
||||
|
@ -84,7 +83,7 @@ namespace ARMeilleure.Instructions
|
|||
EmitScalarUnaryOpZx(context, (op1) => context.ShiftLeft(op1, Const(shift)));
|
||||
}
|
||||
|
||||
public static void Shl_V(EmitterContext context)
|
||||
public static void Shl_V(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimdShImm op = (OpCodeSimdShImm)context.CurrOp;
|
||||
|
||||
|
@ -111,7 +110,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Shll_V(EmitterContext context)
|
||||
public static void Shll_V(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimd op = (OpCodeSimd)context.CurrOp;
|
||||
|
||||
|
@ -142,7 +141,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Shrn_V(EmitterContext context)
|
||||
public static void Shrn_V(ArmEmitterContext context)
|
||||
{
|
||||
if (Optimizations.UseSsse3)
|
||||
{
|
||||
|
@ -179,7 +178,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Sli_V(EmitterContext context)
|
||||
public static void Sli_V(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimdShImm op = (OpCodeSimdShImm)context.CurrOp;
|
||||
|
||||
|
@ -209,7 +208,7 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
||||
public static void Sqrshl_V(EmitterContext context)
|
||||
public static void Sqrshl_V(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
||||
|
||||
|
@ -222,9 +221,7 @@ namespace ARMeilleure.Instructions
|
|||
Operand ne = EmitVectorExtractSx(context, op.Rn, index, op.Size);
|
||||
Operand me = EmitVectorExtractSx(context, op.Rm, index, op.Size);
|
||||
|
||||
MethodInfo info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.SignedShlRegSatQ));
|
||||
|
||||
Operand e = context.Call(info, ne, me, Const(1), Const(op.Size));
|
||||
Operand e = context.Call(new _S64_S64_S64_Bool_S32(SoftFallback.SignedShlRegSatQ), ne, me, Const(1), Const(op.Size));
|
||||
|
||||
res = EmitVectorInsert(context, res, e, index, op.Size);
|
||||
}
|
||||
|
@ -232,27 +229,27 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
||||
public static void Sqrshrn_S(EmitterContext context)
|
||||
public static void Sqrshrn_S(ArmEmitterContext context)
|
||||
{
|
||||
EmitRoundShrImmSaturatingNarrowOp(context, ShrImmSaturatingNarrowFlags.ScalarSxSx);
|
||||
}
|
||||
|
||||
public static void Sqrshrn_V(EmitterContext context)
|
||||
public static void Sqrshrn_V(ArmEmitterContext context)
|
||||
{
|
||||
EmitRoundShrImmSaturatingNarrowOp(context, ShrImmSaturatingNarrowFlags.VectorSxSx);
|
||||
}
|
||||
|
||||
public static void Sqrshrun_S(EmitterContext context)
|
||||
public static void Sqrshrun_S(ArmEmitterContext context)
|
||||
{
|
||||
EmitRoundShrImmSaturatingNarrowOp(context, ShrImmSaturatingNarrowFlags.ScalarSxZx);
|
||||
}
|
||||
|
||||
public static void Sqrshrun_V(EmitterContext context)
|
||||
public static void Sqrshrun_V(ArmEmitterContext context)
|
||||
{
|
||||
EmitRoundShrImmSaturatingNarrowOp(context, ShrImmSaturatingNarrowFlags.VectorSxZx);
|
||||
}
|
||||
|
||||
public static void Sqshl_V(EmitterContext context)
|
||||
public static void Sqshl_V(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
||||
|
||||
|
@ -265,9 +262,7 @@ namespace ARMeilleure.Instructions
|
|||
Operand ne = EmitVectorExtractSx(context, op.Rn, index, op.Size);
|
||||
Operand me = EmitVectorExtractSx(context, op.Rm, index, op.Size);
|
||||
|
||||
MethodInfo info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.SignedShlRegSatQ));
|
||||
|
||||
Operand e = context.Call(info, ne, me, Const(0), Const(op.Size));
|
||||
Operand e = context.Call(new _S64_S64_S64_Bool_S32(SoftFallback.SignedShlRegSatQ), ne, me, Const(0), Const(op.Size));
|
||||
|
||||
res = EmitVectorInsert(context, res, e, index, op.Size);
|
||||
}
|
||||
|
@ -275,27 +270,27 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
||||
public static void Sqshrn_S(EmitterContext context)
|
||||
public static void Sqshrn_S(ArmEmitterContext context)
|
||||
{
|
||||
EmitShrImmSaturatingNarrowOp(context, ShrImmSaturatingNarrowFlags.ScalarSxSx);
|
||||
}
|
||||
|
||||
public static void Sqshrn_V(EmitterContext context)
|
||||
public static void Sqshrn_V(ArmEmitterContext context)
|
||||
{
|
||||
EmitShrImmSaturatingNarrowOp(context, ShrImmSaturatingNarrowFlags.VectorSxSx);
|
||||
}
|
||||
|
||||
public static void Sqshrun_S(EmitterContext context)
|
||||
public static void Sqshrun_S(ArmEmitterContext context)
|
||||
{
|
||||
EmitShrImmSaturatingNarrowOp(context, ShrImmSaturatingNarrowFlags.ScalarSxZx);
|
||||
}
|
||||
|
||||
public static void Sqshrun_V(EmitterContext context)
|
||||
public static void Sqshrun_V(ArmEmitterContext context)
|
||||
{
|
||||
EmitShrImmSaturatingNarrowOp(context, ShrImmSaturatingNarrowFlags.VectorSxZx);
|
||||
}
|
||||
|
||||
public static void Srshl_V(EmitterContext context)
|
||||
public static void Srshl_V(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
||||
|
||||
|
@ -308,9 +303,7 @@ namespace ARMeilleure.Instructions
|
|||
Operand ne = EmitVectorExtractSx(context, op.Rn, index, op.Size);
|
||||
Operand me = EmitVectorExtractSx(context, op.Rm, index, op.Size);
|
||||
|
||||
MethodInfo info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.SignedShlReg));
|
||||
|
||||
Operand e = context.Call(info, ne, me, Const(1), Const(op.Size));
|
||||
Operand e = context.Call(new _S64_S64_S64_Bool_S32(SoftFallback.SignedShlReg), ne, me, Const(1), Const(op.Size));
|
||||
|
||||
res = EmitVectorInsert(context, res, e, index, op.Size);
|
||||
}
|
||||
|
@ -318,12 +311,12 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
||||
public static void Srshr_S(EmitterContext context)
|
||||
public static void Srshr_S(ArmEmitterContext context)
|
||||
{
|
||||
EmitScalarShrImmOpSx(context, ShrImmFlags.Round);
|
||||
}
|
||||
|
||||
public static void Srshr_V(EmitterContext context)
|
||||
public static void Srshr_V(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimdShImm op = (OpCodeSimdShImm)context.CurrOp;
|
||||
|
||||
|
@ -363,12 +356,12 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Srsra_S(EmitterContext context)
|
||||
public static void Srsra_S(ArmEmitterContext context)
|
||||
{
|
||||
EmitScalarShrImmOpSx(context, ShrImmFlags.Round | ShrImmFlags.Accumulate);
|
||||
}
|
||||
|
||||
public static void Srsra_V(EmitterContext context)
|
||||
public static void Srsra_V(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimdShImm op = (OpCodeSimdShImm)context.CurrOp;
|
||||
|
||||
|
@ -410,7 +403,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Sshl_V(EmitterContext context)
|
||||
public static void Sshl_V(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
||||
|
||||
|
@ -423,9 +416,7 @@ namespace ARMeilleure.Instructions
|
|||
Operand ne = EmitVectorExtractSx(context, op.Rn, index, op.Size);
|
||||
Operand me = EmitVectorExtractSx(context, op.Rm, index, op.Size);
|
||||
|
||||
MethodInfo info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.SignedShlReg));
|
||||
|
||||
Operand e = context.Call(info, ne, me, Const(0), Const(op.Size));
|
||||
Operand e = context.Call(new _S64_S64_S64_Bool_S32(SoftFallback.SignedShlReg), ne, me, Const(0), Const(op.Size));
|
||||
|
||||
res = EmitVectorInsert(context, res, e, index, op.Size);
|
||||
}
|
||||
|
@ -433,7 +424,7 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
||||
public static void Sshll_V(EmitterContext context)
|
||||
public static void Sshll_V(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimdShImm op = (OpCodeSimdShImm)context.CurrOp;
|
||||
|
||||
|
@ -467,12 +458,12 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Sshr_S(EmitterContext context)
|
||||
public static void Sshr_S(ArmEmitterContext context)
|
||||
{
|
||||
EmitShrImmOp(context, ShrImmFlags.ScalarSx);
|
||||
}
|
||||
|
||||
public static void Sshr_V(EmitterContext context)
|
||||
public static void Sshr_V(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimdShImm op = (OpCodeSimdShImm)context.CurrOp;
|
||||
|
||||
|
@ -499,12 +490,12 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Ssra_S(EmitterContext context)
|
||||
public static void Ssra_S(ArmEmitterContext context)
|
||||
{
|
||||
EmitScalarShrImmOpSx(context, ShrImmFlags.Accumulate);
|
||||
}
|
||||
|
||||
public static void Ssra_V(EmitterContext context)
|
||||
public static void Ssra_V(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimdShImm op = (OpCodeSimdShImm)context.CurrOp;
|
||||
|
||||
|
@ -536,7 +527,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Uqrshl_V(EmitterContext context)
|
||||
public static void Uqrshl_V(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
||||
|
||||
|
@ -549,9 +540,7 @@ namespace ARMeilleure.Instructions
|
|||
Operand ne = EmitVectorExtractZx(context, op.Rn, index, op.Size);
|
||||
Operand me = EmitVectorExtractZx(context, op.Rm, index, op.Size);
|
||||
|
||||
MethodInfo info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.UnsignedShlRegSatQ));
|
||||
|
||||
Operand e = context.Call(info, ne, me, Const(1), Const(op.Size));
|
||||
Operand e = context.Call(new _U64_U64_U64_Bool_S32(SoftFallback.UnsignedShlRegSatQ), ne, me, Const(1), Const(op.Size));
|
||||
|
||||
res = EmitVectorInsert(context, res, e, index, op.Size);
|
||||
}
|
||||
|
@ -559,17 +548,17 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
||||
public static void Uqrshrn_S(EmitterContext context)
|
||||
public static void Uqrshrn_S(ArmEmitterContext context)
|
||||
{
|
||||
EmitRoundShrImmSaturatingNarrowOp(context, ShrImmSaturatingNarrowFlags.ScalarZxZx);
|
||||
}
|
||||
|
||||
public static void Uqrshrn_V(EmitterContext context)
|
||||
public static void Uqrshrn_V(ArmEmitterContext context)
|
||||
{
|
||||
EmitRoundShrImmSaturatingNarrowOp(context, ShrImmSaturatingNarrowFlags.VectorZxZx);
|
||||
}
|
||||
|
||||
public static void Uqshl_V(EmitterContext context)
|
||||
public static void Uqshl_V(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
||||
|
||||
|
@ -582,9 +571,7 @@ namespace ARMeilleure.Instructions
|
|||
Operand ne = EmitVectorExtractZx(context, op.Rn, index, op.Size);
|
||||
Operand me = EmitVectorExtractZx(context, op.Rm, index, op.Size);
|
||||
|
||||
MethodInfo info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.UnsignedShlRegSatQ));
|
||||
|
||||
Operand e = context.Call(info, ne, me, Const(0), Const(op.Size));
|
||||
Operand e = context.Call(new _U64_U64_U64_Bool_S32(SoftFallback.UnsignedShlRegSatQ), ne, me, Const(0), Const(op.Size));
|
||||
|
||||
res = EmitVectorInsert(context, res, e, index, op.Size);
|
||||
}
|
||||
|
@ -592,17 +579,17 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
||||
public static void Uqshrn_S(EmitterContext context)
|
||||
public static void Uqshrn_S(ArmEmitterContext context)
|
||||
{
|
||||
EmitShrImmSaturatingNarrowOp(context, ShrImmSaturatingNarrowFlags.ScalarZxZx);
|
||||
}
|
||||
|
||||
public static void Uqshrn_V(EmitterContext context)
|
||||
public static void Uqshrn_V(ArmEmitterContext context)
|
||||
{
|
||||
EmitShrImmSaturatingNarrowOp(context, ShrImmSaturatingNarrowFlags.VectorZxZx);
|
||||
}
|
||||
|
||||
public static void Urshl_V(EmitterContext context)
|
||||
public static void Urshl_V(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
||||
|
||||
|
@ -615,9 +602,7 @@ namespace ARMeilleure.Instructions
|
|||
Operand ne = EmitVectorExtractZx(context, op.Rn, index, op.Size);
|
||||
Operand me = EmitVectorExtractZx(context, op.Rm, index, op.Size);
|
||||
|
||||
MethodInfo info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.UnsignedShlReg));
|
||||
|
||||
Operand e = context.Call(info, ne, me, Const(1), Const(op.Size));
|
||||
Operand e = context.Call(new _U64_U64_U64_Bool_S32(SoftFallback.UnsignedShlReg), ne, me, Const(1), Const(op.Size));
|
||||
|
||||
res = EmitVectorInsert(context, res, e, index, op.Size);
|
||||
}
|
||||
|
@ -625,12 +610,12 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
||||
public static void Urshr_S(EmitterContext context)
|
||||
public static void Urshr_S(ArmEmitterContext context)
|
||||
{
|
||||
EmitScalarShrImmOpZx(context, ShrImmFlags.Round);
|
||||
}
|
||||
|
||||
public static void Urshr_V(EmitterContext context)
|
||||
public static void Urshr_V(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimdShImm op = (OpCodeSimdShImm)context.CurrOp;
|
||||
|
||||
|
@ -668,12 +653,12 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Ursra_S(EmitterContext context)
|
||||
public static void Ursra_S(ArmEmitterContext context)
|
||||
{
|
||||
EmitScalarShrImmOpZx(context, ShrImmFlags.Round | ShrImmFlags.Accumulate);
|
||||
}
|
||||
|
||||
public static void Ursra_V(EmitterContext context)
|
||||
public static void Ursra_V(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimdShImm op = (OpCodeSimdShImm)context.CurrOp;
|
||||
|
||||
|
@ -713,7 +698,7 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Ushl_V(EmitterContext context)
|
||||
public static void Ushl_V(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
||||
|
||||
|
@ -726,9 +711,7 @@ namespace ARMeilleure.Instructions
|
|||
Operand ne = EmitVectorExtractZx(context, op.Rn, index, op.Size);
|
||||
Operand me = EmitVectorExtractZx(context, op.Rm, index, op.Size);
|
||||
|
||||
MethodInfo info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.UnsignedShlReg));
|
||||
|
||||
Operand e = context.Call(info, ne, me, Const(0), Const(op.Size));
|
||||
Operand e = context.Call(new _U64_U64_U64_Bool_S32(SoftFallback.UnsignedShlReg), ne, me, Const(0), Const(op.Size));
|
||||
|
||||
res = EmitVectorInsert(context, res, e, index, op.Size);
|
||||
}
|
||||
|
@ -736,7 +719,7 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
||||
public static void Ushll_V(EmitterContext context)
|
||||
public static void Ushll_V(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimdShImm op = (OpCodeSimdShImm)context.CurrOp;
|
||||
|
||||
|
@ -770,12 +753,12 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Ushr_S(EmitterContext context)
|
||||
public static void Ushr_S(ArmEmitterContext context)
|
||||
{
|
||||
EmitShrImmOp(context, ShrImmFlags.ScalarZx);
|
||||
}
|
||||
|
||||
public static void Ushr_V(EmitterContext context)
|
||||
public static void Ushr_V(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimdShImm op = (OpCodeSimdShImm)context.CurrOp;
|
||||
|
||||
|
@ -802,12 +785,12 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
public static void Usra_S(EmitterContext context)
|
||||
public static void Usra_S(ArmEmitterContext context)
|
||||
{
|
||||
EmitScalarShrImmOpZx(context, ShrImmFlags.Accumulate);
|
||||
}
|
||||
|
||||
public static void Usra_V(EmitterContext context)
|
||||
public static void Usra_V(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimdShImm op = (OpCodeSimdShImm)context.CurrOp;
|
||||
|
||||
|
@ -855,27 +838,27 @@ namespace ARMeilleure.Instructions
|
|||
VectorZx = 0
|
||||
}
|
||||
|
||||
private static void EmitScalarShrImmOpSx(EmitterContext context, ShrImmFlags flags)
|
||||
private static void EmitScalarShrImmOpSx(ArmEmitterContext context, ShrImmFlags flags)
|
||||
{
|
||||
EmitShrImmOp(context, ShrImmFlags.ScalarSx | flags);
|
||||
}
|
||||
|
||||
private static void EmitScalarShrImmOpZx(EmitterContext context, ShrImmFlags flags)
|
||||
private static void EmitScalarShrImmOpZx(ArmEmitterContext context, ShrImmFlags flags)
|
||||
{
|
||||
EmitShrImmOp(context, ShrImmFlags.ScalarZx | flags);
|
||||
}
|
||||
|
||||
private static void EmitVectorShrImmOpSx(EmitterContext context, ShrImmFlags flags)
|
||||
private static void EmitVectorShrImmOpSx(ArmEmitterContext context, ShrImmFlags flags)
|
||||
{
|
||||
EmitShrImmOp(context, ShrImmFlags.VectorSx | flags);
|
||||
}
|
||||
|
||||
private static void EmitVectorShrImmOpZx(EmitterContext context, ShrImmFlags flags)
|
||||
private static void EmitVectorShrImmOpZx(ArmEmitterContext context, ShrImmFlags flags)
|
||||
{
|
||||
EmitShrImmOp(context, ShrImmFlags.VectorZx | flags);
|
||||
}
|
||||
|
||||
private static void EmitShrImmOp(EmitterContext context, ShrImmFlags flags)
|
||||
private static void EmitShrImmOp(ArmEmitterContext context, ShrImmFlags flags)
|
||||
{
|
||||
OpCodeSimdShImm op = (OpCodeSimdShImm)context.CurrOp;
|
||||
|
||||
|
@ -925,7 +908,7 @@ namespace ARMeilleure.Instructions
|
|||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
||||
private static void EmitVectorShrImmNarrowOpZx(EmitterContext context, bool round)
|
||||
private static void EmitVectorShrImmNarrowOpZx(ArmEmitterContext context, bool round)
|
||||
{
|
||||
OpCodeSimdShImm op = (OpCodeSimdShImm)context.CurrOp;
|
||||
|
||||
|
@ -974,12 +957,12 @@ namespace ARMeilleure.Instructions
|
|||
VectorZxZx = 0
|
||||
}
|
||||
|
||||
private static void EmitRoundShrImmSaturatingNarrowOp(EmitterContext context, ShrImmSaturatingNarrowFlags flags)
|
||||
private static void EmitRoundShrImmSaturatingNarrowOp(ArmEmitterContext context, ShrImmSaturatingNarrowFlags flags)
|
||||
{
|
||||
EmitShrImmSaturatingNarrowOp(context, ShrImmSaturatingNarrowFlags.Round | flags);
|
||||
}
|
||||
|
||||
private static void EmitShrImmSaturatingNarrowOp(EmitterContext context, ShrImmSaturatingNarrowFlags flags)
|
||||
private static void EmitShrImmSaturatingNarrowOp(ArmEmitterContext context, ShrImmSaturatingNarrowFlags flags)
|
||||
{
|
||||
OpCodeSimdShImm op = (OpCodeSimdShImm)context.CurrOp;
|
||||
|
||||
|
@ -1028,32 +1011,30 @@ namespace ARMeilleure.Instructions
|
|||
|
||||
// dst64 = (Int(src64, signed) + roundConst) >> shift;
|
||||
private static Operand EmitShrImm64(
|
||||
EmitterContext context,
|
||||
ArmEmitterContext context,
|
||||
Operand value,
|
||||
bool signed,
|
||||
long roundConst,
|
||||
int shift)
|
||||
{
|
||||
string name = signed
|
||||
? nameof(SoftFallback.SignedShrImm64)
|
||||
: nameof(SoftFallback.UnsignedShrImm64);
|
||||
Delegate dlg = signed
|
||||
? (Delegate)new _S64_S64_S64_S32(SoftFallback.SignedShrImm64)
|
||||
: (Delegate)new _U64_U64_S64_S32(SoftFallback.UnsignedShrImm64);
|
||||
|
||||
MethodInfo info = typeof(SoftFallback).GetMethod(name);
|
||||
|
||||
return context.Call(info, value, Const(roundConst), Const(shift));
|
||||
return context.Call(dlg, value, Const(roundConst), Const(shift));
|
||||
}
|
||||
|
||||
private static void EmitVectorShImmWidenBinarySx(EmitterContext context, Func2I emit, int imm)
|
||||
private static void EmitVectorShImmWidenBinarySx(ArmEmitterContext context, Func2I emit, int imm)
|
||||
{
|
||||
EmitVectorShImmWidenBinaryOp(context, emit, imm, signed: true);
|
||||
}
|
||||
|
||||
private static void EmitVectorShImmWidenBinaryZx(EmitterContext context, Func2I emit, int imm)
|
||||
private static void EmitVectorShImmWidenBinaryZx(ArmEmitterContext context, Func2I emit, int imm)
|
||||
{
|
||||
EmitVectorShImmWidenBinaryOp(context, emit, imm, signed: false);
|
||||
}
|
||||
|
||||
private static void EmitVectorShImmWidenBinaryOp(EmitterContext context, Func2I emit, int imm, bool signed)
|
||||
private static void EmitVectorShImmWidenBinaryOp(ArmEmitterContext context, Func2I emit, int imm, bool signed)
|
||||
{
|
||||
OpCodeSimd op = (OpCodeSimd)context.CurrOp;
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@ using ARMeilleure.Decoders;
|
|||
using ARMeilleure.IntermediateRepresentation;
|
||||
using ARMeilleure.Translation;
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
using static ARMeilleure.Instructions.InstEmitHelper;
|
||||
using static ARMeilleure.IntermediateRepresentation.OperandHelper;
|
||||
|
@ -13,67 +12,63 @@ namespace ARMeilleure.Instructions
|
|||
{
|
||||
private const int DczSizeLog2 = 4;
|
||||
|
||||
public static void Hint(EmitterContext context)
|
||||
public static void Hint(ArmEmitterContext context)
|
||||
{
|
||||
//Execute as no-op.
|
||||
}
|
||||
|
||||
public static void Isb(EmitterContext context)
|
||||
public static void Isb(ArmEmitterContext context)
|
||||
{
|
||||
//Execute as no-op.
|
||||
}
|
||||
|
||||
public static void Mrs(EmitterContext context)
|
||||
public static void Mrs(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSystem op = (OpCodeSystem)context.CurrOp;
|
||||
|
||||
string name;
|
||||
Delegate dlg;
|
||||
|
||||
switch (GetPackedId(op))
|
||||
{
|
||||
case 0b11_011_0000_0000_001: name = nameof(NativeInterface.GetCtrEl0); break;
|
||||
case 0b11_011_0000_0000_111: name = nameof(NativeInterface.GetDczidEl0); break;
|
||||
case 0b11_011_0100_0100_000: name = nameof(NativeInterface.GetFpcr); break;
|
||||
case 0b11_011_0100_0100_001: name = nameof(NativeInterface.GetFpsr); break;
|
||||
case 0b11_011_1101_0000_010: name = nameof(NativeInterface.GetTpidrEl0); break;
|
||||
case 0b11_011_1101_0000_011: name = nameof(NativeInterface.GetTpidr); break;
|
||||
case 0b11_011_1110_0000_000: name = nameof(NativeInterface.GetCntfrqEl0); break;
|
||||
case 0b11_011_1110_0000_001: name = nameof(NativeInterface.GetCntpctEl0); break;
|
||||
case 0b11_011_0000_0000_001: dlg = new _U64(NativeInterface.GetCtrEl0); break;
|
||||
case 0b11_011_0000_0000_111: dlg = new _U64(NativeInterface.GetDczidEl0); break;
|
||||
case 0b11_011_0100_0100_000: dlg = new _U64(NativeInterface.GetFpcr); break;
|
||||
case 0b11_011_0100_0100_001: dlg = new _U64(NativeInterface.GetFpsr); break;
|
||||
case 0b11_011_1101_0000_010: dlg = new _U64(NativeInterface.GetTpidrEl0); break;
|
||||
case 0b11_011_1101_0000_011: dlg = new _U64(NativeInterface.GetTpidr); break;
|
||||
case 0b11_011_1110_0000_000: dlg = new _U64(NativeInterface.GetCntfrqEl0); break;
|
||||
case 0b11_011_1110_0000_001: dlg = new _U64(NativeInterface.GetCntpctEl0); break;
|
||||
|
||||
default: throw new NotImplementedException($"Unknown MRS 0x{op.RawOpCode:X8} at 0x{op.Address:X16}.");
|
||||
}
|
||||
|
||||
MethodInfo info = typeof(NativeInterface).GetMethod(name);
|
||||
|
||||
SetIntOrZR(context, op.Rt, context.Call(info));
|
||||
SetIntOrZR(context, op.Rt, context.Call(dlg));
|
||||
}
|
||||
|
||||
public static void Msr(EmitterContext context)
|
||||
public static void Msr(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSystem op = (OpCodeSystem)context.CurrOp;
|
||||
|
||||
string name;
|
||||
Delegate dlg;
|
||||
|
||||
switch (GetPackedId(op))
|
||||
{
|
||||
case 0b11_011_0100_0100_000: name = nameof(NativeInterface.SetFpcr); break;
|
||||
case 0b11_011_0100_0100_001: name = nameof(NativeInterface.SetFpsr); break;
|
||||
case 0b11_011_1101_0000_010: name = nameof(NativeInterface.SetTpidrEl0); break;
|
||||
case 0b11_011_0100_0100_000: dlg = new _Void_U64(NativeInterface.SetFpcr); break;
|
||||
case 0b11_011_0100_0100_001: dlg = new _Void_U64(NativeInterface.SetFpsr); break;
|
||||
case 0b11_011_1101_0000_010: dlg = new _Void_U64(NativeInterface.SetTpidrEl0); break;
|
||||
|
||||
default: throw new NotImplementedException($"Unknown MSR 0x{op.RawOpCode:X8} at 0x{op.Address:X16}.");
|
||||
}
|
||||
|
||||
MethodInfo info = typeof(NativeInterface).GetMethod(name);
|
||||
|
||||
context.Call(info, GetIntOrZR(context, op.Rt));
|
||||
context.Call(dlg, GetIntOrZR(context, op.Rt));
|
||||
}
|
||||
|
||||
public static void Nop(EmitterContext context)
|
||||
public static void Nop(ArmEmitterContext context)
|
||||
{
|
||||
//Do nothing.
|
||||
}
|
||||
|
||||
public static void Sys(EmitterContext context)
|
||||
public static void Sys(ArmEmitterContext context)
|
||||
{
|
||||
//This instruction is used to do some operations on the CPU like cache invalidation,
|
||||
//address translation and the like.
|
||||
|
@ -87,13 +82,11 @@ namespace ARMeilleure.Instructions
|
|||
//DC ZVA
|
||||
Operand t = GetIntOrZR(context, op.Rt);
|
||||
|
||||
MethodInfo info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt64));
|
||||
|
||||
for (long offset = 0; offset < (4 << DczSizeLog2); offset += 8)
|
||||
{
|
||||
Operand address = context.Add(t, Const(offset));
|
||||
|
||||
context.Call(info, address, Const(0L));
|
||||
context.Call(new _Void_U64_U64(NativeInterface.WriteUInt64), address, Const(0L));
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
using ARMeilleure.Memory;
|
||||
using ARMeilleure.State;
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
using Thread = System.Threading.Thread;
|
||||
using System;
|
||||
|
||||
namespace ARMeilleure.Instructions
|
||||
{
|
||||
|
@ -28,21 +26,17 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
}
|
||||
|
||||
private static ConcurrentDictionary<Thread, ThreadContext> _contexts;
|
||||
|
||||
static NativeInterface()
|
||||
{
|
||||
_contexts = new ConcurrentDictionary<Thread, ThreadContext>();
|
||||
}
|
||||
[ThreadStatic]
|
||||
private static ThreadContext _context;
|
||||
|
||||
public static void RegisterThread(ExecutionContext context, MemoryManager memory)
|
||||
{
|
||||
_contexts.TryAdd(Thread.CurrentThread, new ThreadContext(context, memory));
|
||||
_context = new ThreadContext(context, memory);
|
||||
}
|
||||
|
||||
public static void UnregisterThread()
|
||||
{
|
||||
_contexts.TryRemove(Thread.CurrentThread, out _);
|
||||
_context = null;
|
||||
}
|
||||
|
||||
public static void Break(ulong address, int imm)
|
||||
|
@ -52,6 +46,8 @@ namespace ARMeilleure.Instructions
|
|||
|
||||
public static void SupervisorCall(ulong address, int imm)
|
||||
{
|
||||
System.Span<byte> test = stackalloc byte[0x2000];
|
||||
|
||||
GetContext().OnSupervisorCall(address, imm);
|
||||
}
|
||||
|
||||
|
@ -61,60 +57,60 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
|
||||
#region "System registers"
|
||||
public static ulong GetCtrEl0()
|
||||
{
|
||||
return (ulong)GetContext().CtrEl0;
|
||||
}
|
||||
public static ulong GetCtrEl0()
|
||||
{
|
||||
return (ulong)GetContext().CtrEl0;
|
||||
}
|
||||
|
||||
public static ulong GetDczidEl0()
|
||||
{
|
||||
return (ulong)GetContext().DczidEl0;
|
||||
}
|
||||
public static ulong GetDczidEl0()
|
||||
{
|
||||
return (ulong)GetContext().DczidEl0;
|
||||
}
|
||||
|
||||
public static ulong GetFpcr()
|
||||
{
|
||||
return (ulong)GetContext().Fpcr;
|
||||
}
|
||||
public static ulong GetFpcr()
|
||||
{
|
||||
return (ulong)GetContext().Fpcr;
|
||||
}
|
||||
|
||||
public static ulong GetFpsr()
|
||||
{
|
||||
return (ulong)GetContext().Fpsr;
|
||||
}
|
||||
public static ulong GetFpsr()
|
||||
{
|
||||
return (ulong)GetContext().Fpsr;
|
||||
}
|
||||
|
||||
public static ulong GetTpidrEl0()
|
||||
{
|
||||
return (ulong)GetContext().TpidrEl0;
|
||||
}
|
||||
public static ulong GetTpidrEl0()
|
||||
{
|
||||
return (ulong)GetContext().TpidrEl0;
|
||||
}
|
||||
|
||||
public static ulong GetTpidr()
|
||||
{
|
||||
return (ulong)GetContext().Tpidr;
|
||||
}
|
||||
public static ulong GetTpidr()
|
||||
{
|
||||
return (ulong)GetContext().Tpidr;
|
||||
}
|
||||
|
||||
public static ulong GetCntfrqEl0()
|
||||
{
|
||||
return GetContext().CntfrqEl0;
|
||||
}
|
||||
public static ulong GetCntfrqEl0()
|
||||
{
|
||||
return GetContext().CntfrqEl0;
|
||||
}
|
||||
|
||||
public static ulong GetCntpctEl0()
|
||||
{
|
||||
return GetContext().CntpctEl0;
|
||||
}
|
||||
public static ulong GetCntpctEl0()
|
||||
{
|
||||
return GetContext().CntpctEl0;
|
||||
}
|
||||
|
||||
public static void SetFpcr(ulong value)
|
||||
{
|
||||
GetContext().Fpcr = (FPCR)value;
|
||||
}
|
||||
public static void SetFpcr(ulong value)
|
||||
{
|
||||
GetContext().Fpcr = (FPCR)value;
|
||||
}
|
||||
|
||||
public static void SetFpsr(ulong value)
|
||||
{
|
||||
GetContext().Fpsr = (FPSR)value;
|
||||
}
|
||||
public static void SetFpsr(ulong value)
|
||||
{
|
||||
GetContext().Fpsr = (FPSR)value;
|
||||
}
|
||||
|
||||
public static void SetTpidrEl0(ulong value)
|
||||
{
|
||||
GetContext().TpidrEl0 = (long)value;
|
||||
}
|
||||
public static void SetTpidrEl0(ulong value)
|
||||
{
|
||||
GetContext().TpidrEl0 = (long)value;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region "Read"
|
||||
|
@ -147,65 +143,55 @@ namespace ARMeilleure.Instructions
|
|||
#region "Read exclusive"
|
||||
public static byte ReadByteExclusive(ulong address)
|
||||
{
|
||||
ThreadContext context = GetCurrentContext();
|
||||
byte value = _context.Memory.ReadByte((long)address);
|
||||
|
||||
byte value = context.Memory.ReadByte((long)address);
|
||||
|
||||
context.ExclusiveAddress = GetMaskedExclusiveAddress(address);
|
||||
context.ExclusiveValueLow = value;
|
||||
context.ExclusiveValueHigh = 0;
|
||||
_context.ExclusiveAddress = GetMaskedExclusiveAddress(address);
|
||||
_context.ExclusiveValueLow = value;
|
||||
_context.ExclusiveValueHigh = 0;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static ushort ReadUInt16Exclusive(ulong address)
|
||||
{
|
||||
ThreadContext context = GetCurrentContext();
|
||||
ushort value = _context.Memory.ReadUInt16((long)address);
|
||||
|
||||
ushort value = context.Memory.ReadUInt16((long)address);
|
||||
|
||||
context.ExclusiveAddress = GetMaskedExclusiveAddress(address);
|
||||
context.ExclusiveValueLow = value;
|
||||
context.ExclusiveValueHigh = 0;
|
||||
_context.ExclusiveAddress = GetMaskedExclusiveAddress(address);
|
||||
_context.ExclusiveValueLow = value;
|
||||
_context.ExclusiveValueHigh = 0;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static uint ReadUInt32Exclusive(ulong address)
|
||||
{
|
||||
ThreadContext context = GetCurrentContext();
|
||||
uint value = _context.Memory.ReadUInt32((long)address);
|
||||
|
||||
uint value = context.Memory.ReadUInt32((long)address);
|
||||
|
||||
context.ExclusiveAddress = GetMaskedExclusiveAddress(address);
|
||||
context.ExclusiveValueLow = value;
|
||||
context.ExclusiveValueHigh = 0;
|
||||
_context.ExclusiveAddress = GetMaskedExclusiveAddress(address);
|
||||
_context.ExclusiveValueLow = value;
|
||||
_context.ExclusiveValueHigh = 0;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static ulong ReadUInt64Exclusive(ulong address)
|
||||
{
|
||||
ThreadContext context = GetCurrentContext();
|
||||
ulong value = _context.Memory.ReadUInt64((long)address);
|
||||
|
||||
ulong value = context.Memory.ReadUInt64((long)address);
|
||||
|
||||
context.ExclusiveAddress = GetMaskedExclusiveAddress(address);
|
||||
context.ExclusiveValueLow = value;
|
||||
context.ExclusiveValueHigh = 0;
|
||||
_context.ExclusiveAddress = GetMaskedExclusiveAddress(address);
|
||||
_context.ExclusiveValueLow = value;
|
||||
_context.ExclusiveValueHigh = 0;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static V128 ReadVector128Exclusive(ulong address)
|
||||
{
|
||||
ThreadContext context = GetCurrentContext();
|
||||
V128 value = _context.Memory.AtomicLoadInt128((long)address);
|
||||
|
||||
V128 value = context.Memory.AtomicLoadInt128((long)address);
|
||||
|
||||
context.ExclusiveAddress = GetMaskedExclusiveAddress(address);
|
||||
context.ExclusiveValueLow = value.GetUInt64(0);
|
||||
context.ExclusiveValueHigh = value.GetUInt64(1);
|
||||
_context.ExclusiveAddress = GetMaskedExclusiveAddress(address);
|
||||
_context.ExclusiveValueLow = value.GetUInt64(0);
|
||||
_context.ExclusiveValueHigh = value.GetUInt64(1);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
@ -241,15 +227,13 @@ namespace ARMeilleure.Instructions
|
|||
#region "Write exclusive"
|
||||
public static int WriteByteExclusive(ulong address, byte value)
|
||||
{
|
||||
ThreadContext context = GetCurrentContext();
|
||||
|
||||
bool success = context.ExclusiveAddress == GetMaskedExclusiveAddress(address);
|
||||
bool success = _context.ExclusiveAddress == GetMaskedExclusiveAddress(address);
|
||||
|
||||
if (success)
|
||||
{
|
||||
success = context.Memory.AtomicCompareExchangeByte(
|
||||
success = _context.Memory.AtomicCompareExchangeByte(
|
||||
(long)address,
|
||||
(byte)context.ExclusiveValueLow,
|
||||
(byte)_context.ExclusiveValueLow,
|
||||
(byte)value);
|
||||
|
||||
if (success)
|
||||
|
@ -263,15 +247,13 @@ namespace ARMeilleure.Instructions
|
|||
|
||||
public static int WriteUInt16Exclusive(ulong address, ushort value)
|
||||
{
|
||||
ThreadContext context = GetCurrentContext();
|
||||
|
||||
bool success = context.ExclusiveAddress == GetMaskedExclusiveAddress(address);
|
||||
bool success = _context.ExclusiveAddress == GetMaskedExclusiveAddress(address);
|
||||
|
||||
if (success)
|
||||
{
|
||||
success = context.Memory.AtomicCompareExchangeInt16(
|
||||
success = _context.Memory.AtomicCompareExchangeInt16(
|
||||
(long)address,
|
||||
(short)context.ExclusiveValueLow,
|
||||
(short)_context.ExclusiveValueLow,
|
||||
(short)value);
|
||||
|
||||
if (success)
|
||||
|
@ -285,15 +267,13 @@ namespace ARMeilleure.Instructions
|
|||
|
||||
public static int WriteUInt32Exclusive(ulong address, uint value)
|
||||
{
|
||||
ThreadContext context = GetCurrentContext();
|
||||
|
||||
bool success = context.ExclusiveAddress == GetMaskedExclusiveAddress(address);
|
||||
bool success = _context.ExclusiveAddress == GetMaskedExclusiveAddress(address);
|
||||
|
||||
if (success)
|
||||
{
|
||||
success = context.Memory.AtomicCompareExchangeInt32(
|
||||
success = _context.Memory.AtomicCompareExchangeInt32(
|
||||
(long)address,
|
||||
(int)context.ExclusiveValueLow,
|
||||
(int)_context.ExclusiveValueLow,
|
||||
(int)value);
|
||||
|
||||
if (success)
|
||||
|
@ -307,15 +287,13 @@ namespace ARMeilleure.Instructions
|
|||
|
||||
public static int WriteUInt64Exclusive(ulong address, ulong value)
|
||||
{
|
||||
ThreadContext context = GetCurrentContext();
|
||||
|
||||
bool success = context.ExclusiveAddress == GetMaskedExclusiveAddress(address);
|
||||
bool success = _context.ExclusiveAddress == GetMaskedExclusiveAddress(address);
|
||||
|
||||
if (success)
|
||||
{
|
||||
success = context.Memory.AtomicCompareExchangeInt64(
|
||||
success = _context.Memory.AtomicCompareExchangeInt64(
|
||||
(long)address,
|
||||
(long)context.ExclusiveValueLow,
|
||||
(long)_context.ExclusiveValueLow,
|
||||
(long)value);
|
||||
|
||||
if (success)
|
||||
|
@ -329,15 +307,13 @@ namespace ARMeilleure.Instructions
|
|||
|
||||
public static int WriteVector128Exclusive(ulong address, V128 value)
|
||||
{
|
||||
ThreadContext context = GetCurrentContext();
|
||||
|
||||
bool success = context.ExclusiveAddress == GetMaskedExclusiveAddress(address);
|
||||
bool success = _context.ExclusiveAddress == GetMaskedExclusiveAddress(address);
|
||||
|
||||
if (success)
|
||||
{
|
||||
V128 expected = new V128(context.ExclusiveValueLow, context.ExclusiveValueHigh);
|
||||
V128 expected = new V128(_context.ExclusiveValueLow, _context.ExclusiveValueHigh);
|
||||
|
||||
success = context.Memory.AtomicCompareExchangeInt128((long)address, expected, value);
|
||||
success = _context.Memory.AtomicCompareExchangeInt128((long)address, expected, value);
|
||||
|
||||
if (success)
|
||||
{
|
||||
|
@ -356,7 +332,7 @@ namespace ARMeilleure.Instructions
|
|||
|
||||
public static void ClearExclusive()
|
||||
{
|
||||
GetCurrentContext().ExclusiveAddress = ulong.MaxValue;
|
||||
_context.ExclusiveAddress = ulong.MaxValue;
|
||||
}
|
||||
|
||||
public static void CheckSynchronization()
|
||||
|
@ -364,19 +340,14 @@ namespace ARMeilleure.Instructions
|
|||
GetContext().CheckInterrupt();
|
||||
}
|
||||
|
||||
private static ThreadContext GetCurrentContext()
|
||||
{
|
||||
return _contexts[Thread.CurrentThread];
|
||||
}
|
||||
|
||||
public static ExecutionContext GetContext()
|
||||
{
|
||||
return _contexts[Thread.CurrentThread].Context;
|
||||
return _context.Context;
|
||||
}
|
||||
|
||||
public static MemoryManager GetMemoryManager()
|
||||
{
|
||||
return _contexts[Thread.CurrentThread].Memory;
|
||||
return _context.Memory;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -927,8 +927,8 @@ namespace ARMeilleure.Instructions
|
|||
|
||||
private static uint Crc32w(uint crc, uint poly, uint val)
|
||||
{
|
||||
crc = Crc32(crc, poly, (byte)(val >> 0 ));
|
||||
crc = Crc32(crc, poly, (byte)(val >> 8 ));
|
||||
crc = Crc32(crc, poly, (byte)(val >> 0));
|
||||
crc = Crc32(crc, poly, (byte)(val >> 8));
|
||||
crc = Crc32(crc, poly, (byte)(val >> 16));
|
||||
crc = Crc32(crc, poly, (byte)(val >> 24));
|
||||
|
||||
|
@ -937,8 +937,8 @@ namespace ARMeilleure.Instructions
|
|||
|
||||
private static uint Crc32x(uint crc, uint poly, ulong val)
|
||||
{
|
||||
crc = Crc32(crc, poly, (byte)(val >> 0 ));
|
||||
crc = Crc32(crc, poly, (byte)(val >> 8 ));
|
||||
crc = Crc32(crc, poly, (byte)(val >> 0));
|
||||
crc = Crc32(crc, poly, (byte)(val >> 8));
|
||||
crc = Crc32(crc, poly, (byte)(val >> 16));
|
||||
crc = Crc32(crc, poly, (byte)(val >> 24));
|
||||
crc = Crc32(crc, poly, (byte)(val >> 32));
|
||||
|
|
|
@ -41,6 +41,7 @@ namespace ARMeilleure.IntermediateRepresentation
|
|||
Multiply64HighSI,
|
||||
Multiply64HighUI,
|
||||
Negate,
|
||||
PopCount,
|
||||
Return,
|
||||
RotateRight,
|
||||
ShiftLeft,
|
||||
|
@ -57,6 +58,7 @@ namespace ARMeilleure.IntermediateRepresentation
|
|||
Store8,
|
||||
StoreToContext,
|
||||
Subtract,
|
||||
VectorCreateScalar,
|
||||
VectorExtract,
|
||||
VectorExtract16,
|
||||
VectorExtract8,
|
||||
|
|
|
@ -237,7 +237,7 @@ namespace ARMeilleure.Memory
|
|||
IntPtr newPtr = Allocate((ulong)(PtLevelSize * IntPtr.Size));
|
||||
|
||||
//Try to swap the current pointer (should be zero), with the allocated one.
|
||||
nextPtr = Interlocked.Exchange(ref *ptePtr, newPtr);
|
||||
nextPtr = Interlocked.CompareExchange(ref *ptePtr, newPtr, IntPtr.Zero);
|
||||
|
||||
//If the old pointer is not null, then another thread already has set it.
|
||||
if (nextPtr != IntPtr.Zero)
|
||||
|
|
|
@ -112,19 +112,34 @@ namespace ARMeilleure.State
|
|||
|
||||
public static int GetRegisterOffset(Register reg)
|
||||
{
|
||||
int offset, size;
|
||||
|
||||
if (reg.Type == RegisterType.Integer)
|
||||
{
|
||||
return reg.Index * IntSize;
|
||||
offset = reg.Index * IntSize;
|
||||
|
||||
size = IntSize;
|
||||
}
|
||||
else if (reg.Type == RegisterType.Vector)
|
||||
{
|
||||
return RegisterConsts.IntRegsCount * IntSize + reg.Index * VecSize;
|
||||
offset = RegisterConsts.IntRegsCount * IntSize + reg.Index * VecSize;
|
||||
|
||||
size = VecSize;
|
||||
}
|
||||
else /* if (reg.Type == RegisterType.Flag) */
|
||||
{
|
||||
return RegisterConsts.IntRegsCount * IntSize +
|
||||
RegisterConsts.VecRegsCount * VecSize + reg.Index * FlagSize;
|
||||
offset = RegisterConsts.IntRegsCount * IntSize +
|
||||
RegisterConsts.VecRegsCount * VecSize + reg.Index * FlagSize;
|
||||
|
||||
size = FlagSize;
|
||||
}
|
||||
|
||||
if ((uint)(offset + size) > (uint)TotalSize)
|
||||
{
|
||||
throw new ArgumentException("Invalid register.");
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
public static int GetCounterOffset()
|
||||
|
|
136
ARMeilleure/Translation/ArmEmitterContext.cs
Normal file
136
ARMeilleure/Translation/ArmEmitterContext.cs
Normal file
|
@ -0,0 +1,136 @@
|
|||
using ARMeilleure.Decoders;
|
||||
using ARMeilleure.Instructions;
|
||||
using ARMeilleure.IntermediateRepresentation;
|
||||
using ARMeilleure.Memory;
|
||||
using ARMeilleure.State;
|
||||
|
||||
using static ARMeilleure.IntermediateRepresentation.OperandHelper;
|
||||
|
||||
namespace ARMeilleure.Translation
|
||||
{
|
||||
class ArmEmitterContext : EmitterContext
|
||||
{
|
||||
private OpCode _optOpLastCompare;
|
||||
private OpCode _optOpLastFlagSet;
|
||||
|
||||
private Operand _optCmpTempN;
|
||||
private Operand _optCmpTempM;
|
||||
|
||||
private Block _currBlock;
|
||||
|
||||
public Block CurrBlock
|
||||
{
|
||||
get
|
||||
{
|
||||
return _currBlock;
|
||||
}
|
||||
set
|
||||
{
|
||||
_currBlock = value;
|
||||
|
||||
ResetBlockState();
|
||||
}
|
||||
}
|
||||
|
||||
public OpCode CurrOp { get; set; }
|
||||
|
||||
public MemoryManager Memory { get; }
|
||||
|
||||
public Aarch32Mode Mode { get; }
|
||||
|
||||
public ArmEmitterContext(MemoryManager memory, Aarch32Mode mode)
|
||||
{
|
||||
Memory = memory;
|
||||
Mode = mode;
|
||||
}
|
||||
|
||||
public void MarkComparison(Operand n, Operand m)
|
||||
{
|
||||
_optOpLastCompare = CurrOp;
|
||||
|
||||
_optCmpTempN = Copy(n);
|
||||
_optCmpTempM = Copy(m);
|
||||
}
|
||||
|
||||
public void MarkFlagSet(PState stateFlag)
|
||||
{
|
||||
// Set this only if any of the NZCV flag bits were modified.
|
||||
// This is used to ensure that when emiting a direct IL branch
|
||||
// instruction for compare + branch sequences, we're not expecting
|
||||
// to use comparison values from an old instruction, when in fact
|
||||
// the flags were already overwritten by another instruction further along.
|
||||
if (stateFlag >= PState.VFlag)
|
||||
{
|
||||
_optOpLastFlagSet = CurrOp;
|
||||
}
|
||||
}
|
||||
|
||||
private void ResetBlockState()
|
||||
{
|
||||
_optOpLastCompare = null;
|
||||
_optOpLastFlagSet = null;
|
||||
}
|
||||
|
||||
public Operand TryGetComparisonResult(Condition condition)
|
||||
{
|
||||
if (_optOpLastCompare == null || _optOpLastCompare != _optOpLastFlagSet)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Operand n = _optCmpTempN;
|
||||
Operand m = _optCmpTempM;
|
||||
|
||||
InstName cmpName = _optOpLastCompare.Instruction.Name;
|
||||
|
||||
if (cmpName == InstName.Subs)
|
||||
{
|
||||
switch (condition)
|
||||
{
|
||||
case Condition.Eq: return ICompareEqual (n, m);
|
||||
case Condition.Ne: return ICompareNotEqual (n, m);
|
||||
case Condition.GeUn: return ICompareGreaterOrEqualUI(n, m);
|
||||
case Condition.LtUn: return ICompareLessUI (n, m);
|
||||
case Condition.GtUn: return ICompareGreaterUI (n, m);
|
||||
case Condition.LeUn: return ICompareLessOrEqualUI (n, m);
|
||||
case Condition.Ge: return ICompareGreaterOrEqual (n, m);
|
||||
case Condition.Lt: return ICompareLess (n, m);
|
||||
case Condition.Gt: return ICompareGreater (n, m);
|
||||
case Condition.Le: return ICompareLessOrEqual (n, m);
|
||||
}
|
||||
}
|
||||
else if (cmpName == InstName.Adds && _optOpLastCompare is IOpCodeAluImm op)
|
||||
{
|
||||
// There are several limitations that needs to be taken into account for CMN comparisons:
|
||||
// - The unsigned comparisons are not valid, as they depend on the
|
||||
// carry flag value, and they will have different values for addition and
|
||||
// subtraction. For addition, it's carry, and for subtraction, it's borrow.
|
||||
// So, we need to make sure we're not doing a unsigned compare for the CMN case.
|
||||
// - We can only do the optimization for the immediate variants,
|
||||
// because when the second operand value is exactly INT_MIN, we can't
|
||||
// negate the value as theres no positive counterpart.
|
||||
// Such invalid values can't be encoded on the immediate encodings.
|
||||
if (op.RegisterSize == RegisterSize.Int32)
|
||||
{
|
||||
m = Const((int)-op.Immediate);
|
||||
}
|
||||
else
|
||||
{
|
||||
m = Const(-op.Immediate);
|
||||
}
|
||||
|
||||
switch (condition)
|
||||
{
|
||||
case Condition.Eq: return ICompareEqual (n, m);
|
||||
case Condition.Ne: return ICompareNotEqual (n, m);
|
||||
case Condition.Ge: return ICompareGreaterOrEqual(n, m);
|
||||
case Condition.Lt: return ICompareLess (n, m);
|
||||
case Condition.Gt: return ICompareGreater (n, m);
|
||||
case Condition.Le: return ICompareLessOrEqual (n, m);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,12 +11,16 @@ namespace ARMeilleure.Translation
|
|||
{
|
||||
public static T Compile<T>(ControlFlowGraph cfg, OperandType funcReturnType)
|
||||
{
|
||||
IntPtr codePtr = JitCache.Map(Compile(cfg, funcReturnType));
|
||||
CompilerContext cctx = GetCompilerContext(cfg, funcReturnType);
|
||||
|
||||
CompiledFunction func = CodeGenerator.Generate(cctx);
|
||||
|
||||
IntPtr codePtr = JitCache.Map(func);
|
||||
|
||||
return Marshal.GetDelegateForFunctionPointer<T>(codePtr);
|
||||
}
|
||||
|
||||
public static CompiledFunction Compile(ControlFlowGraph cfg, OperandType funcReturnType)
|
||||
private static CompilerContext GetCompilerContext(ControlFlowGraph cfg, OperandType funcReturnType)
|
||||
{
|
||||
Logger.StartPass(PassName.Dominance);
|
||||
|
||||
|
@ -31,9 +35,7 @@ namespace ARMeilleure.Translation
|
|||
|
||||
Logger.EndPass(PassName.SsaConstruction, cfg);
|
||||
|
||||
CompilerContext cctx = new CompilerContext(cfg, funcReturnType);
|
||||
|
||||
return CodeGenerator.Generate(cctx);
|
||||
return new CompilerContext(cfg, funcReturnType);
|
||||
}
|
||||
}
|
||||
}
|
26
ARMeilleure/Translation/DelegateCache.cs
Normal file
26
ARMeilleure/Translation/DelegateCache.cs
Normal file
|
@ -0,0 +1,26 @@
|
|||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Reflection;
|
||||
|
||||
namespace ARMeilleure.Translation
|
||||
{
|
||||
static class DelegateCache
|
||||
{
|
||||
private static ConcurrentDictionary<string, Delegate> _delegates;
|
||||
|
||||
static DelegateCache()
|
||||
{
|
||||
_delegates = new ConcurrentDictionary<string, Delegate>();
|
||||
}
|
||||
|
||||
public static Delegate GetOrAdd(Delegate dlg)
|
||||
{
|
||||
return _delegates.GetOrAdd(GetKey(dlg.Method), (key) => dlg);
|
||||
}
|
||||
|
||||
private static string GetKey(MethodInfo info)
|
||||
{
|
||||
return $"{info.DeclaringType.FullName}.{info.Name}";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,11 +1,8 @@
|
|||
using ARMeilleure.Decoders;
|
||||
using ARMeilleure.IntermediateRepresentation;
|
||||
using ARMeilleure.Memory;
|
||||
using ARMeilleure.State;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
using static ARMeilleure.IntermediateRepresentation.OperandHelper;
|
||||
|
||||
|
@ -13,12 +10,7 @@ namespace ARMeilleure.Translation
|
|||
{
|
||||
class EmitterContext
|
||||
{
|
||||
public Block CurrBlock { get; set; }
|
||||
public OpCode CurrOp { get; set; }
|
||||
|
||||
public Aarch32Mode Mode { get; }
|
||||
|
||||
public MemoryManager Memory { get; set; }
|
||||
|
||||
private Dictionary<ulong, Operand> _labels;
|
||||
|
||||
|
@ -92,28 +84,16 @@ namespace ARMeilleure.Translation
|
|||
return Add(Instruction.ByteSwap, Local(op1.Type), op1);
|
||||
}
|
||||
|
||||
public Operand Call(MethodInfo info, params Operand[] callArgs)
|
||||
public Operand Call(Delegate func, params Operand[] callArgs)
|
||||
{
|
||||
RuntimeHelpers.PrepareMethod(info.MethodHandle);
|
||||
//Add the delegate to the cache to ensure it will not be garbage collected.
|
||||
func = DelegateCache.GetOrAdd(func);
|
||||
|
||||
long methodPtr = info.MethodHandle.GetFunctionPointer().ToInt64();
|
||||
IntPtr ptr = Marshal.GetFunctionPointerForDelegate(func);
|
||||
|
||||
Operand[] args = new Operand[callArgs.Length + 1];
|
||||
OperandType returnType = GetOperandType(func.Method.ReturnType);
|
||||
|
||||
args[0] = Const(methodPtr);
|
||||
|
||||
Array.Copy(callArgs, 0, args, 1, callArgs.Length);
|
||||
|
||||
if (info.ReturnType != typeof(void))
|
||||
{
|
||||
OperandType returnType = GetOperandType(info.ReturnType);
|
||||
|
||||
return Add(Instruction.Call, Local(returnType), args);
|
||||
}
|
||||
else
|
||||
{
|
||||
return Add(Instruction.Call, null, args);
|
||||
}
|
||||
return Call(Const(ptr.ToInt64()), returnType, callArgs);
|
||||
}
|
||||
|
||||
private static OperandType GetOperandType(Type type)
|
||||
|
@ -146,12 +126,30 @@ namespace ARMeilleure.Translation
|
|||
return OperandType.V128;
|
||||
}
|
||||
|
||||
if (type == typeof(void))
|
||||
{
|
||||
return OperandType.None;
|
||||
}
|
||||
|
||||
throw new ArgumentException($"Invalid type \"{type.Name}\".");
|
||||
}
|
||||
|
||||
public Operand Call(OperandType returnType, params Operand[] callArgs)
|
||||
public Operand Call(Operand address, OperandType returnType, params Operand[] callArgs)
|
||||
{
|
||||
return Add(Instruction.Call, Local(returnType), callArgs);
|
||||
Operand[] args = new Operand[callArgs.Length + 1];
|
||||
|
||||
args[0] = address;
|
||||
|
||||
Array.Copy(callArgs, 0, args, 1, callArgs.Length);
|
||||
|
||||
if (returnType != OperandType.None)
|
||||
{
|
||||
return Add(Instruction.Call, Local(returnType), args);
|
||||
}
|
||||
else
|
||||
{
|
||||
return Add(Instruction.Call, null, args);
|
||||
}
|
||||
}
|
||||
|
||||
public Operand CompareAndSwap128(Operand address, Operand expected, Operand desired)
|
||||
|
@ -186,6 +184,11 @@ namespace ARMeilleure.Translation
|
|||
|
||||
public Operand Copy(Operand dest, Operand op1)
|
||||
{
|
||||
if (dest.Kind != OperandKind.Register)
|
||||
{
|
||||
throw new ArgumentException($"Invalid dest operand kind \"{dest.Kind}\".");
|
||||
}
|
||||
|
||||
return Add(Instruction.Copy, dest, op1);
|
||||
}
|
||||
|
||||
|
@ -377,6 +380,11 @@ namespace ARMeilleure.Translation
|
|||
return Add(Instruction.Subtract, Local(op1.Type), op1, op2);
|
||||
}
|
||||
|
||||
public Operand VectorCreateScalar(Operand value)
|
||||
{
|
||||
return Add(Instruction.VectorCreateScalar, Local(OperandType.V128), value);
|
||||
}
|
||||
|
||||
public Operand VectorExtract(OperandType type, Operand vector, int index)
|
||||
{
|
||||
return Add(Instruction.VectorExtract, Local(type), vector, Const(index));
|
||||
|
|
|
@ -2,6 +2,7 @@ using ARMeilleure.CodeGen;
|
|||
using ARMeilleure.Memory;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
|
||||
namespace ARMeilleure.Translation
|
||||
{
|
||||
|
@ -10,7 +11,9 @@ namespace ARMeilleure.Translation
|
|||
private const int PageSize = 4 * 1024;
|
||||
private const int PageMask = PageSize - 1;
|
||||
|
||||
private static uint CacheSize = 512 * 1024 * 1024;
|
||||
private const int CodeAlignment = 4; // Bytes
|
||||
|
||||
private const int CacheSize = 512 * 1024 * 1024;
|
||||
|
||||
private static IntPtr _basePointer;
|
||||
|
||||
|
@ -60,11 +63,13 @@ namespace ARMeilleure.Translation
|
|||
|
||||
private static int Allocate(int codeSize)
|
||||
{
|
||||
int allocOffset = _offset;
|
||||
codeSize = checked(codeSize + (CodeAlignment - 1)) & ~(CodeAlignment - 1);
|
||||
|
||||
_offset += codeSize;
|
||||
int newOffset = Interlocked.Add(ref _offset, codeSize);
|
||||
|
||||
if ((ulong)(uint)_offset > CacheSize)
|
||||
int allocOffset = newOffset - codeSize;
|
||||
|
||||
if ((ulong)(uint)newOffset > CacheSize)
|
||||
{
|
||||
throw new OutOfMemoryException();
|
||||
}
|
||||
|
@ -75,20 +80,26 @@ namespace ARMeilleure.Translation
|
|||
private static void Add(JitCacheEntry entry)
|
||||
{
|
||||
//TODO: Use concurrent collection.
|
||||
_cacheEntries.Add(entry);
|
||||
lock (_cacheEntries)
|
||||
{
|
||||
_cacheEntries.Add(entry);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool TryFind(int offset, out JitCacheEntry entry)
|
||||
{
|
||||
foreach (JitCacheEntry cacheEntry in _cacheEntries)
|
||||
lock (_cacheEntries)
|
||||
{
|
||||
int endOffset = cacheEntry.Offset + cacheEntry.Size;
|
||||
|
||||
if (offset >= cacheEntry.Offset && offset < endOffset)
|
||||
foreach (JitCacheEntry cacheEntry in _cacheEntries)
|
||||
{
|
||||
entry = cacheEntry;
|
||||
int endOffset = cacheEntry.Offset + cacheEntry.Size;
|
||||
|
||||
return true;
|
||||
if (offset >= cacheEntry.Offset && offset < endOffset)
|
||||
{
|
||||
entry = cacheEntry;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@ using ARMeilleure.Memory;
|
|||
using ARMeilleure.State;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Reflection;
|
||||
|
||||
using static ARMeilleure.IntermediateRepresentation.OperandHelper;
|
||||
|
||||
|
@ -38,11 +37,6 @@ namespace ARMeilleure.Translation
|
|||
NativeInterface.UnregisterThread();
|
||||
}
|
||||
|
||||
public void SelfRegister(ExecutionContext context)
|
||||
{
|
||||
NativeInterface.RegisterThread(context, _memory);
|
||||
}
|
||||
|
||||
public ulong ExecuteSingle(ExecutionContext context, ulong address)
|
||||
{
|
||||
TranslatedFunction func = GetOrTranslate(address, ExecutionMode.Aarch64);
|
||||
|
@ -64,9 +58,7 @@ namespace ARMeilleure.Translation
|
|||
|
||||
private TranslatedFunction Translate(ulong address, ExecutionMode mode)
|
||||
{
|
||||
EmitterContext context = new EmitterContext();
|
||||
|
||||
context.Memory = _memory;
|
||||
ArmEmitterContext context = new ArmEmitterContext(_memory, Aarch32Mode.User);
|
||||
|
||||
Logger.StartPass(PassName.Decoding);
|
||||
|
||||
|
@ -98,7 +90,7 @@ namespace ARMeilleure.Translation
|
|||
return new TranslatedFunction(func);
|
||||
}
|
||||
|
||||
private static ControlFlowGraph EmitAndGetCFG(EmitterContext context, Block[] blocks)
|
||||
private static ControlFlowGraph EmitAndGetCFG(ArmEmitterContext context, Block[] blocks)
|
||||
{
|
||||
for (int blkIndex = 0; blkIndex < blocks.Length; blkIndex++)
|
||||
{
|
||||
|
@ -172,9 +164,7 @@ namespace ARMeilleure.Translation
|
|||
|
||||
context.BranchIfTrue(lblNonZero, count);
|
||||
|
||||
MethodInfo info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.CheckSynchronization));
|
||||
|
||||
context.Call(info);
|
||||
context.Call(new _Void(NativeInterface.CheckSynchronization));
|
||||
|
||||
context.Branch(lblExit);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue