1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-05 06:05:27 +00:00
CLK/Numeric/RegisterSizes.hpp
2023-02-01 14:31:40 -05:00

93 lines
1.6 KiB
C++

//
// RegisterSizes.hpp
// Clock Signal
//
// Created by Thomas Harte on 14/05/2017.
// Copyright 2017 Thomas Harte. All rights reserved.
//
#ifndef RegisterSizes_hpp
#define RegisterSizes_hpp
#include <cstdint>
#pragma pack(push, 1)
// Unions below assume a modern consumer architecture,
// and that this compiler offers C-style anonymous structs.
namespace CPU {
/// Provides access to all intermediate parts of a larger int.
template <typename Full, typename Half> union alignas(Full) alignas(Half) RegisterPair {
RegisterPair(Full v) : full(v) {}
RegisterPair() {}
Full full;
#if TARGET_RT_BIG_ENDIAN
struct {
Half high, low;
} halves;
#else
struct {
Half low, high;
} halves;
#endif
};
using RegisterPair16 = RegisterPair<uint16_t, uint8_t>;
using RegisterPair32 = RegisterPair<uint32_t, RegisterPair16>;
/// Provides access to lower portions of a larger int.
template <typename IntT> union SlicedInt {};
template <> union SlicedInt<uint16_t> {
struct {
uint16_t w;
};
struct {
#if TARGET_RT_BIG_ENDIAN
uint8_t __padding[1];
#endif
uint8_t b;
};
};
template <> union SlicedInt<uint32_t> {
struct {
uint32_t l;
};
struct {
#if TARGET_RT_BIG_ENDIAN
uint16_t __padding[1];
#endif
uint16_t w;
};
struct {
#if TARGET_RT_BIG_ENDIAN
uint8_t __padding[3];
#endif
uint8_t b;
};
struct {
#if TARGET_RT_BIG_ENDIAN
SlicedInt<uint16_t> high, low;
#else
SlicedInt<uint16_t> low, high;
#endif
};
};
using SlicedInt16 = SlicedInt<uint16_t>;
using SlicedInt32 = SlicedInt<uint32_t>;
}
#pragma pack(pop)
#endif /* RegisterSizes_hpp */