<commit_before>/*
 * (c) 2008 MOSA - The Managed Operating System Alliance
 *
 * Licensed under the terms of the New BSD License.
 *
 * Authors:
 *  <NAME> (grover) <<EMAIL>>
 *  <NAME> (tgiphil) <<EMAIL>>
*/

using System;
using System.Collections.Generic;

using Mosa.Runtime.CompilerFramework;
using Mosa.Runtime.Metadata;
using Mosa.Runtime.Metadata.Signatures;
using Mosa.Platforms.x86.Constraints;

using CPUx86 = Mosa.Platforms.x86.CPUx86;

namespace Mosa.Platforms.x86
{

    /// <summary>
    /// This class provides a common base class for architecture
    /// specific operations.
    /// </summary>
    public class Architecture : BasicArchitecture
    {
        /// <summary>
        /// Defines the register set of the target architecture.
        /// </summary>
        private static readonly Register[] Registers = new Register[]
        {
            ////////////////////////////////////////////////////////
            // 32-bit general purpose registers
            ////////////////////////////////////////////////////////
            GeneralPurposeRegister.EAX,
            GeneralPurposeRegister.ECX,
            GeneralPurposeRegister.EDX,
            GeneralPurposeRegister.EBX,
            GeneralPurposeRegister.ESI,
            GeneralPurposeRegister.EDI,

            ////////////////////////////////////////////////////////
            // 128-bit floating point registers
            ////////////////////////////////////////////////////////
            SSE2Register.XMM0,
            SSE2Register.XMM1,
            SSE2Register.XMM2,
            SSE2Register.XMM3,
            SSE2Register.XMM4,
            SSE2Register.XMM5,
            SSE2Register.XMM6,
            SSE2Register.XMM7
        };

        /// <summary>
        /// Maps constraints to an instruction. Deprecated.
        /// </summary>
        private static readonly Dictionary<Type, Type> Constraints = new Dictionary<Type, Type>()
        {
            { typeof(CPUx86.AddInstruction), typeof(GPRConstraint) },
            { typeof(CPUx86.AdcInstruction), typeof(GPRConstraint) },
            { typeof(CPUx86.DivInstruction), typeof(DivConstraint) },
            { typeof(CPUx86.AndInstruction), typeof(LogicalAndConstraint) },
            { typeof(CPUx86.OrInstruction), typeof(LogicalOrConstraint) },
            { typeof(CPUx86.XorInstruction), typeof(LogicalXorConstraint) },
            { typeof(CPUx86.MovInstruction), typeof(MoveConstraint) },
            { typeof(CPUx86.MulInstruction), typeof(MulConstraint) },
            { typeof(CPUx86.SarInstruction), typeof(ShiftConstraint) },
            { typeof(CPUx86.ShlInstruction), typeof(ShiftConstraint) },
            { typeof(CPUx86.ShrInstruction), typeof(ShiftConstraint) },
            { typeof(CPUx86.SubInstruction), typeof(GPRConstraint) },
        };

        /// <summary>
        /// Specifies the architecture features to use in generated code.
        /// </summary>
        private ArchitectureFeatureFlags architectureFeatures;

        /// <summary>
        /// Initializes a new instance of the <see cref="Architecture"/> class.
        /// </summary>
        /// <param name="architectureFeatures">The features this architecture supports.</param>
        protected Architecture(ArchitectureFeatureFlags architectureFeatures)
        {
            this.architectureFeatures = architectureFeatures;
        }

        /// <summary>
        /// Retrieves the native integer size of the x86 platform.
        /// </summary>
        /// <value>This property always returns 32.</value>
        public override int NativeIntegerSize
        {
            get { return 32; }
        }

        /// <summary>
        /// Retrieves the register set of the x86 platform.
        /// </summary>
        public override Register[] RegisterSet
        {
            get { return Registers; }
        }

        /// <summary>
        /// Retrieves the stack frame register of the x86.
        /// </summary>
        public override Register StackFrameRegister
        {
            get { return GeneralPurposeRegister.EBP; }
        }

