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