Ejemplo n.º 1
0
        private static Operand ConstantFolding3Integer(InstructionNode node)
        {
            if (node.OperandCount != 3 || node.ResultCount != 1)
            {
                return(null);
            }

            if (!node.Operand1.IsResolvedConstant || !node.Operand2.IsResolvedConstant || !node.Operand3.IsResolvedConstant)
            {
                return(null);
            }

            var instruction = node.Instruction;
            var result      = node.Result;
            var op1         = node.Operand1;
            var op2         = node.Operand2;
            var op3         = node.Operand3;

            if (instruction == IRInstruction.AddWithCarry32)
            {
                return(ConstantOperand.Create(result.Type, (uint)(op1.ConstantUnsignedLongInteger + op2.ConstantUnsignedLongInteger + (op3.IsConstantZero ? 0u : 1u))));
            }
            else if (instruction == IRInstruction.SubWithCarry32)
            {
                return(ConstantOperand.Create(result.Type, (uint)(op1.ConstantUnsignedLongInteger - op2.ConstantUnsignedLongInteger - (op3.IsConstantZero ? 0u : 1u))));
            }

            return(null);
        }
Ejemplo n.º 2
0
        public static SimpleInstruction StrengthReductionDivision(InstructionNode node)
        {
            if (!(node.Instruction == IRInstruction.DivUnsigned32 ||
                  node.Instruction == IRInstruction.DivUnsigned64))
            {
                return(null);
            }

            var result = node.Result;
            var op1    = node.Operand1;
            var op2    = node.Operand2;

            if (!op2.IsResolvedConstant)
            {
                return(null);
            }

            if (op2.IsConstantZero || op2.IsVirtualRegister)
            {
                return(null);
            }

            if ((node.Instruction == IRInstruction.DivUnsigned32 || node.Instruction == IRInstruction.DivUnsigned64) && IsPowerOfTwo(op2.ConstantUnsignedLongInteger))
            {
                int shift = GetPowerOfTwo(op2.ConstantUnsignedLongInteger);

                if (shift < 32 || (shift < 64 && result.Is64BitInteger))
                {
                    return(new SimpleInstruction()
                    {
                        Instruction = Select(result.Is64BitInteger, IRInstruction.ShiftRight32, IRInstruction.ShiftRight64),
                        Result = result,
                        Operand1 = op1,
                        Operand2 = ConstantOperand.Create(result.Type, (uint)shift)
                    });
                }
            }

            return(null);
        }
Ejemplo n.º 3
0
        public static SimpleInstruction StrengthReductionRemUnsignedModulus(InstructionNode node)
        {
            if (!(node.Instruction == IRInstruction.RemUnsigned32 ||
                  node.Instruction == IRInstruction.RemUnsigned64))
            {
                return(null);
            }

            var result = node.Result;
            var op1    = node.Operand1;
            var op2    = node.Operand2;

            if (!op2.IsResolvedConstant)
            {
                return(null);
            }

            if (op2.ConstantUnsignedLongInteger == 0)
            {
                return(null);
            }

            if (!IsPowerOfTwo(op2.ConstantUnsignedLongInteger))
            {
                return(null);
            }

            int power = GetPowerOfTwo(op2.ConstantUnsignedLongInteger);

            var mask = (1 << power) - 1;

            return(new SimpleInstruction()
            {
                Instruction = Select(result.Is64BitInteger, IRInstruction.LogicalAnd32, IRInstruction.LogicalAnd64),
                Result = result,
                Operand1 = op1,
                Operand2 = ConstantOperand.Create(result.Type, (uint)mask)
            });
        }
Ejemplo n.º 4
0
        public static SimpleInstruction StrengthReductionMultiplication(InstructionNode node)
        {
            if (!(node.Instruction == IRInstruction.MulSigned32 ||
                  node.Instruction == IRInstruction.MulUnsigned32 ||
                  node.Instruction == IRInstruction.MulSigned64 ||
                  node.Instruction == IRInstruction.MulUnsigned64))
            {
                return(null);
            }

            var result = node.Result;
            var op1    = node.Operand1;
            var op2    = node.Operand2;

            if (!op2.IsResolvedConstant)
            {
                return(null);
            }

            if (IsPowerOfTwo(op2.ConstantUnsignedLongInteger))
            {
                int shift = GetPowerOfTwo(op2.ConstantUnsignedLongInteger);

                if (shift < 32 || (shift < 64 && result.Is64BitInteger))
                {
                    return(new SimpleInstruction()
                    {
                        Instruction = Select(result.Is64BitInteger, IRInstruction.ShiftLeft32, IRInstruction.ShiftLeft64),
                        Result = result,
                        Operand1 = op1,
                        Operand2 = ConstantOperand.Create(result.Type, (uint)shift)
                    });
                }
            }

            return(null);
        }
