Exemplo n.º 1
0
        /// <summary>
        /// Creates a set of instructions to realize a generic lea operation.
        /// </summary>
        /// <param name="sourceType">The source address type (pointer or view).</param>
        /// <param name="elementIndex">The current element index (the offset).</param>
        /// <param name="targetAddressRegister">The allocated target pointer register to write to.</param>
        /// <param name="address">The source address.</param>
        private void MakeLoadElementAddress(
            AddressSpaceType sourceType,
            PrimitiveRegister elementIndex,
            PrimitiveRegister targetAddressRegister,
            PrimitiveRegister address)
        {
            var elementSize    = ABI.GetSizeOf(sourceType.ElementType);
            var offsetRegister = AllocatePlatformRegister(out RegisterDescription _);

            using (var command = BeginCommand(
                       PTXInstructions.GetLEAMulOperation(ABI.PointerArithmeticType)))
            {
                command.AppendArgument(offsetRegister);
                command.AppendArgument(elementIndex);
                command.AppendConstant(elementSize);
            }

            using (var command = BeginCommand(
                       PTXInstructions.GetArithmeticOperation(
                           BinaryArithmeticKind.Add,
                           ABI.PointerArithmeticType,
                           false)))
            {
                command.AppendArgument(targetAddressRegister);
                command.AppendArgument(address);
                command.AppendArgument(offsetRegister);
            }

            FreeRegister(offsetRegister);
        }
Exemplo n.º 2
0
        /// <summary cref="IBackendCodeGenerator.GenerateCode(LoadFieldAddress)"/>
        public void GenerateCode(LoadFieldAddress value)
        {
            var source      = LoadPrimitive(value.Source);
            var fieldOffset = value.StructureType.GetOffset(
                value.FieldSpan.Access);

            if (fieldOffset != 0)
            {
                var targetRegister = AllocatePlatformRegister(
                    value,
                    out RegisterDescription _);
                using var command = BeginCommand(
                          PTXInstructions.GetArithmeticOperation(
                              BinaryArithmeticKind.Add,
                              Backend.PointerArithmeticType,
                              false));
                command.AppendArgument(targetRegister);
                command.AppendArgument(source);
                command.AppendConstant(fieldOffset);
            }
            else
            {
                Alias(value, value.Source);
            }
        }
Exemplo n.º 3
0
        /// <summary cref="IBackendCodeGenerator.GenerateCode(LoadElementAddress)"/>
        public void GenerateCode(LoadElementAddress value)
        {
            var elementIndex          = LoadPrimitive(value.ElementIndex);
            var targetAddressRegister = AllocatePlatformRegister(
                value,
                out RegisterDescription _);

            Debug.Assert(value.IsPointerAccess, "Invalid pointer access");

            var address        = LoadPrimitive(value.Source);
            var sourceType     = value.Source.Type as AddressSpaceType;
            var elementSize    = sourceType.ElementType.Size;
            var offsetRegister = AllocatePlatformRegister(out RegisterDescription _);

            using (var command = BeginCommand(
                       PTXInstructions.GetLEAMulOperation(Backend.PointerArithmeticType)))
            {
                command.AppendArgument(offsetRegister);
                command.AppendArgument(elementIndex);
                command.AppendConstant(elementSize);
            }

            using (var command = BeginCommand(
                       PTXInstructions.GetArithmeticOperation(
                           BinaryArithmeticKind.Add,
                           Backend.PointerArithmeticType,
                           false)))
            {
                command.AppendArgument(targetAddressRegister);
                command.AppendArgument(address);
                command.AppendArgument(offsetRegister);
            }

            FreeRegister(offsetRegister);
        }
Exemplo n.º 4
0
        /// <summary cref="IBackendCodeGenerator.GenerateCode(LoadElementAddress)"/>
        public void GenerateCode(LoadElementAddress value)
        {
            var elementIndex          = LoadPrimitive(value.Offset);
            var targetAddressRegister = AllocatePlatformRegister(
                value,
                out RegisterDescription _);

            Debug.Assert(value.IsPointerAccess, "Invalid pointer access");

            var address     = LoadPrimitive(value.Source);
            var sourceType  = value.Source.Type as AddressSpaceType;
            var elementSize = sourceType.ElementType.Size;

            if (value.Is32BitAccess)
            {
                // Perform two efficient operations TODO
                var offsetRegister = AllocatePlatformRegister(out RegisterDescription _);
                using (var command = BeginCommand(
                           PTXInstructions.GetLEAMulOperation(Backend.PointerArithmeticType)))
                {
                    command.AppendArgument(offsetRegister);
                    command.AppendArgument(elementIndex);
                    command.AppendConstant(elementSize);
                }

                using (var command = BeginCommand(
                           PTXInstructions.GetArithmeticOperation(
                               BinaryArithmeticKind.Add,
                               Backend.PointerArithmeticType,
                               Backend.Capabilities,
                               false)))
                {
                    command.AppendArgument(targetAddressRegister);
                    command.AppendArgument(address);
                    command.AppendArgument(offsetRegister);
                }

                FreeRegister(offsetRegister);
            }
            else
            {
                // Use an efficient MAD instruction to compute the effective address
                using var command = BeginCommand(
                          PTXInstructions.GetArithmeticOperation(
                              TernaryArithmeticKind.MultiplyAdd,
                              Backend.PointerArithmeticType));
                command.AppendArgument(targetAddressRegister);
                command.AppendArgument(elementIndex);
                command.AppendConstant(elementSize);
                command.AppendArgument(address);
            }
        }
