Skip to content

Commit

Permalink
[MC68000] Add MC68881 FPU disassembler
Browse files Browse the repository at this point in the history
  • Loading branch information
tgtakaoka committed Dec 31, 2023
1 parent d4d11d9 commit e3582d3
Show file tree
Hide file tree
Showing 22 changed files with 27,831 additions and 21,235 deletions.
41 changes: 35 additions & 6 deletions src/asm_mc68000.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
#include "asm_mc68000.h"

#include "table_mc68000.h"
#include "text_common.h"
#include "text_mc68000.h"

namespace libasm {
namespace mc68000 {
Expand All @@ -26,6 +26,11 @@ using namespace pseudo;
using namespace reg;
using namespace text::common;

using text::mc68000::TEXT_FPU;
using text::mc68000::TEXT_FPU_68881;
using text::mc68000::TEXT_FPU_MC68881;
using text::mc68000::TEXT_none;

namespace {

// clang-format off
Expand Down Expand Up @@ -77,6 +82,22 @@ AsmMc68000::AsmMc68000(const ValueParser::Plugins &plugins)
reset();
}

void AsmMc68000::reset() {
Assembler::reset();
setFpuType(FPU_NONE);
}

Error AsmMc68000::setFpu(StrScanner &scan) {
if (scan.iequals_P(TEXT_FPU_68881) || scan.iequals_P(TEXT_FPU_MC68881)) {
setFpuType(FPU_MC68881);
} else if (scan.iequals_P(TEXT_none)) {
setFpuType(FPU_NONE);
} else {
return UNKNOWN_OPERAND;
}
return OK;
}

namespace {

int8_t modePos(OprPos pos) {
Expand Down Expand Up @@ -260,11 +281,10 @@ Error AsmMc68000::emitEffectiveAddr(
// "Zero means 2^3" unsigned 3-bit.
if (op.val32 > 8)
insn.setErrorIf(op, OVERFLOW_RANGE);
if (op.val32 == 0 && op.getError() == OK)
if (op.val32 == 0 && op.isOK())
insn.setErrorIf(op, OPERAND_NOT_ALLOWED);
const Config::opcode_t count = (op.val32 & 7); // 8 is encoded to 0.
const Config::opcode_t data = op.getError() ? 0 : (count << 9);
insn.embed(data);
const auto count = (op.val32 & 7); // 8 is encoded to 0.
insn.embed(count << 9);
break;
}
if (mode == M_IM8) {
Expand Down Expand Up @@ -474,6 +494,15 @@ InsnSize AsmInsn::parseInsnSize() {
return isize;
}

Error AsmMc68000::processPseudo(StrScanner &scan, Insn &insn) {
const auto at = scan;
if (strcasecmp_P(insn.name(), TEXT_FPU) == 0) {
const auto error = _opt_fpu.set(scan);
return error ? insn.setErrorIf(at, error) : OK;
}
return Assembler::processPseudo(scan, insn);
}

Error AsmMc68000::encodeImpl(StrScanner &scan, Insn &_insn) const {
AsmInsn insn(_insn);
const auto isize = insn.parseInsnSize();
Expand All @@ -488,7 +517,7 @@ Error AsmMc68000::encodeImpl(StrScanner &scan, Insn &_insn) const {
scan.skipSpaces();
}

if (_insn.setErrorIf(insn.srcOp, TABLE.searchName(cpuType(), insn)))
if (_insn.setErrorIf(insn.srcOp, TABLE.searchName(_cpuSpec, insn)))
return _insn.getError();

insn.setErrorIf(insn.srcOp);
Expand Down
5 changes: 5 additions & 0 deletions src/asm_mc68000.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ namespace mc68000 {
struct AsmMc68000 final : Assembler, Config {
AsmMc68000(const ValueParser::Plugins &plugins = defaultPlugins());

void reset() override;

Error setFpu(StrScanner &scan) override;

private:
Error parseOperand(StrScanner &scan, Operand &op) const;
Error checkAlignment(AsmInsn &insn, OprSize size, const Operand &op) const;
Expand All @@ -39,6 +43,7 @@ struct AsmMc68000 final : Assembler, Config {
Error emitEffectiveAddr(
AsmInsn &insn, OprSize size, const Operand &op, AddrMode mode, OprPos pos) const;

Error processPseudo(StrScanner &scan, Insn &insn) override;
Error encodeImpl(StrScanner &scan, Insn &insn) const override;
const ConfigBase &config() const override { return *this; }
ConfigSetter &configSetter() override { return *this; }
Expand Down
28 changes: 26 additions & 2 deletions src/config_mc68000.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,32 @@ enum CpuType : uint8_t {
MC68000,
};

struct Config : ConfigImpl<CpuType, ADDRESS_24BIT, ADDRESS_BYTE, OPCODE_16BIT, ENDIAN_BIG, 10, 7> {
Config(const InsnTable<CpuType> &table) : ConfigImpl(table, MC68000) {}
enum FpuType : uint8_t {
FPU_NONE,
FPU_MC68881,
};

struct CpuSpec final {
CpuSpec(CpuType cpu_, FpuType fpu_, uint8_t fpuCid_) : cpu(cpu_), fpu(fpu_), fpuCid(fpuCid_) {}
CpuType cpu;
FpuType fpu;
uint8_t fpuCid; // FPU co-processor ID
};

struct Config : ConfigImpl<CpuType, ADDRESS_24BIT, ADDRESS_BYTE, OPCODE_16BIT, ENDIAN_BIG, 16, 7> {
Config(const InsnTable<CpuType> &table)
: ConfigImpl(table, MC68000), _cpuSpec(MC68000, FPU_MC68881, 1) {}

void setCpuType(CpuType cpuType) override {
_cpuSpec.cpu = cpuType;
ConfigImpl::setCpuType(cpuType);
}
void setFpuType(FpuType fpuType) { _cpuSpec.fpu = fpuType; }
// TODO: Add option
void setFpuId(uint8_t id) { _cpuSpec.fpuCid = id; }

protected:
CpuSpec _cpuSpec;
};

} // namespace mc68000
Expand Down
Loading

0 comments on commit e3582d3

Please sign in to comment.