Skip to content

Commit

Permalink
[WIP] Add LIBASM_DIS_NOFLOAT
Browse files Browse the repository at this point in the history
  • Loading branch information
tgtakaoka committed Sep 26, 2024
1 parent aafc578 commit 5a4becf
Show file tree
Hide file tree
Showing 20 changed files with 162 additions and 43 deletions.
3 changes: 3 additions & 0 deletions src/config_libasm.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
/** Disable floating point number support from assembler */
// #define LIBASM_ASM_NOFLOAT

/** Disable floating point number support from disassembler */
// #define LIBASM_DIS_NOFLOAT

/** Enable debugging functionality of Value class */
// #define LIBASM_DEBUG_VALUE

Expand Down
6 changes: 6 additions & 0 deletions src/dis_mc68000.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ void DisMc68000::decodeImmediateData(DisInsn &insn, StrBuffer &out, OprSize size
if (size != SZ_DUBL)
outHex32(out, insn.readUint32());
}
#ifndef LIBASM_DIS_NOFLOAT
} else if (size == SZ_SNGL) {
out.float32(insn.readFloat32());
} else if (size == SZ_DUBL) {
Expand All @@ -96,9 +97,12 @@ void DisMc68000::decodeImmediateData(DisInsn &insn, StrBuffer &out, OprSize size
outExtendedReal(out, insn.readExtendedReal());
} else if (size == SZ_PBCD) {
outDecimalString(out, insn.readDecimalString());
#endif
}
}

#ifndef LIBASM_DIS_NOFLOAT

