Skip to content

Extend System.Runtime.Intrinsics.Arm to support nint and nuint #52027

@tannergooding

Description

@tannergooding

Proposal

Extend ISAs in System.Runtime.Intrinsics.Arm to support nint and nuint as valid primitive types. This will expose a number of new APIs to take the new types. Several of these APIs exist in Base vs Base.AdvSimd splits. Others represent cases where either int or long are possible inputs today.

namespace System.Runtime.Intrinsics.Arm
{
    public abstract partial class ArmBase
    {
        public abstract partial class Arm64
        {
            public static int LeadingSignCount(nint value);
        }

        public static int LeadingZeroCount(nint value);
        public static int LeadingZeroCount(nuint value);

        public static nint ReverseElementBits(nint value);
        public static nuint ReverseElementBits(nuint value)
    }

    public abstract partial class AdvSimd
    {
        public abstract partial class Arm64
        {
            public static Vector128<nint> AddPairwise(Vector128<nint> left, Vector128<nint> right);
            public static Vector128<nuint> AddPairwise(Vector128<nuint> left, Vector128<nuint> right);

            public static Vector64<nint> AddSaturate(Vector64<nint> left, Vector64<nuint> right);
            public static Vector64<nuint> AddSaturate(Vector64<nuint> left, Vector64<nint> right);
            public static Vector128<nint> AddSaturate(Vector128<nint> left, Vector128<nuint> right);
            public static Vector128<nuint> AddSaturate(Vector128<nuint> left, Vector128<nint> right);

            public static Vector64<nint> InsertSelectedScalar(Vector64<nint> result, byte resultIndex, Vector64<nint> value, byte valueIndex);
            public static Vector64<nuint> InsertSelectedScalar(Vector64<nuint> result, byte resultIndex, Vector64<nuint> value, byte valueIndex);
            public static Vector128<nint> InsertSelectedScalar(Vector128<nint> result, byte resultIndex, Vector128<nint> value, byte valueIndex);
            public static Vector128<nuint> InsertSelectedScalar(Vector128<nuint> result, byte resultIndex, Vector128<nuint> value, byte valueIndex);

            public static unsafe void StorePair(nint* address, Vector64<nint> value1, Vector64<nint> value2);
            public static unsafe void StorePair(nuint* address, Vector64<nuint> value1, Vector64<nuint> value2);
            public static unsafe void StorePair(nint* address, Vector128<nint> value1, Vector128<nint> value2);
            public static unsafe void StorePair(nuint* address, Vector128<nuint> value1, Vector128<nuint> value2);

            public static unsafe void StorePairNonTemporal(nint* address, Vector64<nint> value1, Vector64<nint> value2);
            public static unsafe void StorePairNonTemporal(nuint* address, Vector64<nuint> value1, Vector64<nuint> value2);
            public static unsafe void StorePairNonTemporal(nint* address, Vector128<nint> value1, Vector128<nint> value2);
            public static unsafe void StorePairNonTemporal(nuint* address, Vector128<nuint> value1, Vector128<nuint> value2);

            public static Vector64<nint> TransposeEven(Vector64<nint> left, Vector64<nint> right);
            public static Vector64<nuint> TransposeEven(Vector64<nuint> left, Vector64<nuint> right);
            public static Vector128<nint> TransposeEven(Vector128<nint> left, Vector128<nint> right);
            public static Vector128<nuint> TransposeEven(Vector128<nuint> left, Vector128<nuint> right);

            public static Vector64<nint> TransposeOdd(Vector64<nint> left, Vector64<nint> right);
            public static Vector64<nuint> TransposeOdd(Vector64<nuint> left, Vector64<nuint> right);
            public static Vector128<nint> TransposeOdd(Vector128<nint> left, Vector128<nint> right);
            public static Vector128<nuint> TransposeOdd(Vector128<nuint> left, Vector128<nuint> right);

            public static Vector64<nint> UnzipEven(Vector64<nint> left, Vector64<nint> right);
            public static Vector64<nuint> UnzipEven(Vector64<nuint> left, Vector64<nuint> right);
            public static Vector128<nint> UnzipEven(Vector128<nint> left, Vector128<nint> right);
            public static Vector128<nuint> UnzipEven(Vector128<nuint> left, Vector128<nuint> right);