        /// <summary>
        /// Factory method for the Architecture class.
        /// </summary>
        /// <returns>The created architecture instance.</returns>
        /// <param name="architectureFeatures">The features available in the architecture and code generation.</param>
        /// <remarks>
        /// This method creates an instance of an appropriate architecture class, which supports the specific
        /// architecture features.
        /// </remarks>
        public static IArchitecture CreateArchitecture(ArchitectureFeatureFlags architectureFeatures)
        {
            if (architectureFeatures == ArchitectureFeatureFlags.AutoDetect)
                architectureFeatures = ArchitectureFeatureFlags.MMX | ArchitectureFeatureFlags.SSE | ArchitectureFeatureFlags.SSE2;

            return new Architecture(architectureFeatures);
        }

        /// <summary>
        /// Creates a new result operand of the requested type.
        /// </summary>
        /// <param name="signatureType">The type requested.</param>
        /// <param name="instructionLabel">The label of the instruction requesting the operand.</param>
        /// <param name="operandStackIndex">The stack index of the operand.</param>
        /// <returns>A new operand usable as a result operand.</returns>
        public override Operand CreateResultOperand(SigType signatureType, int instructionLabel, int operandStackIndex)
        {
            return new RegisterOperand(signatureType, GeneralPurposeRegister.EAX);
        }

        /// <summary>
        /// Extends the assembly compiler pipeline with x86 specific stages.
        /// </summary>
        /// <param name="assemblyCompilerPipeline">The assembly compiler pipeline to extend.</param>
        public override void ExtendAssemblyCompilerPipeline(CompilerPipeline assemblyCompilerPipeline)
        {
        }

        /// <summary>
        /// Extends the method compiler pipeline with x86 specific stages.
        /// </summary>
        /// <param name="methodCompilerPipeline">The method compiler pipeline to extend.</param>
        public override void ExtendMethodCompilerPipeline(CompilerPipeline methodCompilerPipeline)
        {
            // FIXME: Create a specific code generator instance using requested feature flags.
            // FIXME: Add some more optimization passes, which take advantage of advanced x86 instructions
            // and packed operations available with MMX/SSE extensions
            methodCompilerPipeline.AddRange(
                new IMethodCompilerStage[]
                {
                    new LongOperandTransformationStage(),
                    //new InstructionLogger(typeof(LongOperandTransformationStage)),
                    new AddressModeConversionStage(),
                    //new InstructionLogger(typeof(AddressModeConversionStage)),
                    new CILTransformationStage(),
                    //new InstructionLogger(typeof(CILTransformationStage)),
                    new IRTransformationStage(),
                    //new InstructionLogger(typeof(IRTransformationStage)),
					new TweakTransformationStage(),
                    //new InstructionLogger(typeof(TweakTransformationStage)),
					new MemToMemConversionStage(),
                    //new InstructionLogger(typeof(MemToMemConversionStage)),
                    //new SimplePeepholeOptimizationStage(),
                    //new InstructionLogger(typeof(SimplePeepholeOptimizationStage)),
                    //FlowGraphVisualizationStage.Instance,
                });
        }

        /// <summary>
        /// Retrieves a calling convention object for the requested calling convention.
        /// </summary>
        /// <param name="callingConvention">One of the defined calling conventions.</param>
        /// <returns>An instance of <see cref="ICallingConvention"/>.</returns>
        /// <exception cref="System.NotSupportedException"><paramref name="callingConvention"/> is not a supported calling convention.</exception>
        public override ICallingConvention GetCallingConvention(CallingConvention callingConvention)
        {
            switch (callingConvention)
            {
                case CallingConvention.Default:
                    return new DefaultCallingConvention(this);

                default:
                    throw new NotSupportedException();
            }
        }

