예제 #1
0
        protected override CompilerItem TranslateImpl(CompilerContext cc)
        {
            int i;
            int variablesCount = (_variables != null) ? _variables.Length : 0;

            if (variablesCount > 0)
            {
                // These variables are used by the instruction and we set current offset
                // to their work offsets -> getSpillCandidate never return the variable
                // used this instruction.
                for (i = 0; i < variablesCount; i++)
                {
                    _variables[i].VarData.WorkOffset = cc.CurrentOffset;
                }

                // Alloc variables used by the instruction (special first).
                for (i = 0; i < variablesCount; i++)
                {
                    VarAllocRecord r = _variables[i];
                    // Alloc variables with specific register first.
                    if ((r.VarFlags & VariableAlloc.Special) != 0)
                        cc.AllocVar(r.VarData, r.RegMask, r.VarFlags);
                }

                for (i = 0; i < variablesCount; i++)
                {
                    VarAllocRecord r = _variables[i];
                    // Alloc variables without specific register last.
                    if ((r.VarFlags & VariableAlloc.Special) == 0)
                        cc.AllocVar(r.VarData, r.RegMask, r.VarFlags);
                }

                cc.TranslateOperands(_operands);
            }

            if (_memoryOperand != null && (_memoryOperand.Id & Operand.OperandIdTypeMask) == Operand.OperandIdTypeVar)
            {
                CompilerVar vdata = Compiler.GetVarData(_memoryOperand.Id);
                Contract.Assert(vdata != null);

                switch (vdata.State)
                {
                case VariableState.Unused:
                    vdata.State = VariableState.Memory;
                    break;

                case VariableState.Register:
                    vdata.Changed = false;
                    cc.UnuseVar(vdata, VariableState.Memory);
                    break;
                }
            }

            for (i = 0; i < variablesCount; i++)
            {
                cc.UnuseVarOnEndOfScope(this, _variables[i]);
            }

            return Next;
        }
예제 #2
0
        protected override CompilerItem TranslateImpl(CompilerContext cc)
        {
            switch (_hintKind)
            {
            case VariableHintKind.Alloc:
                cc.AllocVar(_varData, new RegisterMask(_hintValue), VariableAlloc.Read);
                break;

            case VariableHintKind.Spill:
                if (_varData.State == VariableState.Register)
                    cc.SpillVar(_varData);
                break;

            case VariableHintKind.Save:
            case VariableHintKind.SaveAndUnuse:
                if (_varData.State == VariableState.Register && _varData.Changed)
                {
                    cc.EmitSaveVar(_varData, _varData.RegisterIndex);
                    _varData.Changed = false;
                }

                if (_hintKind == VariableHintKind.SaveAndUnuse)
                    goto case VariableHintKind.Unuse;

                break;

            case VariableHintKind.Unuse:
                cc.UnuseVar(_varData, VariableState.Unused);
                goto end;
            }

            cc.UnuseVarOnEndOfScope(this, _varData);

            end:
            return Next;
        }