            public static Vector64<nint> UnzipOdd(Vector64<nint> left, Vector64<nint> right);
            public static Vector64<nuint> UnzipOdd(Vector64<nuint> left, Vector64<nuint> right);
            public static Vector128<nint> UnzipOdd(Vector128<nint> left, Vector128<nint> right);
            public static Vector128<nuint> UnzipOdd(Vector128<nuint> left, Vector128<nuint> right);

            public static Vector64<nint> ZipHigh(Vector64<nint> left, Vector64<nint> right);
            public static Vector64<nuint> ZipHigh(Vector64<nuint> left, Vector64<nuint> right);
            public static Vector128<nint> ZipHigh(Vector128<nint> left, Vector128<nint> right);
            public static Vector128<nuint> ZipHigh(Vector128<nuint> left, Vector128<nuint> right);

            public static Vector64<nint> ZipLow(Vector64<nint> left, Vector64<nint> right);
            public static Vector64<nuint> ZipLow(Vector64<nuint> left, Vector64<nuint> right);
            public static Vector128<nint> ZipLow(Vector128<nint> left, Vector128<nint> right);
            public static Vector128<nuint> ZipLow(Vector128<nuint> left, Vector128<nuint> right);
        }

        public static Vector64<nuint> Abs(Vector64<nint> value);
        public static Vector128<nuint> Abs(Vector128<nint> value);

        public static Vector64<nint> AbsSaturate(Vector64<nint> value);
        public static Vector128<nint> AbsSaturate(Vector128<nint> value);

        public static Vector64<nint> Add(Vector64<nint> left, Vector64<nint> right);
        public static Vector64<nuint> Add(Vector64<nuint> left, Vector64<nuint> right);
        public static Vector128<nint> Add(Vector128<nint> left, Vector128<nint> right);
        public static Vector128<nuint> Add(Vector128<nuint> left, Vector128<nuint> right);

        public static Vector64<nint> AddPairwiseScalar(Vector128<nint> value);
        public static Vector64<nuint> AddPairwiseScalar(Vector128<nuint> value);

        public static Vector64<nint> AddSaturate(Vector64<nint> left, Vector64<nint> right);
        public static Vector64<nuint> AddSaturate(Vector64<nuint> left, Vector64<nuint> right);
        public static Vector128<nint> AddSaturate(Vector128<nint> left, Vector128<nint> right);
        public static Vector128<nuint> AddSaturate(Vector128<nuint> left, Vector128<nuint> right);

        public static Vector64<nint> And(Vector64<nint> left, Vector64<nint> right);
        public static Vector64<nuint> And(Vector64<nuint> left, Vector64<nuint> right);
        public static Vector128<nint> And(Vector128<nint> left, Vector128<nint> right);
        public static Vector128<nuint> And(Vector128<nuint> left, Vector128<nuint> right);

        public static Vector64<nint> BitwiseClear(Vector64<nint> value, Vector64<nint> mask);
        public static Vector64<nuint> BitwiseClear(Vector64<nuint> value, Vector64<nuint> mask);
        public static Vector128<nint> BitwiseClear(Vector128<nint> value, Vector128<nint> mask);
        public static Vector128<nuint> BitwiseClear(Vector128<nuint> value, Vector128<nuint> mask);

        public static Vector64<nint> BitwiseSelect(Vector64<nint> select, Vector64<nint> left, Vector64<nint> right);
        public static Vector64<nuint> BitwiseSelect(Vector64<nuint> select, Vector64<nuint> left, Vector64<nuint> right);
        public static Vector128<nint> BitwiseSelect(Vector128<nint> select, Vector128<nint> left, Vector128<nint> right);
        public static Vector128<nuint> BitwiseSelect(Vector128<nuint> select, Vector128<nuint> left, Vector128<nuint> right);

        public static Vector64<nint> CompareEqual(Vector64<nint> left, Vector64<nint> right);
        public static Vector64<nuint> CompareEqual(Vector64<nuint> left, Vector64<nuint> right);
        public static Vector128<nint> CompareEqual(Vector128<nint> left, Vector128<nint> right);
        public static Vector128<nuint> CompareEqual(Vector128<nuint> left, Vector128<nuint> right);

