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