bool ExtendedReal::isValid() const {
/**
* Extended Binary Real
Expand Down Expand Up @@ -202,6 +206,8 @@ StrBuffer &DisMc68000::outDecimalString(StrBuffer &out, const DecimalString &v)
return out.float80(float80_t::compose(false, exp, sig), 17);
}

#endif

void DisMc68000::decodeEffectiveAddr(
DisInsn &insn, StrBuffer &out, uint8_t mode, RegName reg, OprSize size) const {
if (mode == M_DREG || mode == M_AREG) {
Expand Down
2 changes: 2 additions & 0 deletions src/dis_mc68000.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,10 @@ struct DisMc68000 final : Disassembler, Config {
uint16_t opr16 = 0, Error opr16Error = OK) const;

StrBuffer &outHex32(StrBuffer &buf, uint32_t u32) const;
#ifndef LIBASM_DIS_NOFLOAT
StrBuffer &outExtendedReal(StrBuffer &buf, const ExtendedReal &v) const;
StrBuffer &outDecimalString(StrBuffer &buf, const DecimalString &v) const;
#endif

Error decodeImpl(DisMemory &memory, Insn &insn, StrBuffer &out) const override;
const ConfigBase &config() const override { return *this; }
Expand Down
2 changes: 2 additions & 0 deletions src/dis_ns32000.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ void DisNs32000::decodeImmediate(DisInsn &insn, StrBuffer &out, AddrMode mode) c
outDec(out, static_cast<int8_t>(insn.readByte()), -8);
} else if (size == SZ_BYTE) {
outHex(out, insn.readByte(), 8);
#ifndef LIBASM_DIS_NOFLOAT
} else if (mode == M_FENR || mode == M_FENW) {
if (size == SZ_OCTA) {
const auto float64 = insn.readFloat64Be();
Expand All @@ -231,6 +232,7 @@ void DisNs32000::decodeImmediate(DisInsn &insn, StrBuffer &out, AddrMode mode) c
out.letter('0').letter('f');
out.float32(float32);
}
#endif
} else if (size == SZ_WORD) {
outHex(out, insn.readUint16Be(), 16);
} else if (size == SZ_QUAD) {
Expand Down
4 changes: 4 additions & 0 deletions src/insn_base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,8 @@ uint64_t DisInsnBase::readUint64Le() {
return static_cast<uint64_t>(msw) << 32 | lsw;
}

#ifndef LIBASM_DIS_NOFLOAT

float80_t DisInsnBase::readFloat32Be() {
float32_t f32;
return float80_t(f32.set(readUint32Be()));
Expand All @@ -194,6 +196,8 @@ float80_t DisInsnBase::readFloat64Le() {
return float80_t(f64.set(readUint64Le()));
}

#endif

} // namespace libasm

// Local Variables:
Expand Down
4 changes: 4 additions & 0 deletions src/insn_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,7 @@ struct DisInsnBase : ErrorAt {
/** Read 64 bit little endian data */
uint64_t readUint64Le();

#ifndef LIBASM_DIS_NOFLOAT
/** Read 32 bit big endian floating point data */
float80_t readFloat32Be();

Expand All @@ -272,6 +273,7 @@ struct DisInsnBase : ErrorAt {

/** Read 64 bit little endian floating point data */
float80_t readFloat64Le();
#endif

protected:
Insn &_insn;
Expand Down Expand Up @@ -409,11 +411,13 @@ struct DisInsnImpl : DisInsnBase {
/** Read 64 bit data */
uint64_t readUint64() { return big ? readUint64Be() : readUint64Le(); }

#ifndef LIBASM_DIS_NOFLOAT
/** Read 32 bit floating point data */
float80_t readFloat32() { return big ? readFloat32Be() : readFloat32Le(); }

/** Read 64 bit floating point data */
float80_t readFloat64() { return big ? readFloat64Be() : readFloat64Le(); }
#endif

protected:
DisInsnImpl(Insn &insn, DisMemory &memory, const StrBuffer &out)
Expand Down
4 changes: 4 additions & 0 deletions src/insn_mc68000.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ struct AsmInsn final : AsmInsnImpl<Config>, EntryInsn {
InsnSize _isize;
};

#ifndef LIBASM_DIS_NOFLOAT
struct ExtendedReal {
uint16_t tag;
uint16_t pad;
Expand All @@ -105,6 +106,7 @@ struct DecimalString {
uint64_t sig;
bool isValid() const;
};
#endif

struct DisInsn final : DisInsnImpl<Config>, EntryInsn {
DisInsn(Insn &insn, DisMemory &memory, const StrBuffer &out) : DisInsnImpl(insn, memory, out) {}
Expand All @@ -115,8 +117,10 @@ struct DisInsn final : DisInsnImpl<Config>, EntryInsn {
setPostfix(readUint16());
}

#ifndef LIBASM_DIS_NOFLOAT
ExtendedReal readExtendedReal();
DecimalString readDecimalString();
#endif
};

} // namespace mc68000
Expand Down
4 changes: 4 additions & 0 deletions src/str_buffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ StrBuffer &StrBuffer::rtext_P(const /*PROGMEM*/ char *text_P) {
return *this;
}

#if !defined(LIBASM_ASM_NOFLOAT) || !defined(LIBASM_DIS_NOFLOAT)

StrBuffer &StrBuffer::float32(const float80_t &f80, uint_fast8_t prec) {
*_end = 1; // to check buffer overflow
const auto len = f80.gcvt(mark(), capacity() + 1, prec);
Expand Down Expand Up @@ -137,6 +139,8 @@ StrBuffer &StrBuffer::convert(size_t len) {
return *this;
}

#endif

StrBuffer &StrBuffer::comma() {
return rletter(',').rletter(' ');
}
Expand Down
6 changes: 6 additions & 0 deletions src/str_buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ struct StrBuffer : ErrorReporter {
/** Output |value| as decimal number. */
StrBuffer &int16(int16_t i16, uint_fast8_t prec = 0) { return dec(i16, prec); }

#if !defined(LIBASM_ASM_NOFLOAT) || !defined(LIBASM_DIS_NOFLOAT)

/**
* Output |value| as 32-bit floating point number.
* Significand is 23+1 bit and UINT24_MAX is 16777215 (8 digits).
Expand All @@ -133,6 +135,8 @@ struct StrBuffer : ErrorReporter {
*/
StrBuffer &float80(const float80_t &f80, uint_fast8_t prec = 21);

#endif

/** output ", " */
StrBuffer &comma();

Expand All @@ -144,7 +148,9 @@ struct StrBuffer : ErrorReporter {
char *_out;
char *_end;

#if !defined(LIBASM_ASM_NOFLOAT) || !defined(LIBASM_DIS_NOFLOAT)
StrBuffer &convert(size_t len);
#endif
};

/**
Expand Down
15 changes: 15 additions & 0 deletions src/table_i8086.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -819,6 +819,7 @@ static constexpr uint8_t V30INDEX_0F[] PROGMEM = {
6, // TEXT_SUB4S
};

#if !defined(LIBASM_ASM_NOFLOAT) || !defined(LIBASM_DIS_NOFLOAT)
static constexpr Entry TABLE_D8[] PROGMEM = {
F2(0xC0, TEXT_FADD, SZ_NONE, M_ST0, M_STI, P_NONE, P_OREG),
F2(0xC8, TEXT_FMUL, SZ_NONE, M_ST0, M_STI, P_NONE, P_OREG),
Expand Down Expand Up @@ -1097,6 +1098,8 @@ static constexpr uint8_t INDEX_FPU[] PROGMEM = {
0, // TEXT_FWAIT
};

#endif

// clang-format on

using EntryPage = entry::PrefixTableBase<Entry>;
Expand Down Expand Up @@ -1174,6 +1177,7 @@ static constexpr EntryPage V30_PAGES[] PROGMEM = {
{0xFF, ARRAY_RANGE(TABLE_FF), ARRAY_RANGE(INDEX_FF)},
};

#if !defined(LIBASM_ASM_NOFLOAT) || !defined(LIBASM_DIS_NOFLOAT)
static constexpr EntryPage I8087_PAGES[] PROGMEM = {
{0x00, ARRAY_RANGE(TABLE_FPU), ARRAY_RANGE(INDEX_FPU)},
{0xD8, ARRAY_RANGE(TABLE_D8), ARRAY_RANGE(INDEX_D8)},
Expand All @@ -1185,6 +1189,7 @@ static constexpr EntryPage I8087_PAGES[] PROGMEM = {
{0xDE, ARRAY_RANGE(TABLE_DE), ARRAY_RANGE(INDEX_DE)},
{0xDF, ARRAY_RANGE(TABLE_DF), ARRAY_RANGE(INDEX_DF)},
};
#endif

template <typename CPUTYPE>
using Processor = entry::CpuBase<CPUTYPE, EntryPage>;
Expand Down Expand Up @@ -1213,6 +1218,7 @@ static const Cpu *cpu(CpuType cpuType) {

#define EMPTY_RANGE(a) ARRAY_BEGIN(a), ARRAY_BEGIN(a)

#if !defined(LIBASM_ASM_NOFLOAT) || !defined(LIBASM_DIS_NOFLOAT)
static constexpr Fpu FPU_TABLE[] PROGMEM = {
{FPU_I8087, TEXT_FPU_8087, ARRAY_RANGE(I8087_PAGES)},
{FPU_NONE, TEXT_none, EMPTY_RANGE(I8087_PAGES)},
Expand All @@ -1221,6 +1227,7 @@ static constexpr Fpu FPU_TABLE[] PROGMEM = {
static const Fpu *fpu(FpuType fpuType) {
return Fpu::search(fpuType, ARRAY_RANGE(FPU_TABLE));
}
#endif

static bool acceptMode(AddrMode opr, AddrMode table) {
if (opr == table)
Expand Down Expand Up @@ -1291,6 +1298,7 @@ static bool acceptModes(AsmInsn &insn, const Entry *entry) {
static constexpr char TEXT_FN[] PROGMEM = "FN";

Error TableI8086::searchName(const CpuSpec &cpuSpec, AsmInsn &insn) const {
#if !defined(LIBASM_ASM_NOFLOAT)
fpu(cpuSpec.fpu)->searchName(insn, acceptModes);
if (insn.getError() == UNKNOWN_INSTRUCTION) {
// check non-wait version FNxxxx
Expand All @@ -1310,6 +1318,7 @@ Error TableI8086::searchName(const CpuSpec &cpuSpec, AsmInsn &insn) const {
insn.setFwait();
}
if (insn.getError() == UNKNOWN_INSTRUCTION)
#endif
cpu(cpuSpec.cpu)->searchName(insn, acceptModes);
return insn.getError();
}
Expand Down Expand Up @@ -1367,6 +1376,7 @@ static bool matchOpCode(DisInsn &insn, const Entry *entry, const EntryPage *page
}

Error TableI8086::searchOpCode(const CpuSpec &cpuSpec, DisInsn &insn, StrBuffer &out) const {
#if !defined(LIBASM_DIS_NOFLOAT)
fpu(cpuSpec.fpu)->searchOpCode(insn, out, matchOpCode);
if (insn.isOK()) {
if (insn.opCode() == DisInsn::FWAIT)
Expand All @@ -1382,6 +1392,7 @@ Error TableI8086::searchOpCode(const CpuSpec &cpuSpec, DisInsn &insn, StrBuffer
}
}
if (insn.getError() == UNKNOWN_INSTRUCTION && insn.fwait() == 0)
#endif
cpu(cpuSpec.cpu)->searchOpCode(insn, out, matchOpCode);
return insn.getError();
}
Expand All @@ -1391,7 +1402,11 @@ bool TableI8086::isPrefix(CpuType cpuType, Config::opcode_t code) const {
}

bool TableI8086::isPrefix(FpuType fpuType, Config::opcode_t code) const {
#if !defined(LIBASM_ASM_NOFLOAT) || !defined(LIBASM_DIS_NOFLOAT)
return fpu(fpuType)->isPrefix(code);
#else
return false;
#endif
}

const /*PROGMEM*/ char *TableI8086::listCpu_P() const {
Expand Down
14 changes: 14 additions & 0 deletions src/table_mc68000.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,8 @@ static constexpr uint8_t MC68000_INDEX[] PROGMEM = {
52, // TEXT_UNLK
};

#if !defined(LIBASM_ASM_NOFLOAT) || !defined(LIBASM_DIS_NOFLOAT)

static constexpr Entry MC68881_ARITH[] PROGMEM = {
P2(0xF000, TEXT_FMOVE, ISZ_FIXD, M_FPREG, M_FPREG, EX_RX, EX_RY, SZ_XTND, 0x0000),
P2(0xF000, TEXT_FINT, ISZ_FIXD, M_FPREG, M_FPREG, EX_RX, EX_RY, SZ_XTND, 0x0001),
Expand Down Expand Up @@ -1204,6 +1206,8 @@ static constexpr uint8_t MC68881_TRAP_INDEX[] PROGMEM = {
72, // TEXT_FTRAPUN
104, // TEXT_FTRAPUN
};

#endif
// clang-format on

using EntryPage = entry::TableBase<Entry>;
Expand All @@ -1227,11 +1231,13 @@ static constexpr EntryPage MC68000_PAGES[] PROGMEM = {
{ARRAY_RANGE(MC68000_TABLE), ARRAY_RANGE(MC68000_INDEX)},
};

#if !defined(LIBASM_ASM_NOFLOAT) || !defined(LIBASM_DIS_NOFLOAT)
static constexpr EntryPage MC68881_PAGES[] PROGMEM = {
{ARRAY_RANGE(MC68881_ARITH), ARRAY_RANGE(MC68881_ARITH_INDEX)},
{ARRAY_RANGE(MC68881_BRANCH), ARRAY_RANGE(MC68881_BRANCH_INDEX)},
{ARRAY_RANGE(MC68881_TRAP), ARRAY_RANGE(MC68881_TRAP_INDEX)},
};
#endif

static constexpr Cpu CPU_TABLE[] PROGMEM = {
{MC68000, TEXT_CPU_68000, ARRAY_RANGE(MC68000_PAGES)},
Expand All @@ -1244,6 +1250,7 @@ static const Cpu *cpu(CpuType cpuType) {

#define EMPTY_RANGE(a) ARRAY_BEGIN(a), ARRAY_BEGIN(a)

#if !defined(LIBASM_ASM_NOFLOAT)|| !defined(LIBASM_DIS_NOFLOAT)
static constexpr Fpu FPU_TABLE[] PROGMEM = {
{FPU_MC68881, TEXT_FPU_68881, ARRAY_RANGE(MC68881_PAGES)},
{FPU_NONE, TEXT_none, EMPTY_RANGE(MC68881_PAGES)},
Expand All @@ -1252,6 +1259,7 @@ static constexpr Fpu FPU_TABLE[] PROGMEM = {
static const Fpu *fpu(FpuType fpuType) {
return Fpu::search(fpuType, ARRAY_RANGE(FPU_TABLE));
}
#endif

static bool acceptAll(AsmInsn &insn, const Entry *entry) {
UNUSED(insn);
Expand All @@ -1261,8 +1269,10 @@ static bool acceptAll(AsmInsn &insn, const Entry *entry) {

bool TableMc68000::hasOperand(const CpuSpec &cpuSpec, AsmInsn &insn) const {
cpu(cpuSpec.cpu)->searchName(insn, acceptAll);
#if !defined(LIBASM_ASM_NOFLOAT)
if (!insn.isOK())
fpu(cpuSpec.fpu)->searchName(insn, acceptAll);
#endif
return insn.isOK() && insn.src() != M_NONE;
}

Expand Down Expand Up @@ -1333,11 +1343,13 @@ static bool acceptModes(AsmInsn &insn, const Entry *entry) {

Error TableMc68000::searchName(const CpuSpec &cpuSpec, AsmInsn &insn) const {
cpu(cpuSpec.cpu)->searchName(insn, acceptModes);
#if !defined(LIBASM_ASM_NOFLOAT)
if (insn.getError() == UNKNOWN_INSTRUCTION) {
fpu(cpuSpec.fpu)->searchName(insn, acceptModes);
if (insn.getError() != UNKNOWN_INSTRUCTION)
insn.embed(cpuSpec.fpuCid << 9);
}
#endif
return insn.getError();
}

Expand Down Expand Up @@ -1483,10 +1495,12 @@ static bool matchOpCode(DisInsn &insn, const Entry *entry, const EntryPage *page

Error TableMc68000::searchOpCode(const CpuSpec &cpuSpec, DisInsn &insn, StrBuffer &out) const {
cpu(cpuSpec.cpu)->searchOpCode(insn, out, matchOpCode);
#if !defined(LIBASM_DIS_NOFLOAT)
if (insn.getError() == UNKNOWN_INSTRUCTION) {
if ((insn.opCode() & 0xFE00) == (0xF000 | (cpuSpec.fpuCid << 9)))
fpu(cpuSpec.fpu)->searchOpCode(insn, out, matchOpCode);
}
#endif
if (insn.getError() == UNKNOWN_INSTRUCTION)
insn.nameBuffer().reset();
return insn.getError();
Expand Down
Loading

0 comments on commit 5a4becf

Please sign in to comment.