Example #1
0
File: Mix.cs Project: arlm/MixEmul
 public override void ResetProfilingCounts()
 {
     mFullMemory.ResetProfilingCounts();
     if (FloatingPointModule != null)
     {
         FloatingPointModule.ResetProfilingCounts();
     }
 }
Example #2
0
File: Mix.cs Project: arlm/MixEmul
 public void SetFloatingPointModuleEnabled(bool enabled)
 {
     if (enabled && FloatingPointModule == null)
     {
         FloatingPointModule = new FloatingPointModule(this);
     }
     else if (!enabled && FloatingPointModule != null)
     {
         FloatingPointModule = null;
     }
 }
        public static bool DoFloatingPoint(ModuleBase module, MixInstruction.Instance instance)
        {
            if (!(module is Mix))
            {
                module.ReportRuntimeError(string.Format("Floating point instruction {0} is only available within Mix", instance.Instruction.Mnemonic));
                return(false);
            }

            var mix = (Mix)module;

            FloatingPointModule floatingPointModule = mix.FloatingPointModule;

            if (floatingPointModule == null)
            {
                module.ReportRuntimeError(string.Format("Instruction {0} requires floating point module to be enabled", instance.Instruction.Mnemonic));
                return(false);
            }

            if (mExecutionStatus != null && mExecutionStatus.ProgramCounter != module.ProgramCounter)
            {
                mExecutionStatus = null;
            }

            if (mExecutionStatus == null)
            {
                mExecutionStatus = new ExecutionStatus(module.Mode, module.ProgramCounter, instance.Instruction.Mnemonic);
            }

            if (mExecutionStatus.CurrentStep == ExecutionStatus.Step.Initialize)
            {
                mExecutionStatus.RAValue = module.Registers.RA.FullWordValue;

                bool prenormInstruction = Array.IndexOf(mPrenormOpcodes, instance.MixInstruction.Opcode) != -1;
                bool fcmpInstruction    = !prenormInstruction && instance.MixInstruction.Opcode == fcmpOpcode;

                if (prenormInstruction || fcmpInstruction)
                {
                    var indexedAddress = InstructionHelpers.GetValidIndexedAddress(module, instance.AddressValue, instance.Index);
                    if (indexedAddress == int.MinValue)
                    {
                        mExecutionStatus = null;
                        return(false);
                    }

                    mExecutionStatus.ParameterValue = module.Memory[indexedAddress];
                }

                module.Registers.SaveToMemory(floatingPointModule.FullMemory, ModuleSettings.FloatingPointMemoryWordCount, 0);

                if (!floatingPointModule.ValidateCall(mExecutionStatus.Mnemonic))
                {
                    module.ReportRuntimeError("Unable to initialize floating point module");
                    mExecutionStatus = null;

                    return(false);
                }

                module.Mode = ModuleBase.RunMode.Module;

                if (prenormInstruction)
                {
                    mExecutionStatus.CurrentStep = ExecutionStatus.Step.PrenormRA;

                    if (floatingPointModule.PreparePrenorm(mExecutionStatus.RAValue))
                    {
                        module.ReportBreakpointReached();
                        return(false);
                    }
                }
                else
                {
                    mExecutionStatus.CurrentStep = ExecutionStatus.Step.ExecuteInstruction;

                    if (fcmpInstruction
                                                ? floatingPointModule.PrepareCall(mExecutionStatus.Mnemonic, mExecutionStatus.RAValue, mExecutionStatus.ParameterValue)
                                                : floatingPointModule.PrepareCall(mExecutionStatus.Mnemonic, mExecutionStatus.RAValue))
                    {
                        module.ReportBreakpointReached();
                        return(false);
                    }
                }
            }

            mExecutionStatus.OverflowDetected |= floatingPointModule.Tick();

            switch (floatingPointModule.Status)
            {
            case ModuleBase.RunStatus.Idle:

                switch (mExecutionStatus.CurrentStep)
                {
                case ExecutionStatus.Step.PrenormRA:
                    mExecutionStatus.RAValue     = floatingPointModule.Registers.RA.FullWordValue;
                    mExecutionStatus.CurrentStep = ExecutionStatus.Step.PrenormParameter;

                    if (floatingPointModule.PreparePrenorm(mExecutionStatus.ParameterValue))
                    {
                        module.ReportBreakpointReached();
                        return(false);
                    }

                    break;

                case ExecutionStatus.Step.PrenormParameter:
                    mExecutionStatus.ParameterValue = floatingPointModule.Registers.RA.FullWordValue;
                    mExecutionStatus.CurrentStep    = ExecutionStatus.Step.ExecuteInstruction;

                    if (floatingPointModule.PrepareCall(mExecutionStatus.Mnemonic, mExecutionStatus.RAValue, mExecutionStatus.ParameterValue))
                    {
                        module.ReportBreakpointReached();
                        return(false);
                    }

                    break;

                case ExecutionStatus.Step.ExecuteInstruction:
                    mExecutionStatus.RAValue = floatingPointModule.Registers.RA.FullWordValue;
                    Registers.CompValues comparatorValue = floatingPointModule.Registers.CompareIndicator;
                    module.Registers.LoadFromMemory(floatingPointModule.FullMemory, ModuleSettings.FloatingPointMemoryWordCount);
                    module.Registers.OverflowIndicator = mExecutionStatus.OverflowDetected;

                    if (mExecutionStatus.Mnemonic == FcmpMnemonic)
                    {
                        module.Registers.CompareIndicator = comparatorValue;
                    }
                    else
                    {
                        module.Registers.RA.Magnitude = mExecutionStatus.RAValue.Magnitude;
                        module.Registers.RA.Sign      = mExecutionStatus.RAValue.Sign;
                    }

                    module.Mode = ModuleBase.RunMode.Normal;

                    mExecutionStatus = null;

                    return(true);
                }

                break;

            case ModuleBase.RunStatus.BreakpointReached:
                module.ReportBreakpointReached();

                break;

            case ModuleBase.RunStatus.InvalidInstruction:
            case ModuleBase.RunStatus.RuntimeError:
                module.ReportRuntimeError(string.Format("Floating point module failed to execute instruction {0}", mExecutionStatus.Mnemonic));
                module.Mode = mExecutionStatus.Mode;

                mExecutionStatus = null;

                break;
            }

            return(false);
        }