diff --git a/Source/Data/IR-Optimizations-LowerTo32.json b/Source/Data/IR-Optimizations-LowerTo32.json new file mode 100644 index 0000000000..13c8b7e445 --- /dev/null +++ b/Source/Data/IR-Optimizations-LowerTo32.json @@ -0,0 +1,38 @@ +{ + "Family": "IR", + "Section": "Optimizations.Auto", + "Commutative": [ + "IR.Add32", + "IR.Add64", + "IR.AddR4", + "IR.AddR8", + "IR.And32", + "IR.And64", + "IR.Or32", + "IR.Or64", + "IR.Xor32", + "IR.Xor64", + "IR.MulR4", + "IR.MulR8", + "IR.MulUnsigned32", + "IR.MulUnsigned64", + "IR.MulSigned32", + "IR.MulSigned64", + "IR.AddCarryOut64", + "IR.AddCarryOut32", + "IR.AddCarryIn32", + "IR.AddCarryIn64" + ], + "Optimizations": [ + { + "Type": "LowerTo32", + "Name": "Or32Truncate64x32Truncate64x32", + "SubName": "", + "Expression": "IR.Or32 (IR.Truncate64x32 x) (IR.Truncate64x32 y)", + "Filter": "", + "Prefilter": "Is32BitPlatform(@) && IsLowerTo32(@)", + "Result": "(IR.GetLow32 (IR.Or64 x y))", + "Variations": "No" + } + ] +} diff --git a/Source/Data/IR-Optimizations-Simplification.json b/Source/Data/IR-Optimizations-Simplification.json index 64d91c5c2b..c54bf7de8c 100644 --- a/Source/Data/IR-Optimizations-Simplification.json +++ b/Source/Data/IR-Optimizations-Simplification.json @@ -443,15 +443,6 @@ "Result": "(IR.SignExtend16x## (IR.Or## x y))", "Variations": "Yes" }, - { - "Type": "Simplification", - "Name": "Or32Truncate64x32Truncate64x32", - "SubName": "", - "Expression": "IR.Or32 (IR.Truncate64x32 x) (IR.Truncate64x32 y)", - "Filter": "", - "Result": "(IR.GetLow32 (IR.Or64 x y))", - "Variations": "No" - }, { "Type": "Simplification", "Name": "SignExtend32x64Truncate64x32", diff --git a/Source/Data/X64-Instructions.json b/Source/Data/X64-Instructions.json index b49bd8bedf..c7de0f31b7 100644 --- a/Source/Data/X64-Instructions.json +++ b/Source/Data/X64-Instructions.json @@ -735,7 +735,7 @@ "OpcodeEncoding": [ { "Condition": "", - "Encoding": "[x64-rex32],opcode=0xF2,opcode2=0x0F,opcode3=0x5A,mod=11,reg=reg3:o1,rm=reg3:o2,rex.r=reg4x:o1,rex.x=0,rex.b=reg4x:o1" + "Encoding": "[x64-rex32],opcode=0xF2,opcode2=0x0F,opcode3=0x5A,mod=11,reg=reg3:r,rm=reg3:o1,rex.r=reg4x:r,rex.x=0,rex.b=reg4x:o1" } ] }, diff --git a/Source/Mosa.BareMetal.HelloWorld.x86/Boot.cs b/Source/Mosa.BareMetal.HelloWorld.x86/Boot.cs index e1421d1b45..43afd7e8c3 100644 --- a/Source/Mosa.BareMetal.HelloWorld.x86/Boot.cs +++ b/Source/Mosa.BareMetal.HelloWorld.x86/Boot.cs @@ -133,7 +133,7 @@ public static void Main() // var fatFileStream = new FatFileStream(fat, location); - // uint len = (uint)fatFileStream.Length; + // var len = (uint)fatFileStream.Length; // Console.WriteLine(" - Length: " + len + " bytes"); diff --git a/Source/Mosa.Compiler.Framework/MethodCompiler.cs b/Source/Mosa.Compiler.Framework/MethodCompiler.cs index 2373da3e48..a9beac2347 100644 --- a/Source/Mosa.Compiler.Framework/MethodCompiler.cs +++ b/Source/Mosa.Compiler.Framework/MethodCompiler.cs @@ -335,6 +335,7 @@ public void Compile() private void LogException(Exception exception, string title) { Compiler.PostEvent(CompilerEvent.Exception, title); + Compiler.PostEvent(CompilerEvent.Exception, exception.ToString()); var exceptionLog = new TraceLog(TraceType.MethodDebug, Method, "Exception", MethodData.Version); diff --git a/Source/Mosa.Compiler.Framework/Stages/CILDecoderStage.cs b/Source/Mosa.Compiler.Framework/Stages/CILDecoderStage.cs index 16b25adc16..d201c64fb4 100644 --- a/Source/Mosa.Compiler.Framework/Stages/CILDecoderStage.cs +++ b/Source/Mosa.Compiler.Framework/Stages/CILDecoderStage.cs @@ -1849,6 +1849,13 @@ private bool Compare(Context context, Stack stack, ConditionCode con context.AppendInstruction(IRInstruction.Compare64x32, conditionCode, result, entry1.Operand, entry2.Operand); return true; + case PrimitiveType.Int64 when entry2.PrimitiveType == PrimitiveType.Int32: + var v1 = MethodCompiler.VirtualRegisters.Allocate64(); + + context.AppendInstruction(IRInstruction.ZeroExtend32x64, v1, entry2.Operand); + context.AppendInstruction(IRInstruction.Compare64x32, conditionCode, result, entry1.Operand, v1); + return true; + default: // TODO: Managed Pointers diff --git a/Source/Mosa.Compiler.Framework/TransformContext.cs b/Source/Mosa.Compiler.Framework/TransformContext.cs index f2aa7ccee0..917cfec79c 100644 --- a/Source/Mosa.Compiler.Framework/TransformContext.cs +++ b/Source/Mosa.Compiler.Framework/TransformContext.cs @@ -32,7 +32,7 @@ public sealed class TransformContext public BasicBlocks BasicBlocks { get; set; } - public bool LowerTo32 { get; private set; } + public bool IsLowerTo32 { get; private set; } public bool IsInSSAForm { get; private set; } @@ -125,12 +125,10 @@ public void SetCompiler(Compiler compiler) Is32BitPlatform = Compiler.Architecture.Is32BitPlatform; TypeSystem = Compiler.TypeSystem; - LowerTo32 = Compiler.MosaSettings.LongExpansion; + IsLowerTo32 = Compiler.MosaSettings.LongExpansion; Devirtualization = Compiler.MosaSettings.Devirtualization; Window = Math.Max(Compiler.MosaSettings.OptimizationBasicWindow, 1); - LowerTo32 = Compiler.MosaSettings.LongExpansion; - LoadInstruction = Is32BitPlatform ? IRInstruction.Load32 : IRInstruction.Load64; StoreInstruction = Is32BitPlatform ? IRInstruction.Store32 : IRInstruction.Store64; MoveInstruction = Is32BitPlatform ? IRInstruction.Move32 : IRInstruction.Move64; @@ -153,7 +151,7 @@ public void SetMethodCompiler(MethodCompiler methodCompiler) AreCPURegistersAllocated = methodCompiler.AreCPURegistersAllocated; IsInSSAForm = methodCompiler.IsInSSAForm; - LowerTo32 = false; + IsLowerTo32 = false; TraceLog = null; Managers.Clear(); @@ -162,7 +160,7 @@ public void SetMethodCompiler(MethodCompiler methodCompiler) public void SetStageOptions(bool lowerTo32) { - LowerTo32 = Compiler.MosaSettings.LongExpansion && lowerTo32 && Is32BitPlatform; + IsLowerTo32 = Compiler.MosaSettings.LongExpansion && lowerTo32 && Is32BitPlatform; } #region Manager diff --git a/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/ArithShiftRight64By32.cs b/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/ArithShiftRight64By32.cs index b7d39321a1..df27fc2848 100644 --- a/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/ArithShiftRight64By32.cs +++ b/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/ArithShiftRight64By32.cs @@ -10,7 +10,7 @@ public ArithShiftRight64By32() : base(IRInstruction.ArithShiftRight64, Transform public override bool Match(Context context, TransformContext transform) { - return transform.LowerTo32 && context.Operand2.IsResolvedConstant && context.Operand2.ConstantUnsigned32 == 32; + return transform.IsLowerTo32 && context.Operand2.IsResolvedConstant && context.Operand2.ConstantUnsigned32 == 32; } public override void Transform(Context context, TransformContext transform) diff --git a/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/BaseLower32Transform.cs b/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/BaseLower32Transform.cs index 3e0b8eb621..9622def0d5 100644 --- a/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/BaseLower32Transform.cs +++ b/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/BaseLower32Transform.cs @@ -12,7 +12,7 @@ public BaseLower32Transform(BaseInstruction instruction, TransformType type, boo public override bool Match(Context context, TransformContext transform) { - return transform.LowerTo32; + return transform.IsLowerTo32; } } } diff --git a/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/Branch64.cs b/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/Branch64.cs index 93159bc891..94236773fc 100644 --- a/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/Branch64.cs +++ b/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/Branch64.cs @@ -18,7 +18,7 @@ public override bool Match(Context context, TransformContext transform) if (branch64Extends.Match(context, transform)) return false; - return transform.LowerTo32; + return transform.IsLowerTo32; } public override void Transform(Context context, TransformContext transform) diff --git a/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/Branch64Extends.cs b/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/Branch64Extends.cs index 517c075193..0bc51c9ce7 100644 --- a/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/Branch64Extends.cs +++ b/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/Branch64Extends.cs @@ -10,7 +10,7 @@ public Branch64Extends() : base(IRInstruction.Branch64, TransformType.Manual | T public override bool Match(Context context, TransformContext transform) { - if (!transform.LowerTo32) + if (!transform.IsLowerTo32) return false; if (!context.Operand1.IsVirtualRegister) diff --git a/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/Compare64x32EqualOrNotEqual.cs b/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/Compare64x32EqualOrNotEqual.cs index ec7e800480..9b57e4c27a 100644 --- a/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/Compare64x32EqualOrNotEqual.cs +++ b/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/Compare64x32EqualOrNotEqual.cs @@ -13,7 +13,7 @@ public override bool Match(Context context, TransformContext transform) if (context.ConditionCode != ConditionCode.Equal && context.ConditionCode != ConditionCode.NotEqual) return false; - return transform.LowerTo32; + return transform.IsLowerTo32; } public override void Transform(Context context, TransformContext transform) diff --git a/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/Compare64x32Rest.cs b/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/Compare64x32Rest.cs index d8d6bb3be7..13a35b302d 100644 --- a/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/Compare64x32Rest.cs +++ b/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/Compare64x32Rest.cs @@ -18,7 +18,7 @@ public override bool Match(Context context, TransformContext transform) if (transform.IsInSSAForm) return false; - return transform.LowerTo32; + return transform.IsLowerTo32; } public override void Transform(Context context, TransformContext transform) diff --git a/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/Compare64x32RestInSSA.cs b/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/Compare64x32RestInSSA.cs index 15d99bc297..c9cc733048 100644 --- a/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/Compare64x32RestInSSA.cs +++ b/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/Compare64x32RestInSSA.cs @@ -18,7 +18,7 @@ public override bool Match(Context context, TransformContext transform) if (!transform.IsInSSAForm) return false; - return transform.LowerTo32; + return transform.IsLowerTo32; } public override void Transform(Context context, TransformContext transform) diff --git a/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/Compare64x32UnsignedGreater.cs b/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/Compare64x32UnsignedGreater.cs index b3c8c6af11..d0b53a4bbf 100644 --- a/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/Compare64x32UnsignedGreater.cs +++ b/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/Compare64x32UnsignedGreater.cs @@ -14,7 +14,7 @@ public override bool Match(Context context, TransformContext transform) if (context.ConditionCode != ConditionCode.UnsignedGreater) return false; - return transform.LowerTo32; + return transform.IsLowerTo32; } public override void Transform(Context context, TransformContext transform) diff --git a/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/Compare64x64EqualOrNotEqual.cs b/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/Compare64x64EqualOrNotEqual.cs index 43b4460d12..d7d1788dc6 100644 --- a/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/Compare64x64EqualOrNotEqual.cs +++ b/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/Compare64x64EqualOrNotEqual.cs @@ -13,7 +13,7 @@ public override bool Match(Context context, TransformContext transform) if (context.ConditionCode != ConditionCode.Equal && context.ConditionCode != ConditionCode.NotEqual) return false; - return transform.LowerTo32; + return transform.IsLowerTo32; } public override void Transform(Context context, TransformContext transform) diff --git a/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/Compare64x64Rest.cs b/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/Compare64x64Rest.cs index 3f6dda4cf5..f72567636e 100644 --- a/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/Compare64x64Rest.cs +++ b/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/Compare64x64Rest.cs @@ -18,7 +18,7 @@ public override bool Match(Context context, TransformContext transform) if (transform.IsInSSAForm) return false; - return transform.LowerTo32; + return transform.IsLowerTo32; } public override void Transform(Context context, TransformContext transform) diff --git a/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/Compare64x64RestInSSA.cs b/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/Compare64x64RestInSSA.cs index 1d093cb2a3..0ac5fcf852 100644 --- a/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/Compare64x64RestInSSA.cs +++ b/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/Compare64x64RestInSSA.cs @@ -18,7 +18,7 @@ public override bool Match(Context context, TransformContext transform) if (!transform.IsInSSAForm) return false; - return transform.LowerTo32; + return transform.IsLowerTo32; } public override void Transform(Context context, TransformContext transform) diff --git a/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/ShiftLeft64ByConstant32.cs b/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/ShiftLeft64ByConstant32.cs index f8a2c66116..9b36f5cd71 100644 --- a/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/ShiftLeft64ByConstant32.cs +++ b/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/ShiftLeft64ByConstant32.cs @@ -10,7 +10,7 @@ public ShiftLeft64ByConstant32() : base(IRInstruction.ShiftLeft64, TransformType public override bool Match(Context context, TransformContext transform) { - return transform.LowerTo32 && context.Operand2.IsResolvedConstant && context.Operand2.ConstantUnsigned32 <= 32; + return transform.IsLowerTo32 && context.Operand2.IsResolvedConstant && context.Operand2.ConstantUnsigned32 <= 32; } public override void Transform(Context context, TransformContext transform) diff --git a/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/ShiftLeft64ByConstant32Plus.cs b/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/ShiftLeft64ByConstant32Plus.cs index b2d77a26ec..6adea41f7d 100644 --- a/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/ShiftLeft64ByConstant32Plus.cs +++ b/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/ShiftLeft64ByConstant32Plus.cs @@ -10,7 +10,7 @@ public ShiftLeft64ByConstant32Plus() : base(IRInstruction.ShiftLeft64, Transform public override bool Match(Context context, TransformContext transform) { - return transform.LowerTo32 && context.Operand2.IsResolvedConstant && context.Operand2.ConstantUnsigned32 > 32; + return transform.IsLowerTo32 && context.Operand2.IsResolvedConstant && context.Operand2.ConstantUnsigned32 > 32; } public override void Transform(Context context, TransformContext transform) diff --git a/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/ShiftRight64ByConstant32.cs b/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/ShiftRight64ByConstant32.cs index 64da55fdc9..f6f9f42735 100644 --- a/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/ShiftRight64ByConstant32.cs +++ b/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/ShiftRight64ByConstant32.cs @@ -10,7 +10,7 @@ public ShiftRight64ByConstant32() : base(IRInstruction.ShiftRight64, TransformTy public override bool Match(Context context, TransformContext transform) { - return transform.LowerTo32 && context.Operand2.IsResolvedConstant && context.Operand2.ConstantUnsigned32 <= 32; + return transform.IsLowerTo32 && context.Operand2.IsResolvedConstant && context.Operand2.ConstantUnsigned32 <= 32; } public override void Transform(Context context, TransformContext transform) diff --git a/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/ShiftRight64ByConstant32Plus.cs b/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/ShiftRight64ByConstant32Plus.cs index 06f67077b5..bec1fd1e9d 100644 --- a/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/ShiftRight64ByConstant32Plus.cs +++ b/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/ShiftRight64ByConstant32Plus.cs @@ -10,7 +10,7 @@ public ShiftRight64ByConstant32Plus() : base(IRInstruction.ShiftRight64, Transfo public override bool Match(Context context, TransformContext transform) { - return transform.LowerTo32 && context.Operand2.IsResolvedConstant && context.Operand2.ConstantUnsigned32 > 32; + return transform.IsLowerTo32 && context.Operand2.IsResolvedConstant && context.Operand2.ConstantUnsigned32 > 32; } public override void Transform(Context context, TransformContext transform) diff --git a/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/SignExtend16x64.cs b/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/SignExtend16x64.cs index 862ba275a6..f1f33c4513 100644 --- a/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/SignExtend16x64.cs +++ b/Source/Mosa.Compiler.Framework/Transforms/LowerTo32/SignExtend16x64.cs @@ -10,7 +10,7 @@ public SignExtend16x64() : base(IRInstruction.SignExtend16x64, TransformType.Man public override bool Match(Context context, TransformContext transform) { - return transform.LowerTo32; + return transform.IsLowerTo32; } public override void Transform(Context context, TransformContext transform) diff --git a/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Auto/AutoTransforms.cs b/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Auto/AutoTransforms.cs index c7a01f98df..da7fe917c9 100644 --- a/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Auto/AutoTransforms.cs +++ b/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Auto/AutoTransforms.cs @@ -286,7 +286,6 @@ public static class AutoTransforms new Simplification.Or32SignExtend16x32SignExtend16x32_v1(), new Simplification.Or64SignExtend16x64SignExtend16x64(), new Simplification.Or64SignExtend16x64SignExtend16x64_v1(), - new Simplification.Or32Truncate64x32Truncate64x32(), new Simplification.SignExtend32x64Truncate64x32(), new StrengthReduction.Add32Zero(), new StrengthReduction.Add32Zero_v1(), @@ -771,6 +770,7 @@ public static class AutoTransforms new Simplification.Xor32Max_v1(), new Simplification.Xor64Max(), new Simplification.Xor64Max_v1(), + new LowerTo32.Or32Truncate64x32Truncate64x32(), new Algebraic.Signed32AAPlusBBPlus2AB(), new Algebraic.Signed32AAPlusBBPlus2AB_v1(), new Algebraic.Signed32AAPlusBBPlus2AB_v2(), diff --git a/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Auto/Simplification/Or32Truncate64x32Truncate64x32.cs b/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Auto/LowerTo32/Or32Truncate64x32Truncate64x32.cs similarity index 89% rename from Source/Mosa.Compiler.Framework/Transforms/Optimizations/Auto/Simplification/Or32Truncate64x32Truncate64x32.cs rename to Source/Mosa.Compiler.Framework/Transforms/Optimizations/Auto/LowerTo32/Or32Truncate64x32Truncate64x32.cs index 4806366ae4..7d5dc558d6 100644 --- a/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Auto/Simplification/Or32Truncate64x32Truncate64x32.cs +++ b/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Auto/LowerTo32/Or32Truncate64x32Truncate64x32.cs @@ -4,12 +4,12 @@ using Mosa.Compiler.Framework; -namespace Mosa.Compiler.Framework.Transforms.Optimizations.Auto.Simplification; +namespace Mosa.Compiler.Framework.Transforms.Optimizations.Auto.LowerTo32; /// /// Or32Truncate64x32Truncate64x32 /// -[Transform("IR.Optimizations.Auto.Simplification")] +[Transform("IR.Optimizations.Auto.LowerTo32")] public sealed class Or32Truncate64x32Truncate64x32 : BaseTransform { public Or32Truncate64x32Truncate64x32() : base(IRInstruction.Or32, TransformType.Auto | TransformType.Optimization) @@ -18,6 +18,12 @@ public Or32Truncate64x32Truncate64x32() : base(IRInstruction.Or32, TransformType public override bool Match(Context context, TransformContext transform) { + if (!transform.Is32BitPlatform) + return false; + + if (!transform.IsLowerTo32) + return false; + if (!context.Operand1.IsVirtualRegister) return false; diff --git a/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Manual/Special/GetLow32CPURegister.cs b/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Manual/Special/GetLow32CPURegister.cs index e2576efcc7..6afd5adb5b 100644 --- a/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Manual/Special/GetLow32CPURegister.cs +++ b/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Manual/Special/GetLow32CPURegister.cs @@ -16,7 +16,7 @@ public override bool Match(Context context, TransformContext transform) if (!transform.Is32BitPlatform) return false; - if (!transform.LowerTo32) + if (!transform.IsLowerTo32) return false; if (!context.Operand1.IsCPURegister) diff --git a/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Manual/Special/GetLow32From64.cs b/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Manual/Special/GetLow32From64.cs index 105d1b6d00..4d2f00985f 100644 --- a/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Manual/Special/GetLow32From64.cs +++ b/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Manual/Special/GetLow32From64.cs @@ -16,7 +16,7 @@ public override bool Match(Context context, TransformContext transform) if (!transform.Is32BitPlatform) return false; - if (!transform.LowerTo32) + if (!transform.IsLowerTo32) return false; if (!context.Operand1.IsVirtualRegister) diff --git a/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Manual/Special/StoreLoad32.cs b/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Manual/Special/StoreLoad32.cs index 19791fb3b0..795ddebf9f 100644 --- a/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Manual/Special/StoreLoad32.cs +++ b/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Manual/Special/StoreLoad32.cs @@ -19,7 +19,7 @@ public override bool Match(Context context, TransformContext transform) if (context.Operand1 != transform.StackFrame) return false; - if (context.Operand2.Uses.Count != 2) + if (context.Operand2.Uses.Count != 2) // FUTURE: traverse all uses return false; if (!(context.Operand3.IsConstant || context.Operand3.IsDefinedOnce)) diff --git a/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Manual/Special/StoreLoad64.cs b/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Manual/Special/StoreLoad64.cs index 9c2ecffb39..1445864787 100644 --- a/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Manual/Special/StoreLoad64.cs +++ b/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Manual/Special/StoreLoad64.cs @@ -19,6 +19,9 @@ public override bool Match(Context context, TransformContext transform) if (context.Operand1 != transform.StackFrame) return false; + if (context.Operand2.Uses.Count != 2) // FUTURE: traverse all uses + return false; + if (!(context.Operand3.IsConstant || context.Operand3.IsDefinedOnce)) return false; diff --git a/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Manual/Special/StoreLoadManagedPointer.cs b/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Manual/Special/StoreLoadManagedPointer.cs index 97bbfc521e..13cfc361ba 100644 --- a/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Manual/Special/StoreLoadManagedPointer.cs +++ b/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Manual/Special/StoreLoadManagedPointer.cs @@ -19,7 +19,7 @@ public override bool Match(Context context, TransformContext transform) if (context.Operand1 != transform.StackFrame) return false; - if (context.Operand2.Uses.Count != 2) + if (context.Operand2.Uses.Count != 2) // FUTURE: traverse all uses return false; if (!context.Operand3.IsDefinedOnce) diff --git a/Source/Mosa.Korlib/System.Threading/Interlocked.cs b/Source/Mosa.Korlib/System.Threading/Interlocked.cs index 7f84be0647..6c3b582560 100644 --- a/Source/Mosa.Korlib/System.Threading/Interlocked.cs +++ b/Source/Mosa.Korlib/System.Threading/Interlocked.cs @@ -47,12 +47,8 @@ public static long Decrement(ref long location) [MethodImplAttribute(MethodImplOptions.InternalCall)] public static extern int CompareExchange(ref int location1, int value, int comparand); - //[MethodImplAttribute(MethodImplOptions.InternalCall)] - //public static extern long CompareExchange(ref long location1, long value, long comparand); - public static long CompareExchange(ref long location1, long value, long comparand) - { - return 0; //temp - } + [MethodImplAttribute(MethodImplOptions.InternalCall)] + public static extern long CompareExchange(ref long location1, long value, long comparand); [MethodImplAttribute(MethodImplOptions.InternalCall)] public static extern float CompareExchange(ref float location1, float value, float comparand); diff --git a/Source/Mosa.Platform.x64/Architecture.cs b/Source/Mosa.Platform.x64/Architecture.cs index 57e26d65fd..c559b36cb8 100644 --- a/Source/Mosa.Platform.x64/Architecture.cs +++ b/Source/Mosa.Platform.x64/Architecture.cs @@ -265,15 +265,11 @@ public override void InsertLoadInstruction(Context context, Operand destination, /// The source. public override void InsertExchangeInstruction(Context context, Operand destination, Operand source) { - if (source.IsR4) + if (source.IsR8 || source.IsR4) { - // TODO - throw new CompilerException("R4 not implemented in InsertExchangeInstruction method"); - } - else if (source.IsR8) - { - // TODO - throw new CompilerException("R8 not implemented in InsertExchangeInstruction method"); + context.AppendInstruction(X64.PXor, destination, source); + context.AppendInstruction(X64.PXor, source, destination); + context.AppendInstruction(X64.PXor, destination, source); } else { diff --git a/Source/Mosa.Platform.x64/Instructions/Cvtsd2ss.cs b/Source/Mosa.Platform.x64/Instructions/Cvtsd2ss.cs index e74df1d5f1..06ea71d4db 100644 --- a/Source/Mosa.Platform.x64/Instructions/Cvtsd2ss.cs +++ b/Source/Mosa.Platform.x64/Instructions/Cvtsd2ss.cs @@ -25,14 +25,14 @@ public override void Emit(InstructionNode node, OpcodeEncoder opcodeEncoder) opcodeEncoder.SuppressByte(0x40); opcodeEncoder.Append4Bits(0b0100); opcodeEncoder.Append1Bit(0b0); - opcodeEncoder.Append1Bit(node.Operand1.Register.RegisterCode >> 3); + opcodeEncoder.Append1Bit(node.Result.Register.RegisterCode >> 3); opcodeEncoder.Append1Bit(0b0); opcodeEncoder.Append1Bit(node.Operand1.Register.RegisterCode >> 3); opcodeEncoder.Append8Bits(0xF2); opcodeEncoder.Append8Bits(0x0F); opcodeEncoder.Append8Bits(0x5A); opcodeEncoder.Append2Bits(0b11); + opcodeEncoder.Append3Bits(node.Result.Register.RegisterCode); opcodeEncoder.Append3Bits(node.Operand1.Register.RegisterCode); - opcodeEncoder.Append3Bits(node.Operand2.Register.RegisterCode); } } diff --git a/Source/Mosa.Platform.x64/Intrinsic/SuppressStackFrame.cs b/Source/Mosa.Platform.x64/Intrinsic/SuppressStackFrame.cs deleted file mode 100644 index ff487dc746..0000000000 --- a/Source/Mosa.Platform.x64/Intrinsic/SuppressStackFrame.cs +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) MOSA Project. Licensed under the New BSD License. - -using Mosa.Compiler.Framework; - -namespace Mosa.Platform.x64.Intrinsic; - -/// -/// IntrinsicMethods -/// -internal static partial class IntrinsicMethods -{ - [IntrinsicMethod("Mosa.Platform.x64.Intrinsic:SuppressStackFrame")] - private static void SurpressStackFrame(Context context, TransformContext transformContext) - { - transformContext.MethodCompiler.IsStackFrameRequired = false; - context.Empty(); - } -} diff --git a/Source/Mosa.Platform.x64/Stages/PlatformTransformationStage.cs b/Source/Mosa.Platform.x64/Stages/PlatformTransformationStage.cs index 180bf7a49b..2a0596b9dc 100644 --- a/Source/Mosa.Platform.x64/Stages/PlatformTransformationStage.cs +++ b/Source/Mosa.Platform.x64/Stages/PlatformTransformationStage.cs @@ -1,6 +1,8 @@ // Copyright (c) MOSA Project. Licensed under the New BSD License. +using Mosa.Platform.x64.Transforms.AddressMode; using Mosa.Platform.x64.Transforms.FixedRegisters; +using Mosa.Platform.x64.Transforms.Optimizations.Manual.Special; using Mosa.Platform.x64.Transforms.Stack; using Mosa.Platform.x64.Transforms.Tweak; @@ -20,6 +22,13 @@ public PlatformTransformationStage() AddTranforms(TweakTransforms.List); AddTranforms(FixedRegistersTransforms.List); AddTranforms(StackTransforms.List); + AddTranforms(AddressModeTransforms.List); AddTranforms(SpecialTransforms.List); + + AddTranform(new Mov32Unless()); + AddTranform(new Mov64Unless()); + AddTranform(new Mov32Coalescing()); + AddTranform(new Mov64Coalescing()); + AddTranform(new Deadcode()); } } diff --git a/Source/Mosa.Platform.x64/Transforms/FixedRegisters/Rcr32.cs b/Source/Mosa.Platform.x64/Transforms/FixedRegisters/Rcr32.cs index b82ad4461c..2acadbe5c3 100644 --- a/Source/Mosa.Platform.x64/Transforms/FixedRegisters/Rcr32.cs +++ b/Source/Mosa.Platform.x64/Transforms/FixedRegisters/Rcr32.cs @@ -13,12 +13,18 @@ public sealed class Rcr32 : BaseTransform public Rcr32() : base(X64.Rcr32, TransformType.Manual | TransformType.Transform) { } - public override bool Match(Context context, TransformContext transform) { + if (context.Operand2.IsConstant) + return false; + + if (context.Operand2.Register == CPURegister.RCX) + return false; + return true; } + public override void Transform(Context context, TransformContext transform) { var operand1 = context.Operand1; diff --git a/Source/Mosa.Platform.x64/Transforms/FixedRegisters/Rcr64.cs b/Source/Mosa.Platform.x64/Transforms/FixedRegisters/Rcr64.cs index 516fb4a633..a4f08b6eff 100644 --- a/Source/Mosa.Platform.x64/Transforms/FixedRegisters/Rcr64.cs +++ b/Source/Mosa.Platform.x64/Transforms/FixedRegisters/Rcr64.cs @@ -16,6 +16,12 @@ public Rcr64() : base(X64.Rcr64, TransformType.Manual | TransformType.Transform) public override bool Match(Context context, TransformContext transform) { + if (context.Operand2.IsConstant) + return false; + + if (context.Operand2.Register == CPURegister.RCX) + return false; + return true; } diff --git a/Source/Mosa.Platform.x64/Transforms/FixedRegisters/Sar32.cs b/Source/Mosa.Platform.x64/Transforms/FixedRegisters/Sar32.cs index ce7360d8d1..c32771952d 100644 --- a/Source/Mosa.Platform.x64/Transforms/FixedRegisters/Sar32.cs +++ b/Source/Mosa.Platform.x64/Transforms/FixedRegisters/Sar32.cs @@ -16,6 +16,12 @@ public Sar32() : base(X64.Sar32, TransformType.Manual | TransformType.Transform) public override bool Match(Context context, TransformContext transform) { + if (context.Operand2.IsConstant) + return false; + + if (context.Operand2.Register == CPURegister.RCX) + return false; + return true; } diff --git a/Source/Mosa.Platform.x64/Transforms/FixedRegisters/Sar64.cs b/Source/Mosa.Platform.x64/Transforms/FixedRegisters/Sar64.cs index cfff0d4c4d..7eca59f797 100644 --- a/Source/Mosa.Platform.x64/Transforms/FixedRegisters/Sar64.cs +++ b/Source/Mosa.Platform.x64/Transforms/FixedRegisters/Sar64.cs @@ -16,6 +16,12 @@ public Sar64() : base(X64.Sar64, TransformType.Manual | TransformType.Transform) public override bool Match(Context context, TransformContext transform) { + if (context.Operand2.IsConstant) + return false; + + if (context.Operand2.Register == CPURegister.RCX) + return false; + return true; } diff --git a/Source/Mosa.Platform.x64/Transforms/FixedRegisters/Shr32.cs b/Source/Mosa.Platform.x64/Transforms/FixedRegisters/Shr32.cs index 98e7d99d03..64725c8200 100644 --- a/Source/Mosa.Platform.x64/Transforms/FixedRegisters/Shr32.cs +++ b/Source/Mosa.Platform.x64/Transforms/FixedRegisters/Shr32.cs @@ -14,11 +14,19 @@ public Shr32() : base(X64.Shr32, TransformType.Manual | TransformType.Transform) { } + public override bool Match(Context context, TransformContext transform) { + if (context.Operand2.IsConstant) + return false; + + if (context.Operand2.Register == CPURegister.RCX) + return false; + return true; } + public override void Transform(Context context, TransformContext transform) { var operand1 = context.Operand1; diff --git a/Source/Mosa.Platform.x64/Transforms/FixedRegisters/Shr64.cs b/Source/Mosa.Platform.x64/Transforms/FixedRegisters/Shr64.cs index aa3240bd84..dff7e117c6 100644 --- a/Source/Mosa.Platform.x64/Transforms/FixedRegisters/Shr64.cs +++ b/Source/Mosa.Platform.x64/Transforms/FixedRegisters/Shr64.cs @@ -16,6 +16,12 @@ public Shr64() : base(X64.Shr64, TransformType.Manual | TransformType.Transform) public override bool Match(Context context, TransformContext transform) { + if (context.Operand2.IsConstant) + return false; + + if (context.Operand2.Register == CPURegister.RCX) + return false; + return true; } diff --git a/Source/Mosa.Platform.x64/Transforms/IR/AddCarryIn64.cs b/Source/Mosa.Platform.x64/Transforms/IR/AddCarryIn64.cs new file mode 100644 index 0000000000..4704c0c5d3 --- /dev/null +++ b/Source/Mosa.Platform.x64/Transforms/IR/AddCarryIn64.cs @@ -0,0 +1,29 @@ +// Copyright (c) MOSA Project. Licensed under the New BSD License. + +using Mosa.Compiler.Framework; + +namespace Mosa.Platform.x64.Transforms.IR; + +/// +/// AddCarryIn64 +/// +[Transform("x64.IR")] +public sealed class AddCarryIn64 : BaseIRTransform +{ + public AddCarryIn64() : base(IRInstruction.AddCarryIn64, TransformType.Manual | TransformType.Transform) + { + } + + public override void Transform(Context context, TransformContext transform) + { + var result = context.Result; + var operand1 = context.Operand1; + var operand2 = context.Operand2; + var operand3 = context.Operand3; + + var v1 = transform.VirtualRegisters.Allocate64(); + + context.SetInstruction(X64.Bt32, v1, operand3, Operand.Constant64_0); + context.AppendInstruction(X64.Adc64, result, operand1, operand2); + } +} diff --git a/Source/Mosa.Platform.x64/Transforms/IR/AddCarryOut64.cs b/Source/Mosa.Platform.x64/Transforms/IR/AddCarryOut64.cs new file mode 100644 index 0000000000..65af8123f7 --- /dev/null +++ b/Source/Mosa.Platform.x64/Transforms/IR/AddCarryOut64.cs @@ -0,0 +1,30 @@ +// Copyright (c) MOSA Project. Licensed under the New BSD License. + +using Mosa.Compiler.Framework; + +namespace Mosa.Platform.x64.Transforms.IR; + +/// +/// AddCarryOut32 +/// +[Transform("x64.IR")] +public sealed class AddCarryOut64 : BaseIRTransform +{ + public AddCarryOut64() : base(IRInstruction.AddCarryOut64, TransformType.Manual | TransformType.Transform) + { + } + + public override void Transform(Context context, TransformContext transform) + { + var result = context.Result; + var result2 = context.Result2; + var operand1 = context.Operand1; + var operand2 = context.Operand2; + + var v1 = transform.VirtualRegisters.Allocate64(); + + context.SetInstruction(X64.Add64, result, operand1, operand2); + context.AppendInstruction(X64.Setcc, ConditionCode.Carry, v1); + context.AppendInstruction(X64.Movzx8To64, result2, v1); + } +} diff --git a/Source/Mosa.Platform.x64/Transforms/IR/AddOverflowOut32.cs b/Source/Mosa.Platform.x64/Transforms/IR/AddOverflowOut32.cs new file mode 100644 index 0000000000..29c18c153f --- /dev/null +++ b/Source/Mosa.Platform.x64/Transforms/IR/AddOverflowOut32.cs @@ -0,0 +1,30 @@ +// Copyright (c) MOSA Project. Licensed under the New BSD License. + +using Mosa.Compiler.Framework; + +namespace Mosa.Platform.x64.Transforms.IR; + +/// +/// AddOverflowOut32 +/// +[Transform("x64.IR")] +public sealed class AddOverflowOut32 : BaseIRTransform +{ + public AddOverflowOut32() : base(IRInstruction.AddOverflowOut32, TransformType.Manual | TransformType.Transform) + { + } + + public override void Transform(Context context, TransformContext transform) + { + var result = context.Result; + var result2 = context.Result2; + var operand1 = context.Operand1; + var operand2 = context.Operand2; + + var v1 = transform.VirtualRegisters.Allocate32(); + + context.SetInstruction(X64.Add32, result, operand1, operand2); + context.AppendInstruction(X64.Setcc, ConditionCode.Overflow, v1); + context.AppendInstruction(X64.Movzx8To32, result2, v1); + } +} diff --git a/Source/Mosa.Platform.x64/Transforms/IR/AddOverflowOut64.cs b/Source/Mosa.Platform.x64/Transforms/IR/AddOverflowOut64.cs new file mode 100644 index 0000000000..3e47baf21f --- /dev/null +++ b/Source/Mosa.Platform.x64/Transforms/IR/AddOverflowOut64.cs @@ -0,0 +1,30 @@ +// Copyright (c) MOSA Project. Licensed under the New BSD License. + +using Mosa.Compiler.Framework; + +namespace Mosa.Platform.x64.Transforms.IR; + +/// +/// AddOverflowOut64 +/// +[Transform("x64.IR")] +public sealed class AddOverflowOut64 : BaseIRTransform +{ + public AddOverflowOut64() : base(IRInstruction.AddOverflowOut64, TransformType.Manual | TransformType.Transform) + { + } + + public override void Transform(Context context, TransformContext transform) + { + var result = context.Result; + var result2 = context.Result2; + var operand1 = context.Operand1; + var operand2 = context.Operand2; + + var v1 = transform.VirtualRegisters.Allocate64(); + + context.SetInstruction(X64.Adc64, result, operand1, operand2); + context.AppendInstruction(X64.Setcc, ConditionCode.Overflow, v1); + context.AppendInstruction(X64.Movzx8To64, result2, v1); + } +} diff --git a/Source/Mosa.Platform.x64/Transforms/IR/BitCopy32ToR4.cs b/Source/Mosa.Platform.x64/Transforms/IR/BitCopy32ToR4.cs new file mode 100644 index 0000000000..438b69db4b --- /dev/null +++ b/Source/Mosa.Platform.x64/Transforms/IR/BitCopy32ToR4.cs @@ -0,0 +1,21 @@ +// Copyright (c) MOSA Project. Licensed under the New BSD License. + +using Mosa.Compiler.Framework; + +namespace Mosa.Platform.x64.Transforms.IR; + +/// +/// BitCopy32ToR4 +/// +[Transform("x64.IR")] +public sealed class BitCopy32ToR4 : BaseIRTransform +{ + public BitCopy32ToR4() : base(IRInstruction.BitCopy32ToR4, TransformType.Manual | TransformType.Transform) + { + } + + public override void Transform(Context context, TransformContext transform) + { + //context.ReplaceInstruction(X64.Movdi32ss); // TODO + } +} diff --git a/Source/Mosa.Platform.x64/Transforms/IR/BitCopyR4To32.cs b/Source/Mosa.Platform.x64/Transforms/IR/BitCopyR4To32.cs new file mode 100644 index 0000000000..30561d5c53 --- /dev/null +++ b/Source/Mosa.Platform.x64/Transforms/IR/BitCopyR4To32.cs @@ -0,0 +1,26 @@ +// Copyright (c) MOSA Project. Licensed under the New BSD License. + +using Mosa.Compiler.Framework; + +namespace Mosa.Platform.x64.Transforms.IR; + +/// +/// BitCopyR4To32 +/// +[Transform("x64.IR")] +public sealed class BitCopyR4To32 : BaseIRTransform +{ + public BitCopyR4To32() : base(IRInstruction.BitCopyR4To32, TransformType.Manual | TransformType.Transform) + { + } + + public override void Transform(Context context, TransformContext transform) + { + var result = context.Result; + var operand1 = context.Operand1; + + operand1 = MoveConstantToFloatRegister(transform, context, operand1); + + //context.SetInstruction(X64.Movdssi64, result, operand1); // TODO + } +} diff --git a/Source/Mosa.Platform.x64/Transforms/IR/ConvertR4ToI64.cs b/Source/Mosa.Platform.x64/Transforms/IR/ConvertR4ToI64.cs index 1972ab21c7..1f5daf7e39 100644 --- a/Source/Mosa.Platform.x64/Transforms/IR/ConvertR4ToI64.cs +++ b/Source/Mosa.Platform.x64/Transforms/IR/ConvertR4ToI64.cs @@ -16,6 +16,6 @@ public ConvertR4ToI64() : base(IRInstruction.ConvertR4ToI64, TransformType.Manua public override void Transform(Context context, TransformContext transform) { - context.ReplaceInstruction(X64.Cvtss2sd); + context.ReplaceInstruction(X64.Cvttss2si64); } } diff --git a/Source/Mosa.Platform.x64/Transforms/IR/ConvertR4ToU32.cs b/Source/Mosa.Platform.x64/Transforms/IR/ConvertR4ToU32.cs new file mode 100644 index 0000000000..b8f2ba78af --- /dev/null +++ b/Source/Mosa.Platform.x64/Transforms/IR/ConvertR4ToU32.cs @@ -0,0 +1,26 @@ +// Copyright (c) MOSA Project. Licensed under the New BSD License. + +using Mosa.Compiler.Framework; + +namespace Mosa.Platform.x64.Transforms.IR; + +/// +/// ConvertR4ToU32 +/// +[Transform("x64.IR")] +public sealed class ConvertR4ToU32 : BaseIRTransform +{ + public ConvertR4ToU32() : base(IRInstruction.ConvertR4ToU32, TransformType.Manual | TransformType.Transform) + { + } + + public override void Transform(Context context, TransformContext transform) + { + var result = context.Result; + var operand1 = context.Operand1; + + operand1 = MoveConstantToFloatRegister(transform, context, operand1); + + context.SetInstruction(X64.Cvttss2si64, result, operand1); + } +} diff --git a/Source/Mosa.Platform.x64/Transforms/IR/ConvertR4ToU64.cs b/Source/Mosa.Platform.x64/Transforms/IR/ConvertR4ToU64.cs new file mode 100644 index 0000000000..466b920f29 --- /dev/null +++ b/Source/Mosa.Platform.x64/Transforms/IR/ConvertR4ToU64.cs @@ -0,0 +1,21 @@ +// Copyright (c) MOSA Project. Licensed under the New BSD License. + +using Mosa.Compiler.Framework; + +namespace Mosa.Platform.x64.Transforms.IR; + +/// +/// ConvertR4ToU64 +/// +[Transform("x64.IR")] +public sealed class ConvertR4ToU64 : BaseIRTransform +{ + public ConvertR4ToU64() : base(IRInstruction.ConvertR4ToI64, TransformType.Manual | TransformType.Transform) + { + } + + public override void Transform(Context context, TransformContext transform) + { + //context.ReplaceInstruction(X64.Cvttss2si64); // + } +} diff --git a/Source/Mosa.Platform.x64/Transforms/IR/ConvertR8ToR4.cs b/Source/Mosa.Platform.x64/Transforms/IR/ConvertR8ToR4.cs index 18eec8f2c9..8ef7d8e516 100644 --- a/Source/Mosa.Platform.x64/Transforms/IR/ConvertR8ToR4.cs +++ b/Source/Mosa.Platform.x64/Transforms/IR/ConvertR8ToR4.cs @@ -17,7 +17,7 @@ public ConvertR8ToR4() : base(IRInstruction.ConvertR8ToR4, TransformType.Manual public override void Transform(Context context, TransformContext transform) { - Debug.Assert(context.Result.IsFloatingPoint && !context.Result.IsFloatingPoint); + Debug.Assert(context.Result.IsFloatingPoint && context.Result.IsFloatingPoint); var result = context.Result; var operand1 = context.Operand1; diff --git a/Source/Mosa.Platform.x64/Transforms/IR/ConvertR8ToU32.cs b/Source/Mosa.Platform.x64/Transforms/IR/ConvertR8ToU32.cs new file mode 100644 index 0000000000..00c50e0cfe --- /dev/null +++ b/Source/Mosa.Platform.x64/Transforms/IR/ConvertR8ToU32.cs @@ -0,0 +1,26 @@ +// Copyright (c) MOSA Project. Licensed under the New BSD License. + +using Mosa.Compiler.Framework; + +namespace Mosa.Platform.x64.Transforms.IR; + +/// +/// ConvertR8ToU32 +/// +[Transform("x64.IR")] +public sealed class ConvertR8ToU32 : BaseIRTransform +{ + public ConvertR8ToU32() : base(IRInstruction.ConvertR8ToU32, TransformType.Manual | TransformType.Transform) + { + } + + public override void Transform(Context context, TransformContext transform) + { + var result = context.Result; + var operand1 = context.Operand1; + + operand1 = MoveConstantToFloatRegister(transform, context, operand1); + + context.SetInstruction(X64.Cvttsd2si32, result, operand1); + } +} diff --git a/Source/Mosa.Platform.x64/Transforms/IR/ConvertU32ToR4.cs b/Source/Mosa.Platform.x64/Transforms/IR/ConvertU32ToR4.cs new file mode 100644 index 0000000000..36e1e0876f --- /dev/null +++ b/Source/Mosa.Platform.x64/Transforms/IR/ConvertU32ToR4.cs @@ -0,0 +1,28 @@ +// Copyright (c) MOSA Project. Licensed under the New BSD License. + +using Mosa.Compiler.Framework; + +namespace Mosa.Platform.x64.Transforms.IR; + +/// +/// ConvertR8ToU32 +/// +[Transform("x64.IR")] +public sealed class ConvertU32ToR4 : BaseIRTransform +{ + public ConvertU32ToR4() : base(IRInstruction.ConvertU32ToR4, TransformType.Manual | TransformType.Transform, true) + { + } + + public override void Transform(Context context, TransformContext transform) + { + var result = context.Result; + var operand1 = context.Operand1; + + //operand1 = MoveConstantToFloatRegister(transform, context, operand1); + + //context.SetInstruction(X64.Xorps, result, result, result); + //context.SetInstruction(X64.Movss, result, operand1); + context.SetInstruction(X64.Cvtsi2ss32, result, operand1); + } +} diff --git a/Source/Mosa.Platform.x64/Transforms/IR/ConvertU32ToR8.cs b/Source/Mosa.Platform.x64/Transforms/IR/ConvertU32ToR8.cs new file mode 100644 index 0000000000..a7c8cca47c --- /dev/null +++ b/Source/Mosa.Platform.x64/Transforms/IR/ConvertU32ToR8.cs @@ -0,0 +1,28 @@ +// Copyright (c) MOSA Project. Licensed under the New BSD License. + +using Mosa.Compiler.Framework; + +namespace Mosa.Platform.x64.Transforms.IR; + +/// +/// ConvertU32ToR8 +/// +[Transform("x64.IR")] +public sealed class ConvertU32ToR8 : BaseIRTransform +{ + public ConvertU32ToR8() : base(IRInstruction.ConvertU32ToR8, TransformType.Manual | TransformType.Transform, true) + { + } + + public override void Transform(Context context, TransformContext transform) + { + var result = context.Result; + var operand1 = context.Operand1; + + //operand1 = MoveConstantToFloatRegister(transform, context, operand1); + + //context.SetInstruction(X64.Xorps, result, result, result); + //context.SetInstruction(X64.Movss, result, operand1); + context.SetInstruction(X64.Cvtsi2sd32, result, operand1); + } +} diff --git a/Source/Mosa.Platform.x64/Transforms/IR/DivSigned32.cs b/Source/Mosa.Platform.x64/Transforms/IR/DivSigned32.cs index fe2bafac7c..607a945463 100644 --- a/Source/Mosa.Platform.x64/Transforms/IR/DivSigned32.cs +++ b/Source/Mosa.Platform.x64/Transforms/IR/DivSigned32.cs @@ -20,11 +20,12 @@ public override void Transform(Context context, TransformContext transform) var operand2 = context.Operand2; var result = context.Result; - var v1 = transform.VirtualRegisters.Allocate32(); - var v2 = transform.VirtualRegisters.Allocate32(); - var v3 = transform.VirtualRegisters.Allocate32(); + var v1 = transform.VirtualRegisters.Allocate64(); + var v2 = transform.VirtualRegisters.Allocate64(); + var v3 = transform.VirtualRegisters.Allocate64(); - context.SetInstruction2(X64.Cdq32, v1, v2, operand1); - context.AppendInstruction2(X64.IDiv32, v3, result, v1, v2, operand2); + context.SetInstruction(X64.Mov32, v2, operand1); + context.AppendInstruction(X64.Cdq32, v3, v2); + context.AppendInstruction2(X64.IDiv32, v1, result, v3, v2, operand2); } } diff --git a/Source/Mosa.Platform.x64/Transforms/IR/DivSigned64.cs b/Source/Mosa.Platform.x64/Transforms/IR/DivSigned64.cs index d233eb1d90..281e665fc7 100644 --- a/Source/Mosa.Platform.x64/Transforms/IR/DivSigned64.cs +++ b/Source/Mosa.Platform.x64/Transforms/IR/DivSigned64.cs @@ -20,11 +20,12 @@ public override void Transform(Context context, TransformContext transform) var operand1 = context.Operand1; var operand2 = context.Operand2; - var v1 = transform.VirtualRegisters.Allocate32(); - var v2 = transform.VirtualRegisters.Allocate32(); - var v3 = transform.VirtualRegisters.Allocate32(); + var v1 = transform.VirtualRegisters.Allocate64(); + var v2 = transform.VirtualRegisters.Allocate64(); + var v3 = transform.VirtualRegisters.Allocate64(); - context.SetInstruction2(X64.Cdq64, v1, v2, operand1); - context.AppendInstruction2(X64.IDiv64, result, v3, v1, v2, operand2); + context.SetInstruction(X64.Mov64, v2, operand1); + context.AppendInstruction(X64.Cdq64, v3, v2); + context.AppendInstruction2(X64.IDiv64, v1, result, v3, v2, operand2); } } diff --git a/Source/Mosa.Platform.x64/Transforms/IR/IRTransforms.cs b/Source/Mosa.Platform.x64/Transforms/IR/IRTransforms.cs index 210a7fbbeb..1d51de05e3 100644 --- a/Source/Mosa.Platform.x64/Transforms/IR/IRTransforms.cs +++ b/Source/Mosa.Platform.x64/Transforms/IR/IRTransforms.cs @@ -16,7 +16,7 @@ public static class IRTransforms new AddCarryIn32(), new AddCarryOut32(), new AddManagedPointer(), - //new AddOverflowOut32(), + new AddOverflowOut32(), new AddR4(), new AddR8(), new AddressOf(), @@ -34,18 +34,23 @@ public static class IRTransforms new Compare32x32(), new ConvertR4ToR8(), new ConvertR4ToI32(), - //new ConvertR4ToU32(), + new ConvertR4ToU32(), + new ConvertR4ToI64(), new ConvertR8ToR4(), new ConvertR8ToI32(), - //new ConvertR8ToU32(), + new ConvertR8ToU32(), + new ConvertR8ToI64(), new ConvertI32ToR4(), new ConvertI32ToR8(), - //new ConvertU32ToR4(), - //new ConvertU32ToR8(), + new ConvertU32ToR4(), + new ConvertU32ToR8(), + // new ConvertR4ToU64(), new DivR4(), new DivR8(), new DivSigned32(), + new DivSigned64(), new DivUnsigned32(), + new DivUnsigned64(), new IfThenElse32(), new Jmp(), new LoadR4(), @@ -66,6 +71,12 @@ public static class IRTransforms new LoadSignExtend8x32(), new LoadZeroExtend16x32(), new LoadZeroExtend8x32(), + new LoadSignExtend8x64(), + new LoadSignExtend16x64(), + new LoadSignExtend32x64(), + new LoadZeroExtend8x64(), + new LoadZeroExtend16x64(), + new LoadZeroExtend32x64(), new And32(), new Not32(), new Or32(), @@ -75,8 +86,8 @@ public static class IRTransforms new Move32(), new MoveObject(), new MoveManagedPointer(), - //new MulCarryOut32(), - //new MulOverflowOut32(), + new MulCarryOut32(), + new MulOverflowOut32(), new MulR4(), new MulR8(), new MulSigned32(), @@ -84,6 +95,8 @@ public static class IRTransforms new Nop(), new RemSigned32(), new RemUnsigned32(), + new RemSigned64(), + new RemUnsigned64(), new ShiftLeft32(), new ShiftRight32(), new SignExtend16x32(), @@ -106,14 +119,14 @@ public static class IRTransforms new SubCarryIn32(), new SubCarryOut32(), new SubManagedPointer(), - //new SubOverflowOut32(), + new SubOverflowOut32(), new SubR4(), new SubR8(), new ZeroExtend16x32(), new ZeroExtend8x32(), new Add64(), - //new AddCarryOut64(), - //new AddOverflowOut64(), + new AddCarryOut64(), + new AddOverflowOut64(), //new BitCopyR8To64(), //new BitCopy64ToR8(), new ArithShiftRight64(), @@ -152,8 +165,8 @@ public static class IRTransforms new Store64(), new StoreParam64(), new Sub64(), - //new SubCarryOut64(), - //new SubOverflowOut64(), + new SubCarryOut64(), + new SubOverflowOut64(), //new To64(), new Truncate64x32(), new ZeroExtend16x64(), diff --git a/Source/Mosa.Platform.x64/Transforms/IR/MulCarryOut32.cs b/Source/Mosa.Platform.x64/Transforms/IR/MulCarryOut32.cs new file mode 100644 index 0000000000..4df66b8443 --- /dev/null +++ b/Source/Mosa.Platform.x64/Transforms/IR/MulCarryOut32.cs @@ -0,0 +1,31 @@ +// Copyright (c) MOSA Project. Licensed under the New BSD License. + +using Mosa.Compiler.Framework; + +namespace Mosa.Platform.x64.Transforms.IR; + +/// +/// MulCarryOut32 +/// +[Transform("x64.IR")] +public sealed class MulCarryOut32 : BaseIRTransform +{ + public MulCarryOut32() : base(IRInstruction.MulCarryOut32, TransformType.Manual | TransformType.Transform) + { + } + + public override void Transform(Context context, TransformContext transform) + { + var result = context.Result; + var result2 = context.Result2; + var operand1 = context.Operand1; + var operand2 = context.Operand2; + + var v1 = transform.VirtualRegisters.Allocate32(); + var v2 = transform.VirtualRegisters.Allocate32(); + + context.SetInstruction2(X64.Mul32, v2, result, operand1, operand2); + context.AppendInstruction(X64.Setcc, ConditionCode.Carry, v1); + context.AppendInstruction(X64.Movzx8To32, result2, v1); + } +} diff --git a/Source/Mosa.Platform.x64/Transforms/IR/MulOverflowOut32.cs b/Source/Mosa.Platform.x64/Transforms/IR/MulOverflowOut32.cs new file mode 100644 index 0000000000..29b012d732 --- /dev/null +++ b/Source/Mosa.Platform.x64/Transforms/IR/MulOverflowOut32.cs @@ -0,0 +1,30 @@ +// Copyright (c) MOSA Project. Licensed under the New BSD License. + +using Mosa.Compiler.Framework; + +namespace Mosa.Platform.x64.Transforms.IR; + +/// +/// MulOverflowOut32 +/// +[Transform("x64.IR")] +public sealed class MulOverflowOut32 : BaseIRTransform +{ + public MulOverflowOut32() : base(IRInstruction.MulOverflowOut32, TransformType.Manual | TransformType.Transform) + { + } + + public override void Transform(Context context, TransformContext transform) + { + var result = context.Result; + var result2 = context.Result2; + var operand1 = context.Operand1; + var operand2 = context.Operand2; + + var v1 = transform.VirtualRegisters.Allocate32(); + + context.SetInstruction(X64.IMul32, result, operand1, operand2); + context.AppendInstruction(X64.Setcc, ConditionCode.Overflow, v1); + context.AppendInstruction(X64.Movzx8To32, result2, v1); + } +} diff --git a/Source/Mosa.Platform.x64/Transforms/IR/RemSigned32.cs b/Source/Mosa.Platform.x64/Transforms/IR/RemSigned32.cs index 7f2dff02cb..23256b29eb 100644 --- a/Source/Mosa.Platform.x64/Transforms/IR/RemSigned32.cs +++ b/Source/Mosa.Platform.x64/Transforms/IR/RemSigned32.cs @@ -22,9 +22,8 @@ public override void Transform(Context context, TransformContext transform) var v1 = transform.VirtualRegisters.Allocate32(); var v2 = transform.VirtualRegisters.Allocate32(); - var v3 = transform.VirtualRegisters.Allocate32(); - context.SetInstruction2(X64.Cdq32, v1, v2, operand1); - context.AppendInstruction2(X64.IDiv32, result, v3, v1, v2, operand2); + context.SetInstruction(X64.Cdq32, v1, operand1); + context.AppendInstruction2(X64.IDiv32, result, v2, v1, operand1, operand2); } } diff --git a/Source/Mosa.Platform.x64/Transforms/IR/RemSigned64.cs b/Source/Mosa.Platform.x64/Transforms/IR/RemSigned64.cs index aebf919da0..d0438378d0 100644 --- a/Source/Mosa.Platform.x64/Transforms/IR/RemSigned64.cs +++ b/Source/Mosa.Platform.x64/Transforms/IR/RemSigned64.cs @@ -22,9 +22,8 @@ public override void Transform(Context context, TransformContext transform) var v1 = transform.VirtualRegisters.Allocate32(); var v2 = transform.VirtualRegisters.Allocate32(); - var v3 = transform.VirtualRegisters.Allocate32(); - context.SetInstruction2(X64.Cdq64, v1, v2, operand1); - context.AppendInstruction2(X64.IDiv64, result, v3, v1, v2, operand2); + context.SetInstruction(X64.Mov64, v1, Operand.Constant64_0); + context.AppendInstruction2(X64.Div64, result, v2, v1, operand1, operand2); } } diff --git a/Source/Mosa.Platform.x64/Transforms/IR/SubCarryOut64.cs b/Source/Mosa.Platform.x64/Transforms/IR/SubCarryOut64.cs new file mode 100644 index 0000000000..2d5bd0f24c --- /dev/null +++ b/Source/Mosa.Platform.x64/Transforms/IR/SubCarryOut64.cs @@ -0,0 +1,30 @@ +// Copyright (c) MOSA Project. Licensed under the New BSD License. + +using Mosa.Compiler.Framework; + +namespace Mosa.Platform.x64.Transforms.IR; + +/// +/// SubCarryOut64 +/// +[Transform("x64.IR")] +public sealed class SubCarryOut64 : BaseIRTransform +{ + public SubCarryOut64() : base(IRInstruction.SubCarryOut64, TransformType.Manual | TransformType.Transform) + { + } + + public override void Transform(Context context, TransformContext transform) + { + var result = context.Result; + var result2 = context.Result2; + var operand1 = context.Operand1; + var operand2 = context.Operand2; + + var v1 = transform.VirtualRegisters.Allocate64(); + + context.SetInstruction(X64.Sub64, result, operand1, operand2); + context.AppendInstruction(X64.Setcc, ConditionCode.Carry, v1); + context.AppendInstruction(X64.Movzx8To64, result2, v1); + } +} diff --git a/Source/Mosa.Platform.x64/Transforms/IR/SubOverflowOut32.cs b/Source/Mosa.Platform.x64/Transforms/IR/SubOverflowOut32.cs new file mode 100644 index 0000000000..72178770ac --- /dev/null +++ b/Source/Mosa.Platform.x64/Transforms/IR/SubOverflowOut32.cs @@ -0,0 +1,30 @@ +// Copyright (c) MOSA Project. Licensed under the New BSD License. + +using Mosa.Compiler.Framework; + +namespace Mosa.Platform.x64.Transforms.IR; + +/// +/// SubOverflowOut32 +/// +[Transform("x64.IR")] +public sealed class SubOverflowOut32 : BaseIRTransform +{ + public SubOverflowOut32() : base(IRInstruction.SubOverflowOut32, TransformType.Manual | TransformType.Transform) + { + } + + public override void Transform(Context context, TransformContext transform) + { + var result = context.Result; + var result2 = context.Result2; + var operand1 = context.Operand1; + var operand2 = context.Operand2; + + var v1 = transform.VirtualRegisters.Allocate32(); + + context.SetInstruction(X64.Sub32, result, operand1, operand2); + context.AppendInstruction(X64.Setcc, ConditionCode.Overflow, v1); + context.AppendInstruction(X64.Movzx8To32, result2, v1); + } +} diff --git a/Source/Mosa.Platform.x64/Transforms/IR/SubOverflowOut64.cs b/Source/Mosa.Platform.x64/Transforms/IR/SubOverflowOut64.cs new file mode 100644 index 0000000000..9bde5c642e --- /dev/null +++ b/Source/Mosa.Platform.x64/Transforms/IR/SubOverflowOut64.cs @@ -0,0 +1,30 @@ +// Copyright (c) MOSA Project. Licensed under the New BSD License. + +using Mosa.Compiler.Framework; + +namespace Mosa.Platform.x64.Transforms.IR; + +/// +/// SubOverflowOut64 +/// +[Transform("x64.IR")] +public sealed class SubOverflowOut64 : BaseIRTransform +{ + public SubOverflowOut64() : base(IRInstruction.SubOverflowOut64, TransformType.Manual | TransformType.Transform) + { + } + + public override void Transform(Context context, TransformContext transform) + { + var result = context.Result; + var result2 = context.Result2; + var operand1 = context.Operand1; + var operand2 = context.Operand2; + + var v1 = transform.VirtualRegisters.Allocate64(); + + context.SetInstruction(X64.Sub64, result, operand1, operand2); + context.AppendInstruction(X64.Setcc, ConditionCode.Overflow, v1); + context.AppendInstruction(X64.Movzx8To64, result2, v1); + } +} diff --git a/Source/Mosa.Platform.x64/Transforms/Optimizations/Manual/Special/Mov32Unless.cs b/Source/Mosa.Platform.x64/Transforms/Optimizations/Manual/Special/Mov32Unless.cs new file mode 100644 index 0000000000..792f1aee47 --- /dev/null +++ b/Source/Mosa.Platform.x64/Transforms/Optimizations/Manual/Special/Mov32Unless.cs @@ -0,0 +1,55 @@ +// Copyright (c) MOSA Project. Licensed under the New BSD License. + +using Mosa.Compiler.Framework; + +namespace Mosa.Platform.x64.Transforms.Optimizations.Manual.Special; + +[Transform("x86.Optimizations.Manual.Special")] +public sealed class Mov32Unless : BaseTransform +{ + public Mov32Unless() : base(X64.Mov32, TransformType.Manual | TransformType.Optimization) + { + } + + public override bool Match(Context context, TransformContext transform) + { + if (!transform.AreCPURegistersAllocated) + return false; + + if (!context.Result.IsCPURegister) + return false; + + if (!context.Operand1.IsCPURegister) + return false; + + //if (context.Result.Register != CPURegister.ESP) + // return false; + + var previous = context.Node.PreviousNonEmpty; + + if (previous == null || previous.Instruction != X64.Mov32) + return false; + + //if (previous.Result.Register != CPURegister.ESP) + // return false; + + if (!previous.Result.IsCPURegister) + return false; + + if (!previous.Operand1.IsCPURegister) + return false; + + if (context.Result.Register != previous.Operand1.Register) + return false; + + if (context.Operand1.Register != previous.Result.Register) + return false; + + return true; + } + + public override void Transform(Context context, TransformContext transform) + { + context.SetNop(); + } +} diff --git a/Source/Mosa.Platform.x64/Transforms/Optimizations/Manual/Special/Mov64Coalescing.cs b/Source/Mosa.Platform.x64/Transforms/Optimizations/Manual/Special/Mov64Coalescing.cs new file mode 100644 index 0000000000..18beed79f1 --- /dev/null +++ b/Source/Mosa.Platform.x64/Transforms/Optimizations/Manual/Special/Mov64Coalescing.cs @@ -0,0 +1,48 @@ +// Copyright (c) MOSA Project. Licensed under the New BSD License. + +using Mosa.Compiler.Framework; + +namespace Mosa.Platform.x64.Transforms.Optimizations.Manual.Special; + +[Transform("x64.Optimizations.Manual.Special")] +public sealed class Mov64Coalescing : BaseTransform +{ + public Mov64Coalescing() : base(X64.Mov64, TransformType.Manual | TransformType.Optimization) + { + } + + public override bool Match(Context context, TransformContext transform) + { + if (!context.Operand1.IsVirtualRegister) + return false; + + if (!context.Result.IsVirtualRegister) + return false; + + if (!context.Result.IsDefinedOnce) + return false; + + return true; + } + + public override void Transform(Context context, TransformContext transform) + { + var result = context.Result; + var operand1 = context.Operand1; + + foreach (var use in result.Uses.ToArray()) + { + for (int i = 0; i < use.OperandCount; i++) + { + var operand = use.GetOperand(i); + + if (operand == result) + { + use.SetOperand(i, operand1); + } + } + } + + context.Empty(); + } +} diff --git a/Source/Mosa.Platform.x64/Transforms/Optimizations/Manual/Special/Mov64Unless.cs b/Source/Mosa.Platform.x64/Transforms/Optimizations/Manual/Special/Mov64Unless.cs new file mode 100644 index 0000000000..8814392957 --- /dev/null +++ b/Source/Mosa.Platform.x64/Transforms/Optimizations/Manual/Special/Mov64Unless.cs @@ -0,0 +1,55 @@ +// Copyright (c) MOSA Project. Licensed under the New BSD License. + +using Mosa.Compiler.Framework; + +namespace Mosa.Platform.x64.Transforms.Optimizations.Manual.Special; + +[Transform("x86.Optimizations.Manual.Special")] +public sealed class Mov64Unless : BaseTransform +{ + public Mov64Unless() : base(X64.Mov64, TransformType.Manual | TransformType.Optimization) + { + } + + public override bool Match(Context context, TransformContext transform) + { + if (!transform.AreCPURegistersAllocated) + return false; + + if (!context.Result.IsCPURegister) + return false; + + if (!context.Operand1.IsCPURegister) + return false; + + //if (context.Result.Register != CPURegister.ESP) + // return false; + + var previous = context.Node.PreviousNonEmpty; + + if (previous == null || previous.Instruction != X64.Mov64) + return false; + + //if (previous.Result.Register != CPURegister.ESP) + // return false; + + if (!previous.Result.IsCPURegister) + return false; + + if (!previous.Operand1.IsCPURegister) + return false; + + if (context.Result.Register != previous.Operand1.Register) + return false; + + if (context.Operand1.Register != previous.Result.Register) + return false; + + return true; + } + + public override void Transform(Context context, TransformContext transform) + { + context.SetNop(); + } +} diff --git a/Source/Mosa.Platform.x64/Transforms/RuntimeCall/ConvertR4ToI64.cs b/Source/Mosa.Platform.x64/Transforms/RuntimeCall/ConvertR4ToI64.cs new file mode 100644 index 0000000000..8030471892 --- /dev/null +++ b/Source/Mosa.Platform.x64/Transforms/RuntimeCall/ConvertR4ToI64.cs @@ -0,0 +1,28 @@ +// Copyright (c) MOSA Project. Licensed under the New BSD License. + +using Mosa.Compiler.Framework; + +namespace Mosa.Platform.x64.Transforms.RuntimeCall; + +/// +/// ConvertR4ToI64 +/// +[Transform("x64.RuntimeCall")] +public sealed class ConvertR4ToI64 : BaseTransform +{ + public ConvertR4ToI64() : base(IRInstruction.ConvertR4ToI64, TransformType.Manual | TransformType.Transform) + { + } + + public override int Priority => -100; + + public override bool Match(Context context, TransformContext transform) + { + return true; + } + + public override void Transform(Context context, TransformContext transform) + { + transform.ReplaceWithCall(context, "Mosa.Runtime.Math.Conversion", "R4ToI8"); + } +} diff --git a/Source/Mosa.Platform.x64/Transforms/RuntimeCall/ConvertR4ToU64.cs b/Source/Mosa.Platform.x64/Transforms/RuntimeCall/ConvertR4ToU64.cs new file mode 100644 index 0000000000..e40e790d1b --- /dev/null +++ b/Source/Mosa.Platform.x64/Transforms/RuntimeCall/ConvertR4ToU64.cs @@ -0,0 +1,28 @@ +// Copyright (c) MOSA Project. Licensed under the New BSD License. + +using Mosa.Compiler.Framework; + +namespace Mosa.Platform.x64.Transforms.RuntimeCall; + +/// +/// ConvertR4ToU64 +/// +[Transform("x64.RuntimeCall")] +public sealed class ConvertR4ToU64 : BaseTransform +{ + public ConvertR4ToU64() : base(IRInstruction.ConvertR4ToU64, TransformType.Manual | TransformType.Transform) + { + } + + public override int Priority => -100; + + public override bool Match(Context context, TransformContext transform) + { + return true; + } + + public override void Transform(Context context, TransformContext transform) + { + transform.ReplaceWithCall(context, "Mosa.Runtime.Math.Conversion", "R4ToU8"); + } +} diff --git a/Source/Mosa.Platform.x64/Transforms/RuntimeCall/ConvertR8ToI64.cs b/Source/Mosa.Platform.x64/Transforms/RuntimeCall/ConvertR8ToI64.cs new file mode 100644 index 0000000000..ca16a7c51b --- /dev/null +++ b/Source/Mosa.Platform.x64/Transforms/RuntimeCall/ConvertR8ToI64.cs @@ -0,0 +1,28 @@ +// Copyright (c) MOSA Project. Licensed under the New BSD License. + +using Mosa.Compiler.Framework; + +namespace Mosa.Platform.x64.Transforms.RuntimeCall; + +/// +/// ConvertR8ToI64 +/// +[Transform("x64.RuntimeCall")] +public sealed class ConvertR8ToI64 : BaseTransform +{ + public ConvertR8ToI64() : base(IRInstruction.ConvertR8ToI64, TransformType.Manual | TransformType.Transform) + { + } + + public override int Priority => -100; + + public override bool Match(Context context, TransformContext transform) + { + return true; + } + + public override void Transform(Context context, TransformContext transform) + { + transform.ReplaceWithCall(context, "Mosa.Runtime.Math.Conversion", "R8ToI8"); + } +} diff --git a/Source/Mosa.Platform.x64/Transforms/RuntimeCall/ConvertR8ToU64.cs b/Source/Mosa.Platform.x64/Transforms/RuntimeCall/ConvertR8ToU64.cs new file mode 100644 index 0000000000..548b3f6416 --- /dev/null +++ b/Source/Mosa.Platform.x64/Transforms/RuntimeCall/ConvertR8ToU64.cs @@ -0,0 +1,28 @@ +// Copyright (c) MOSA Project. Licensed under the New BSD License. + +using Mosa.Compiler.Framework; + +namespace Mosa.Platform.x64.Transforms.RuntimeCall; + +/// +/// ConvertR8ToU64 +/// +[Transform("x64.RuntimeCall")] +public sealed class ConvertR8ToU64 : BaseTransform +{ + public ConvertR8ToU64() : base(IRInstruction.ConvertR8ToU64, TransformType.Manual | TransformType.Transform) + { + } + + public override int Priority => -100; + + public override bool Match(Context context, TransformContext transform) + { + return true; + } + + public override void Transform(Context context, TransformContext transform) + { + transform.ReplaceWithCall(context, "Mosa.Runtime.Math.Conversion", "R8ToU8"); + } +} diff --git a/Source/Mosa.Platform.x64/Transforms/RuntimeCall/MulCarryOut64.cs b/Source/Mosa.Platform.x64/Transforms/RuntimeCall/MulCarryOut64.cs new file mode 100644 index 0000000000..923efaedd3 --- /dev/null +++ b/Source/Mosa.Platform.x64/Transforms/RuntimeCall/MulCarryOut64.cs @@ -0,0 +1,47 @@ +// Copyright (c) MOSA Project. Licensed under the New BSD License. + +using System.Diagnostics; +using Mosa.Compiler.Framework; + +namespace Mosa.Platform.x64.Transforms.RuntimeCall; + +/// +/// MulCarryOut64 +/// +[Transform("x64.RuntimeCall")] +public sealed class MulCarryOut64 : BaseTransform +{ + public MulCarryOut64() : base(IRInstruction.MulCarryOut64, TransformType.Manual | TransformType.Transform) + { + } + + public override int Priority => -100; + + public override bool Match(Context context, TransformContext transform) + { + return true; + } + + public override void Transform(Context context, TransformContext transform) + { + var method = transform.GetMethod("Mosa.Runtime.Math.Multiplication", "Mul64Carry"); + + var operand1 = context.Operand1; + var operand2 = context.Operand2; + var result = context.Result; + var result2 = context.Result2; + + var v1 = transform.LocalStack.Allocate(result2); // REVIEW + var v2 = transform.VirtualRegisters.Allocate64(); + + Debug.Assert(method != null, $"Cannot find method: Mul64Carry"); + + var symbol = Operand.CreateLabel(method, transform.Is32BitPlatform); + + context.SetInstruction(IRInstruction.AddressOf, v2, v1); + context.AppendInstruction(IRInstruction.CallStatic, result, symbol, operand1, operand2, v2); + context.AppendInstruction(IRInstruction.LoadZeroExtend8x32, result2, v2, Operand.Constant64_0); + + transform.MethodScanner.MethodInvoked(method, transform.Method); + } +} diff --git a/Source/Mosa.Platform.x64/Transforms/RuntimeCall/MulOverflowOut64.cs b/Source/Mosa.Platform.x64/Transforms/RuntimeCall/MulOverflowOut64.cs new file mode 100644 index 0000000000..b5e24c38e3 --- /dev/null +++ b/Source/Mosa.Platform.x64/Transforms/RuntimeCall/MulOverflowOut64.cs @@ -0,0 +1,47 @@ +// Copyright (c) MOSA Project. Licensed under the New BSD License. + +using System.Diagnostics; +using Mosa.Compiler.Framework; + +namespace Mosa.Platform.x64.Transforms.RuntimeCall; + +/// +/// MulOverflowOut64 +/// +[Transform("x64.RuntimeCall")] +public sealed class MulOverflowOut64 : BaseTransform +{ + public MulOverflowOut64() : base(IRInstruction.MulOverflowOut64, TransformType.Manual | TransformType.Transform) + { + } + + public override int Priority => -100; + + public override bool Match(Context context, TransformContext transform) + { + return true; + } + + public override void Transform(Context context, TransformContext transform) + { + var method = transform.GetMethod("Mosa.Runtime.Math.Multiplication", "Mul64Overflow"); + + var operand1 = context.Operand1; + var operand2 = context.Operand2; + var result = context.Result; + var result2 = context.Result2; + + var v1 = transform.LocalStack.Allocate(result2); + var v2 = transform.VirtualRegisters.Allocate64(); + + Debug.Assert(method != null, $"Cannot find method: Mul64Overflow"); + + var symbol = Operand.CreateLabel(method, transform.Is32BitPlatform); + + context.SetInstruction(IRInstruction.AddressOf, v2, v1); + context.AppendInstruction(IRInstruction.CallStatic, result, symbol, operand1, operand2, v2); + context.AppendInstruction(IRInstruction.LoadZeroExtend8x32, result2, v2, Operand.Constant64_0); + + transform.MethodScanner.MethodInvoked(method, transform.Method); + } +} diff --git a/Source/Mosa.Platform.x64/Transforms/RuntimeCall/RuntimeCallTransforms.cs b/Source/Mosa.Platform.x64/Transforms/RuntimeCall/RuntimeCallTransforms.cs index 80076f2cde..5fa1b0fff4 100644 --- a/Source/Mosa.Platform.x64/Transforms/RuntimeCall/RuntimeCallTransforms.cs +++ b/Source/Mosa.Platform.x64/Transforms/RuntimeCall/RuntimeCallTransforms.cs @@ -14,15 +14,15 @@ public static class RuntimeCallTransforms { //new DivSigned64(), //new DivUnsigned64(), - //new MulCarryOut64(), - //new MulOverflowOut64(), + new MulCarryOut64(), + new MulOverflowOut64(), new RemR4(), new RemR8(), //new RemSigned64(), //new RemUnsigned64(), - //new ConvertR4ToI64(), - //new ConvertR8ToI64(), - //new ConvertR4ToU64(), - //new ConvertR8ToU64(), + new ConvertR4ToI64(), + new ConvertR8ToI64(), + new ConvertR4ToU64(), + new ConvertR8ToU64(), }; } diff --git a/Source/Mosa.Platform.x86/Intrinsic/SuppressStackFrame.cs b/Source/Mosa.Platform.x86/Intrinsic/SuppressStackFrame.cs deleted file mode 100644 index e341f800ca..0000000000 --- a/Source/Mosa.Platform.x86/Intrinsic/SuppressStackFrame.cs +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) MOSA Project. Licensed under the New BSD License. - -using Mosa.Compiler.Framework; - -namespace Mosa.Platform.x86.Intrinsic -{ - /// - /// IntrinsicMethods - /// - static partial class IntrinsicMethods - { - [IntrinsicMethod("Mosa.Platform.x86.Intrinsic:SuppressStackFrame")] - private static void SurpressStackFrame(Context context, MethodCompiler methodCompiler) - { - methodCompiler.IsStackFrameRequired = false; - context.Empty(); - } - } -} diff --git a/Source/Mosa.Platform.x86/Mosa.Platform.x86.csproj b/Source/Mosa.Platform.x86/Mosa.Platform.x86.csproj index 7a016f7640..8891140187 100644 --- a/Source/Mosa.Platform.x86/Mosa.Platform.x86.csproj +++ b/Source/Mosa.Platform.x86/Mosa.Platform.x86.csproj @@ -27,13 +27,4 @@ - - - - - - - - - diff --git a/Source/Mosa.Platform.x86/Stages/PlatformTransformationStage.cs b/Source/Mosa.Platform.x86/Stages/PlatformTransformationStage.cs index 7b9b566aa8..febf1d0aa0 100644 --- a/Source/Mosa.Platform.x86/Stages/PlatformTransformationStage.cs +++ b/Source/Mosa.Platform.x86/Stages/PlatformTransformationStage.cs @@ -24,8 +24,6 @@ public PlatformTransformationStage() AddTranforms(StackTransforms.List); AddTranforms(AddressModeTransforms.List); - //AddTranform(new GetLow32Register()); - AddTranform(new Mov32Unless()); AddTranform(new Mov32Coalescing()); AddTranform(new Deadcode()); diff --git a/Source/Mosa.Platform.x86/Transforms/IR/DivSigned32.cs b/Source/Mosa.Platform.x86/Transforms/IR/DivSigned32.cs index 506215c242..473e3e8e75 100644 --- a/Source/Mosa.Platform.x86/Transforms/IR/DivSigned32.cs +++ b/Source/Mosa.Platform.x86/Transforms/IR/DivSigned32.cs @@ -21,12 +21,11 @@ public override void Transform(Context context, TransformContext transform) var result = context.Result; var v1 = transform.VirtualRegisters.Allocate32(); + var v2 = transform.VirtualRegisters.Allocate32(); + var v3 = transform.VirtualRegisters.Allocate32(); - var eax = Operand.CreateCPURegister32(CPURegister.EAX); - var edx = Operand.CreateCPURegister32(CPURegister.EDX); - - context.SetInstruction(X86.Mov32, eax, operand1); - context.AppendInstruction(X86.Cdq32, edx, eax); - context.AppendInstruction2(X86.IDiv32, v1, result, edx, eax, operand2); + context.SetInstruction(X86.Mov32, v2, operand1); + context.AppendInstruction(X86.Cdq32, v3, v2); + context.AppendInstruction2(X86.IDiv32, v1, result, v3, v2, operand2); } } diff --git a/Source/Mosa.Platform.x86/Transforms/RuntimeCall/MulCarryOut64.cs b/Source/Mosa.Platform.x86/Transforms/RuntimeCall/MulCarryOut64.cs index 731a854fd5..41a8ab1cfc 100644 --- a/Source/Mosa.Platform.x86/Transforms/RuntimeCall/MulCarryOut64.cs +++ b/Source/Mosa.Platform.x86/Transforms/RuntimeCall/MulCarryOut64.cs @@ -24,8 +24,7 @@ public override bool Match(Context context, TransformContext transform) public override void Transform(Context context, TransformContext transform) { - var methodName = "Mul64Carry"; - var method = transform.GetMethod("Mosa.Runtime.Math.Multiplication", methodName); + var method = transform.GetMethod("Mosa.Runtime.Math.Multiplication", "Mul64Carry"); var operand1 = context.Operand1; var operand2 = context.Operand2; @@ -35,7 +34,7 @@ public override void Transform(Context context, TransformContext transform) var v1 = transform.LocalStack.Allocate(result2); // REVIEW var v2 = transform.VirtualRegisters.Allocate32(); - Debug.Assert(method != null, $"Cannot find method: {methodName}"); + Debug.Assert(method != null, $"Cannot find method: Mul64Carry"); var symbol = Operand.CreateLabel(method, transform.Is32BitPlatform); diff --git a/Source/Mosa.Platform.x86/Transforms/RuntimeCall/MulOverflowOut64.cs b/Source/Mosa.Platform.x86/Transforms/RuntimeCall/MulOverflowOut64.cs index 5e10181002..8fcba8427b 100644 --- a/Source/Mosa.Platform.x86/Transforms/RuntimeCall/MulOverflowOut64.cs +++ b/Source/Mosa.Platform.x86/Transforms/RuntimeCall/MulOverflowOut64.cs @@ -24,8 +24,7 @@ public override bool Match(Context context, TransformContext transform) public override void Transform(Context context, TransformContext transform) { - var methodName = "Mul64Overflow"; - var method = transform.GetMethod("Mosa.Runtime.Math.Multiplication", methodName); + var method = transform.GetMethod("Mosa.Runtime.Math.Multiplication", "Mul64Overflow"); var operand1 = context.Operand1; var operand2 = context.Operand2; @@ -35,7 +34,7 @@ public override void Transform(Context context, TransformContext transform) var v1 = transform.LocalStack.Allocate(result2); var v2 = transform.VirtualRegisters.Allocate32(); - Debug.Assert(method != null, $"Cannot find method: {methodName}"); + Debug.Assert(method != null, $"Cannot find method: Mul64Overflow"); var symbol = Operand.CreateLabel(method, transform.Is32BitPlatform); diff --git a/Source/Mosa.Plug.Korlib.x64/System.Threading/InterlockedPlug.cs b/Source/Mosa.Plug.Korlib.x64/System.Threading/InterlockedPlug.cs index cb7625e008..4c4271e833 100644 --- a/Source/Mosa.Plug.Korlib.x64/System.Threading/InterlockedPlug.cs +++ b/Source/Mosa.Plug.Korlib.x64/System.Threading/InterlockedPlug.cs @@ -33,4 +33,10 @@ public static IntPtr CompareExchange(ref IntPtr location1, IntPtr value, IntPtr return new IntPtr(CompareExchange(ref address, value.ToInt64(), comparand.ToInt64())); } + + [Plug("System.Threading.Interlocked::CompareExchange")] + internal static int CompareExchange(ref int location1, int value, int comparand) + { + return (int)Native.CmpXChgLoad64(location1, value, comparand); + } } diff --git a/Source/Mosa.Plug.Korlib.x86/System.Runtime.Intrinsics.X86/PopcntPlug.cs b/Source/Mosa.Plug.Korlib.x86/System.Runtime.Intrinsics.X86/PopcntPlug.cs index 0793b9f7ad..3079f54aca 100644 --- a/Source/Mosa.Plug.Korlib.x86/System.Runtime.Intrinsics.X86/PopcntPlug.cs +++ b/Source/Mosa.Plug.Korlib.x86/System.Runtime.Intrinsics.X86/PopcntPlug.cs @@ -3,11 +3,11 @@ using Mosa.Runtime.Plug; using Mosa.Runtime.x86; -namespace Mosa.Plug.Korlib.System.Runtime.Intrinsics.X86; +namespace Mosa.Plug.Korlib.System.Runtime.Intrinsics.X64; internal static class PopcntPlug { - [Plug("System.Runtime.Intrinsics.X86.Popcnt::PopCount")] + [Plug("System.Runtime.Intrinsics.X64.Popcnt::PopCount")] internal static uint PopCount(uint value) { return Native.Popcnt32(value); diff --git a/Source/Mosa.Plug.Korlib.x86/System.Threading/InterlockedPlug.cs b/Source/Mosa.Plug.Korlib.x86/System.Threading/InterlockedPlug.cs index aad72ef182..b6e0894e95 100644 --- a/Source/Mosa.Plug.Korlib.x86/System.Threading/InterlockedPlug.cs +++ b/Source/Mosa.Plug.Korlib.x86/System.Threading/InterlockedPlug.cs @@ -33,4 +33,11 @@ public static IntPtr CompareExchange(ref IntPtr location1, IntPtr value, IntPtr return new IntPtr(CompareExchange(ref address, value.ToInt32(), comparand.ToInt32())); } + + [Plug("System.Threading.Interlocked::CompareExchange")] + internal static long CompareExchange(ref long location1, long value, long comparand) + { + int location = (int)location1; + return Native.CmpXChgLoad32(location, (int)value, (int)comparand); + } } diff --git a/Source/Mosa.Runtime.x64/Native.cs b/Source/Mosa.Runtime.x64/Native.cs index a775f8b399..07d0f29ad4 100644 --- a/Source/Mosa.Runtime.x64/Native.cs +++ b/Source/Mosa.Runtime.x64/Native.cs @@ -68,7 +68,7 @@ public static unsafe class Native [DllImport("Mosa.Platform.x64.Intrinsic::Int")] public static extern void Int(byte interrupt); - [DllImport("Mosa.Platform.x86.Intrinsic::Blsr32")] + [DllImport("Mosa.Platform.x64.Intrinsic::Blsr32")] public static extern uint Blsr32(uint esp); [DllImport("Mosa.Platform.x64.Intrinsic::Blsr64")] @@ -86,10 +86,10 @@ public static unsafe class Native //[DllImport("Mosa.Platform.x64.Intrinsic::Lzcnt64")] //public static extern uint Lzcnt64(uint esp); - //[DllImport("Mosa.Platform.x86.Intrinsic::Tzcnt32")] + //[DllImport("Mosa.Platform.x64.Intrinsic::Tzcnt32")] //public static extern uint Tzcnt32(uint esp); - //[DllImport("Mosa.Platform.x86.Intrinsic::Tzcnt64")] + //[DllImport("Mosa.Platform.x64.Intrinsic::Tzcnt64")] //public static extern uint Tzcnt64(uint esp); #endregion Intrinsic Instructions diff --git a/Source/Mosa.Runtime/Math/CheckedConversion.cs b/Source/Mosa.Runtime/Math/CheckedConversion.cs index 01f98483bf..cc4ac96441 100644 --- a/Source/Mosa.Runtime/Math/CheckedConversion.cs +++ b/Source/Mosa.Runtime/Math/CheckedConversion.cs @@ -25,6 +25,7 @@ public static long R4ToI8(float value) // 0x402 is epsilon used to get us to the next value if (!(r8Value > -two63 - 0x402 && r8Value < two63)) Internal.ThrowOverflowException(); + return (long)value; } @@ -36,6 +37,7 @@ public static long R8ToI8(double value) // 0x402 is epsilon used to get us to the next value if (!(value > -two63 - 0x402 && value < two63)) Internal.ThrowOverflowException(); + return (long)value; } diff --git a/Source/Mosa.Tool.Compiler/Compiler.cs b/Source/Mosa.Tool.Compiler/Compiler.cs index 2e0c47a3b0..97653f2152 100644 --- a/Source/Mosa.Tool.Compiler/Compiler.cs +++ b/Source/Mosa.Tool.Compiler/Compiler.cs @@ -19,13 +19,6 @@ public class Compiler private DateTime CompileStartTime; - /// - /// A string holding a simple usage description. - /// - private readonly string usageString = @"Usage: Mosa.Tool.Compiler.exe -o outputfile --platform [x86|x64] {additional options} inputfiles. - -Example: Mosa.Tool.Compiler.exe -o Mosa.HelloWorld.x86.bin -platform x86 Mosa.HelloWorld.x86.dll System.Runtime.dll Mosa.Plug.Korlib.dll Mosa.Plug.Korlib.x86.dll"; - #endregion Data #region Public Methods @@ -77,8 +70,8 @@ public void Run(string[] args) Trace.Listeners.Add(new TextWriterTraceListener(Console.Out)); Debug.AutoFlush = true; - Console.WriteLine($" > Output file: {compiler.MosaSettings.OutputFile}"); Console.WriteLine($" > Input file(s): {string.Join(", ", new List(compiler.MosaSettings.SourceFiles.ToArray()))}"); + Console.WriteLine($" > Output file: {compiler.MosaSettings.OutputFile}"); Console.WriteLine($" > Platform: {compiler.MosaSettings.Platform}"); Console.WriteLine(); @@ -91,7 +84,8 @@ public void Run(string[] args) } catch (Exception ce) { - ShowError(ce.Message); + Output($"Exception: {ce.Message}"); + Output($"Exception: {ce.StackTrace}"); Environment.Exit(1); return; } @@ -136,23 +130,13 @@ private void NotifyEvent(CompilerEvent compilerEvent, string message, int thread && compilerEvent != CompilerEvent.FinalizationStageEnd) { message = string.IsNullOrWhiteSpace(message) ? string.Empty : $": {message}"; - Console.WriteLine($"{(DateTime.Now - CompileStartTime).TotalSeconds:0.00} [{threadID}] {compilerEvent.ToText()}{message}"); + Output($"[{threadID}] {compilerEvent.ToText()}{message}"); } } - /// - /// Shows an error and a short information text. - /// - /// The error message to show. - private void ShowError(string message) + private void Output(string log) { - Console.WriteLine(usageString); - Console.WriteLine(); - Console.Write("Error: "); - Console.WriteLine(message); - Console.WriteLine(); - Console.WriteLine("Execute 'Mosa.Tool.Compiler.exe --help' for more information."); - Console.WriteLine(); + Console.WriteLine($"{(DateTime.Now - CompileStartTime).TotalSeconds:0.00} | {log}"); } #endregion Private Methods diff --git a/Source/Mosa.Tool.Explorer/MainForm.cs b/Source/Mosa.Tool.Explorer/MainForm.cs index 494b12cdde..765fb586d7 100644 --- a/Source/Mosa.Tool.Explorer/MainForm.cs +++ b/Source/Mosa.Tool.Explorer/MainForm.cs @@ -86,7 +86,6 @@ public MainForm() RegisterPlatforms(); - Stopwatch.Restart(); } @@ -1376,9 +1375,8 @@ private void PopulateTransformList() return; var list = new List(); - //{ - // new TranformEntry() { ID = -1, Name = "***Start***" } - //}; + + list.Add(new TranformEntry() { ID = 0, Name = "***Start***" }); var pass = 0; TranformEntry entry = null; @@ -1417,11 +1415,12 @@ private void PopulateTransformList() continue; } - entry = new TranformEntry(); - - entry.ID = Convert.ToInt32(parts[0].Trim()); - entry.Name = part1; - entry.Pass = pass; + entry = new TranformEntry + { + ID = Convert.ToInt32(parts[0].Trim()) + 1, + Name = part1, + Pass = pass + }; list.Add(entry); } diff --git a/Source/Mosa.Tool.Launcher.Console/Properties/launchSettings.json b/Source/Mosa.Tool.Launcher.Console/Properties/launchSettings.json index 99fb4e4f94..1946a0782c 100644 --- a/Source/Mosa.Tool.Launcher.Console/Properties/launchSettings.json +++ b/Source/Mosa.Tool.Launcher.Console/Properties/launchSettings.json @@ -2,7 +2,7 @@ "profiles": { "Mosa.Tool.Launcher.Console": { "commandName": "Project", - "commandLineArgs": "Mosa.BareMetal.HelloWorld.x86.dll -test", + "commandLineArgs": "Mosa.Demo.TestWorld.x64.dll -check -x64 -o5", "workingDirectory": "..\\..\\bin" } } diff --git a/Source/Mosa.UnitTests/Basic/ConvFloatTests.cs b/Source/Mosa.UnitTests/Basic/ConvFloatTests.cs index 5dcd85fb2e..bebff3ef26 100644 --- a/Source/Mosa.UnitTests/Basic/ConvFloatTests.cs +++ b/Source/Mosa.UnitTests/Basic/ConvFloatTests.cs @@ -45,4 +45,45 @@ public static ulong ConvR8U8(double a) { return (ulong)a; } + + public static int ConvR4I4(float a) + { + return (int)a; + } + + [MosaUnitTest(0.0f)] + [MosaUnitTest(1.0f)] + [MosaUnitTest(2.0f)] + [MosaUnitTest(3.0f)] + [MosaUnitTest(100000.0f)] + [MosaUnitTest(-1.0f)] + [MosaUnitTest(-2.0f)] + [MosaUnitTest(-100000.0f)] + public static uint ConvR4U4(float a) + { + return (uint)a; + } + + [MosaUnitTest(Series = "R8")] + public static int ConvR8I4(double a) + { + return (int)a; + } + + [MosaUnitTest(0d)] + [MosaUnitTest(1d)] + [MosaUnitTest(2d)] + [MosaUnitTest(3d)] + [MosaUnitTest(100000.0d)] + [MosaUnitTest(-1d)] + [MosaUnitTest(-2d)] + [MosaUnitTest(-1.00012d)] + [MosaUnitTest(17.0002501d)] + [MosaUnitTest(23d)] + [MosaUnitTest(-23d)] + [MosaUnitTest(-17.0002501d)] + public static uint ConvR8U4(double a) + { + return (uint)a; + } } diff --git a/Source/Mosa.Utility.Configuration/CommandLineArguments.cs b/Source/Mosa.Utility.Configuration/CommandLineArguments.cs index 59f77c3f4f..5e678aadf1 100644 --- a/Source/Mosa.Utility.Configuration/CommandLineArguments.cs +++ b/Source/Mosa.Utility.Configuration/CommandLineArguments.cs @@ -72,6 +72,7 @@ private static List GetMap() new Argument { Name = "-x86", Setting = Name.Compiler_Platform, Value= "x86"}, new Argument { Name = "-x64", Setting = Name.Compiler_Platform, Value= "x64"}, new Argument { Name = "-armv8a32", Setting = Name.Compiler_Platform, Value= "armv8a32"}, + new Argument { Name = "-arm32", Setting = Name.Compiler_Platform, Value= "armv8a32"}, new Argument { Name = "-interrupt-method", Setting = Name.X86_InterruptMethodName}, diff --git a/Source/Mosa.Utility.Configuration/MOSASettings.cs b/Source/Mosa.Utility.Configuration/MOSASettings.cs index fcef2f6fa1..adf4685a83 100644 --- a/Source/Mosa.Utility.Configuration/MOSASettings.cs +++ b/Source/Mosa.Utility.Configuration/MOSASettings.cs @@ -764,6 +764,10 @@ public void NormalizeSettings() Emulator = Emulator == null ? string.Empty : Emulator.ToLowerInvariant().Trim(); Platform = Platform == null ? string.Empty : Platform.ToLowerInvariant().Trim(); LinkerFormat = LinkerFormat == null ? string.Empty : LinkerFormat.ToLowerInvariant().Trim(); + + // special case - to match with DLL + if (Platform == "armv8a32") + Platform = "ARMv8A32"; } public void UpdateFileAndPathSettings() diff --git a/Source/Mosa.Utility.SourceCodeGenerator/BuildBaseTemplate.cs b/Source/Mosa.Utility.SourceCodeGenerator/BuildBaseTemplate.cs index 2838db4167..7a74e472c7 100644 --- a/Source/Mosa.Utility.SourceCodeGenerator/BuildBaseTemplate.cs +++ b/Source/Mosa.Utility.SourceCodeGenerator/BuildBaseTemplate.cs @@ -9,7 +9,9 @@ namespace Mosa.Utility.SourceCodeGenerator; public class BuildBaseTemplate { public string JsonFile { get; } + public string DestinationPath { get; } + protected string DestinationFile { get; set; } protected StringBuilder Lines { get; } = new StringBuilder(); diff --git a/Source/Mosa.Utility.SourceCodeGenerator/BuildIRInstructionFiles.cs b/Source/Mosa.Utility.SourceCodeGenerator/BuildIRInstructionFiles.cs index eb6c240509..f656d050fa 100644 --- a/Source/Mosa.Utility.SourceCodeGenerator/BuildIRInstructionFiles.cs +++ b/Source/Mosa.Utility.SourceCodeGenerator/BuildIRInstructionFiles.cs @@ -50,12 +50,6 @@ protected override void Body(dynamic node = null) Lines.AppendLine("\t{"); Lines.AppendLine("\t}"); - //if (node.FlowControl != null && node.FlowControl != "Next") - //{ - // Lines.AppendLine(); - // Lines.AppendLine("\tpublic override FlowControl FlowControl => FlowControl." + node.FlowControl + ";"); - //} - if (node.FlowControl != null && node.FlowControl != "Next") { Lines.AppendLine(); diff --git a/Source/Mosa.Utility.SourceCodeGenerator/BuildTransformations.cs b/Source/Mosa.Utility.SourceCodeGenerator/BuildTransformations.cs index 80e185afda..f0e73b2d28 100644 --- a/Source/Mosa.Utility.SourceCodeGenerator/BuildTransformations.cs +++ b/Source/Mosa.Utility.SourceCodeGenerator/BuildTransformations.cs @@ -1,7 +1,6 @@ // Copyright (c) MOSA Project. Licensed under the New BSD License. using System.Collections.Generic; -using System.Security; using System.Text; using Mosa.Utility.SourceCodeGenerator.TransformExpressions; @@ -59,7 +58,9 @@ protected override void Body(dynamic node = null) string subName = node.SubName; string expression = node.Expression; string filter = node.Filter; + string prefilter = node.Prefilter; string result = node.Result; + bool log = node.Log != null && node.Log == "Yes"; bool variations = node.Variations != null && node.Variations == "Yes"; @@ -75,24 +76,24 @@ protected override void Body(dynamic node = null) if (!optimization && !transformation) optimization = true; - GenerateTranformations(name, Family, type, subName, expression, filter, result, variations, log, optimization, priority); + GenerateTranformations(name, Family, type, subName, expression, filter, prefilter, result, variations, log, optimization, priority); } - private void GenerateTranformations(string name, string familyName, string type, string subName, string expression, string filter, string result, bool variations, bool log, bool optimization, int priority) + private void GenerateTranformations(string name, string familyName, string type, string subName, string expression, string filter, string prefilter, string result, bool variations, bool log, bool optimization, int priority) { if (expression.Contains("R#")) { - GenerateTransformation(R4(name), R4(familyName), R4(type), R4(subName), new Transformation(R4(expression), R4(filter), R4(result)), variations, log, optimization, priority); - GenerateTransformation(R8(name), R8(familyName), R8(type), R8(subName), new Transformation(R8(expression), R8(filter), R8(result)), variations, log, optimization, priority); + GenerateTransformation(R4(name), R4(familyName), R4(type), R4(subName), new Transformation(R4(expression), R4(filter), R4(result), prefilter), variations, log, optimization, priority); + GenerateTransformation(R8(name), R8(familyName), R8(type), R8(subName), new Transformation(R8(expression), R8(filter), R8(result), prefilter), variations, log, optimization, priority); } else if (expression.Contains("##")) { - GenerateTransformation(To32(name), To32(familyName), To32(type), To32(subName), new Transformation(To32(expression), To32(filter), To32(result)), variations, log, optimization, priority); - GenerateTransformation(To64(name), To64(familyName), To64(type), To64(subName), new Transformation(To64(expression), To64(filter), To64(result)), variations, log, optimization, priority); + GenerateTransformation(To32(name), To32(familyName), To32(type), To32(subName), new Transformation(To32(expression), To32(filter), To32(result), prefilter), variations, log, optimization, priority); + GenerateTransformation(To64(name), To64(familyName), To64(type), To64(subName), new Transformation(To64(expression), To64(filter), To64(result), prefilter), variations, log, optimization, priority); } else { - GenerateTransformation(name, familyName, type, subName, new Transformation(expression, filter, result), variations, log, optimization, priority); + GenerateTransformation(name, familyName, type, subName, new Transformation(expression, filter, result, prefilter), variations, log, optimization, priority); } } @@ -186,13 +187,12 @@ private void GenerateTransformation2(string name, string familyName, string type Lines.AppendLine($"public sealed class {name}{subName} : BaseTransform"); Lines.AppendLine("{"); - var typestring = "TransformType.Auto" + - (optimization ? " | TransformType.Optimization" : string.Empty); + var typestring = $"TransformType.Auto{(optimization ? " | TransformType.Optimization" : string.Empty)}"; if (log) - Lines.AppendLine($"\tpublic {name}{subName}() : base({instructionName}, " + typestring + ", true)"); + Lines.AppendLine($"\tpublic {name}{subName}() : base({instructionName}, {typestring}, true)"); else - Lines.AppendLine($"\tpublic {name}{subName}() : base({instructionName}, " + typestring + ")"); + Lines.AppendLine($"\tpublic {name}{subName}() : base({instructionName}, {typestring})"); Lines.AppendLine("\t{"); Lines.AppendLine("\t}"); @@ -207,6 +207,8 @@ private void GenerateTransformation2(string name, string familyName, string type Lines.AppendLine("\tpublic override bool Match(Context context, TransformContext transform)"); Lines.AppendLine("\t{"); + ProcessPrefilters(transform); + ProcessExpressionNode(transform.InstructionTree); ProcessDuplicatesInExpression(transform); @@ -324,9 +326,6 @@ private void ProcessResultInstructionTree(Transformation transform) { methodToMethodNbr.Add(operand.Method, found); continue; - - //Lines.AppendLine($"\t\tvar e{found} = Operand.CreateConstant({name});"); - //continue; } methodNbr++; @@ -517,6 +516,62 @@ private void ProcessDuplicatesInExpression(Transformation transform) } } + private void ProcessPrefilters(Transformation transform) + { + var filters = transform.Prefilters; + + foreach (var filter in filters) + { + var sb = new StringBuilder(); + + if (!filter.IsNegated) + sb.Append('!'); + + sb.Append(ProcessPrefilters(filter, transform)); + + EmitCondition(sb.ToString()); + } + } + + private string ProcessPrefilters(Method filter, Transformation transform) + { + var sb = new StringBuilder(); + + sb.Append("transform."); + sb.Append(filter.MethodName); + sb.Append('('); + + foreach (var parameter in filter.Parameters) + { + if (parameter.IsInteger) + { + sb.Append(CreateConstantName(parameter)); + } + else if (parameter.IsDouble) + { + sb.Append(CreateConstantName(parameter)); + } + else if (parameter.IsFloat) + { + sb.Append(CreateConstantName(parameter)); + } + if (parameter.IsAt) + { + sb.Length--; + return sb.ToString(); + } + + sb.Append(", "); + } + + if (filter.Parameters.Count != 0) + sb.Length -= 2; + + sb.Append(')'); + + return sb.ToString(); + } + private void ProcessFilters(Transformation transform) { var filters = transform.Filters; @@ -579,21 +634,14 @@ private string ProcessFilters(Method filter, Transformation transform) else if (parameter.IsInteger) { sb.Append(CreateConstantName(parameter)); - - //sb.Append(parameter.Integer.ToString()); } else if (parameter.IsDouble) { sb.Append(CreateConstantName(parameter)); - - //sb.Append(parameter.Double.ToString()); } else if (parameter.IsFloat) { sb.Append(CreateConstantName(parameter)); - - //sb.Append(parameter.Float.ToString()); - //sb.Append('f'); } if (!register) diff --git a/Source/Mosa.Utility.SourceCodeGenerator/Program.cs b/Source/Mosa.Utility.SourceCodeGenerator/Program.cs index 5602eb6145..e3cfeaf404 100644 --- a/Source/Mosa.Utility.SourceCodeGenerator/Program.cs +++ b/Source/Mosa.Utility.SourceCodeGenerator/Program.cs @@ -85,6 +85,13 @@ public static void Main() "Mosa.Compiler.Framework" ).Execute(); + new BuildTransformations( + Path.Combine(dataPath, @"IR-Optimizations-LowerTo32.json"), + Path.Combine(targetPath, @"Mosa.Compiler.Framework\Transforms\Optimizations\Auto"), + "Mosa.Compiler.Framework", + "Mosa.Compiler.Framework" + ).Execute(); + new BuildTransformations( Path.Combine(dataPath, @"IR-Optimizations-Algebraic.json"), Path.Combine(targetPath, @"Mosa.Compiler.Framework\Transforms\Optimizations\Auto"), @@ -215,22 +222,5 @@ public static void Main() Path.Combine(dataPath, @"ARMv8A32-Instructions.json"), Path.Combine(targetPath, @"Mosa.Platform.ARMv8A32\Instructions") ).Execute(); - - //new BuildESP32( - // Path.Combine(dataPath, @"ESP32-Instructions.json"), - // Path.Combine(targetPath, @"Mosa.Platform.ESP32\"), - // "ESP32.cs" - //).Execute(); - - //new BuildESP32Instructions( - // Path.Combine(dataPath, @"ESP32-Instructions.json"), - // Path.Combine(targetPath, @"Mosa.Platform.ESP32\"), - // "ESP32Instructions.cs" - //).Execute(); - - //new BuildESP32InstructionFiles( - // Path.Combine(dataPath, @"ESP32-Instructions.json"), - // Path.Combine(targetPath, @"Mosa.Platform.ESP32\Instructions") - //).Execute(); } } diff --git a/Source/Mosa.Utility.SourceCodeGenerator/TransformExpressions/PrefilterParser.cs b/Source/Mosa.Utility.SourceCodeGenerator/TransformExpressions/PrefilterParser.cs new file mode 100644 index 0000000000..6a7d6c80ac --- /dev/null +++ b/Source/Mosa.Utility.SourceCodeGenerator/TransformExpressions/PrefilterParser.cs @@ -0,0 +1,106 @@ +// Copyright (c) MOSA Project. Licensed under the New BSD License. + +using System; +using System.Collections.Generic; + +namespace Mosa.Utility.SourceCodeGenerator.TransformExpressions; + +public static class PrefilterParser +{ + public static List ParseAll(List tokens) + { + var methods = new List(); + + var length = tokens.Count; + var index = 0; + + while (index < length) + { + var (method, end) = ParseMethod(tokens, index); + + index = end; + methods.Add(method); + } + + return methods; + } + + private static (Method method, int end) ParseMethod(List tokens, int start) + { + var method = new Method(); + var length = tokens.Count; + + // skip ANDs + while (start != length && tokens[start].TokenType == TokenType.And) + { + start++; + } + + for (var index = start; index < length;) + { + var token = tokens[index++]; + + if (token.TokenType == TokenType.Not && method.MethodName == null) + { + method.IsNegated = true; + } + else if (token.TokenType == TokenType.Word && method.MethodName == null) + { + method.MethodName = token.Value; + index++; // skip open param + } + else if (token.TokenType == TokenType.Word && method.MethodName != null) + { + // peak ahead + var next = tokens[index]; + + if (next.TokenType == TokenType.OpenParens) + { + var (innermethod, end) = ParseMethod(tokens, index - 1); + + index = end; + + method.Parameters.Add(new Operand(innermethod, method.Parameters.Count)); + } + else + { + method.Parameters.Add(new Operand(new Token(TokenType.Label, token.Position, token.Value), method.Parameters.Count)); + } + } + else if (token.TokenType == TokenType.IntegerConstant) + { + method.Parameters.Add(new Operand(token, method.Parameters.Count)); + } + else if (token.TokenType == TokenType.DoubleConstant) + { + method.Parameters.Add(new Operand(token, method.Parameters.Count)); + } + else if (token.TokenType == TokenType.FloatConstant) + { + method.Parameters.Add(new Operand(token, method.Parameters.Count)); + } + else if (token.TokenType == TokenType.At && method.MethodName != null) + { + method.Parameters.Add(new Operand(token, method.Parameters.Count)); + } + else if (token.TokenType == TokenType.Percent && method.MethodName != null) + { + method.Parameters.Add(new Operand(token, method.Parameters.Count)); + } + else if (token.TokenType == TokenType.Comma) + { + // skip + } + else if (token.TokenType == TokenType.CloseParens) + { + return (method, index); + } + else + { + throw new Exception($"parsing error {token}"); + } + } + + throw new Exception($"parsing error unexpected end"); + } +} diff --git a/Source/Mosa.Utility.SourceCodeGenerator/TransformExpressions/Token.cs b/Source/Mosa.Utility.SourceCodeGenerator/TransformExpressions/Token.cs index ac3a273c78..258d91be4a 100644 --- a/Source/Mosa.Utility.SourceCodeGenerator/TransformExpressions/Token.cs +++ b/Source/Mosa.Utility.SourceCodeGenerator/TransformExpressions/Token.cs @@ -5,15 +5,21 @@ namespace Mosa.Utility.SourceCodeGenerator.TransformExpressions; public class Token { public TokenType TokenType { get; protected set; } + public string Value { get; protected set; } + public int Position { get; protected set; } = -1; public bool IsInteger => TokenType == TokenType.IntegerConstant; + public bool IsFloat => TokenType == TokenType.FloatConstant; + public bool IsDouble => TokenType == TokenType.DoubleConstant; + public ulong Integer { get; set; } public double Double { get; } + public double Float { get; } public Token(TokenType tokenType, int index) diff --git a/Source/Mosa.Utility.SourceCodeGenerator/TransformExpressions/Tokenizer.cs b/Source/Mosa.Utility.SourceCodeGenerator/TransformExpressions/Tokenizer.cs index add5ce7851..ce8a37bdb5 100644 --- a/Source/Mosa.Utility.SourceCodeGenerator/TransformExpressions/Tokenizer.cs +++ b/Source/Mosa.Utility.SourceCodeGenerator/TransformExpressions/Tokenizer.cs @@ -11,6 +11,10 @@ public static class Tokenizer public static List Parse(string expression) { var tokens = new List(); + + if (expression == null) + return tokens; + var length = expression.Length; var index = 0; diff --git a/Source/Mosa.Utility.SourceCodeGenerator/TransformExpressions/Transformation.cs b/Source/Mosa.Utility.SourceCodeGenerator/TransformExpressions/Transformation.cs index 43c4c0b969..88b27b5aeb 100644 --- a/Source/Mosa.Utility.SourceCodeGenerator/TransformExpressions/Transformation.cs +++ b/Source/Mosa.Utility.SourceCodeGenerator/TransformExpressions/Transformation.cs @@ -8,40 +8,47 @@ public class Transformation { public readonly string ExpressionText; public readonly string FilterText; + public readonly string PrefilterText; public readonly string ResultText; protected readonly List TokenizedExpression; protected readonly List TokenizedFilter; protected readonly List TokenizedResult; + protected readonly List TokenizedPrefilter; public readonly LabelSet LabelSet; public readonly InstructionNode InstructionTree; public readonly InstructionNode ResultInstructionTree; public readonly List Filters; + public readonly List Prefilters; - public Transformation(string expression, string filter, string result) + public Transformation(string expression, string filter, string result, string prefilterText) { ExpressionText = expression; FilterText = filter; ResultText = result; + PrefilterText = prefilterText; TokenizedExpression = Tokenizer.Parse(ExpressionText); TokenizedFilter = Tokenizer.Parse(FilterText); + TokenizedPrefilter = Tokenizer.Parse(PrefilterText); TokenizedResult = Tokenizer.Parse(ResultText); InstructionTree = InstructionParser.Parse(TokenizedExpression); ResultInstructionTree = ResultParser.Parse(TokenizedResult); Filters = FilterParser.ParseAll(TokenizedFilter); + Prefilters = PrefilterParser.ParseAll(TokenizedPrefilter); LabelSet = new LabelSet(InstructionTree); LabelSet.AddUse(ResultInstructionTree); } - private Transformation(InstructionNode instructionTree, InstructionNode resultInstructionTree, List filters) + private Transformation(InstructionNode instructionTree, InstructionNode resultInstructionTree, List filters, List prefilters) { InstructionTree = instructionTree; ResultInstructionTree = resultInstructionTree; Filters = filters; + Prefilters = prefilters; LabelSet = new LabelSet(InstructionTree); LabelSet.AddUse(ResultInstructionTree); @@ -352,7 +359,7 @@ private Transformation CreateVariation(List cumulativeInstructions, int } } - return new Transformation(instructionTree, ResultInstructionTree, Filters); + return new Transformation(instructionTree, ResultInstructionTree, Filters, Prefilters); } public static ConditionCode GetReverse(ConditionCode conditionCode) diff --git a/Source/Mosa.Utility.UnitTests/Numbers/R4.cs b/Source/Mosa.Utility.UnitTests/Numbers/R4.cs index 5fa6c9938d..12f4b4bf9f 100644 --- a/Source/Mosa.Utility.UnitTests/Numbers/R4.cs +++ b/Source/Mosa.Utility.UnitTests/Numbers/R4.cs @@ -36,10 +36,10 @@ public static IList GetSeries() 17.0002501f, 23f, 12321452132.561f, - - // negatives - -1, - -2, + 17f, + 12321452132f,// negatives + -1f, + -2f, -1.00012f, -17.0002501f, -23f, diff --git a/Source/Mosa.Utility.UnitTests/Numbers/R8.cs b/Source/Mosa.Utility.UnitTests/Numbers/R8.cs index e6a204c29d..4da6b25fa4 100644 --- a/Source/Mosa.Utility.UnitTests/Numbers/R8.cs +++ b/Source/Mosa.Utility.UnitTests/Numbers/R8.cs @@ -24,25 +24,29 @@ public static IList GetSeries() { var list = new List { - 0, - 1, - 2, - - //list.Add(double.MinValue); - //list.Add(double.MaxValue); + 0d, + 1d, + 2d, + double.MinValue, + double.MaxValue, double.NaN, double.PositiveInfinity, double.NegativeInfinity, - 17, - 23, - 12321452132, - + 1.00012d, + 17.0002501d, + 23d, + 12321452132.561d, + 17d, + 12321452132d, // negatives - -1, - -2, - -17, - -23, - -12321452132 + -1d, + -2d, + -17d, + -23d, + -12321452132d + -1.00012d, + -17.0002501d, + -12321452132.561d }; list = list.Distinct().ToList(); diff --git a/Source/Mosa.sln b/Source/Mosa.sln index d185b0b857..978fb403e8 100644 --- a/Source/Mosa.sln +++ b/Source/Mosa.sln @@ -163,6 +163,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Transforms", "Transforms", Data\IR-Optimizations-ConstantFolding.json = Data\IR-Optimizations-ConstantFolding.json Data\IR-Optimizations-ConstantMove-Expression.json = Data\IR-Optimizations-ConstantMove-Expression.json Data\IR-Optimizations-ConstantMove.json = Data\IR-Optimizations-ConstantMove.json + Data\IR-Optimizations-LowerTo32.json = Data\IR-Optimizations-LowerTo32.json Data\IR-Optimizations-Phi.json = Data\IR-Optimizations-Phi.json Data\IR-Optimizations-Reorder.json = Data\IR-Optimizations-Reorder.json Data\IR-Optimizations-Rewrite.json = Data\IR-Optimizations-Rewrite.json