Ejemplo n.º 5
0
        private static Operand ConstantFolding1Integer(InstructionNode node)
        {
            if (node.OperandCount != 1 || node.ResultCount != 1)
            {
                return(null);
            }

            if (!node.Operand1.IsResolvedConstant)
            {
                return(null);
            }

            var instruction = node.Instruction;
            var result      = node.Result;
            var op1         = node.Operand1;

            if (instruction == IRInstruction.GetLow64)
            {
                return(ConstantOperand.Create(result.Type, (uint)op1.ConstantUnsignedLongInteger & 0xFFFFFFFF));
            }
            else if (instruction == IRInstruction.GetHigh64)
            {
                return(ConstantOperand.Create(result.Type, (uint)(op1.ConstantUnsignedLongInteger >> 32)));
            }
            else if (instruction == IRInstruction.LogicalNot32)
            {
                return(ConstantOperand.Create(result.Type, ~((uint)op1.ConstantUnsignedLongInteger)));
            }
            else if (instruction == IRInstruction.LogicalNot64)
            {
                return(ConstantOperand.Create(result.Type, ~((ulong)op1.ConstantUnsignedLongInteger)));
            }
            else if (instruction == IRInstruction.Truncation64x32)
            {
                return(ConstantOperand.Create(result.Type, (uint)op1.ConstantUnsignedLongInteger));
            }
            else if (instruction == IRInstruction.SignExtend8x32)
            {
                return(ConstantOperand.Create(result.Type, SignExtend8x32((byte)op1.ConstantUnsignedLongInteger)));
            }
            else if (instruction == IRInstruction.SignExtend16x32)
            {
                return(ConstantOperand.Create(result.Type, SignExtend16x32((ushort)op1.ConstantUnsignedLongInteger)));
            }
            else if (instruction == IRInstruction.SignExtend8x64)
            {
                return(ConstantOperand.Create(result.Type, SignExtend8x64((byte)op1.ConstantUnsignedLongInteger)));
            }
            else if (instruction == IRInstruction.SignExtend16x64)
            {
                return(ConstantOperand.Create(result.Type, SignExtend16x64((ushort)op1.ConstantUnsignedLongInteger)));
            }
            else if (instruction == IRInstruction.SignExtend32x64)
            {
                return(ConstantOperand.Create(result.Type, SignExtend32x64((uint)op1.ConstantUnsignedLongInteger)));
            }
            else if (instruction == IRInstruction.ZeroExtend8x32)
            {
                return(ConstantOperand.Create(result.Type, (byte)op1.ConstantUnsignedLongInteger));
            }
            else if (instruction == IRInstruction.ZeroExtend16x32)
            {
                return(ConstantOperand.Create(result.Type, (ushort)op1.ConstantUnsignedLongInteger));
            }
            else if (instruction == IRInstruction.ZeroExtend8x64)
            {
                return(ConstantOperand.Create(result.Type, (byte)op1.ConstantUnsignedLongInteger));
            }
            else if (instruction == IRInstruction.ZeroExtend16x64)
            {
                return(ConstantOperand.Create(result.Type, (ushort)op1.ConstantUnsignedLongInteger));
            }
            else if (instruction == IRInstruction.ZeroExtend32x64)
            {
                return(ConstantOperand.Create(result.Type, (uint)op1.ConstantUnsignedLongInteger));
            }
            else if (instruction == IRInstruction.ConvertInt32ToFloatR4)
            {
                return(ConstantOperand.Create(result.Type, (float)op1.ConstantUnsignedLongInteger));
            }
            else if (instruction == IRInstruction.ConvertInt32ToFloatR8)
            {
                return(ConstantOperand.Create(result.Type, (double)op1.ConstantUnsignedLongInteger));
            }
            else if (instruction == IRInstruction.ConvertInt64ToFloatR4)
            {
                return(ConstantOperand.Create(result.Type, (float)op1.ConstantUnsignedLongInteger));
            }
            else if (instruction == IRInstruction.ConvertInt64ToFloatR8)
            {
                return(ConstantOperand.Create(result.Type, (double)op1.ConstantUnsignedLongInteger));
            }

            return(null);
        }
