public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode) { var xSource = aOpCode.StackPopTypes[0]; var xSourceSize = SizeOfType(xSource); var xSourceIsFloat = TypeIsFloat(xSource); if (xSourceSize <= 4) { if (!xSourceIsFloat) { if (xSourceSize <= 2 || IsIntegerSigned(xSource)) { XS.SSE.ConvertSI2SS(XMM0, ESP, sourceIsIndirect: true); XS.SSE.MoveSS(ESP, XMM0, destinationIsIndirect: true); } else { throw new NotSupportedException(); } } } else if (xSourceSize <= 8) { if (xSourceIsFloat) { XS.SSE2.ConvertSD2SS(XMM0, ESP, sourceIsIndirect: true); XS.Add(ESP, 4); XS.SSE.MoveSS(ESP, XMM0, destinationIsIndirect: true); } else { if (IsIntegerSigned(xSource)) { /* * Again there is no SSE instruction in x86 to do this conversion as we need a 64 Bit register to do this! So we are forced * to use the legacy x87 FPU to do this operation. In x64 the SSE instruction ConvertSIQ2SS should exist. */ XS.FPU.IntLoad(ESP, isIndirect: true, size: RegisterSize.Long64); XS.Add(ESP, 4); /* This instruction is not needed FloatStoreAndPop does already the conversion */ // XS.SSE2.ConvertSD2SS(XMM0, ESP, sourceIsIndirect: true); XS.FPU.FloatStoreAndPop(ESP, isIndirect: true, size: RegisterSize.Int32); } else { throw new NotSupportedException(); } } } else { throw new NotImplementedException("Cosmos.IL2CPU.x86->IL->Conv_R4.cs->Error: StackSize > 8 not supported"); } }
public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode) { // TODO: Implement exception DoNullReferenceCheck(Assembler, DebugEnabled, 4); XS.Add(ESP, 4); XS.Pop(EAX); XS.Set(DataMember.GetStaticFieldName(ExceptionHelperRefs.CurrentExceptionRef), EAX, destinationIsIndirect: true); XS.Call("SystemExceptionOccurred"); XS.Set(ECX, 3); EmitExceptionLogic(Assembler, aMethod, aOpCode, false, null); }
public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode) { OpDouble xOp = (OpDouble)aOpCode; byte[] xBytes = BitConverter.GetBytes(xOp.Value); new CPU.Push { DestinationValue = BitConverter.ToUInt32(xBytes, 4) }; new CPU.Push { DestinationValue = BitConverter.ToUInt32(xBytes, 0) }; }
public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode) { ILOpCodes.OpSwitch OpSw = (ILOpCodes.OpSwitch)aOpCode; XS.Pop(XSRegisters.EAX); for (int i = 0; i < OpSw.BranchLocations.Length; i++) { XS.Compare(XSRegisters.EAX, ( uint )i); //string DestLabel = AssemblerNasm.TmpBranchLabel( aMethod, new ILOpCodes.OpBranch( ILOpCode.Code.Jmp, aOpCode.Position, OpSw.BranchLocations[ i ] ) ); string xDestLabel = AppAssembler.TmpPosLabel(aMethod, OpSw.BranchLocations[i]); XS.Jump(CPUx86.ConditionalTestEnum.Equal, xDestLabel); } }
public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode) { // apparently, Roslyn changed something to the output. We now have to figure out where to jump to. if (aOpCode.CurrentExceptionRegion.Kind.HasFlag(ExceptionRegionKind.Finally) && aOpCode.CurrentExceptionRegion.HandlerOffset > aOpCode.Position) { XS.Set(aMethod.MethodBase.GetFullName() + "_" + "LeaveAddress_" + aOpCode.CurrentExceptionRegion.HandlerOffset.ToString("X2"), Assembler.CurrentIlLabel + "." + (Assembler.AsmIlIdx + 2).ToString("X2"), destinationIsIndirect: true, size: RegisterSize.Int32); XS.Jump(AppAssembler.TmpPosLabel(aMethod, aOpCode.CurrentExceptionRegion.HandlerOffset)); } XS.Jump(AppAssembler.TmpBranchLabel(aMethod, aOpCode)); }
public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode) { var xStackContent = aOpCode.StackPopTypes[0]; var xStackContentSize = SizeOfType(xStackContent); var StackSize = (int)((xStackContentSize / 4) + (xStackContentSize % 4 == 0 ? 0 : 1)); for (int i = StackSize; i > 0; i--) { XS.Push(ESP, true, (StackSize - 1) * 4); //new CPUx86.Push { DestinationReg = CPUx86.RegistersEnum.ESP, DestinationIsIndirect = true, DestinationDisplacement = (int)((StackSize - 1) * 4) }; } }
public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode) { // MtW: for now, disable this instruction. To me, it's unclear in what context it's being used. uint mObjSize = 0; Type mType = ((Cosmos.IL2CPU.ILOpCodes.OpType)aOpCode).Value; mObjSize = SizeOfType(mType); XS.Pop(XSRegisters.EAX); for (int i = 0; i < (mObjSize / 4); i++) { XS.Set(EAX, 0, destinationDisplacement: i * 4, size: RegisterSize.Int32); } switch (mObjSize % 4) { case 1: { new CPUx86.Mov { DestinationReg = CPUx86.RegistersEnum.EAX, DestinationIsIndirect = true, DestinationDisplacement = ( int )((mObjSize / 4) * 4), SourceValue = 0, Size = 8 }; break; } case 2: { new CPUx86.Mov { DestinationReg = CPUx86.RegistersEnum.EAX, DestinationIsIndirect = true, DestinationDisplacement = ( int )((mObjSize / 4) * 4), SourceValue = 0, Size = 16 }; break; } case 3: { new CPUx86.Mov { DestinationReg = CPUx86.RegistersEnum.EAX, DestinationIsIndirect = true, DestinationDisplacement = ( int )((mObjSize / 4) * 4), SourceValue = 0, Size = 8 }; new CPUx86.Mov { DestinationReg = CPUx86.RegistersEnum.EAX, DestinationIsIndirect = true, DestinationDisplacement = ( int )(((mObjSize / 4) * 4) + 1), SourceValue = 0, Size = 16 }; break; } case 0: break; default: { throw new NotImplementedException("Remainder size " + mObjSize % 4 + " not supported yet! (Type = '" + mType.FullName + "')"); } } }
public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode) { var xSource = aOpCode.StackPopTypes[0]; var xSourceSize = SizeOfType(xSource); var xSourceIsFloat = TypeIsFloat(xSource); if (xSourceIsFloat) { if (xSourceSize == 4) { XS.SSE.MoveSS(XMM0, ESP, sourceIsIndirect: true); XS.SSE.ConvertSS2SIAndTruncate(EAX, XMM0); XS.Set(ESP, EAX, destinationIsIndirect: true); } else if (xSourceSize == 8) { XS.SSE2.MoveSD(XMM0, ESP, sourceIsIndirect: true); XS.SSE2.ConvertSD2SIAndTruncate(EAX, XMM0); XS.Set(ESP, EAX, destinationIsIndirect: true); } else { throw new Exception("Cosmos.IL2CPU.x86->IL->Conv_I1.cs->Unknown size of floating point value."); } } switch (xSourceSize) { case 1: throw new Exception("Cosmos.IL2CPU.x86->IL->Conv_I1.cs->The size 1 could not exist, because always is pushed Int32 or Int64!"); case 2: throw new Exception("Cosmos.IL2CPU.x86->IL->Conv_I1.cs->The size 2 could not exist, because always is pushed Int32 or Int64!"); case 4: XS.Pop(XSRegisters.EAX); XS.MoveSignExtend(XSRegisters.EAX, XSRegisters.AL); XS.Push(XSRegisters.EAX); break; case 8: XS.Pop(XSRegisters.EAX); XS.Pop(XSRegisters.EBX); XS.MoveSignExtend(XSRegisters.EAX, XSRegisters.AL); XS.Push(XSRegisters.EAX); break; default: //EmitNotImplementedException( Assembler, GetServiceProvider(), "Conv_I1: SourceSize " + xSource + " not supported!", mCurLabel, mMethodInformation, mCurOffset, mNextLabel ); throw new NotImplementedException("Cosmos.IL2CPU.x86->IL->Conv_I1.cs->Unknown size of variable on the top of the stack."); } }
public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode) { var xOpType = (OpType)aOpCode; var xSize = SizeOfType(xOpType.Value); if (xOpType.Value.GetTypeInfo().IsValueType&& !xOpType.Value.GetTypeInfo().IsPrimitive) { Ldelema.Assemble(Assembler, xOpType, xSize, DebugEnabled); Ldobj.DoAssemble(xOpType.Value); return; } Ldelem_Ref.Assemble(Assembler, xSize, false, aMethod, aOpCode, DebugEnabled); }
/// <summary> Draws the parameters of the passed object into the screen </summary> public void drawDebug(object obj, int x, int y) { Type type = obj.GetType(); object classInstance = Activator.CreateInstance(type, null); _MethodInfo methodInfo = type.GetMethod("getAttr"); object[] parametersArray = new object[] { obj }; object result = methodInfo.Invoke(classInstance, parametersArray); Console.SetCursorPosition(x, y); Console.Write(type.Name + (string)result); }
public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode) { var xOp = (OpInt64)aOpCode; // push high part new CPUx86.Push { DestinationValue = BitConverter.ToUInt32(BitConverter.GetBytes(xOp.Value), 4) }; // push low part new CPUx86.Push { DestinationValue = BitConverter.ToUInt32(BitConverter.GetBytes(xOp.Value), 0) }; }
/// <summary> /// Sucht einfach nur die Parameternamen der aktuell übergebenen Methode heraus und setzt noch den passenden Typ /// für TypeScript hinter den Namen z.B.: "alter: number, name: string, ..." /// </summary> public string GetFunctionParametersWithType(_MethodInfo methodInfo) { StringBuilder builder = new StringBuilder(); //Zusammenbauen der PrameterInfos für die übergebene Methode. foreach (ParameterInfo info in methodInfo.GetParameters()) { //Die Parameterliste inkl. des Typen zurückgeben builder.Append(string.Format("{0}: {1}", info.Name, GetTsType(info.ParameterType))).Append(","); } return(builder.ToString().TrimEnd(',')); }
public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode) { #warning TODO: Implement exception DoNullReferenceCheck(Assembler, DebugEnabled, 4); XS.Add(XSRegisters.ESP, 4); XS.Pop(XSRegisters.EAX); new CPUx86.Mov { DestinationRef = Cosmos.Assembler.ElementReference.New(DataMember.GetStaticFieldName(ExceptionHelperRefs.CurrentExceptionRef)), DestinationIsIndirect = true, SourceReg = CPUx86.RegistersEnum.EAX }; XS.Call("SystemExceptionOccurred"); XS.Set(XSRegisters.ECX, 3); Call.EmitExceptionLogic(Assembler, aMethod, aOpCode, false, null); }
public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode) { // destination address XS.Pop(EDI); // source address XS.Pop(ESI); // byte count XS.Pop(ECX); new Movs { Prefixes = InstructionPrefixes.Repeat, Size = 8 }; }
private void DoExecute(Assembler assembler, _MethodInfo aMethod, ILOpCode aOpCode, OpType aTargetType, bool debugEnabled) { var xType = aTargetType.Value; XS.Comment($"Type = {aTargetType.Value}"); if (xType.GetTypeInfo().BaseType == typeof(ValueType)) { } else if (xType.GetTypeInfo().BaseType == typeof(object)) { throw new NotImplementedException($"Constrained not implemented for {aTargetType.Value}"); } }
public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode) { var xSource = aOpCode.StackPopTypes[0]; var xSourceSize = SizeOfType(xSource); var xSourceIsFloat = TypeIsFloat(xSource); if (IsReferenceType(xSource)) { // todo: Stop GC tracking XS.Add(ESP, SizeOfType(typeof(UIntPtr))); // todo: x64 XS.Pop(EAX); XS.Push(0); XS.Push(EAX); } else if (IsByRef(xSource)) { // todo: Stop GC tracking throw new NotImplementedException($"Error compiling '{GetLabel(aMethod)}': conv.u8 not implemented for byref types!"); } else if (xSourceSize <= 4) { if (xSourceIsFloat) { XS.FPU.FloatLoad(ESP, destinationIsIndirect: true, size: RegisterSize.Int32); XS.Sub(ESP, 4); XS.FPU.IntStoreWithTruncate(ESP, isIndirect: true, size: RegisterSize.Long64); } else { XS.Pop(EAX); XS.Push(0); XS.Push(EAX); } } else if (xSourceSize <= 8) { if (xSourceIsFloat) { XS.FPU.FloatLoad(ESP, destinationIsIndirect: true, size: RegisterSize.Long64); /* The sign of the value should not be changed a negative value is simply converted to its corresponding ulong value */ //XS.FPU.FloatAbs(); XS.FPU.IntStoreWithTruncate(ESP, isIndirect: true, size: RegisterSize.Long64); } } else { throw new NotImplementedException("Cosmos.IL2CPU.x86->IL->Conv_U8.cs->Error: StackSize > 8 not supported"); } }
public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode) { var xSource = aOpCode.StackPopTypes[0]; var xSourceSize = SizeOfType(xSource); var xSourceIsFloat = TypeIsFloat(xSource); switch (xSourceSize) { case 1: throw new Exception("Cosmos.IL2CPU.x86->IL->Conv_I8.cs->The size 1 could not exist, because always is pushed Int32 or Int64!"); case 2: throw new Exception("Cosmos.IL2CPU.x86->IL->Conv_I8.cs->The size 2 could not exist, because always is pushed Int32 or Int64!"); case 4: if (xSourceIsFloat) { /* * Sadly for x86 there is no way using SSE to convert a float to an Int64... in x64 we could use ConvertPD2DQAndTruncate with * x64 register as a destination... so this one of the few cases in which we need the legacy FPU! */ XS.FPU.FloatLoad(ESP, destinationIsIndirect: true, size: RegisterSize.Int32); XS.Sub(XSRegisters.ESP, 4); XS.FPU.IntStoreWithTruncate(ESP, isIndirect: true, size: RegisterSize.Long64); } else { XS.Pop(XSRegisters.EAX); XS.SignExtendAX(RegisterSize.Int32); XS.Push(XSRegisters.EDX); XS.Push(XSRegisters.EAX); } break; case 8: if (xSourceIsFloat) { /* * Sadly for x86 there is no way using SSE to convert a double to an Int64... in x64 we could use ConvertPD2DQAndTruncate with * x64 register as a destination... so only in this case we need the legacy FPU! */ XS.FPU.FloatLoad(ESP, destinationIsIndirect: true, size: RegisterSize.Long64); XS.FPU.IntStoreWithTruncate(ESP, isIndirect: true, size: RegisterSize.Long64); } break; default: //EmitNotImplementedException(Assembler, GetServiceProvider(), "Conv_I8: SourceSize " + xSource + " not supported!", mCurLabel, mMethodInformation, mCurOffset, mNextLabel); throw new NotImplementedException(); } }
public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode) { OpType xType = (OpType)aOpCode; string xTypeID = GetTypeIDLabel(xType.Value); string xCurrentMethodLabel = GetLabel(aMethod, aOpCode); string xAfterIsInstanceCallLabel = xCurrentMethodLabel + "_After_IsInstance_Call"; string xReturnNullLabel = xCurrentMethodLabel + "_ReturnNull"; string xNextPositionLabel = GetLabel(aMethod, aOpCode.NextPosition); XS.Set(EAX, ESP, sourceDisplacement: 4); XS.Compare(EAX, 0); XS.Jump(CPUx86.ConditionalTestEnum.Zero, xReturnNullLabel); XS.Push(EAX, isIndirect: true); XS.Push(xTypeID, isIndirect: true); XS.Push(Convert.ToUInt32(xType.Value.IsInterface)); MethodBase xMethodIsInstance = VTablesImplRefs.IsInstanceRef; Call.DoExecute(Assembler, aMethod, xMethodIsInstance, aOpCode, xCurrentMethodLabel, xAfterIsInstanceCallLabel, DebugEnabled); XS.Label(xAfterIsInstanceCallLabel); XS.Pop(EAX); XS.Compare(EAX, 0); XS.Jump(CPUx86.ConditionalTestEnum.Equal, xReturnNullLabel); XS.Jump(xNextPositionLabel); XS.Label(xReturnNullLabel); XS.Add(ESP, 8); //string xAllocInfoLabelName = LabelName.Get( GCImplementationRefs.AllocNewObjectRef ); // TODO: Emit new exceptions //new Newobj( Assembler ).Execute( aMethod, aOpCode ); //Newobj.Assemble( Assembler, // typeof( InvalidCastException ).GetConstructor( new Type[ 0 ] ), // GetService<IMetaDataInfoService>().GetTypeIdLabel( typeof( InvalidCastException ) ), // mThisLabel, // mMethodInfo, // mCurrentILOffset, // mThisLabel + "_After_NewException", // GetService<IMetaDataInfoService>().GetTypeInfo( typeof( InvalidCastException ) ), // GetService<IMetaDataInfoService>().GetMethodInfo( typeof( InvalidCastException ).GetConstructor( new Type[ 0 ] ), false ), // GetServiceProvider(), // xAllocInfo.LabelName ); XS.Label(xCurrentMethodLabel + "_After_NewException"); //Call.EmitExceptionLogic( Assembler, ( uint )mCurrentILOffset, mMethodInfo, mNextOpLabel, false, null ); }
public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode) { var xSource = aOpCode.StackPopTypes[0]; var xSourceSize = SizeOfType(xSource); var xSourceIsFloat = TypeIsFloat(xSource); switch (xSourceSize) { case 1: case 2: case 4: { if (xSourceIsFloat) { XS.SSE.MoveSS(XMM0, ESP, sourceIsIndirect: true); XS.SSE.ConvertSS2SIAndTruncate(EAX, XMM0); XS.Set(ESP, EAX, destinationIsIndirect: true); } break; } case 8: { if (xSourceIsFloat) { XS.SSE2.MoveSD(XMM0, ESP, sourceIsIndirect: true); XS.SSE2.ConvertSD2SIAndTruncate(EAX, XMM0); XS.Set(ESP, EAX, destinationIsIndirect: true); } if (IsReferenceType(xSource)) { XS.Add(ESP, 4); } else { XS.Pop(EAX); XS.Add(ESP, 4); XS.Push(EAX); } break; } default: //EmitNotImplementedException( Assembler, GetServiceProvider(), "Conv_I4: SourceSize " + xSource + " not yet supported!", mCurLabel, mMethodInformation, mCurOffset, mNextLabel ); throw new NotImplementedException(); } }
public void Execute(_MethodInfo aMethod, ILOpCode aOpCode, bool aFromNewObj = false) { Type mType = ((ILOpCodes.OpType)aOpCode).Value; uint mObjSize = SizeOfType(mType); XS.Pop(EAX); for (int i = 0; i < (mObjSize / 4); i++) { XS.Set(EAX, 0, destinationDisplacement: i * 4, size: RegisterSize.Int32); } switch (mObjSize % 4) { case 1: { new CPUx86.Mov { DestinationReg = CPUx86.RegistersEnum.EAX, DestinationIsIndirect = true, DestinationDisplacement = (int)((mObjSize / 4) * 4), SourceValue = 0, Size = 8 }; break; } case 2: { new CPUx86.Mov { DestinationReg = CPUx86.RegistersEnum.EAX, DestinationIsIndirect = true, DestinationDisplacement = (int)((mObjSize / 4) * 4), SourceValue = 0, Size = 16 }; break; } case 3: { new CPUx86.Mov { DestinationReg = CPUx86.RegistersEnum.EAX, DestinationIsIndirect = true, DestinationDisplacement = (int)((mObjSize / 4) * 4), SourceValue = 0, Size = 8 }; new CPUx86.Mov { DestinationReg = CPUx86.RegistersEnum.EAX, DestinationIsIndirect = true, DestinationDisplacement = (int)(((mObjSize / 4) * 4) + 1), SourceValue = 0, Size = 16 }; break; } case 0: break; default: { throw new NotImplementedException("Remainder size " + mObjSize % 4 + " not supported yet! (Type = '" + mType.FullName + "')"); } } }
public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode) { var xOpVar = (OpVar)aOpCode; var xVar = aMethod.MethodBase.GetLocalVariables()[xOpVar.Value]; var xEBPOffset = GetEBPOffsetForLocal(aMethod, xOpVar.Value); xEBPOffset += (uint)(((int)GetStackCountForLocal(aMethod, xVar.Type) - 1) * 4); XS.Comment("Local type = " + xVar.Type); XS.Comment("Local EBP offset = " + xEBPOffset); XS.Set(EAX, EBP); XS.Sub(EAX, xEBPOffset); XS.Push(EAX); }
public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode) { var xType = aOpCode.StackPopTypes[0]; var xSize = SizeOfType(xType); var xIsFloat = TypeIsFloat(xType); if (xIsFloat) { throw new Exception("Cosmos.IL2CPU.x86->IL->Sub_Ovf.cs->Error: Expected signed integer operands but get float!"); } if (xSize > 8) { throw new NotImplementedException("Cosmos.IL2CPU.x86->IL->Sub_Ovf.cs->Error: StackSize > 8 not supported"); } else { var xBaseLabel = GetLabel(aMethod, aOpCode) + "."; var xSuccessLabel = xBaseLabel + "Success"; if (xSize > 4) // long { XS.Pop(EAX); //low part XS.Pop(EDX); //high part XS.Sub(ESP, EAX, destinationIsIndirect: true); XS.SubWithCarry(ESP, EDX, destinationDisplacement: 4); } else //integer { XS.Pop(ECX);//first integer XS.Pop(EAX); //second integer XS.Sub(EAX, ECX); XS.Push(EAX); //push result on stack } // Let's check if we add overflow and if so throw OverflowException XS.Jump(ConditionalTestEnum.NoOverflow, xSuccessLabel); if (xSize > 4) // Hack to stop stack corruption { XS.Add(ESP, 8); } else { XS.Add(ESP, 4); } Call.DoExecute(Assembler, aMethod, typeof(ExceptionHelper).GetMethod("ThrowOverflow", BindingFlags.Static | BindingFlags.Public), aOpCode, GetLabel(aMethod, aOpCode), xSuccessLabel, DebugEnabled); XS.Label(xSuccessLabel); } }
public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode) { var xOpVar = (OpVar)aOpCode; var xVar = aMethod.MethodBase.GetLocalVariables()[xOpVar.Value]; var xStackCount = (int)GetStackCountForLocal(aMethod, xVar.LocalType); var xEBPOffset = (int)GetEBPOffsetForLocal(aMethod, xOpVar.Value); var xSize = SizeOfType(xVar.LocalType); bool xSigned = IsIntegerSigned(xVar.LocalType); XS.Comment("Local type = " + xVar.LocalType); XS.Comment("Local EBP offset = " + xEBPOffset); XS.Comment("Local size = " + xSize); switch (xSize) { case 1: if (xSigned) { XS.MoveSignExtend(EAX, EBP, sourceIsIndirect: true, sourceDisplacement: (0 - xEBPOffset), size: RegisterSize.Byte8); } else { XS.MoveZeroExtend(EAX, EBP, sourceIsIndirect: true, sourceDisplacement: (0 - xEBPOffset), size: RegisterSize.Byte8); } XS.Push(EAX); break; case 2: if (xSigned) { XS.MoveSignExtend(EAX, EBP, sourceIsIndirect: true, sourceDisplacement: (0 - xEBPOffset), size: RegisterSize.Short16); } else { XS.MoveZeroExtend(EAX, EBP, sourceIsIndirect: true, sourceDisplacement: (0 - xEBPOffset), size: RegisterSize.Short16); } XS.Push(EAX); break; default: for (int i = 0; i < xStackCount; i++) { XS.Set(EAX, EBP, sourceDisplacement: 0 - (xEBPOffset + (i * 4))); XS.Push(EAX); } break; } }
public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode) { // TODO overflow check for float var xType = aOpCode.StackPopTypes[0]; var xSize = SizeOfType(xType); var xIsFloat = TypeIsFloat(xType); if (xIsFloat) { throw new Exception("Cosmos.IL2CPU.x86->IL->Add_Ovf_Un.cs->Error: Expected unsigned integer operands but get float!"); } if (xSize > 8) { //EmitNotImplementedException( Assembler, aServiceProvider, "Size '" + xSize.Size + "' not supported (add)", aCurrentLabel, aCurrentMethodInfo, aCurrentOffset, aNextLabel ); throw new NotImplementedException("Cosmos.IL2CPU.x86->IL->Add_Ovf_Un.cs->Error: StackSize > 8 not supported"); } else { var xBaseLabel = GetLabel(aMethod, aOpCode) + "."; var xSuccessLabel = xBaseLabel + "Success"; if (xSize > 4) // long { XS.Pop(EDX); // low part XS.Pop(EAX); // high part XS.Sub(ESP, EDX, destinationIsIndirect: true); XS.SubWithCarry(ESP, EAX, destinationDisplacement: 4); } else //integer { XS.Pop(EAX); XS.Sub(ESP, EAX, destinationIsIndirect: true); } // Let's check if we add overflow and if so throw OverflowException XS.Jump(ConditionalTestEnum.NotCarry, xSuccessLabel); if (xSize > 4) // Hack to stop stack corruption { XS.Add(ESP, 8); } else { XS.Add(ESP, 4); } Call.DoExecute(Assembler, aMethod, typeof(ExceptionHelper).GetMethod("ThrowOverflow", BindingFlags.Static | BindingFlags.Public), aOpCode, GetLabel(aMethod, aOpCode), xSuccessLabel, DebugEnabled); XS.Label(xSuccessLabel); } }
public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode) { var xSource = aOpCode.StackPopTypes[0]; var xSourceSize = SizeOfType(xSource); var xSourceIsFloat = TypeIsFloat(xSource); if (xSourceSize <= 4) { if (xSourceIsFloat) { XS.SSE.ConvertSS2SD(XMM0, ESP, sourceIsIndirect: true); XS.Sub(ESP, 4); XS.SSE2.MoveSD(ESP, XMM0, destinationIsIndirect: true); } else { if (IsIntegerSigned(xSource)) { XS.SSE2.ConvertSI2SD(XMM0, ESP, sourceIsIndirect: true); XS.Sub(ESP, 4); XS.SSE2.MoveSD(ESP, XMM0, destinationIsIndirect: true); } else { throw new NotSupportedException(); } } } else if (xSourceSize <= 8) { if (!xSourceIsFloat) { if (IsIntegerSigned(xSource)) { XS.FPU.IntLoad(ESP, isIndirect: true, size: RegisterSize.Long64); XS.FPU.FloatStoreAndPop(ESP, isIndirect: true, size: RegisterSize.Long64); } else { throw new NotSupportedException(); } } } else { throw new NotImplementedException("Cosmos.IL2CPU.x86->IL->Conv_R8.cs->Error: StackSize > 8 not supported"); } }
public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode) { var xSource = aOpCode.StackPopTypes[0]; var xSourceSize = SizeOfType(xSource); switch (xSourceSize) { case 1: throw new Exception("Cosmos.IL2CPU.x86->IL->Conv_U4.cs->The size 1 could not exist, because always is pushed Int32 or Int64!"); case 2: throw new Exception("Cosmos.IL2CPU.x86->IL->Conv_U4.cs->The size 2 could not exist, because always is pushed Int32 or Int64!"); case 4: if (TypeIsFloat(xSource)) { XS.SSE.MoveSS(XMM0, ESP, sourceIsIndirect: true); XS.SSE.ConvertSS2SIAndTruncate(EAX, XMM0); XS.Set(ESP, EAX, destinationIsIndirect: true); } break; case 8: if (TypeIsFloat(xSource)) { XS.SSE2.MoveSD(XMM0, ESP, sourceIsIndirect: true); XS.SSE2.ConvertSD2SIAndTruncate(EAX, XMM0); // We need to move the stack pointer of 4 Byte to "eat" the second double that is yet in the stack or we get a corrupted stack! XS.Add(ESP, 4); XS.Set(ESP, EAX, destinationIsIndirect: true); // Is this really needed? Conv.U2 and Conv.U1 did not this! In reality they should call the same code... //XS.Push(EAX); break; } else { XS.Pop(EAX); XS.Pop(ECX); XS.Push(EAX); break; } default: //EmitNotImplementedException( Assembler, GetServiceProvider(), "Conv_U4: SourceSize " + xStackItem.Size + " not supported!", mCurLabel, mMethodInformation, mCurOffset, mNextLabel ); throw new NotImplementedException("Cosmos.IL2CPU.x86->IL->Conv_U4.cs->Unknown size of variable on the top of the stack."); } }
public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode) { if (aOpCode.OpCode == ILOpCode.Code.Stind_I8 || aOpCode.OpCode == ILOpCode.Code.Stind_R8 || aOpCode.OpCode == ILOpCode.Code.Stind_Ref) { DoNullReferenceCheck(Assembler, DebugEnabled, 8); } else { DoNullReferenceCheck(Assembler, DebugEnabled, 4); } switch (aOpCode.OpCode) { case ILOpCode.Code.Stind_I1: XS.Pop(ECX); XS.Pop(EAX); XS.Set(EAX, CL, destinationIsIndirect: true); break; case ILOpCode.Code.Stind_I2: XS.Pop(ECX); XS.Pop(EAX); XS.Set(EAX, CX, destinationIsIndirect: true); break; case ILOpCode.Code.Stind_I: case ILOpCode.Code.Stind_I4: case ILOpCode.Code.Stind_R4: XS.Pop(ECX); XS.Pop(EAX); XS.Set(EAX, ECX, destinationIsIndirect: true); break; case ILOpCode.Code.Stind_I8: case ILOpCode.Code.Stind_R8: case ILOpCode.Code.Stind_Ref: XS.Pop(ECX); XS.Pop(EBX); XS.Pop(EAX); XS.Set(EAX, ECX, destinationIsIndirect: true); XS.Set(EAX, EBX, destinationDisplacement: 4); break; } }
public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode) { var xSource = aOpCode.StackPopTypes[0]; var xSourceSize = SizeOfType(xSource); var xSourceIsFloat = TypeIsFloat(xSource); if (xSourceSize <= 4) { if (xSourceIsFloat) { XS.SSE.MoveSS(XMM0, ESP, sourceIsIndirect: true); XS.SSE.ConvertSS2SIAndTruncate(EAX, XMM0); XS.MoveZeroExtend(EAX, AX); XS.Set(ESP, EAX, destinationIsIndirect: true); } else { XS.Pop(EAX); XS.MoveZeroExtend(EAX, AX); XS.Push(EAX); } } else if (xSourceSize <= 8) { if (xSourceIsFloat) { XS.SSE2.MoveSD(XMM0, ESP, sourceIsIndirect: true); XS.Add(ESP, 4); XS.SSE2.ConvertSD2SIAndTruncate(EAX, XMM0); XS.MoveZeroExtend(EAX, AX); XS.Set(ESP, EAX, destinationIsIndirect: true); } else { XS.Pop(EAX); XS.Add(ESP, 4); XS.MoveZeroExtend(EAX, AX); XS.Push(EAX); } } else { throw new NotImplementedException("Cosmos.IL2CPU.x86->IL->Conv_U2.cs->Error: StackSize > 8 not supported"); } }
public static void DoExecute(XSharp.Assembler.Assembler Assembler, _MethodInfo aMethod, ushort aParam) { var xDisplacement = Ldarg.GetArgumentDisplacement(aMethod, aParam); /* * The function GetArgumentDisplacement() does not give the correct displacement for the Ldarga opcode * we need to "fix" it subtracting the argSize and 4 */ Type xArgType; if (aMethod.MethodBase.IsStatic) { xArgType = aMethod.MethodBase.GetParameters()[aParam].ParameterType; } else { if (aParam == 0u) { xArgType = aMethod.MethodBase.DeclaringType; if (xArgType.IsValueType) { xArgType = xArgType.MakeByRefType(); } } else { xArgType = aMethod.MethodBase.GetParameters()[aParam - 1].ParameterType; } } uint xArgRealSize = SizeOfType(xArgType); uint xArgSize = Align(xArgRealSize, 4); XS.Comment("Arg idx = " + aParam); XS.Comment("Arg type = " + xArgType); XS.Comment("Arg real size = " + xArgRealSize + " aligned size = " + xArgSize); xDisplacement -= (int)(xArgSize - 4); XS.Comment("Real displacement " + xDisplacement); XS.Set(EAX, EBP); XS.Set(EBX, (uint)(xDisplacement)); XS.Add(EAX, EBX); XS.Push(EAX); }
public static void DoExecute(Cosmos.Assembler.Assembler assembler, _MethodInfo aMethod, string field, Type declaringType, ILOpCode aCurrentOpCode) { // call cctor: var xCctor = (declaringType.GetConstructors(BindingFlags.Static | BindingFlags.NonPublic) ?? new ConstructorInfo[0]).SingleOrDefault(); if (xCctor != null) { XS.Call(LabelName.Get(xCctor)); if (aCurrentOpCode != null) { ILOp.EmitExceptionLogic(assembler, aMethod, aCurrentOpCode, true, null, ".AfterCCTorExceptionCheck"); XS.Label(".AfterCCTorExceptionCheck"); } } string xDataName = field; XS.Push(xDataName); }