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.
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.