Exemplo n.º 1
0
 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);
 }
Exemplo n.º 2
0
 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);
 }
Exemplo n.º 4
0
 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));
 }
Exemplo n.º 5
0
        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);
        }
Exemplo n.º 6
0
 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));
 }
Exemplo n.º 7
0
        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();
            }
        }
Exemplo n.º 10
0
        public bool MatchBinaryNumericInstruction(BinaryNumericOperator @operator)
        {
            var op = this as BinaryNumericInstruction;

            return(op != null && op.Operator == @operator);
        }
Exemplo n.º 11
0
 public BinaryNumericInstruction(BinaryNumericOperator op, ILInstruction left, ILInstruction right, bool checkForOverflow, Sign sign)
     : this(op, left, right, left.ResultType, right.ResultType, checkForOverflow, sign)
 {
 }