        /// <summary>
        /// Gets the type memory requirements.
        /// </summary><commit_msg>- Experimental Branch Merge #466<commit_after>/*
 * (c) 2008 MOSA - The Managed Operating System Alliance
 *
 * Licensed under the terms of the New BSD License.
 *
 * Authors:
 *  <NAME> (grover) <<EMAIL>>
 *  <NAME> (tgiphil) <<EMAIL>>
*/

using System;
using System.Collections.Generic;

using Mosa.Runtime.CompilerFramework;
using Mosa.Runtime.Metadata;
using Mosa.Runtime.Metadata.Signatures;
using Mosa.Platforms.x86.Constraints;

using CPUx86 = Mosa.Platforms.x86.CPUx86;

namespace Mosa.Platforms.x86
{

    /// <summary>
    /// This class provides a common base class for architecture
    /// specific operations.
    /// </summary>
    public class Architecture : BasicArchitecture
    {
        /// <summary>
        /// Defines the register set of the target architecture.
        /// </summary>
        private static readonly Register[] Registers = new Register[]
        {
            ////////////////////////////////////////////////////////
            // 32-bit general purpose registers
            ////////////////////////////////////////////////////////
            GeneralPurposeRegister.EAX,
            GeneralPurposeRegister.ECX,
            GeneralPurposeRegister.EDX,
            GeneralPurposeRegister.EBX,
            GeneralPurposeRegister.ESI,
            GeneralPurposeRegister.EDI,

            ////////////////////////////////////////////////////////
            // 128-bit floating point registers
            ////////////////////////////////////////////////////////
            SSE2Register.XMM0,
            SSE2Register.XMM1,
            SSE2Register.XMM2,
            SSE2Register.XMM3,
            SSE2Register.XMM4,
            SSE2Register.XMM5,
            SSE2Register.XMM6,
            SSE2Register.XMM7
        };

        /// <summary>
        /// Maps constraints to an instruction. Deprecated.
        /// </summary>
        private static readonly Dictionary<Type, Type> Constraints = new Dictionary<Type, Type>()
        {
            { typeof(CPUx86.AddInstruction), typeof(GPRConstraint) },
            { typeof(CPUx86.AdcInstruction), typeof(GPRConstraint) },
            { typeof(CPUx86.DivInstruction), typeof(DivConstraint) },
            { typeof(CPUx86.AndInstruction), typeof(LogicalAndConstraint) },
            { typeof(CPUx86.OrInstruction), typeof(LogicalOrConstraint) },
            { typeof(CPUx86.XorInstruction), typeof(LogicalXorConstraint) },
            { typeof(CPUx86.MovInstruction), typeof(MoveConstraint) },
            { typeof(CPUx86.MulInstruction), typeof(MulConstraint) },
            { typeof(CPUx86.SarInstruction), typeof(ShiftConstraint) },
            { typeof(CPUx86.ShlInstruction), typeof(ShiftConstraint) },
            { typeof(CPUx86.ShrInstruction), typeof(ShiftConstraint) },
            { typeof(CPUx86.SubInstruction), typeof(GPRConstraint) },
        };

        /// <summary>
        /// Specifies the architecture features to use in generated code.
        /// </summary>
        private ArchitectureFeatureFlags architectureFeatures;

        /// <summary>
        /// Initializes a new instance of the <see cref="Architecture"/> class.
        /// </summary>
        /// <param name="architectureFeatures">The features this architecture supports.</param>
        protected Architecture(ArchitectureFeatureFlags architectureFeatures)
        {
            this.architectureFeatures = architectureFeatures;
        }

        /// <summary>
        /// Retrieves the native integer size of the x86 platform.
        /// </summary>
        /// <value>This property always returns 32.</value>
        public override int NativeIntegerSize
        {
            get { return 32; }
        }

        /// <summary>
        /// Retrieves the register set of the x86 platform.
        /// </summary>
        public override Register[] RegisterSet
        {
            get { return Registers; }
        }

        /// <summary>
        /// Retrieves the stack frame register of the x86.
        /// </summary>
        public override Register StackFrameRegister
        {
            get { return GeneralPurposeRegister.EBP; }
        }

