Esempio n. 1
0
        /// <summary cref="IValueVisitor.Visit(CompareValue)"/>
        public void Visit(CompareValue value)
        {
            var left  = LoadPrimitive(value.Left);
            var right = LoadPrimitive(value.Right);

            var targetRegister = AllocatePrimitive(value);

            if (left.Kind == PTXRegisterKind.Predicate)
            {
                // Predicate registers require a special treatment
                using (var command = BeginCommand(
                           PTXInstructions.GetArithmeticOperation(
                               BinaryArithmeticKind.Xor,
                               ArithmeticBasicValueType.UInt1,
                               false)))
                {
                    command.AppendArgument(targetRegister);
                    command.AppendArgument(left);
                    command.AppendArgument(right);
                }

                if (value.Kind == CompareKind.Equal)
                {
                    using (var command = BeginCommand(
                               PTXInstructions.GetArithmeticOperation(
                                   UnaryArithmeticKind.Not,
                                   ArithmeticBasicValueType.UInt1,
                                   false)))
                    {
                        command.AppendArgument(targetRegister);
                        command.AppendArgument(targetRegister);
                    }
                }
            }
            else
            {
                using (var command = BeginCommand(
                           PTXInstructions.GetCompareOperation(
                               value.Kind,
                               value.CompareType)))
                {
                    command.AppendArgument(targetRegister);
                    command.AppendArgument(left);
                    command.AppendArgument(right);
                }
            }
        }
        /// <summary cref="IValueVisitor.Visit(SwitchBranch)"/>
        public void Visit(SwitchBranch branch)
        {
            var idx = LoadPrimitive(branch.Condition);

            using (var lowerBoundsScope = new PredicateScope(this))
            {
                // Emit less than
                var lessThanCommand = PTXInstructions.GetCompareOperation(
                    CompareKind.LessThan,
                    ArithmeticBasicValueType.Int32);
                using (var command = BeginCommand(
                           lessThanCommand))
                {
                    command.AppendArgument(lowerBoundsScope.PredicateRegister);
                    command.AppendArgument(idx);
                    command.AppendConstant(0);
                }

                using (var upperBoundsScope = new PredicateScope(this))
                {
                    using (var command = BeginCommand(
                               PTXInstructions.BranchIndexRangeComparison))
                    {
                        command.AppendArgument(upperBoundsScope.PredicateRegister);
                        command.AppendArgument(idx);
                        command.AppendConstant(branch.NumCasesWithoutDefault);
                        command.AppendArgument(lowerBoundsScope.PredicateRegister);
                    }
                    using (var command = BeginCommand(
                               PTXInstructions.BranchOperation,
                               new PredicateConfiguration(upperBoundsScope.PredicateRegister, true)))
                    {
                        var defaultTarget = blockLookup[branch.DefaultBlock];
                        command.AppendLabel(defaultTarget);
                    }
                }
            }

            var targetLabel = DeclareLabel();

            MarkLabel(targetLabel);
            Builder.Append('\t');
            Builder.Append(PTXInstructions.BranchTargetsDeclaration);
            Builder.Append(' ');
            for (int i = 0, e = branch.NumCasesWithoutDefault; i < e; ++i)
            {
                var caseTarget = branch.GetCaseTarget(i);
                var caseLabel  = blockLookup[caseTarget];
                Builder.Append(caseLabel);
                if (i + 1 < e)
                {
                    Builder.Append(", ");
                }
            }
            Builder.AppendLine(";");

            using (var command = BeginCommand(
                       PTXInstructions.BranchIndexOperation))
            {
                command.AppendArgument(idx);
                command.AppendLabel(targetLabel);
            }
        }