private static void __cyclesrdtsc(int *target) { /* * push eax * push ecx * push edx * lea esi, target * rdtsc * mov [esi+4], eax * mov [esi], edx * pop edx * pop ecx * pop eax * ret */ __cyclesrdtscptr = target; string intname = LabelName.GetStaticFieldName(typeof(CPUImpl).GetField(nameof(__cyclesrdtscptr))); XS.Push(XSRegisters.EAX); XS.Push(XSRegisters.ECX); XS.Push(XSRegisters.EDX); XS.Lea(XSRegisters.ESI, intname); XS.Rdtsc(); XS.Set(XSRegisters.ESI, XSRegisters.EAX, destinationIsIndirect: true, destinationDisplacement: 4); XS.Set(XSRegisters.ESI, XSRegisters.EDX, destinationIsIndirect: true); XS.Push(XSRegisters.EDX); XS.Push(XSRegisters.ECX); XS.Push(XSRegisters.EAX); XS.Return(); }
private static void __raterdmsr(int *target) { /* * ; esi register layout: (mperf_hi, mperf_lo, aperf_hi, aperf_lo) * ; * ; int* ptr = new int[4]; * ; * lea esi, ptr ;equivalent with `mov esi, &ptr` * mov ecx, e7h * rdmsr * mov [esi + 4], eax * mov [esi], edx * mov ecx, e8h * rdmsr * mov [esi + 12], eax * mov [esi + 8], edx * xor eax, eax * ret */ __raterdmsrptr = target; string intname = LabelName.GetStaticFieldName(typeof(CPUImpl).GetField(nameof(__raterdmsrptr))); XS.Lea(XSRegisters.ESI, intname); XS.Set(XSRegisters.ECX, 0xe7); XS.Rdmsr(); XS.Set(XSRegisters.EAX, XSRegisters.ESI, destinationIsIndirect: true, destinationDisplacement: 4); XS.Set(XSRegisters.EDX, XSRegisters.ESI, destinationIsIndirect: true, destinationDisplacement: 0); XS.Set(XSRegisters.ECX, 0xe8); XS.Rdmsr(); XS.Set(XSRegisters.EAX, XSRegisters.ESI, destinationIsIndirect: true, destinationDisplacement: 12); XS.Set(XSRegisters.EDX, XSRegisters.ESI, destinationIsIndirect: true, destinationDisplacement: 8); XS.Xor(XSRegisters.EAX, XSRegisters.EAX); // XS.Set(XSRegisters.EAX, 0); XS.Return(); }
public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode) { var xOpCode = (OpField)aOpCode; var xFieldName = LabelName.GetStaticFieldName(xOpCode.Value); DoExecute(Assembler, aMethod, xFieldName, xOpCode.Value.DeclaringType, aOpCode); }
public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode) { // TODO: Implement exception DoNullReferenceCheck(Assembler, DebugEnabled, 4); XS.Add(ESP, 4); XS.Pop(EAX); XS.Set(LabelName.GetStaticFieldName(ExceptionHelperRefs.CurrentExceptionRef), EAX, destinationIsIndirect: true); XS.Call("SystemExceptionOccurred"); XS.Set(ECX, 3); EmitExceptionLogic(Assembler, aMethod, aOpCode, false, null); }
internal static void FetchCPUVendor(int *target) { /* * lea esi, target * xor eax, eax * cpuid * mov [esi], ebx * mov [esi + 4], edx * mov [esi + 8], ecx * ret */ __vendortargetptr = target; string intname = LabelName.GetStaticFieldName(typeof(CPUImpl).GetField(nameof(__vendortargetptr))); XS.Lea(XSRegisters.ESI, intname); // new Lea { DestinationReg = RegistersEnum.ESI, SourceRef = ElementReference.New(intname) }; XS.Cpuid(); XS.Set(XSRegisters.ESI, XSRegisters.EBX, destinationIsIndirect: true); XS.Set(XSRegisters.ESI, XSRegisters.EDX, destinationIsIndirect: true, destinationDisplacement: 4); XS.Set(XSRegisters.ESI, XSRegisters.ECX, destinationIsIndirect: true, destinationDisplacement: 8); XS.Return(); }
public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode) { var xToken = (OpToken)aOpCode; string xTokenAddress = null; if (xToken.ValueIsType) { xTokenAddress = ILOp.GetTypeIDLabel(xToken.ValueType); } if (xToken.ValueIsField) { xTokenAddress = LabelName.GetStaticFieldName(xToken.ValueField); } if (String.IsNullOrEmpty(xTokenAddress)) { throw new Exception("Ldtoken not implemented!"); } XS.Push(xTokenAddress); XS.Push(0); }
public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode) { var xType = aMethod.MethodBase.DeclaringType; var xOpCode = (OpField)aOpCode; FieldInfo xField = xOpCode.Value; // call cctor: var xCctor = (xField.DeclaringType.GetConstructors(BindingFlags.Static | BindingFlags.NonPublic)).SingleOrDefault(); if (xCctor != null) { XS.Call(LabelName.Get(xCctor)); ILOp.EmitExceptionLogic(Assembler, aMethod, aOpCode, true, null, ".AfterCCTorExceptionCheck"); XS.Label(".AfterCCTorExceptionCheck"); } //Assembler.Stack.Pop(); //int aExtraOffset;// = 0; //bool xNeedsGC = xField.FieldType.IsClass && !xField.FieldType.IsValueType; var xSize = SizeOfType(xField.FieldType); //if( xNeedsGC ) //{ // aExtraOffset = 12; //} string xDataName = LabelName.GetStaticFieldName(xField); var xTypeNeedsGC = IsReferenceType(xField.FieldType); if (xTypeNeedsGC) { XS.Push(xDataName, isIndirect: true, displacement: 4); XS.Push(0); return; } if (xSize >= 4) { for (int i = 1; i <= (xSize / 4); i++) { // Pop("eax"); // Move(Assembler, "dword [" + mDataName + " + 0x" + (i * 4).ToString("X") + "]", "eax"); new CPUx86.Push { DestinationRef = XSharp.Assembler.ElementReference.New(xDataName), DestinationIsIndirect = true, DestinationDisplacement = (int)(xSize - (i * 4)) }; } switch (xSize % 4) { case 1: { XS.Set(XSRegisters.EAX, 0); XS.Set(XSRegisters.AL, xDataName, sourceIsIndirect: true); XS.Push(XSRegisters.EAX); break; } case 2: { XS.Set(XSRegisters.EAX, 0); XS.Set(XSRegisters.AX, xDataName, sourceIsIndirect: true); XS.Push(XSRegisters.EAX); break; } case 0: { break; } default: //EmitNotImplementedException( Assembler, GetServiceProvider(), "Ldsfld: Remainder size " + ( xSize % 4 ) + " not supported!", mCurLabel, mMethodInformation, mCurOffset, mNextLabel ); throw new NotImplementedException(); //break; } } else { switch (xSize) { case 1: { XS.Set(XSRegisters.EAX, 0); XS.Set(XSRegisters.AL, xDataName, sourceIsIndirect: true); XS.Push(XSRegisters.EAX); break; } case 2: { XS.Set(XSRegisters.EAX, 0); XS.Set(XSRegisters.AX, xDataName, sourceIsIndirect: true); XS.Push(XSRegisters.EAX); break; } case 0: { break; } default: //EmitNotImplementedException( Assembler, GetServiceProvider(), "Ldsfld: Remainder size " + ( xSize % 4 ) + " not supported!", mCurLabel, mMethodInformation, mCurOffset, mNextLabel ); throw new NotImplementedException(); //break; } } }
public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode) { var xType = aMethod.MethodBase.DeclaringType; var xOpCode = (ILOpCodes.OpField)aOpCode; FieldInfo xField = xOpCode.Value; var xIsReferenceType = IsReferenceType(xField.FieldType); // call cctor: var xCctor = (xField.DeclaringType.GetConstructors(BindingFlags.Static | BindingFlags.NonPublic)).SingleOrDefault(); if (xCctor != null) { XS.Call(LabelName.Get(xCctor)); EmitExceptionLogic(Assembler, aMethod, aOpCode, true, null, ".AfterCCTorExceptionCheck"); XS.Label(".AfterCCTorExceptionCheck"); } uint xSize = SizeOfType(xField.FieldType); XS.Comment("Type = '" + xField.FieldType.FullName + "'"); uint xOffset = 0; var xFields = xField.DeclaringType.GetFields(); foreach (FieldInfo xInfo in xFields) { if (xInfo == xField) { break; } xOffset += SizeOfType(xInfo.FieldType); } string xDataName = LabelName.GetStaticFieldName(xField); if (xIsReferenceType) { var name = ElementReference.New(xDataName).Name; XS.Add(ESP, 4); // GC clean up old object XS.Compare(name, 0, destinationIsIndirect: true, destinationDisplacement: 4); XS.Jump(CPU.ConditionalTestEnum.Equal, ".AfterGC"); XS.Push(name, isIndirect: true, displacement: 4); // push object as pointer to send to DecRootCount XS.Call(LabelName.Get(GCImplementationRefs.DecRootCountRef)); XS.Label(".AfterGC"); XS.Pop(EAX); XS.Set(name, EAX, destinationIsIndirect: true, destinationDisplacement: 4); // Update GC for new object XS.Compare(name, 0, destinationIsIndirect: true, destinationDisplacement: 4); XS.Jump(CPU.ConditionalTestEnum.Equal, ".SecondAfterGC"); XS.Push(name, isIndirect: true, displacement: 4); // push object as pointer/uint to send to IncRootCount XS.Call(LabelName.Get(GCImplementationRefs.IncRootCountRef)); XS.Label(".SecondAfterGC"); return; } // value types if (!xField.FieldType.IsPointer && !xField.FieldType.IsPrimitive && !xField.FieldType.IsEnum) { // let clean up object deal with it XS.Push(xDataName, isIndirect: true, displacement: 4); XS.Push(GetTypeIDLabel(xField.FieldType), isIndirect: true); XS.Call(LabelName.Get(GCImplementationRefs.DecRootCountsInStructRef)); } for (int i = 0; i < (xSize / 4); i++) { XS.Pop(EAX); new CPU.Mov { DestinationRef = ElementReference.New(xDataName, i * 4), DestinationIsIndirect = true, SourceReg = CPU.RegistersEnum.EAX }; } switch (xSize % 4) { case 1: { XS.Pop(EAX); new CPU.Mov { DestinationRef = ElementReference.New(xDataName, (int)((xSize / 4) * 4)), DestinationIsIndirect = true, SourceReg = CPU.RegistersEnum.AL }; break; } case 2: { XS.Pop(EAX); new CPU.Mov { DestinationRef = ElementReference.New(xDataName, (int)((xSize / 4) * 4)), DestinationIsIndirect = true, SourceReg = CPU.RegistersEnum.AX }; break; } case 0: { break; } default: throw new NotImplementedException(); } if (!xField.FieldType.IsPointer && !xField.FieldType.IsPrimitive && !xField.FieldType.IsEnum) { // let clean up object deal with it XS.Push(xDataName, isIndirect: true, displacement: 4); XS.Push(GetTypeIDLabel(xField.FieldType), isIndirect: true); XS.Call(LabelName.Get(GCImplementationRefs.IncRootCountsInStructRef)); } }
public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode) { var xType = aMethod.MethodBase.DeclaringType; var xOpCode = (ILOpCodes.OpField)aOpCode; FieldInfo xField = xOpCode.Value; var xIsReferenceType = IsReferenceType(xField.FieldType); // call cctor: var xCctor = (xField.DeclaringType.GetConstructors(BindingFlags.Static | BindingFlags.NonPublic)).SingleOrDefault(); if (xCctor != null) { XS.Call(LabelName.Get(xCctor)); ILOp.EmitExceptionLogic(Assembler, aMethod, aOpCode, true, null, ".AfterCCTorExceptionCheck"); XS.Label(".AfterCCTorExceptionCheck"); } //int aExtraOffset;// = 0; //bool xNeedsGC = xField.FieldType.IsClass && !xField.FieldType.IsValueType; uint xSize = SizeOfType(xField.FieldType); //if( xNeedsGC ) //{ // aExtraOffset = 12; //} new Comment(Assembler, "Type = '" + xField.FieldType.FullName /*+ "', NeedsGC = " + xNeedsGC*/); uint xOffset = 0; var xFields = xField.DeclaringType.GetFields(); foreach (FieldInfo xInfo in xFields) { if (xInfo == xField) { break; } xOffset += SizeOfType(xInfo.FieldType); } string xDataName = LabelName.GetStaticFieldName(xField); if (xIsReferenceType) { XS.Add(XSRegisters.ESP, 4); XS.Pop(XSRegisters.EAX); XS.Set(ElementReference.New(xDataName).Name, XSRegisters.EAX, destinationIsIndirect: true, destinationDisplacement: 4); return; } for (int i = 0; i < (xSize / 4); i++) { XS.Pop(XSRegisters.EAX); new CPUx86.Mov { DestinationRef = ElementReference.New(xDataName, i * 4), DestinationIsIndirect = true, SourceReg = CPUx86.RegistersEnum.EAX }; } switch (xSize % 4) { case 1: { XS.Pop(XSRegisters.EAX); new CPUx86.Mov { DestinationRef = ElementReference.New(xDataName, (int)((xSize / 4) * 4)), DestinationIsIndirect = true, SourceReg = CPUx86.RegistersEnum.AL }; break; } case 2: { XS.Pop(XSRegisters.EAX); new CPUx86.Mov { DestinationRef = XSharp.Assembler.ElementReference.New(xDataName, (int)((xSize / 4) * 4)), DestinationIsIndirect = true, SourceReg = CPUx86.RegistersEnum.AX }; break; } case 0: { break; } default: //EmitNotImplementedException(Assembler, GetServiceProvider(), "Ldsfld: Remainder size " + (xSize % 4) + " not supported!", mCurLabel, mMethodInformation, mCurOffset, mNextLabel); throw new NotImplementedException(); //break; } }