Ejemplo n.º 6
0
        private static Operand StrengthReductionInteger(InstructionNode node)
        {
            if (node.OperandCount != 2 || node.ResultCount != 1)
            {
                return(null);
            }

            var instruction = node.Instruction;
            var result      = node.Result;
            var op1         = node.Operand1;
            var op2         = node.Operand2;

            if ((instruction == IRInstruction.Add32 || instruction == IRInstruction.Add64 || instruction == IRInstruction.AddFloatR4 || instruction == IRInstruction.AddFloatR8) && op1.IsConstantZero)
            {
                return(op2);
            }
            else if ((instruction == IRInstruction.Add32 || instruction == IRInstruction.Add64 || instruction == IRInstruction.AddFloatR4 || instruction == IRInstruction.AddFloatR8) && op2.IsConstantZero)
            {
                return(op1);
            }
            else if ((instruction == IRInstruction.Sub32 || instruction == IRInstruction.Sub64 || instruction == IRInstruction.SubFloatR4 || instruction == IRInstruction.SubFloatR8) && op2.IsConstantZero)
            {
                return(op1);
            }
            else if ((instruction == IRInstruction.Sub32 || instruction == IRInstruction.Sub64 || instruction == IRInstruction.SubFloatR4 || instruction == IRInstruction.SubFloatR8) && (op1 == op2))
            {
                return(ConstantOperand.Create(result.Type, 0));
            }
            else if ((instruction == IRInstruction.ShiftLeft32 || instruction == IRInstruction.ShiftLeft64 || instruction == IRInstruction.ShiftRight32 || instruction == IRInstruction.ShiftRight64) && op1.IsConstantZero)
            {
                return(ConstantOperand.Create(result.Type, 0));
            }
            else if ((instruction == IRInstruction.ShiftLeft32 || instruction == IRInstruction.ShiftLeft64 || instruction == IRInstruction.ShiftRight32 || instruction == IRInstruction.ShiftRight64) && op2.IsConstantZero)
            {
                return(op1);
            }
            else if ((instruction == IRInstruction.ShiftLeft32 || instruction == IRInstruction.ShiftRight32) && op2.IsResolvedConstant && op2.ConstantUnsignedLongInteger >= 32)
            {
                return(ConstantOperand.Create(result.Type, 0));
            }
            else if ((instruction == IRInstruction.ShiftLeft64 || instruction == IRInstruction.ShiftRight64) && op2.IsResolvedConstant && op2.ConstantUnsignedLongInteger >= 64)
            {
                return(ConstantOperand.Create(result.Type, 0));
            }
            else if ((instruction == IRInstruction.MulSigned32 || instruction == IRInstruction.MulUnsigned32 || instruction == IRInstruction.MulSigned64 || instruction == IRInstruction.MulUnsigned64 || instruction == IRInstruction.MulFloatR4 || instruction == IRInstruction.MulFloatR8) && (op1.IsConstantZero || op2.IsConstantZero))
            {
                return(ConstantOperand.Create(result.Type, 0));
            }
            else if ((instruction == IRInstruction.MulSigned32 || instruction == IRInstruction.MulUnsigned32 || instruction == IRInstruction.MulSigned64 || instruction == IRInstruction.MulUnsigned64 || instruction == IRInstruction.MulFloatR4 || instruction == IRInstruction.MulFloatR8) && op1.IsConstantOne)
            {
                return(op2);
            }
            else if ((instruction == IRInstruction.MulSigned32 || instruction == IRInstruction.MulUnsigned32 || instruction == IRInstruction.MulSigned64 || instruction == IRInstruction.MulUnsigned64 || instruction == IRInstruction.MulFloatR4 || instruction == IRInstruction.MulFloatR8) && op2.IsConstantOne)
            {
                return(op1);
            }
            else if ((node.Instruction == IRInstruction.DivSigned32 || node.Instruction == IRInstruction.DivUnsigned32 || node.Instruction == IRInstruction.DivSigned64 || node.Instruction == IRInstruction.DivUnsigned64 || instruction == IRInstruction.DivFloatR4 || instruction == IRInstruction.DivFloatR8) && op2.IsConstantOne)
            {
                return(op1);
            }
            else if ((node.Instruction == IRInstruction.DivSigned32 || node.Instruction == IRInstruction.DivUnsigned32 || node.Instruction == IRInstruction.DivSigned64 || node.Instruction == IRInstruction.DivUnsigned64 || instruction == IRInstruction.DivFloatR4 || instruction == IRInstruction.DivFloatR8) && op1.IsConstantZero)
            {
                return(ConstantOperand.Create(result.Type, 0));
            }
            else if ((node.Instruction == IRInstruction.DivSigned32 || node.Instruction == IRInstruction.DivUnsigned32 || node.Instruction == IRInstruction.DivSigned64 || node.Instruction == IRInstruction.DivUnsigned64 || instruction == IRInstruction.DivFloatR4 || instruction == IRInstruction.DivFloatR8) && op1 == op2)
            {
                return(ConstantOperand.Create(result.Type, 1));
            }
            else if ((node.Instruction == IRInstruction.RemUnsigned32 || node.Instruction == IRInstruction.RemUnsigned64 || instruction == IRInstruction.RemFloatR4 || instruction == IRInstruction.RemFloatR8) && op2.IsConstantOne)
            {
                return(ConstantOperand.Create(result.Type, 0));
            }
            else if ((instruction == IRInstruction.LogicalAnd32 || instruction == IRInstruction.LogicalAnd64) && op1 == op2)
            {
                return(op1);
            }
            else if ((instruction == IRInstruction.LogicalAnd32 || instruction == IRInstruction.LogicalAnd64) && (op1.IsConstantZero || op2.IsConstantZero))
            {
                return(ConstantOperand.Create(result.Type, 0));
            }
            else if (instruction == IRInstruction.LogicalAnd32 && op1.IsConstant && op1.ConstantUnsignedInteger == 0xFFFFFFFF)
            {
                return(op2);
            }
            else if (instruction == IRInstruction.LogicalAnd64 && op1.IsConstant && op1.ConstantUnsignedLongInteger == 0xFFFFFFFFFFFFFFFF)
            {
                return(op2);
            }
            else if (instruction == IRInstruction.LogicalAnd32 && op2.IsConstant && op2.ConstantUnsignedInteger == 0xFFFFFFFF)
            {
                return(op1);
            }
            else if (instruction == IRInstruction.LogicalAnd64 && op2.IsConstant && op2.ConstantUnsignedLongInteger == 0xFFFFFFFFFFFFFFFF)
            {
                return(op1);
            }
            else if ((instruction == IRInstruction.LogicalOr32 || instruction == IRInstruction.LogicalOr64) && op1 == op2)
            {
                return(op1);
            }
            else if ((instruction == IRInstruction.LogicalOr32 || instruction == IRInstruction.LogicalOr64) && op1.IsConstantZero)
            {
                return(op2);
            }
            else if ((instruction == IRInstruction.LogicalOr32 || instruction == IRInstruction.LogicalOr64) && op2.IsConstantZero)
            {
                return(op1);
            }
            else if (instruction == IRInstruction.LogicalOr32 && op1.IsConstant && op1.ConstantUnsignedInteger == 0xFFFFFFFF)
            {
                return(ConstantOperand.Create(result.Type, 0xFFFFFFFF));
            }
            else if (instruction == IRInstruction.LogicalOr64 && op1.IsConstant && op1.ConstantUnsignedLongInteger == 0xFFFFFFFFFFFFFFFF)
            {
                return(ConstantOperand.Create(result.Type, 0xFFFFFFFFFFFFFFFF));
            }
            else if (instruction == IRInstruction.LogicalOr32 && op2.IsConstant && op2.ConstantUnsignedInteger == 0xFFFFFFFF)
            {
                return(ConstantOperand.Create(result.Type, 0xFFFFFFFF));
            }
            else if (instruction == IRInstruction.LogicalOr64 && op2.IsConstant && op2.ConstantUnsignedLongInteger == 0xFFFFFFFFFFFFFFFF)
            {
                return(ConstantOperand.Create(result.Type, 0xFFFFFFFFFFFFFFFF));
            }
            else if ((instruction == IRInstruction.LogicalXor32 || instruction == IRInstruction.LogicalXor64) && op1 == op2)
            {
                return(ConstantOperand.Create(result.Type, 0));
            }
            else if ((instruction == IRInstruction.LogicalXor32 || instruction == IRInstruction.LogicalXor64) && op1.IsConstantZero)
            {
                return(op2);
            }
            else if ((instruction == IRInstruction.LogicalXor32 || instruction == IRInstruction.LogicalXor64) && op2.IsConstantZero)
            {
                return(op1);
            }
            else if (instruction == IRInstruction.CompareInt32x32 || instruction == IRInstruction.CompareInt64x32 || instruction == IRInstruction.CompareInt64x64 || instruction == IRInstruction.CompareInt32x64)
            {
                var condition = node.ConditionCode;

                if (op1 == op2 && (condition == ConditionCode.Equal || condition == ConditionCode.GreaterOrEqual || condition == ConditionCode.UnsignedGreaterOrEqual || condition == ConditionCode.UnsignedLessOrEqual || condition == ConditionCode.LessOrEqual))
                {
                    return(ConstantOperand.Create(result.Type, true ? 1 : 0));
                }
                else if (op1 == op2 && (condition == ConditionCode.NotEqual || condition == ConditionCode.GreaterThan || condition == ConditionCode.LessThan || condition == ConditionCode.UnsignedGreaterThan || condition == ConditionCode.UnsignedLessThan))
                {
                    return(ConstantOperand.Create(result.Type, false ? 1 : 0));
                }
            }

            return(null);
        }
