Exemple #1
0
        public StateData(StateData other, int memVarsCount)
        {
            if (other == null)
                throw new ArgumentNullException("other");
            if (memVarsCount < 0)
                throw new ArgumentOutOfRangeException("memVarsCount");

            _registers = (CompilerVar[])other._registers.Clone();
            Contract.Assume(_registers.Length == other._registers.Length);

            UsedGP = other.UsedGP;
            UsedMM = other.UsedMM;
            UsedXMM = other.UsedXMM;
            ChangedGP = other.ChangedGP;
            ChangedMM = other.ChangedMM;
            ChangedXMM = other.ChangedXMM;
            MemVarsData = new CompilerVar[memVarsCount];
        }
        protected override CompilerItem TranslateImpl(CompilerContext cc)
        {
            // translate using Instruction
            CompilerItem ret = base.TranslateImpl(cc);

            // we jump with item if it's InstructionCode.JMP (unconditional) and points to yet unknown location.
            if (Code == InstructionCode.Jmp && !JumpTarget.IsTranslated)
            {
                cc.AddBackwardCode(this);
                ret = JumpTarget;
            }
            else
            {
                _state = cc.SaveState();
                if (JumpTarget.IsTranslated)
                {
                    DoJump(cc);
                }
                else
                {
                    // state is not known, so we need to call DoJump() later. Compiler will do it for us.
                    cc.AddForwardJump(this);
                    JumpTarget.State = _state;
                }

                // Mark next code as unrecheable, cleared by a next label (ETarget).
                if (Code == InstructionCode.Jmp)
                {
                    cc.Unreachable = true;
                }
            }

            // Need to traverse over all active variables and unuse them if their scope ends here
            if (cc.Active != null)
            {
                CompilerVar first = cc.Active;
                CompilerVar var = first;

                do
                {
                    cc.UnuseVarOnEndOfScope(this, var);
                    var = var.NextActive;
                } while (var != first);
            }

            return ret;
        }
        internal void RestoreState(StateData state, int targetOffset = Operand.InvalidValue)
        {
            // 16 + 8 + 16 = GP + MMX + XMM registers.
            const int STATE_REGS_COUNT = 16 + 8 + 16;

            StateData fromState = _state;
            StateData toState = state;

            // No change, rare...
            if (fromState == toState)
                return;

            int @base;
            int i;

            // TODO: 16 + 8 + 16 is cryptic, make constants instead!

            // --------------------------------------------------------------------------
            // Set target state to all variables. vdata->tempInt is target state in this
            // function.
            // --------------------------------------------------------------------------

            {
                // UNUSED.
                CompilerVar vdata = _active;
                if (vdata != null)
                {
                    do
                    {
                        vdata.Temp = VariableState.Unused;
                        vdata = vdata.NextActive;
                    } while (vdata != _active);
                }

                // MEMORY.
                for (i = 0; i < toState.MemVarsData.Length; i++)
                {
                    toState.MemVarsData[i].Temp = VariableState.Memory;
                }

                // REGISTER.
                for (i = 0; i < StateData.RegisterCount; i++)
                {
                    if ((vdata = toState.Registers[i]) != null)
                        vdata.Temp = VariableState.Register;
                }
            }

            #if false
            // --------------------------------------------------------------------------
            // [GP-Registers Switch]
            // --------------------------------------------------------------------------

            // TODO.
            for (i = 0; i < RegNum.GP; i++)
            {
                VarData fromVar = fromState.GP[i];
                VarData toVar = toState.GP[i];

                if (fromVar != toVar)
                {
                    if (fromVar != null)
                    {
                        if (toVar != null)
                        {
                            if (fromState.GP[to
        internal void AssignState(StateData state)
        {
            Contract.Requires(state != null);

            Compiler compiler = Compiler;
            _state.CopyFrom(state);
            _state.MemVarsData = new CompilerVar[0];

            int i;
            CompilerVar vdata;

            // Unuse all variables first.
            vdata = _active;
            if (vdata != null)
            {
                do
                {
                    vdata.State = VariableState.Unused;
                    vdata = vdata.NextActive;
                } while (vdata != _active);
            }

            // Assign variables stored in memory which are not unused.
            for (i = 0; i < state.MemVarsData.Length; i++)
            {
                state.MemVarsData[i].State = VariableState.Memory;
            }

            // Assign allocated variables.
            for (i = 0; i < RegNum.GP; i++)
            {
                RegisterMask mask = RegisterMask.FromIndex((RegIndex)i);
                if ((vdata = _state.GP[i]) != null)
                {
                    vdata.State = VariableState.Register;
                    vdata.RegisterIndex = (RegIndex)i;
                    vdata.Changed = (_state.ChangedGP & mask) != RegisterMask.Zero;
                }
            }

            for (i = 0; i < RegNum.MM; i++)
            {
                RegisterMask mask = RegisterMask.FromIndex((RegIndex)i);
                if ((vdata = _state.MM[i]) != null)
                {
                    vdata.State = VariableState.Register;
                    vdata.RegisterIndex = (RegIndex)i;
                    vdata.Changed = (_state.ChangedMM & mask) != RegisterMask.Zero;
                }
            }

            for (i = 0; i < RegNum.XMM; i++)
            {
                RegisterMask mask = RegisterMask.FromIndex((RegIndex)i);
                if ((vdata = _state.XMM[i]) != null)
                {
                    vdata.State = VariableState.Register;
                    vdata.RegisterIndex = (RegIndex)i;
                    vdata.Changed = (_state.ChangedXMM & mask) != RegisterMask.Zero;
                }
            }
        }
        protected override CompilerItem TranslateImpl(CompilerContext cc)
        {
            // If this Target was already translated, it's needed to change the current
            // state and return null to tell CompilerContext to process next untranslated
            // item.
            if (IsTranslated)
            {
                cc.RestoreState(_state);
                return null;
            }

            if (cc.Unreachable)
            {
                // If the context has "isUnreachable" flag set and there is no state then
                // it means that this code will be never called. This is a problem, because
                // we are unable to assign a state to current location so we can't allocate
                // registers for variables used inside. So instead of doing anything wrong
                // we remove the unreachable code.
                if (_state == null)
                    return RemoveUnreachableItems();

                // Assign state to the compiler context.
                cc.Unreachable = false;
                cc.AssignState(_state);
            }
            else
            {
                _state = cc.SaveState();
            }

            return Next;
        }
Exemple #6
0
        internal void CopyFrom(StateData other)
        {
            Contract.Requires(other != null);

            Array.Copy(other._registers, _registers, _registers.Length);
            UsedGP = other.UsedGP;
            UsedMM = other.UsedMM;
            UsedXMM = other.UsedXMM;
            ChangedGP = other.ChangedGP;
            ChangedMM = other.ChangedMM;
            ChangedXMM = other.ChangedXMM;
        }