Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expanding ARM32 Support #1184

Merged
merged 1 commit into from
Dec 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions Source/Mosa.Compiler.ARM32/Transforms/BaseARM32Transform.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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)
{
Expand All @@ -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);
}
}

Expand Down
29 changes: 29 additions & 0 deletions Source/Mosa.Compiler.ARM32/Transforms/BaseIR/AddCarryOut64.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright (c) MOSA Project. Licensed under the New BSD License.

using Mosa.Compiler.Framework;

namespace Mosa.Compiler.ARM32.Transforms.BaseIR;

/// <summary>
/// AddCarryOut64
/// </summary>
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);
}
}
30 changes: 30 additions & 0 deletions Source/Mosa.Compiler.ARM32/Transforms/BaseIR/AddOverflowOut32.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright (c) MOSA Project. Licensed under the New BSD License.

using Mosa.Compiler.Framework;

namespace Mosa.Compiler.ARM32.Transforms.BaseIR;

/// <summary>
/// AddOverflowOut32
/// </summary>
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);
}
}
34 changes: 34 additions & 0 deletions Source/Mosa.Compiler.ARM32/Transforms/BaseIR/AddOverflowOut64.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright (c) MOSA Project. Licensed under the New BSD License.

using Mosa.Compiler.Framework;

namespace Mosa.Compiler.ARM32.Transforms.BaseIR;

/// <summary>
/// AddOverflowOut64
/// </summary>
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);
}
}
16 changes: 8 additions & 8 deletions Source/Mosa.Compiler.ARM32/Transforms/BaseIR/IRTransforms.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public static class IRTransforms
new AddCarryIn32(),
new AddCarryOut32(),
new AddManagedPointer(),
//new AddOverflowOut32(),
new AddOverflowOut32(),
new AddR4(),
new AddR8(),
new AddressOf(),
Expand Down Expand Up @@ -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(),
Expand Down Expand Up @@ -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(),
Expand Down Expand Up @@ -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(),
Expand Down
27 changes: 27 additions & 0 deletions Source/Mosa.Compiler.ARM32/Transforms/BaseIR/MulCarryOut32.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright (c) MOSA Project. Licensed under the New BSD License.

using Mosa.Compiler.Framework;

namespace Mosa.Compiler.ARM32.Transforms.BaseIR;

/// <summary>
/// MulCarryOut32
/// </summary>
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);
}
}
27 changes: 27 additions & 0 deletions Source/Mosa.Compiler.ARM32/Transforms/BaseIR/MulOverflowOut32.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright (c) MOSA Project. Licensed under the New BSD License.

using Mosa.Compiler.Framework;

namespace Mosa.Compiler.ARM32.Transforms.BaseIR;

/// <summary>
/// MulOverflowOut32
/// </summary>
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);
}
}
29 changes: 29 additions & 0 deletions Source/Mosa.Compiler.ARM32/Transforms/BaseIR/SubCarryOut64.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright (c) MOSA Project. Licensed under the New BSD License.

using Mosa.Compiler.Framework;

namespace Mosa.Compiler.ARM32.Transforms.BaseIR;

/// <summary>
/// SubCarryOut64
/// </summary>
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);
}
}
30 changes: 30 additions & 0 deletions Source/Mosa.Compiler.ARM32/Transforms/BaseIR/SubOverflowOut32.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright (c) MOSA Project. Licensed under the New BSD License.

using Mosa.Compiler.Framework;

namespace Mosa.Compiler.ARM32.Transforms.BaseIR;

/// <summary>
/// SubOverflowOut32
/// </summary>
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);
}
}
29 changes: 29 additions & 0 deletions Source/Mosa.Compiler.ARM32/Transforms/BaseIR/SubOverflowOut64.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright (c) MOSA Project. Licensed under the New BSD License.

using Mosa.Compiler.Framework;

namespace Mosa.Compiler.ARM32.Transforms.BaseIR;

/// <summary>
/// SubOverflowOut64
/// </summary>
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);
}
}
46 changes: 46 additions & 0 deletions Source/Mosa.Compiler.ARM32/Transforms/RuntimeCall/MulCarryOut64.cs
Original file line number Diff line number Diff line change
@@ -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;

/// <summary>
/// MulCarryOut64
/// </summary>
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);
}
}
Loading
Loading