Ejemplo n.º 7
0
        private static Operand ConstantFolding2Integer(InstructionNode node)
        {
            if (node.OperandCount != 2 || node.ResultCount != 1)
            {
                return(null);
            }

            if (!node.Operand1.IsResolvedConstant || !node.Operand2.IsResolvedConstant)
            {
                return(null);
            }

            var instruction = node.Instruction;
            var result      = node.Result;
            var op1         = node.Operand1;
            var op2         = node.Operand2;

            if (instruction == IRInstruction.Add32)
            {
                return(ConstantOperand.Create(result.Type, (op1.ConstantUnsignedLongInteger + op2.ConstantUnsignedLongInteger) & 0xFFFFFFFF));
            }
            else if (instruction == IRInstruction.Add64)
            {
                return(ConstantOperand.Create(result.Type, op1.ConstantUnsignedLongInteger + op2.ConstantUnsignedLongInteger));
            }
            else if (instruction == IRInstruction.AddFloatR4)
            {
                return(ConstantOperand.Create(result.Type, (op1.ConstantDoubleFloatingPoint + op2.ConstantDoubleFloatingPoint)));
            }
            else if (instruction == IRInstruction.AddFloatR8)
            {
                return(ConstantOperand.Create(result.Type, op1.ConstantDoubleFloatingPoint + op2.ConstantDoubleFloatingPoint));
            }
            else if (instruction == IRInstruction.Sub32)
            {
                return(ConstantOperand.Create(result.Type, (op1.ConstantUnsignedLongInteger - op2.ConstantUnsignedLongInteger) & 0xFFFFFFFF));
            }
            else if (instruction == IRInstruction.Sub64)
            {
                return(ConstantOperand.Create(result.Type, op1.ConstantUnsignedLongInteger - op2.ConstantUnsignedLongInteger));
            }
            else if (instruction == IRInstruction.SubFloatR4)
            {
                return(ConstantOperand.Create(result.Type, op1.ConstantSingleFloatingPoint + op2.ConstantSingleFloatingPoint));
            }
            else if (instruction == IRInstruction.SubFloatR8)
            {
                return(ConstantOperand.Create(result.Type, op1.ConstantSingleFloatingPoint + op2.ConstantSingleFloatingPoint));
            }
            else if (instruction == IRInstruction.LogicalAnd32)
            {
                return(ConstantOperand.Create(result.Type, op1.ConstantUnsignedLongInteger & op2.ConstantUnsignedLongInteger & 0xFFFFFFFF));
            }
            else if (instruction == IRInstruction.LogicalAnd64)
            {
                return(ConstantOperand.Create(result.Type, op1.ConstantUnsignedLongInteger & op2.ConstantUnsignedLongInteger));
            }
            else if (instruction == IRInstruction.LogicalOr32)
            {
                return(ConstantOperand.Create(result.Type, (op1.ConstantUnsignedLongInteger | op2.ConstantUnsignedLongInteger) & 0xFFFFFFFF));
            }
            else if (instruction == IRInstruction.LogicalOr64)
            {
                return(ConstantOperand.Create(result.Type, op1.ConstantUnsignedLongInteger | op2.ConstantUnsignedLongInteger));
            }
            else if (instruction == IRInstruction.LogicalXor32)
            {
                return(ConstantOperand.Create(result.Type, (op1.ConstantUnsignedLongInteger ^ op2.ConstantUnsignedLongInteger) & 0xFFFFFFFF));
            }
            else if (instruction == IRInstruction.LogicalXor64)
            {
                return(ConstantOperand.Create(result.Type, op1.ConstantUnsignedLongInteger ^ op2.ConstantUnsignedLongInteger));
            }
            else if (instruction == IRInstruction.MulSigned32 || instruction == IRInstruction.MulUnsigned32)
            {
                return(ConstantOperand.Create(result.Type, (op1.ConstantUnsignedLongInteger * op2.ConstantUnsignedLongInteger) & 0xFFFFFFFF));
            }
            else if (instruction == IRInstruction.MulSigned64 || instruction == IRInstruction.MulUnsigned64)
            {
                return(ConstantOperand.Create(result.Type, op1.ConstantUnsignedLongInteger * op2.ConstantUnsignedLongInteger));
            }
            else if (instruction == IRInstruction.MulFloatR4)
            {
                return(ConstantOperand.Create(result.Type, (op1.ConstantSingleFloatingPoint * op2.ConstantSingleFloatingPoint)));
            }
            else if (instruction == IRInstruction.MulFloatR8)
            {
                return(ConstantOperand.Create(result.Type, op1.ConstantDoubleFloatingPoint * op2.ConstantDoubleFloatingPoint));
            }
            else if (instruction == IRInstruction.DivUnsigned32 && !op2.IsConstantZero)
            {
                return(ConstantOperand.Create(result.Type, (op1.ConstantUnsignedLongInteger / op2.ConstantUnsignedLongInteger) & 0xFFFFFFFF));
            }
            else if (instruction == IRInstruction.DivUnsigned64 && !op2.IsConstantZero)
            {
                return(ConstantOperand.Create(result.Type, op1.ConstantUnsignedLongInteger / op2.ConstantUnsignedLongInteger));
            }
            else if (instruction == IRInstruction.DivSigned32 && !op2.IsConstantZero)
            {
                return(ConstantOperand.Create(result.Type, ((ulong)(op1.ConstantSignedLongInteger / op2.ConstantSignedLongInteger)) & 0xFFFFFFFF));
            }
            else if (instruction == IRInstruction.DivSigned64 && !op2.IsConstantZero)
            {
                return(ConstantOperand.Create(result.Type, (ulong)(op1.ConstantSignedLongInteger / op2.ConstantSignedLongInteger)));
            }
            else if (instruction == IRInstruction.DivFloatR4 && !op2.IsConstantZero)
            {
                return(ConstantOperand.Create(result.Type, op1.ConstantSingleFloatingPoint / op2.ConstantSingleFloatingPoint));
            }
            else if (instruction == IRInstruction.DivFloatR8 && !op2.IsConstantZero)
            {
                return(ConstantOperand.Create(result.Type, op1.ConstantDoubleFloatingPoint / op2.ConstantDoubleFloatingPoint));
            }
            else if (instruction == IRInstruction.ArithShiftRight32)
            {
                return(ConstantOperand.Create(result.Type, ((ulong)(((long)op1.ConstantUnsignedLongInteger) >> (int)op2.ConstantUnsignedLongInteger)) & 0xFFFFFFFF));
            }
            else if (instruction == IRInstruction.ArithShiftRight64)
            {
                return(ConstantOperand.Create(result.Type, (ulong)(((long)op1.ConstantUnsignedLongInteger) >> (int)op2.ConstantUnsignedLongInteger)));
            }
            else if (instruction == IRInstruction.ShiftRight32)
            {
                return(ConstantOperand.Create(result.Type, (op1.ConstantUnsignedLongInteger >> (int)op2.ConstantUnsignedLongInteger) & 0xFFFFFFFF));
            }
            else if (instruction == IRInstruction.ShiftRight64)
            {
                return(ConstantOperand.Create(result.Type, op1.ConstantUnsignedLongInteger >> (int)op2.ConstantUnsignedLongInteger));
            }
            else if (instruction == IRInstruction.ShiftLeft32)
            {
                return(ConstantOperand.Create(result.Type, (op1.ConstantUnsignedLongInteger << (int)op2.ConstantUnsignedLongInteger) & 0xFFFFFFFF));
            }
            else if (instruction == IRInstruction.ShiftLeft64)
            {
                return(ConstantOperand.Create(result.Type, op1.ConstantUnsignedLongInteger << (int)op2.ConstantUnsignedLongInteger));
            }
            else if (instruction == IRInstruction.RemSigned32 && !op2.IsConstantZero)
            {
                return(ConstantOperand.Create(result.Type, ((ulong)(op1.ConstantSignedLongInteger % op2.ConstantSignedLongInteger)) & 0xFFFFFFFF));
            }
            else if (instruction == IRInstruction.RemSigned64 && !op2.IsConstantZero)
            {
                return(ConstantOperand.Create(result.Type, (ulong)(op1.ConstantSignedLongInteger % op2.ConstantSignedLongInteger)));
            }
            else if (instruction == IRInstruction.RemUnsigned32 && !op2.IsConstantZero)
            {
                return(ConstantOperand.Create(result.Type, (op1.ConstantUnsignedLongInteger % op2.ConstantUnsignedLongInteger) & 0xFFFFFFFF));
            }
            else if (instruction == IRInstruction.RemUnsigned64 && !op2.IsConstantZero)
            {
                return(ConstantOperand.Create(result.Type, op1.ConstantUnsignedLongInteger % op2.ConstantUnsignedLongInteger));
            }
            else if (instruction == IRInstruction.RemFloatR4 && !op2.IsConstantZero)
            {
                return(ConstantOperand.Create(result.Type, op1.ConstantSingleFloatingPoint % op2.ConstantSingleFloatingPoint));
            }
            else if (instruction == IRInstruction.RemFloatR8 && !op2.IsConstantZero)
            {
                return(ConstantOperand.Create(result.Type, op1.ConstantDoubleFloatingPoint % op2.ConstantDoubleFloatingPoint));
            }
            else if (instruction == IRInstruction.To64)
            {
                return(ConstantOperand.Create(result.Type, op2.ConstantUnsignedLongInteger << 32 | op1.ConstantUnsignedLongInteger));
            }
            else if (instruction == IRInstruction.CompareInt32x32 || instruction == IRInstruction.CompareInt64x32 || instruction == IRInstruction.CompareInt64x64 || instruction == IRInstruction.CompareInt32x64)
            {
                bool compareResult = true;

                switch (node.ConditionCode)
                {
                case ConditionCode.Equal: compareResult = (op1.ConstantUnsignedLongInteger == op2.ConstantUnsignedLongInteger); break;

                case ConditionCode.NotEqual: compareResult = (op1.ConstantUnsignedLongInteger != op2.ConstantUnsignedLongInteger); break;

                case ConditionCode.GreaterOrEqual: compareResult = (op1.ConstantUnsignedLongInteger >= op2.ConstantUnsignedLongInteger); break;

                case ConditionCode.GreaterThan: compareResult = (op1.ConstantUnsignedLongInteger > op2.ConstantUnsignedLongInteger); break;

                case ConditionCode.LessOrEqual: compareResult = (op1.ConstantUnsignedLongInteger <= op2.ConstantUnsignedLongInteger); break;

                case ConditionCode.LessThan: compareResult = (op1.ConstantUnsignedLongInteger < op2.ConstantUnsignedLongInteger); break;

                case ConditionCode.UnsignedGreaterThan: compareResult = (op1.ConstantUnsignedLongInteger > op2.ConstantUnsignedLongInteger); break;

                case ConditionCode.UnsignedGreaterOrEqual: compareResult = (op1.ConstantUnsignedLongInteger >= op2.ConstantUnsignedLongInteger); break;

                case ConditionCode.UnsignedLessThan: compareResult = (op1.ConstantUnsignedLongInteger < op2.ConstantUnsignedLongInteger); break;

                case ConditionCode.UnsignedLessOrEqual: compareResult = (op1.ConstantUnsignedLongInteger <= op2.ConstantUnsignedLongInteger); break;

                // TODO: Add more
                default: return(null);
                }

                return(ConstantOperand.Create(result.Type, compareResult ? 1 : 0));
            }

            return(null);
        }