internal static StackType ComputeResultType(BinaryNumericOperator op, StackType left, StackType right) { // Based on Table 2: Binary Numeric Operations // also works for Table 5: Integer Operations // and for Table 7: Overflow Arithmetic Operations if (left == right || op == BinaryNumericOperator.ShiftLeft || op == BinaryNumericOperator.ShiftRight) { // Shift op codes use Table 6 return(left); } if (left == StackType.Ref || right == StackType.Ref) { if (left == StackType.Ref && right == StackType.Ref) { // sub(&, &) = I Debug.Assert(op == BinaryNumericOperator.Sub); return(StackType.I); } else { // add/sub with I or I4 and & Debug.Assert(op == BinaryNumericOperator.Add || op == BinaryNumericOperator.Sub); return(StackType.Ref); } } return(StackType.Unknown); }
public BinaryNumericInstruction(BinaryNumericOperator op, ILInstruction left, ILInstruction right, bool checkForOverflow, Sign sign) : base(OpCode.BinaryNumericInstruction, left, right) { this.CheckForOverflow = checkForOverflow; this.Sign = sign; this.Operator = op; this.resultType = ComputeResultType(op, left.ResultType, right.ResultType); Debug.Assert(resultType != StackType.Unknown); }
public BinaryNumericInstruction(BinaryNumericOperator op, ILInstruction left, ILInstruction right, StackType leftInputType, StackType rightInputType, bool checkForOverflow, Sign sign, bool isLifted = false) : base(OpCode.BinaryNumericInstruction, left, right) { this.CheckForOverflow = checkForOverflow; this.Sign = sign; this.Operator = op; this.LeftInputType = leftInputType; this.RightInputType = rightInputType; this.IsLifted = isLifted; this.resultType = ComputeResultType(op, LeftInputType, RightInputType); }
public CompoundAssignmentInstruction(BinaryNumericOperator op, ILInstruction target, ILInstruction value, IType type, bool checkForOverflow, Sign sign, CompoundAssignmentType compoundAssigmentType) : base(OpCode.CompoundAssignmentInstruction) { this.CheckForOverflow = checkForOverflow; this.Sign = sign; this.Operator = op; this.Target = target; this.type = type; this.Value = value; this.CompoundAssignmentType = compoundAssigmentType; Debug.Assert(compoundAssigmentType == CompoundAssignmentType.EvaluatesToNewValue || (op == BinaryNumericOperator.Add || op == BinaryNumericOperator.Sub)); Debug.Assert(IsValidCompoundAssignmentTarget(Target)); }
public bool MatchBinaryNumericInstruction(BinaryNumericOperator @operator, out ILInstruction left, out ILInstruction right) { var op = this as BinaryNumericInstruction; if (op != null && op.Operator == @operator) { left = op.Left; right = op.Right; return(true); } left = null; right = null; return(false); }
public NumericCompoundAssign(BinaryNumericInstruction binary, ILInstruction target, ILInstruction value, IType type, CompoundAssignmentType compoundAssignmentType) : base(OpCode.NumericCompoundAssign, compoundAssignmentType, target, value) { Debug.Assert(IsBinaryCompatibleWithType(binary, type)); this.CheckForOverflow = binary.CheckForOverflow; this.Sign = binary.Sign; this.LeftInputType = binary.LeftInputType; this.RightInputType = binary.RightInputType; this.UnderlyingResultType = binary.UnderlyingResultType; this.Operator = binary.Operator; this.IsLifted = binary.IsLifted; this.type = type; this.ILRange = binary.ILRange; Debug.Assert(compoundAssignmentType == CompoundAssignmentType.EvaluatesToNewValue || (Operator == BinaryNumericOperator.Add || Operator == BinaryNumericOperator.Sub)); Debug.Assert(IsValidCompoundAssignmentTarget(Target)); }
public bool MatchBinaryNumericInstruction(out BinaryNumericOperator @operator, out ILInstruction left, out ILInstruction right) { var op = this as BinaryNumericInstruction; if (op != null) { @operator = op.Operator; left = op.Left; right = op.Right; return(true); } @operator = BinaryNumericOperator.None; left = null; right = null; return(false); }
public NumericCompoundAssign(BinaryNumericInstruction binary, ILInstruction target, CompoundTargetKind targetKind, ILInstruction value, IType type, CompoundEvalMode evalMode) : base(OpCode.NumericCompoundAssign, evalMode, target, targetKind, value) { Debug.Assert(IsBinaryCompatibleWithType(binary, type)); this.CheckForOverflow = binary.CheckForOverflow; this.Sign = binary.Sign; this.LeftInputType = binary.LeftInputType; this.RightInputType = binary.RightInputType; this.UnderlyingResultType = binary.UnderlyingResultType; this.Operator = binary.Operator; this.IsLifted = binary.IsLifted; this.type = type; this.AddILRange(binary); Debug.Assert(evalMode == CompoundEvalMode.EvaluatesToNewValue || (Operator == BinaryNumericOperator.Add || Operator == BinaryNumericOperator.Sub)); Debug.Assert(this.ResultType == (IsLifted ? StackType.O : UnderlyingResultType)); }
string GetOperatorName(BinaryNumericOperator @operator) { switch (@operator) { case BinaryNumericOperator.Add: return("add"); case BinaryNumericOperator.Sub: return("sub"); case BinaryNumericOperator.Mul: return("mul"); case BinaryNumericOperator.Div: return("div"); case BinaryNumericOperator.Rem: return("rem"); case BinaryNumericOperator.BitAnd: return("bit.and"); case BinaryNumericOperator.BitOr: return("bit.or"); case BinaryNumericOperator.BitXor: return("bit.xor"); case BinaryNumericOperator.ShiftLeft: return("bit.shl"); case BinaryNumericOperator.ShiftRight: return("bit.shr"); default: throw new ArgumentOutOfRangeException(); } }
public bool MatchBinaryNumericInstruction(BinaryNumericOperator @operator) { var op = this as BinaryNumericInstruction; return(op != null && op.Operator == @operator); }
public BinaryNumericInstruction(BinaryNumericOperator op, ILInstruction left, ILInstruction right, bool checkForOverflow, Sign sign) : this(op, left, right, left.ResultType, right.ResultType, checkForOverflow, sign) { }