diff --git a/Source/Mosa.Compiler.ARM32/Transforms/BaseARM32Transform.cs b/Source/Mosa.Compiler.ARM32/Transforms/BaseARM32Transform.cs index 7142cd663b..8d3e19bec3 100644 --- a/Source/Mosa.Compiler.ARM32/Transforms/BaseARM32Transform.cs +++ b/Source/Mosa.Compiler.ARM32/Transforms/BaseARM32Transform.cs @@ -28,7 +28,7 @@ public static void MoveConstantRightForComparison(Context context) context.ConditionCode = context.ConditionCode.GetReverse(); } - public static void Translate(Transform transform, Context context, BaseInstruction instruction, bool allowImmediate) + public static void Translate(Transform transform, Context context, BaseInstruction instruction, bool allowImmediate, InstructionOption options = InstructionOption.None) { var result = context.Result; var operand1 = context.Operand1; @@ -39,7 +39,7 @@ public static void Translate(Transform transform, Context context, BaseInstructi ? MoveConstantToFloatRegisterOrImmediate(transform, context, operand1, allowImmediate) : MoveConstantToRegisterOrImmediate(transform, context, operand1, allowImmediate); - context.SetInstruction(instruction, result, operand1); + context.SetInstruction(instruction, options, result, operand1); } else if (context.OperandCount == 2) { @@ -51,7 +51,7 @@ public static void Translate(Transform transform, Context context, BaseInstructi ? MoveConstantToFloatRegisterOrImmediate(transform, context, operand2, allowImmediate) : MoveConstantToRegisterOrImmediate(transform, context, operand2, allowImmediate); - context.SetInstruction(instruction, result, operand1, operand2); + context.SetInstruction(instruction, options, result, operand1, operand2); } } diff --git a/Source/Mosa.Compiler.ARM32/Transforms/BaseIR/AddCarryOut64.cs b/Source/Mosa.Compiler.ARM32/Transforms/BaseIR/AddCarryOut64.cs new file mode 100644 index 0000000000..914221fd18 --- /dev/null +++ b/Source/Mosa.Compiler.ARM32/Transforms/BaseIR/AddCarryOut64.cs @@ -0,0 +1,29 @@ +// Copyright (c) MOSA Project. Licensed under the New BSD License. + +using Mosa.Compiler.Framework; + +namespace Mosa.Compiler.ARM32.Transforms.BaseIR; + +/// +/// AddCarryOut64 +/// +public sealed class AddCarryOut64 : BaseIRTransform +{ + public AddCarryOut64() : base(IR.AddCarryOut64, TransformType.Manual | TransformType.Transform) + { + } + + public override void Transform(Context context, Transform transform) + { + var result2 = context.Result2; + + transform.SplitOperand(context.Result, out var resultLow, out var resultHigh); + transform.SplitOperand(context.Operand1, out var op1L, out var op1H); + transform.SplitOperand(context.Operand2, out var op2L, out var op2H); + + context.SetInstruction(ARM32.Add, InstructionOption.SetFlags, resultLow, op1L, op2L); + context.AppendInstruction(ARM32.Adc, InstructionOption.SetFlags, resultHigh, op1H, op2H); + context.AppendInstruction(ARM32.Mov, ConditionCode.Carry, result2, Operand.Constant32_1); + context.AppendInstruction(ARM32.Mov, ConditionCode.NoCarry, result2, Operand.Constant32_0); + } +} diff --git a/Source/Mosa.Compiler.ARM32/Transforms/BaseIR/AddOverflowOut32.cs b/Source/Mosa.Compiler.ARM32/Transforms/BaseIR/AddOverflowOut32.cs new file mode 100644 index 0000000000..b13c943916 --- /dev/null +++ b/Source/Mosa.Compiler.ARM32/Transforms/BaseIR/AddOverflowOut32.cs @@ -0,0 +1,30 @@ +// Copyright (c) MOSA Project. Licensed under the New BSD License. + +using Mosa.Compiler.Framework; + +namespace Mosa.Compiler.ARM32.Transforms.BaseIR; + +/// +/// AddOverflowOut32 +/// +public sealed class AddOverflowOut32 : BaseIRTransform +{ + public AddOverflowOut32() : base(IR.AddOverflowOut32, TransformType.Manual | TransformType.Transform) + { + } + + public override void Transform(Context context, Transform transform) + { + var result = context.Result; + var result2 = context.Result2; + var operand1 = context.Operand1; + var operand2 = context.Operand2; + + operand1 = MoveConstantToRegister(transform, context, operand1); + operand2 = MoveConstantToRegisterOrImmediate(transform, context, operand2); + + context.SetInstruction(ARM32.Add, InstructionOption.SetFlags, result, operand1, operand2); + context.AppendInstruction(ARM32.Mov, ConditionCode.Overflow, result2, Operand.Constant32_1); + context.AppendInstruction(ARM32.Mov, ConditionCode.NoOverflow, result2, Operand.Constant32_0); + } +} diff --git a/Source/Mosa.Compiler.ARM32/Transforms/BaseIR/AddOverflowOut64.cs b/Source/Mosa.Compiler.ARM32/Transforms/BaseIR/AddOverflowOut64.cs new file mode 100644 index 0000000000..b574f5d5a5 --- /dev/null +++ b/Source/Mosa.Compiler.ARM32/Transforms/BaseIR/AddOverflowOut64.cs @@ -0,0 +1,34 @@ +// Copyright (c) MOSA Project. Licensed under the New BSD License. + +using Mosa.Compiler.Framework; + +namespace Mosa.Compiler.ARM32.Transforms.BaseIR; + +/// +/// AddOverflowOut64 +/// +public sealed class AddOverflowOut64 : BaseIRTransform +{ + public AddOverflowOut64() : base(IR.AddOverflowOut64, TransformType.Manual | TransformType.Transform) + { + } + + public override void Transform(Context context, Transform transform) + { + var result2 = context.Result2; + + transform.SplitOperand(context.Result, out var resultLow, out var resultHigh); + transform.SplitOperand(context.Operand1, out var op1L, out var op1H); + transform.SplitOperand(context.Operand2, out var op2L, out var op2H); + + op1L = MoveConstantToRegister(transform, context, op1L); + op1H = MoveConstantToRegister(transform, context, op1H); + op2L = MoveConstantToRegisterOrImmediate(transform, context, op2L); + op2H = MoveConstantToRegisterOrImmediate(transform, context, op2H); + + context.SetInstruction(ARM32.Add, InstructionOption.SetFlags, resultLow, op1L, op2L); + context.AppendInstruction(ARM32.Adc, InstructionOption.SetFlags, resultHigh, op1H, op2H); + context.AppendInstruction(ARM32.Mov, ConditionCode.Overflow, result2, Operand.Constant32_1); + context.AppendInstruction(ARM32.Mov, ConditionCode.NoOverflow, result2, Operand.Constant32_0); + } +} diff --git a/Source/Mosa.Compiler.ARM32/Transforms/BaseIR/IRTransforms.cs b/Source/Mosa.Compiler.ARM32/Transforms/BaseIR/IRTransforms.cs index e37ef431e2..d2d35cd720 100644 --- a/Source/Mosa.Compiler.ARM32/Transforms/BaseIR/IRTransforms.cs +++ b/Source/Mosa.Compiler.ARM32/Transforms/BaseIR/IRTransforms.cs @@ -15,7 +15,7 @@ public static class IRTransforms new AddCarryIn32(), new AddCarryOut32(), new AddManagedPointer(), - //new AddOverflowOut32(), + new AddOverflowOut32(), new AddR4(), new AddR8(), new AddressOf(), @@ -74,8 +74,8 @@ public static class IRTransforms new Move32(), new MoveObject(), new MoveManagedPointer(), - //new MulCarryOut32(), - //new MulOverflowOut32(), + new MulCarryOut32(), + new MulOverflowOut32(), new MulHu32(), new MulR4(), new MulR8(), @@ -106,15 +106,15 @@ public static class IRTransforms new SubCarryIn32(), new SubCarryOut32(), new SubManagedPointer(), - //new SubOverflowOut32(), + new SubOverflowOut32(), new SubR4(), new SubR8(), //new Switch(), new ZeroExtend16x32(), new ZeroExtend8x32(), new Add64(), - //new AddCarryOut64(), - //new AddOverflowOut64(), + new AddCarryOut64(), + new AddOverflowOut64(), //new BitCopyR8To64(), //new BitCopy64ToR8(), new ArithShiftRight64(), @@ -153,8 +153,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.Compiler.ARM32/Transforms/BaseIR/MulCarryOut32.cs b/Source/Mosa.Compiler.ARM32/Transforms/BaseIR/MulCarryOut32.cs new file mode 100644 index 0000000000..b4b2506532 --- /dev/null +++ b/Source/Mosa.Compiler.ARM32/Transforms/BaseIR/MulCarryOut32.cs @@ -0,0 +1,27 @@ +// Copyright (c) MOSA Project. Licensed under the New BSD License. + +using Mosa.Compiler.Framework; + +namespace Mosa.Compiler.ARM32.Transforms.BaseIR; + +/// +/// MulCarryOut32 +/// +public sealed class MulCarryOut32 : BaseIRTransform +{ + public MulCarryOut32() : base(IR.MulCarryOut32, TransformType.Manual | TransformType.Transform) + { + } + + public override void Transform(Context context, Transform transform) + { + var result2 = context.Result2; + + Framework.Transform.MoveConstantRight(context); + + Translate(transform, context, ARM32.Mul, false, InstructionOption.SetFlags); + + context.AppendInstruction(ARM32.Mov, ConditionCode.Overflow, result2, Operand.Constant32_1); + context.AppendInstruction(ARM32.Mov, ConditionCode.NoOverflow, result2, Operand.Constant32_0); + } +} diff --git a/Source/Mosa.Compiler.ARM32/Transforms/BaseIR/MulOverflowOut32.cs b/Source/Mosa.Compiler.ARM32/Transforms/BaseIR/MulOverflowOut32.cs new file mode 100644 index 0000000000..fcc318f5c7 --- /dev/null +++ b/Source/Mosa.Compiler.ARM32/Transforms/BaseIR/MulOverflowOut32.cs @@ -0,0 +1,27 @@ +// Copyright (c) MOSA Project. Licensed under the New BSD License. + +using Mosa.Compiler.Framework; + +namespace Mosa.Compiler.ARM32.Transforms.BaseIR; + +/// +/// MulOverflowOut32 +/// +public sealed class MulOverflowOut32 : BaseIRTransform +{ + public MulOverflowOut32() : base(IR.MulOverflowOut32, TransformType.Manual | TransformType.Transform) + { + } + + public override void Transform(Context context, Transform transform) + { + var result2 = context.Result2; + + Framework.Transform.MoveConstantRight(context); + + Translate(transform, context, ARM32.Mul, false, InstructionOption.SetFlags); + + context.AppendInstruction(ARM32.Mov, ConditionCode.Overflow, result2, Operand.Constant32_1); + context.AppendInstruction(ARM32.Mov, ConditionCode.NoOverflow, result2, Operand.Constant32_0); + } +} diff --git a/Source/Mosa.Compiler.ARM32/Transforms/BaseIR/SubCarryOut64.cs b/Source/Mosa.Compiler.ARM32/Transforms/BaseIR/SubCarryOut64.cs new file mode 100644 index 0000000000..64f20417c2 --- /dev/null +++ b/Source/Mosa.Compiler.ARM32/Transforms/BaseIR/SubCarryOut64.cs @@ -0,0 +1,29 @@ +// Copyright (c) MOSA Project. Licensed under the New BSD License. + +using Mosa.Compiler.Framework; + +namespace Mosa.Compiler.ARM32.Transforms.BaseIR; + +/// +/// SubCarryOut64 +/// +public sealed class SubCarryOut64 : BaseIRTransform +{ + public SubCarryOut64() : base(IR.SubCarryOut64, TransformType.Manual | TransformType.Transform) + { + } + + public override void Transform(Context context, Transform transform) + { + var result2 = context.Result2; + + transform.SplitOperand(context.Result, out var resultLow, out var resultHigh); + transform.SplitOperand(context.Operand1, out var op1L, out var op1H); + transform.SplitOperand(context.Operand2, out var op2L, out var op2H); + + context.SetInstruction(ARM32.Sub, InstructionOption.SetFlags, resultLow, op1L, op2L); + context.AppendInstruction(ARM32.Sbc, InstructionOption.SetFlags, resultHigh, op1H, op2H); + context.AppendInstruction(ARM32.Mov, ConditionCode.Carry, result2, Operand.Constant32_1); + context.AppendInstruction(ARM32.Mov, ConditionCode.NoCarry, result2, Operand.Constant32_0); + } +} diff --git a/Source/Mosa.Compiler.ARM32/Transforms/BaseIR/SubOverflowOut32.cs b/Source/Mosa.Compiler.ARM32/Transforms/BaseIR/SubOverflowOut32.cs new file mode 100644 index 0000000000..bd335cb6a7 --- /dev/null +++ b/Source/Mosa.Compiler.ARM32/Transforms/BaseIR/SubOverflowOut32.cs @@ -0,0 +1,30 @@ +// Copyright (c) MOSA Project. Licensed under the New BSD License. + +using Mosa.Compiler.Framework; + +namespace Mosa.Compiler.ARM32.Transforms.BaseIR; + +/// +/// SubOverflowOut32 +/// +public sealed class SubOverflowOut32 : BaseIRTransform +{ + public SubOverflowOut32() : base(IR.SubOverflowOut32, TransformType.Manual | TransformType.Transform) + { + } + + public override void Transform(Context context, Transform transform) + { + var result = context.Result; + var result2 = context.Result2; + var operand1 = context.Operand1; + var operand2 = context.Operand2; + + operand1 = MoveConstantToRegister(transform, context, operand1); + operand2 = MoveConstantToRegisterOrImmediate(transform, context, operand2); + + context.SetInstruction(ARM32.Sub, InstructionOption.SetFlags, result, operand1, operand2); + context.AppendInstruction(ARM32.Mov, ConditionCode.Overflow, result2, Operand.Constant32_1); + context.AppendInstruction(ARM32.Mov, ConditionCode.NoOverflow, result2, Operand.Constant32_0); + } +} diff --git a/Source/Mosa.Compiler.ARM32/Transforms/BaseIR/SubOverflowOut64.cs b/Source/Mosa.Compiler.ARM32/Transforms/BaseIR/SubOverflowOut64.cs new file mode 100644 index 0000000000..64d5fb9ae5 --- /dev/null +++ b/Source/Mosa.Compiler.ARM32/Transforms/BaseIR/SubOverflowOut64.cs @@ -0,0 +1,29 @@ +// Copyright (c) MOSA Project. Licensed under the New BSD License. + +using Mosa.Compiler.Framework; + +namespace Mosa.Compiler.ARM32.Transforms.BaseIR; + +/// +/// SubOverflowOut64 +/// +public sealed class SubOverflowOut64 : BaseIRTransform +{ + public SubOverflowOut64() : base(IR.SubOverflowOut64, TransformType.Manual | TransformType.Transform) + { + } + + public override void Transform(Context context, Transform transform) + { + var result2 = context.Result2; + + transform.SplitOperand(context.Result, out var resultLow, out var resultHigh); + transform.SplitOperand(context.Operand1, out var op1L, out var op1H); + transform.SplitOperand(context.Operand2, out var op2L, out var op2H); + + context.SetInstruction(ARM32.Sub, InstructionOption.SetFlags, resultLow, op1L, op2L); + context.AppendInstruction(ARM32.Sbc, InstructionOption.SetFlags, resultHigh, op1H, op2H); + context.AppendInstruction(ARM32.Mov, ConditionCode.Overflow, result2, Operand.Constant32_1); + context.AppendInstruction(ARM32.Mov, ConditionCode.NoOverflow, result2, Operand.Constant32_0); + } +} diff --git a/Source/Mosa.Compiler.ARM32/Transforms/RuntimeCall/MulCarryOut64.cs b/Source/Mosa.Compiler.ARM32/Transforms/RuntimeCall/MulCarryOut64.cs new file mode 100644 index 0000000000..850eb12f3e --- /dev/null +++ b/Source/Mosa.Compiler.ARM32/Transforms/RuntimeCall/MulCarryOut64.cs @@ -0,0 +1,46 @@ +// Copyright (c) MOSA Project. Licensed under the New BSD License. + +using System.Diagnostics; +using Mosa.Compiler.Framework; + +namespace Mosa.Compiler.ARM32.Transforms.RuntimeCall; + +/// +/// MulCarryOut64 +/// +public sealed class MulCarryOut64 : BaseTransform +{ + public MulCarryOut64() : base(IR.MulCarryOut64, TransformType.Manual | TransformType.Transform) + { + } + + public override int Priority => -100; + + public override bool Match(Context context, Transform transform) + { + return true; + } + + public override void Transform(Context context, Transform 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.Allocate32(); + + Debug.Assert(method != null, $"Cannot find method: Mul64Carry"); + + var symbol = Operand.CreateLabel(method, transform.Is32BitPlatform); + + context.SetInstruction(IR.AddressOf, v2, v1); + context.AppendInstruction(IR.CallStatic, result, symbol, operand1, operand2, v2); + context.AppendInstruction(IR.LoadZeroExtend8x32, result2, v2, Operand.Constant32_0); + + transform.MethodScanner.MethodInvoked(method, transform.Method); + } +} diff --git a/Source/Mosa.Compiler.ARM32/Transforms/RuntimeCall/MulOverflowOut64.cs b/Source/Mosa.Compiler.ARM32/Transforms/RuntimeCall/MulOverflowOut64.cs new file mode 100644 index 0000000000..fbe64a0c48 --- /dev/null +++ b/Source/Mosa.Compiler.ARM32/Transforms/RuntimeCall/MulOverflowOut64.cs @@ -0,0 +1,46 @@ +// Copyright (c) MOSA Project. Licensed under the New BSD License. + +using System.Diagnostics; +using Mosa.Compiler.Framework; + +namespace Mosa.Compiler.ARM32.Transforms.RuntimeCall; + +/// +/// MulOverflowOut64 +/// +public sealed class MulOverflowOut64 : BaseTransform +{ + public MulOverflowOut64() : base(IR.MulOverflowOut64, TransformType.Manual | TransformType.Transform) + { + } + + public override int Priority => -100; + + public override bool Match(Context context, Transform transform) + { + return true; + } + + public override void Transform(Context context, Transform 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.Allocate32(); + + Debug.Assert(method != null, $"Cannot find method: Mul64Overflow"); + + var symbol = Operand.CreateLabel(method, transform.Is32BitPlatform); + + context.SetInstruction(IR.AddressOf, v2, v1); + context.AppendInstruction(IR.CallStatic, result, symbol, operand1, operand2, v2); + context.AppendInstruction(IR.LoadZeroExtend8x32, result2, v2, Operand.Constant32_0); + + transform.MethodScanner.MethodInvoked(method, transform.Method); + } +} diff --git a/Source/Mosa.Compiler.ARM32/Transforms/RuntimeCall/RuntimeCallTransforms.cs b/Source/Mosa.Compiler.ARM32/Transforms/RuntimeCall/RuntimeCallTransforms.cs index b550ca1317..ad611491e7 100644 --- a/Source/Mosa.Compiler.ARM32/Transforms/RuntimeCall/RuntimeCallTransforms.cs +++ b/Source/Mosa.Compiler.ARM32/Transforms/RuntimeCall/RuntimeCallTransforms.cs @@ -23,5 +23,7 @@ public static class RuntimeCallTransforms new ConvertR8ToR4(), new BitCopyR4To32(), new BitCopy32ToR4(), + new MulCarryOut64(), + new MulOverflowOut64(), }; } diff --git a/Source/Mosa.Compiler.Framework/Stages/CILDecoderStage.cs b/Source/Mosa.Compiler.Framework/Stages/CILDecoderStage.cs index e948befb75..374c65d322 100644 --- a/Source/Mosa.Compiler.Framework/Stages/CILDecoderStage.cs +++ b/Source/Mosa.Compiler.Framework/Stages/CILDecoderStage.cs @@ -1306,7 +1306,7 @@ private bool AddUnsigned(Context context, Stack stack) case PrimitiveType.Int64 when entry2.PrimitiveType == PrimitiveType.Int64: { var result = MethodCompiler.VirtualRegisters.Allocate64(); - var result2 = MethodCompiler.VirtualRegisters.Allocate64(); + var result2 = MethodCompiler.VirtualRegisters.Allocate32(); context.AppendInstruction2(IR.AddCarryOut64, result, result2, entry2.Operand, entry1.Operand); context.AppendInstruction(IR.CheckThrowOverflow, null, result2); PushStack(stack, new StackEntry(result)); @@ -1317,7 +1317,7 @@ private bool AddUnsigned(Context context, Stack stack) { var v1 = MethodCompiler.VirtualRegisters.Allocate64(); var result = MethodCompiler.VirtualRegisters.Allocate64(); - var result2 = MethodCompiler.VirtualRegisters.Allocate64(); + var result2 = MethodCompiler.VirtualRegisters.Allocate32(); context.AppendInstruction(IR.ZeroExtend32x64, v1, entry1.Operand); context.AppendInstruction2(IR.AddCarryOut64, result, result2, v1, entry2.Operand); context.AppendInstruction(IR.CheckThrowOverflow, null, result2); @@ -1329,7 +1329,7 @@ private bool AddUnsigned(Context context, Stack stack) { var v1 = MethodCompiler.VirtualRegisters.Allocate64(); var result = MethodCompiler.VirtualRegisters.Allocate64(); - var result2 = MethodCompiler.VirtualRegisters.Allocate64(); + var result2 = MethodCompiler.VirtualRegisters.Allocate32(); context.AppendInstruction(IR.ZeroExtend32x64, v1, entry2.Operand); context.AppendInstruction2(IR.AddCarryOut64, result, result2, entry1.Operand, v1); context.AppendInstruction(IR.CheckThrowOverflow, null, result2); @@ -1352,7 +1352,7 @@ private bool AddUnsigned(Context context, Stack stack) case PrimitiveType.Int64 when entry2.PrimitiveType == PrimitiveType.ManagedPointer && Is64BitPlatform: { var result = MethodCompiler.VirtualRegisters.AllocateManagedPointer(); - var result2 = MethodCompiler.VirtualRegisters.Allocate64(); + var result2 = MethodCompiler.VirtualRegisters.Allocate32(); context.AppendInstruction2(IR.AddCarryOut64, result, result2, entry2.Operand, entry1.Operand); context.AppendInstruction(IR.CheckThrowOverflow, null, result2); PushStack(stack, new StackEntry(result)); @@ -1362,7 +1362,7 @@ private bool AddUnsigned(Context context, Stack stack) case PrimitiveType.Int32 when entry2.PrimitiveType == PrimitiveType.ManagedPointer && Is64BitPlatform: { var result = MethodCompiler.VirtualRegisters.AllocateManagedPointer(); - var result2 = MethodCompiler.VirtualRegisters.Allocate64(); + var result2 = MethodCompiler.VirtualRegisters.Allocate32(); var v1 = MethodCompiler.VirtualRegisters.Allocate64(); context.AppendInstruction(IR.ZeroExtend32x64, v1, entry1.Operand); context.AppendInstruction2(IR.AddCarryOut64, result, result2, v1, entry2.Operand); @@ -1374,7 +1374,7 @@ private bool AddUnsigned(Context context, Stack stack) case PrimitiveType.ManagedPointer when entry2.PrimitiveType == PrimitiveType.Int32 && Is64BitPlatform: { var result = MethodCompiler.VirtualRegisters.AllocateManagedPointer(); - var result2 = MethodCompiler.VirtualRegisters.Allocate64(); + var result2 = MethodCompiler.VirtualRegisters.Allocate32(); var v1 = MethodCompiler.VirtualRegisters.Allocate64(); context.AppendInstruction(IR.ZeroExtend32x64, v1, entry2.Operand); context.AppendInstruction2(IR.AddCarryOut64, result, result2, entry1.Operand, v1); @@ -1407,7 +1407,7 @@ private bool AddSigned(Context context, Stack stack) case PrimitiveType.Int64 when entry2.PrimitiveType == PrimitiveType.Int64: { var result = MethodCompiler.VirtualRegisters.Allocate64(); - var result2 = MethodCompiler.VirtualRegisters.Allocate64(); + var result2 = MethodCompiler.VirtualRegisters.Allocate32(); context.AppendInstruction2(IR.AddOverflowOut64, result, result2, entry2.Operand, entry1.Operand); context.AppendInstruction(IR.CheckThrowOverflow, null, result2); PushStack(stack, new StackEntry(result)); @@ -1418,7 +1418,7 @@ private bool AddSigned(Context context, Stack stack) { var v1 = MethodCompiler.VirtualRegisters.Allocate64(); var result = MethodCompiler.VirtualRegisters.Allocate64(); - var result2 = MethodCompiler.VirtualRegisters.Allocate64(); + var result2 = MethodCompiler.VirtualRegisters.Allocate32(); context.AppendInstruction(IR.SignExtend32x64, v1, entry1.Operand); context.AppendInstruction2(IR.AddOverflowOut64, result, result2, v1, entry2.Operand); context.AppendInstruction(IR.CheckThrowOverflow, null, result2); @@ -1430,7 +1430,7 @@ private bool AddSigned(Context context, Stack stack) { var v1 = MethodCompiler.VirtualRegisters.Allocate64(); var result = MethodCompiler.VirtualRegisters.Allocate64(); - var result2 = MethodCompiler.VirtualRegisters.Allocate64(); + var result2 = MethodCompiler.VirtualRegisters.Allocate32(); context.AppendInstruction(IR.SignExtend32x64, v1, entry2.Operand); context.AppendInstruction2(IR.AddOverflowOut64, result, result2, entry1.Operand, v1); context.AppendInstruction(IR.CheckThrowOverflow, null, result2); @@ -1452,7 +1452,7 @@ private bool AddSigned(Context context, Stack stack) case PrimitiveType.Int64 when entry2.PrimitiveType == PrimitiveType.ManagedPointer && Is64BitPlatform: { var result = MethodCompiler.VirtualRegisters.AllocateManagedPointer(); - var result2 = MethodCompiler.VirtualRegisters.Allocate64(); + var result2 = MethodCompiler.VirtualRegisters.Allocate32(); context.AppendInstruction2(IR.AddOverflowOut64, result, result2, entry2.Operand, entry1.Operand); context.AppendInstruction(IR.CheckThrowOverflow, null, result2); PushStack(stack, new StackEntry(result)); @@ -1462,8 +1462,8 @@ private bool AddSigned(Context context, Stack stack) case PrimitiveType.Int32 when entry2.PrimitiveType == PrimitiveType.ManagedPointer && Is64BitPlatform: { var result = MethodCompiler.VirtualRegisters.AllocateManagedPointer(); - var result2 = MethodCompiler.VirtualRegisters.Allocate64(); - var v1 = MethodCompiler.VirtualRegisters.Allocate64(); + var result2 = MethodCompiler.VirtualRegisters.Allocate32(); + var v1 = MethodCompiler.VirtualRegisters.Allocate32(); context.AppendInstruction(IR.SignExtend32x64, v1, entry1.Operand); context.AppendInstruction2(IR.AddOverflowOut64, result, result2, v1, entry2.Operand); context.AppendInstruction(IR.CheckThrowOverflow, null, result2); @@ -1474,8 +1474,8 @@ private bool AddSigned(Context context, Stack stack) case PrimitiveType.ManagedPointer when entry2.PrimitiveType == PrimitiveType.Int32 && Is64BitPlatform: { var result = MethodCompiler.VirtualRegisters.AllocateManagedPointer(); - var result2 = MethodCompiler.VirtualRegisters.Allocate64(); - var v1 = MethodCompiler.VirtualRegisters.Allocate64(); + var result2 = MethodCompiler.VirtualRegisters.Allocate32(); + var v1 = MethodCompiler.VirtualRegisters.Allocate32(); context.AppendInstruction(IR.SignExtend32x64, v1, entry2.Operand); context.AppendInstruction2(IR.AddOverflowOut64, result, result2, entry1.Operand, v1); context.AppendInstruction(IR.CheckThrowOverflow, null, result2); @@ -5045,7 +5045,7 @@ private bool SubSigned(Context context, Stack stack) case PrimitiveType.Int64 when entry2.PrimitiveType == PrimitiveType.Int64: { var result = MethodCompiler.VirtualRegisters.Allocate64(); - var result2 = MethodCompiler.VirtualRegisters.Allocate64(); + var result2 = MethodCompiler.VirtualRegisters.Allocate32(); context.AppendInstruction2(IR.SubOverflowOut64, result, result2, entry2.Operand, entry1.Operand); context.AppendInstruction(IR.CheckThrowOverflow, null, result2); PushStack(stack, new StackEntry(result)); @@ -5056,7 +5056,7 @@ private bool SubSigned(Context context, Stack stack) { var v1 = MethodCompiler.VirtualRegisters.Allocate64(); var result = MethodCompiler.VirtualRegisters.Allocate64(); - var result2 = MethodCompiler.VirtualRegisters.Allocate64(); + var result2 = MethodCompiler.VirtualRegisters.Allocate32(); context.AppendInstruction(IR.SignExtend32x64, v1, entry1.Operand); context.AppendInstruction2(IR.SubOverflowOut64, result, result2, v1, entry2.Operand); context.AppendInstruction(IR.CheckThrowOverflow, null, result2); @@ -5068,7 +5068,7 @@ private bool SubSigned(Context context, Stack stack) { var v1 = MethodCompiler.VirtualRegisters.Allocate64(); var result = MethodCompiler.VirtualRegisters.Allocate64(); - var result2 = MethodCompiler.VirtualRegisters.Allocate64(); + var result2 = MethodCompiler.VirtualRegisters.Allocate32(); context.AppendInstruction(IR.SignExtend32x64, v1, entry2.Operand); context.AppendInstruction2(IR.SubOverflowOut64, result, result2, entry1.Operand, v1); context.AppendInstruction(IR.CheckThrowOverflow, null, result2); @@ -5089,7 +5089,7 @@ private bool SubSigned(Context context, Stack stack) case PrimitiveType.ManagedPointer when entry2.PrimitiveType == PrimitiveType.ManagedPointer && Is64BitPlatform: { var result = MethodCompiler.VirtualRegisters.Allocate64(); - var result2 = MethodCompiler.VirtualRegisters.Allocate64(); + var result2 = MethodCompiler.VirtualRegisters.Allocate32(); context.AppendInstruction2(IR.SubOverflowOut64, result, result2, entry2.Operand, entry1.Operand); context.AppendInstruction(IR.CheckThrowOverflow, null, result2); PushStack(stack, new StackEntry(result)); @@ -5110,7 +5110,7 @@ private bool SubSigned(Context context, Stack stack) case PrimitiveType.Int64 when entry2.PrimitiveType == PrimitiveType.ManagedPointer && Is64BitPlatform: { var result = MethodCompiler.VirtualRegisters.AllocateManagedPointer(); - var result2 = MethodCompiler.VirtualRegisters.Allocate64(); + var result2 = MethodCompiler.VirtualRegisters.Allocate32(); context.AppendInstruction2(IR.SubOverflowOut64, result, result2, entry2.Operand, entry1.Operand); context.AppendInstruction(IR.CheckThrowOverflow, null, result2); PushStack(stack, new StackEntry(result)); @@ -5120,8 +5120,8 @@ private bool SubSigned(Context context, Stack stack) case PrimitiveType.Int32 when entry2.PrimitiveType == PrimitiveType.ManagedPointer && Is64BitPlatform: { var result = MethodCompiler.VirtualRegisters.AllocateManagedPointer(); - var result2 = MethodCompiler.VirtualRegisters.Allocate64(); - var v1 = MethodCompiler.VirtualRegisters.Allocate64(); + var result2 = MethodCompiler.VirtualRegisters.Allocate32(); + var v1 = MethodCompiler.VirtualRegisters.Allocate32(); context.AppendInstruction(IR.SignExtend32x64, v1, entry1.Operand); context.AppendInstruction2(IR.SubOverflowOut64, result, result2, v1, entry2.Operand); context.AppendInstruction(IR.CheckThrowOverflow, null, result2); @@ -5132,8 +5132,8 @@ private bool SubSigned(Context context, Stack stack) case PrimitiveType.ManagedPointer when entry2.PrimitiveType == PrimitiveType.Int32 && Is64BitPlatform: { var result = MethodCompiler.VirtualRegisters.AllocateManagedPointer(); - var result2 = MethodCompiler.VirtualRegisters.Allocate64(); - var v1 = MethodCompiler.VirtualRegisters.Allocate64(); + var result2 = MethodCompiler.VirtualRegisters.Allocate32(); + var v1 = MethodCompiler.VirtualRegisters.Allocate32(); context.AppendInstruction(IR.SignExtend32x64, v1, entry2.Operand); context.AppendInstruction2(IR.SubOverflowOut64, result, result2, entry1.Operand, v1); context.AppendInstruction(IR.CheckThrowOverflow, null, result2); @@ -5165,7 +5165,7 @@ private bool SubUnsigned(Context context, Stack stack) case PrimitiveType.Int64 when entry2.PrimitiveType == PrimitiveType.Int64: { var result = MethodCompiler.VirtualRegisters.Allocate64(); - var result2 = MethodCompiler.VirtualRegisters.Allocate64(); + var result2 = MethodCompiler.VirtualRegisters.Allocate32(); context.AppendInstruction2(IR.SubCarryOut64, result, result2, entry2.Operand, entry1.Operand); context.AppendInstruction(IR.CheckThrowOverflow, null, result2); PushStack(stack, new StackEntry(result)); @@ -5175,8 +5175,8 @@ private bool SubUnsigned(Context context, Stack stack) case PrimitiveType.Int32 when entry2.PrimitiveType == PrimitiveType.Int64: { var v1 = MethodCompiler.VirtualRegisters.Allocate64(); - var result = MethodCompiler.VirtualRegisters.Allocate64(); - var result2 = MethodCompiler.VirtualRegisters.Allocate64(); + var result = MethodCompiler.VirtualRegisters.Allocate32(); + var result2 = MethodCompiler.VirtualRegisters.Allocate32(); context.AppendInstruction(IR.ZeroExtend32x64, v1, entry1.Operand); context.AppendInstruction2(IR.SubCarryOut64, result, result2, v1, entry2.Operand); context.AppendInstruction(IR.CheckThrowOverflow, null, result2); @@ -5188,7 +5188,7 @@ private bool SubUnsigned(Context context, Stack stack) { var v1 = MethodCompiler.VirtualRegisters.Allocate64(); var result = MethodCompiler.VirtualRegisters.Allocate64(); - var result2 = MethodCompiler.VirtualRegisters.Allocate64(); + var result2 = MethodCompiler.VirtualRegisters.Allocate32(); context.AppendInstruction(IR.ZeroExtend32x64, v1, entry2.Operand); context.AppendInstruction2(IR.SubCarryOut64, result, result2, entry1.Operand, v1); context.AppendInstruction(IR.CheckThrowOverflow, null, result2); @@ -5209,7 +5209,7 @@ private bool SubUnsigned(Context context, Stack stack) case PrimitiveType.ManagedPointer when entry2.PrimitiveType == PrimitiveType.ManagedPointer && Is64BitPlatform: { var result = MethodCompiler.VirtualRegisters.Allocate64(); - var result2 = MethodCompiler.VirtualRegisters.Allocate64(); + var result2 = MethodCompiler.VirtualRegisters.Allocate32(); context.AppendInstruction2(IR.SubCarryOut64, result, result2, entry2.Operand, entry1.Operand); context.AppendInstruction(IR.CheckThrowOverflow, null, result2); PushStack(stack, new StackEntry(result)); @@ -5230,7 +5230,7 @@ private bool SubUnsigned(Context context, Stack stack) case PrimitiveType.Int64 when entry2.PrimitiveType == PrimitiveType.ManagedPointer && Is64BitPlatform: { var result = MethodCompiler.VirtualRegisters.AllocateManagedPointer(); - var result2 = MethodCompiler.VirtualRegisters.Allocate64(); + var result2 = MethodCompiler.VirtualRegisters.Allocate32(); context.AppendInstruction2(IR.SubCarryOut64, result, result2, entry2.Operand, entry1.Operand); context.AppendInstruction(IR.CheckThrowOverflow, null, result2); PushStack(stack, new StackEntry(result)); @@ -5240,7 +5240,7 @@ private bool SubUnsigned(Context context, Stack stack) case PrimitiveType.Int32 when entry2.PrimitiveType == PrimitiveType.ManagedPointer && Is64BitPlatform: { var result = MethodCompiler.VirtualRegisters.AllocateManagedPointer(); - var result2 = MethodCompiler.VirtualRegisters.Allocate64(); + var result2 = MethodCompiler.VirtualRegisters.Allocate32(); var v1 = MethodCompiler.VirtualRegisters.Allocate64(); context.AppendInstruction(IR.ZeroExtend32x64, v1, entry1.Operand); context.AppendInstruction2(IR.SubCarryOut64, result, result2, v1, entry2.Operand); @@ -5252,7 +5252,7 @@ private bool SubUnsigned(Context context, Stack stack) case PrimitiveType.ManagedPointer when entry2.PrimitiveType == PrimitiveType.Int32 && Is64BitPlatform: { var result = MethodCompiler.VirtualRegisters.AllocateManagedPointer(); - var result2 = MethodCompiler.VirtualRegisters.Allocate64(); + var result2 = MethodCompiler.VirtualRegisters.Allocate32(); var v1 = MethodCompiler.VirtualRegisters.Allocate64(); context.AppendInstruction(IR.ZeroExtend32x64, v1, entry2.Operand); context.AppendInstruction2(IR.SubCarryOut64, result, result2, entry1.Operand, v1); diff --git a/Source/Mosa.Compiler.x86/Transforms/BaseIR/AddCarryOut64.cs b/Source/Mosa.Compiler.x86/Transforms/BaseIR/AddCarryOut64.cs index 64687cba35..e016ad9366 100644 --- a/Source/Mosa.Compiler.x86/Transforms/BaseIR/AddCarryOut64.cs +++ b/Source/Mosa.Compiler.x86/Transforms/BaseIR/AddCarryOut64.cs @@ -15,10 +15,11 @@ public AddCarryOut64() : base(IR.AddCarryOut64, TransformType.Manual | Transform public override void Transform(Context context, Transform transform) { + var result2 = context.Result2; + transform.SplitOperand(context.Result, out var resultLow, out var resultHigh); transform.SplitOperand(context.Operand1, out var op1L, out var op1H); transform.SplitOperand(context.Operand2, out var op2L, out var op2H); - var result2 = context.Result2; var v1 = transform.VirtualRegisters.Allocate32(); diff --git a/Source/Mosa.Compiler.x86/Transforms/BaseIR/AddOverflowOut64.cs b/Source/Mosa.Compiler.x86/Transforms/BaseIR/AddOverflowOut64.cs index 2fc935fb74..2352ae86fc 100644 --- a/Source/Mosa.Compiler.x86/Transforms/BaseIR/AddOverflowOut64.cs +++ b/Source/Mosa.Compiler.x86/Transforms/BaseIR/AddOverflowOut64.cs @@ -15,10 +15,11 @@ public AddOverflowOut64() : base(IR.AddOverflowOut64, TransformType.Manual | Tra public override void Transform(Context context, Transform transform) { + var result2 = context.Result2; + transform.SplitOperand(context.Result, out var resultLow, out var resultHigh); transform.SplitOperand(context.Operand1, out var op1L, out var op1H); transform.SplitOperand(context.Operand2, out var op2L, out var op2H); - var result2 = context.Result2; var v1 = transform.VirtualRegisters.Allocate32(); diff --git a/Source/Mosa.Compiler.x86/Transforms/BaseIR/ArithShiftRight64Less64.cs b/Source/Mosa.Compiler.x86/Transforms/BaseIR/ArithShiftRight64Less64.cs index c0b81ee2e6..2cc29caf9f 100644 --- a/Source/Mosa.Compiler.x86/Transforms/BaseIR/ArithShiftRight64Less64.cs +++ b/Source/Mosa.Compiler.x86/Transforms/BaseIR/ArithShiftRight64Less64.cs @@ -23,7 +23,7 @@ public override bool Match(Context context, Transform transform) public override void Transform(Context context, Transform transform) { transform.SplitOperand(context.Result, out var resultLow, out var resultHigh); - transform.SplitOperand(context.Operand1, out var op1L, out var op1H); + transform.SplitOperand(context.Operand1, out _, out var op1H); var count = context.Operand2; diff --git a/Source/Mosa.Compiler.x86/Transforms/BaseIR/SubCarryOut64.cs b/Source/Mosa.Compiler.x86/Transforms/BaseIR/SubCarryOut64.cs index cab7a2bcf2..ba8b71e6d9 100644 --- a/Source/Mosa.Compiler.x86/Transforms/BaseIR/SubCarryOut64.cs +++ b/Source/Mosa.Compiler.x86/Transforms/BaseIR/SubCarryOut64.cs @@ -15,10 +15,11 @@ public SubCarryOut64() : base(IR.SubCarryOut64, TransformType.Manual | Transform public override void Transform(Context context, Transform transform) { + var result2 = context.Result2; + transform.SplitOperand(context.Result, out var resultLow, out var resultHigh); transform.SplitOperand(context.Operand1, out var op1L, out var op1H); transform.SplitOperand(context.Operand2, out var op2L, out var op2H); - var result2 = context.Result2; var v1 = transform.VirtualRegisters.Allocate32(); diff --git a/Source/Mosa.Compiler.x86/Transforms/BaseIR/SubOverflowOut64.cs b/Source/Mosa.Compiler.x86/Transforms/BaseIR/SubOverflowOut64.cs index c2a6384585..48d3fa563c 100644 --- a/Source/Mosa.Compiler.x86/Transforms/BaseIR/SubOverflowOut64.cs +++ b/Source/Mosa.Compiler.x86/Transforms/BaseIR/SubOverflowOut64.cs @@ -15,10 +15,11 @@ public SubOverflowOut64() : base(IR.SubOverflowOut64, TransformType.Manual | Tra public override void Transform(Context context, Transform transform) { + var result2 = context.Result2; + transform.SplitOperand(context.Result, out var resultLow, out var resultHigh); transform.SplitOperand(context.Operand1, out var op1L, out var op1H); transform.SplitOperand(context.Operand2, out var op2L, out var op2H); - var result2 = context.Result2; var v1 = transform.VirtualRegisters.Allocate32(); diff --git a/Source/Mosa.Compiler.x86/Transforms/RuntimeCall/RuntimeCallTransforms.cs b/Source/Mosa.Compiler.x86/Transforms/RuntimeCall/RuntimeCallTransforms.cs index 1ae14b3057..4cc736f3fc 100644 --- a/Source/Mosa.Compiler.x86/Transforms/RuntimeCall/RuntimeCallTransforms.cs +++ b/Source/Mosa.Compiler.x86/Transforms/RuntimeCall/RuntimeCallTransforms.cs @@ -13,8 +13,6 @@ public static class RuntimeCallTransforms { new DivSigned64(), new DivUnsigned64(), - new MulCarryOut64(), - new MulOverflowOut64(), new RemR4(), new RemR8(), new RemSigned64(), @@ -23,5 +21,7 @@ public static class RuntimeCallTransforms new ConvertR8ToI64(), new ConvertR4ToU64(), new ConvertR8ToU64(), + new MulCarryOut64(), + new MulOverflowOut64(), }; }