        /// <summary>
        /// Factory method for the Architecture class.
        /// </summary>
        /// <returns>The created architecture instance.</returns>
        /// <param name="architectureFeatures">The features available in the architecture and code generation.</param>
        /// <remarks>
        /// This method creates an instance of an appropriate architecture class, which supports the specific
        /// architecture features.
        /// </remarks>
        public static IArchitecture CreateArchitecture(ArchitectureFeatureFlags architectureFeatures)
        {
            if (architectureFeatures == ArchitectureFeatureFlags.AutoDetect)
                architectureFeatures = ArchitectureFeatureFlags.MMX | ArchitectureFeatureFlags.SSE | ArchitectureFeatureFlags.SSE2;

            return new Architecture(architectureFeatures);
        }

        /// <summary>
        /// Creates a new result operand of the requested type.
        /// </summary>
        /// <param name="signatureType">The type requested.</param>
        /// <param name="instructionLabel">The label of the instruction requesting the operand.</param>
        /// <param name="operandStackIndex">The stack index of the operand.</param>
        /// <returns>A new operand usable as a result operand.</returns>
        public override Operand CreateResultOperand(SigType signatureType, int instructionLabel, int operandStackIndex)
        {
            return new RegisterOperand(signatureType, GeneralPurposeRegister.EAX);
        }

        /// <summary>
        /// Extends the assembly compiler pipeline with x86 specific stages.
        /// </summary>
        /// <param name="assemblyCompilerPipeline">The assembly compiler pipeline to extend.</param>
        public override void ExtendAssemblyCompilerPipeline(CompilerPipeline assemblyCompilerPipeline)
        {
        }

        /// <summary>
        /// Extends the method compiler pipeline with x86 specific stages.
        /// </summary>
        /// <param name="methodCompilerPipeline">The method compiler pipeline to extend.</param>
        public override void ExtendMethodCompilerPipeline(CompilerPipeline methodCompilerPipeline)
        {
            // FIXME: Create a specific code generator instance using requested feature flags.
            // FIXME: Add some more optimization passes, which take advantage of advanced x86 instructions
            // and packed operations available with MMX/SSE extensions
            methodCompilerPipeline.AddRange(
                new IMethodCompilerStage[]
                {
                    new LongOperandTransformationStage(),
                    new InstructionLogger(typeof(LongOperandTransformationStage)),
                    new AddressModeConversionStage(),
                    new InstructionLogger(typeof(AddressModeConversionStage)),
                    new CILTransformationStage(),
                    new InstructionLogger(typeof(CILTransformationStage)),
                    new IRTransformationStage(),
                    new InstructionLogger(typeof(IRTransformationStage)),
					new TweakTransformationStage(),
                    new InstructionLogger(typeof(TweakTransformationStage)),
					new MemToMemConversionStage(),
                    new InstructionLogger(typeof(MemToMemConversionStage)),
                    //new SimplePeepholeOptimizationStage(),
                    //new InstructionLogger(typeof(SimplePeepholeOptimizationStage)),
                    //FlowGraphVisualizationStage.Instance,
                });
        }

        /// <summary>
        /// Retrieves a calling convention object for the requested calling convention.
        /// </summary>
        /// <param name="callingConvention">One of the defined calling conventions.</param>
        /// <returns>An instance of <see cref="ICallingConvention"/>.</returns>
        /// <exception cref="System.NotSupportedException"><paramref name="callingConvention"/> is not a supported calling convention.</exception>
        public override ICallingConvention GetCallingConvention(CallingConvention callingConvention)
        {
            switch (callingConvention)
            {
                case CallingConvention.Default:
                    return new DefaultCallingConvention(this);

                default:
                    throw new NotSupportedException();
            }
        }

        /// <summary>
        /// Gets the type memory requirements.
        /// </summary>
{'fraction_non_alphanumeric': 0.11779724946323913, 'fraction_numerical': 0.008994371264434515, 'mean_word_length': 1.9409556313993175, 'pattern_counts': {'":': 0, '<': 137, '<?xml version=': 0, '>': 137, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '953101', 'n_tokens_mistral': 4077, 'n_tokens_neox': 3874, 'n_words': 1011}