/// <summary cref="IValueVisitor.Visit(UnaryArithmeticValue)"/> public void Visit(UnaryArithmeticValue value) { var argument = Load(value.Value); var target = Allocate(value, value.ArithmeticBasicValueType); using (var statement = BeginStatement(target)) { statement.AppendCast(value.ArithmeticBasicValueType); var operation = CLInstructions.GetArithmeticOperation( value.Kind, value.BasicValueType.IsFloat(), out bool isFunction); if (isFunction) { statement.AppendCommand(operation); } statement.BeginArguments(); if (!isFunction) { statement.AppendCommand(operation); } statement.AppendCast(value.ArithmeticBasicValueType); statement.AppendArgument(argument); statement.EndArguments(); } }
/// <summary cref="IBackendCodeGenerator.GenerateCode(UnaryArithmeticValue)"/> public void GenerateCode(UnaryArithmeticValue value) { var argument = Load(value.Value); var target = Allocate( value, value.BasicValueType == BasicValueType.Int1 ? ArithmeticBasicValueType.UInt1 : value.ArithmeticBasicValueType); using var statement = BeginStatement(target); if (value.BasicValueType != BasicValueType.Int1) { statement.AppendCast(value.ArithmeticBasicValueType); } var operation = CLInstructions.GetArithmeticOperation( value.Kind, value.ArithmeticBasicValueType, out bool isFunction); if (isFunction) { statement.AppendCommand(operation); } statement.BeginArguments(); if (!isFunction) { statement.AppendCommand(operation); } statement.AppendCast(value.ArithmeticBasicValueType); statement.AppendArgument(argument); statement.EndArguments(); }
/// <summary cref="IBackendCodeGenerator.GenerateCode(DynamicMemoryLengthValue)"/> public void GenerateCode(DynamicMemoryLengthValue value) { if (value.AddressSpace != MemoryAddressSpace.Shared) { throw new InvalidCodeGenerationException(); } // Resolve the name of the global variable containing the length of the // shared dynamic memory buffer. var dynamicView = value.GetFirstUseNode().ResolveAs <Alloca>(); var lengthVariableName = GetSharedMemoryAllocationLengthName(dynamicView); // Load the dynamic memory size (in bytes) from the dynamic length variable // and divide by the size in bytes of the array element. var target = Allocate(value); using var statement = BeginStatement(target); statement.AppendCast(value.Type); var operation = CLInstructions.GetArithmeticOperation( BinaryArithmeticKind.Div, value.BasicValueType.IsFloat(), out bool isFunction); if (isFunction) { statement.AppendCommand(operation); statement.BeginArguments(); } else { statement.OpenParen(); } statement.AppendCast(dynamicView.ArrayLength.Type); statement.AppendCommand(lengthVariableName); if (!isFunction) { statement.AppendCommand(operation); } statement.AppendArgument(); statement.AppendCast(value.ElementType.BasicValueType); statement.AppendConstant(value.ElementType.Size); if (isFunction) { statement.EndArguments(); } else { statement.CloseParen(); } }
/// <summary cref="IValueVisitor.Visit(BinaryArithmeticValue)"/> public void Visit(BinaryArithmeticValue value) { var left = Load(value.Left); var right = Load(value.Right); var target = Allocate(value, value.ArithmeticBasicValueType); using (var statement = BeginStatement(target)) { statement.AppendCast(value.ArithmeticBasicValueType); var operation = CLInstructions.GetArithmeticOperation( value.Kind, value.BasicValueType.IsFloat(), out bool isFunction); if (isFunction) { statement.AppendCommand(operation); statement.BeginArguments(); } else { statement.OpenParen(); } statement.AppendCast(value.ArithmeticBasicValueType); statement.AppendArgument(left); if (!isFunction) { statement.AppendCommand(operation); } statement.AppendArgument(); statement.AppendCast(value.ArithmeticBasicValueType); statement.Append(right); if (isFunction) { statement.EndArguments(); } else { statement.CloseParen(); } } }
/// <summary cref="IValueVisitor.Visit(ViewCast)"/> public void Visit(ViewCast value) { var target = AllocateView(value); var source = LoadView(value.Value); // Declare view Declare(target); using (var statement = BeginStatement(target, target.PointerFieldIndex)) { statement.AppendPointerCast(TypeGenerator[target.ElementType]); statement.Append(source); statement.AppendField(source.PointerFieldIndex); } var sourceElementSize = ABI.GetSizeOf(value.SourceElementType); var targetElementSize = ABI.GetSizeOf(value.TargetElementType); // var newLength = length * sourceElementSize / targetElementSize; using (var statement = BeginStatement(target, target.LengthFieldIndex)) { statement.OpenParen(); statement.Append(source); statement.AppendField(source.LengthFieldIndex); statement.AppendOperation( CLInstructions.GetArithmeticOperation( BinaryArithmeticKind.Mul, false, out bool _)); statement.AppendConstant(sourceElementSize); statement.CloseParen(); statement.AppendOperation( CLInstructions.GetArithmeticOperation( BinaryArithmeticKind.Div, false, out bool _)); statement.AppendConstant(targetElementSize); } }
/// <summary cref="IValueVisitor.Visit(ViewCast)"/> public void Visit(ViewCast value) { var source = LoadAs <ViewVariable>(value.Value); var pointer = source.Pointer; var length = source.Length; var sourceElementSize = ABI.GetSizeOf(value.SourceElementType); var targetElementSize = ABI.GetSizeOf(value.TargetElementType); // var newLength = length * sourceElementSize / targetElementSize; var newLength = AllocateType(BasicValueType.Int32) as PrimitiveVariable; using (var statement = BeginStatement(newLength)) { statement.OpenParen(); statement.Append(length); statement.AppendOperation( CLInstructions.GetArithmeticOperation( BinaryArithmeticKind.Mul, false, out bool _)); statement.AppendConstant(sourceElementSize); statement.CloseParen(); statement.AppendOperation( CLInstructions.GetArithmeticOperation( BinaryArithmeticKind.Div, false, out bool _)); statement.AppendConstant(targetElementSize); } var newView = new ViewVariable( value.Type as ViewType, pointer, newLength); Bind(value, newView); }
/// <summary cref="IBackendCodeGenerator.GenerateCode(AlignTo)"/> public void GenerateCode(AlignTo value) { // Load the base view pointer var source = Load(value.Source); var target = Allocate(value); var alignmentVariable = Load(value.AlignmentInBytes); var arithmeticBasicValueType = value.Source.BasicValueType.GetArithmeticBasicValueType(true); // var baseOffset = (int)ptr & (alignmentInBytes - 1); var baseOffset = AllocateType(arithmeticBasicValueType); using (var statement = BeginStatement(baseOffset)) { statement.AppendCast(arithmeticBasicValueType); statement.AppendArgument(source); statement.AppendCommand(CLInstructions.GetArithmeticOperation( BinaryArithmeticKind.And, isFloat: false, out bool _)); // Optimize for the case in which the alignment is a constant value if (value.TryGetAlignmentConstant(out int alignment)) { statement.AppendConstant(alignment - 1); } else { statement.AppendCommand('('); statement.AppendArgument(alignmentVariable); statement.AppendCommand(CLInstructions.GetArithmeticOperation( BinaryArithmeticKind.Sub, isFloat: false, out bool _)); statement.AppendConstant(1); statement.AppendCommand(')'); } } // if (baseOffset == 0) { 0 } else { alignment - baseOffset } var adjustment = AllocateType(arithmeticBasicValueType); using (var selectStatement = BeginStatement(adjustment)) { selectStatement.AppendArgument(baseOffset); selectStatement.AppendCommand(" == 0 ? 0 : ("); if (value.TryGetAlignmentConstant(out int alignmentConstant)) { selectStatement.AppendConstant(alignmentConstant); } else { selectStatement.AppendArgument(alignmentVariable); } selectStatement.AppendCommand(CLInstructions.GetArithmeticOperation( BinaryArithmeticKind.Sub, isFloat: false, out bool _)); selectStatement.AppendArgument(baseOffset); selectStatement.AppendCommand(')'); } // Adjust the given pointer using var command = BeginStatement(target); command.AppendCast(value.Type); command.AppendCommand('('); command.AppendCast(arithmeticBasicValueType); command.AppendArgument(source); command.AppendCommand(CLInstructions.GetArithmeticOperation( BinaryArithmeticKind.Add, isFloat: false, out bool _)); command.AppendArgument(adjustment); command.AppendCommand(')'); }