From 2b66b951eebe480d54e0dbfbe991d33b00cd1d01 Mon Sep 17 00:00:00 2001 From: Trivalik_cp <42497cfff885d3ca0e6fda54fb6262dd42101bd5sx56jUzf> Date: Sun, 12 Jun 2011 22:59:42 +0000 Subject: [PATCH] add Conv_Ovf_I_Un implementation fix wrong type in newobj fix math.sqrt --- .../Cosmos.IL2CPU.X86/IL/Conv_Ovf_I_Un.cs | 43 ++++++++++++++++--- source2/IL2CPU/Cosmos.IL2CPU.X86/IL/Newobj.cs | 19 ++++---- .../Core/Cosmos.Core.Plugs/MathImpl.cs | 6 +-- 3 files changed, 48 insertions(+), 20 deletions(-) diff --git a/source2/IL2CPU/Cosmos.IL2CPU.X86/IL/Conv_Ovf_I_Un.cs b/source2/IL2CPU/Cosmos.IL2CPU.X86/IL/Conv_Ovf_I_Un.cs index 3233af76c..2e5e4e36e 100644 --- a/source2/IL2CPU/Cosmos.IL2CPU.X86/IL/Conv_Ovf_I_Un.cs +++ b/source2/IL2CPU/Cosmos.IL2CPU.X86/IL/Conv_Ovf_I_Un.cs @@ -1,18 +1,49 @@ using System; - +using CPUx86 = Cosmos.Compiler.Assembler.X86; +using Label = Cosmos.Compiler.Assembler.Label; namespace Cosmos.IL2CPU.X86.IL { [Cosmos.IL2CPU.OpCode(ILOpCode.Code.Conv_Ovf_I_Un)] public class Conv_Ovf_I_Un: ILOp { - public Conv_Ovf_I_Un(Cosmos.Compiler.Assembler.Assembler aAsmblr):base(aAsmblr) + public Conv_Ovf_I_Un(Cosmos.Compiler.Assembler.Assembler aAsmblr) + :base(aAsmblr) { } - public override void Execute(MethodInfo aMethod, ILOpCode aOpCode) { - ThrowNotImplementedException("Conv_Ovf_I_Un not implemented!"); - } + public override void Execute(MethodInfo aMethod, ILOpCode aOpCode) { + //TODO: What if the last ILOp in a method was Conv_Ovf_I_Un or an other? + var xSource = Assembler.Stack.Pop(); + if(xSource.IsFloat) + ThrowNotImplementedException("Conv_Ovf_I_Un throws an ArgumentException, because float is not implemented!"); + switch (xSource.Size) + { + case 1: + case 2: + case 4: + break; + case 8: + { + string NoOverflowLabel = GetLabel(aMethod, aOpCode) + "__NoOverflow"; + new CPUx86.Pop { DestinationReg = CPUx86.Registers.EAX }; + // EBX is high part and should be zero for unsigned, so we test it on zero + { + new CPUx86.Pop { DestinationReg = CPUx86.Registers.EBX }; + new CPUx86.Compare { DestinationReg = CPUx86.Registers.EBX, SourceValue = 0 }; + new CPUx86.ConditionalJump { Condition = CPUx86.ConditionalTestEnum.Equal, DestinationLabel = NoOverflowLabel }; + ThrowNotImplementedException("Conv_Ovf_I_Un throws an overflow exception, which is not implemented!"); + } + new Label(NoOverflowLabel); + new CPUx86.Push { DestinationReg = CPUx86.Registers.EAX }; + break; + } + default: + ThrowNotImplementedException("Conv_Ovf_I_Un not implemented for this size!"); + break; + } + Assembler.Stack.Push(4, typeof(uint)); + } // using System; // using System.IO; @@ -77,4 +108,4 @@ namespace Cosmos.IL2CPU.X86.IL // } } -} +} \ No newline at end of file diff --git a/source2/IL2CPU/Cosmos.IL2CPU.X86/IL/Newobj.cs b/source2/IL2CPU/Cosmos.IL2CPU.X86/IL/Newobj.cs index 50288ac87..82add88a4 100644 --- a/source2/IL2CPU/Cosmos.IL2CPU.X86/IL/Newobj.cs +++ b/source2/IL2CPU/Cosmos.IL2CPU.X86/IL/Newobj.cs @@ -105,15 +105,14 @@ namespace Cosmos.IL2CPU.X86.IL new CPUx86.Move { DestinationReg = CPUx86.Registers.EAX, DestinationIsIndirect = true, DestinationDisplacement = 4, SourceValue = (uint)InstanceTypeEnum.NormalObject, Size = 32 }; new CPUx86.Move { DestinationReg = CPUx86.Registers.EAX, DestinationIsIndirect = true, DestinationDisplacement = 8, SourceValue = (uint)xGCFieldCount, Size = 32 }; uint xSize = (uint)(((from item in xParams - let xQSize = Align(SizeOfType(item.GetType()), 4) + let xQSize = Align(SizeOfType(item.ParameterType), 4) select (int)xQSize).Take(xParams.Length).Sum())); foreach (var xParam in xParams) { - uint xParamSize = SizeOfType(xParams.GetType()); + uint xParamSize = Align(SizeOfType(xParam.ParameterType), 4); new Comment(aAssembler, String.Format("Arg {0}: {1}", xParam.Name, xParamSize)); - for (int i = 0; i < xParamSize; i += 4) - { + for (int i = 0; i < xParamSize; i += 4) { new CPUx86.Push { DestinationReg = CPUx86.Registers.ESP, DestinationIsIndirect = true, DestinationDisplacement = (int)(xSize + 4) }; } } @@ -145,9 +144,8 @@ namespace Cosmos.IL2CPU.X86.IL //} uint xESPOffset = 0; - foreach (var xParam in xParams) - { - xESPOffset += SizeOfType(xParams.GetType()); + foreach (var xParam in xParams) { + xESPOffset += Align(SizeOfType(xParam.ParameterType), 4); } new CPUx86.Add { DestinationReg = CPUx86.Registers.ESP, SourceValue = xESPOffset }; @@ -195,7 +193,7 @@ namespace Cosmos.IL2CPU.X86.IL //uint xArgSize = 0; var xParams = constructor.GetParameters(); uint xArgSize = (uint)(((from item in xParams.Skip(1) - let xQSize = Align(SizeOfType(item.GetType()), 4) + let xQSize = Align(SizeOfType(item.ParameterType), 4) select (int)xQSize).Take(xParams.Length - 1).Sum())); //foreach( var xArg in aCtorMethodInfo.Arguments.Skip( 1 ) ) @@ -209,8 +207,7 @@ namespace Cosmos.IL2CPU.X86.IL { xExtraArgSize = 0; } - if (xExtraArgSize > 0) - { + if (xExtraArgSize > 0) { new CPUx86.Sub { DestinationReg = CPUx86.Registers.ESP, SourceValue = (uint)xExtraArgSize }; } new CPUx86.Push { DestinationReg = CPUx86.Registers.ESP }; @@ -241,7 +238,7 @@ namespace Cosmos.IL2CPU.X86.IL new Comment("[ Newobj.PushAlignedParameterSize start count = " + xParams.Length.ToString() + " ]" ); for( int i = 0; i < xParams.Length; i++ ) { - xSize = SizeOfType( xParams[ i ].GetType() ); + xSize = SizeOfType( xParams[ i ].ParameterType ); new CPUx86.Add { DestinationReg = CPUx86.Registers.ESP, SourceValue = Align( xSize, 4 ) }; } new Comment("[ Newobj.PushAlignedParameterSize end ]" ); diff --git a/source2/Kernel/System/Hardware/Core/Cosmos.Core.Plugs/MathImpl.cs b/source2/Kernel/System/Hardware/Core/Cosmos.Core.Plugs/MathImpl.cs index 32f4c24be..e79a0e869 100644 --- a/source2/Kernel/System/Hardware/Core/Cosmos.Core.Plugs/MathImpl.cs +++ b/source2/Kernel/System/Hardware/Core/Cosmos.Core.Plugs/MathImpl.cs @@ -19,10 +19,10 @@ namespace Cosmos.Core.Plugs { new CPUx86.x87.FloatLoad { DestinationReg = CPUx86.Registers.EBP, Size = 64, DestinationIsIndirect = true, DestinationDisplacement = 8 }; new CPUx86.x87.FloatSqrt{ }; - // reservate 8 byte for double on stack - new CPUx86.Sub { DestinationReg = CPUx86.Registers.ESP, SourceValue = unchecked((uint)-8) }; + // reservate 8 byte for returntype double on stack + new CPUx86.Sub { DestinationReg = CPUx86.Registers.ESP, SourceValue = 8 }; // write double value to this reservation - new CPUx86.x87.FloatStoreAndPop { DestinationReg = CPUx86.Registers.EBP, Size = 64, DestinationIsIndirect = true, DestinationDisplacement = 8 }; + new CPUx86.x87.FloatStoreAndPop { DestinationReg = CPUx86.Registers.ESP, Size = 64, DestinationIsIndirect = true }; // after this is the result popped } }