From 5f85210b5dfe39edcc7fab273b2a88e6897e6f85 Mon Sep 17 00:00:00 2001 From: Phil Date: Sun, 30 Jul 2023 18:21:07 -0700 Subject: [PATCH 01/11] - WIP --- Source/Mosa.Kernel.BareMetal/Boot.cs | 107 +++++++++--------- Source/Mosa.Kernel.BareMetal/BootOptions.cs | 1 + Source/Mosa.Kernel.BareMetal/Kernel.cs | 10 ++ .../{ConsoleColor.cs => ScreenColor.cs} | 2 +- .../{Console.cs => ScreenConsole.cs} | 14 +-- Source/Mosa.UnitTests.BareMetal.x86/Boot.cs | 14 +-- .../UnitTestEngine.cs | 22 ++-- 7 files changed, 91 insertions(+), 79 deletions(-) create mode 100644 Source/Mosa.Kernel.BareMetal/Kernel.cs rename Source/Mosa.Kernel.BareMetal/{ConsoleColor.cs => ScreenColor.cs} (91%) rename Source/Mosa.Kernel.BareMetal/{Console.cs => ScreenConsole.cs} (88%) diff --git a/Source/Mosa.Kernel.BareMetal/Boot.cs b/Source/Mosa.Kernel.BareMetal/Boot.cs index 6abbeb8a62..6f53ef7adf 100644 --- a/Source/Mosa.Kernel.BareMetal/Boot.cs +++ b/Source/Mosa.Kernel.BareMetal/Boot.cs @@ -18,23 +18,23 @@ public static void PlatformInitialization() BootStatus.Initalize(); - Console.SetBackground(ConsoleColor.Black); - Console.ClearScreen(); + ScreenConsole.SetBackground(ScreenColor.Black); + ScreenConsole.ClearScreen(); - Console.WriteLine(ConsoleColor.BrightYellow, "MOSA BareMetal v0.1"); + ScreenConsole.WriteLine(ScreenColor.BrightYellow, "MOSA BareMetal v0.1"); - Console.WriteLine(); + ScreenConsole.WriteLine(); - Console.WriteLine(ConsoleColor.BrightYellow, "Initializing kernel..."); + ScreenConsole.WriteLine(ScreenColor.BrightYellow, "Initializing kernel..."); Debug.Setup(true); - Console.Write(ConsoleColor.BrightGreen, "> Initial garbage collection..."); + ScreenConsole.Write(ScreenColor.BrightGreen, "> Initial garbage collection..."); InitialGCMemory.Initialize(); - Console.WriteLine(ConsoleColor.BrightBlack, " [Completed]"); + ScreenConsole.WriteLine(ScreenColor.BrightBlack, " [Completed]"); - Console.Write(ConsoleColor.BrightGreen, "> Platform initialization..."); + ScreenConsole.Write(ScreenColor.BrightGreen, "> Platform initialization..."); Platform.EntryPoint(); - Console.WriteLine(ConsoleColor.BrightBlack, " [Completed]"); + ScreenConsole.WriteLine(ScreenColor.BrightBlack, " [Completed]"); } [Plug("Mosa.Runtime.StartUp::KernelEntryPoint")] @@ -42,97 +42,98 @@ public static void EntryPoint() { Debug.WriteLine("[Entry Point]"); - Console.Write(ConsoleColor.BrightGreen, "> Enabling debug logging..."); + ScreenConsole.Write(ScreenColor.BrightGreen, "> Enabling debug logging..."); Debug.Setup(true); - Console.WriteLine(ConsoleColor.BrightBlack, " [Completed]"); + ScreenConsole.WriteLine(ScreenColor.BrightBlack, " [Completed]"); - Console.Write(ConsoleColor.BrightGreen, "> Boot page allocator..."); + ScreenConsole.Write(ScreenColor.BrightGreen, "> Boot page allocator..."); BootPageAllocator.Setup(); - Console.WriteLine(ConsoleColor.BrightBlack, " [Completed]"); + ScreenConsole.WriteLine(ScreenColor.BrightBlack, " [Completed]"); - Console.Write(ConsoleColor.BrightGreen, "> Memory map..."); + ScreenConsole.Write(ScreenColor.BrightGreen, "> Memory map..."); BootMemoryMap.Setup(); BootMemoryMap.Dump(); - Console.WriteLine(ConsoleColor.BrightBlack, " [Completed]"); + ScreenConsole.WriteLine(ScreenColor.BrightBlack, " [Completed]"); - Console.Write(ConsoleColor.BrightGreen, "> Physical page allocator..."); + ScreenConsole.Write(ScreenColor.BrightGreen, "> Physical page allocator..."); PageFrameAllocator.Setup(); - Console.WriteLine(ConsoleColor.BrightBlack, " [Completed]"); + ScreenConsole.WriteLine(ScreenColor.BrightBlack, " [Completed]"); - Console.Write(ConsoleColor.BrightGreen, "> Page table..."); + ScreenConsole.Write(ScreenColor.BrightGreen, "> Page table..."); PageTable.Setup(); - Console.WriteLine(ConsoleColor.BrightBlack, " [Completed]"); + ScreenConsole.WriteLine(ScreenColor.BrightBlack, " [Completed]"); - Console.Write(ConsoleColor.BrightGreen, "> Virtual page allocator..."); + ScreenConsole.Write(ScreenColor.BrightGreen, "> Virtual page allocator..."); VirtualPageAllocator.Setup(); - Console.WriteLine(ConsoleColor.BrightBlack, " [Completed]"); + ScreenConsole.WriteLine(ScreenColor.BrightBlack, " [Completed]"); - Console.Write(ConsoleColor.BrightGreen, "> Interrupt Manager..."); + ScreenConsole.Write(ScreenColor.BrightGreen, "> Interrupt Manager..."); InterreuptManager.Setup(); - Console.WriteLine(ConsoleColor.BrightBlack, " [Completed]"); + ScreenConsole.WriteLine(ScreenColor.BrightBlack, " [Completed]"); - Console.Write(ConsoleColor.BrightGreen, "> Garbage collection..."); + ScreenConsole.Write(ScreenColor.BrightGreen, "> Garbage collection..."); GCMemory.Setup(); - Console.WriteLine(ConsoleColor.BrightBlack, " [Completed]"); - Console.Write(ConsoleColor.BrightGreen, "> Interrupt Handler..."); + ScreenConsole.WriteLine(ScreenColor.BrightBlack, " [Completed]"); + ScreenConsole.Write(ScreenColor.BrightGreen, "> Interrupt Handler..."); InterreuptManager.SetHandler(null); - Console.WriteLine(ConsoleColor.BrightBlack, " [Completed]"); + ScreenConsole.WriteLine(ScreenColor.BrightBlack, " [Completed]"); - Console.Write(ConsoleColor.BrightGreen, "> Virtual memory allocator..."); + ScreenConsole.Write(ScreenColor.BrightGreen, "> Virtual memory allocator..."); VirtualMemoryAllocator.Setup(); - Console.WriteLine(ConsoleColor.BrightBlack, " [Completed]"); + ScreenConsole.WriteLine(ScreenColor.BrightBlack, " [Completed]"); //Console.Write(ConsoleColor.BrightGreen, "> Scheduler..."); //Scheduler.Setup(); //Console.WriteLine(ConsoleColor.BrightBlack, " [Completed]"); - Console.Write(ConsoleColor.BrightGreen, "> Hardware abstraction layer..."); + ScreenConsole.Write(ScreenColor.BrightGreen, "> Hardware abstraction layer..."); var hardware = new HAL.Hardware(); var deviceService = new DeviceService(); DeviceSystem.Setup.Initialize(hardware, deviceService.ProcessInterrupt); - Console.WriteLine(ConsoleColor.BrightBlack, " [Completed]"); + ScreenConsole.WriteLine(ScreenColor.BrightBlack, " [Completed]"); - Console.Write(ConsoleColor.BrightGreen, "> Registering device drivers..."); + ScreenConsole.Write(ScreenColor.BrightGreen, "> Registering device drivers..."); deviceService.RegisterDeviceDriver(DeviceDriver.Setup.GetDeviceDriverRegistryEntries()); - Console.WriteLine(ConsoleColor.BrightBlack, " [Completed]"); + ScreenConsole.WriteLine(ScreenColor.BrightBlack, " [Completed]"); - Console.WriteLine(); - Console.WriteLine(ConsoleColor.BrightYellow, "Initializing services..."); + ScreenConsole.WriteLine(); + ScreenConsole.WriteLine(ScreenColor.BrightYellow, "Initializing services..."); - Console.Write(ConsoleColor.BrightGreen, "> Service Manager..."); + ScreenConsole.Write(ScreenColor.BrightGreen, "> Service Manager..."); var serviceManager = new ServiceManager(); - Console.WriteLine(ConsoleColor.BrightBlack, " [Completed]"); + Kernel.ServiceManger = serviceManager; + ScreenConsole.WriteLine(ScreenColor.BrightBlack, " [Completed]"); - Console.Write(ConsoleColor.BrightGreen, "> Device Service..."); + ScreenConsole.Write(ScreenColor.BrightGreen, "> Device Service..."); serviceManager.AddService(deviceService); - Console.WriteLine(ConsoleColor.BrightBlack, " [Completed]"); + ScreenConsole.WriteLine(ScreenColor.BrightBlack, " [Completed]"); - Console.Write(ConsoleColor.BrightGreen, "> Disk Device Service..."); + ScreenConsole.Write(ScreenColor.BrightGreen, "> Disk Device Service..."); serviceManager.AddService(new DiskDeviceService()); - Console.WriteLine(ConsoleColor.BrightBlack, " [Completed]"); + ScreenConsole.WriteLine(ScreenColor.BrightBlack, " [Completed]"); - Console.Write(ConsoleColor.BrightGreen, "> Partition Service..."); + ScreenConsole.Write(ScreenColor.BrightGreen, "> Partition Service..."); serviceManager.AddService(new PartitionService()); - Console.WriteLine(ConsoleColor.BrightBlack, " [Completed]"); + ScreenConsole.WriteLine(ScreenColor.BrightBlack, " [Completed]"); - Console.Write(ConsoleColor.BrightGreen, "> PCI Controller Service..."); + ScreenConsole.Write(ScreenColor.BrightGreen, "> PCI Controller Service..."); serviceManager.AddService(new PCIControllerService()); - Console.WriteLine(ConsoleColor.BrightBlack, " [Completed]"); + ScreenConsole.WriteLine(ScreenColor.BrightBlack, " [Completed]"); - Console.Write(ConsoleColor.BrightGreen, "> PCI Device Service..."); + ScreenConsole.Write(ScreenColor.BrightGreen, "> PCI Device Service..."); serviceManager.AddService(new PCIDeviceService()); - Console.WriteLine(ConsoleColor.BrightBlack, " [Completed]"); + ScreenConsole.WriteLine(ScreenColor.BrightBlack, " [Completed]"); - Console.Write(ConsoleColor.BrightGreen, "> PC Service..."); + ScreenConsole.Write(ScreenColor.BrightGreen, "> PC Service..."); serviceManager.AddService(new PCService()); - Console.WriteLine(ConsoleColor.BrightBlack, " [Completed]"); + ScreenConsole.WriteLine(ScreenColor.BrightBlack, " [Completed]"); - Debug.WriteLine("[System]"); - Console.Write(ConsoleColor.BrightGreen, "> X86System..."); + ScreenConsole.Write(ScreenColor.BrightGreen, "> X86System..."); deviceService.Initialize(new X86System(), null); - Console.WriteLine(ConsoleColor.BrightBlack, " [Completed]"); + ScreenConsole.WriteLine(ScreenColor.BrightBlack, " [Completed]"); + + Debug.WriteLine("[Kernel Ready]"); - Debug.WriteLine("Done"); //Debug.Kill(); } diff --git a/Source/Mosa.Kernel.BareMetal/BootOptions.cs b/Source/Mosa.Kernel.BareMetal/BootOptions.cs index 490a22e564..f9ae49526e 100644 --- a/Source/Mosa.Kernel.BareMetal/BootOptions.cs +++ b/Source/Mosa.Kernel.BareMetal/BootOptions.cs @@ -4,6 +4,7 @@ namespace Mosa.Kernel.BareMetal { public static class BootOptions { + public static bool EanbleVirtualMemory; public static bool EnableDebugOutput; } } diff --git a/Source/Mosa.Kernel.BareMetal/Kernel.cs b/Source/Mosa.Kernel.BareMetal/Kernel.cs new file mode 100644 index 0000000000..4bb778de61 --- /dev/null +++ b/Source/Mosa.Kernel.BareMetal/Kernel.cs @@ -0,0 +1,10 @@ +// Copyright (c) MOSA Project. Licensed under the New BSD License. + +using Mosa.DeviceSystem; + +namespace Mosa.Kernel.BareMetal; + +public class Kernel +{ + public static ServiceManager ServiceManger { get; set; } +} diff --git a/Source/Mosa.Kernel.BareMetal/ConsoleColor.cs b/Source/Mosa.Kernel.BareMetal/ScreenColor.cs similarity index 91% rename from Source/Mosa.Kernel.BareMetal/ConsoleColor.cs rename to Source/Mosa.Kernel.BareMetal/ScreenColor.cs index 77b0f37759..411a71fff4 100644 --- a/Source/Mosa.Kernel.BareMetal/ConsoleColor.cs +++ b/Source/Mosa.Kernel.BareMetal/ScreenColor.cs @@ -2,7 +2,7 @@ namespace Mosa.Kernel.BareMetal; -public enum ConsoleColor : byte +public enum ScreenColor : byte { Black = 30, Red = 31, diff --git a/Source/Mosa.Kernel.BareMetal/Console.cs b/Source/Mosa.Kernel.BareMetal/ScreenConsole.cs similarity index 88% rename from Source/Mosa.Kernel.BareMetal/Console.cs rename to Source/Mosa.Kernel.BareMetal/ScreenConsole.cs index 6f8a0459e2..da52f7b225 100644 --- a/Source/Mosa.Kernel.BareMetal/Console.cs +++ b/Source/Mosa.Kernel.BareMetal/ScreenConsole.cs @@ -2,7 +2,7 @@ namespace Mosa.Kernel.BareMetal; -public static class Console +public static class ScreenConsole { public const byte Escape = 0x1b; public const byte Newline = 0x0A; @@ -51,25 +51,25 @@ public static void WriteLine(string s) Write(Newline); } - public static void WriteLine(ConsoleColor color, string s) + public static void WriteLine(ScreenColor color, string s) { SetForground(color); WriteLine(s); } - public static void Write(ConsoleColor color, string s) + public static void Write(ScreenColor color, string s) { SetForground(color); Write(s); } - public static void WriteLine(ConsoleColor color) + public static void WriteLine(ScreenColor color) { SetForground(color); Write(Newline); } - public static void Write(ConsoleColor color) + public static void Write(ScreenColor color) { SetForground(color); } @@ -85,7 +85,7 @@ public static void ClearScreen() Write("[2J"); } - public static void SetForground(ConsoleColor color) + public static void SetForground(ScreenColor color) { var c = (byte)color; @@ -96,7 +96,7 @@ public static void SetForground(ConsoleColor color) Write("m"); } - public static void SetBackground(ConsoleColor color) + public static void SetBackground(ScreenColor color) { var c = (byte)color + 10; diff --git a/Source/Mosa.UnitTests.BareMetal.x86/Boot.cs b/Source/Mosa.UnitTests.BareMetal.x86/Boot.cs index 4d9626048c..e545b93ecf 100644 --- a/Source/Mosa.UnitTests.BareMetal.x86/Boot.cs +++ b/Source/Mosa.UnitTests.BareMetal.x86/Boot.cs @@ -22,13 +22,13 @@ public static void Main() UnitTestEngine.Setup(0x3F8); // Serial.COM1 - Console.SetBackground(ConsoleColor.Blue); - Console.ClearScreen(); - Console.GotoTop(); - Console.SetForground(ConsoleColor.Yellow); - Console.Write("MOSA OS Version 2.0 - UnitTest"); - Console.WriteLine(); - Console.WriteLine(); + ScreenConsole.SetBackground(ScreenColor.Blue); + ScreenConsole.ClearScreen(); + ScreenConsole.GotoTop(); + ScreenConsole.SetForground(ScreenColor.Yellow); + ScreenConsole.Write("MOSA OS Version 2.0 - UnitTest"); + ScreenConsole.WriteLine(); + ScreenConsole.WriteLine(); UnitTestEngine.DisplayUpdate(); diff --git a/Source/Mosa.UnitTests.BareMetal.x86/UnitTestEngine.cs b/Source/Mosa.UnitTests.BareMetal.x86/UnitTestEngine.cs index 0673686185..19c26eedfa 100644 --- a/Source/Mosa.UnitTests.BareMetal.x86/UnitTestEngine.cs +++ b/Source/Mosa.UnitTests.BareMetal.x86/UnitTestEngine.cs @@ -279,21 +279,21 @@ public static void DisplayUpdate(bool test = false) { if (!test) { - Console.Goto(4, 0); - Console.Write("Total : "); - Console.WriteValue(TestCount, 7); + ScreenConsole.Goto(4, 0); + ScreenConsole.Write("Total : "); + ScreenConsole.WriteValue(TestCount, 7); - Console.Goto(5, 0); - Console.Write("Pending: "); - Console.WriteValue(PendingCount, 7); + ScreenConsole.Goto(5, 0); + ScreenConsole.Write("Pending: "); + ScreenConsole.WriteValue(PendingCount, 7); } else { - Console.Goto(6, 0); - Console.Write("Active : "); - Console.WriteValue(TestID, 7); - Console.Write(" @ "); - Console.WriteValueAsHex(TestMethodAddress.ToUInt32(), 8); + ScreenConsole.Goto(6, 0); + ScreenConsole.Write("Active : "); + ScreenConsole.WriteValue(TestID, 7); + ScreenConsole.Write(" @ "); + ScreenConsole.WriteValueAsHex(TestMethodAddress.ToUInt32(), 8); } } } From a04ff71255a66eb956b87e12cdafe5521d14b0a1 Mon Sep 17 00:00:00 2001 From: Phil Date: Mon, 31 Jul 2023 22:03:08 -0700 Subject: [PATCH 02/11] - WIP --- Source/Mosa.BareMetal.HelloWorld.x86/Boot.cs | 174 +++++++++++++++++- .../Linker/MosaLinker.cs | 3 + .../Plugs/EnvironmentPlug.cs | 11 -- .../Plugs/EnvironmentPlug.cs | 11 -- .../Plugs/EnvironmentPlug.cs | 3 - .../Plugs/EnvironmentPlug.cs | 19 -- .../Plugs/EnvironmentPlug.cs | 11 -- Source/Mosa.DeviceSystem/HAL.cs | 2 + .../Mosa.Kernel.BareMetal.x86/VGAConsole.cs | 6 +- Source/Mosa.Kernel.BareMetal/Boot.cs | 8 +- Source/Mosa.Kernel.BareMetal/BootOptions.cs | 5 +- ...ardware.cs => HardwareAbstractionLayer.cs} | 16 +- .../Korlib/ConsolePlug.cs | 129 +++++++++++++ .../Mosa.Kernel.BareMetal/Korlib/DebugPlug.cs | 1 - .../Korlib/EnvironmentPlug.cs | 2 +- Source/Mosa.Kernel.BareMetal/Korlib/Notes.md | 5 + .../System/EnvironmentPlug.cs | 21 +++ 17 files changed, 343 insertions(+), 84 deletions(-) delete mode 100644 Source/Mosa.Demo.CoolWorld.x86/Plugs/EnvironmentPlug.cs delete mode 100644 Source/Mosa.Demo.HelloWorld.x86/Plugs/EnvironmentPlug.cs delete mode 100644 Source/Mosa.Demo.TestWorld.x64/Plugs/EnvironmentPlug.cs delete mode 100644 Source/Mosa.Demo.TestWorld.x86/Plugs/EnvironmentPlug.cs rename Source/Mosa.Kernel.BareMetal/{HAL/Hardware.cs => HardwareAbstractionLayer.cs} (80%) create mode 100644 Source/Mosa.Kernel.BareMetal/Korlib/ConsolePlug.cs create mode 100644 Source/Mosa.Kernel.BareMetal/Korlib/Notes.md create mode 100644 Source/Mosa.Plug.Korlib/System/EnvironmentPlug.cs diff --git a/Source/Mosa.BareMetal.HelloWorld.x86/Boot.cs b/Source/Mosa.BareMetal.HelloWorld.x86/Boot.cs index c8591b9a32..e1421d1b45 100644 --- a/Source/Mosa.BareMetal.HelloWorld.x86/Boot.cs +++ b/Source/Mosa.BareMetal.HelloWorld.x86/Boot.cs @@ -1,8 +1,13 @@ // Copyright (c) MOSA Project. Licensed under the New BSD License. +using System; +using Mosa.DeviceDriver.ISA; +using Mosa.DeviceSystem; +using Mosa.DeviceSystem.PCI; +using Mosa.DeviceSystem.Service; +using Mosa.FileSystem.FAT; using Mosa.Kernel.BareMetal; using Mosa.Kernel.BareMetal.x86; -using Mosa.Runtime.Plug; namespace Mosa.BareMetal.HelloWorld.x86; @@ -11,13 +16,143 @@ namespace Mosa.BareMetal.HelloWorld.x86; /// public static class Boot { - /// - /// Main - /// public static void Main() { - VGAText.SetColor(VGAColor.Brown); - VGAText.Write((byte)'+'); + Debug.WriteLine("Boot::Main()"); + + var deviceService = Mosa.Kernel.BareMetal.Kernel.ServiceManger.GetFirstService(); + + Console.BackgroundColor = ConsoleColor.Black; + Console.ForegroundColor = ConsoleColor.White; + Console.Clear(); + Console.Write("> Probing for ISA devices..."); + + var isaDevices = deviceService.GetChildrenOf(deviceService.GetFirstDevice()); + Console.WriteLine("[Completed: " + isaDevices.Count + " found]"); + + foreach (var device in isaDevices) + { + Console.Write(" "); + Bullet(ConsoleColor.Yellow); + Console.Write(" "); + InBrackets(device.Name, ConsoleColor.White, ConsoleColor.Green); + Console.WriteLine(); + } + + Console.Write("> Probing for PCI devices..."); + var devices = deviceService.GetDevices(); + Console.WriteLine("[Completed: " + devices.Count + " found]"); + + foreach (var device in devices) + { + Console.Write(" "); + Bullet(ConsoleColor.Yellow); + Console.Write(" "); + + var pciDevice = device.DeviceDriver as PCIDevice; + InBrackets(device.Name + ": " + pciDevice.VendorID.ToString("x") + ":" + pciDevice.DeviceID.ToString("x") + " " + pciDevice.SubSystemID.ToString("x") + ":" + pciDevice.SubSystemVendorID.ToString("x") + " (" + pciDevice.ClassCode.ToString("x") + ":" + pciDevice.SubClassCode.ToString("x") + ":" + pciDevice.ProgIF.ToString("x") + ":" + pciDevice.RevisionID.ToString("x") + ")", ConsoleColor.White, ConsoleColor.Green); + + var children = deviceService.GetChildrenOf(device); + + if (children.Count != 0) + { + var child = children[0]; + + Console.WriteLine(); + Console.Write(" "); + + var pciDevice2 = child.DeviceDriver as PCIDevice; + InBrackets(child.Name, ConsoleColor.White, ConsoleColor.Green); + } + + Console.WriteLine(); + } + + Console.Write("> Probing for disk controllers..."); + var diskcontrollers = deviceService.GetDevices(); + Console.WriteLine("[Completed: " + diskcontrollers.Count + " found]"); + + foreach (var device in diskcontrollers) + { + Console.Write(" "); + Bullet(ConsoleColor.Yellow); + Console.Write(" "); + InBrackets(device.Name, ConsoleColor.White, ConsoleColor.Green); + Console.WriteLine(); + } + + Console.Write("> Probing for disks..."); + var disks = deviceService.GetDevices(); + Console.WriteLine("[Completed: " + disks.Count + " found]"); + + foreach (var disk in disks) + { + Console.Write(" "); + Bullet(ConsoleColor.Yellow); + Console.Write(" "); + InBrackets(disk.Name, ConsoleColor.White, ConsoleColor.Green); + Console.Write(" " + (disk.DeviceDriver as IDiskDevice).TotalBlocks + " blocks"); + Console.WriteLine(); + } + + var partitionService = Mosa.Kernel.BareMetal.Kernel.ServiceManger.GetFirstService(); + + partitionService.CreatePartitionDevices(); + + Console.Write("> Finding partitions..."); + var partitions = deviceService.GetDevices(); + Console.WriteLine("[Completed: " + partitions.Count + " found]"); + + foreach (var partition in partitions) + { + Console.Write(" "); + Bullet(ConsoleColor.Yellow); + Console.Write(" "); + InBrackets(partition.Name, ConsoleColor.White, ConsoleColor.Green); + Console.Write(" " + (partition.DeviceDriver as IPartitionDevice).BlockCount.ToString() + " blocks"); + Console.WriteLine(); + } + + //Console.Write("> Finding file systems..."); + + //foreach (var partition in partitions) + //{ + // var fat = new FatFileSystem(partition.DeviceDriver as IPartitionDevice); + + // if (fat.IsValid) + // { + // Console.WriteLine("Found a FAT file system!"); + + // const string filename = "TEST.TXT"; + + // var location = fat.FindEntry(filename); + + // if (location.IsValid) + // { + // Console.Write("Found: " + filename); + + // var fatFileStream = new FatFileStream(fat, location); + + // uint len = (uint)fatFileStream.Length; + + // Console.WriteLine(" - Length: " + len + " bytes"); + + // Console.Write("Reading File: "); + + // for (; ; ) + // { + // int i = fatFileStream.ReadByte(); + + // if (i < 0) + // break; + + // Console.Write((char)i); + // } + + // Console.WriteLine(); + // } + // } + //} while (true) { } @@ -27,5 +162,32 @@ public static void Main() public static void SetBootOptions() { BootOptions.EnableDebugOutput = true; + //BootOptions.EnableVirtualMemory = true; + //BootOptions.EnableMinimalBoot = true; + } + + public static void InBrackets(string message, ConsoleColor outerColor, ConsoleColor innerColor) + { + var restore = Console.ForegroundColor; + Console.ForegroundColor = outerColor; + Console.Write("["); + Console.ForegroundColor = innerColor; + Console.Write(message); + Console.ForegroundColor = outerColor; + Console.Write("]"); + Console.ForegroundColor = restore; + } + + public static void Bullet(ConsoleColor color) + { + var restore = Console.ForegroundColor; + Console.ForegroundColor = color; + Console.Write("*"); + Console.ForegroundColor = restore; + } + + public static void Include() + { + Mosa.Kernel.BareMetal.x86.Scheduler.SwitchToThread(null); } } diff --git a/Source/Mosa.Compiler.Framework/Linker/MosaLinker.cs b/Source/Mosa.Compiler.Framework/Linker/MosaLinker.cs index c4c7dd473c..d6ebd6fb78 100644 --- a/Source/Mosa.Compiler.Framework/Linker/MosaLinker.cs +++ b/Source/Mosa.Compiler.Framework/Linker/MosaLinker.cs @@ -274,6 +274,9 @@ private uint ResolveSymbolLocation(SectionKind section, ulong VirtualAddress) if (symbol.IsResolved) continue; + if (symbol.Size == 0) + continue; + symbol.SectionOffset = position; symbol.VirtualAddress = VirtualAddress + position; diff --git a/Source/Mosa.Demo.CoolWorld.x86/Plugs/EnvironmentPlug.cs b/Source/Mosa.Demo.CoolWorld.x86/Plugs/EnvironmentPlug.cs deleted file mode 100644 index e958ba873c..0000000000 --- a/Source/Mosa.Demo.CoolWorld.x86/Plugs/EnvironmentPlug.cs +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) MOSA Project. Licensed under the New BSD License. - -using Mosa.Runtime.Plug; - -namespace Mosa.Demo.CoolWorld.x86.Plugs; - -public static class EnvironmentPlug -{ - [Plug("System.Environment::GetProcessorCount")] - internal static int GetProcessorCount() => 1; // TODO: APIC -} diff --git a/Source/Mosa.Demo.HelloWorld.x86/Plugs/EnvironmentPlug.cs b/Source/Mosa.Demo.HelloWorld.x86/Plugs/EnvironmentPlug.cs deleted file mode 100644 index 502e4db259..0000000000 --- a/Source/Mosa.Demo.HelloWorld.x86/Plugs/EnvironmentPlug.cs +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) MOSA Project. Licensed under the New BSD License. - -using Mosa.Runtime.Plug; - -namespace Mosa.Demo.HelloWorld.x86.Plugs; - -public static class EnvironmentPlug -{ - [Plug("System.Environment::GetProcessorCount")] - internal static int GetProcessorCount() => 1; // TODO: APIC -} diff --git a/Source/Mosa.Demo.SVGAWorld.x86/Plugs/EnvironmentPlug.cs b/Source/Mosa.Demo.SVGAWorld.x86/Plugs/EnvironmentPlug.cs index 4d15e0ab45..cbd8f39db8 100644 --- a/Source/Mosa.Demo.SVGAWorld.x86/Plugs/EnvironmentPlug.cs +++ b/Source/Mosa.Demo.SVGAWorld.x86/Plugs/EnvironmentPlug.cs @@ -22,7 +22,4 @@ internal static void FailFast(string message) Console.WriteLine("***FAIL FAST*** " + message); for (; ; ); } - - [Plug("System.Environment::GetProcessorCount")] - internal static int GetProcessorCount() => 1; // TODO: APIC } diff --git a/Source/Mosa.Demo.TestWorld.x64/Plugs/EnvironmentPlug.cs b/Source/Mosa.Demo.TestWorld.x64/Plugs/EnvironmentPlug.cs deleted file mode 100644 index e415a53738..0000000000 --- a/Source/Mosa.Demo.TestWorld.x64/Plugs/EnvironmentPlug.cs +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) MOSA Project. Licensed under the New BSD License. - -using System; -using Mosa.Runtime.Plug; - -namespace Mosa.Demo.TestWorld.x64.Plugs; - -public static class EnvironmentPlug -{ - [Plug("System.Environment::FailFast")] - internal static void FailFast(string message) - { - Console.WriteLine("PANIC: " + message); - for (;;) ; - } - - [Plug("System.Environment::GetProcessorCount")] - internal static int GetProcessorCount() => 1; // TODO: APIC -} diff --git a/Source/Mosa.Demo.TestWorld.x86/Plugs/EnvironmentPlug.cs b/Source/Mosa.Demo.TestWorld.x86/Plugs/EnvironmentPlug.cs deleted file mode 100644 index addc9f2a68..0000000000 --- a/Source/Mosa.Demo.TestWorld.x86/Plugs/EnvironmentPlug.cs +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) MOSA Project. Licensed under the New BSD License. - -using Mosa.Runtime.Plug; - -namespace Mosa.Demo.TestWorld.x86.Plugs; - -public static class EnvironmentPlug -{ - [Plug("System.Environment::GetProcessorCount")] - internal static int GetProcessorCount() => 1; // TODO: APIC -} diff --git a/Source/Mosa.DeviceSystem/HAL.cs b/Source/Mosa.DeviceSystem/HAL.cs index 87424a7f1f..19261778e6 100644 --- a/Source/Mosa.DeviceSystem/HAL.cs +++ b/Source/Mosa.DeviceSystem/HAL.cs @@ -100,7 +100,9 @@ public static class HAL public static void Assert(bool condition, string message) { if (!condition) + { hardwareAbstraction.Abort(message); + } } /// diff --git a/Source/Mosa.Kernel.BareMetal.x86/VGAConsole.cs b/Source/Mosa.Kernel.BareMetal.x86/VGAConsole.cs index 311aa33cea..d8f5c1fcfe 100644 --- a/Source/Mosa.Kernel.BareMetal.x86/VGAConsole.cs +++ b/Source/Mosa.Kernel.BareMetal.x86/VGAConsole.cs @@ -144,7 +144,7 @@ private static void Evaluate() case 34: VGAText.SetColor(VGAColor.Blue); break; case 35: VGAText.SetColor(VGAColor.Magenta); break; case 36: VGAText.SetColor(VGAColor.Cyan); break; - case 37: VGAText.SetColor(VGAColor.LightGray); break; + case 37: VGAText.SetColor(VGAColor.White); break; case 90: VGAText.SetColor(VGAColor.DarkGray); break; case 91: VGAText.SetColor(VGAColor.LightRed); break; @@ -153,7 +153,7 @@ private static void Evaluate() case 94: VGAText.SetColor(VGAColor.LightBlue); break; case 95: VGAText.SetColor(VGAColor.LightMagenta); break; case 96: VGAText.SetColor(VGAColor.LightCyan); break; - case 97: VGAText.SetColor(VGAColor.White); break; + case 97: VGAText.SetColor(VGAColor.LightGray); break; case 40: VGAText.SetBackground(VGAColor.Black); break; case 41: VGAText.SetBackground(VGAColor.Red); break; @@ -171,7 +171,7 @@ private static void Evaluate() case 104: VGAText.SetBackground(VGAColor.LightBlue); break; case 105: VGAText.SetBackground(VGAColor.LightMagenta); break; case 106: VGAText.SetBackground(VGAColor.LightCyan); break; - case 107: VGAText.SetBackground(VGAColor.White); break; + case 107: VGAText.SetBackground(VGAColor.LightGray); break; // FUTURE: //0 Reset all attributes diff --git a/Source/Mosa.Kernel.BareMetal/Boot.cs b/Source/Mosa.Kernel.BareMetal/Boot.cs index 6f53ef7adf..190532aafa 100644 --- a/Source/Mosa.Kernel.BareMetal/Boot.cs +++ b/Source/Mosa.Kernel.BareMetal/Boot.cs @@ -40,7 +40,7 @@ public static void PlatformInitialization() [Plug("Mosa.Runtime.StartUp::KernelEntryPoint")] public static void EntryPoint() { - Debug.WriteLine("[Entry Point]"); + Debug.WriteLine("[Kernel Entry Point]"); ScreenConsole.Write(ScreenColor.BrightGreen, "> Enabling debug logging..."); Debug.Setup(true); @@ -87,7 +87,7 @@ public static void EntryPoint() //Console.WriteLine(ConsoleColor.BrightBlack, " [Completed]"); ScreenConsole.Write(ScreenColor.BrightGreen, "> Hardware abstraction layer..."); - var hardware = new HAL.Hardware(); + var hardware = new HardwareAbstractionLayer(); var deviceService = new DeviceService(); DeviceSystem.Setup.Initialize(hardware, deviceService.ProcessInterrupt); ScreenConsole.WriteLine(ScreenColor.BrightBlack, " [Completed]"); @@ -131,10 +131,6 @@ public static void EntryPoint() ScreenConsole.Write(ScreenColor.BrightGreen, "> X86System..."); deviceService.Initialize(new X86System(), null); ScreenConsole.WriteLine(ScreenColor.BrightBlack, " [Completed]"); - - Debug.WriteLine("[Kernel Ready]"); - - //Debug.Kill(); } [Plug("Mosa.Runtime.GC::AllocateMemory")] diff --git a/Source/Mosa.Kernel.BareMetal/BootOptions.cs b/Source/Mosa.Kernel.BareMetal/BootOptions.cs index f9ae49526e..2671fa5caa 100644 --- a/Source/Mosa.Kernel.BareMetal/BootOptions.cs +++ b/Source/Mosa.Kernel.BareMetal/BootOptions.cs @@ -4,7 +4,10 @@ namespace Mosa.Kernel.BareMetal { public static class BootOptions { - public static bool EanbleVirtualMemory; + // FUTURE + + public static bool EnableVirtualMemory; + public static bool EnableMinimalBoot; public static bool EnableDebugOutput; } } diff --git a/Source/Mosa.Kernel.BareMetal/HAL/Hardware.cs b/Source/Mosa.Kernel.BareMetal/HardwareAbstractionLayer.cs similarity index 80% rename from Source/Mosa.Kernel.BareMetal/HAL/Hardware.cs rename to Source/Mosa.Kernel.BareMetal/HardwareAbstractionLayer.cs index 7f80f7bc06..a0de8dcb74 100644 --- a/Source/Mosa.Kernel.BareMetal/HAL/Hardware.cs +++ b/Source/Mosa.Kernel.BareMetal/HardwareAbstractionLayer.cs @@ -3,12 +3,12 @@ using Mosa.DeviceSystem; using Mosa.Runtime; -namespace Mosa.Kernel.BareMetal.HAL; +namespace Mosa.Kernel.BareMetal; /// -/// Hardware Interface +/// Hardware Abstraction Layer /// -public sealed class Hardware : BaseHardwareAbstraction +public sealed class HardwareAbstractionLayer : BaseHardwareAbstraction { public override uint PageSize => Page.Size; @@ -21,20 +21,14 @@ public override ConstrainedPointer GetPhysicalMemory(Pointer address, uint size) public override void DisableInterrupts() => Platform.Interrupt.Disable(); - public override void ProcessInterrupt(byte irq) => DeviceSystem.HAL.ProcessInterrupt(irq); + public override void ProcessInterrupt(byte irq) => HAL.ProcessInterrupt(irq); public override void Sleep(uint milliseconds) { // TODO } - public override ConstrainedPointer AllocateVirtualMemory(uint size, uint alignment) - { - var address = VirtualMemoryAllocator.AllocateMemory(size); - - //return new ConstrainedPointer(address, size); - return new ConstrainedPointer(Pointer.Zero, 0); - } + public override ConstrainedPointer AllocateVirtualMemory(uint size, uint alignment) => VirtualMemoryAllocator.AllocateMemory(size); public override void DebugWrite(string message) => Debug.Write(message); diff --git a/Source/Mosa.Kernel.BareMetal/Korlib/ConsolePlug.cs b/Source/Mosa.Kernel.BareMetal/Korlib/ConsolePlug.cs new file mode 100644 index 0000000000..19ba9fde94 --- /dev/null +++ b/Source/Mosa.Kernel.BareMetal/Korlib/ConsolePlug.cs @@ -0,0 +1,129 @@ +// Copyright (c) MOSA Project. Licensed under the New BSD License. + +using System; +using Mosa.Runtime.Plug; + +namespace Mosa.Kernel.BareMetal.Korlib; + +public static class ConsolePlug +{ + private static ConsoleColor forgroundColor = ConsoleColor.White; + private static ConsoleColor backgroundColor = ConsoleColor.Black; + + [Plug("System.Console::Clear")] + public static void Clear() + { + ScreenConsole.ClearScreen(); + } + + [Plug("System.Console::WriteLine")] + public static void WriteLine(string value) + { + ScreenConsole.WriteLine(value); + } + + [Plug("System.Console::WriteLine")] + public static void WriteLine() + { + ScreenConsole.WriteLine(); + } + + [Plug("System.Console::Write")] + public static void Write(string value) + { + ScreenConsole.Write(value); + } + + [Plug("System.Console::Write")] + public static void Write(char value) + { + ScreenConsole.Write(value); + } + + [Plug("System.Console::SetForegroundColor")] + public static void SetForegroundColor(ConsoleColor color) + { + forgroundColor = color; + ScreenConsole.SetForground(Convert(color)); + } + + [Plug("System.Console::SetBackgroundColor")] + public static void SetBackgroundColor(ConsoleColor color) + { + backgroundColor = color; + ScreenConsole.SetBackground(Convert(color)); + } + + [Plug("System.Console::GetForegroundColor")] + public static ConsoleColor GetForegroundColor() + { + return forgroundColor; + } + + [Plug("System.Console::GetBackgroundColor")] + public static ConsoleColor GetBackgroundColor() + { + return backgroundColor; + } + + [Plug("System.Console::SetCursorPosition")] + public static void SetCursorPosition(int left, int top) + { + ScreenConsole.Goto((uint)top, (uint)left); + } + + [Plug("System.Console::ResetColor")] + public static void ResetColor() + { + SetBackgroundColor(ConsoleColor.Black); + SetForegroundColor(ConsoleColor.White); + } + + private static ConsoleColor Convert(ScreenColor color) + { + return color switch + { + ScreenColor.White => ConsoleColor.White, + ScreenColor.Black => ConsoleColor.Black, + ScreenColor.Red => ConsoleColor.Red, + ScreenColor.Green => ConsoleColor.Green, + ScreenColor.Yellow => ConsoleColor.Yellow, + ScreenColor.Blue => ConsoleColor.Blue, + ScreenColor.Magenta => ConsoleColor.Magenta, + ScreenColor.Cyan => ConsoleColor.Cyan, + ScreenColor.BrightBlack => ConsoleColor.DarkGray, + ScreenColor.BrightRed => ConsoleColor.LightRed, + ScreenColor.BrightGreen => ConsoleColor.LightGreen, + ScreenColor.BrightYellow => ConsoleColor.Yellow, + ScreenColor.BrightBlue => ConsoleColor.LightBlue, + ScreenColor.BrightMagenta => ConsoleColor.LightMagenta, + ScreenColor.BrightCyan => ConsoleColor.LightCyan, + ScreenColor.BrightWhite => ConsoleColor.Gray, + _ => ConsoleColor.White, + }; + } + + private static ScreenColor Convert(ConsoleColor color) + { + return color switch + { + ConsoleColor.White => ScreenColor.White, + ConsoleColor.Black => ScreenColor.Black, + ConsoleColor.Blue => ScreenColor.Blue, + ConsoleColor.Green => ScreenColor.Green, + ConsoleColor.Cyan => ScreenColor.Cyan, + ConsoleColor.Red => ScreenColor.Red, + ConsoleColor.Magenta => ScreenColor.Magenta, + ConsoleColor.Brown => ScreenColor.Magenta, + ConsoleColor.Gray => ScreenColor.BrightWhite, + ConsoleColor.DarkGray => ScreenColor.BrightBlack, + ConsoleColor.LightBlue => ScreenColor.BrightBlue, + ConsoleColor.LightGreen => ScreenColor.BrightGreen, + ConsoleColor.LightCyan => ScreenColor.BrightCyan, + ConsoleColor.LightRed => ScreenColor.BrightRed, + ConsoleColor.LightMagenta => ScreenColor.BrightMagenta, + ConsoleColor.Yellow => ScreenColor.Yellow, + _ => ScreenColor.White, + }; + } +} diff --git a/Source/Mosa.Kernel.BareMetal/Korlib/DebugPlug.cs b/Source/Mosa.Kernel.BareMetal/Korlib/DebugPlug.cs index f240958e32..cde8ec4e84 100644 --- a/Source/Mosa.Kernel.BareMetal/Korlib/DebugPlug.cs +++ b/Source/Mosa.Kernel.BareMetal/Korlib/DebugPlug.cs @@ -1,6 +1,5 @@ // Copyright (c) MOSA Project. Licensed under the New BSD License. -using System.Diagnostics; using Mosa.Runtime.Plug; namespace Mosa.Kernel.BareMetal.Korlib; diff --git a/Source/Mosa.Kernel.BareMetal/Korlib/EnvironmentPlug.cs b/Source/Mosa.Kernel.BareMetal/Korlib/EnvironmentPlug.cs index 72eaee68da..317d08321e 100644 --- a/Source/Mosa.Kernel.BareMetal/Korlib/EnvironmentPlug.cs +++ b/Source/Mosa.Kernel.BareMetal/Korlib/EnvironmentPlug.cs @@ -15,7 +15,7 @@ public static void FailFast(string message) Debug.Fatal(); } - [Plug("System.Environme::Exit")] + [Plug("System.Environment::Exit")] public static void Exit(int exitCode) { Debug.Fatal(); diff --git a/Source/Mosa.Kernel.BareMetal/Korlib/Notes.md b/Source/Mosa.Kernel.BareMetal/Korlib/Notes.md new file mode 100644 index 0000000000..debc5c8bc2 --- /dev/null +++ b/Source/Mosa.Kernel.BareMetal/Korlib/Notes.md @@ -0,0 +1,5 @@ + +* +* These plugs directly patch Korlib with the BareMetal Kernel. +* + diff --git a/Source/Mosa.Plug.Korlib/System/EnvironmentPlug.cs b/Source/Mosa.Plug.Korlib/System/EnvironmentPlug.cs new file mode 100644 index 0000000000..634f5361b1 --- /dev/null +++ b/Source/Mosa.Plug.Korlib/System/EnvironmentPlug.cs @@ -0,0 +1,21 @@ +using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; +using Mosa.Runtime.Plug; + +namespace Mosa.Plug.Korlib.System; + +public static class EnvironmentPlug +{ + public const string NewLine = "\n"; + + [DoesNotReturn] + [MethodImpl(MethodImplOptions.InternalCall)] + public static extern void Exit(int exitCode); + + [DoesNotReturn] + [MethodImpl(MethodImplOptions.InternalCall)] + public static extern void FailFast(string message); + + [Plug("System.Environment::GetProcessorCount")] + internal static int GetProcessorCount() => 1; // TODO: APIC +} From b5c34ddbc46fe3547cb66ea22cae383756dc0911 Mon Sep 17 00:00:00 2001 From: Phil Date: Thu, 3 Aug 2023 23:30:54 -0700 Subject: [PATCH 03/11] - WIP - x64 --- Source/Data/X64-Instructions.json | 2 +- Source/Mosa.BareMetal.HelloWorld.x86/Boot.cs | 2 +- .../Stages/CILDecoderStage.cs | 7 +++ .../Instructions/Cvtsd2ss.cs | 4 +- .../Intrinsic/SuppressStackFrame.cs | 18 ------ .../Stages/PlatformTransformationStage.cs | 9 +++ .../Transforms/IR/AddCarryIn64.cs | 29 ++++++++++ .../Transforms/IR/AddCarryOut64.cs | 30 ++++++++++ .../Transforms/IR/AddOverflowOut32.cs | 30 ++++++++++ .../Transforms/IR/AddOverflowOut64.cs | 30 ++++++++++ .../Transforms/IR/BitCopy32ToR4.cs | 21 +++++++ .../Transforms/IR/BitCopyR4To32.cs | 26 +++++++++ .../Transforms/IR/ConvertR4ToI64.cs | 2 +- .../Transforms/IR/ConvertR4ToU32.cs | 26 +++++++++ .../Transforms/IR/ConvertR4ToU64.cs | 21 +++++++ .../Transforms/IR/ConvertR8ToR4.cs | 2 +- .../Transforms/IR/DivSigned32.cs | 10 ++-- .../Transforms/IR/IRTransforms.cs | 31 ++++++++--- .../Transforms/IR/MulCarryOut32.cs | 31 +++++++++++ .../Transforms/IR/MulOverflowOut32.cs | 30 ++++++++++ .../Transforms/IR/RemSigned32.cs | 5 +- .../Transforms/IR/SubCarryOut64.cs | 30 ++++++++++ .../Transforms/IR/SubOverflowOut32.cs | 30 ++++++++++ .../Transforms/IR/SubOverflowOut64.cs | 30 ++++++++++ .../Manual/Special/Mov32Unless.cs | 55 +++++++++++++++++++ .../Manual/Special/Mov64Coalescing.cs | 48 ++++++++++++++++ .../Manual/Special/Mov64Unless.cs | 55 +++++++++++++++++++ .../Transforms/RuntimeCall/ConvertR4ToI64.cs | 28 ++++++++++ .../Transforms/RuntimeCall/ConvertR4ToU64.cs | 28 ++++++++++ .../Transforms/RuntimeCall/ConvertR8ToI64.cs | 28 ++++++++++ .../Transforms/RuntimeCall/ConvertR8ToU64.cs | 28 ++++++++++ .../Transforms/RuntimeCall/MulCarryOut64.cs | 47 ++++++++++++++++ .../RuntimeCall/MulOverflowOut64.cs | 47 ++++++++++++++++ .../RuntimeCall/RuntimeCallTransforms.cs | 12 ++-- .../Intrinsic/SuppressStackFrame.cs | 19 ------- .../Mosa.Platform.x86.csproj | 9 --- .../Stages/PlatformTransformationStage.cs | 2 - .../Transforms/RuntimeCall/MulCarryOut64.cs | 5 +- .../RuntimeCall/MulOverflowOut64.cs | 5 +- Source/Mosa.Runtime/Math/CheckedConversion.cs | 2 + Source/Mosa.Tool.Explorer/MainForm.cs | 17 +++--- Source/Mosa.UnitTests/Basic/ConvFloatTests.cs | 24 ++++++++ 42 files changed, 824 insertions(+), 91 deletions(-) delete mode 100644 Source/Mosa.Platform.x64/Intrinsic/SuppressStackFrame.cs create mode 100644 Source/Mosa.Platform.x64/Transforms/IR/AddCarryIn64.cs create mode 100644 Source/Mosa.Platform.x64/Transforms/IR/AddCarryOut64.cs create mode 100644 Source/Mosa.Platform.x64/Transforms/IR/AddOverflowOut32.cs create mode 100644 Source/Mosa.Platform.x64/Transforms/IR/AddOverflowOut64.cs create mode 100644 Source/Mosa.Platform.x64/Transforms/IR/BitCopy32ToR4.cs create mode 100644 Source/Mosa.Platform.x64/Transforms/IR/BitCopyR4To32.cs create mode 100644 Source/Mosa.Platform.x64/Transforms/IR/ConvertR4ToU32.cs create mode 100644 Source/Mosa.Platform.x64/Transforms/IR/ConvertR4ToU64.cs create mode 100644 Source/Mosa.Platform.x64/Transforms/IR/MulCarryOut32.cs create mode 100644 Source/Mosa.Platform.x64/Transforms/IR/MulOverflowOut32.cs create mode 100644 Source/Mosa.Platform.x64/Transforms/IR/SubCarryOut64.cs create mode 100644 Source/Mosa.Platform.x64/Transforms/IR/SubOverflowOut32.cs create mode 100644 Source/Mosa.Platform.x64/Transforms/IR/SubOverflowOut64.cs create mode 100644 Source/Mosa.Platform.x64/Transforms/Optimizations/Manual/Special/Mov32Unless.cs create mode 100644 Source/Mosa.Platform.x64/Transforms/Optimizations/Manual/Special/Mov64Coalescing.cs create mode 100644 Source/Mosa.Platform.x64/Transforms/Optimizations/Manual/Special/Mov64Unless.cs create mode 100644 Source/Mosa.Platform.x64/Transforms/RuntimeCall/ConvertR4ToI64.cs create mode 100644 Source/Mosa.Platform.x64/Transforms/RuntimeCall/ConvertR4ToU64.cs create mode 100644 Source/Mosa.Platform.x64/Transforms/RuntimeCall/ConvertR8ToI64.cs create mode 100644 Source/Mosa.Platform.x64/Transforms/RuntimeCall/ConvertR8ToU64.cs create mode 100644 Source/Mosa.Platform.x64/Transforms/RuntimeCall/MulCarryOut64.cs create mode 100644 Source/Mosa.Platform.x64/Transforms/RuntimeCall/MulOverflowOut64.cs delete mode 100644 Source/Mosa.Platform.x86/Intrinsic/SuppressStackFrame.cs 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/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.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/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/DivSigned32.cs b/Source/Mosa.Platform.x64/Transforms/IR/DivSigned32.cs index fe2bafac7c..99dbd1917b 100644 --- a/Source/Mosa.Platform.x64/Transforms/IR/DivSigned32.cs +++ b/Source/Mosa.Platform.x64/Transforms/IR/DivSigned32.cs @@ -21,10 +21,12 @@ 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(); - context.SetInstruction2(X64.Cdq32, v1, v2, operand1); - context.AppendInstruction2(X64.IDiv32, v3, result, v1, v2, operand2); + var rax = Operand.CreateCPURegister32(CPURegister.RAX); + var rdx = Operand.CreateCPURegister32(CPURegister.RDX); + + context.SetInstruction(X64.Mov32, rax, operand1); + context.AppendInstruction(X64.Cdq32, rdx, rax); + context.AppendInstruction2(X64.IDiv32, v1, result, rdx, rax, operand2); } } diff --git a/Source/Mosa.Platform.x64/Transforms/IR/IRTransforms.cs b/Source/Mosa.Platform.x64/Transforms/IR/IRTransforms.cs index 210a7fbbeb..e2514ff29a 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 ConvertR8ToI64(), new ConvertI32ToR4(), new ConvertI32ToR8(), //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/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/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.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.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.UnitTests/Basic/ConvFloatTests.cs b/Source/Mosa.UnitTests/Basic/ConvFloatTests.cs index 5dcd85fb2e..15a75c5932 100644 --- a/Source/Mosa.UnitTests/Basic/ConvFloatTests.cs +++ b/Source/Mosa.UnitTests/Basic/ConvFloatTests.cs @@ -45,4 +45,28 @@ public static ulong ConvR8U8(double a) { return (ulong)a; } + + [MosaUnitTest(Series = "R4")] + public static int ConvR4I4(float a) + { + return (int)a; + } + + [MosaUnitTest(Series = "R4")] + public static ulong ConvR4U4(float a) + { + return (uint)a; + } + + [MosaUnitTest(Series = "R8")] + public static long ConvR4I4(double a) + { + return (int)a; + } + + [MosaUnitTest(Series = "R8")] + public static ulong ConvR4U4(double a) + { + return (uint)a; + } } From 4aa676c0912e24bbf8f2b951939102809c3cbe19 Mon Sep 17 00:00:00 2001 From: Phil Date: Fri, 4 Aug 2023 20:01:15 -0700 Subject: [PATCH 04/11] - WIP - x64 --- .../Transforms/IR/ConvertR8ToU32.cs | 26 +++++++++++++++++++ .../Transforms/IR/IRTransforms.cs | 2 +- Source/Mosa.UnitTests/Basic/ConvFloatTests.cs | 6 ++--- 3 files changed, 30 insertions(+), 4 deletions(-) create mode 100644 Source/Mosa.Platform.x64/Transforms/IR/ConvertR8ToU32.cs 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/IRTransforms.cs b/Source/Mosa.Platform.x64/Transforms/IR/IRTransforms.cs index e2514ff29a..200e1b2a10 100644 --- a/Source/Mosa.Platform.x64/Transforms/IR/IRTransforms.cs +++ b/Source/Mosa.Platform.x64/Transforms/IR/IRTransforms.cs @@ -38,7 +38,7 @@ public static class IRTransforms new ConvertR4ToI64(), new ConvertR8ToR4(), new ConvertR8ToI32(), - //new ConvertR8ToU32(), + new ConvertR8ToU32(), new ConvertR8ToI64(), new ConvertI32ToR4(), new ConvertI32ToR8(), diff --git a/Source/Mosa.UnitTests/Basic/ConvFloatTests.cs b/Source/Mosa.UnitTests/Basic/ConvFloatTests.cs index 15a75c5932..47a21ad264 100644 --- a/Source/Mosa.UnitTests/Basic/ConvFloatTests.cs +++ b/Source/Mosa.UnitTests/Basic/ConvFloatTests.cs @@ -53,19 +53,19 @@ public static int ConvR4I4(float a) } [MosaUnitTest(Series = "R4")] - public static ulong ConvR4U4(float a) + public static uint ConvR4U4(float a) { return (uint)a; } [MosaUnitTest(Series = "R8")] - public static long ConvR4I4(double a) + public static int ConvR8I4(double a) { return (int)a; } [MosaUnitTest(Series = "R8")] - public static ulong ConvR4U4(double a) + public static uint ConvR8U4(double a) { return (uint)a; } From bd048eca13564ddcbd4d36290eb2a236ccdc5f53 Mon Sep 17 00:00:00 2001 From: Phil Date: Fri, 4 Aug 2023 20:12:21 -0700 Subject: [PATCH 05/11] - WIP - x64 --- Source/Mosa.UnitTests/Basic/ConvFloatTests.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Source/Mosa.UnitTests/Basic/ConvFloatTests.cs b/Source/Mosa.UnitTests/Basic/ConvFloatTests.cs index 47a21ad264..0e2f6a5fec 100644 --- a/Source/Mosa.UnitTests/Basic/ConvFloatTests.cs +++ b/Source/Mosa.UnitTests/Basic/ConvFloatTests.cs @@ -46,13 +46,12 @@ public static ulong ConvR8U8(double a) return (ulong)a; } - [MosaUnitTest(Series = "R4")] public static int ConvR4I4(float a) { return (int)a; } - [MosaUnitTest(Series = "R4")] + //[MosaUnitTest(Series = "R4")] // BUG public static uint ConvR4U4(float a) { return (uint)a; @@ -64,7 +63,7 @@ public static int ConvR8I4(double a) return (int)a; } - [MosaUnitTest(Series = "R8")] + //[MosaUnitTest(Series = "R8")] // BUG public static uint ConvR8U4(double a) { return (uint)a; From 8cdceff9e9ac8e01fbcdd5dae06659897b6716d3 Mon Sep 17 00:00:00 2001 From: Phil Date: Fri, 4 Aug 2023 22:19:10 -0700 Subject: [PATCH 06/11] - WIP - x64 --- Source/Mosa.UnitTests/Basic/ConvFloatTests.cs | 22 ++++++++++-- Source/Mosa.Utility.UnitTests/Numbers/R4.cs | 8 ++--- Source/Mosa.Utility.UnitTests/Numbers/R8.cs | 34 +++++++++++-------- 3 files changed, 43 insertions(+), 21 deletions(-) diff --git a/Source/Mosa.UnitTests/Basic/ConvFloatTests.cs b/Source/Mosa.UnitTests/Basic/ConvFloatTests.cs index 0e2f6a5fec..bebff3ef26 100644 --- a/Source/Mosa.UnitTests/Basic/ConvFloatTests.cs +++ b/Source/Mosa.UnitTests/Basic/ConvFloatTests.cs @@ -51,7 +51,14 @@ public static int ConvR4I4(float a) return (int)a; } - //[MosaUnitTest(Series = "R4")] // BUG + [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; @@ -63,7 +70,18 @@ public static int ConvR8I4(double a) return (int)a; } - //[MosaUnitTest(Series = "R8")] // BUG + [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.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(); From 809f85e94015435d1a873ac172d3cddcebb38e1b Mon Sep 17 00:00:00 2001 From: Phil Date: Sat, 5 Aug 2023 13:15:48 -0700 Subject: [PATCH 07/11] - WIP - x64 --- .../Data/IR-Optimizations-Simplification.json | 9 ---- .../Mosa.Compiler.Framework/MethodCompiler.cs | 1 + .../Optimizations/Auto/AutoTransforms.cs | 1 - .../Or32Truncate64x32Truncate64x32.cs | 54 ------------------- .../Transforms/FixedRegisters/Rcr32.cs | 8 ++- .../Transforms/FixedRegisters/Rcr64.cs | 6 +++ .../Transforms/FixedRegisters/Sar32.cs | 6 +++ .../Transforms/FixedRegisters/Sar64.cs | 6 +++ .../Transforms/FixedRegisters/Shr32.cs | 8 +++ .../Transforms/FixedRegisters/Shr64.cs | 6 +++ .../Transforms/IR/ConvertU32ToR4.cs | 28 ++++++++++ .../Transforms/IR/ConvertU32ToR8.cs | 28 ++++++++++ .../Transforms/IR/DivSigned32.cs | 13 +++-- .../Transforms/IR/DivSigned64.cs | 11 ++-- .../Transforms/IR/IRTransforms.cs | 4 +- .../Transforms/IR/RemSigned64.cs | 5 +- .../Transforms/IR/DivSigned32.cs | 11 ++-- Source/Mosa.Runtime.x64/Native.cs | 6 +-- 18 files changed, 120 insertions(+), 91 deletions(-) delete mode 100644 Source/Mosa.Compiler.Framework/Transforms/Optimizations/Auto/Simplification/Or32Truncate64x32Truncate64x32.cs create mode 100644 Source/Mosa.Platform.x64/Transforms/IR/ConvertU32ToR4.cs create mode 100644 Source/Mosa.Platform.x64/Transforms/IR/ConvertU32ToR8.cs 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/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/Transforms/Optimizations/Auto/AutoTransforms.cs b/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Auto/AutoTransforms.cs index c7a01f98df..5e274d20d6 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(), diff --git a/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Auto/Simplification/Or32Truncate64x32Truncate64x32.cs b/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Auto/Simplification/Or32Truncate64x32Truncate64x32.cs deleted file mode 100644 index 4806366ae4..0000000000 --- a/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Auto/Simplification/Or32Truncate64x32Truncate64x32.cs +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (c) MOSA Project. Licensed under the New BSD License. - -// This code was generated by an automated template. - -using Mosa.Compiler.Framework; - -namespace Mosa.Compiler.Framework.Transforms.Optimizations.Auto.Simplification; - -/// -/// Or32Truncate64x32Truncate64x32 -/// -[Transform("IR.Optimizations.Auto.Simplification")] -public sealed class Or32Truncate64x32Truncate64x32 : BaseTransform -{ - public Or32Truncate64x32Truncate64x32() : base(IRInstruction.Or32, TransformType.Auto | TransformType.Optimization) - { - } - - public override bool Match(Context context, TransformContext transform) - { - if (!context.Operand1.IsVirtualRegister) - return false; - - if (!context.Operand2.IsVirtualRegister) - return false; - - if (!context.Operand1.IsDefinedOnce) - return false; - - if (context.Operand1.Definitions[0].Instruction != IRInstruction.Truncate64x32) - return false; - - if (!context.Operand2.IsDefinedOnce) - return false; - - if (context.Operand2.Definitions[0].Instruction != IRInstruction.Truncate64x32) - return false; - - return true; - } - - public override void Transform(Context context, TransformContext transform) - { - var result = context.Result; - - var t1 = context.Operand1.Definitions[0].Operand1; - var t2 = context.Operand2.Definitions[0].Operand1; - - var v1 = transform.VirtualRegisters.Allocate64(); - - context.SetInstruction(IRInstruction.Or64, v1, t1, t2); - context.AppendInstruction(IRInstruction.GetLow32, result, v1); - } -} 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/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 99dbd1917b..607a945463 100644 --- a/Source/Mosa.Platform.x64/Transforms/IR/DivSigned32.cs +++ b/Source/Mosa.Platform.x64/Transforms/IR/DivSigned32.cs @@ -20,13 +20,12 @@ public override void Transform(Context context, TransformContext transform) var operand2 = context.Operand2; var result = context.Result; - var v1 = transform.VirtualRegisters.Allocate32(); + var v1 = transform.VirtualRegisters.Allocate64(); + var v2 = transform.VirtualRegisters.Allocate64(); + var v3 = transform.VirtualRegisters.Allocate64(); - var rax = Operand.CreateCPURegister32(CPURegister.RAX); - var rdx = Operand.CreateCPURegister32(CPURegister.RDX); - - context.SetInstruction(X64.Mov32, rax, operand1); - context.AppendInstruction(X64.Cdq32, rdx, rax); - context.AppendInstruction2(X64.IDiv32, v1, result, rdx, rax, 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 200e1b2a10..1d51de05e3 100644 --- a/Source/Mosa.Platform.x64/Transforms/IR/IRTransforms.cs +++ b/Source/Mosa.Platform.x64/Transforms/IR/IRTransforms.cs @@ -42,8 +42,8 @@ public static class IRTransforms new ConvertR8ToI64(), new ConvertI32ToR4(), new ConvertI32ToR8(), - //new ConvertU32ToR4(), - //new ConvertU32ToR8(), + new ConvertU32ToR4(), + new ConvertU32ToR8(), // new ConvertR4ToU64(), new DivR4(), new DivR8(), 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.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.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 From d197128b32ffdb6a91b576ca7e444ddf66c2d288 Mon Sep 17 00:00:00 2001 From: Phil Date: Sun, 6 Aug 2023 12:26:01 -0700 Subject: [PATCH 08/11] - WIP - x64 --- Source/Data/IR-Optimizations-LowerTo32.json | 38 +++++++ .../TransformContext.cs | 10 +- .../LowerTo32/ArithShiftRight64By32.cs | 2 +- .../LowerTo32/BaseLower32Transform.cs | 2 +- .../Transforms/LowerTo32/Branch64.cs | 2 +- .../Transforms/LowerTo32/Branch64Extends.cs | 2 +- .../LowerTo32/Compare64x32EqualOrNotEqual.cs | 2 +- .../Transforms/LowerTo32/Compare64x32Rest.cs | 2 +- .../LowerTo32/Compare64x32RestInSSA.cs | 2 +- .../LowerTo32/Compare64x32UnsignedGreater.cs | 2 +- .../LowerTo32/Compare64x64EqualOrNotEqual.cs | 2 +- .../Transforms/LowerTo32/Compare64x64Rest.cs | 2 +- .../LowerTo32/Compare64x64RestInSSA.cs | 2 +- .../LowerTo32/ShiftLeft64ByConstant32.cs | 2 +- .../LowerTo32/ShiftLeft64ByConstant32Plus.cs | 2 +- .../LowerTo32/ShiftRight64ByConstant32.cs | 2 +- .../LowerTo32/ShiftRight64ByConstant32Plus.cs | 2 +- .../Transforms/LowerTo32/SignExtend16x64.cs | 2 +- .../Optimizations/Auto/AutoTransforms.cs | 1 + .../Or32Truncate64x32Truncate64x32.cs | 60 ++++++++++ .../Manual/Special/GetLow32CPURegister.cs | 2 +- .../Manual/Special/GetLow32From64.cs | 2 +- .../Properties/launchSettings.json | 2 +- .../BuildBaseTemplate.cs | 2 + .../BuildIRInstructionFiles.cs | 6 - .../BuildTransformations.cs | 92 +++++++++++---- .../Program.cs | 24 ++-- .../TransformExpressions/PrefilterParser.cs | 106 ++++++++++++++++++ .../TransformExpressions/Token.cs | 6 + .../TransformExpressions/Tokenizer.cs | 4 + .../TransformExpressions/Transformation.cs | 13 ++- Source/Mosa.sln | 1 + 32 files changed, 328 insertions(+), 73 deletions(-) create mode 100644 Source/Data/IR-Optimizations-LowerTo32.json create mode 100644 Source/Mosa.Compiler.Framework/Transforms/Optimizations/Auto/LowerTo32/Or32Truncate64x32Truncate64x32.cs create mode 100644 Source/Mosa.Utility.SourceCodeGenerator/TransformExpressions/PrefilterParser.cs 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/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 5e274d20d6..da7fe917c9 100644 --- a/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Auto/AutoTransforms.cs +++ b/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Auto/AutoTransforms.cs @@ -770,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/LowerTo32/Or32Truncate64x32Truncate64x32.cs b/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Auto/LowerTo32/Or32Truncate64x32Truncate64x32.cs new file mode 100644 index 0000000000..7d5dc558d6 --- /dev/null +++ b/Source/Mosa.Compiler.Framework/Transforms/Optimizations/Auto/LowerTo32/Or32Truncate64x32Truncate64x32.cs @@ -0,0 +1,60 @@ +// Copyright (c) MOSA Project. Licensed under the New BSD License. + +// This code was generated by an automated template. + +using Mosa.Compiler.Framework; + +namespace Mosa.Compiler.Framework.Transforms.Optimizations.Auto.LowerTo32; + +/// +/// Or32Truncate64x32Truncate64x32 +/// +[Transform("IR.Optimizations.Auto.LowerTo32")] +public sealed class Or32Truncate64x32Truncate64x32 : BaseTransform +{ + public Or32Truncate64x32Truncate64x32() : base(IRInstruction.Or32, TransformType.Auto | TransformType.Optimization) + { + } + + public override bool Match(Context context, TransformContext transform) + { + if (!transform.Is32BitPlatform) + return false; + + if (!transform.IsLowerTo32) + return false; + + if (!context.Operand1.IsVirtualRegister) + return false; + + if (!context.Operand2.IsVirtualRegister) + return false; + + if (!context.Operand1.IsDefinedOnce) + return false; + + if (context.Operand1.Definitions[0].Instruction != IRInstruction.Truncate64x32) + return false; + + if (!context.Operand2.IsDefinedOnce) + return false; + + if (context.Operand2.Definitions[0].Instruction != IRInstruction.Truncate64x32) + return false; + + return true; + } + + public override void Transform(Context context, TransformContext transform) + { + var result = context.Result; + + var t1 = context.Operand1.Definitions[0].Operand1; + var t2 = context.Operand2.Definitions[0].Operand1; + + var v1 = transform.VirtualRegisters.Allocate64(); + + context.SetInstruction(IRInstruction.Or64, v1, t1, t2); + context.AppendInstruction(IRInstruction.GetLow32, result, v1); + } +} 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.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.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.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 From a47f14f6232f1ae6ed6bc9b2bb0d35fb5c2a8278 Mon Sep 17 00:00:00 2001 From: Phil Date: Sun, 6 Aug 2023 16:24:48 -0700 Subject: [PATCH 09/11] - WIP - x64 --- .../Optimizations/Manual/Special/StoreLoad32.cs | 2 +- .../Optimizations/Manual/Special/StoreLoad64.cs | 3 +++ .../Manual/Special/StoreLoadManagedPointer.cs | 2 +- Source/Mosa.Korlib/System.Threading/Interlocked.cs | 8 ++------ Source/Mosa.Platform.x64/Architecture.cs | 12 ++++-------- .../System.Threading/InterlockedPlug.cs | 6 ++++++ .../System.Runtime.Intrinsics.X86/PopcntPlug.cs | 4 ++-- 7 files changed, 19 insertions(+), 18 deletions(-) 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.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); From 886aa4532e697607aafa53b4d9e2f48d4910ff65 Mon Sep 17 00:00:00 2001 From: Phil Date: Sun, 6 Aug 2023 16:43:34 -0700 Subject: [PATCH 10/11] - WIP - x64 --- Source/Mosa.Tool.Compiler/Compiler.cs | 28 ++++--------------- .../CommandLineArguments.cs | 1 + .../MOSASettings.cs | 4 +++ 3 files changed, 11 insertions(+), 22 deletions(-) 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.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() From 906263998988aea5615956b4bc77062eb36f9823 Mon Sep 17 00:00:00 2001 From: Phil Date: Sun, 6 Aug 2023 16:53:26 -0700 Subject: [PATCH 11/11] - WIP - x64 --- .../System.Threading/InterlockedPlug.cs | 7 +++++++ 1 file changed, 7 insertions(+) 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); + } }