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(),
};
}