        public static Vector64<nint> CompareGreaterThan(Vector64<nint> left, Vector64<nint> right);
        public static Vector64<nuint> CompareGreaterThan(Vector64<nuint> left, Vector64<nuint> right);
        public static Vector128<nint> CompareGreaterThan(Vector128<nint> left, Vector128<nint> right);
        public static Vector128<nuint> CompareGreaterThan(Vector128<nuint> left, Vector128<nuint> right);

        public static Vector64<nint> CompareGreaterThanOrEqual(Vector64<nint> left, Vector64<nint> right);
        public static Vector64<nuint> CompareGreaterThanOrEqual(Vector64<nuint> left, Vector64<nuint> right);
        public static Vector128<nint> CompareGreaterThanOrEqual(Vector128<nint> left, Vector128<nint> right);
        public static Vector128<nuint> CompareGreaterThanOrEqual(Vector128<nuint> left, Vector128<nuint> right);

        public static Vector64<nint> CompareLessThan(Vector64<nint> left, Vector64<nint> right);
        public static Vector64<nuint> CompareLessThan(Vector64<nuint> left, Vector64<nuint> right);
        public static Vector128<nint> CompareLessThan(Vector128<nint> left, Vector128<nint> right);
        public static Vector128<nuint> CompareLessThan(Vector128<nuint> left, Vector128<nuint> right);

        public static Vector64<nint> CompareLessThanOrEqual(Vector64<nint> left, Vector64<nint> right);
        public static Vector64<nuint> CompareLessThanOrEqual(Vector64<nuint> left, Vector64<nuint> right);
        public static Vector128<nint> CompareLessThanOrEqual(Vector128<nint> left, Vector128<nint> right);
        public static Vector128<nuint> CompareLessThanOrEqual(Vector128<nuint> left, Vector128<nuint> right);

        public static Vector64<nint> CompareTest(Vector64<nint> left, Vector64<nint> right);
        public static Vector64<nuint> CompareTest(Vector64<nuint> left, Vector64<nuint> right);
        public static Vector128<nint> CompareTest(Vector128<nint> left, Vector128<nint> right);
        public static Vector128<nuint> CompareTest(Vector128<nuint> left, Vector128<nuint> right);

        public static Vector64<nint> DuplicateSelectedScalarToVector64(Vector128<nint> value, byte index);
        public static Vector64<nuint> DuplicateSelectedScalarToVector64(Vector128<nuint> value, byte index);
        public static Vector128<nint> DuplicateSelectedScalarToVector128(Vector128<nint> value, byte index);
        public static Vector128<nuint> DuplicateSelectedScalarToVector128(Vector128<nuint> value, byte index);

        public static Vector64<nint> DuplicateToVector64(nint value);
        public static Vector64<nuint> DuplicateToVector64(nuint value);
        public static Vector128<nint> DuplicateToVector128(nint value);
        public static Vector128<nuint> DuplicateToVector128(nuint value);

        public static nint Extract(Vector64<nint> vector, byte index);
        public static nuint Extract(Vector64<nuint> vector, byte index);
        public static nint Extract(Vector128<nint> vector, byte index);
        public static nuint Extract(Vector128<nuint> vector, byte index);

        public static Vector64<nint> ExtractVector64(Vector64<nint> upper, Vector64<nint> lower, byte index);
        public static Vector64<nuint> ExtractVector64(Vector64<nuint> upper, Vector64<nuint> lower, byte index);
        public static Vector128<nint> ExtractVector128(Vector128<nint> upper, Vector128<nint> lower, byte index);
        public static Vector128<nuint> ExtractVector128(Vector128<nuint> upper, Vector128<nuint> lower, byte index);

        public static Vector64<nint> Insert(Vector64<nint> vector, byte index, nint data);
        public static Vector64<nuint> Insert(Vector64<nuint> vector, byte index, nuint data);
        public static Vector128<nint> Insert(Vector128<nint> vector, byte index, nint data);
        public static Vector128<nuint> Insert(Vector128<nuint> vector, byte index, nuint data);

        public static unsafe Vector64<nint> LoadAndInsertScalar(Vector64<nint> value, byte index, nint* address);
        public static unsafe Vector64<nuint> LoadAndInsertScalar(Vector64<nuint> value, byte index, nuint* address);
        public static unsafe Vector128<nint> LoadAndInsertScalar(Vector128<nint> value, byte index, nint* address);
        public static unsafe Vector128<nuint> LoadAndInsertScalar(Vector128<nuint> value, byte index, nuint* address);