Exemplo n.º 5
0
        /// <summary cref="IBackendCodeGenerator.GenerateCode(UnaryArithmeticValue)"/>
        public void GenerateCode(UnaryArithmeticValue value)
        {
            var argument       = LoadPrimitive(value.Value);
            var targetRegister = AllocateHardware(value);

            using var command = BeginCommand(
                      PTXInstructions.GetArithmeticOperation(
                          value.Kind,
                          value.ArithmeticBasicValueType,
                          FastMath));
            command.AppendArgument(targetRegister);
            command.AppendArgument(argument);
        }
Exemplo n.º 6
0
        /// <summary cref="IBackendCodeGenerator.GenerateCode(BinaryArithmeticValue)"/>
        public void GenerateCode(BinaryArithmeticValue value)
        {
            var left  = LoadPrimitive(value.Left);
            var right = LoadPrimitive(value.Right);

            var targetRegister = Allocate(value, left.Description);

            using var command = BeginCommand(
                      PTXInstructions.GetArithmeticOperation(
                          value.Kind,
                          value.ArithmeticBasicValueType,
                          FastMath));
            command.AppendArgument(targetRegister);
            command.AppendArgument(left);
            command.AppendArgument(right);
        }
Exemplo n.º 7
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);
                }
            }
        }
Exemplo n.º 8
0
        /// <summary cref="IBackendCodeGenerator.GenerateCode(TernaryArithmeticValue)"/>
        public void GenerateCode(TernaryArithmeticValue value)
        {
            var first  = LoadPrimitive(value.First);
            var second = LoadPrimitive(value.Second);
            var third  = LoadPrimitive(value.Third);


            var targetRegister = Allocate(value, first.Description);

            using var command = BeginCommand(
                      PTXInstructions.GetArithmeticOperation(
                          value.Kind,
                          value.ArithmeticBasicValueType));
            command.AppendArgument(targetRegister);
            command.AppendArgument(first);
            command.AppendArgument(second);
            command.AppendArgument(third);
        }
Exemplo n.º 9
0
        /// <summary cref="IValueVisitor.Visit(ViewCast)"/>
        public void Visit(ViewCast value)
        {
            var source  = LoadAs <ViewImplementationRegister>(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 lengthTimesSourceElementSize = AllocateRegister(length.Description);
            var newLength = AllocateRegister(length.Description);

            using (var command = BeginCommand(
                       PTXInstructions.GetArithmeticOperation(
                           BinaryArithmeticKind.Mul,
                           ArithmeticBasicValueType.Int32,
                           FastMath)))
            {
                command.AppendArgument(lengthTimesSourceElementSize);
                command.AppendArgument(length);
                command.AppendConstant(sourceElementSize);
            }

            using (var command = BeginCommand(
                       PTXInstructions.GetArithmeticOperation(
                           BinaryArithmeticKind.Div,
                           ArithmeticBasicValueType.Int32,
                           FastMath)))
            {
                command.AppendArgument(newLength);
                command.AppendArgument(lengthTimesSourceElementSize);
                command.AppendConstant(targetElementSize);
            }

            var newView = new ViewImplementationRegister(
                value.Type as ViewType,
                pointer,
                newLength);

            Bind(value, newView);

            FreeRegister(lengthTimesSourceElementSize);
        }
Exemplo n.º 10
0
        /// <summary cref="IBackendCodeGenerator.GenerateCode(DynamicMemoryLengthValue)"/>
        public void GenerateCode(DynamicMemoryLengthValue value)
        {
            if (value.AddressSpace != MemoryAddressSpace.Shared)
            {
                throw new InvalidCodeGenerationException();
            }

            // Load the dynamic memory size (in bytes) from the PTX special register
            // and divide by the size in bytes of the array element.
            var lengthRegister            = AllocateHardware(value);
            var dynamicMemorySizeRegister = MoveFromIntrinsicRegister(
                PTXRegisterKind.DynamicSharedMemorySize);

            using var command = BeginCommand(
                      PTXInstructions.GetArithmeticOperation(
                          BinaryArithmeticKind.Div,
                          ArithmeticBasicValueType.UInt32,
                          Backend.Capabilities,
                          false));
            command.AppendArgument(lengthRegister);
            command.AppendArgument(dynamicMemorySizeRegister);
            command.AppendConstant(value.ElementType.Size);
        }
Exemplo n.º 11
0
        /// <summary cref="IValueVisitor.Visit(LoadFieldAddress)"/>
        public void Visit(LoadFieldAddress value)
        {
            var source      = LoadPrimitive(value.Source);
            var fieldOffset = ABI.GetOffsetOf(value.StructureType, value.FieldIndex);

            if (fieldOffset != 0)
            {
                var targetRegister = AllocatePlatformRegister(value, out RegisterDescription _);
                using (var command = BeginCommand(
                           PTXInstructions.GetArithmeticOperation(
                               BinaryArithmeticKind.Add,
                               ABI.PointerArithmeticType,
                               false)))
                {
                    command.AppendArgument(targetRegister);
                    command.AppendArgument(source);
                    command.AppendConstant(fieldOffset);
                }
            }
            else
            {
                Alias(value, value.Source);
            }
        }