Stop using GetFunctionPointer as that can't be called from native code, misc. fixes and tweaks

This commit is contained in:
gdkchan 2019-07-17 19:29:19 -03:00
parent 70970b4c22
commit 686f7f4ff2
48 changed files with 1952 additions and 2888 deletions

View file

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

View file

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

View file

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

View file

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

View file

@ -20,7 +20,6 @@ namespace ARMeilleure.CodeGen.X86
Cmpsd,
Cmpss,
Cmpxchg16b,
Cmpxchg8b,
Comisd,
Comiss,
Cvtdq2pd,

View file

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

View file

@ -2,5 +2,5 @@ using ARMeilleure.Translation;
namespace ARMeilleure.Decoders
{
delegate void InstEmitter(EmitterContext context);
delegate void InstEmitter(ArmEmitterContext context);
}

View file

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

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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();

View file

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

View file

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

View file

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

View file

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

View file

@ -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)

View file

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

View file

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

View file

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

View file

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

View file

@ -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)

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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,

View file

@ -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)

View file

@ -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()

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

View file

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

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

View file

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

View file

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

View file

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