        public static unsafe Vector64<nint> LoadAndReplicateToVector64(nint* address);
        public static unsafe Vector64<nuint> LoadAndReplicateToVector64(nuint* address);
        public static unsafe Vector128<nint> LoadAndReplicateToVector128(nint* address);
        public static unsafe Vector128<nuint> LoadAndReplicateToVector128(nuint* address);

        public static unsafe Vector64<nint> LoadVector64(nint* address);
        public static unsafe Vector64<nuint> LoadVector64(nuint* address);
        public static unsafe Vector128<nint> LoadVector128(nint* address);
        public static unsafe Vector128<nuint> LoadVector128(nuint* address);

        public static Vector64<nint> Negate(Vector64<nint> value);
        public static Vector128<nint> Negate(Vector128<nint> value);

        public static Vector64<nint> NegateSaturate(Vector64<nint> value);
        public static Vector128<nint> NegateSaturate(Vector128<nint> value);

        public static Vector64<nint> Not(Vector64<nint> value);
        public static Vector64<nuint> Not(Vector64<nuint> value);
        public static Vector128<nint> Not(Vector128<nint> value);
        public static Vector128<nuint> Not(Vector128<nuint> value);

        public static Vector64<nint> Or(Vector64<nint> left, Vector64<nint> right);
        public static Vector64<nuint> Or(Vector64<nuint> left, Vector64<nuint> right);
        public static Vector128<nint> Or(Vector128<nint> left, Vector128<nint> right);
        public static Vector128<nuint> Or(Vector128<nuint> left, Vector128<nuint> right);

        public static Vector64<nint> OrNot(Vector64<nint> left, Vector64<nint> right);
        public static Vector64<nuint> OrNot(Vector64<nuint> left, Vector64<nuint> right);
        public static Vector128<nint> OrNot(Vector128<nint> left, Vector128<nint> right);
        public static Vector128<nuint> OrNot(Vector128<nuint> left, Vector128<nuint> right);

        public static Vector64<nint> ReverseElement8(Vector64<nint> value);
        public static Vector64<nuint> ReverseElement8(Vector64<nuint> value);
        public static Vector128<nint> ReverseElement8(Vector128<nint> value);
        public static Vector128<nuint> ReverseElement8(Vector128<nuint> value);

        public static Vector64<nint> ReverseElement16(Vector64<nint> value);
        public static Vector64<nuint> ReverseElement16(Vector64<nuint> value);
        public static Vector128<nint> ReverseElement16(Vector128<nint> value);
        public static Vector128<nuint> ReverseElement16(Vector128<nuint> value);

        public static Vector64<nint> ReverseElement32(Vector64<nint> value);
        public static Vector64<nuint> ReverseElement32(Vector64<nuint> value);
        public static Vector128<nint> ReverseElement32(Vector128<nint> value);
        public static Vector128<nuint> ReverseElement32(Vector128<nuint> value);

        public static Vector64<nint> ShiftArithmetic(Vector64<nint> value, Vector64<nint> count);
        public static Vector128<nint> ShiftArithmetic(Vector128<nint> value, Vector128<nint> count);

        public static Vector64<nint> ShiftArithmeticRounded(Vector64<nint> value, Vector64<nint> count);
        public static Vector128<nint> ShiftArithmeticRounded(Vector128<nint> value, Vector128<nint> count);

        public static Vector64<nint> ShiftArithmeticRoundedSaturate(Vector64<nint> value, Vector64<nint> count);
        public static Vector128<nint> ShiftArithmeticRoundedSaturate(Vector128<nint> value, Vector128<nint> count);

        public static Vector64<nint> ShiftArithmeticSaturate(Vector64<nint> value, Vector64<nint> count);
        public static Vector128<nint> ShiftArithmeticSaturate(Vector128<nint> value, Vector128<nint> count);

        public static Vector64<nint> ShiftLeftAndInsert(Vector64<nint> left, Vector64<nint> right, byte shift);
        public static Vector64<nuint> ShiftLeftAndInsert(Vector64<nuint> left, Vector64<nuint> right, byte shift);
        public static Vector128<nint> ShiftLeftAndInsert(Vector128<nint> left, Vector128<nint> right, byte shift);
        public static Vector128<nuint> ShiftLeftAndInsert(Vector128<nuint> left, Vector128<nuint> right, byte shift);

