Skip to content

Commit

Permalink
[TEST] Improve ArrayMemory
Browse files Browse the repository at this point in the history
  • Loading branch information
tgtakaoka committed Jan 30, 2025
1 parent 332ef41 commit 1d6b050
Show file tree
Hide file tree
Showing 24 changed files with 345 additions and 194 deletions.
81 changes: 58 additions & 23 deletions src/array_memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,49 +26,85 @@
namespace libasm {

/**
* Byte addressable memory from array constant
* Byte/Word addressable memory from array constant
*/
struct ArrayMemory {
/** DisMemory interface of ArrayMemory */
struct Iterator : DisMemory {
bool hasNext() const override { return _index < _memory.size(); }

uint16_t readUint16() {
uint16_t word = readByte();
if (_endian == ENDIAN_BIG) {
word = (word << 8) | readByte();
} else {
word |= readByte() << 8;
}
return word;
}

/** rewind to the first byte */
void rewind() {
DisMemory::resetAddress(_memory.origin());
DisMemory::resetAddress(_memory.origin() * _memory.unit());
_index = 0;
}

private:
friend ArrayMemory;
Iterator(const ArrayMemory &memory)
: DisMemory(memory.origin()), _memory(memory), _index(0) {}
uint8_t nextByte() override { return _memory.byteAt(_memory.origin() + _index++); }
Iterator(const ArrayMemory &memory, Endian endian)
: DisMemory(memory.origin() * memory.unit()),
_memory(memory),
_endian(endian),
_index(0) {}

uint8_t nextByte() override {
return _memory.byteAt(_memory.origin() * _memory.unit() + _index++);
}

const ArrayMemory &_memory;
const Endian _endian;
size_t _index;
};

/** Construct byte addressable memory from uint8_t array */
ArrayMemory(
uint32_t origin, const uint8_t *bytes, size_t sizeof_bytes, Endian endian = ENDIAN_BIG)
: _origin(origin), _bytes(bytes), _words(nullptr), _size(sizeof_bytes), _endian(endian) {}
ArrayMemory(uint32_t origin, const uint8_t *bytes, size_t sizeof_bytes,
Endian endian = ENDIAN_BIG, AddressUnit = ADDRESS_BYTE)
: _origin(origin),
_bytes(bytes),
_words(nullptr),
_size(sizeof_bytes),
_endian(endian),
_unit(ADDRESS_BYTE) {}

/** Construct byte/word addressable memory from uint16_t array */
ArrayMemory(uint32_t origin, const uint16_t *words, size_t sizeof_words, Endian endian,
AddressUnit unit)
: _origin(origin * unit),
_bytes(nullptr),
_words(words),
_size(sizeof_words),
_endian(endian),
_unit(unit) {}

/** byte address of the first byte/word */
uint32_t origin() const { return _origin / _unit; }

/** byte address of the last byte/word */
uint32_t end() const { return (_origin + size()) / _unit - 1; }

/** Construct byte addressable memory from uint16_t array with specified endian */
ArrayMemory(uint32_t origin, const uint16_t *words, size_t sizeof_words, Endian endian)
: _origin(origin), _bytes(nullptr), _words(words), _size(sizeof_words), _endian(endian) {}
/** memory size in byte */
size_t size() const { return _size; }

/** byte address of the first byte */
uint32_t origin() const { return _origin; }
bool word() const { return _words != nullptr; }

/** byte address of the last byte */
uint32_t end() const { return _origin + size() - 1; }
/** endianess */
Endian endian() const { return _endian; }

/** memory size in byte */
size_t size() const { return _size; }
AddressUnit unit() const { return _unit; }

/** returns DisMemory interface */
Iterator iterator() const { return Iterator(*this); }
/** returns DisMemory interface with specified endian */
Iterator iterator(Endian endian = ENDIAN_BIG) const { return Iterator(*this, endian); }

/** returns byte at address |addr|, otherwise zero */
uint8_t byteAt(uint32_t addr) const {
Expand All @@ -78,12 +114,10 @@ struct ArrayMemory {
if (_bytes)
return _bytes[offset];
const uint16_t word = _words[offset / 2];
const uint8_t hi = word >> 8;
const uint8_t lo = word;
if (offset % 2 == 0) {
return _endian == ENDIAN_BIG ? hi : lo;
if (_endian == ENDIAN_BIG) {
return (offset % 2) == 0 ? (word >> 8) : word;
} else {
return _endian == ENDIAN_BIG ? lo : hi;
return (offset % 2) == 0 ? word : (word >> 8);
}
}

Expand All @@ -95,6 +129,7 @@ struct ArrayMemory {
/** size in byte */
const size_t _size;
const Endian _endian;
const AddressUnit _unit;
};

} // namespace libasm
Expand Down
8 changes: 8 additions & 0 deletions src/config_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,14 @@ enum Endian : uint8_t {
ENDIAN_LITTLE,
};

enum Radix : uint8_t {
RADIX_NONE = 0,
RADIX_2 = 2,
RADIX_8 = 8,
RADIX_10 = 10,
RADIX_16 = 16,
};

enum Size : uint8_t {
SZ_NONE = 0,
SZ_BYTE = 1, // 1 byte
Expand Down
21 changes: 14 additions & 7 deletions src/entry_table.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,18 +126,25 @@ struct CpuBase {
return strcasecmp_P(insn.name(), entry_P->name_P());
}

template <typename INSN, typename ENTRY>
static bool acceptAll(INSN &, const ENTRY *) {
return true;
}

/** Tempalte specialization of |readCode| for non-prefixed TableBase */
template <typename INSN, typename ENTRY, typename PAGE,
typename enable_if<!is_base_of<PrefixTableBase<ENTRY>, PAGE>::value>::type * = nullptr>
static void defaultReadCode(INSN &insn, const ENTRY *entry_P, const PAGE *) {
template <typename INSN, typename ENTRY,
typename enable_if<!is_base_of<PrefixTableBase<ENTRY>, ENTRY_PAGE>::value>::type * =
nullptr>
static void defaultReadCode(INSN &insn, const ENTRY *entry_P, const ENTRY_PAGE *) {
insn.setOpCode(entry_P->readOpCode());
insn.setFlags(entry_P->readFlags());
}

/** Template specialization of |readCode| for PrefixTableBase */
template <typename INSN, typename ENTRY, typename PAGE,
typename enable_if<is_base_of<PrefixTableBase<ENTRY>, PAGE>::value>::type * = nullptr>
static void defaultReadCode(INSN &insn, const ENTRY *entry_P, const PAGE *page_P) {
template <typename INSN, typename ENTRY,
typename enable_if<is_base_of<PrefixTableBase<ENTRY>, ENTRY_PAGE>::value>::type * =
nullptr>
static void defaultReadCode(INSN &insn, const ENTRY *entry_P, const ENTRY_PAGE *page_P) {
insn.setPrefix(page_P->readPrefix());
insn.setOpCode(entry_P->readOpCode());
insn.setFlags(entry_P->readFlags());
Expand Down Expand Up @@ -173,7 +180,7 @@ struct CpuBase {

template <typename INSN, typename ENTRY>
static void defaultReadName(
INSN &insn, const ENTRY *entry_P, StrBuffer &out, const ENTRY_PAGE *) {
INSN &insn, const ENTRY *entry_P, StrBuffer &out, const ENTRY_PAGE * = nullptr) {
insn.setFlags(entry_P->readFlags());
auto save{out};
insn.nameBuffer().reset().over(out).text_P(entry_P->name_P()).over(insn.nameBuffer());
Expand Down
6 changes: 1 addition & 5 deletions src/table_f3850.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -206,12 +206,8 @@ static const Cpu *cpu(CpuType) {
return &CPU_TABLE[0];
}

static bool acceptAll(AsmInsn &, const Entry *) {
return true;
}

bool TableF3850::hasOperand(CpuType cpuType, AsmInsn &insn) const {
cpu(cpuType)->searchName(insn, acceptAll);
cpu(cpuType)->searchName(insn, Cpu::acceptAll<AsmInsn, Entry>);
return insn.isOK() && insn.mode1() != M_NONE;
}

Expand Down
8 changes: 2 additions & 6 deletions src/table_mc6800.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -607,12 +607,8 @@ static const Cpu *cpu(CpuType cpuType) {
return Cpu::search(cpuType, ARRAY_RANGE(CPU_TABLE));
}

static bool acceptAll(AsmInsn &, const Entry *) {
return true;
}

bool TableMc6800::hasOperand(CpuType cpuType, AsmInsn &insn) const {
cpu(cpuType)->searchName(insn, acceptAll);
cpu(cpuType)->searchName(insn, Cpu::acceptAll<AsmInsn, Entry>);
return insn.isOK() && insn.mode1() != M_NONE;
}

Expand Down Expand Up @@ -686,7 +682,7 @@ Error TableMc6800::searchOpCodeAlias(CpuType cpuType, DisInsn &insn, StrBuffer &
entry += 1;
if (entry->readOpCode() != insn.opCode())
return insn.setError(INTERNAL_ERROR);
Cpu::defaultReadName(insn, entry, out, nullptr);
Cpu::defaultReadName(insn, entry, out);
return OK;
}

Expand Down
8 changes: 2 additions & 6 deletions src/table_mc68000.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1271,15 +1271,11 @@ static const Fpu *fpu(FpuType fpuType) {
}
#endif

static bool acceptAll(AsmInsn &, const Entry *) {
return true;
}

bool TableMc68000::hasOperand(const CpuSpec &cpuSpec, AsmInsn &insn) const {
cpu(cpuSpec.cpu)->searchName(insn, acceptAll);
cpu(cpuSpec.cpu)->searchName(insn, Cpu::acceptAll<AsmInsn, Entry>);
#if !defined(LIBASM_MC68000_NOFPU)
if (!insn.isOK())
fpu(cpuSpec.fpu)->searchName(insn, acceptAll);
fpu(cpuSpec.fpu)->searchName(insn, Cpu::acceptAll<AsmInsn, Entry>);
#endif
return insn.isOK() && insn.src() != M_NONE;
}
Expand Down
6 changes: 1 addition & 5 deletions src/table_mc6805.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -455,12 +455,8 @@ static const Cpu *cpu(CpuType cpuType) {
return Cpu::search(cpuType, ARRAY_RANGE(CPU_TABLE));
}

static bool acceptAll(AsmInsn &, const Entry *) {
return true;
}

bool TableMc6805::hasOperand(CpuType cpuType, AsmInsn &insn) const {
cpu(cpuType)->searchName(insn, acceptAll);
cpu(cpuType)->searchName(insn, Cpu::acceptAll<AsmInsn, Entry>);
return insn.isOK() && insn.mode1() != M_NONE;
}

Expand Down
6 changes: 1 addition & 5 deletions src/table_mc6809.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -684,12 +684,8 @@ Error TableMc6809::searchName(CpuType cpuType, AsmInsn &insn) const {
return insn.getError();
}

static bool acceptAll(AsmInsn &, const Entry *) {
return true;
}

Error TableMc6809::hasName(CpuType cpuType, AsmInsn &insn) const {
cpu(cpuType)->searchName(insn, acceptAll);
cpu(cpuType)->searchName(insn, Cpu::acceptAll<AsmInsn, Entry>);
return insn.getError();
}

Expand Down
6 changes: 1 addition & 5 deletions src/table_mn1610.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -296,12 +296,8 @@ static const Cpu *cpu(CpuType cpuType) {
return Cpu::search(cpuType, ARRAY_RANGE(CPU_TABLE));
}

static bool acceptAll(AsmInsn &, const Entry *) {
return true;
}

bool TableMn1610::hasOperand(CpuType cpuType, AsmInsn &insn) const {
cpu(cpuType)->searchName(insn, acceptAll);
cpu(cpuType)->searchName(insn, Cpu::acceptAll<AsmInsn, Entry>);
return insn.isOK() && insn.mode1() != M_NONE;
}

Expand Down
6 changes: 1 addition & 5 deletions src/table_mos6502.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -713,12 +713,8 @@ static const Cpu *cpu(CpuType cpuType) {
return Cpu::search(cpuType, ARRAY_RANGE(CPU_TABLE));
}

static bool acceptAll(AsmInsn &, const Entry *) {
return true;
}

bool TableMos6502::hasOperand(CpuType cpuType, AsmInsn &insn) const {
cpu(cpuType)->searchName(insn, acceptAll);
cpu(cpuType)->searchName(insn, Cpu::acceptAll<AsmInsn, Entry>);
return insn.isOK() && insn.mode1() != M_NONE;
}

Expand Down
6 changes: 1 addition & 5 deletions src/table_pdp11.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -403,12 +403,8 @@ Error TablePdp11::searchName(CpuType cpuType, AsmInsn &insn) const {
return insn.getError();
}

static bool acceptAll(AsmInsn &, const Entry *) {
return true;
}

Error TablePdp11::hasName(CpuType cpuType, AsmInsn &insn) const {
cpu(cpuType)->searchName(insn, acceptAll);
cpu(cpuType)->searchName(insn, Cpu::acceptAll<AsmInsn, Entry>);
return insn.getError();
}

Expand Down
6 changes: 1 addition & 5 deletions src/table_pdp8.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -393,12 +393,8 @@ static const Cpu *cpu(CpuType cpuType) {
return Cpu::search(cpuType, ARRAY_RANGE(CPU_TABLE));
}

static bool acceptAll(AsmInsn &, const Entry *) {
return true;
}

Error TablePdp8::searchName(CpuType cpuType, AsmInsn &insn) const {
cpu(cpuType)->searchName(insn, acceptAll);
cpu(cpuType)->searchName(insn, Cpu::acceptAll<AsmInsn, Entry>);
return insn.getError();
}

Expand Down
6 changes: 1 addition & 5 deletions src/table_scn2650.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,12 +222,8 @@ static const Cpu *cpu(CpuType) {
return &CPU_TABLE[0];
}

static bool acceptAll(AsmInsn &, const Entry *) {
return true;
}

bool TableScn2650::hasOperand(CpuType cpuType, AsmInsn &insn) const {
cpu(cpuType)->searchName(insn, acceptAll);
cpu(cpuType)->searchName(insn, Cpu::acceptAll<AsmInsn, Entry>);
return insn.isOK() && insn.mode1() != M_NONE;
}

Expand Down
8 changes: 2 additions & 6 deletions src/table_tms7000.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ namespace libasm {
namespace tms7000 {

#define E3(_opc, _name, _opr1, _opr2, _opr3) \
{ _opc, Entry::Flags::create(_opr1, _opr2, _opr3), _name }
{_opc, Entry::Flags::create(_opr1, _opr2, _opr3), _name}
#define E2(_opc, _name, _opr1, _opr2) E3(_opc, _name, _opr1, _opr2, M_NONE)
#define E1(_opc, _name, _opr1) E2(_opc, _name, _opr1, M_NONE)
#define E0(_opc, _name) E1(_opc, _name, M_NONE)
Expand Down Expand Up @@ -477,12 +477,8 @@ static const Cpu *cpu(CpuType) {
return &CPU_TABLE[0];
}

static bool acceptAll(AsmInsn &, const Entry *) {
return true;
}

bool TableTms7000::hasOperand(CpuType cpuType, AsmInsn &insn) const {
cpu(cpuType)->searchName(insn, acceptAll);
cpu(cpuType)->searchName(insn, Cpu::acceptAll<AsmInsn, Entry>);
return insn.isOK() && insn.src() != M_NONE;
}

Expand Down
6 changes: 1 addition & 5 deletions src/table_tms9900.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -304,12 +304,8 @@ static const Cpu *cpu(CpuType cpuType) {
return Cpu::search(cpuType, ARRAY_RANGE(CPU_TABLE));
}

static bool acceptAll(AsmInsn &, const Entry *) {
return true;
}

bool TableTms9900::hasOperand(CpuType cpuType, AsmInsn &insn) const {
cpu(cpuType)->searchName(insn, acceptAll);
cpu(cpuType)->searchName(insn, Cpu::acceptAll<AsmInsn, Entry>);
return insn.isOK() && insn.src() != M_NONE;
}

Expand Down
2 changes: 1 addition & 1 deletion src/table_z8000.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -587,7 +587,7 @@ Error TableZ8000::searchOpCodeAlias(CpuType cpuType, DisInsn &insn, StrBuffer &o
auto entry = cpu(cpuType)->searchOpCode(insn, out, matchOpCode);
if (entry) {
entry++;
Cpu::defaultReadName(insn, entry, out, nullptr);
Cpu::defaultReadName(insn, entry, out);
}
return insn.getError();
}
Expand Down
Loading

0 comments on commit 1d6b050

Please sign in to comment.