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; }
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; }