        public static Vector64<nint> ShiftLeftLogical(Vector64<nint> value, byte count);
        public static Vector64<nuint> ShiftLeftLogical(Vector64<nuint> value, byte count);
        public static Vector128<nint> ShiftLeftLogical(Vector128<nint> value, byte count);
        public static Vector128<nuint> ShiftLeftLogical(Vector128<nuint> value, byte count);

        public static Vector64<nint> ShiftLeftLogicalSaturate(Vector64<nint> value, byte count);
        public static Vector64<nuint> ShiftLeftLogicalSaturate(Vector64<nuint> value, byte count);
        public static Vector128<nint> ShiftLeftLogicalSaturate(Vector128<nint> value, byte count);
        public static Vector128<nuint> ShiftLeftLogicalSaturate(Vector128<nuint> value, byte count);

        public static Vector64<nuint> ShiftLeftLogicalSaturateUnsigned(Vector64<nint> value, byte count);
        public static Vector128<nuint> ShiftLeftLogicalSaturateUnsigned(Vector128<nint> value, byte count);

        public static Vector64<nint> ShiftLogical(Vector64<nint> value, Vector64<nint> count);
        public static Vector64<nuint> ShiftLogical(Vector64<nuint> value, Vector64<nint> count);
        public static Vector128<nint> ShiftLogical(Vector128<nint> value, Vector128<nint> count);
        public static Vector128<nuint> ShiftLogical(Vector128<nuint> value, Vector128<nint> count);

        public static Vector64<nint> ShiftLogicalRounded(Vector64<nint> value, Vector64<nint> count);
        public static Vector64<nuint> ShiftLogicalRounded(Vector64<nuint> value, Vector64<nint> count);
        public static Vector128<nint> ShiftLogicalRounded(Vector128<nint> value, Vector128<nint> count);
        public static Vector128<nuint> ShiftLogicalRounded(Vector128<nuint> value, Vector128<nint> count);

        public static Vector64<nint> ShiftLogicalRoundedSaturate(Vector64<nint> value, Vector64<nint> count);
        public static Vector64<nuint> ShiftLogicalRoundedSaturate(Vector64<nuint> value, Vector64<nint> count);
        public static Vector128<nint> ShiftLogicalRoundedSaturate(Vector128<nint> value, Vector128<nint> count);
        public static Vector128<nuint> ShiftLogicalRoundedSaturate(Vector128<nuint> value, Vector128<nint> count);

        public static Vector64<nint> ShiftLogicalSaturate(Vector64<nint> value, Vector64<nint> count);
        public static Vector64<nuint> ShiftLogicalSaturate(Vector64<nuint> value, Vector64<nint> count);
        public static Vector128<nint> ShiftLogicalSaturate(Vector128<nint> value, Vector128<nint> count);
        public static Vector128<nuint> ShiftLogicalSaturate(Vector128<nuint> value, Vector128<nint> count);

        public static Vector64<nint> ShiftRightAndInsert(Vector64<nint> left, Vector64<nint> right, byte shift);
        public static Vector64<nuint> ShiftRightAndInsert(Vector64<nuint> left, Vector64<nuint> right, byte shift);
        public static Vector128<nint> ShiftRightAndInsert(Vector128<nint> left, Vector128<nint> right, byte shift);
        public static Vector128<nuint> ShiftRightAndInsert(Vector128<nuint> left, Vector128<nuint> right, byte shift);

        public static Vector64<nint> ShiftRightArithmetic(Vector64<nint> value, byte count);
        public static Vector128<nint> ShiftRightArithmetic(Vector128<nint> value, byte count);

        public static Vector64<nint> ShiftRightArithmeticAdd(Vector64<nint> addend, Vector64<nint> value, byte count);
        public static Vector128<nint> ShiftRightArithmeticAdd(Vector128<nint> addend, Vector128<nint> value, byte count);

        public static Vector64<nint> ShiftRightArithmeticRounded(Vector64<nint> value, byte count);
        public static Vector128<nint> ShiftRightArithmeticRounded(Vector128<nint> value, byte count);

