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(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.º 3
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);
            }
        }