diff --git a/ARMeilleure/CodeGen/RegisterAllocators/FastLinearScan.cs b/ARMeilleure/CodeGen/RegisterAllocators/FastLinearScan.cs index d72c60c1da..040100eee8 100644 --- a/ARMeilleure/CodeGen/RegisterAllocators/FastLinearScan.cs +++ b/ARMeilleure/CodeGen/RegisterAllocators/FastLinearScan.cs @@ -67,12 +67,24 @@ namespace ARMeilleure.CodeGen.RegisterAllocators fixedIntervals[0] = new List(); fixedIntervals[1] = new List(); + 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); diff --git a/ARMeilleure/CodeGen/RegisterAllocators/LinearScan.cs b/ARMeilleure/CodeGen/RegisterAllocators/LinearScan.cs index a49a8c0a8f..8e91f2389f 100644 --- a/ARMeilleure/CodeGen/RegisterAllocators/LinearScan.cs +++ b/ARMeilleure/CodeGen/RegisterAllocators/LinearScan.cs @@ -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; } diff --git a/ARMeilleure/CodeGen/X86/Assembler.cs b/ARMeilleure/CodeGen/X86/Assembler.cs index 1511068336..757281de09 100644 --- a/ARMeilleure/CodeGen/X86/Assembler.cs +++ b/ARMeilleure/CodeGen/X86/Assembler.cs @@ -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) diff --git a/ARMeilleure/CodeGen/X86/CodeGenerator.cs b/ARMeilleure/CodeGen/X86/CodeGenerator.cs index a523eac392..0077626436 100644 --- a/ARMeilleure/CodeGen/X86/CodeGenerator.cs +++ b/ARMeilleure/CodeGen/X86/CodeGenerator.cs @@ -16,10 +16,38 @@ namespace ARMeilleure.CodeGen.X86 { private static Action[] _instTable; + private enum X86IntrinsicType + { + Comis_, + PopCount, + Unary, + UnaryToGpr, + Binary, + BinaryImm, + Ternary, + TernaryImm + } + + private struct X86Intrinsic + { + public X86Instruction Inst { get; } + public X86IntrinsicType Type { get; } + + public X86Intrinsic(X86Instruction inst, X86IntrinsicType type) + { + Inst = inst; + Type = type; + } + } + + private static X86Intrinsic[] _x86InstTable; + static CodeGenerator() { _instTable = new Action[(int)Instruction.Count]; + _x86InstTable = new X86Intrinsic[(int)Instruction.Count]; + Add(Instruction.Add, GenerateAdd); Add(Instruction.BitwiseAnd, GenerateBitwiseAnd); Add(Instruction.BitwiseExclusiveOr, GenerateBitwiseExclusiveOr); @@ -71,6 +99,7 @@ namespace ARMeilleure.CodeGen.X86 Add(Instruction.Store16, GenerateStore16); Add(Instruction.Store8, GenerateStore8); Add(Instruction.Subtract, GenerateSubtract); + Add(Instruction.VectorCreateScalar, GenerateVectorCreateScalar); Add(Instruction.VectorExtract, GenerateVectorExtract); Add(Instruction.VectorExtract16, GenerateVectorExtract16); Add(Instruction.VectorExtract8, GenerateVectorExtract8); @@ -84,138 +113,139 @@ namespace ARMeilleure.CodeGen.X86 Add(Instruction.ZeroExtend16, GenerateZeroExtend16); Add(Instruction.ZeroExtend32, GenerateZeroExtend32); Add(Instruction.ZeroExtend8, GenerateZeroExtend8); - Add(Instruction.X86Addpd, GenerateX86Addpd); - Add(Instruction.X86Addps, GenerateX86Addps); - Add(Instruction.X86Addsd, GenerateX86Addsd); - Add(Instruction.X86Addss, GenerateX86Addss); - Add(Instruction.X86Andnpd, GenerateX86Andnpd); - Add(Instruction.X86Andnps, GenerateX86Andnps); - Add(Instruction.X86Cmppd, GenerateX86Cmppd); - Add(Instruction.X86Cmpps, GenerateX86Cmpps); - Add(Instruction.X86Cmpsd, GenerateX86Cmpsd); - Add(Instruction.X86Cmpss, GenerateX86Cmpss); - Add(Instruction.X86Comisdeq, GenerateX86Comisdeq); - Add(Instruction.X86Comisdge, GenerateX86Comisdge); - Add(Instruction.X86Comisdlt, GenerateX86Comisdlt); - Add(Instruction.X86Comisseq, GenerateX86Comisseq); - Add(Instruction.X86Comissge, GenerateX86Comissge); - Add(Instruction.X86Comisslt, GenerateX86Comisslt); - Add(Instruction.X86Cvtdq2pd, GenerateX86Cvtdq2pd); - Add(Instruction.X86Cvtdq2ps, GenerateX86Cvtdq2ps); - Add(Instruction.X86Cvtpd2dq, GenerateX86Cvtpd2dq); - Add(Instruction.X86Cvtpd2ps, GenerateX86Cvtpd2ps); - Add(Instruction.X86Cvtps2dq, GenerateX86Cvtps2dq); - Add(Instruction.X86Cvtps2pd, GenerateX86Cvtps2pd); - Add(Instruction.X86Cvtsd2si, GenerateX86Cvtsd2si); - Add(Instruction.X86Cvtsd2ss, GenerateX86Cvtsd2ss); - Add(Instruction.X86Cvtss2sd, GenerateX86Cvtss2sd); - Add(Instruction.X86Divpd, GenerateX86Divpd); - Add(Instruction.X86Divps, GenerateX86Divps); - Add(Instruction.X86Divsd, GenerateX86Divsd); - Add(Instruction.X86Divss, GenerateX86Divss); - Add(Instruction.X86Haddpd, GenerateX86Haddpd); - Add(Instruction.X86Haddps, GenerateX86Haddps); - Add(Instruction.X86Maxpd, GenerateX86Maxpd); - Add(Instruction.X86Maxps, GenerateX86Maxps); - Add(Instruction.X86Maxsd, GenerateX86Maxsd); - Add(Instruction.X86Maxss, GenerateX86Maxss); - Add(Instruction.X86Minpd, GenerateX86Minpd); - Add(Instruction.X86Minps, GenerateX86Minps); - Add(Instruction.X86Minsd, GenerateX86Minsd); - Add(Instruction.X86Minss, GenerateX86Minss); - Add(Instruction.X86Movhlps, GenerateX86Movhlps); - Add(Instruction.X86Movlhps, GenerateX86Movlhps); - Add(Instruction.X86Mulpd, GenerateX86Mulpd); - Add(Instruction.X86Mulps, GenerateX86Mulps); - Add(Instruction.X86Mulsd, GenerateX86Mulsd); - Add(Instruction.X86Mulss, GenerateX86Mulss); - Add(Instruction.X86Paddb, GenerateX86Paddb); - Add(Instruction.X86Paddd, GenerateX86Paddd); - Add(Instruction.X86Paddq, GenerateX86Paddq); - Add(Instruction.X86Paddw, GenerateX86Paddw); - Add(Instruction.X86Pand, GenerateX86Pand); - Add(Instruction.X86Pandn, GenerateX86Pandn); - Add(Instruction.X86Pavgb, GenerateX86Pavgb); - Add(Instruction.X86Pavgw, GenerateX86Pavgw); - Add(Instruction.X86Pblendvb, GenerateX86Pblendvb); - Add(Instruction.X86Pcmpeqb, GenerateX86Pcmpeqb); - Add(Instruction.X86Pcmpeqd, GenerateX86Pcmpeqd); - Add(Instruction.X86Pcmpeqq, GenerateX86Pcmpeqq); - Add(Instruction.X86Pcmpeqw, GenerateX86Pcmpeqw); - Add(Instruction.X86Pcmpgtb, GenerateX86Pcmpgtb); - Add(Instruction.X86Pcmpgtd, GenerateX86Pcmpgtd); - Add(Instruction.X86Pcmpgtq, GenerateX86Pcmpgtq); - Add(Instruction.X86Pcmpgtw, GenerateX86Pcmpgtw); - Add(Instruction.X86Pmaxsb, GenerateX86Pmaxsb); - Add(Instruction.X86Pmaxsd, GenerateX86Pmaxsd); - Add(Instruction.X86Pmaxsw, GenerateX86Pmaxsw); - Add(Instruction.X86Pmaxub, GenerateX86Pmaxub); - Add(Instruction.X86Pmaxud, GenerateX86Pmaxud); - Add(Instruction.X86Pmaxuw, GenerateX86Pmaxuw); - Add(Instruction.X86Pminsb, GenerateX86Pminsb); - Add(Instruction.X86Pminsd, GenerateX86Pminsd); - Add(Instruction.X86Pminsw, GenerateX86Pminsw); - Add(Instruction.X86Pminub, GenerateX86Pminub); - Add(Instruction.X86Pminud, GenerateX86Pminud); - Add(Instruction.X86Pminuw, GenerateX86Pminuw); - Add(Instruction.X86Pmovsxbw, GenerateX86Pmovsxbw); - Add(Instruction.X86Pmovsxdq, GenerateX86Pmovsxdq); - Add(Instruction.X86Pmovsxwd, GenerateX86Pmovsxwd); - Add(Instruction.X86Pmovzxbw, GenerateX86Pmovzxbw); - Add(Instruction.X86Pmovzxdq, GenerateX86Pmovzxdq); - Add(Instruction.X86Pmovzxwd, GenerateX86Pmovzxwd); - Add(Instruction.X86Pmulld, GenerateX86Pmulld); - Add(Instruction.X86Pmullw, GenerateX86Pmullw); - Add(Instruction.X86Popcnt, GenerateX86Popcnt); - Add(Instruction.X86Por, GenerateX86Por); - Add(Instruction.X86Pshufb, GenerateX86Pshufb); - Add(Instruction.X86Pslld, GenerateX86Pslld); - Add(Instruction.X86Pslldq, GenerateX86Pslldq); - Add(Instruction.X86Psllq, GenerateX86Psllq); - Add(Instruction.X86Psllw, GenerateX86Psllw); - Add(Instruction.X86Psrad, GenerateX86Psrad); - Add(Instruction.X86Psraw, GenerateX86Psraw); - Add(Instruction.X86Psrld, GenerateX86Psrld); - Add(Instruction.X86Psrlq, GenerateX86Psrlq); - Add(Instruction.X86Psrldq, GenerateX86Psrldq); - Add(Instruction.X86Psrlw, GenerateX86Psrlw); - Add(Instruction.X86Psubb, GenerateX86Psubb); - Add(Instruction.X86Psubd, GenerateX86Psubd); - Add(Instruction.X86Psubq, GenerateX86Psubq); - Add(Instruction.X86Psubw, GenerateX86Psubw); - Add(Instruction.X86Punpckhbw, GenerateX86Punpckhbw); - Add(Instruction.X86Punpckhdq, GenerateX86Punpckhdq); - Add(Instruction.X86Punpckhqdq, GenerateX86Punpckhqdq); - Add(Instruction.X86Punpckhwd, GenerateX86Punpckhwd); - Add(Instruction.X86Punpcklbw, GenerateX86Punpcklbw); - Add(Instruction.X86Punpckldq, GenerateX86Punpckldq); - Add(Instruction.X86Punpcklqdq, GenerateX86Punpcklqdq); - Add(Instruction.X86Punpcklwd, GenerateX86Punpcklwd); - Add(Instruction.X86Pxor, GenerateX86Pxor); - Add(Instruction.X86Rcpps, GenerateX86Rcpps); - Add(Instruction.X86Rcpss, GenerateX86Rcpss); - Add(Instruction.X86Roundpd, GenerateX86Roundpd); - Add(Instruction.X86Roundps, GenerateX86Roundps); - Add(Instruction.X86Roundsd, GenerateX86Roundsd); - Add(Instruction.X86Roundss, GenerateX86Roundss); - Add(Instruction.X86Rsqrtps, GenerateX86Rsqrtps); - Add(Instruction.X86Rsqrtss, GenerateX86Rsqrtss); - Add(Instruction.X86Shufpd, GenerateX86Shufpd); - Add(Instruction.X86Shufps, GenerateX86Shufps); - Add(Instruction.X86Sqrtpd, GenerateX86Sqrtpd); - Add(Instruction.X86Sqrtps, GenerateX86Sqrtps); - Add(Instruction.X86Sqrtsd, GenerateX86Sqrtsd); - Add(Instruction.X86Sqrtss, GenerateX86Sqrtss); - Add(Instruction.X86Subpd, GenerateX86Subpd); - Add(Instruction.X86Subps, GenerateX86Subps); - Add(Instruction.X86Subsd, GenerateX86Subsd); - Add(Instruction.X86Subss, GenerateX86Subss); - Add(Instruction.X86Unpckhpd, GenerateX86Unpckhpd); - Add(Instruction.X86Unpckhps, GenerateX86Unpckhps); - Add(Instruction.X86Unpcklpd, GenerateX86Unpcklpd); - Add(Instruction.X86Unpcklps, GenerateX86Unpcklps); - Add(Instruction.X86Xorpd, GenerateX86Xorpd); - Add(Instruction.X86Xorps, GenerateX86Xorps); + + Add(Instruction.X86Addpd, new X86Intrinsic(X86Instruction.Addpd, X86IntrinsicType.Binary)); + Add(Instruction.X86Addps, new X86Intrinsic(X86Instruction.Addps, X86IntrinsicType.Binary)); + Add(Instruction.X86Addsd, new X86Intrinsic(X86Instruction.Addsd, X86IntrinsicType.Binary)); + Add(Instruction.X86Addss, new X86Intrinsic(X86Instruction.Addss, X86IntrinsicType.Binary)); + Add(Instruction.X86Andnpd, new X86Intrinsic(X86Instruction.Andnpd, X86IntrinsicType.Binary)); + Add(Instruction.X86Andnps, new X86Intrinsic(X86Instruction.Andnps, X86IntrinsicType.Binary)); + Add(Instruction.X86Cmppd, new X86Intrinsic(X86Instruction.Cmppd, X86IntrinsicType.TernaryImm)); + Add(Instruction.X86Cmpps, new X86Intrinsic(X86Instruction.Cmpps, X86IntrinsicType.TernaryImm)); + Add(Instruction.X86Cmpsd, new X86Intrinsic(X86Instruction.Cmpsd, X86IntrinsicType.TernaryImm)); + Add(Instruction.X86Cmpss, new X86Intrinsic(X86Instruction.Cmpss, X86IntrinsicType.TernaryImm)); + Add(Instruction.X86Comisdeq, new X86Intrinsic(X86Instruction.Comisd, X86IntrinsicType.Comis_)); + Add(Instruction.X86Comisdge, new X86Intrinsic(X86Instruction.Comisd, X86IntrinsicType.Comis_)); + Add(Instruction.X86Comisdlt, new X86Intrinsic(X86Instruction.Comisd, X86IntrinsicType.Comis_)); + Add(Instruction.X86Comisseq, new X86Intrinsic(X86Instruction.Comiss, X86IntrinsicType.Comis_)); + Add(Instruction.X86Comissge, new X86Intrinsic(X86Instruction.Comiss, X86IntrinsicType.Comis_)); + Add(Instruction.X86Comisslt, new X86Intrinsic(X86Instruction.Comiss, X86IntrinsicType.Comis_)); + Add(Instruction.X86Cvtdq2pd, new X86Intrinsic(X86Instruction.Cvtdq2pd, X86IntrinsicType.Unary)); + Add(Instruction.X86Cvtdq2ps, new X86Intrinsic(X86Instruction.Cvtdq2ps, X86IntrinsicType.Unary)); + Add(Instruction.X86Cvtpd2dq, new X86Intrinsic(X86Instruction.Cvtpd2dq, X86IntrinsicType.Unary)); + Add(Instruction.X86Cvtpd2ps, new X86Intrinsic(X86Instruction.Cvtpd2ps, X86IntrinsicType.Unary)); + Add(Instruction.X86Cvtps2dq, new X86Intrinsic(X86Instruction.Cvtps2dq, X86IntrinsicType.Unary)); + Add(Instruction.X86Cvtps2pd, new X86Intrinsic(X86Instruction.Cvtps2pd, X86IntrinsicType.Unary)); + Add(Instruction.X86Cvtsd2si, new X86Intrinsic(X86Instruction.Cvtsd2si, X86IntrinsicType.UnaryToGpr)); + Add(Instruction.X86Cvtsd2ss, new X86Intrinsic(X86Instruction.Cvtsd2ss, X86IntrinsicType.Binary)); + Add(Instruction.X86Cvtss2sd, new X86Intrinsic(X86Instruction.Cvtss2sd, X86IntrinsicType.Binary)); + Add(Instruction.X86Divpd, new X86Intrinsic(X86Instruction.Divpd, X86IntrinsicType.Binary)); + Add(Instruction.X86Divps, new X86Intrinsic(X86Instruction.Divps, X86IntrinsicType.Binary)); + Add(Instruction.X86Divsd, new X86Intrinsic(X86Instruction.Divsd, X86IntrinsicType.Binary)); + Add(Instruction.X86Divss, new X86Intrinsic(X86Instruction.Divss, X86IntrinsicType.Binary)); + Add(Instruction.X86Haddpd, new X86Intrinsic(X86Instruction.Haddpd, X86IntrinsicType.Binary)); + Add(Instruction.X86Haddps, new X86Intrinsic(X86Instruction.Haddps, X86IntrinsicType.Binary)); + Add(Instruction.X86Maxpd, new X86Intrinsic(X86Instruction.Maxpd, X86IntrinsicType.Binary)); + Add(Instruction.X86Maxps, new X86Intrinsic(X86Instruction.Maxps, X86IntrinsicType.Binary)); + Add(Instruction.X86Maxsd, new X86Intrinsic(X86Instruction.Maxsd, X86IntrinsicType.Binary)); + Add(Instruction.X86Maxss, new X86Intrinsic(X86Instruction.Maxss, X86IntrinsicType.Binary)); + Add(Instruction.X86Minpd, new X86Intrinsic(X86Instruction.Minpd, X86IntrinsicType.Binary)); + Add(Instruction.X86Minps, new X86Intrinsic(X86Instruction.Minps, X86IntrinsicType.Binary)); + Add(Instruction.X86Minsd, new X86Intrinsic(X86Instruction.Minsd, X86IntrinsicType.Binary)); + Add(Instruction.X86Minss, new X86Intrinsic(X86Instruction.Minss, X86IntrinsicType.Binary)); + Add(Instruction.X86Movhlps, new X86Intrinsic(X86Instruction.Movhlps, X86IntrinsicType.Binary)); + Add(Instruction.X86Movlhps, new X86Intrinsic(X86Instruction.Movlhps, X86IntrinsicType.Binary)); + Add(Instruction.X86Mulpd, new X86Intrinsic(X86Instruction.Mulpd, X86IntrinsicType.Binary)); + Add(Instruction.X86Mulps, new X86Intrinsic(X86Instruction.Mulps, X86IntrinsicType.Binary)); + Add(Instruction.X86Mulsd, new X86Intrinsic(X86Instruction.Mulsd, X86IntrinsicType.Binary)); + Add(Instruction.X86Mulss, new X86Intrinsic(X86Instruction.Mulss, X86IntrinsicType.Binary)); + Add(Instruction.X86Paddb, new X86Intrinsic(X86Instruction.Paddb, X86IntrinsicType.Binary)); + Add(Instruction.X86Paddd, new X86Intrinsic(X86Instruction.Paddd, X86IntrinsicType.Binary)); + Add(Instruction.X86Paddq, new X86Intrinsic(X86Instruction.Paddq, X86IntrinsicType.Binary)); + Add(Instruction.X86Paddw, new X86Intrinsic(X86Instruction.Paddw, X86IntrinsicType.Binary)); + Add(Instruction.X86Pand, new X86Intrinsic(X86Instruction.Pand, X86IntrinsicType.Binary)); + Add(Instruction.X86Pandn, new X86Intrinsic(X86Instruction.Pandn, X86IntrinsicType.Binary)); + Add(Instruction.X86Pavgb, new X86Intrinsic(X86Instruction.Pavgb, X86IntrinsicType.Binary)); + Add(Instruction.X86Pavgw, new X86Intrinsic(X86Instruction.Pavgw, X86IntrinsicType.Binary)); + Add(Instruction.X86Pblendvb, new X86Intrinsic(X86Instruction.Pblendvb, X86IntrinsicType.Ternary)); + Add(Instruction.X86Pcmpeqb, new X86Intrinsic(X86Instruction.Pcmpeqb, X86IntrinsicType.Binary)); + Add(Instruction.X86Pcmpeqd, new X86Intrinsic(X86Instruction.Pcmpeqd, X86IntrinsicType.Binary)); + Add(Instruction.X86Pcmpeqq, new X86Intrinsic(X86Instruction.Pcmpeqq, X86IntrinsicType.Binary)); + Add(Instruction.X86Pcmpeqw, new X86Intrinsic(X86Instruction.Pcmpeqw, X86IntrinsicType.Binary)); + Add(Instruction.X86Pcmpgtb, new X86Intrinsic(X86Instruction.Pcmpgtb, X86IntrinsicType.Binary)); + Add(Instruction.X86Pcmpgtd, new X86Intrinsic(X86Instruction.Pcmpgtd, X86IntrinsicType.Binary)); + Add(Instruction.X86Pcmpgtq, new X86Intrinsic(X86Instruction.Pcmpgtq, X86IntrinsicType.Binary)); + Add(Instruction.X86Pcmpgtw, new X86Intrinsic(X86Instruction.Pcmpgtw, X86IntrinsicType.Binary)); + Add(Instruction.X86Pmaxsb, new X86Intrinsic(X86Instruction.Pmaxsb, X86IntrinsicType.Binary)); + Add(Instruction.X86Pmaxsd, new X86Intrinsic(X86Instruction.Pmaxsd, X86IntrinsicType.Binary)); + Add(Instruction.X86Pmaxsw, new X86Intrinsic(X86Instruction.Pmaxsw, X86IntrinsicType.Binary)); + Add(Instruction.X86Pmaxub, new X86Intrinsic(X86Instruction.Pmaxub, X86IntrinsicType.Binary)); + Add(Instruction.X86Pmaxud, new X86Intrinsic(X86Instruction.Pmaxud, X86IntrinsicType.Binary)); + Add(Instruction.X86Pmaxuw, new X86Intrinsic(X86Instruction.Pmaxuw, X86IntrinsicType.Binary)); + Add(Instruction.X86Pminsb, new X86Intrinsic(X86Instruction.Pminsb, X86IntrinsicType.Binary)); + Add(Instruction.X86Pminsd, new X86Intrinsic(X86Instruction.Pminsd, X86IntrinsicType.Binary)); + Add(Instruction.X86Pminsw, new X86Intrinsic(X86Instruction.Pminsw, X86IntrinsicType.Binary)); + Add(Instruction.X86Pminub, new X86Intrinsic(X86Instruction.Pminub, X86IntrinsicType.Binary)); + Add(Instruction.X86Pminud, new X86Intrinsic(X86Instruction.Pminud, X86IntrinsicType.Binary)); + Add(Instruction.X86Pminuw, new X86Intrinsic(X86Instruction.Pminuw, X86IntrinsicType.Binary)); + Add(Instruction.X86Pmovsxbw, new X86Intrinsic(X86Instruction.Pmovsxbw, X86IntrinsicType.Unary)); + Add(Instruction.X86Pmovsxdq, new X86Intrinsic(X86Instruction.Pmovsxdq, X86IntrinsicType.Unary)); + Add(Instruction.X86Pmovsxwd, new X86Intrinsic(X86Instruction.Pmovsxwd, X86IntrinsicType.Unary)); + Add(Instruction.X86Pmovzxbw, new X86Intrinsic(X86Instruction.Pmovzxbw, X86IntrinsicType.Unary)); + Add(Instruction.X86Pmovzxdq, new X86Intrinsic(X86Instruction.Pmovzxdq, X86IntrinsicType.Unary)); + Add(Instruction.X86Pmovzxwd, new X86Intrinsic(X86Instruction.Pmovzxwd, X86IntrinsicType.Unary)); + Add(Instruction.X86Pmulld, new X86Intrinsic(X86Instruction.Pmulld, X86IntrinsicType.Binary)); + Add(Instruction.X86Pmullw, new X86Intrinsic(X86Instruction.Pmullw, X86IntrinsicType.Binary)); + Add(Instruction.X86Popcnt, new X86Intrinsic(X86Instruction.Popcnt, X86IntrinsicType.PopCount)); + Add(Instruction.X86Por, new X86Intrinsic(X86Instruction.Por, X86IntrinsicType.Binary)); + Add(Instruction.X86Pshufb, new X86Intrinsic(X86Instruction.Pshufb, X86IntrinsicType.Binary)); + Add(Instruction.X86Pslld, new X86Intrinsic(X86Instruction.Pslld, X86IntrinsicType.Binary)); + Add(Instruction.X86Pslldq, new X86Intrinsic(X86Instruction.Pslldq, X86IntrinsicType.Binary)); + Add(Instruction.X86Psllq, new X86Intrinsic(X86Instruction.Psllq, X86IntrinsicType.Binary)); + Add(Instruction.X86Psllw, new X86Intrinsic(X86Instruction.Psllw, X86IntrinsicType.Binary)); + Add(Instruction.X86Psrad, new X86Intrinsic(X86Instruction.Psrad, X86IntrinsicType.Binary)); + Add(Instruction.X86Psraw, new X86Intrinsic(X86Instruction.Psraw, X86IntrinsicType.Binary)); + Add(Instruction.X86Psrld, new X86Intrinsic(X86Instruction.Psrld, X86IntrinsicType.Binary)); + Add(Instruction.X86Psrlq, new X86Intrinsic(X86Instruction.Psrlq, X86IntrinsicType.Binary)); + Add(Instruction.X86Psrldq, new X86Intrinsic(X86Instruction.Psrldq, X86IntrinsicType.Binary)); + Add(Instruction.X86Psrlw, new X86Intrinsic(X86Instruction.Psrlw, X86IntrinsicType.Binary)); + Add(Instruction.X86Psubb, new X86Intrinsic(X86Instruction.Psubb, X86IntrinsicType.Binary)); + Add(Instruction.X86Psubd, new X86Intrinsic(X86Instruction.Psubd, X86IntrinsicType.Binary)); + Add(Instruction.X86Psubq, new X86Intrinsic(X86Instruction.Psubq, X86IntrinsicType.Binary)); + Add(Instruction.X86Psubw, new X86Intrinsic(X86Instruction.Psubw, X86IntrinsicType.Binary)); + Add(Instruction.X86Punpckhbw, new X86Intrinsic(X86Instruction.Punpckhbw, X86IntrinsicType.Binary)); + Add(Instruction.X86Punpckhdq, new X86Intrinsic(X86Instruction.Punpckhdq, X86IntrinsicType.Binary)); + Add(Instruction.X86Punpckhqdq, new X86Intrinsic(X86Instruction.Punpckhqdq, X86IntrinsicType.Binary)); + Add(Instruction.X86Punpckhwd, new X86Intrinsic(X86Instruction.Punpckhwd, X86IntrinsicType.Binary)); + Add(Instruction.X86Punpcklbw, new X86Intrinsic(X86Instruction.Punpcklbw, X86IntrinsicType.Binary)); + Add(Instruction.X86Punpckldq, new X86Intrinsic(X86Instruction.Punpckldq, X86IntrinsicType.Binary)); + Add(Instruction.X86Punpcklqdq, new X86Intrinsic(X86Instruction.Punpcklqdq, X86IntrinsicType.Binary)); + Add(Instruction.X86Punpcklwd, new X86Intrinsic(X86Instruction.Punpcklwd, X86IntrinsicType.Binary)); + Add(Instruction.X86Pxor, new X86Intrinsic(X86Instruction.Pxor, X86IntrinsicType.Binary)); + Add(Instruction.X86Rcpps, new X86Intrinsic(X86Instruction.Rcpps, X86IntrinsicType.Unary)); + Add(Instruction.X86Rcpss, new X86Intrinsic(X86Instruction.Rcpss, X86IntrinsicType.Unary)); + Add(Instruction.X86Roundpd, new X86Intrinsic(X86Instruction.Roundpd, X86IntrinsicType.BinaryImm)); + Add(Instruction.X86Roundps, new X86Intrinsic(X86Instruction.Roundps, X86IntrinsicType.BinaryImm)); + Add(Instruction.X86Roundsd, new X86Intrinsic(X86Instruction.Roundsd, X86IntrinsicType.BinaryImm)); + Add(Instruction.X86Roundss, new X86Intrinsic(X86Instruction.Roundss, X86IntrinsicType.BinaryImm)); + Add(Instruction.X86Rsqrtps, new X86Intrinsic(X86Instruction.Rsqrtps, X86IntrinsicType.Unary)); + Add(Instruction.X86Rsqrtss, new X86Intrinsic(X86Instruction.Rsqrtss, X86IntrinsicType.Unary)); + Add(Instruction.X86Shufpd, new X86Intrinsic(X86Instruction.Shufpd, X86IntrinsicType.TernaryImm)); + Add(Instruction.X86Shufps, new X86Intrinsic(X86Instruction.Shufps, X86IntrinsicType.TernaryImm)); + Add(Instruction.X86Sqrtpd, new X86Intrinsic(X86Instruction.Sqrtpd, X86IntrinsicType.Unary)); + Add(Instruction.X86Sqrtps, new X86Intrinsic(X86Instruction.Sqrtps, X86IntrinsicType.Unary)); + Add(Instruction.X86Sqrtsd, new X86Intrinsic(X86Instruction.Sqrtsd, X86IntrinsicType.Unary)); + Add(Instruction.X86Sqrtss, new X86Intrinsic(X86Instruction.Sqrtss, X86IntrinsicType.Unary)); + Add(Instruction.X86Subpd, new X86Intrinsic(X86Instruction.Subpd, X86IntrinsicType.Binary)); + Add(Instruction.X86Subps, new X86Intrinsic(X86Instruction.Subps, X86IntrinsicType.Binary)); + Add(Instruction.X86Subsd, new X86Intrinsic(X86Instruction.Subsd, X86IntrinsicType.Binary)); + Add(Instruction.X86Subss, new X86Intrinsic(X86Instruction.Subss, X86IntrinsicType.Binary)); + Add(Instruction.X86Unpckhpd, new X86Intrinsic(X86Instruction.Unpckhpd, X86IntrinsicType.Binary)); + Add(Instruction.X86Unpckhps, new X86Intrinsic(X86Instruction.Unpckhps, X86IntrinsicType.Binary)); + Add(Instruction.X86Unpcklpd, new X86Intrinsic(X86Instruction.Unpcklpd, X86IntrinsicType.Binary)); + Add(Instruction.X86Unpcklps, new X86Intrinsic(X86Instruction.Unpcklps, X86IntrinsicType.Binary)); + Add(Instruction.X86Xorpd, new X86Intrinsic(X86Instruction.Xorpd, X86IntrinsicType.Binary)); + Add(Instruction.X86Xorps, new X86Intrinsic(X86Instruction.Xorps, X86IntrinsicType.Binary)); } private static void Add(Instruction inst, Action func) @@ -223,6 +253,11 @@ namespace ARMeilleure.CodeGen.X86 _instTable[(int)inst] = func; } + private static void Add(Instruction inst, X86Intrinsic intrin) + { + _x86InstTable[(int)inst] = intrin; + } + public static CompiledFunction Generate(CompilerContext cctx) { ControlFlowGraph cfg = cctx.Cfg; @@ -286,15 +321,146 @@ namespace ARMeilleure.CodeGen.X86 private static void GenerateOperation(CodeGenContext context, Operation operation) { - Action func = _instTable[(int)operation.Inst]; - - if (func != null) + if (operation.Inst > Instruction.X86Intrinsic_Start && + operation.Inst < Instruction.X86Intrinsic_End) { - func(context, operation); + X86Intrinsic intrin = _x86InstTable[(int)operation.Inst]; + + switch (intrin.Type) + { + case X86IntrinsicType.Comis_: + { + Operand dest = operation.Dest; + Operand src1 = operation.GetSource(0); + Operand src2 = operation.GetSource(1); + + switch (operation.Inst) + { + case Instruction.X86Comisdeq: + context.Assembler.Comisd(src1, src2); + context.Assembler.Setcc(dest, X86Condition.Equal); + break; + + case Instruction.X86Comisdge: + context.Assembler.Comisd(src1, src2); + context.Assembler.Setcc(dest, X86Condition.AboveOrEqual); + break; + + case Instruction.X86Comisdlt: + context.Assembler.Comisd(src1, src2); + context.Assembler.Setcc(dest, X86Condition.Below); + break; + + case Instruction.X86Comisseq: + context.Assembler.Comiss(src1, src2); + context.Assembler.Setcc(dest, X86Condition.Equal); + break; + + case Instruction.X86Comissge: + context.Assembler.Comiss(src1, src2); + context.Assembler.Setcc(dest, X86Condition.AboveOrEqual); + break; + + case Instruction.X86Comisslt: + context.Assembler.Comiss(src1, src2); + context.Assembler.Setcc(dest, X86Condition.Below); + break; + } + + context.Assembler.Movzx8(dest, dest); + + break; + } + + case X86IntrinsicType.PopCount: + { + Operand dest = operation.Dest; + Operand source = operation.GetSource(0); + + context.Assembler.Popcnt(dest, source); + + break; + } + + case X86IntrinsicType.Unary: + { + Operand dest = operation.Dest; + Operand source = operation.GetSource(0); + + context.Assembler.WriteInstruction(intrin.Inst, dest, source); + + break; + } + + case X86IntrinsicType.UnaryToGpr: + { + Operand dest = operation.Dest; + Operand source = operation.GetSource(0); + + context.Assembler.WriteInstruction(intrin.Inst, dest, source); + + break; + } + + case X86IntrinsicType.Binary: + { + Operand dest = operation.Dest; + Operand src1 = operation.GetSource(0); + Operand src2 = operation.GetSource(1); + + context.Assembler.WriteInstruction(intrin.Inst, dest, src1, src2); + + break; + } + + case X86IntrinsicType.BinaryImm: + { + Operand dest = operation.Dest; + Operand source = operation.GetSource(0); + byte imm = operation.GetSource(1).AsByte(); + + context.Assembler.WriteInstruction(intrin.Inst, dest, source, imm); + + break; + } + + case X86IntrinsicType.Ternary: + { + Operand dest = operation.Dest; + Operand src1 = operation.GetSource(0); + Operand src2 = operation.GetSource(1); + Operand src3 = operation.GetSource(2); + + context.Assembler.WriteInstruction(intrin.Inst, dest, src1, src2, src3); + + break; + } + + case X86IntrinsicType.TernaryImm: + { + Operand dest = operation.Dest; + Operand src1 = operation.GetSource(0); + Operand src2 = operation.GetSource(1); + byte imm = operation.GetSource(2).AsByte(); + + context.Assembler.WriteInstruction(intrin.Inst, dest, src1, src2, imm); + + break; + } + } } else { - throw new ArgumentException($"Invalid instruction \"{operation.Inst}\"."); + Action func = _instTable[(int)operation.Inst]; + + if (func != null) + { + func(context, operation); + } + else + { + throw new ArgumentException($"Invalid instruction \"{operation.Inst}\"."); + } } } @@ -437,6 +603,7 @@ namespace ARMeilleure.CodeGen.X86 GenerateCompare(context, operation, X86Condition.Below); } + private static void GenerateCompareNotEqual(CodeGenContext context, Operation operation) { GenerateCompare(context, operation, X86Condition.NotEqual); @@ -521,14 +688,7 @@ namespace ARMeilleure.CodeGen.X86 } else if (dest.GetRegister().Type == RegisterType.Vector) { - if (source.GetRegister().Type == RegisterType.Integer) - { - context.Assembler.Movd(dest, source); - } - else - { - context.Assembler.Movdqu(dest, source); - } + context.Assembler.Movdqu(dest, source); } else { @@ -843,6 +1003,14 @@ namespace ARMeilleure.CodeGen.X86 } } + private static void GenerateVectorCreateScalar(CodeGenContext context, Operation operation) + { + Operand dest = operation.Dest; + Operand source = operation.GetSource(0); + + context.Assembler.Movd(dest, source); + } + private static void GenerateVectorExtract(CodeGenContext context, Operation operation) { Operand dest = operation.Dest; //Value @@ -1012,706 +1180,6 @@ namespace ARMeilleure.CodeGen.X86 context.Assembler.Movzx8(operation.Dest, Get32BitsRegister(operation.GetSource(0).GetRegister())); } - private static void GenerateX86Addpd(CodeGenContext context, Operation operation) - { - context.Assembler.Addpd(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Addps(CodeGenContext context, Operation operation) - { - context.Assembler.Addps(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Addsd(CodeGenContext context, Operation operation) - { - context.Assembler.Addsd(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Addss(CodeGenContext context, Operation operation) - { - context.Assembler.Addss(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Andnpd(CodeGenContext context, Operation operation) - { - context.Assembler.Andnpd(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Andnps(CodeGenContext context, Operation operation) - { - context.Assembler.Andnps(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Cmppd(CodeGenContext context, Operation operation) - { - context.Assembler.Cmppd( - operation.Dest, - operation.GetSource(1), - operation.GetSource(0), - operation.GetSource(2).AsByte()); - } - - private static void GenerateX86Cmpps(CodeGenContext context, Operation operation) - { - context.Assembler.Cmpps( - operation.Dest, - operation.GetSource(1), - operation.GetSource(0), - operation.GetSource(2).AsByte()); - } - - private static void GenerateX86Cmpsd(CodeGenContext context, Operation operation) - { - context.Assembler.Cmpsd( - operation.Dest, - operation.GetSource(1), - operation.GetSource(0), - operation.GetSource(2).AsByte()); - } - - private static void GenerateX86Cmpss(CodeGenContext context, Operation operation) - { - context.Assembler.Cmpss( - operation.Dest, - operation.GetSource(1), - operation.GetSource(0), - operation.GetSource(2).AsByte()); - } - - private static void GenerateX86Comisdeq(CodeGenContext context, Operation operation) - { - context.Assembler.Comisd(operation.GetSource(0), operation.GetSource(1)); - context.Assembler.Setcc(operation.Dest, X86Condition.Equal); - context.Assembler.Movzx8(operation.Dest, operation.Dest); - } - - private static void GenerateX86Comisdge(CodeGenContext context, Operation operation) - { - context.Assembler.Comisd(operation.GetSource(0), operation.GetSource(1)); - context.Assembler.Setcc(operation.Dest, X86Condition.AboveOrEqual); - context.Assembler.Movzx8(operation.Dest, operation.Dest); - } - - private static void GenerateX86Comisdlt(CodeGenContext context, Operation operation) - { - context.Assembler.Comisd(operation.GetSource(0), operation.GetSource(1)); - context.Assembler.Setcc(operation.Dest, X86Condition.Below); - context.Assembler.Movzx8(operation.Dest, operation.Dest); - } - - private static void GenerateX86Comisseq(CodeGenContext context, Operation operation) - { - context.Assembler.Comiss(operation.GetSource(0), operation.GetSource(1)); - context.Assembler.Setcc(operation.Dest, X86Condition.Equal); - context.Assembler.Movzx8(operation.Dest, operation.Dest); - } - - private static void GenerateX86Comissge(CodeGenContext context, Operation operation) - { - context.Assembler.Comiss(operation.GetSource(0), operation.GetSource(1)); - context.Assembler.Setcc(operation.Dest, X86Condition.AboveOrEqual); - context.Assembler.Movzx8(operation.Dest, operation.Dest); - } - - private static void GenerateX86Comisslt(CodeGenContext context, Operation operation) - { - context.Assembler.Comiss(operation.GetSource(0), operation.GetSource(1)); - context.Assembler.Setcc(operation.Dest, X86Condition.Below); - context.Assembler.Movzx8(operation.Dest, operation.Dest); - } - - private static void GenerateX86Cvtdq2pd(CodeGenContext context, Operation operation) - { - context.Assembler.Cvtdq2pd(operation.Dest, operation.GetSource(0)); - } - - private static void GenerateX86Cvtdq2ps(CodeGenContext context, Operation operation) - { - context.Assembler.Cvtdq2ps(operation.Dest, operation.GetSource(0)); - } - - private static void GenerateX86Cvtpd2dq(CodeGenContext context, Operation operation) - { - context.Assembler.Cvtpd2dq(operation.Dest, operation.GetSource(0)); - } - - private static void GenerateX86Cvtpd2ps(CodeGenContext context, Operation operation) - { - context.Assembler.Cvtpd2ps(operation.Dest, operation.GetSource(0)); - } - - private static void GenerateX86Cvtps2dq(CodeGenContext context, Operation operation) - { - context.Assembler.Cvtps2dq(operation.Dest, operation.GetSource(0)); - } - - private static void GenerateX86Cvtps2pd(CodeGenContext context, Operation operation) - { - context.Assembler.Cvtps2pd(operation.Dest, operation.GetSource(0)); - } - - private static void GenerateX86Cvtsd2si(CodeGenContext context, Operation operation) - { - context.Assembler.Cvtsd2si(operation.Dest, operation.GetSource(0)); - } - - private static void GenerateX86Cvtsd2ss(CodeGenContext context, Operation operation) - { - context.Assembler.Cvtsd2ss(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Cvtss2sd(CodeGenContext context, Operation operation) - { - context.Assembler.Cvtss2sd(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Divpd(CodeGenContext context, Operation operation) - { - context.Assembler.Divpd(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Divps(CodeGenContext context, Operation operation) - { - context.Assembler.Divps(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Divsd(CodeGenContext context, Operation operation) - { - context.Assembler.Divsd(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Divss(CodeGenContext context, Operation operation) - { - context.Assembler.Divss(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Haddpd(CodeGenContext context, Operation operation) - { - context.Assembler.Addpd(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Haddps(CodeGenContext context, Operation operation) - { - context.Assembler.Addps(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Maxpd(CodeGenContext context, Operation operation) - { - context.Assembler.Maxpd(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Maxps(CodeGenContext context, Operation operation) - { - context.Assembler.Maxps(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Maxsd(CodeGenContext context, Operation operation) - { - context.Assembler.Maxsd(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Maxss(CodeGenContext context, Operation operation) - { - context.Assembler.Maxss(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Minpd(CodeGenContext context, Operation operation) - { - context.Assembler.Minpd(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Minps(CodeGenContext context, Operation operation) - { - context.Assembler.Minps(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Minsd(CodeGenContext context, Operation operation) - { - context.Assembler.Minsd(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Minss(CodeGenContext context, Operation operation) - { - context.Assembler.Minss(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Movhlps(CodeGenContext context, Operation operation) - { - context.Assembler.Movhlps(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Movlhps(CodeGenContext context, Operation operation) - { - context.Assembler.Movlhps(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Mulpd(CodeGenContext context, Operation operation) - { - context.Assembler.Mulpd(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Mulps(CodeGenContext context, Operation operation) - { - context.Assembler.Mulps(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Mulsd(CodeGenContext context, Operation operation) - { - context.Assembler.Mulsd(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Mulss(CodeGenContext context, Operation operation) - { - context.Assembler.Mulss(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Paddb(CodeGenContext context, Operation operation) - { - context.Assembler.Paddb(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Paddd(CodeGenContext context, Operation operation) - { - context.Assembler.Paddd(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Paddq(CodeGenContext context, Operation operation) - { - context.Assembler.Paddq(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Paddw(CodeGenContext context, Operation operation) - { - context.Assembler.Paddw(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Pand(CodeGenContext context, Operation operation) - { - context.Assembler.Pand(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Pandn(CodeGenContext context, Operation operation) - { - context.Assembler.Pandn(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Pavgb(CodeGenContext context, Operation operation) - { - context.Assembler.Pavgb(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Pavgw(CodeGenContext context, Operation operation) - { - context.Assembler.Pavgw(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Pblendvb(CodeGenContext context, Operation operation) - { - context.Assembler.Pblendvb( - operation.Dest, - operation.GetSource(0), - operation.GetSource(1), - operation.GetSource(2)); - } - - private static void GenerateX86Pcmpeqb(CodeGenContext context, Operation operation) - { - context.Assembler.Pcmpeqb(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Pcmpeqd(CodeGenContext context, Operation operation) - { - context.Assembler.Pcmpeqd(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Pcmpeqq(CodeGenContext context, Operation operation) - { - context.Assembler.Pcmpeqq(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Pcmpeqw(CodeGenContext context, Operation operation) - { - context.Assembler.Pcmpeqw(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Pcmpgtb(CodeGenContext context, Operation operation) - { - context.Assembler.Pcmpgtb(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Pcmpgtd(CodeGenContext context, Operation operation) - { - context.Assembler.Pcmpgtd(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Pcmpgtq(CodeGenContext context, Operation operation) - { - context.Assembler.Pcmpgtq(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Pcmpgtw(CodeGenContext context, Operation operation) - { - context.Assembler.Pcmpgtw(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Pmaxsb(CodeGenContext context, Operation operation) - { - context.Assembler.Pmaxsb(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Pmaxsd(CodeGenContext context, Operation operation) - { - context.Assembler.Pmaxsd(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Pmaxsw(CodeGenContext context, Operation operation) - { - context.Assembler.Pmaxsw(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Pmaxub(CodeGenContext context, Operation operation) - { - context.Assembler.Pmaxub(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Pmaxud(CodeGenContext context, Operation operation) - { - context.Assembler.Pmaxud(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Pmaxuw(CodeGenContext context, Operation operation) - { - context.Assembler.Pmaxuw(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Pminsb(CodeGenContext context, Operation operation) - { - context.Assembler.Pminsb(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Pminsd(CodeGenContext context, Operation operation) - { - context.Assembler.Pminsd(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Pminsw(CodeGenContext context, Operation operation) - { - context.Assembler.Pminsw(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Pminub(CodeGenContext context, Operation operation) - { - context.Assembler.Pminub(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Pminud(CodeGenContext context, Operation operation) - { - context.Assembler.Pminud(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Pminuw(CodeGenContext context, Operation operation) - { - context.Assembler.Pminuw(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Pmovsxbw(CodeGenContext context, Operation operation) - { - context.Assembler.Pmovsxbw(operation.Dest, operation.GetSource(0)); - } - - private static void GenerateX86Pmovsxdq(CodeGenContext context, Operation operation) - { - context.Assembler.Pmovsxdq(operation.Dest, operation.GetSource(0)); - } - - private static void GenerateX86Pmovsxwd(CodeGenContext context, Operation operation) - { - context.Assembler.Pmovsxwd(operation.Dest, operation.GetSource(0)); - } - - private static void GenerateX86Pmovzxbw(CodeGenContext context, Operation operation) - { - context.Assembler.Pmovzxbw(operation.Dest, operation.GetSource(0)); - } - - private static void GenerateX86Pmovzxdq(CodeGenContext context, Operation operation) - { - context.Assembler.Pmovzxdq(operation.Dest, operation.GetSource(0)); - } - - private static void GenerateX86Pmovzxwd(CodeGenContext context, Operation operation) - { - context.Assembler.Pmovzxwd(operation.Dest, operation.GetSource(0)); - } - - private static void GenerateX86Pmulld(CodeGenContext context, Operation operation) - { - context.Assembler.Pmulld(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Pmullw(CodeGenContext context, Operation operation) - { - context.Assembler.Pmullw(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Popcnt(CodeGenContext context, Operation operation) - { - context.Assembler.Popcnt(operation.Dest, operation.GetSource(0)); - } - - private static void GenerateX86Por(CodeGenContext context, Operation operation) - { - context.Assembler.Por(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Pshufb(CodeGenContext context, Operation operation) - { - context.Assembler.Pshufb(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Pslld(CodeGenContext context, Operation operation) - { - context.Assembler.Pslld(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Pslldq(CodeGenContext context, Operation operation) - { - context.Assembler.Pslldq(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Psllq(CodeGenContext context, Operation operation) - { - context.Assembler.Psllq(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Psllw(CodeGenContext context, Operation operation) - { - context.Assembler.Psllw(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Psrad(CodeGenContext context, Operation operation) - { - context.Assembler.Psrad(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Psraw(CodeGenContext context, Operation operation) - { - context.Assembler.Psraw(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Psrld(CodeGenContext context, Operation operation) - { - context.Assembler.Psrld(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Psrlq(CodeGenContext context, Operation operation) - { - context.Assembler.Psrlq(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Psrldq(CodeGenContext context, Operation operation) - { - context.Assembler.Psrldq(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Psrlw(CodeGenContext context, Operation operation) - { - context.Assembler.Psrlw(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Psubb(CodeGenContext context, Operation operation) - { - context.Assembler.Psubb(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Psubd(CodeGenContext context, Operation operation) - { - context.Assembler.Psubd(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Psubq(CodeGenContext context, Operation operation) - { - context.Assembler.Psubq(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Psubw(CodeGenContext context, Operation operation) - { - context.Assembler.Psubw(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Punpckhbw(CodeGenContext context, Operation operation) - { - context.Assembler.Punpckhbw(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Punpckhdq(CodeGenContext context, Operation operation) - { - context.Assembler.Punpckhdq(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Punpckhqdq(CodeGenContext context, Operation operation) - { - context.Assembler.Punpckhqdq(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Punpckhwd(CodeGenContext context, Operation operation) - { - context.Assembler.Punpckhwd(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Punpcklbw(CodeGenContext context, Operation operation) - { - context.Assembler.Punpcklbw(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Punpckldq(CodeGenContext context, Operation operation) - { - context.Assembler.Punpckldq(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Punpcklqdq(CodeGenContext context, Operation operation) - { - context.Assembler.Punpcklqdq(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Punpcklwd(CodeGenContext context, Operation operation) - { - context.Assembler.Punpcklwd(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Pxor(CodeGenContext context, Operation operation) - { - context.Assembler.Pxor(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Rcpps(CodeGenContext context, Operation operation) - { - context.Assembler.Rcpps(operation.Dest, operation.GetSource(0)); - } - - private static void GenerateX86Rcpss(CodeGenContext context, Operation operation) - { - context.Assembler.Rcpss(operation.Dest, operation.GetSource(0)); - } - - private static void GenerateX86Roundpd(CodeGenContext context, Operation operation) - { - context.Assembler.Roundpd(operation.Dest, operation.GetSource(0), operation.GetSource(1).AsByte()); - } - - private static void GenerateX86Roundps(CodeGenContext context, Operation operation) - { - context.Assembler.Roundps(operation.Dest, operation.GetSource(0), operation.GetSource(1).AsByte()); - } - - private static void GenerateX86Roundsd(CodeGenContext context, Operation operation) - { - context.Assembler.Roundsd(operation.Dest, operation.GetSource(0), operation.GetSource(1).AsByte()); - } - - private static void GenerateX86Roundss(CodeGenContext context, Operation operation) - { - context.Assembler.Roundss(operation.Dest, operation.GetSource(0), operation.GetSource(1).AsByte()); - } - - private static void GenerateX86Rsqrtps(CodeGenContext context, Operation operation) - { - context.Assembler.Rsqrtps(operation.Dest, operation.GetSource(0)); - } - - private static void GenerateX86Rsqrtss(CodeGenContext context, Operation operation) - { - context.Assembler.Rsqrtss(operation.Dest, operation.GetSource(0)); - } - - private static void GenerateX86Shufpd(CodeGenContext context, Operation operation) - { - context.Assembler.Shufpd( - operation.Dest, - operation.GetSource(1), - operation.GetSource(2).AsByte(), - operation.GetSource(0)); - } - - private static void GenerateX86Shufps(CodeGenContext context, Operation operation) - { - context.Assembler.Shufps( - operation.Dest, - operation.GetSource(1), - operation.GetSource(2).AsByte(), - operation.GetSource(0)); - } - - private static void GenerateX86Sqrtpd(CodeGenContext context, Operation operation) - { - context.Assembler.Sqrtpd(operation.Dest, operation.GetSource(0)); - } - - private static void GenerateX86Sqrtps(CodeGenContext context, Operation operation) - { - context.Assembler.Sqrtps(operation.Dest, operation.GetSource(0)); - } - - private static void GenerateX86Sqrtsd(CodeGenContext context, Operation operation) - { - context.Assembler.Sqrtsd(operation.Dest, operation.GetSource(0)); - } - - private static void GenerateX86Sqrtss(CodeGenContext context, Operation operation) - { - context.Assembler.Sqrtss(operation.Dest, operation.GetSource(0)); - } - - private static void GenerateX86Subpd(CodeGenContext context, Operation operation) - { - context.Assembler.Subpd(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Subps(CodeGenContext context, Operation operation) - { - context.Assembler.Subps(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Subsd(CodeGenContext context, Operation operation) - { - context.Assembler.Subsd(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Subss(CodeGenContext context, Operation operation) - { - context.Assembler.Subss(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Unpckhpd(CodeGenContext context, Operation operation) - { - context.Assembler.Unpckhpd(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Unpckhps(CodeGenContext context, Operation operation) - { - context.Assembler.Unpckhps(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Unpcklpd(CodeGenContext context, Operation operation) - { - context.Assembler.Unpcklpd(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Unpcklps(CodeGenContext context, Operation operation) - { - context.Assembler.Unpcklps(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Xorpd(CodeGenContext context, Operation operation) - { - context.Assembler.Xorpd(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - - private static void GenerateX86Xorps(CodeGenContext context, Operation operation) - { - context.Assembler.Xorps(operation.Dest, operation.GetSource(1), operation.GetSource(0)); - } - private static void GenerateCompare(CodeGenContext context, Operation operation, X86Condition condition) { context.Assembler.Cmp(operation.GetSource(0), operation.GetSource(1)); diff --git a/ARMeilleure/CodeGen/X86/PreAllocator.cs b/ARMeilleure/CodeGen/X86/PreAllocator.cs index d93fb175ac..65726a1c11 100644 --- a/ARMeilleure/CodeGen/X86/PreAllocator.cs +++ b/ARMeilleure/CodeGen/X86/PreAllocator.cs @@ -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); diff --git a/ARMeilleure/CodeGen/X86/X86Instruction.cs b/ARMeilleure/CodeGen/X86/X86Instruction.cs index ee9805e9b4..fa8f1889e1 100644 --- a/ARMeilleure/CodeGen/X86/X86Instruction.cs +++ b/ARMeilleure/CodeGen/X86/X86Instruction.cs @@ -20,7 +20,6 @@ namespace ARMeilleure.CodeGen.X86 Cmpsd, Cmpss, Cmpxchg16b, - Cmpxchg8b, Comisd, Comiss, Cvtdq2pd, diff --git a/ARMeilleure/Decoders/Decoder.cs b/ARMeilleure/Decoders/Decoder.cs index 361b2dbd3d..3b1cded39e 100644 --- a/ARMeilleure/Decoders/Decoder.cs +++ b/ARMeilleure/Decoders/Decoder.cs @@ -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); diff --git a/ARMeilleure/Decoders/InstEmitter.cs b/ARMeilleure/Decoders/InstEmitter.cs index 4c0faca2a3..a8b5265693 100644 --- a/ARMeilleure/Decoders/InstEmitter.cs +++ b/ARMeilleure/Decoders/InstEmitter.cs @@ -2,5 +2,5 @@ using ARMeilleure.Translation; namespace ARMeilleure.Decoders { - delegate void InstEmitter(EmitterContext context); + delegate void InstEmitter(ArmEmitterContext context); } \ No newline at end of file diff --git a/ARMeilleure/Diagnostics/Logger.cs b/ARMeilleure/Diagnostics/Logger.cs index 72b3d60dd8..e8cd47ad8c 100644 --- a/ARMeilleure/Diagnostics/Logger.cs +++ b/ARMeilleure/Diagnostics/Logger.cs @@ -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; diff --git a/ARMeilleure/Instructions/DelegateTypes.cs b/ARMeilleure/Instructions/DelegateTypes.cs new file mode 100644 index 0000000000..e90e4d77a1 --- /dev/null +++ b/ARMeilleure/Instructions/DelegateTypes.cs @@ -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); +} \ No newline at end of file diff --git a/ARMeilleure/Instructions/InstEmitAlu.cs b/ARMeilleure/Instructions/InstEmitAlu.cs index 87880e9132..d505324f76 100644 --- a/ARMeilleure/Instructions/InstEmitAlu.cs +++ b/ARMeilleure/Instructions/InstEmitAlu.cs @@ -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; diff --git a/ARMeilleure/Instructions/InstEmitAluHelper.cs b/ARMeilleure/Instructions/InstEmitAluHelper.cs index 7a822dd312..87c0244c45 100644 --- a/ARMeilleure/Instructions/InstEmitAluHelper.cs +++ b/ARMeilleure/Instructions/InstEmitAluHelper.cs @@ -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); } } } diff --git a/ARMeilleure/Instructions/InstEmitBfm.cs b/ARMeilleure/Instructions/InstEmitBfm.cs index 8d0b5aa03e..93fd42fa22 100644 --- a/ARMeilleure/Instructions/InstEmitBfm.cs +++ b/ARMeilleure/Instructions/InstEmitBfm.cs @@ -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; diff --git a/ARMeilleure/Instructions/InstEmitCcmp.cs b/ARMeilleure/Instructions/InstEmitCcmp.cs index 9bdca49e06..b1b0a2a1c8 100644 --- a/ARMeilleure/Instructions/InstEmitCcmp.cs +++ b/ARMeilleure/Instructions/InstEmitCcmp.cs @@ -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); diff --git a/ARMeilleure/Instructions/InstEmitCsel.cs b/ARMeilleure/Instructions/InstEmitCsel.cs index 63edba3452..60baf0bc29 100644 --- a/ARMeilleure/Instructions/InstEmitCsel.cs +++ b/ARMeilleure/Instructions/InstEmitCsel.cs @@ -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; diff --git a/ARMeilleure/Instructions/InstEmitDiv.cs b/ARMeilleure/Instructions/InstEmitDiv.cs index 8e7f99fd54..ee0ec6eca0 100644 --- a/ARMeilleure/Instructions/InstEmitDiv.cs +++ b/ARMeilleure/Instructions/InstEmitDiv.cs @@ -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; diff --git a/ARMeilleure/Instructions/InstEmitException.cs b/ARMeilleure/Instructions/InstEmitException.cs index 7a85a0b656..6f7b6fd51f 100644 --- a/ARMeilleure/Instructions/InstEmitException.cs +++ b/ARMeilleure/Instructions/InstEmitException.cs @@ -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(); diff --git a/ARMeilleure/Instructions/InstEmitFlow.cs b/ARMeilleure/Instructions/InstEmitFlow.cs index 8c4d6e1f1f..d9e770755a 100644 --- a/ARMeilleure/Instructions/InstEmitFlow.cs +++ b/ARMeilleure/Instructions/InstEmitFlow.cs @@ -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; diff --git a/ARMeilleure/Instructions/InstEmitFlowHelper.cs b/ARMeilleure/Instructions/InstEmitFlowHelper.cs index d31a82e661..1b77ce5818 100644 --- a/ARMeilleure/Instructions/InstEmitFlowHelper.cs +++ b/ARMeilleure/Instructions/InstEmitFlowHelper.cs @@ -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 diff --git a/ARMeilleure/Instructions/InstEmitHash.cs b/ARMeilleure/Instructions/InstEmitHash.cs index 23faf2691b..0be8458e20 100644 --- a/ARMeilleure/Instructions/InstEmitHash.cs +++ b/ARMeilleure/Instructions/InstEmitHash.cs @@ -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); } diff --git a/ARMeilleure/Instructions/InstEmitHelper.cs b/ARMeilleure/Instructions/InstEmitHelper.cs index 9a215dae76..d28770b524 100644 --- a/ARMeilleure/Instructions/InstEmitHelper.cs +++ b/ARMeilleure/Instructions/InstEmitHelper.cs @@ -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); + } } } diff --git a/ARMeilleure/Instructions/InstEmitMemory.cs b/ARMeilleure/Instructions/InstEmitMemory.cs index d9abffd477..f36536ccdd 100644 --- a/ARMeilleure/Instructions/InstEmitMemory.cs +++ b/ARMeilleure/Instructions/InstEmitMemory.cs @@ -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) diff --git a/ARMeilleure/Instructions/InstEmitMemoryEx.cs b/ARMeilleure/Instructions/InstEmitMemoryEx.cs index cfc7243b6c..68e4829147 100644 --- a/ARMeilleure/Instructions/InstEmitMemoryEx.cs +++ b/ARMeilleure/Instructions/InstEmitMemoryEx.cs @@ -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 diff --git a/ARMeilleure/Instructions/InstEmitMemoryHelper.cs b/ARMeilleure/Instructions/InstEmitMemoryHelper.cs index 0220efd5cd..ac9a174425 100644 --- a/ARMeilleure/Instructions/InstEmitMemoryHelper.cs +++ b/ARMeilleure/Instructions/InstEmitMemoryHelper.cs @@ -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); } } } \ No newline at end of file diff --git a/ARMeilleure/Instructions/InstEmitMove.cs b/ARMeilleure/Instructions/InstEmitMove.cs index db2306fcc5..bf051f3294 100644 --- a/ARMeilleure/Instructions/InstEmitMove.cs +++ b/ARMeilleure/Instructions/InstEmitMove.cs @@ -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; diff --git a/ARMeilleure/Instructions/InstEmitMul.cs b/ARMeilleure/Instructions/InstEmitMul.cs index 783f97992a..65d11b30df 100644 --- a/ARMeilleure/Instructions/InstEmitMul.cs +++ b/ARMeilleure/Instructions/InstEmitMul.cs @@ -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; diff --git a/ARMeilleure/Instructions/InstEmitSimdArithmetic.cs b/ARMeilleure/Instructions/InstEmitSimdArithmetic.cs index ded192315a..ed1e24a9e9 100644 --- a/ARMeilleure/Instructions/InstEmitSimdArithmetic.cs +++ b/ARMeilleure/Instructions/InstEmitSimdArithmetic.cs @@ -6,7 +6,6 @@ using ARMeilleure.IntermediateRepresentation; using ARMeilleure.State; using ARMeilleure.Translation; using System; -using System.Reflection; using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.Instructions.InstEmitSimdHelper; @@ -19,22 +18,22 @@ namespace ARMeilleure.Instructions static partial class InstEmit { - public static void Abs_S(EmitterContext context) + public static void Abs_S(ArmEmitterContext context) { EmitScalarUnaryOpSx(context, (op1) => EmitAbs(context, op1)); } - public static void Abs_V(EmitterContext context) + public static void Abs_V(ArmEmitterContext context) { EmitVectorUnaryOpSx(context, (op1) => EmitAbs(context, op1)); } - public static void Add_S(EmitterContext context) + public static void Add_S(ArmEmitterContext context) { EmitScalarBinaryOpZx(context, (op1, op2) => context.Add(op1, op2)); } - public static void Add_V(EmitterContext context) + public static void Add_V(ArmEmitterContext context) { if (Optimizations.UseSse2) { @@ -60,12 +59,12 @@ namespace ARMeilleure.Instructions } } - public static void Addhn_V(EmitterContext context) + public static void Addhn_V(ArmEmitterContext context) { EmitHighNarrow(context, (op1, op2) => context.Add(op1, op2), round: false); } - public static void Addp_S(EmitterContext context) + public static void Addp_S(ArmEmitterContext context) { OpCodeSimd op = (OpCodeSimd)context.CurrOp; @@ -77,17 +76,17 @@ namespace ARMeilleure.Instructions context.Copy(GetVec(op.Rd), EmitVectorInsert(context, context.VectorZero(), res, 0, op.Size)); } - public static void Addp_V(EmitterContext context) + public static void Addp_V(ArmEmitterContext context) { EmitVectorPairwiseOpZx(context, (op1, op2) => context.Add(op1, op2)); } - public static void Addv_V(EmitterContext context) + public static void Addv_V(ArmEmitterContext context) { EmitVectorAcrossVectorOpZx(context, (op1, op2) => context.Add(op1, op2)); } - public static void Cls_V(EmitterContext context) + public static void Cls_V(ArmEmitterContext context) { OpCodeSimd op = (OpCodeSimd)context.CurrOp; @@ -101,9 +100,7 @@ namespace ARMeilleure.Instructions { Operand ne = EmitVectorExtractZx(context, op.Rn, index, op.Size); - MethodInfo info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.CountLeadingSigns)); - - Operand de = context.Call(info, ne, Const(eSize)); + Operand de = context.Call(new _U64_U64_S32(SoftFallback.CountLeadingSigns), ne, Const(eSize)); res = EmitVectorInsert(context, res, de, index, op.Size); } @@ -111,7 +108,7 @@ namespace ARMeilleure.Instructions context.Copy(GetVec(op.Rd), res); } - public static void Clz_V(EmitterContext context) + public static void Clz_V(ArmEmitterContext context) { OpCodeSimd op = (OpCodeSimd)context.CurrOp; @@ -133,9 +130,7 @@ namespace ARMeilleure.Instructions } else { - MethodInfo info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.CountLeadingZeros)); - - de = context.Call(info, ne, Const(eSize)); + de = context.Call(new _U64_U64_S32(SoftFallback.CountLeadingZeros), ne, Const(eSize)); } res = EmitVectorInsert(context, res, de, index, op.Size); @@ -144,7 +139,7 @@ namespace ARMeilleure.Instructions context.Copy(GetVec(op.Rd), res); } - public static void Cnt_V(EmitterContext context) + public static void Cnt_V(ArmEmitterContext context) { OpCodeSimd op = (OpCodeSimd)context.CurrOp; @@ -164,9 +159,7 @@ namespace ARMeilleure.Instructions } else { - MethodInfo info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.CountSetBits8)); - - de = context.Call(info, ne); + de = context.Call(new _U64_U64(SoftFallback.CountSetBits8), ne); } res = EmitVectorInsert(context, res, de, index, 0); @@ -175,7 +168,7 @@ namespace ARMeilleure.Instructions context.Copy(GetVec(op.Rd), res); } - public static void Fabd_S(EmitterContext context) + public static void Fabd_S(ArmEmitterContext context) { if (Optimizations.FastFP && Optimizations.UseSse2) { @@ -208,14 +201,14 @@ namespace ARMeilleure.Instructions { EmitScalarBinaryOpF(context, (op1, op2) => { - Operand res = EmitSoftFloatCall(context, nameof(SoftFloat32.FPSub), op1, op2); + Operand res = EmitSoftFloatCall(context, SoftFloat32.FPSub, SoftFloat64.FPSub, op1, op2); - return EmitUnaryMathCall(context, nameof(Math.Abs), res); + return EmitUnaryMathCall(context, MathF.Abs, Math.Abs, res); }); } } - public static void Fabd_V(EmitterContext context) + public static void Fabd_V(ArmEmitterContext context) { if (Optimizations.FastFP && Optimizations.UseSse2) { @@ -253,14 +246,14 @@ namespace ARMeilleure.Instructions { EmitVectorBinaryOpF(context, (op1, op2) => { - Operand res = EmitSoftFloatCall(context, nameof(SoftFloat32.FPSub), op1, op2); + Operand res = EmitSoftFloatCall(context, SoftFloat32.FPSub, SoftFloat64.FPSub, op1, op2); - return EmitUnaryMathCall(context, nameof(Math.Abs), res); + return EmitUnaryMathCall(context, MathF.Abs, Math.Abs, res); }); } } - public static void Fabs_S(EmitterContext context) + public static void Fabs_S(ArmEmitterContext context) { if (Optimizations.UseSse2) { @@ -287,12 +280,12 @@ namespace ARMeilleure.Instructions { EmitScalarUnaryOpF(context, (op1) => { - return EmitUnaryMathCall(context, nameof(Math.Abs), op1); + return EmitUnaryMathCall(context, MathF.Abs, Math.Abs, op1); }); } } - public static void Fabs_V(EmitterContext context) + public static void Fabs_V(ArmEmitterContext context) { if (Optimizations.UseSse2) { @@ -326,42 +319,50 @@ namespace ARMeilleure.Instructions { EmitVectorUnaryOpF(context, (op1) => { - return EmitUnaryMathCall(context, nameof(Math.Abs), op1); + return EmitUnaryMathCall(context, MathF.Abs, Math.Abs, op1); }); } } - public static void Fadd_S(EmitterContext context) + public static void Fadd_S(ArmEmitterContext context) { if (Optimizations.FastFP && Optimizations.UseSse2) { EmitScalarBinaryOpF(context, Instruction.X86Addss, Instruction.X86Addsd); } + else if (Optimizations.FastFP) + { + EmitScalarBinaryOpF(context, (op1, op2) => context.Add(op1, op2)); + } else { EmitScalarBinaryOpF(context, (op1, op2) => { - return EmitSoftFloatCall(context, nameof(SoftFloat32.FPAdd), op1, op2); + return EmitSoftFloatCall(context, SoftFloat32.FPAdd, SoftFloat64.FPAdd, op1, op2); }); } } - public static void Fadd_V(EmitterContext context) + public static void Fadd_V(ArmEmitterContext context) { if (Optimizations.FastFP && Optimizations.UseSse2) { EmitVectorBinaryOpF(context, Instruction.X86Addps, Instruction.X86Addpd); } + else if (Optimizations.FastFP) + { + EmitVectorBinaryOpF(context, (op1, op2) => context.Add(op1, op2)); + } else { EmitVectorBinaryOpF(context, (op1, op2) => { - return EmitSoftFloatCall(context, nameof(SoftFloat32.FPAdd), op1, op2); + return EmitSoftFloatCall(context, SoftFloat32.FPAdd, SoftFloat64.FPAdd, op1, op2); }); } } - public static void Faddp_S(EmitterContext context) + public static void Faddp_S(ArmEmitterContext context) { OpCodeSimd op = (OpCodeSimd)context.CurrOp; @@ -390,13 +391,13 @@ namespace ARMeilleure.Instructions Operand ne0 = context.VectorExtract(type, GetVec(op.Rn), 0); Operand ne1 = context.VectorExtract(type, GetVec(op.Rn), 1); - Operand res = EmitSoftFloatCall(context, nameof(SoftFloat32.FPAdd), ne0, ne1); + Operand res = EmitSoftFloatCall(context, SoftFloat32.FPAdd, SoftFloat64.FPAdd, ne0, ne1); context.Copy(GetVec(op.Rd), context.VectorInsert(context.VectorZero(), res, 0)); } } - public static void Faddp_V(EmitterContext context) + public static void Faddp_V(ArmEmitterContext context) { if (Optimizations.FastFP && Optimizations.UseSse2) { @@ -406,12 +407,12 @@ namespace ARMeilleure.Instructions { EmitVectorPairwiseOpF(context, (op1, op2) => { - return EmitSoftFloatCall(context, nameof(SoftFloat32.FPAdd), op1, op2); + return EmitSoftFloatCall(context, SoftFloat32.FPAdd, SoftFloat64.FPAdd, op1, op2); }); } } - public static void Fdiv_S(EmitterContext context) + public static void Fdiv_S(ArmEmitterContext context) { if (Optimizations.FastFP && Optimizations.UseSse2) { @@ -421,12 +422,12 @@ namespace ARMeilleure.Instructions { EmitScalarBinaryOpF(context, (op1, op2) => { - return EmitSoftFloatCall(context, nameof(SoftFloat32.FPDiv), op1, op2); + return EmitSoftFloatCall(context, SoftFloat32.FPDiv, SoftFloat64.FPDiv, op1, op2); }); } } - public static void Fdiv_V(EmitterContext context) + public static void Fdiv_V(ArmEmitterContext context) { if (Optimizations.FastFP && Optimizations.UseSse2) { @@ -436,12 +437,12 @@ namespace ARMeilleure.Instructions { EmitVectorBinaryOpF(context, (op1, op2) => { - return EmitSoftFloatCall(context, nameof(SoftFloat32.FPDiv), op1, op2); + return EmitSoftFloatCall(context, SoftFloat32.FPDiv, SoftFloat64.FPDiv, op1, op2); }); } } - public static void Fmadd_S(EmitterContext context) // Fused. + public static void Fmadd_S(ArmEmitterContext context) // Fused. { if (Optimizations.FastFP && Optimizations.UseSse2) { @@ -472,12 +473,12 @@ namespace ARMeilleure.Instructions { EmitScalarTernaryRaOpF(context, (op1, op2, op3) => { - return EmitSoftFloatCall(context, nameof(SoftFloat32.FPMulAdd), op1, op2, op3); + return EmitSoftFloatCall(context, SoftFloat32.FPMulAdd, SoftFloat64.FPMulAdd, op1, op2, op3); }); } } - public static void Fmax_S(EmitterContext context) + public static void Fmax_S(ArmEmitterContext context) { if (Optimizations.FastFP && Optimizations.UseSse2) { @@ -487,12 +488,12 @@ namespace ARMeilleure.Instructions { EmitScalarBinaryOpF(context, (op1, op2) => { - return EmitSoftFloatCall(context, nameof(SoftFloat32.FPMax), op1, op2); + return EmitSoftFloatCall(context, SoftFloat32.FPMax, SoftFloat64.FPMax, op1, op2); }); } } - public static void Fmax_V(EmitterContext context) + public static void Fmax_V(ArmEmitterContext context) { if (Optimizations.FastFP && Optimizations.UseSse2) { @@ -502,28 +503,28 @@ namespace ARMeilleure.Instructions { EmitVectorBinaryOpF(context, (op1, op2) => { - return EmitSoftFloatCall(context, nameof(SoftFloat32.FPMax), op1, op2); + return EmitSoftFloatCall(context, SoftFloat32.FPMax, SoftFloat64.FPMax, op1, op2); }); } } - public static void Fmaxnm_S(EmitterContext context) + public static void Fmaxnm_S(ArmEmitterContext context) { EmitScalarBinaryOpF(context, (op1, op2) => { - return EmitSoftFloatCall(context, nameof(SoftFloat32.FPMaxNum), op1, op2); + return EmitSoftFloatCall(context, SoftFloat32.FPMaxNum, SoftFloat64.FPMaxNum, op1, op2); }); } - public static void Fmaxnm_V(EmitterContext context) + public static void Fmaxnm_V(ArmEmitterContext context) { EmitVectorBinaryOpF(context, (op1, op2) => { - return EmitSoftFloatCall(context, nameof(SoftFloat32.FPMaxNum), op1, op2); + return EmitSoftFloatCall(context, SoftFloat32.FPMaxNum, SoftFloat64.FPMaxNum, op1, op2); }); } - public static void Fmaxp_V(EmitterContext context) + public static void Fmaxp_V(ArmEmitterContext context) { if (Optimizations.FastFP && Optimizations.UseSse2) { @@ -533,12 +534,12 @@ namespace ARMeilleure.Instructions { EmitVectorPairwiseOpF(context, (op1, op2) => { - return EmitSoftFloatCall(context, nameof(SoftFloat32.FPMax), op1, op2); + return EmitSoftFloatCall(context, SoftFloat32.FPMax, SoftFloat64.FPMax, op1, op2); }); } } - public static void Fmin_S(EmitterContext context) + public static void Fmin_S(ArmEmitterContext context) { if (Optimizations.FastFP && Optimizations.UseSse2) { @@ -548,12 +549,12 @@ namespace ARMeilleure.Instructions { EmitScalarBinaryOpF(context, (op1, op2) => { - return EmitSoftFloatCall(context, nameof(SoftFloat32.FPMin), op1, op2); + return EmitSoftFloatCall(context, SoftFloat32.FPMin, SoftFloat64.FPMin, op1, op2); }); } } - public static void Fmin_V(EmitterContext context) + public static void Fmin_V(ArmEmitterContext context) { if (Optimizations.FastFP && Optimizations.UseSse2) { @@ -563,28 +564,28 @@ namespace ARMeilleure.Instructions { EmitVectorBinaryOpF(context, (op1, op2) => { - return EmitSoftFloatCall(context, nameof(SoftFloat32.FPMin), op1, op2); + return EmitSoftFloatCall(context, SoftFloat32.FPMin, SoftFloat64.FPMin, op1, op2); }); } } - public static void Fminnm_S(EmitterContext context) + public static void Fminnm_S(ArmEmitterContext context) { EmitScalarBinaryOpF(context, (op1, op2) => { - return EmitSoftFloatCall(context, nameof(SoftFloat32.FPMinNum), op1, op2); + return EmitSoftFloatCall(context, SoftFloat32.FPMinNum, SoftFloat64.FPMinNum, op1, op2); }); } - public static void Fminnm_V(EmitterContext context) + public static void Fminnm_V(ArmEmitterContext context) { EmitVectorBinaryOpF(context, (op1, op2) => { - return EmitSoftFloatCall(context, nameof(SoftFloat32.FPMinNum), op1, op2); + return EmitSoftFloatCall(context, SoftFloat32.FPMinNum, SoftFloat64.FPMinNum, op1, op2); }); } - public static void Fminp_V(EmitterContext context) + public static void Fminp_V(ArmEmitterContext context) { if (Optimizations.FastFP && Optimizations.UseSse2) { @@ -594,12 +595,12 @@ namespace ARMeilleure.Instructions { EmitVectorPairwiseOpF(context, (op1, op2) => { - return EmitSoftFloatCall(context, nameof(SoftFloat32.FPMin), op1, op2); + return EmitSoftFloatCall(context, SoftFloat32.FPMin, SoftFloat64.FPMin, op1, op2); }); } } - public static void Fmla_Se(EmitterContext context) // Fused. + public static void Fmla_Se(ArmEmitterContext context) // Fused. { EmitScalarTernaryOpByElemF(context, (op1, op2, op3) => { @@ -607,7 +608,7 @@ namespace ARMeilleure.Instructions }); } - public static void Fmla_V(EmitterContext context) // Fused. + public static void Fmla_V(ArmEmitterContext context) // Fused. { if (Optimizations.FastFP && Optimizations.UseSse2) { @@ -645,12 +646,12 @@ namespace ARMeilleure.Instructions { EmitVectorTernaryOpF(context, (op1, op2, op3) => { - return EmitSoftFloatCall(context, nameof(SoftFloat32.FPMulAdd), op1, op2, op3); + return EmitSoftFloatCall(context, SoftFloat32.FPMulAdd, SoftFloat64.FPMulAdd, op1, op2, op3); }); } } - public static void Fmla_Ve(EmitterContext context) // Fused. + public static void Fmla_Ve(ArmEmitterContext context) // Fused. { if (Optimizations.FastFP && Optimizations.UseSse2) { @@ -694,12 +695,12 @@ namespace ARMeilleure.Instructions { EmitVectorTernaryOpByElemF(context, (op1, op2, op3) => { - return EmitSoftFloatCall(context, nameof(SoftFloat32.FPMulAdd), op1, op2, op3); + return EmitSoftFloatCall(context, SoftFloat32.FPMulAdd, SoftFloat64.FPMulAdd, op1, op2, op3); }); } } - public static void Fmls_Se(EmitterContext context) // Fused. + public static void Fmls_Se(ArmEmitterContext context) // Fused. { EmitScalarTernaryOpByElemF(context, (op1, op2, op3) => { @@ -707,7 +708,7 @@ namespace ARMeilleure.Instructions }); } - public static void Fmls_V(EmitterContext context) // Fused. + public static void Fmls_V(ArmEmitterContext context) // Fused. { if (Optimizations.FastFP && Optimizations.UseSse2) { @@ -745,12 +746,12 @@ namespace ARMeilleure.Instructions { EmitVectorTernaryOpF(context, (op1, op2, op3) => { - return EmitSoftFloatCall(context, nameof(SoftFloat32.FPMulSub), op1, op2, op3); + return EmitSoftFloatCall(context, SoftFloat32.FPMulSub, SoftFloat64.FPMulSub, op1, op2, op3); }); } } - public static void Fmls_Ve(EmitterContext context) // Fused. + public static void Fmls_Ve(ArmEmitterContext context) // Fused. { if (Optimizations.FastFP && Optimizations.UseSse2) { @@ -794,12 +795,12 @@ namespace ARMeilleure.Instructions { EmitVectorTernaryOpByElemF(context, (op1, op2, op3) => { - return EmitSoftFloatCall(context, nameof(SoftFloat32.FPMulSub), op1, op2, op3); + return EmitSoftFloatCall(context, SoftFloat32.FPMulSub, SoftFloat64.FPMulSub, op1, op2, op3); }); } } - public static void Fmsub_S(EmitterContext context) // Fused. + public static void Fmsub_S(ArmEmitterContext context) // Fused. { if (Optimizations.FastFP && Optimizations.UseSse2) { @@ -830,12 +831,12 @@ namespace ARMeilleure.Instructions { EmitScalarTernaryRaOpF(context, (op1, op2, op3) => { - return EmitSoftFloatCall(context, nameof(SoftFloat32.FPMulSub), op1, op2, op3); + return EmitSoftFloatCall(context, SoftFloat32.FPMulSub, SoftFloat64.FPMulSub, op1, op2, op3); }); } } - public static void Fmul_S(EmitterContext context) + public static void Fmul_S(ArmEmitterContext context) { if (Optimizations.FastFP && Optimizations.UseSse2) { @@ -845,17 +846,17 @@ namespace ARMeilleure.Instructions { EmitScalarBinaryOpF(context, (op1, op2) => { - return EmitSoftFloatCall(context, nameof(SoftFloat32.FPMul), op1, op2); + return EmitSoftFloatCall(context, SoftFloat32.FPMul, SoftFloat64.FPMul, op1, op2); }); } } - public static void Fmul_Se(EmitterContext context) + public static void Fmul_Se(ArmEmitterContext context) { EmitScalarBinaryOpByElemF(context, (op1, op2) => context.Multiply(op1, op2)); } - public static void Fmul_V(EmitterContext context) + public static void Fmul_V(ArmEmitterContext context) { if (Optimizations.FastFP && Optimizations.UseSse2) { @@ -865,12 +866,12 @@ namespace ARMeilleure.Instructions { EmitVectorBinaryOpF(context, (op1, op2) => { - return EmitSoftFloatCall(context, nameof(SoftFloat32.FPMul), op1, op2); + return EmitSoftFloatCall(context, SoftFloat32.FPMul, SoftFloat64.FPMul, op1, op2); }); } } - public static void Fmul_Ve(EmitterContext context) + public static void Fmul_Ve(ArmEmitterContext context) { if (Optimizations.FastFP && Optimizations.UseSse2) { @@ -911,44 +912,44 @@ namespace ARMeilleure.Instructions { EmitVectorBinaryOpByElemF(context, (op1, op2) => { - return EmitSoftFloatCall(context, nameof(SoftFloat32.FPMul), op1, op2); + return EmitSoftFloatCall(context, SoftFloat32.FPMul, SoftFloat64.FPMul, op1, op2); }); } } - public static void Fmulx_S(EmitterContext context) + public static void Fmulx_S(ArmEmitterContext context) { EmitScalarBinaryOpF(context, (op1, op2) => { - return EmitSoftFloatCall(context, nameof(SoftFloat32.FPMulX), op1, op2); + return EmitSoftFloatCall(context, SoftFloat32.FPMulX, SoftFloat64.FPMulX, op1, op2); }); } - public static void Fmulx_Se(EmitterContext context) + public static void Fmulx_Se(ArmEmitterContext context) { EmitScalarBinaryOpByElemF(context, (op1, op2) => { - return EmitSoftFloatCall(context, nameof(SoftFloat32.FPMulX), op1, op2); + return EmitSoftFloatCall(context, SoftFloat32.FPMulX, SoftFloat64.FPMulX, op1, op2); }); } - public static void Fmulx_V(EmitterContext context) + public static void Fmulx_V(ArmEmitterContext context) { EmitVectorBinaryOpF(context, (op1, op2) => { - return EmitSoftFloatCall(context, nameof(SoftFloat32.FPMulX), op1, op2); + return EmitSoftFloatCall(context, SoftFloat32.FPMulX, SoftFloat64.FPMulX, op1, op2); }); } - public static void Fmulx_Ve(EmitterContext context) + public static void Fmulx_Ve(ArmEmitterContext context) { EmitVectorBinaryOpByElemF(context, (op1, op2) => { - return EmitSoftFloatCall(context, nameof(SoftFloat32.FPMulX), op1, op2); + return EmitSoftFloatCall(context, SoftFloat32.FPMulX, SoftFloat64.FPMulX, op1, op2); }); } - public static void Fneg_S(EmitterContext context) + public static void Fneg_S(ArmEmitterContext context) { if (Optimizations.UseSse2) { @@ -977,7 +978,7 @@ namespace ARMeilleure.Instructions } } - public static void Fneg_V(EmitterContext context) + public static void Fneg_V(ArmEmitterContext context) { if (Optimizations.UseSse2) { @@ -1013,7 +1014,7 @@ namespace ARMeilleure.Instructions } } - public static void Fnmadd_S(EmitterContext context) + public static void Fnmadd_S(ArmEmitterContext context) { OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp; @@ -1031,7 +1032,7 @@ namespace ARMeilleure.Instructions context.Copy(GetVec(op.Rd), context.VectorInsert(context.VectorZero(), res, 0)); } - public static void Fnmsub_S(EmitterContext context) + public static void Fnmsub_S(ArmEmitterContext context) { OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp; @@ -1049,12 +1050,12 @@ namespace ARMeilleure.Instructions context.Copy(GetVec(op.Rd), context.VectorInsert(context.VectorZero(), res, 0)); } - public static void Fnmul_S(EmitterContext context) + public static void Fnmul_S(ArmEmitterContext context) { EmitScalarBinaryOpF(context, (op1, op2) => context.Negate(context.Multiply(op1, op2))); } - public static void Frecpe_S(EmitterContext context) + public static void Frecpe_S(ArmEmitterContext context) { OpCodeSimd op = (OpCodeSimd)context.CurrOp; @@ -1068,12 +1069,12 @@ namespace ARMeilleure.Instructions { EmitScalarUnaryOpF(context, (op1) => { - return EmitSoftFloatCall(context, nameof(SoftFloat32.FPRecipEstimate), op1); + return EmitSoftFloatCall(context, SoftFloat32.FPRecipEstimate, SoftFloat64.FPRecipEstimate, op1); }); } } - public static void Frecpe_V(EmitterContext context) + public static void Frecpe_V(ArmEmitterContext context) { OpCodeSimd op = (OpCodeSimd)context.CurrOp; @@ -1087,12 +1088,12 @@ namespace ARMeilleure.Instructions { EmitVectorUnaryOpF(context, (op1) => { - return EmitSoftFloatCall(context, nameof(SoftFloat32.FPRecipEstimate), op1); + return EmitSoftFloatCall(context, SoftFloat32.FPRecipEstimate, SoftFloat64.FPRecipEstimate, op1); }); } } - public static void Frecps_S(EmitterContext context) // Fused. + public static void Frecps_S(ArmEmitterContext context) // Fused. { if (Optimizations.FastFP && Optimizations.UseSse2) { @@ -1125,12 +1126,12 @@ namespace ARMeilleure.Instructions { EmitScalarBinaryOpF(context, (op1, op2) => { - return EmitSoftFloatCall(context, nameof(SoftFloat32.FPRecipStepFused), op1, op2); + return EmitSoftFloatCall(context, SoftFloat32.FPRecipStepFused, SoftFloat64.FPRecipStepFused, op1, op2); }); } } - public static void Frecps_V(EmitterContext context) // Fused. + public static void Frecps_V(ArmEmitterContext context) // Fused. { if (Optimizations.FastFP && Optimizations.UseSse2) { @@ -1168,20 +1169,20 @@ namespace ARMeilleure.Instructions { EmitVectorBinaryOpF(context, (op1, op2) => { - return EmitSoftFloatCall(context, nameof(SoftFloat32.FPRecipStepFused), op1, op2); + return EmitSoftFloatCall(context, SoftFloat32.FPRecipStepFused, SoftFloat64.FPRecipStepFused, op1, op2); }); } } - public static void Frecpx_S(EmitterContext context) + public static void Frecpx_S(ArmEmitterContext context) { EmitScalarUnaryOpF(context, (op1) => { - return EmitSoftFloatCall(context, nameof(SoftFloat32.FPRecpX), op1); + return EmitSoftFloatCall(context, SoftFloat32.FPRecpX, SoftFloat64.FPRecpX, op1); }); } - public static void Frinta_S(EmitterContext context) + public static void Frinta_S(ArmEmitterContext context) { EmitScalarUnaryOpF(context, (op1) => { @@ -1189,7 +1190,7 @@ namespace ARMeilleure.Instructions }); } - public static void Frinta_V(EmitterContext context) + public static void Frinta_V(ArmEmitterContext context) { EmitVectorUnaryOpF(context, (op1) => { @@ -1197,7 +1198,7 @@ namespace ARMeilleure.Instructions }); } - public static void Frinti_S(EmitterContext context) + public static void Frinti_S(ArmEmitterContext context) { OpCodeSimd op = (OpCodeSimd)context.CurrOp; @@ -1205,20 +1206,16 @@ namespace ARMeilleure.Instructions { if (op.Size == 0) { - MethodInfo info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.RoundF)); - - return context.Call(info, op1); + return context.Call(new _F32_F32(SoftFallback.RoundF), op1); } else /* if (op.Size == 1) */ { - MethodInfo info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.Round)); - - return context.Call(info, op1); + return context.Call(new _F64_F64(SoftFallback.Round), op1); } }); } - public static void Frinti_V(EmitterContext context) + public static void Frinti_V(ArmEmitterContext context) { OpCodeSimd op = (OpCodeSimd)context.CurrOp; @@ -1228,20 +1225,16 @@ namespace ARMeilleure.Instructions { if (sizeF == 0) { - MethodInfo info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.RoundF)); - - return context.Call(info, op1); + return context.Call(new _F32_F32(SoftFallback.RoundF), op1); } else /* if (sizeF == 1) */ { - MethodInfo info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.Round)); - - return context.Call(info, op1); + return context.Call(new _F64_F64(SoftFallback.Round), op1); } }); } - public static void Frintm_S(EmitterContext context) + public static void Frintm_S(ArmEmitterContext context) { if (Optimizations.UseSse41) { @@ -1251,12 +1244,12 @@ namespace ARMeilleure.Instructions { EmitScalarUnaryOpF(context, (op1) => { - return EmitUnaryMathCall(context, nameof(Math.Floor), op1); + return EmitUnaryMathCall(context, MathF.Floor, Math.Floor, op1); }); } } - public static void Frintm_V(EmitterContext context) + public static void Frintm_V(ArmEmitterContext context) { if (Optimizations.UseSse41) { @@ -1266,12 +1259,12 @@ namespace ARMeilleure.Instructions { EmitVectorUnaryOpF(context, (op1) => { - return EmitUnaryMathCall(context, nameof(Math.Floor), op1); + return EmitUnaryMathCall(context, MathF.Floor, Math.Floor, op1); }); } } - public static void Frintn_S(EmitterContext context) + public static void Frintn_S(ArmEmitterContext context) { if (Optimizations.UseSse41) { @@ -1286,7 +1279,7 @@ namespace ARMeilleure.Instructions } } - public static void Frintn_V(EmitterContext context) + public static void Frintn_V(ArmEmitterContext context) { if (Optimizations.UseSse41) { @@ -1301,7 +1294,7 @@ namespace ARMeilleure.Instructions } } - public static void Frintp_S(EmitterContext context) + public static void Frintp_S(ArmEmitterContext context) { if (Optimizations.UseSse41) { @@ -1311,12 +1304,12 @@ namespace ARMeilleure.Instructions { EmitScalarUnaryOpF(context, (op1) => { - return EmitUnaryMathCall(context, nameof(Math.Ceiling), op1); + return EmitUnaryMathCall(context, MathF.Ceiling, Math.Ceiling, op1); }); } } - public static void Frintp_V(EmitterContext context) + public static void Frintp_V(ArmEmitterContext context) { if (Optimizations.UseSse41) { @@ -1326,12 +1319,12 @@ namespace ARMeilleure.Instructions { EmitVectorUnaryOpF(context, (op1) => { - return EmitUnaryMathCall(context, nameof(Math.Ceiling), op1); + return EmitUnaryMathCall(context, MathF.Ceiling, Math.Ceiling, op1); }); } } - public static void Frintx_S(EmitterContext context) + public static void Frintx_S(ArmEmitterContext context) { OpCodeSimd op = (OpCodeSimd)context.CurrOp; @@ -1339,20 +1332,16 @@ namespace ARMeilleure.Instructions { if (op.Size == 0) { - MethodInfo info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.RoundF)); - - return context.Call(info, op1); + return context.Call(new _F32_F32(SoftFallback.RoundF), op1); } else /* if (op.Size == 1) */ { - MethodInfo info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.Round)); - - return context.Call(info, op1); + return context.Call(new _F64_F64(SoftFallback.Round), op1); } }); } - public static void Frintx_V(EmitterContext context) + public static void Frintx_V(ArmEmitterContext context) { OpCodeSimd op = (OpCodeSimd)context.CurrOp; @@ -1362,20 +1351,16 @@ namespace ARMeilleure.Instructions { if (sizeF == 0) { - MethodInfo info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.RoundF)); - - return context.Call(info, op1); + return context.Call(new _F32_F32(SoftFallback.RoundF), op1); } else /* if (sizeF == 1) */ { - MethodInfo info = typeof(SoftFallback).GetMethod(nameof(SoftFallback.Round)); - - return context.Call(info, op1); + return context.Call(new _F64_F64(SoftFallback.Round), op1); } }); } - public static void Frintz_S(EmitterContext context) + public static void Frintz_S(ArmEmitterContext context) { if (Optimizations.UseSse41) { @@ -1385,12 +1370,12 @@ namespace ARMeilleure.Instructions { EmitScalarUnaryOpF(context, (op1) => { - return EmitUnaryMathCall(context, nameof(Math.Truncate), op1); + return EmitUnaryMathCall(context, MathF.Truncate, Math.Truncate, op1); }); } } - public static void Frintz_V(EmitterContext context) + public static void Frintz_V(ArmEmitterContext context) { if (Optimizations.UseSse41) { @@ -1400,12 +1385,12 @@ namespace ARMeilleure.Instructions { EmitVectorUnaryOpF(context, (op1) => { - return EmitUnaryMathCall(context, nameof(Math.Truncate), op1); + return EmitUnaryMathCall(context, MathF.Truncate, Math.Truncate, op1); }); } } - public static void Frsqrte_S(EmitterContext context) + public static void Frsqrte_S(ArmEmitterContext context) { OpCodeSimd op = (OpCodeSimd)context.CurrOp; @@ -1419,12 +1404,12 @@ namespace ARMeilleure.Instructions { EmitScalarUnaryOpF(context, (op1) => { - return EmitSoftFloatCall(context, nameof(SoftFloat32.FPRSqrtEstimate), op1); + return EmitSoftFloatCall(context, SoftFloat32.FPRSqrtEstimate, SoftFloat64.FPRSqrtEstimate, op1); }); } } - public static void Frsqrte_V(EmitterContext context) + public static void Frsqrte_V(ArmEmitterContext context) { OpCodeSimd op = (OpCodeSimd)context.CurrOp; @@ -1438,12 +1423,12 @@ namespace ARMeilleure.Instructions { EmitVectorUnaryOpF(context, (op1) => { - return EmitSoftFloatCall(context, nameof(SoftFloat32.FPRSqrtEstimate), op1); + return EmitSoftFloatCall(context, SoftFloat32.FPRSqrtEstimate, SoftFloat64.FPRSqrtEstimate, op1); }); } } - public static void Frsqrts_S(EmitterContext context) // Fused. + public static void Frsqrts_S(ArmEmitterContext context) // Fused. { if (Optimizations.FastFP && Optimizations.UseSse2) { @@ -1480,12 +1465,12 @@ namespace ARMeilleure.Instructions { EmitScalarBinaryOpF(context, (op1, op2) => { - return EmitSoftFloatCall(context, nameof(SoftFloat32.FPRSqrtStepFused), op1, op2); + return EmitSoftFloatCall(context, SoftFloat32.FPRSqrtStepFused, SoftFloat64.FPRSqrtStepFused, op1, op2); }); } } - public static void Frsqrts_V(EmitterContext context) // Fused. + public static void Frsqrts_V(ArmEmitterContext context) // Fused. { if (Optimizations.FastFP && Optimizations.UseSse2) { @@ -1527,12 +1512,12 @@ namespace ARMeilleure.Instructions { EmitVectorBinaryOpF(context, (op1, op2) => { - return EmitSoftFloatCall(context, nameof(SoftFloat32.FPRSqrtStepFused), op1, op2); + return EmitSoftFloatCall(context, SoftFloat32.FPRSqrtStepFused, SoftFloat64.FPRSqrtStepFused, op1, op2); }); } } - public static void Fsqrt_S(EmitterContext context) + public static void Fsqrt_S(ArmEmitterContext context) { if (Optimizations.FastFP && Optimizations.UseSse2) { @@ -1542,12 +1527,12 @@ namespace ARMeilleure.Instructions { EmitScalarUnaryOpF(context, (op1) => { - return EmitSoftFloatCall(context, nameof(SoftFloat32.FPSqrt), op1); + return EmitSoftFloatCall(context, SoftFloat32.FPSqrt, SoftFloat64.FPSqrt, op1); }); } } - public static void Fsqrt_V(EmitterContext context) + public static void Fsqrt_V(ArmEmitterContext context) { if (Optimizations.FastFP && Optimizations.UseSse2) { @@ -1557,12 +1542,12 @@ namespace ARMeilleure.Instructions { EmitVectorUnaryOpF(context, (op1) => { - return EmitSoftFloatCall(context, nameof(SoftFloat32.FPSqrt), op1); + return EmitSoftFloatCall(context, SoftFloat32.FPSqrt, SoftFloat64.FPSqrt, op1); }); } } - public static void Fsub_S(EmitterContext context) + public static void Fsub_S(ArmEmitterContext context) { if (Optimizations.FastFP && Optimizations.UseSse2) { @@ -1572,12 +1557,12 @@ namespace ARMeilleure.Instructions { EmitScalarBinaryOpF(context, (op1, op2) => { - return EmitSoftFloatCall(context, nameof(SoftFloat32.FPSub), op1, op2); + return EmitSoftFloatCall(context, SoftFloat32.FPSub, SoftFloat64.FPSub, op1, op2); }); } } - public static void Fsub_V(EmitterContext context) + public static void Fsub_V(ArmEmitterContext context) { if (Optimizations.FastFP && Optimizations.UseSse2) { @@ -1587,12 +1572,12 @@ namespace ARMeilleure.Instructions { EmitVectorBinaryOpF(context, (op1, op2) => { - return EmitSoftFloatCall(context, nameof(SoftFloat32.FPSub), op1, op2); + return EmitSoftFloatCall(context, SoftFloat32.FPSub, SoftFloat64.FPSub, op1, op2); }); } } - public static void Mla_V(EmitterContext context) + public static void Mla_V(ArmEmitterContext context) { if (Optimizations.UseSse41) { @@ -1607,7 +1592,7 @@ namespace ARMeilleure.Instructions } } - public static void Mla_Ve(EmitterContext context) + public static void Mla_Ve(ArmEmitterContext context) { EmitVectorTernaryOpByElemZx(context, (op1, op2, op3) => { @@ -1615,7 +1600,7 @@ namespace ARMeilleure.Instructions }); } - public static void Mls_V(EmitterContext context) + public static void Mls_V(ArmEmitterContext context) { if (Optimizations.UseSse41) { @@ -1630,7 +1615,7 @@ namespace ARMeilleure.Instructions } } - public static void Mls_Ve(EmitterContext context) + public static void Mls_Ve(ArmEmitterContext context) { EmitVectorTernaryOpByElemZx(context, (op1, op2, op3) => { @@ -1638,7 +1623,7 @@ namespace ARMeilleure.Instructions }); } - public static void Mul_V(EmitterContext context) + public static void Mul_V(ArmEmitterContext context) { if (Optimizations.UseSse41) { @@ -1650,17 +1635,17 @@ namespace ARMeilleure.Instructions } } - public static void Mul_Ve(EmitterContext context) + public static void Mul_Ve(ArmEmitterContext context) { EmitVectorBinaryOpByElemZx(context, (op1, op2) => context.Multiply(op1, op2)); } - public static void Neg_S(EmitterContext context) + public static void Neg_S(ArmEmitterContext context) { EmitScalarUnaryOpSx(context, (op1) => context.Negate(op1)); } - public static void Neg_V(EmitterContext context) + public static void Neg_V(ArmEmitterContext context) { if (Optimizations.UseSse2) { @@ -1683,17 +1668,17 @@ namespace ARMeilleure.Instructions } } - public static void Raddhn_V(EmitterContext context) + public static void Raddhn_V(ArmEmitterContext context) { EmitHighNarrow(context, (op1, op2) => context.Add(op1, op2), round: true); } - public static void Rsubhn_V(EmitterContext context) + public static void Rsubhn_V(ArmEmitterContext context) { EmitHighNarrow(context, (op1, op2) => context.Subtract(op1, op2), round: true); } - public static void Saba_V(EmitterContext context) + public static void Saba_V(ArmEmitterContext context) { EmitVectorTernaryOpSx(context, (op1, op2, op3) => { @@ -1701,7 +1686,7 @@ namespace ARMeilleure.Instructions }); } - public static void Sabal_V(EmitterContext context) + public static void Sabal_V(ArmEmitterContext context) { EmitVectorWidenRnRmTernaryOpSx(context, (op1, op2, op3) => { @@ -1709,7 +1694,7 @@ namespace ARMeilleure.Instructions }); } - public static void Sabd_V(EmitterContext context) + public static void Sabd_V(ArmEmitterContext context) { if (Optimizations.UseSse2) { @@ -1729,7 +1714,7 @@ namespace ARMeilleure.Instructions } } - public static void Sabdl_V(EmitterContext context) + public static void Sabdl_V(ArmEmitterContext context) { OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp; @@ -1762,12 +1747,12 @@ namespace ARMeilleure.Instructions } } - public static void Sadalp_V(EmitterContext context) + public static void Sadalp_V(ArmEmitterContext context) { EmitAddLongPairwise(context, signed: true, accumulate: true); } - public static void Saddl_V(EmitterContext context) + public static void Saddl_V(ArmEmitterContext context) { if (Optimizations.UseSse41) { @@ -1797,17 +1782,17 @@ namespace ARMeilleure.Instructions } } - public static void Saddlp_V(EmitterContext context) + public static void Saddlp_V(ArmEmitterContext context) { EmitAddLongPairwise(context, signed: true, accumulate: false); } - public static void Saddlv_V(EmitterContext context) + public static void Saddlv_V(ArmEmitterContext context) { EmitVectorLongAcrossVectorOpSx(context, (op1, op2) => context.Add(op1, op2)); } - public static void Saddw_V(EmitterContext context) + public static void Saddw_V(ArmEmitterContext context) { if (Optimizations.UseSse41) { @@ -1835,7 +1820,7 @@ namespace ARMeilleure.Instructions } } - public static void Shadd_V(EmitterContext context) + public static void Shadd_V(ArmEmitterContext context) { OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp; @@ -1872,7 +1857,7 @@ namespace ARMeilleure.Instructions } } - public static void Shsub_V(EmitterContext context) + public static void Shsub_V(ArmEmitterContext context) { OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp; @@ -1913,7 +1898,7 @@ namespace ARMeilleure.Instructions } } - public static void Smax_V(EmitterContext context) + public static void Smax_V(ArmEmitterContext context) { if (Optimizations.UseSse41) { @@ -1935,33 +1920,27 @@ namespace ARMeilleure.Instructions } else { - Type[] types = new Type[] { typeof(long), typeof(long) }; + Delegate dlg = new _S64_S64_S64(Math.Max); - MethodInfo info = typeof(Math).GetMethod(nameof(Math.Max), types); - - EmitVectorBinaryOpSx(context, (op1, op2) => context.Call(info, op1, op2)); + EmitVectorBinaryOpSx(context, (op1, op2) => context.Call(dlg, op1, op2)); } } - public static void Smaxp_V(EmitterContext context) + public static void Smaxp_V(ArmEmitterContext context) { - Type[] types = new Type[] { typeof(long), typeof(long) }; + Delegate dlg = new _S64_S64_S64(Math.Max); - MethodInfo info = typeof(Math).GetMethod(nameof(Math.Max), types); - - EmitVectorPairwiseOpSx(context, (op1, op2) => context.Call(info, op1, op2)); + EmitVectorPairwiseOpSx(context, (op1, op2) => context.Call(dlg, op1, op2)); } - public static void Smaxv_V(EmitterContext context) + public static void Smaxv_V(ArmEmitterContext context) { - Type[] types = new Type[] { typeof(long), typeof(long) }; + Delegate dlg = new _S64_S64_S64(Math.Max); - MethodInfo info = typeof(Math).GetMethod(nameof(Math.Max), types); - - EmitVectorAcrossVectorOpSx(context, (op1, op2) => context.Call(info, op1, op2)); + EmitVectorAcrossVectorOpSx(context, (op1, op2) => context.Call(dlg, op1, op2)); } - public static void Smin_V(EmitterContext context) + public static void Smin_V(ArmEmitterContext context) { if (Optimizations.UseSse41) { @@ -1983,33 +1962,27 @@ namespace ARMeilleure.Instructions } else { - Type[] types = new Type[] { typeof(long), typeof(long) }; + Delegate dlg = new _S64_S64_S64(Math.Min); - MethodInfo info = typeof(Math).GetMethod(nameof(Math.Min), types); - - EmitVectorBinaryOpSx(context, (op1, op2) => context.Call(info, op1, op2)); + EmitVectorBinaryOpSx(context, (op1, op2) => context.Call(dlg, op1, op2)); } } - public static void Sminp_V(EmitterContext context) + public static void Sminp_V(ArmEmitterContext context) { - Type[] types = new Type[] { typeof(long), typeof(long) }; + Delegate dlg = new _S64_S64_S64(Math.Min); - MethodInfo info = typeof(Math).GetMethod(nameof(Math.Min), types); - - EmitVectorPairwiseOpSx(context, (op1, op2) => context.Call(info, op1, op2)); + EmitVectorPairwiseOpSx(context, (op1, op2) => context.Call(dlg, op1, op2)); } - public static void Sminv_V(EmitterContext context) + public static void Sminv_V(ArmEmitterContext context) { - Type[] types = new Type[] { typeof(long), typeof(long) }; + Delegate dlg = new _S64_S64_S64(Math.Min); - MethodInfo info = typeof(Math).GetMethod(nameof(Math.Min), types); - - EmitVectorAcrossVectorOpSx(context, (op1, op2) => context.Call(info, op1, op2)); + EmitVectorAcrossVectorOpSx(context, (op1, op2) => context.Call(dlg, op1, op2)); } - public static void Smlal_V(EmitterContext context) + public static void Smlal_V(ArmEmitterContext context) { OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp; @@ -2048,7 +2021,7 @@ namespace ARMeilleure.Instructions } } - public static void Smlal_Ve(EmitterContext context) + public static void Smlal_Ve(ArmEmitterContext context) { EmitVectorWidenTernaryOpByElemSx(context, (op1, op2, op3) => { @@ -2056,7 +2029,7 @@ namespace ARMeilleure.Instructions }); } - public static void Smlsl_V(EmitterContext context) + public static void Smlsl_V(ArmEmitterContext context) { OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp; @@ -2097,7 +2070,7 @@ namespace ARMeilleure.Instructions } } - public static void Smlsl_Ve(EmitterContext context) + public static void Smlsl_Ve(ArmEmitterContext context) { EmitVectorWidenTernaryOpByElemSx(context, (op1, op2, op3) => { @@ -2105,97 +2078,97 @@ namespace ARMeilleure.Instructions }); } - public static void Smull_V(EmitterContext context) + public static void Smull_V(ArmEmitterContext context) { EmitVectorWidenRnRmBinaryOpSx(context, (op1, op2) => context.Multiply(op1, op2)); } - public static void Smull_Ve(EmitterContext context) + public static void Smull_Ve(ArmEmitterContext context) { EmitVectorWidenBinaryOpByElemSx(context, (op1, op2) => context.Multiply(op1, op2)); } - public static void Sqabs_S(EmitterContext context) + public static void Sqabs_S(ArmEmitterContext context) { EmitScalarSaturatingUnaryOpSx(context, (op1) => EmitAbs(context, op1)); } - public static void Sqabs_V(EmitterContext context) + public static void Sqabs_V(ArmEmitterContext context) { EmitVectorSaturatingUnaryOpSx(context, (op1) => EmitAbs(context, op1)); } - public static void Sqadd_S(EmitterContext context) + public static void Sqadd_S(ArmEmitterContext context) { EmitScalarSaturatingBinaryOpSx(context, SaturatingFlags.Add); } - public static void Sqadd_V(EmitterContext context) + public static void Sqadd_V(ArmEmitterContext context) { EmitVectorSaturatingBinaryOpSx(context, SaturatingFlags.Add); } - public static void Sqdmulh_S(EmitterContext context) + public static void Sqdmulh_S(ArmEmitterContext context) { EmitSaturatingBinaryOp(context, (op1, op2) => EmitDoublingMultiplyHighHalf(context, op1, op2, round: false), SaturatingFlags.ScalarSx); } - public static void Sqdmulh_V(EmitterContext context) + public static void Sqdmulh_V(ArmEmitterContext context) { EmitSaturatingBinaryOp(context, (op1, op2) => EmitDoublingMultiplyHighHalf(context, op1, op2, round: false), SaturatingFlags.VectorSx); } - public static void Sqneg_S(EmitterContext context) + public static void Sqneg_S(ArmEmitterContext context) { EmitScalarSaturatingUnaryOpSx(context, (op1) => context.Negate(op1)); } - public static void Sqneg_V(EmitterContext context) + public static void Sqneg_V(ArmEmitterContext context) { EmitVectorSaturatingUnaryOpSx(context, (op1) => context.Negate(op1)); } - public static void Sqrdmulh_S(EmitterContext context) + public static void Sqrdmulh_S(ArmEmitterContext context) { EmitSaturatingBinaryOp(context, (op1, op2) => EmitDoublingMultiplyHighHalf(context, op1, op2, round: true), SaturatingFlags.ScalarSx); } - public static void Sqrdmulh_V(EmitterContext context) + public static void Sqrdmulh_V(ArmEmitterContext context) { EmitSaturatingBinaryOp(context, (op1, op2) => EmitDoublingMultiplyHighHalf(context, op1, op2, round: true), SaturatingFlags.VectorSx); } - public static void Sqsub_S(EmitterContext context) + public static void Sqsub_S(ArmEmitterContext context) { EmitScalarSaturatingBinaryOpSx(context, SaturatingFlags.Sub); } - public static void Sqsub_V(EmitterContext context) + public static void Sqsub_V(ArmEmitterContext context) { EmitVectorSaturatingBinaryOpSx(context, SaturatingFlags.Sub); } - public static void Sqxtn_S(EmitterContext context) + public static void Sqxtn_S(ArmEmitterContext context) { EmitSaturatingNarrowOp(context, SaturatingNarrowFlags.ScalarSxSx); } - public static void Sqxtn_V(EmitterContext context) + public static void Sqxtn_V(ArmEmitterContext context) { EmitSaturatingNarrowOp(context, SaturatingNarrowFlags.VectorSxSx); } - public static void Sqxtun_S(EmitterContext context) + public static void Sqxtun_S(ArmEmitterContext context) { EmitSaturatingNarrowOp(context, SaturatingNarrowFlags.ScalarSxZx); } - public static void Sqxtun_V(EmitterContext context) + public static void Sqxtun_V(ArmEmitterContext context) { EmitSaturatingNarrowOp(context, SaturatingNarrowFlags.VectorSxZx); } - public static void Srhadd_V(EmitterContext context) + public static void Srhadd_V(ArmEmitterContext context) { OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp; @@ -2240,7 +2213,7 @@ namespace ARMeilleure.Instructions } } - public static void Ssubl_V(EmitterContext context) + public static void Ssubl_V(ArmEmitterContext context) { if (Optimizations.UseSse41) { @@ -2270,7 +2243,7 @@ namespace ARMeilleure.Instructions } } - public static void Ssubw_V(EmitterContext context) + public static void Ssubw_V(ArmEmitterContext context) { if (Optimizations.UseSse41) { @@ -2298,12 +2271,12 @@ namespace ARMeilleure.Instructions } } - public static void Sub_S(EmitterContext context) + public static void Sub_S(ArmEmitterContext context) { EmitScalarBinaryOpZx(context, (op1, op2) => context.Subtract(op1, op2)); } - public static void Sub_V(EmitterContext context) + public static void Sub_V(ArmEmitterContext context) { if (Optimizations.UseSse2) { @@ -2329,22 +2302,22 @@ namespace ARMeilleure.Instructions } } - public static void Subhn_V(EmitterContext context) + public static void Subhn_V(ArmEmitterContext context) { EmitHighNarrow(context, (op1, op2) => context.Subtract(op1, op2), round: false); } - public static void Suqadd_S(EmitterContext context) + public static void Suqadd_S(ArmEmitterContext context) { EmitScalarSaturatingBinaryOpSx(context, SaturatingFlags.Accumulate); } - public static void Suqadd_V(EmitterContext context) + public static void Suqadd_V(ArmEmitterContext context) { EmitVectorSaturatingBinaryOpSx(context, SaturatingFlags.Accumulate); } - public static void Uaba_V(EmitterContext context) + public static void Uaba_V(ArmEmitterContext context) { EmitVectorTernaryOpZx(context, (op1, op2, op3) => { @@ -2352,7 +2325,7 @@ namespace ARMeilleure.Instructions }); } - public static void Uabal_V(EmitterContext context) + public static void Uabal_V(ArmEmitterContext context) { EmitVectorWidenRnRmTernaryOpZx(context, (op1, op2, op3) => { @@ -2360,7 +2333,7 @@ namespace ARMeilleure.Instructions }); } - public static void Uabd_V(EmitterContext context) + public static void Uabd_V(ArmEmitterContext context) { if (Optimizations.UseSse41) { @@ -2380,7 +2353,7 @@ namespace ARMeilleure.Instructions } } - public static void Uabdl_V(EmitterContext context) + public static void Uabdl_V(ArmEmitterContext context) { OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp; @@ -2413,12 +2386,12 @@ namespace ARMeilleure.Instructions } } - public static void Uadalp_V(EmitterContext context) + public static void Uadalp_V(ArmEmitterContext context) { EmitAddLongPairwise(context, signed: false, accumulate: true); } - public static void Uaddl_V(EmitterContext context) + public static void Uaddl_V(ArmEmitterContext context) { if (Optimizations.UseSse41) { @@ -2448,17 +2421,17 @@ namespace ARMeilleure.Instructions } } - public static void Uaddlp_V(EmitterContext context) + public static void Uaddlp_V(ArmEmitterContext context) { EmitAddLongPairwise(context, signed: false, accumulate: false); } - public static void Uaddlv_V(EmitterContext context) + public static void Uaddlv_V(ArmEmitterContext context) { EmitVectorLongAcrossVectorOpZx(context, (op1, op2) => context.Add(op1, op2)); } - public static void Uaddw_V(EmitterContext context) + public static void Uaddw_V(ArmEmitterContext context) { if (Optimizations.UseSse41) { @@ -2486,7 +2459,7 @@ namespace ARMeilleure.Instructions } } - public static void Uhadd_V(EmitterContext context) + public static void Uhadd_V(ArmEmitterContext context) { OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp; @@ -2523,7 +2496,7 @@ namespace ARMeilleure.Instructions } } - public static void Uhsub_V(EmitterContext context) + public static void Uhsub_V(ArmEmitterContext context) { OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp; @@ -2557,7 +2530,7 @@ namespace ARMeilleure.Instructions } } - public static void Umax_V(EmitterContext context) + public static void Umax_V(ArmEmitterContext context) { if (Optimizations.UseSse41) { @@ -2579,33 +2552,27 @@ namespace ARMeilleure.Instructions } else { - Type[] types = new Type[] { typeof(ulong), typeof(ulong) }; + Delegate dlg = new _U64_U64_U64(Math.Max); - MethodInfo info = typeof(Math).GetMethod(nameof(Math.Max), types); - - EmitVectorBinaryOpZx(context, (op1, op2) => context.Call(info, op1, op2)); + EmitVectorBinaryOpZx(context, (op1, op2) => context.Call(dlg, op1, op2)); } } - public static void Umaxp_V(EmitterContext context) + public static void Umaxp_V(ArmEmitterContext context) { - Type[] types = new Type[] { typeof(ulong), typeof(ulong) }; + Delegate dlg = new _U64_U64_U64(Math.Max); - MethodInfo info = typeof(Math).GetMethod(nameof(Math.Max), types); - - EmitVectorPairwiseOpZx(context, (op1, op2) => context.Call(info, op1, op2)); + EmitVectorPairwiseOpZx(context, (op1, op2) => context.Call(dlg, op1, op2)); } - public static void Umaxv_V(EmitterContext context) + public static void Umaxv_V(ArmEmitterContext context) { - Type[] types = new Type[] { typeof(ulong), typeof(ulong) }; + Delegate dlg = new _U64_U64_U64(Math.Max); - MethodInfo info = typeof(Math).GetMethod(nameof(Math.Max), types); - - EmitVectorAcrossVectorOpZx(context, (op1, op2) => context.Call(info, op1, op2)); + EmitVectorAcrossVectorOpZx(context, (op1, op2) => context.Call(dlg, op1, op2)); } - public static void Umin_V(EmitterContext context) + public static void Umin_V(ArmEmitterContext context) { if (Optimizations.UseSse41) { @@ -2627,33 +2594,27 @@ namespace ARMeilleure.Instructions } else { - Type[] types = new Type[] { typeof(ulong), typeof(ulong) }; + Delegate dlg = new _U64_U64_U64(Math.Min); - MethodInfo info = typeof(Math).GetMethod(nameof(Math.Min), types); - - EmitVectorBinaryOpZx(context, (op1, op2) => context.Call(info, op1, op2)); + EmitVectorBinaryOpZx(context, (op1, op2) => context.Call(dlg, op1, op2)); } } - public static void Uminp_V(EmitterContext context) + public static void Uminp_V(ArmEmitterContext context) { - Type[] types = new Type[] { typeof(ulong), typeof(ulong) }; + Delegate dlg = new _U64_U64_U64(Math.Min); - MethodInfo info = typeof(Math).GetMethod(nameof(Math.Min), types); - - EmitVectorPairwiseOpZx(context, (op1, op2) => context.Call(info, op1, op2)); + EmitVectorPairwiseOpZx(context, (op1, op2) => context.Call(dlg, op1, op2)); } - public static void Uminv_V(EmitterContext context) + public static void Uminv_V(ArmEmitterContext context) { - Type[] types = new Type[] { typeof(ulong), typeof(ulong) }; + Delegate dlg = new _U64_U64_U64(Math.Min); - MethodInfo info = typeof(Math).GetMethod(nameof(Math.Min), types); - - EmitVectorAcrossVectorOpZx(context, (op1, op2) => context.Call(info, op1, op2)); + EmitVectorAcrossVectorOpZx(context, (op1, op2) => context.Call(dlg, op1, op2)); } - public static void Umlal_V(EmitterContext context) + public static void Umlal_V(ArmEmitterContext context) { OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp; @@ -2692,7 +2653,7 @@ namespace ARMeilleure.Instructions } } - public static void Umlal_Ve(EmitterContext context) + public static void Umlal_Ve(ArmEmitterContext context) { EmitVectorWidenTernaryOpByElemZx(context, (op1, op2, op3) => { @@ -2700,7 +2661,7 @@ namespace ARMeilleure.Instructions }); } - public static void Umlsl_V(EmitterContext context) + public static void Umlsl_V(ArmEmitterContext context) { OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp; @@ -2741,7 +2702,7 @@ namespace ARMeilleure.Instructions } } - public static void Umlsl_Ve(EmitterContext context) + public static void Umlsl_Ve(ArmEmitterContext context) { EmitVectorWidenTernaryOpByElemZx(context, (op1, op2, op3) => { @@ -2749,47 +2710,47 @@ namespace ARMeilleure.Instructions }); } - public static void Umull_V(EmitterContext context) + public static void Umull_V(ArmEmitterContext context) { EmitVectorWidenRnRmBinaryOpZx(context, (op1, op2) => context.Multiply(op1, op2)); } - public static void Umull_Ve(EmitterContext context) + public static void Umull_Ve(ArmEmitterContext context) { EmitVectorWidenBinaryOpByElemZx(context, (op1, op2) => context.Multiply(op1, op2)); } - public static void Uqadd_S(EmitterContext context) + public static void Uqadd_S(ArmEmitterContext context) { EmitScalarSaturatingBinaryOpZx(context, SaturatingFlags.Add); } - public static void Uqadd_V(EmitterContext context) + public static void Uqadd_V(ArmEmitterContext context) { EmitVectorSaturatingBinaryOpZx(context, SaturatingFlags.Add); } - public static void Uqsub_S(EmitterContext context) + public static void Uqsub_S(ArmEmitterContext context) { EmitScalarSaturatingBinaryOpZx(context, SaturatingFlags.Sub); } - public static void Uqsub_V(EmitterContext context) + public static void Uqsub_V(ArmEmitterContext context) { EmitVectorSaturatingBinaryOpZx(context, SaturatingFlags.Sub); } - public static void Uqxtn_S(EmitterContext context) + public static void Uqxtn_S(ArmEmitterContext context) { EmitSaturatingNarrowOp(context, SaturatingNarrowFlags.ScalarZxZx); } - public static void Uqxtn_V(EmitterContext context) + public static void Uqxtn_V(ArmEmitterContext context) { EmitSaturatingNarrowOp(context, SaturatingNarrowFlags.VectorZxZx); } - public static void Urhadd_V(EmitterContext context) + public static void Urhadd_V(ArmEmitterContext context) { OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp; @@ -2823,17 +2784,17 @@ namespace ARMeilleure.Instructions } } - public static void Usqadd_S(EmitterContext context) + public static void Usqadd_S(ArmEmitterContext context) { EmitScalarSaturatingBinaryOpZx(context, SaturatingFlags.Accumulate); } - public static void Usqadd_V(EmitterContext context) + public static void Usqadd_V(ArmEmitterContext context) { EmitVectorSaturatingBinaryOpZx(context, SaturatingFlags.Accumulate); } - public static void Usubl_V(EmitterContext context) + public static void Usubl_V(ArmEmitterContext context) { if (Optimizations.UseSse41) { @@ -2863,7 +2824,7 @@ namespace ARMeilleure.Instructions } } - public static void Usubw_V(EmitterContext context) + public static void Usubw_V(ArmEmitterContext context) { if (Optimizations.UseSse41) { @@ -2891,14 +2852,14 @@ namespace ARMeilleure.Instructions } } - private static Operand EmitAbs(EmitterContext context, Operand value) + private static Operand EmitAbs(ArmEmitterContext context, Operand value) { Operand isPositive = context.ICompareGreaterOrEqual(value, Const(value.Type, 0)); return context.ConditionalSelect(isPositive, value, context.Negate(value)); } - private static void EmitAddLongPairwise(EmitterContext context, bool signed, bool accumulate) + private static void EmitAddLongPairwise(ArmEmitterContext context, bool signed, bool accumulate) { OpCodeSimd op = (OpCodeSimd)context.CurrOp; @@ -2929,7 +2890,7 @@ namespace ARMeilleure.Instructions } private static Operand EmitDoublingMultiplyHighHalf( - EmitterContext context, + ArmEmitterContext context, Operand n, Operand m, bool round) @@ -2962,7 +2923,7 @@ namespace ARMeilleure.Instructions return res; } - private static void EmitHighNarrow(EmitterContext context, Func2I emit, bool round) + private static void EmitHighNarrow(ArmEmitterContext context, Func2I emit, bool round) { OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp; @@ -2995,7 +2956,7 @@ namespace ARMeilleure.Instructions context.Copy(GetVec(op.Rd), res); } - public static void EmitScalarRoundOpF(EmitterContext context, FPRoundingMode roundMode) + public static void EmitScalarRoundOpF(ArmEmitterContext context, FPRoundingMode roundMode) { OpCodeSimd op = (OpCodeSimd)context.CurrOp; @@ -3018,7 +2979,7 @@ namespace ARMeilleure.Instructions context.Copy(GetVec(op.Rd), res); } - public static void EmitVectorRoundOpF(EmitterContext context, FPRoundingMode roundMode) + public static void EmitVectorRoundOpF(ArmEmitterContext context, FPRoundingMode roundMode) { OpCodeSimd op = (OpCodeSimd)context.CurrOp; @@ -3044,7 +3005,7 @@ namespace ARMeilleure.Instructions Subtract } - private static void EmitSse41Mul_AddSub(EmitterContext context, AddSub addSub) + private static void EmitSse41Mul_AddSub(ArmEmitterContext context, AddSub addSub) { OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp; @@ -3109,7 +3070,7 @@ namespace ARMeilleure.Instructions } private static void EmitSse41Sabd( - EmitterContext context, + ArmEmitterContext context, OpCodeSimdReg op, Operand n, Operand m, @@ -3142,7 +3103,7 @@ namespace ARMeilleure.Instructions } private static void EmitSse41Uabd( - EmitterContext context, + ArmEmitterContext context, OpCodeSimdReg op, Operand n, Operand m, diff --git a/ARMeilleure/Instructions/InstEmitSimdCmp.cs b/ARMeilleure/Instructions/InstEmitSimdCmp.cs index 4297c2c239..3d711f92f8 100644 --- a/ARMeilleure/Instructions/InstEmitSimdCmp.cs +++ b/ARMeilleure/Instructions/InstEmitSimdCmp.cs @@ -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) diff --git a/ARMeilleure/Instructions/InstEmitSimdCrypto.cs b/ARMeilleure/Instructions/InstEmitSimdCrypto.cs index 03f00ed13f..2b61fadac1 100644 --- a/ARMeilleure/Instructions/InstEmitSimdCrypto.cs +++ b/ARMeilleure/Instructions/InstEmitSimdCrypto.cs @@ -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)); } } } diff --git a/ARMeilleure/Instructions/InstEmitSimdCvt.cs b/ARMeilleure/Instructions/InstEmitSimdCvt.cs index d759a77871..b8e9e6ffc4 100644 --- a/ARMeilleure/Instructions/InstEmitSimdCvt.cs +++ b/ARMeilleure/Instructions/InstEmitSimdCvt.cs @@ -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); diff --git a/ARMeilleure/Instructions/InstEmitSimdHash.cs b/ARMeilleure/Instructions/InstEmitSimdHash.cs index 734d00fca6..d3f39c375d 100644 --- a/ARMeilleure/Instructions/InstEmitSimdHash.cs +++ b/ARMeilleure/Instructions/InstEmitSimdHash.cs @@ -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); } diff --git a/ARMeilleure/Instructions/InstEmitSimdHelper.cs b/ARMeilleure/Instructions/InstEmitSimdHelper.cs index 7dae668ae1..2e939cfaab 100644 --- a/ARMeilleure/Instructions/InstEmitSimdHelper.cs +++ b/ARMeilleure/Instructions/InstEmitSimdHelper.cs @@ -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); diff --git a/ARMeilleure/Instructions/InstEmitSimdLogical.cs b/ARMeilleure/Instructions/InstEmitSimdLogical.cs index 9435033166..1fe679ace8 100644 --- a/ARMeilleure/Instructions/InstEmitSimdLogical.cs +++ b/ARMeilleure/Instructions/InstEmitSimdLogical.cs @@ -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; diff --git a/ARMeilleure/Instructions/InstEmitSimdMemory.cs b/ARMeilleure/Instructions/InstEmitSimdMemory.cs index 6dfc280c1b..9863db1289 100644 --- a/ARMeilleure/Instructions/InstEmitSimdMemory.cs +++ b/ARMeilleure/Instructions/InstEmitSimdMemory.cs @@ -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; diff --git a/ARMeilleure/Instructions/InstEmitSimdMove.cs b/ARMeilleure/Instructions/InstEmitSimdMove.cs index d22a74f9de..ee88ec3aa3 100644 --- a/ARMeilleure/Instructions/InstEmitSimdMove.cs +++ b/ARMeilleure/Instructions/InstEmitSimdMove.cs @@ -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; diff --git a/ARMeilleure/Instructions/InstEmitSimdShift.cs b/ARMeilleure/Instructions/InstEmitSimdShift.cs index 2ebf55c547..be050060ca 100644 --- a/ARMeilleure/Instructions/InstEmitSimdShift.cs +++ b/ARMeilleure/Instructions/InstEmitSimdShift.cs @@ -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; diff --git a/ARMeilleure/Instructions/InstEmitSystem.cs b/ARMeilleure/Instructions/InstEmitSystem.cs index 7ddacd1f18..fefb838c9f 100644 --- a/ARMeilleure/Instructions/InstEmitSystem.cs +++ b/ARMeilleure/Instructions/InstEmitSystem.cs @@ -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; diff --git a/ARMeilleure/Instructions/NativeInterface.cs b/ARMeilleure/Instructions/NativeInterface.cs index 69e594eedc..3e64d64f58 100644 --- a/ARMeilleure/Instructions/NativeInterface.cs +++ b/ARMeilleure/Instructions/NativeInterface.cs @@ -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 _contexts; - - static NativeInterface() - { - _contexts = new ConcurrentDictionary(); - } + [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 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; } } } \ No newline at end of file diff --git a/ARMeilleure/Instructions/SoftFallback.cs b/ARMeilleure/Instructions/SoftFallback.cs index 4a47e53d2e..dc0309218b 100644 --- a/ARMeilleure/Instructions/SoftFallback.cs +++ b/ARMeilleure/Instructions/SoftFallback.cs @@ -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)); diff --git a/ARMeilleure/IntermediateRepresentation/Instruction.cs b/ARMeilleure/IntermediateRepresentation/Instruction.cs index 130dc0e3e8..6e863cd6b8 100644 --- a/ARMeilleure/IntermediateRepresentation/Instruction.cs +++ b/ARMeilleure/IntermediateRepresentation/Instruction.cs @@ -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, diff --git a/ARMeilleure/Memory/MemoryManager.cs b/ARMeilleure/Memory/MemoryManager.cs index 8cc36fb1c9..bff9cc81e0 100644 --- a/ARMeilleure/Memory/MemoryManager.cs +++ b/ARMeilleure/Memory/MemoryManager.cs @@ -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) diff --git a/ARMeilleure/State/NativeContext.cs b/ARMeilleure/State/NativeContext.cs index e868b13b9b..4e6a5302f5 100644 --- a/ARMeilleure/State/NativeContext.cs +++ b/ARMeilleure/State/NativeContext.cs @@ -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() diff --git a/ARMeilleure/Translation/ArmEmitterContext.cs b/ARMeilleure/Translation/ArmEmitterContext.cs new file mode 100644 index 0000000000..da9e95367f --- /dev/null +++ b/ARMeilleure/Translation/ArmEmitterContext.cs @@ -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; + } + } +} \ No newline at end of file diff --git a/ARMeilleure/Translation/Compiler.cs b/ARMeilleure/Translation/Compiler.cs index a279563458..79ceafe831 100644 --- a/ARMeilleure/Translation/Compiler.cs +++ b/ARMeilleure/Translation/Compiler.cs @@ -11,12 +11,16 @@ namespace ARMeilleure.Translation { public static T Compile(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(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); } } } \ No newline at end of file diff --git a/ARMeilleure/Translation/DelegateCache.cs b/ARMeilleure/Translation/DelegateCache.cs new file mode 100644 index 0000000000..7328c61a67 --- /dev/null +++ b/ARMeilleure/Translation/DelegateCache.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Concurrent; +using System.Reflection; + +namespace ARMeilleure.Translation +{ + static class DelegateCache + { + private static ConcurrentDictionary _delegates; + + static DelegateCache() + { + _delegates = new ConcurrentDictionary(); + } + + 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}"; + } + } +} \ No newline at end of file diff --git a/ARMeilleure/Translation/EmitterContext.cs b/ARMeilleure/Translation/EmitterContext.cs index cee396ce38..f9acaa2923 100644 --- a/ARMeilleure/Translation/EmitterContext.cs +++ b/ARMeilleure/Translation/EmitterContext.cs @@ -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 _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)); diff --git a/ARMeilleure/Translation/JitCache.cs b/ARMeilleure/Translation/JitCache.cs index 8cbfd8299f..cc7e41bf45 100644 --- a/ARMeilleure/Translation/JitCache.cs +++ b/ARMeilleure/Translation/JitCache.cs @@ -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; + } } } diff --git a/ARMeilleure/Translation/Translator.cs b/ARMeilleure/Translation/Translator.cs index 1186709b48..8d12a94321 100644 --- a/ARMeilleure/Translation/Translator.cs +++ b/ARMeilleure/Translation/Translator.cs @@ -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);