        public static Vector64<nint> ShiftRightArithmeticRoundedAdd(Vector64<nint> addend, Vector64<nint> value, byte count);
        public static Vector128<nint> ShiftRightArithmeticRoundedAdd(Vector128<nint> addend, Vector128<nint> value, byte count);

        public static Vector64<nint> ShiftRightLogical(Vector64<nint> value, byte count);
        public static Vector64<nuint> ShiftRightLogical(Vector64<nuint> value, byte count);
        public static Vector128<nint> ShiftRightLogical(Vector128<nint> value, byte count);
        public static Vector128<nuint> ShiftRightLogical(Vector128<nuint> value, byte count);

        public static Vector64<nint> ShiftRightLogicalAdd(Vector64<nint> addend, Vector64<nint> value, byte count);
        public static Vector64<nuint> ShiftRightLogicalAdd(Vector64<nuint> addend, Vector64<nuint> value, byte count);
        public static Vector128<nint> ShiftRightLogicalAdd(Vector128<nint> addend, Vector128<nint> value, byte count);
        public static Vector128<nuint> ShiftRightLogicalAdd(Vector128<nuint> addend, Vector128<nuint> value, byte count);

        public static Vector64<nint> ShiftRightLogicalRounded(Vector64<nint> value, byte count);
        public static Vector64<nuint> ShiftRightLogicalRounded(Vector64<nuint> value, byte count);
        public static Vector128<nint> ShiftRightLogicalRounded(Vector128<nint> value, byte count);
        public static Vector128<nuint> ShiftRightLogicalRounded(Vector128<nuint> value, byte count);

        public static Vector64<nint> ShiftRightLogicalRoundedAddScalar(Vector64<nint> addend, Vector64<nint> value, byte count);
        public static Vector64<nuint> ShiftRightLogicalRoundedAddScalar(Vector64<nuint> addend, Vector64<nuint> value, byte count);
        public static Vector128<nint> ShiftRightLogicalRoundedAdd(Vector128<nint> addend, Vector128<nint> value, byte count);
        public static Vector128<nuint> ShiftRightLogicalRoundedAdd(Vector128<nuint> addend, Vector128<nuint> value, byte count);

        public static unsafe void Store(nint* address, Vector64<nint> source);
        public static unsafe void Store(nuint* address, Vector64<nuint> source);
        public static unsafe void Store(nint* address, Vector128<nint> source);
        public static unsafe void Store(nuint* address, Vector128<nuint> source);

        public static unsafe void StoreSelectedScalar(nint* address, Vector128<nint> value, byte index);
        public static unsafe void StoreSelectedScalar(nuint* address, Vector128<nuint> value, byte index);
        public static unsafe void StoreSelectedScalar(nint* address, Vector128<nint> value, byte index);
        public static unsafe void StoreSelectedScalar(nuint* address, Vector128<nuint> value, byte index);

        public static Vector64<nint> Subtract(Vector64<nint> left, Vector64<nint> right);
        public static Vector64<nuint> Subtract(Vector64<nuint> left, Vector64<nuint> right);
        public static Vector128<nint> Subtract(Vector128<nint> left, Vector128<nint> right);
        public static Vector128<nuint> Subtract(Vector128<nuint> left, Vector128<nuint> right);

        public static Vector64<nint> SubtractSaturate(Vector64<nint> left, Vector64<nint> right);
        public static Vector64<nuint> SubtractSaturate(Vector64<nuint> left, Vector64<nuint> right);
        public static Vector128<nint> SubtractSaturate(Vector128<nint> left, Vector128<nint> right);
        public static Vector128<nuint> SubtractSaturate(Vector128<nuint> left, Vector128<nuint> right);

        public static Vector64<nint> Xor(Vector64<nint> left, Vector64<nint> right);
        public static Vector64<nuint> Xor(Vector64<nuint> left, Vector64<nuint> right);
        public static Vector128<nint> Xor(Vector128<nint> left, Vector128<nint> right);
        public static Vector128<nuint> Xor(Vector128<nuint> left, Vector128<nuint> right);
    }

    public abstract partial class Crc32
    {
        public static uint ComputeCrc32(uint crc, nuint data);
        public static uint ComputeCrc32C(uint crc, nuint data);
    }

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions