mirror of https://github.com/stella-emu/stella.git
Convert C-style union and malloc/free to C++ std::variant and unique_ptr.
This commit is contained in:
parent
ec17cfa610
commit
6614a2228a
|
@ -509,8 +509,8 @@ CortexM0::err_t CortexM0::BusTransactionDelegate::write8(uInt32 address, uInt8 v
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
CortexM0::err_t CortexM0::BusTransactionDelegate::fetch16(
|
CortexM0::err_t CortexM0::BusTransactionDelegate::fetch16(
|
||||||
uInt32 address, uInt16& value, uInt8& op, CortexM0& cortex
|
uInt32 address, uInt16& value, uInt8& op, CortexM0& cortex)
|
||||||
) {
|
{
|
||||||
const err_t err = read16(address, value, cortex);
|
const err_t err = read16(address, value, cortex);
|
||||||
if (err) return err;
|
if (err) return err;
|
||||||
|
|
||||||
|
@ -536,32 +536,32 @@ string CortexM0::describeError(err_t err) {
|
||||||
CortexM0::CortexM0()
|
CortexM0::CortexM0()
|
||||||
{
|
{
|
||||||
myPageMap = make_unique<uInt8[]>(PAGEMAP_SIZE);
|
myPageMap = make_unique<uInt8[]>(PAGEMAP_SIZE);
|
||||||
std::memset(myPageMap.get(), 0xff, PAGEMAP_SIZE);
|
std::fill_n(myPageMap.get(), PAGEMAP_SIZE, 0xff);
|
||||||
|
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
CortexM0& CortexM0::mapRegionData(uInt32 pageBase,
|
CortexM0& CortexM0::mapRegionData(uInt32 pageBase, uInt32 pageCount,
|
||||||
uInt32 pageCount, bool readOnly, uInt8* backingStore)
|
bool readOnly, uInt8* backingStore)
|
||||||
{
|
{
|
||||||
MemoryRegion& region =
|
MemoryRegion& region =
|
||||||
setupMapping(pageBase, pageCount, readOnly, MemoryRegionType::directData);
|
setupMapping(pageBase, pageCount, readOnly, MemoryRegionType::directData);
|
||||||
|
|
||||||
region.access.accessData.backingStore = backingStore;
|
region.access.emplace<0>(backingStore);
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
CortexM0& CortexM0::mapRegionCode(uInt32 pageBase,
|
CortexM0& CortexM0::mapRegionCode(uInt32 pageBase, uInt32 pageCount,
|
||||||
uInt32 pageCount, bool readOnly, uInt8* backingStore)
|
bool readOnly, uInt8* backingStore)
|
||||||
{
|
{
|
||||||
MemoryRegion& region =
|
MemoryRegion& region =
|
||||||
setupMapping(pageBase, pageCount, readOnly, MemoryRegionType::directCode);
|
setupMapping(pageBase, pageCount, readOnly, MemoryRegionType::directCode);
|
||||||
|
|
||||||
region.access.accessCode.backingStore = backingStore;
|
region.access.emplace<1>(backingStore,
|
||||||
region.access.accessCode.ops = static_cast<uInt8*>(std::malloc((pageCount * PAGE_SIZE) >> 1));
|
make_unique<uInt8[]>((pageCount * PAGE_SIZE) >> 1));
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -573,7 +573,7 @@ CortexM0& CortexM0::mapRegionDelegate(uInt32 pageBase, uInt32 pageCount, bool re
|
||||||
MemoryRegion& region =
|
MemoryRegion& region =
|
||||||
setupMapping(pageBase, pageCount, readOnly, MemoryRegionType::delegate);
|
setupMapping(pageBase, pageCount, readOnly, MemoryRegionType::delegate);
|
||||||
|
|
||||||
region.access.delegate = delegate;
|
region.access.emplace<2>(delegate);
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -655,7 +655,7 @@ CortexM0::err_t CortexM0::run(uInt32 maxCycles, uInt32& cycles)
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
CortexM0::MemoryRegion& CortexM0::setupMapping(uInt32 pageBase, uInt32 pageCount,
|
CortexM0::MemoryRegion& CortexM0::setupMapping(uInt32 pageBase, uInt32 pageCount,
|
||||||
bool readOnly, CortexM0::MemoryRegionType type)
|
bool readOnly, CortexM0::MemoryRegionType type)
|
||||||
{
|
{
|
||||||
if (myNextRegionIndex == 0xff) throw runtime_error("no free memory region");
|
if (myNextRegionIndex == 0xff) throw runtime_error("no free memory region");
|
||||||
const uInt8 regionIndex = myNextRegionIndex++;
|
const uInt8 regionIndex = myNextRegionIndex++;
|
||||||
|
@ -677,11 +677,12 @@ CortexM0::MemoryRegion& CortexM0::setupMapping(uInt32 pageBase, uInt32 pageCount
|
||||||
void CortexM0::recompileCodeRegions()
|
void CortexM0::recompileCodeRegions()
|
||||||
{
|
{
|
||||||
for (const auto& region: myRegions) {
|
for (const auto& region: myRegions) {
|
||||||
if (region.type != MemoryRegionType::directCode) continue;
|
if (!std::holds_alternative<MemoryRegionAccessCode>(region.access))
|
||||||
|
continue;
|
||||||
|
|
||||||
for (size_t i = 0; i < region.size; i += 2)
|
for (size_t i = 0; i < region.size; i += 2)
|
||||||
region.access.accessCode.ops[i >> 1] =
|
std::get<1>(region.access).ops[i >> 1] =
|
||||||
decodeInstructionWord(READ16(region.access.accessCode.backingStore, i));
|
decodeInstructionWord(READ16(std::get<1>(region.access).backingStore, i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -694,19 +695,20 @@ CortexM0::err_t CortexM0::read32(uInt32 address, uInt32& value)
|
||||||
|
|
||||||
switch (region.type) {
|
switch (region.type) {
|
||||||
case MemoryRegionType::delegate:
|
case MemoryRegionType::delegate:
|
||||||
return region.access.delegate->read32(address, value, *this);
|
return std::get<2>(region.access)->read32(address, value, *this);
|
||||||
|
|
||||||
case MemoryRegionType::directCode:
|
case MemoryRegionType::directCode:
|
||||||
value = READ32(region.access.accessCode.backingStore, address - region.base);
|
value = READ32(std::get<1>(region.access).backingStore, address - region.base);
|
||||||
return ERR_NONE;
|
return ERR_NONE;
|
||||||
|
|
||||||
case MemoryRegionType::directData:
|
case MemoryRegionType::directData:
|
||||||
value = READ32(region.access.accessData.backingStore, address - region.base);
|
value = READ32(std::get<0>(region.access).backingStore, address - region.base);
|
||||||
return ERR_NONE;
|
return ERR_NONE;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return myDefaultDelegate ?
|
return myDefaultDelegate
|
||||||
myDefaultDelegate->read32(address, value, *this) : errIntrinsic(ERR_UNMAPPED_READ32, address);
|
? myDefaultDelegate->read32(address, value, *this)
|
||||||
|
: errIntrinsic(ERR_UNMAPPED_READ32, address);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -719,19 +721,20 @@ CortexM0::err_t CortexM0::read16(uInt32 address, uInt16& value)
|
||||||
|
|
||||||
switch (region.type) {
|
switch (region.type) {
|
||||||
case MemoryRegionType::delegate:
|
case MemoryRegionType::delegate:
|
||||||
return region.access.delegate->read16(address, value, *this);
|
return std::get<2>(region.access)->read16(address, value, *this);
|
||||||
|
|
||||||
case MemoryRegionType::directCode:
|
case MemoryRegionType::directCode:
|
||||||
value = READ16(region.access.accessCode.backingStore, address - region.base);
|
value = READ16(std::get<1>(region.access).backingStore, address - region.base);
|
||||||
return ERR_NONE;
|
return ERR_NONE;
|
||||||
|
|
||||||
case MemoryRegionType::directData:
|
case MemoryRegionType::directData:
|
||||||
value = READ16(region.access.accessData.backingStore, address - region.base);
|
value = READ16(std::get<0>(region.access).backingStore, address - region.base);
|
||||||
return ERR_NONE;
|
return ERR_NONE;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return myDefaultDelegate ?
|
return myDefaultDelegate
|
||||||
myDefaultDelegate->read16(address, value, *this) : errIntrinsic(ERR_UNMAPPED_READ16, address);
|
? myDefaultDelegate->read16(address, value, *this)
|
||||||
|
: errIntrinsic(ERR_UNMAPPED_READ16, address);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -742,19 +745,20 @@ CortexM0::err_t CortexM0::read8(uInt32 address, uInt8& value)
|
||||||
|
|
||||||
switch (region.type) {
|
switch (region.type) {
|
||||||
case MemoryRegionType::delegate:
|
case MemoryRegionType::delegate:
|
||||||
return region.access.delegate->read8(address, value, *this);
|
return std::get<2>(region.access)->read8(address, value, *this);
|
||||||
|
|
||||||
case MemoryRegionType::directCode:
|
case MemoryRegionType::directCode:
|
||||||
value = region.access.accessCode.backingStore[address - region.base];
|
value = std::get<1>(region.access).backingStore[address - region.base];
|
||||||
return ERR_NONE;
|
return ERR_NONE;
|
||||||
|
|
||||||
case MemoryRegionType::directData:
|
case MemoryRegionType::directData:
|
||||||
value = region.access.accessData.backingStore[address - region.base];
|
value = std::get<0>(region.access).backingStore[address - region.base];
|
||||||
return ERR_NONE;
|
return ERR_NONE;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return myDefaultDelegate ?
|
return myDefaultDelegate
|
||||||
myDefaultDelegate->read8(address, value, *this) : errIntrinsic(ERR_UNMAPPED_READ8, address);
|
? myDefaultDelegate->read8(address, value, *this)
|
||||||
|
: errIntrinsic(ERR_UNMAPPED_READ8, address);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -768,19 +772,20 @@ CortexM0::err_t CortexM0::write32(uInt32 address, uInt32 value)
|
||||||
|
|
||||||
switch (region.type) {
|
switch (region.type) {
|
||||||
case MemoryRegionType::delegate:
|
case MemoryRegionType::delegate:
|
||||||
return region.access.delegate->write32(address, value, *this);
|
return std::get<2>(region.access)->write32(address, value, *this);
|
||||||
|
|
||||||
case MemoryRegionType::directCode:
|
case MemoryRegionType::directCode:
|
||||||
WRITE32(region.access.accessCode.backingStore, address - region.base, value);
|
WRITE32(std::get<1>(region.access).backingStore, address - region.base, value);
|
||||||
return ERR_NONE;
|
return ERR_NONE;
|
||||||
|
|
||||||
case MemoryRegionType::directData:
|
case MemoryRegionType::directData:
|
||||||
WRITE32(region.access.accessData.backingStore, address - region.base, value);
|
WRITE32(std::get<0>(region.access).backingStore, address - region.base, value);
|
||||||
return ERR_NONE;
|
return ERR_NONE;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return myDefaultDelegate ?
|
return myDefaultDelegate
|
||||||
myDefaultDelegate->write32(address, value, *this) : errIntrinsic(ERR_UNMAPPED_WRITE32, address);
|
? myDefaultDelegate->write32(address, value, *this)
|
||||||
|
: errIntrinsic(ERR_UNMAPPED_WRITE32, address);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -794,24 +799,25 @@ CortexM0::err_t CortexM0::write16(uInt32 address, uInt16 value)
|
||||||
|
|
||||||
switch (region.type) {
|
switch (region.type) {
|
||||||
case MemoryRegionType::delegate:
|
case MemoryRegionType::delegate:
|
||||||
return region.access.delegate->write16(address, value, *this);
|
return std::get<2>(region.access)->write16(address, value, *this);
|
||||||
|
|
||||||
case MemoryRegionType::directCode: {
|
case MemoryRegionType::directCode: {
|
||||||
const uInt32 offset = address - region.base;
|
const uInt32 offset = address - region.base;
|
||||||
|
|
||||||
WRITE16(region.access.accessCode.backingStore, offset, value);
|
WRITE16(std::get<1>(region.access).backingStore, offset, value);
|
||||||
region.access.accessCode.ops[offset >> 1] = decodeInstructionWord(value);
|
std::get<1>(region.access).ops[offset >> 1] = decodeInstructionWord(value);
|
||||||
|
|
||||||
return ERR_NONE;
|
return ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
case MemoryRegionType::directData:
|
case MemoryRegionType::directData:
|
||||||
WRITE16(region.access.accessData.backingStore, address - region.base, value);
|
WRITE16(std::get<0>(region.access).backingStore, address - region.base, value);
|
||||||
return ERR_NONE;
|
return ERR_NONE;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return myDefaultDelegate ?
|
return myDefaultDelegate
|
||||||
myDefaultDelegate->write16(address, value, *this) : errIntrinsic(ERR_UNMAPPED_WRITE16, address);
|
? myDefaultDelegate->write16(address, value, *this)
|
||||||
|
: errIntrinsic(ERR_UNMAPPED_WRITE16, address);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -823,24 +829,25 @@ CortexM0::err_t CortexM0::write8(uInt32 address, uInt8 value)
|
||||||
|
|
||||||
switch (region.type) {
|
switch (region.type) {
|
||||||
case MemoryRegionType::delegate:
|
case MemoryRegionType::delegate:
|
||||||
return region.access.delegate->write8(address, value, *this);
|
return std::get<2>(region.access)->write8(address, value, *this);
|
||||||
|
|
||||||
case MemoryRegionType::directCode: {
|
case MemoryRegionType::directCode: {
|
||||||
const uInt32 offset = address - region.base;
|
const uInt32 offset = address - region.base;
|
||||||
|
|
||||||
region.access.accessCode.backingStore[offset] = value;
|
std::get<1>(region.access).backingStore[offset] = value;
|
||||||
region.access.accessCode.ops[offset >> 1] = decodeInstructionWord(value);
|
std::get<1>(region.access).ops[offset >> 1] = decodeInstructionWord(value);
|
||||||
|
|
||||||
return ERR_NONE;
|
return ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
case MemoryRegionType::directData:
|
case MemoryRegionType::directData:
|
||||||
region.access.accessData.backingStore[address - region.base] = value;
|
std::get<0>(region.access).backingStore[address - region.base] = value;
|
||||||
return ERR_NONE;
|
return ERR_NONE;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return myDefaultDelegate ?
|
return myDefaultDelegate
|
||||||
myDefaultDelegate->write8(address, value, *this) : errIntrinsic(ERR_UNMAPPED_WRITE8, address);
|
? myDefaultDelegate->write8(address, value, *this)
|
||||||
|
: errIntrinsic(ERR_UNMAPPED_WRITE8, address);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -853,26 +860,27 @@ CortexM0::err_t CortexM0::fetch16(uInt32 address, uInt16& value, uInt8& op)
|
||||||
|
|
||||||
switch (region.type) {
|
switch (region.type) {
|
||||||
case MemoryRegionType::delegate:
|
case MemoryRegionType::delegate:
|
||||||
return region.access.delegate->fetch16(address, value, op, *this);
|
return std::get<2>(region.access)->fetch16(address, value, op, *this);
|
||||||
|
|
||||||
case MemoryRegionType::directCode: {
|
case MemoryRegionType::directCode: {
|
||||||
const uInt32 offset = address - region.base;
|
const uInt32 offset = address - region.base;
|
||||||
|
|
||||||
value = READ16(region.access.accessCode.backingStore, offset);
|
value = READ16(std::get<1>(region.access).backingStore, offset);
|
||||||
op = region.access.accessCode.ops[offset >> 1];
|
op = std::get<1>(region.access).ops[offset >> 1];
|
||||||
|
|
||||||
return ERR_NONE;
|
return ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
case MemoryRegionType::directData:
|
case MemoryRegionType::directData:
|
||||||
value = READ16(region.access.accessCode.backingStore, address - region.base);
|
value = READ16(std::get<0>(region.access).backingStore, address - region.base);
|
||||||
op = decodeInstructionWord(value);
|
op = decodeInstructionWord(value);
|
||||||
|
|
||||||
return ERR_NONE;
|
return ERR_NONE;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return myDefaultDelegate ?
|
return myDefaultDelegate
|
||||||
myDefaultDelegate->fetch16(address, value, op, *this) : errIntrinsic(ERR_UNMAPPED_FETCH16, address);
|
? myDefaultDelegate->fetch16(address, value, op, *this)
|
||||||
|
: errIntrinsic(ERR_UNMAPPED_FETCH16, address);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -893,6 +901,7 @@ void CortexM0::do_cvflag(uInt32 a, uInt32 b, uInt32 c)
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
// NOLINTNEXTLINE: function exceeds recommended size/complexity thresholds
|
||||||
CortexM0::err_t CortexM0::execute(uInt16 inst, uInt8 op)
|
CortexM0::err_t CortexM0::execute(uInt16 inst, uInt8 op)
|
||||||
{
|
{
|
||||||
uInt32 sp, ra, rb, rc, rm, rd, rn, rs; // NOLINT: don't need to initialize
|
uInt32 sp, ra, rb, rc, rm, rd, rn, rs; // NOLINT: don't need to initialize
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
#ifndef CORTEX_M0
|
#ifndef CORTEX_M0
|
||||||
#define CORTEX_M0
|
#define CORTEX_M0
|
||||||
|
|
||||||
|
#include <variant>
|
||||||
|
|
||||||
#include "bspf.hxx"
|
#include "bspf.hxx"
|
||||||
|
|
||||||
class CortexM0
|
class CortexM0
|
||||||
|
@ -148,16 +150,12 @@ class CortexM0
|
||||||
|
|
||||||
struct MemoryRegionAccessCode {
|
struct MemoryRegionAccessCode {
|
||||||
uInt8* backingStore;
|
uInt8* backingStore;
|
||||||
uInt8* ops;
|
unique_ptr<uInt8[]> ops;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MemoryRegion {
|
struct MemoryRegion {
|
||||||
MemoryRegion() = default;
|
MemoryRegion() = default;
|
||||||
|
~MemoryRegion() = default;
|
||||||
~MemoryRegion() {
|
|
||||||
if (type == MemoryRegionType::directCode)
|
|
||||||
std::free(access.accessCode.ops);
|
|
||||||
}
|
|
||||||
|
|
||||||
MemoryRegionType type{MemoryRegionType::unmapped};
|
MemoryRegionType type{MemoryRegionType::unmapped};
|
||||||
|
|
||||||
|
@ -165,11 +163,11 @@ class CortexM0
|
||||||
uInt32 size{0};
|
uInt32 size{0};
|
||||||
bool readOnly{false};
|
bool readOnly{false};
|
||||||
|
|
||||||
union {
|
std::variant<
|
||||||
MemoryRegionAccessData accessData;
|
MemoryRegionAccessData, // ::get<0>, directData
|
||||||
MemoryRegionAccessCode accessCode;
|
MemoryRegionAccessCode, // ::get<1>, directCode
|
||||||
BusTransactionDelegate* delegate{nullptr};
|
BusTransactionDelegate* // ::get<2>, delegate
|
||||||
} access;
|
> access;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MemoryRegion(const MemoryRegion&) = delete;
|
MemoryRegion(const MemoryRegion&) = delete;
|
||||||
|
|
Loading…
Reference in New Issue