Integer Types

The GBA has registers that are 32-bits wide.

Due to limitations in the armv4t architecture any operations performed on data-types that are not 32-bits wide will require additional instructions to clear the upper bits and propagate any sign-bit for any signed arithmetic.

[[nodiscard]]
short increment( const short value ) noexcept {
    return value + 1;
}

[[nodiscard]]
int increment( const int value ) noexcept {
    return value + 1;
}

Notice how the produced assembly code has two additional instructions for the 16-bit short version versus the 32-bit int version.

increment(short):
    add     r0, r0, #1
    lsl     r0, r0, #16
    asr     r0, r0, #16
    bx      lr

increment(int):
    add     r0, r0, #1
    bx      lr

This is even worse for unsigned values:

[[nodiscard]]
unsigned short increment( const unsigned short value ) noexcept {
    return value + 1u;
}

[[nodiscard]]
unsigned int increment( const unsigned int value ) noexcept {
    return value + 1u;
}

The 16-bit unsigned short version inserts 3 additional instructions that build a mask to clear the upper 16-bits from the result.

increment(unsigned short):
    mov     r1, #255
    add     r0, r0, #1
    orr     r1, r1, #65280
    and     r0, r0, r1
    bx      lr

increment(unsigned int):
    add     r0, r0, #1
    bx      lr

For these reasons, a good rule to stick by is to always use 32-bit integers for operations, and only use other sizes for loading/storing the values.

gba-plusplus provides 8-bit, 16-bit and 32-bit sized integer types:

[[nodiscard]]
gba::int32 increment( const gba::int32 value ) noexcept {
    return value + 1;
}

[[nodiscard]]
gba::uint32 increment( const gba::uint32 value ) noexcept {
    return value + 1u;
}

These are defined by the gba::int_type<> and gba::uint_type<> templates, which provides appropriately sized storage for a desired minimum bit-length.

Signed Integers

template<unsigned Bits>
struct gba::int_type

Signed integer types

tparam Bits

minimum size of this integer type in bits

Public Types

using type = typename std::conditional<Bits <= 8, std::int8_t, typename std::conditional<Bits <= 16, std::int16_t, typename std::conditional<Bits <= 32, std::int32_t, std::int64_t>::type>::type>::type

Exact-width integer type.

using least = typename std::conditional<Bits <= 8, std::int_least8_t, typename std::conditional<Bits <= 16, std::int_least16_t, typename std::conditional<Bits <= 32, std::int_least32_t, std::int_least64_t>::type>::type>::type

Minimum-width integer type.

using fast = typename std::conditional<Bits <= 8, std::int_fast8_t, typename std::conditional<Bits <= 16, std::int_fast16_t, typename std::conditional<Bits <= 32, std::int_fast32_t, std::int_fast64_t>::type>::type>::type

Fastest minimum-width integer type.

Public Static Functions

static inline constexpr auto min() noexcept

Smallest possible value to be stored in this type

Returns

-(2^(Bits-1))

static inline constexpr auto max() noexcept

Largest possible value to be stored in this type

Returns

(2^(Bits-1))-1

Unsigned Integers

template<unsigned int Bits>
struct gba::uint_type

Unsigned integer types

tparam Bits

minimum size of this integer type in bits

Public Types

using type = typename std::conditional<Bits <= 8, std::uint8_t, typename std::conditional<Bits <= 16, std::uint16_t, typename std::conditional<Bits <= 32, std::uint32_t, std::uint64_t>::type>::type>::type

Exact-width integer type.

using least = typename std::conditional<Bits <= 8, std::uint_least8_t, typename std::conditional<Bits <= 16, std::uint_least16_t, typename std::conditional<Bits <= 32, std::uint_least32_t, std::uint_least64_t>::type>::type>::type

Minimum-width integer type.

using fast = typename std::conditional<Bits <= 8, std::uint_fast8_t, typename std::conditional<Bits <= 16, std::uint_fast16_t, typename std::conditional<Bits <= 32, std::uint_fast32_t, std::uint_fast64_t>::type>::type>::type

Fastest minimum-width integer type.

Public Static Functions

static inline constexpr auto min() noexcept

Smallest possible value to be stored in this type

Returns

0

static inline constexpr auto max() noexcept

Largest possible value to be stored in this type

Returns

(2^Bits)-1