stmt_ins: refactor

The overall intent is to make writing a decompiler require less code
duplication.

"bits.hpp" and "stmt_enum.hpp" are replaced with "stmt_ins.hpp" which
is generated directly from dsp-notes.csv.
This commit is contained in:
Zack Buhman 2023-09-03 04:46:34 +00:00
parent 2d047c6c54
commit ddf46ce8fd
32 changed files with 2683 additions and 907 deletions

3
.gitignore vendored
View File

@ -7,4 +7,5 @@ scu-dsp-asm.*
*.d
test/*.s
test/*.txt
*.bin
*.bin
__pycache__

View File

@ -3,7 +3,7 @@ CXXFLAGS = -Og -g -Wall -Wextra -Werror -Wfatal-errors -Wno-c99-designator -std=
LDFLAGS =
TARGET ?=
CXX = $(TARGET)g++
CXX = $(TARGET)clang++
SRC = main.cpp
SRC += lexer.cpp

View File

@ -89,9 +89,59 @@ uint32_t emitter_t::visit(const unary_t * unary) const
// instructions
uint32_t emitter_t::visit(const op::alu_t * alu) const
uint32_t emitter_t::visit(const op::andl_t * andl) const
{
return alu->code() | alu->bits();
return andl->code() | andl->bits();
}
uint32_t emitter_t::visit(const op::orl_t * orl) const
{
return orl->code() | orl->bits();
}
uint32_t emitter_t::visit(const op::xorl_t * xorl) const
{
return xorl->code() | xorl->bits();
}
uint32_t emitter_t::visit(const op::add_t * add) const
{
return add->code() | add->bits();
}
uint32_t emitter_t::visit(const op::sub_t * sub) const
{
return sub->code() | sub->bits();
}
uint32_t emitter_t::visit(const op::ad2_t * ad2) const
{
return ad2->code() | ad2->bits();
}
uint32_t emitter_t::visit(const op::sr_t * sr) const
{
return sr->code() | sr->bits();
}
uint32_t emitter_t::visit(const op::rr_t * rr) const
{
return rr->code() | rr->bits();
}
uint32_t emitter_t::visit(const op::sl_t * sl) const
{
return sl->code() | sl->bits();
}
uint32_t emitter_t::visit(const op::rl_t * rl) const
{
return rl->code() | rl->bits();
}
uint32_t emitter_t::visit(const op::rl8_t * rl8) const
{
return rl8->code() | rl8->bits();
}
uint32_t emitter_t::visit(const op::mov_ram_x_t * mov_ram_x) const
@ -146,7 +196,9 @@ uint32_t emitter_t::visit(const op::mov_ram_d1_t * mov_ram_d1) const
uint32_t emitter_t::visit(const op::control_word_t * control_word) const
{
uint32_t word = control_word->code() | control_word->bits();
for (auto& op : control_word->ops) { word |= dynamic_cast<const stmt_t *>(op)->accept(this); }
for (const auto& op : control_word->ops) {
word |= std::visit([*this](auto&& arg) -> uint32_t { return (arg).accept(this); }, op);
}
return word;
}

View File

@ -7,6 +7,8 @@
#include "visitor.hpp"
#include "expr.hpp"
#include "stmt.hpp"
#include "stmt_ins.hpp"
#include "control_word.hpp"
#include "ast.hpp"
namespace dsp {
@ -33,7 +35,18 @@ struct emitter_t : visitor_t<uint32_t>
uint32_t visit(const literal_t * literal) const;
uint32_t visit(const unary_t * unary) const;
uint32_t visit(const op::alu_t * alu) const;
uint32_t visit(const op::andl_t * andl) const;
uint32_t visit(const op::orl_t * orl) const;
uint32_t visit(const op::xorl_t * xorl) const;
uint32_t visit(const op::add_t * add) const;
uint32_t visit(const op::sub_t * sub) const;
uint32_t visit(const op::ad2_t * ad2) const;
uint32_t visit(const op::sr_t * sr) const;
uint32_t visit(const op::rr_t * rr) const;
uint32_t visit(const op::sl_t * sl) const;
uint32_t visit(const op::rl_t * rl) const;
uint32_t visit(const op::rl8_t * rl8) const;
uint32_t visit(const op::mov_ram_x_t * mov_ram_x) const;
uint32_t visit(const op::mov_mul_p_t * mov_mul_p) const;
uint32_t visit(const op::mov_ram_p_t * mov_ram_p) const;

View File

@ -1,5 +1,6 @@
#include "ast_printer.hpp"
#include "stmt_string.hpp"
#include "control_word.hpp"
namespace dsp {
@ -96,14 +97,75 @@ void printer_t::parenthesize(const std::string_view s, const expr_t * a, const e
// instructions
void printer_t::visit(const op::alu_t * alu) const
void printer_t::visit(const op::andl_t * andl) const
{
parenthesize(op::alu_type_string[static_cast<int>(alu->type)]);
(void)andl;
parenthesize("andl");
}
void printer_t::visit(const op::orl_t * orl) const
{
(void)orl;
parenthesize("orl");
}
void printer_t::visit(const op::xorl_t * xorl) const
{
(void)xorl;
parenthesize("xorl");
}
void printer_t::visit(const op::add_t * add) const
{
(void)add;
parenthesize("add");
}
void printer_t::visit(const op::sub_t * sub) const
{
(void)sub;
parenthesize("sub");
}
void printer_t::visit(const op::ad2_t * ad2) const
{
(void)ad2;
parenthesize("ad2");
}
void printer_t::visit(const op::sr_t * sr) const
{
(void)sr;
parenthesize("sr");
}
void printer_t::visit(const op::rr_t * rr) const
{
(void)rr;
parenthesize("rr");
}
void printer_t::visit(const op::sl_t * sl) const
{
(void)sl;
parenthesize("sl");
}
void printer_t::visit(const op::rl_t * rl) const
{
(void)rl;
parenthesize("rl");
}
void printer_t::visit(const op::rl8_t * rl8) const
{
(void)rl8;
parenthesize("rl8");
}
void printer_t::visit(const op::mov_ram_x_t * mov_ram_x) const
{
parenthesize("mov", op::xy_src_string[static_cast<int>(mov_ram_x->src)], "x");
parenthesize("mov", op::x_src_string[static_cast<int>(mov_ram_x->src.value)], "x");
}
void printer_t::visit(const op::mov_mul_p_t * mov_mul_p) const
@ -114,12 +176,12 @@ void printer_t::visit(const op::mov_mul_p_t * mov_mul_p) const
void printer_t::visit(const op::mov_ram_p_t * mov_ram_p) const
{
parenthesize("mov", op::xy_src_string[static_cast<int>(mov_ram_p->src)], "p");
parenthesize("mov", op::x_src_string[static_cast<int>(mov_ram_p->src.value)], "p");
}
void printer_t::visit(const op::mov_ram_y_t * mov_ram_y) const
{
parenthesize("mov", op::xy_src_string[static_cast<int>(mov_ram_y->src)], "y");
parenthesize("mov", op::y_src_string[static_cast<int>(mov_ram_y->src.value)], "y");
}
void printer_t::visit(const op::clr_a_t * clr_a) const
@ -136,28 +198,28 @@ void printer_t::visit(const op::mov_alu_a_t * mov_alu_a) const
void printer_t::visit(const op::mov_ram_a_t * mov_ram_a) const
{
parenthesize("mov", op::xy_src_string[static_cast<int>(mov_ram_a->src)], "a");
parenthesize("mov", op::y_src_string[static_cast<int>(mov_ram_a->src.value)], "a");
}
void printer_t::visit(const op::mov_imm_d1_t * mov_imm_d1) const
{
parenthesize("mov",
mov_imm_d1->imm.expr,
op::d1_dest_string[static_cast<int>(mov_imm_d1->dest)]);
op::d1_dst_string[static_cast<int>(mov_imm_d1->dst.value)]);
}
void printer_t::visit(const op::mov_ram_d1_t * mov_ram_d1) const
{
parenthesize("mov",
op::d1_src_string[static_cast<int>(mov_ram_d1->src)],
op::d1_dest_string[static_cast<int>(mov_ram_d1->dest)]);
op::d1_src_string[static_cast<int>(mov_ram_d1->src.value)],
op::d1_dst_string[static_cast<int>(mov_ram_d1->dst.value)]);
}
void printer_t::visit(const op::control_word_t * control_word) const
{
os << "(control_word ";
for (const auto& op : control_word->ops) {
dynamic_cast<const stmt_t *>(op)->accept(this);
std::visit([*this](auto&& arg){ (arg).accept(this); }, op);
os << ' ';
}
os << ')';
@ -165,27 +227,27 @@ void printer_t::visit(const op::control_word_t * control_word) const
void printer_t::visit(const load::mvi_t * mvi) const
{
parenthesize("mvi", mvi->imm.expr, load::dest_string[static_cast<int>(mvi->dest)]);
parenthesize("mvi", mvi->imm.expr, load::dst_string[static_cast<int>(mvi->dst.value)]);
}
void printer_t::visit(const load::mvi_cond_t * mvi_cond) const
{
parenthesize("mvi",
mvi_cond->imm.expr,
load::dest_string[static_cast<int>(mvi_cond->dest)],
load::cond_string[static_cast<int>(mvi_cond->cond)]);
load::dst_string[static_cast<int>(mvi_cond->dst.value)],
load::cond_string[static_cast<int>(mvi_cond->cond.value)]);
}
static std::string dma_hold_add(bool hold, dma::add_mode_t add)
static std::string dma_hold_add(dma::hold_t hold, dma::add_t add)
{
return dma::hold_mode_string[static_cast<int>(hold)]
+ dma::add_mode_string[static_cast<int>(add)];
return dma::hold_mode_string[static_cast<int>(hold.value)]
+ dma::add_mode_string[static_cast<int>(add.value)];
}
void printer_t::visit(const dma::src_d0_imm_t * src_d0_imm) const
{
parenthesize(dma_hold_add(src_d0_imm->hold, src_d0_imm->add),
dma::src_string[static_cast<int>(src_d0_imm->src)],
dma::src_string[static_cast<int>(src_d0_imm->src.value)],
"d0",
src_d0_imm->imm.expr);
}
@ -194,24 +256,24 @@ void printer_t::visit(const dma::d0_dst_imm_t * d0_dst_imm) const
{
parenthesize(dma_hold_add(d0_dst_imm->hold, d0_dst_imm->add),
"d0",
dma::dst_string[static_cast<int>(d0_dst_imm->dst)],
dma::dst_string[static_cast<int>(d0_dst_imm->dst.value)],
d0_dst_imm->imm.expr);
}
void printer_t::visit(const dma::src_d0_ram_t * src_d0_ram) const
{
parenthesize(dma_hold_add(src_d0_ram->hold, src_d0_ram->add),
dma::src_string[static_cast<int>(src_d0_ram->src)],
dma::src_string[static_cast<int>(src_d0_ram->src.value)],
"d0",
dma::length_ram_string[static_cast<int>(src_d0_ram->ram)]);
dma::length_ram_string[static_cast<int>(src_d0_ram->ram.value)]);
}
void printer_t::visit(const dma::d0_dst_ram_t * d0_dst_ram) const
{
parenthesize(dma_hold_add(d0_dst_ram->hold, d0_dst_ram->add),
"d0",
dma::dst_string[static_cast<int>(d0_dst_ram->dst)],
dma::length_ram_string[static_cast<int>(d0_dst_ram->ram)]);
dma::dst_string[static_cast<int>(d0_dst_ram->dst.value)],
dma::length_ram_string[static_cast<int>(d0_dst_ram->ram.value)]);
}
void printer_t::visit(const jump::jmp_t * jmp) const
@ -222,7 +284,7 @@ void printer_t::visit(const jump::jmp_t * jmp) const
void printer_t::visit(const jump::jmp_cond_t * jmp_cond) const
{
parenthesize("jmp",
jump::cond_string[static_cast<int>(jmp_cond->cond)],
jump::cond_string[static_cast<int>(jmp_cond->cond.value)],
jmp_cond->imm.expr);
}

View File

@ -7,6 +7,7 @@
#include "expr.hpp"
#include "num.hpp"
#include "stmt.hpp"
#include "stmt_ins.hpp"
namespace dsp {
@ -25,7 +26,18 @@ struct printer_t : visitor_t<void>
void visit(const literal_t * literal) const;
void visit(const unary_t * unary) const;
void visit(const op::alu_t * alu) const;
void visit(const op::andl_t * andl) const;
void visit(const op::orl_t * orl) const;
void visit(const op::xorl_t * xorl) const;
void visit(const op::add_t * add) const;
void visit(const op::sub_t * sub) const;
void visit(const op::ad2_t * ad2) const;
void visit(const op::sr_t * sr) const;
void visit(const op::rr_t * rr) const;
void visit(const op::sl_t * sl) const;
void visit(const op::rl_t * rl) const;
void visit(const op::rl8_t * rl8) const;
void visit(const op::mov_ram_x_t * mov_ram_x) const;
void visit(const op::mov_mul_p_t * mov_mul_p) const;
void visit(const op::mov_ram_p_t * mov_ram_p) const;

View File

@ -33,9 +33,59 @@ void resolver_t::visit(const unary_t * unary) const
// instructions
void resolver_t::visit(const op::alu_t * alu) const
void resolver_t::visit(const op::andl_t * andl) const
{
(void)alu;
(void)andl;
}
void resolver_t::visit(const op::orl_t * orl) const
{
(void)orl;
}
void resolver_t::visit(const op::xorl_t * xorl) const
{
(void)xorl;
}
void resolver_t::visit(const op::add_t * add) const
{
(void)add;
}
void resolver_t::visit(const op::sub_t * sub) const
{
(void)sub;
}
void resolver_t::visit(const op::ad2_t * ad2) const
{
(void)ad2;
}
void resolver_t::visit(const op::sr_t * sr) const
{
(void)sr;
}
void resolver_t::visit(const op::rr_t * rr) const
{
(void)rr;
}
void resolver_t::visit(const op::sl_t * sl) const
{
(void)sl;
}
void resolver_t::visit(const op::rl_t * rl) const
{
(void)rl;
}
void resolver_t::visit(const op::rl8_t * rl8) const
{
(void)rl8;
}
void resolver_t::visit(const op::mov_ram_x_t * mov_ram_x) const

View File

@ -37,7 +37,18 @@ struct resolver_t : visitor_t<void>
void visit(const literal_t * literal) const;
void visit(const unary_t * unary) const;
void visit(const op::alu_t * alu) const;
void visit(const op::andl_t * andl) const;
void visit(const op::orl_t * orl) const;
void visit(const op::xorl_t * xorl) const;
void visit(const op::add_t * add) const;
void visit(const op::sub_t * sub) const;
void visit(const op::ad2_t * ad2) const;
void visit(const op::sr_t * sr) const;
void visit(const op::rr_t * rr) const;
void visit(const op::sl_t * sl) const;
void visit(const op::rl_t * rl) const;
void visit(const op::rl8_t * rl8) const;
void visit(const op::mov_ram_x_t * mov_ram_x) const;
void visit(const op::mov_mul_p_t * mov_mul_p) const;
void visit(const op::mov_ram_p_t * mov_ram_p) const;

222
bits.hpp
View File

@ -1,222 +0,0 @@
namespace dsp {
namespace op {
static uint32_t alu_bits(alu_type_t type)
{
using enum alu_type_t;
switch (type) {
case alu_type_t::andl: return 0b0001 << 26;
case alu_type_t::orl: return 0b0010 << 26;
case alu_type_t::xorl: return 0b0011 << 26;
case alu_type_t::add: return 0b0100 << 26;
case alu_type_t::sub: return 0b0101 << 26;
case alu_type_t::ad2: return 0b0110 << 26;
case alu_type_t::sr: return 0b1000 << 26;
case alu_type_t::rr: return 0b1001 << 26;
case alu_type_t::sl: return 0b1010 << 26;
case alu_type_t::rl: return 0b1011 << 26;
case alu_type_t::rl8: return 0b1111 << 26;
default: __builtin_unreachable();
}
}
static uint32_t xy_src_bits(xy_src_t src, int shift)
{
using enum xy_src_t;
switch (src) {
case m0: return 0b000 << shift;
case m1: return 0b001 << shift;
case m2: return 0b010 << shift;
case m3: return 0b011 << shift;
case mc0: return 0b100 << shift;
case mc1: return 0b101 << shift;
case mc2: return 0b110 << shift;
case mc3: return 0b111 << shift;
default: __builtin_unreachable();
}
}
static uint32_t d1_dest_bits(d1_dest_t dest)
{
using enum d1_dest_t;
switch (dest) {
case mc0: return 0b0000 << 8;
case mc1: return 0b0001 << 8;
case mc2: return 0b0010 << 8;
case mc3: return 0b0011 << 8;
case rx: return 0b0100 << 8;
case pl: return 0b0101 << 8;
case ra0: return 0b0110 << 8;
case wa0: return 0b0111 << 8;
case lop: return 0b1010 << 8;
case top: return 0b1011 << 8;
case ct0: return 0b1100 << 8;
case ct1: return 0b1101 << 8;
case ct2: return 0b1110 << 8;
case ct3: return 0b1111 << 8;
default: __builtin_unreachable();
}
}
static uint32_t d1_src_bits(d1_src_t src)
{
using enum d1_src_t;
switch (src) {
case m0: return 0b0000 << 0;
case m1: return 0b0001 << 0;
case m2: return 0b0010 << 0;
case m3: return 0b0011 << 0;
case mc0: return 0b0100 << 0;
case mc1: return 0b0101 << 0;
case mc2: return 0b0110 << 0;
case mc3: return 0b0111 << 0;
case all: return 0b1001 << 0;
case alh: return 0b1010 << 0;
default: __builtin_unreachable();
}
}
} // op
namespace load {
static uint32_t dest_bits(dest_t dest)
{
using enum dest_t;
switch (dest) {
case mc0: return 0b0000 << 26;
case mc1: return 0b0001 << 26;
case mc2: return 0b0010 << 26;
case mc3: return 0b0011 << 26;
case rx: return 0b0100 << 26;
case pl: return 0b0101 << 26;
case ra0: return 0b0110 << 26;
case wa0: return 0b0111 << 26;
case lop: return 0b1010 << 26;
case pc: return 0b1100 << 26;
default: __builtin_unreachable();
}
}
static uint32_t cond_bits(cond_t cond)
{
using enum cond_t;
switch (cond) {
case z: return 0b1'0'0001 << 19;
case nz: return 0b0'0'0001 << 19;
case s: return 0b1'0'0010 << 19;
case ns: return 0b0'0'0010 << 19;
case c: return 0b1'0'0100 << 19;
case nc: return 0b0'0'0100 << 19;
case t0: return 0b1'0'1000 << 19;
case nt0: return 0b0'0'1000 << 19;
case zs: return 0b1'0'0011 << 19;
case nzs: return 0b0'0'0011 << 19;
default: __builtin_unreachable();
}
}
} // load
namespace dma {
static uint32_t add_mode_bits(add_mode_t add)
{
using enum add_mode_t;
switch (add) {
case _0 : return 0b000 << 15;
case _1 : return 0b001 << 15;
case _2 : return 0b010 << 15;
case _4 : return 0b011 << 15;
case _8 : return 0b100 << 15;
case _16: return 0b101 << 15;
case _32: return 0b110 << 15;
case _64: return 0b111 << 15;
default: __builtin_unreachable();
}
}
static uint32_t hold_bits(bool hold)
{
return hold ? (1 << 14)
: (0 << 14)
;
}
static uint32_t src_bits(src_t src)
{
using enum src_t;
switch (src) {
case mc0: return 0b000 << 8;
case mc1: return 0b001 << 8;
case mc2: return 0b010 << 8;
case mc3: return 0b011 << 8;
default: __builtin_unreachable();
}
}
static uint32_t dst_bits(dst_t dst)
{
using enum dst_t;
switch (dst) {
case mc0: return 0b000 << 8;
case mc1: return 0b001 << 8;
case mc2: return 0b010 << 8;
case mc3: return 0b011 << 8;
case prg: return 0b100 << 8;
default: __builtin_unreachable();
}
}
static uint32_t length_ram_bits(length_ram_t ram)
{
using enum length_ram_t;
switch (ram) {
case m0 : return 0b000 << 0;
case m1 : return 0b001 << 0;
case m2 : return 0b010 << 0;
case m3 : return 0b011 << 0;
case mc0: return 0b100 << 0;
case mc1: return 0b101 << 0;
case mc2: return 0b110 << 0;
case mc3: return 0b111 << 0;
default: __builtin_unreachable();
}
}
} // dma
namespace jump {
static uint32_t cond_bits(cond_t cond)
{
using enum cond_t;
switch (cond) {
case z : return 0b100'001 << 19;
case nz : return 0b000'001 << 19;
case s : return 0b100'010 << 19;
case ns : return 0b000'010 << 19;
case c : return 0b100'100 << 19;
case nc : return 0b000'100 << 19;
case t0 : return 0b101'000 << 19;
case nt0: return 0b001'000 << 19;
case zs : return 0b100'011 << 19;
case nzs: return 0b000'011 << 19;
default: __builtin_unreachable();
}
}
} // jump
} // dsp

84
control_word.hpp Normal file
View File

@ -0,0 +1,84 @@
#pragma once
#include <cstdint>
#include <variant>
#include <vector>
#include <utility>
#include "stmt_base.hpp"
#include "stmt_ins.hpp"
namespace dsp {
namespace op {
using op_t = std::variant<andl_t,
orl_t,
xorl_t,
add_t,
sub_t,
ad2_t,
sr_t,
rr_t,
sl_t,
rl_t,
rl8_t,
mov_ram_x_t,
mov_mul_p_t,
mov_ram_p_t,
mov_ram_y_t,
clr_a_t,
mov_alu_a_t,
mov_ram_a_t,
mov_imm_d1_t,
mov_ram_d1_t>;
struct control_word_t : stmt_accept_t<control_word_t>
{
control_word_t(std::vector<op_t> ops)
: ops(ops)
{
}
std::vector<op_t> build_ops(uint32_t code)
{
std::vector<op_t> ops;
if (andl_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<andl_t>, code});
else if (orl_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<orl_t>, code});
else if (xorl_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<xorl_t>, code});
else if (add_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<add_t>, code});
else if (sub_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<sub_t>, code});
else if (ad2_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<ad2_t>, code});
else if (sr_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<sr_t>, code});
else if (rr_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<rr_t>, code});
else if (sl_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<sl_t>, code});
else if (rl_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<rl_t>, code});
else if (rl8_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<rl8_t>, code});
else if (mov_ram_x_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<mov_ram_x_t>, code});
else if (mov_mul_p_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<mov_mul_p_t>, code});
else if (mov_ram_p_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<mov_ram_p_t>, code});
else if (mov_ram_y_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<mov_ram_y_t>, code});
else if (clr_a_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<clr_a_t>, code});
else if (mov_alu_a_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<mov_alu_a_t>, code});
else if (mov_ram_a_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<mov_ram_a_t>, code});
else if (mov_imm_d1_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<mov_imm_d1_t>, code});
else if (mov_ram_d1_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<mov_ram_d1_t>, code});
else {
std::cerr << "invalid control word code: " << (code) << std::endl;
throw std::runtime_error("invalid control word code");
}
return ops;
}
control_word_t(uint32_t code)
: ops(build_ops(code)) {}
const std::vector<op_t> ops;
uint32_t mask() const { return 0b11 << 30; }
uint32_t code() const { return 0b00 << 30; }
uint32_t bits() const { return 0; }
};
}
}

158
dsp-notes.csv Normal file
View File

@ -0,0 +1,158 @@
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0,
"OP",,,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,"ALU",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,"struct andl",,,0,0,0,1,,,,,,,,,,,,,,,,,,,,,,,,,,,1
,,"struct orl",,,0,0,1,0,,,,,,,,,,,,,,,,,,,,,,,,,,,2
,,"struct xorl",,,0,0,1,1,,,,,,,,,,,,,,,,,,,,,,,,,,,3
,,"struct add",,,0,1,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,4
,,"struct sub",,,0,1,0,1,,,,,,,,,,,,,,,,,,,,,,,,,,,5
,,"struct ad2",,,0,1,1,0,,,,,,,,,,,,,,,,,,,,,,,,,,,6
,,"struct sr",,,1,0,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,8
,,"struct rr",,,1,0,0,1,,,,,,,,,,,,,,,,,,,,,,,,,,,9
,,"struct sl",,,1,0,1,0,,,,,,,,,,,,,,,,,,,,,,,,,,,10
,,"struct rl",,,1,0,1,1,,,,,,,,,,,,,,,,,,,,,,,,,,,11
,,"struct rl8",,,1,1,1,1,,,,,,,,,,,,,,,,,,,,,,,,,,,15
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,"X-bus","enum x_src",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,"m0",,,,,,,,,,0,0,0,,,,,,,,,,,,,,,,,,,,,
,,"m1",,,,,,,,,,0,0,1,,,,,,,,,,,,,,,,,,,,,
,,"m2",,,,,,,,,,0,1,0,,,,,,,,,,,,,,,,,,,,,
,,"m3",,,,,,,,,,0,1,1,,,,,,,,,,,,,,,,,,,,,
,,"mc0",,,,,,,,,,1,0,0,,,,,,,,,,,,,,,,,,,,,
,,"mc1",,,,,,,,,,1,0,1,,,,,,,,,,,,,,,,,,,,,
,,"mc2",,,,,,,,,,1,1,0,,,,,,,,,,,,,,,,,,,,,
,,"mc3",,,,,,,,,,1,1,1,,,,,,,,,,,,,,,,,,,,,
,,"struct mov_ram_x",,,,,,,1,,,"x_src",,,,,,,,,,,,,,,,,,,,,,,
,,"struct mov_mul_p",,,,,,,,1,0,,,,,,,,,,,,,,,,,,,,,,,,
,,"struct mov_ram_p",,,,,,,,1,1,"x_src",,,,,,,,,,,,,,,,,,,,,,,
,"Y-bus","enum y_src",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,"m0",,,,,,,,,,,,,,,,0,0,0,,,,,,,,,,,,,,,
,,"m1",,,,,,,,,,,,,,,,0,0,1,,,,,,,,,,,,,,,
,,"m2",,,,,,,,,,,,,,,,0,1,0,,,,,,,,,,,,,,,
,,"m3",,,,,,,,,,,,,,,,0,1,1,,,,,,,,,,,,,,,
,,"mc0",,,,,,,,,,,,,,,,1,0,0,,,,,,,,,,,,,,,
,,"mc1",,,,,,,,,,,,,,,,1,0,1,,,,,,,,,,,,,,,
,,"mc2",,,,,,,,,,,,,,,,1,1,0,,,,,,,,,,,,,,,
,,"mc3",,,,,,,,,,,,,,,,1,1,1,,,,,,,,,,,,,,,
,,"struct mov_ram_y",,,,,,,,,,,,,1,,,"y_src",,,,,,,,,,,,,,,,,
,,"struct clr_a",,,,,,,,,,,,,,0,1,,,,,,,,,,,,,,,,,,
,,"struct mov_alu_a",,,,,,,,,,,,,,1,0,,,,,,,,,,,,,,,,,,
,,"struct mov_ram_a",,,,,,,,,,,,,,1,1,"y_src",,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0,
,"D1-bus","enum d1_src",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,"m0",,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0,0,0,0
,,"m1",,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0,0,1,1
,,"m2",,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0,1,0,2
,,"m3",,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0,1,1,3
,,"mc0",,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,1,0,0,4
,,"mc1",,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,1,0,1,5
,,"mc2",,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,1,1,0,6
,,"mc3",,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,1,1,1,7
,,"all",,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,0,0,1,9
,,"alh",,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,0,1,0,10
,,"enum d1_dst",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,"mc0",,,,,,,,,,,,,,,,,,,,,0,0,0,0,,,,,,,,,0
,,"mc1",,,,,,,,,,,,,,,,,,,,,0,0,0,1,,,,,,,,,1
,,"mc2",,,,,,,,,,,,,,,,,,,,,0,0,1,0,,,,,,,,,2
,,"mc3",,,,,,,,,,,,,,,,,,,,,0,0,1,1,,,,,,,,,3
,,"rx",,,,,,,,,,,,,,,,,,,,,0,1,0,0,,,,,,,,,4
,,"pl",,,,,,,,,,,,,,,,,,,,,0,1,0,1,,,,,,,,,5
,,"ra0",,,,,,,,,,,,,,,,,,,,,0,1,1,0,,,,,,,,,6
,,"wa0",,,,,,,,,,,,,,,,,,,,,0,1,1,1,,,,,,,,,7
,,"lop",,,,,,,,,,,,,,,,,,,,,1,0,1,0,,,,,,,,,10
,,"top",,,,,,,,,,,,,,,,,,,,,1,0,1,1,,,,,,,,,11
,,"ct0",,,,,,,,,,,,,,,,,,,,,1,1,0,0,,,,,,,,,12
,,"ct1",,,,,,,,,,,,,,,,,,,,,1,1,0,1,,,,,,,,,13
,,"ct2",,,,,,,,,,,,,,,,,,,,,1,1,1,0,,,,,,,,,14
,,"ct3",,,,,,,,,,,,,,,,,,,,,1,1,1,1,,,,,,,,,15
,,"struct mov_imm_d1",,,,,,,,,,,,,,,,,,,0,1,"d1_dst",,,,"imm",,,,,,,,
,,"struct mov_ram_d1",,,,,,,,,,,,,,,,,,,1,1,"d1_dst",,,,,,,,"d1_src",,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0,
"LOAD",,"struct mvi",1,0,"dst",,,,0,"imm",,,,,,,,,,,,,,,,,,,,,,,,,
,"conditional","struct mvi_cond",1,0,"dst",,,,1,"cond",,,,,,"imm",,,,,,,,,,,,,,,,,,,
,,"enum cond",,,,,,,,"N",,"T0","C","S","Z",,,,,,,,,,,,,,,,,,,,
,,"z",,,,,,,,1,0,0,0,0,1,,,,,,,,,,,,,,,,,,,,
,,"nz",,,,,,,,0,0,0,0,0,1,,,,,,,,,,,,,,,,,,,,
,,"s",,,,,,,,1,0,0,0,1,0,,,,,,,,,,,,,,,,,,,,
,,"ns",,,,,,,,0,0,0,0,1,0,,,,,,,,,,,,,,,,,,,,
,,"c",,,,,,,,1,0,0,1,0,0,,,,,,,,,,,,,,,,,,,,
,,"nc",,,,,,,,0,0,0,1,0,0,,,,,,,,,,,,,,,,,,,,
,,"t0",,,,,,,,1,0,1,0,0,0,,,,,,,,,,,,,,,,,,,,
,,"nt0",,,,,,,,0,0,1,0,0,0,,,,,,,,,,,,,,,,,,,,
,,"zs",,,,,,,,1,0,0,0,1,1,,,,,,,,,,,,,,,,,,,,
,,"nzs",,,,,,,,0,0,0,0,1,1,,,,,,,,,,,,,,,,,,,,
,,"enum dst",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,"mc0",,,0,0,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,0
,,"mc1",,,0,0,0,1,,,,,,,,,,,,,,,,,,,,,,,,,,,1
,,"mc2",,,0,0,1,0,,,,,,,,,,,,,,,,,,,,,,,,,,,2
,,"mc3",,,0,0,1,1,,,,,,,,,,,,,,,,,,,,,,,,,,,3
,,"rx",,,0,1,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,4
,,"pl",,,0,1,0,1,,,,,,,,,,,,,,,,,,,,,,,,,,,5
,,"ra0",,,0,1,1,0,,,,,,,,,,,,,,,,,,,,,,,,,,,6
,,"wa0",,,0,1,1,1,,,,,,,,,,,,,,,,,,,,,,,,,,,7
,,"lop",,,1,0,1,0,,,,,,,,,,,,,,,,,,,,,,,,,,,10
,,"pc",,,1,1,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,12
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0,
"DMA",,,,,,,,,,,,,,,,,,,,"H","L","D",,,,,,,,,,,,,
,"imm","struct d0_dst_imm",1,1,0,0,,,,,,,,,,,"add",,,"hold",0,0,,"dst",,,"imm",,,,,,,,
,,"struct src_d0_imm",1,1,0,0,,,,,,,,,,,"add",,,"hold",0,1,,"src",,,"imm",,,,,,,,
,"ram","struct d0_dst_ram",1,1,0,0,,,,,,,,,,,"add",,,"hold",1,0,,"dst",,,,,,,,"ram",,,
,,"struct src_d0_ram",1,1,0,0,,,,,,,,,,,"add",,,"hold",1,1,,"src",,,,,,,,"ram",,,
,,"enum ram",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,"m0",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0,0,0
,,"m1",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,0,1,1
,,"m2",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,1,0,2
,,"m3",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0,1,1,3
,,"mc0",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,0,0,4
,,"mc1",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,0,1,5
,,"mc2",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,0,6
,,"mc3",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,1,7
,,"enum src",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,"mc0",,,,,,,,,,,,,,,,,,,,,,0,0,0,,,,,,,,,
,,"mc1",,,,,,,,,,,,,,,,,,,,,,0,0,1,,,,,,,,,
,,"mc2",,,,,,,,,,,,,,,,,,,,,,0,1,0,,,,,,,,,
,,"mc3",,,,,,,,,,,,,,,,,,,,,,0,1,1,,,,,,,,,
,,"enum dst",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,"mc0",,,,,,,,,,,,,,,,,,,,,,0,0,0,,,,,,,,,
,,"mc1",,,,,,,,,,,,,,,,,,,,,,0,0,1,,,,,,,,,
,,"mc2",,,,,,,,,,,,,,,,,,,,,,0,1,0,,,,,,,,,
,,"mc3",,,,,,,,,,,,,,,,,,,,,,0,1,1,,,,,,,,,
,,"prg",,,,,,,,,,,,,,,,,,,,,,1,0,0,,,,,,,,,
,,"enum hold",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,"_false",,,,,,,,,,,,,,,,,,0,,,,,,,,,,,,,,,
,,"_true",,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,
,,"enum add",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,"_0",,,,,,,,,,,,,,,0,0,0,,,,,,,,,,,,,,,,0
,,"_1",,,,,,,,,,,,,,,0,0,1,,,,,,,,,,,,,,,,1
,,"_2",,,,,,,,,,,,,,,0,1,0,,,,,,,,,,,,,,,,2
,,"_4",,,,,,,,,,,,,,,0,1,1,,,,,,,,,,,,,,,,3
,,"_8",,,,,,,,,,,,,,,1,0,0,,,,,,,,,,,,,,,,4
,,"_16",,,,,,,,,,,,,,,1,0,1,,,,,,,,,,,,,,,,5
,,"_32",,,,,,,,,,,,,,,1,1,0,,,,,,,,,,,,,,,,6
,,"_64",,,,,,,,,,,,,,,1,1,1,,,,,,,,,,,,,,,,7
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0,
"JUMP",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,"struct jmp",1,1,0,1,,,0,"imm",,,,,,,,,,,,,,,,,,,,,,,,,
,"conditional","struct jmp_cond",1,1,0,1,,,1,"cond",,,,,,"imm",,,,,,,,,,,,,,,,,,,
,,"enum cond",,,,,,,"F","N",,"T0","C","S","Z",,,,,,,,,,,,,,,,,,,,
,,"z",,,,,,,,1,0,0,0,0,1,,,,,,,,,,,,,,,,,,,,
,,"nz",,,,,,,,0,0,0,0,0,1,,,,,,,,,,,,,,,,,,,,
,,"s",,,,,,,,1,0,0,0,1,0,,,,,,,,,,,,,,,,,,,,
,,"ns",,,,,,,,0,0,0,0,1,0,,,,,,,,,,,,,,,,,,,,
,,"c",,,,,,,,1,0,0,1,0,0,,,,,,,,,,,,,,,,,,,,
,,"nc",,,,,,,,0,0,0,1,0,0,,,,,,,,,,,,,,,,,,,,
,,"t0",,,,,,,,1,0,1,0,0,0,,,,,,,,,,,,,,,,,,,,
,,"nt0",,,,,,,,0,0,1,0,0,0,,,,,,,,,,,,,,,,,,,,
,,"zs",,,,,,,,1,0,0,0,1,1,,,,,,,,,,,,,,,,,,,,
,,"nzs",,,,,,,,0,0,0,0,1,1,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
"LOOP",,"struct btm",1,1,1,0,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,"struct lps",1,1,1,0,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
"END",,"struct end",1,1,1,1,0,,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,"struct endi",1,1,1,1,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,
1
2 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
3 OP 0 0
4 ALU
5 struct andl 0 0 0 1 1
6 struct orl 0 0 1 0 2
7 struct xorl 0 0 1 1 3
8 struct add 0 1 0 0 4
9 struct sub 0 1 0 1 5
10 struct ad2 0 1 1 0 6
11 struct sr 1 0 0 0 8
12 struct rr 1 0 0 1 9
13 struct sl 1 0 1 0 10
14 struct rl 1 0 1 1 11
15 struct rl8 1 1 1 1 15
16
17 X-bus enum x_src
18 m0 0 0 0
19 m1 0 0 1
20 m2 0 1 0
21 m3 0 1 1
22 mc0 1 0 0
23 mc1 1 0 1
24 mc2 1 1 0
25 mc3 1 1 1
26 struct mov_ram_x 1 x_src
27 struct mov_mul_p 1 0
28 struct mov_ram_p 1 1 x_src
29 Y-bus enum y_src
30 m0 0 0 0
31 m1 0 0 1
32 m2 0 1 0
33 m3 0 1 1
34 mc0 1 0 0
35 mc1 1 0 1
36 mc2 1 1 0
37 mc3 1 1 1
38 struct mov_ram_y 1 y_src
39 struct clr_a 0 1
40 struct mov_alu_a 1 0
41 struct mov_ram_a 1 1 y_src
42
43 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
44 D1-bus enum d1_src
45 m0 0 0 0 0 0
46 m1 0 0 0 1 1
47 m2 0 0 1 0 2
48 m3 0 0 1 1 3
49 mc0 0 1 0 0 4
50 mc1 0 1 0 1 5
51 mc2 0 1 1 0 6
52 mc3 0 1 1 1 7
53 all 1 0 0 1 9
54 alh 1 0 1 0 10
55 enum d1_dst
56 mc0 0 0 0 0 0
57 mc1 0 0 0 1 1
58 mc2 0 0 1 0 2
59 mc3 0 0 1 1 3
60 rx 0 1 0 0 4
61 pl 0 1 0 1 5
62 ra0 0 1 1 0 6
63 wa0 0 1 1 1 7
64 lop 1 0 1 0 10
65 top 1 0 1 1 11
66 ct0 1 1 0 0 12
67 ct1 1 1 0 1 13
68 ct2 1 1 1 0 14
69 ct3 1 1 1 1 15
70 struct mov_imm_d1 0 1 d1_dst imm
71 struct mov_ram_d1 1 1 d1_dst d1_src
72
73 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
74 LOAD struct mvi 1 0 dst 0 imm
75 conditional struct mvi_cond 1 0 dst 1 cond imm
76 enum cond N T0 C S Z
77 z 1 0 0 0 0 1
78 nz 0 0 0 0 0 1
79 s 1 0 0 0 1 0
80 ns 0 0 0 0 1 0
81 c 1 0 0 1 0 0
82 nc 0 0 0 1 0 0
83 t0 1 0 1 0 0 0
84 nt0 0 0 1 0 0 0
85 zs 1 0 0 0 1 1
86 nzs 0 0 0 0 1 1
87 enum dst
88 mc0 0 0 0 0 0
89 mc1 0 0 0 1 1
90 mc2 0 0 1 0 2
91 mc3 0 0 1 1 3
92 rx 0 1 0 0 4
93 pl 0 1 0 1 5
94 ra0 0 1 1 0 6
95 wa0 0 1 1 1 7
96 lop 1 0 1 0 10
97 pc 1 1 0 0 12
98
99 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
100 DMA H L D
101 imm struct d0_dst_imm 1 1 0 0 add hold 0 0 dst imm
102 struct src_d0_imm 1 1 0 0 add hold 0 1 src imm
103 ram struct d0_dst_ram 1 1 0 0 add hold 1 0 dst ram
104 struct src_d0_ram 1 1 0 0 add hold 1 1 src ram
105 enum ram
106 m0 0 0 0 0
107 m1 0 0 1 1
108 m2 0 1 0 2
109 m3 0 1 1 3
110 mc0 1 0 0 4
111 mc1 1 0 1 5
112 mc2 1 1 0 6
113 mc3 1 1 1 7
114 enum src
115 mc0 0 0 0
116 mc1 0 0 1
117 mc2 0 1 0
118 mc3 0 1 1
119 enum dst
120 mc0 0 0 0
121 mc1 0 0 1
122 mc2 0 1 0
123 mc3 0 1 1
124 prg 1 0 0
125 enum hold
126 _false 0
127 _true 1
128 enum add
129 _0 0 0 0 0
130 _1 0 0 1 1
131 _2 0 1 0 2
132 _4 0 1 1 3
133 _8 1 0 0 4
134 _16 1 0 1 5
135 _32 1 1 0 6
136 _64 1 1 1 7
137
138 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
139 JUMP
140 struct jmp 1 1 0 1 0 imm
141 conditional struct jmp_cond 1 1 0 1 1 cond imm
142 enum cond F N T0 C S Z
143 z 1 0 0 0 0 1
144 nz 0 0 0 0 0 1
145 s 1 0 0 0 1 0
146 ns 0 0 0 0 1 0
147 c 1 0 0 1 0 0
148 nc 0 0 0 1 0 0
149 t0 1 0 1 0 0 0
150 nt0 0 0 1 0 0 0
151 zs 1 0 0 0 1 1
152 nzs 0 0 0 0 1 1
153
154 LOOP struct btm 1 1 1 0 0
155 struct lps 1 1 1 0 1
156
157 END struct end 1 1 1 1 0
158 struct endi 1 1 1 1 1

Binary file not shown.

View File

@ -17,6 +17,12 @@ static inline void report(const int line, const int col, const std::string where
had_error = true;
}
static inline void error(std::string message, const int value)
{
std::cerr << "error " << message << ": " << value << std::endl;
had_error = true;
}
static inline void error(const int line, const int col, std::string message)
{
report(line, col, "", message);

24
gen/generate.py Normal file
View File

@ -0,0 +1,24 @@
import io
def _render(out, lines):
indent = " "
level = 0
for l in lines:
if l and (l[0] == "}" or l[0] == ")"):
level -= 2
assert level >= 0, out.getvalue()
out.write(indent * level + l + "\n")
if l and (l[-1] == "{" or l[-1] == "("):
level += 2
if level == 0 and l and l[-1] == ";":
out.write("\n")
return out
def renderer():
out = io.StringIO()
def render(lines):
return _render(out, lines)
return render, out

241
gen/generate_notes.py Normal file
View File

@ -0,0 +1,241 @@
import sys
from generate import renderer
from parse_notes import parse, read, X, Bits, Enum, Struct, Namespace
def bits_mask_literal(bits, start, end) -> str:
b_str = lambda b: '1' if b is not X else '0'
s = ''.join(map(b_str, reversed(bits[start:end])))
return s
def bits_literal(bits, start, end) -> str:
b_str = lambda b: str(b) if b is not X else '0'
s = ''.join(map(b_str, reversed(bits[start:end])))
return s
def bits_start_end(bits):
start = 0
while bits[start] is X:
start += 1
ix = start + 1
end = ix
while ix < 32:
if bits[ix] is not X:
end = ix + 1
ix += 1
return start, end
def bits_to_shift(bits) -> str:
start, end = bits_start_end(bits)
literal = bits_literal(bits, start, end)
return f"0b{literal} << {start}"
def bits_to_mask(bits) -> str:
start, end = bits_start_end(bits)
mask = bits_mask_literal(bits, start, end)
return f"0b{mask} << {start}"
def enum_consts_to_value(namespace_name, enum_name, consts):
yield "static constexpr value_t to_value(uint32_t code)"
yield "{"
yield "using enum value_t;"
yield ""
yield "switch (code & mask()) {"
for const in consts:
shift = bits_to_shift(const.bits)
yield f"case {shift}: return {const.name};"
yield "default:"
yield f' std::cerr << "invalid {namespace_name} {enum_name} code: " << (code & mask()) << std::endl;'
yield ' throw std::runtime_error("invalid code");'
yield "}"
yield "}"
def enum_consts_bits(consts):
yield "uint32_t bits() const"
yield "{"
yield "using enum value_t;"
yield ""
yield "switch (value) {"
for const in consts:
shift = bits_to_shift(const.bits)
yield f"case {const.name}: return {shift};"
yield "default: __builtin_unreachable();"
yield "}"
yield "}"
def enum_value_t(consts):
yield "enum value_t {"
for const in consts:
yield f"{const.name},"
yield "};"
def enum_struct(namespace, enum):
yield f"struct {enum.name}_t {{"
yield from enum_value_t(enum.consts)
yield ""
yield "const value_t value;"
yield ""
yield f"constexpr {enum.name}_t(value_t value)"
yield " : value(value) {}"
yield ""
yield f"constexpr {enum.name}_t(uint32_t code)"
yield " : value(to_value(code)) {}"
yield ""
mask = bits_to_mask(enum.consts[0].bits)
yield f"static constexpr uint32_t mask() {{ return {mask}; }}"
yield ""
yield from enum_consts_to_value(namespace.name, enum.name, enum.consts)
yield ""
yield from enum_consts_bits(enum.consts)
yield "};"
def has_imm(struct):
return 'imm' in {name for _i, name in struct.fields}
def imm_length(struct):
imm_length, = [i for i, name in struct.fields if name == 'imm']
return imm_length + 1
def f_name(name):
return name.split('_', maxsplit=1)[-1]
def struct_struct(namespace, struct):
if has_imm(struct):
length = imm_length(struct)
yield f"struct {struct.name}_t : stmt_accept_t<{struct.name}_t>, ins_imm_t<{struct.name}_t, {length}>"
yield "{"
yield f"using imm_type = uimm_t<{length}>;"
else:
yield f"struct {struct.name}_t : stmt_accept_t<{struct.name}_t>, ins_t<{struct.name}_t>"
yield "{"
yield ""
field_decls = [f"{name}_t {f_name(name)}" for _, name in struct.fields if name != 'imm']
field_inits = [f"{f_name(name)}({f_name(name)})" for _, name in struct.fields if name != 'imm']
if has_imm(struct):
field_decls.insert(0, "imm_type imm")
field_inits.insert(0, "ins_imm_t(imm)")
field_inits = ", ".join(field_inits)
field_decls = ", ".join(field_decls)
yield f"{struct.name}_t({field_decls})"
if field_inits.strip():
yield f" : {field_inits} {{}}"
else:
yield "{}"
yield ""
yield f"{struct.name}_t(uint32_t code)"
code_inits = [f"{f_name(name)}(code)" for _, name in struct.fields if name != 'imm']
if has_imm(struct):
code_inits.insert(0, "ins_imm_t(code)")
code_inits = ", ".join(code_inits)
if code_inits.strip():
yield f" : {code_inits} {{ (void)code; }}"
else:
yield "{ (void)code; }"
yield ""
for _, name in struct.fields:
if name == 'imm':
pass
else:
yield f"const {name}_t {f_name(name)};"
yield ""
start, end = bits_start_end(struct.bits)
mask_literal = bits_mask_literal(struct.bits, start, end)
literal = bits_literal(struct.bits, start, end)
yield f"static uint32_t mask() {{ return 0b{mask_literal} << {start}; }}"
yield f"static uint32_t code() {{ return 0b{literal} << {start}; }}"
bits_return = " | ".join(f"{f_name(name)}.bits()" for _, name in struct.fields if name != 'imm')
if not bits_return.strip():
bits_return = "0"
yield f"uint32_t bits() const {{ return {bits_return}; }}"
yield "};"
def sort_events(events):
enums = []
structs = []
namespace = None
def do_yield():
nonlocal enums, structs, namespace
yield namespace
#yield from sorted(enums, key=lambda e: e.name)
yield from enums
assert structs, structs
yield from structs
#yield from sorted(structs, key=lambda e: e.name)
for event in events:
if type(event) is Namespace:
if namespace is not None:
yield from do_yield()
else:
assert not enums
assert not structs
namespace = event
enums = []
structs = []
elif type(event) is Enum:
assert namespace is not None
enums.append(event)
elif type(event) is Struct:
assert namespace is not None
structs.append(event)
else:
assert False
assert namespace is not None
yield from do_yield()
def generate_header_namespaces(events):
namespace = None
yield "namespace dsp {"
for event in events:
if type(event) is Namespace:
if namespace is not None:
yield ""
yield f"}} // {namespace.name}"
yield ""
yield f"namespace {event.name} {{"
yield ""
namespace = event
elif type(event) is Enum:
yield from enum_struct(namespace, event)
yield ""
elif type(event) is Struct:
yield from struct_struct(namespace, event)
yield ""
else:
assert False
assert namespace is not None
yield f"}} // namespace {namespace.name}"
yield ""
yield "} // namespace dsp"
def generate_includes():
yield "#pragma once"
yield ""
yield "#include <cstdint>"
yield "#include <iostream>"
yield ""
yield '#include "imm.hpp"'
yield '#include "ins.hpp"'
yield '#include "stmt_base.hpp"'
yield ""
def generate_header():
events = list(sort_events(parse(read(sys.argv[1]))))
render, out = renderer()
render(generate_includes())
render(generate_header_namespaces(events))
return out
print(generate_header().getvalue())
#consts=[Const(name='z', bits=xxxxxxx100001xxxxxxxxxxxxxxxxxxx),
b = Bits(bits=[X,X,1,1,0,0,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X])

128
gen/parse_notes.py Normal file
View File

@ -0,0 +1,128 @@
import csv
import sys
from dataclasses import dataclass
from typing import Union
class _X:
def __repr__(self):
return 'x'
X = _X()
bit = Union[int, _X]
@dataclass
class Bits:
bits: tuple[bit, bit, bit, bit, bit, bit, bit, bit,
bit, bit, bit, bit, bit, bit, bit, bit,
bit, bit, bit, bit, bit, bit, bit, bit,
bit, bit, bit, bit, bit, bit, bit, bit]
def __repr__(self):
return ''.join(repr(i) for i in self.bits)
def __getitem__(self, key):
return list(reversed(self.bits))[key]
@dataclass
class Const:
name: str
bits: Bits
@dataclass
class Enum:
name: str
consts: list[Const]
@dataclass
class Struct:
name: str
bits: Bits
fields: list[tuple[int, str]]
@dataclass
class Namespace:
name: str
def read(path):
with open(path, newline='') as f:
reader = csv.reader(f, delimiter=',', quotechar='"')
return list(reader)
label_col = 2
bits_col = 3
def parse_struct(rows, ix):
return None, ix + 1
def validate_consts(consts):
by_index = set([
frozenset([ix for ix, bit in enumerate(const.bits) if bit is not X])
for const in consts
])
assert len(by_index) == 1
def get_bits(row):
return [
int(i) if i in {"0", "1"} else X
for i in row[bits_col:bits_col+32]
]
def get_nonbits(row):
return [
(31-ix, i)
for ix, i in enumerate(row[bits_col:bits_col+32])
if i and i not in {"0", "1"}
]
def get_name(row, key):
label0 = row[label_col]
assert label0.startswith(f'{key} '), label0
_, name = label0.split(' ', maxsplit=1)
return name
def parse_enum(rows, ix):
enum_name = get_name(rows[ix], "enum")
ix += 1
consts = []
while ix < len(rows):
label = rows[ix][label_col]
if not label or ' ' in label:
validate_consts(consts)
return Enum(enum_name, consts), ix
else:
const_name = label
bits = get_bits(rows[ix])
assert len(bits) == 32
consts.append(Const(const_name, Bits(bits)))
ix += 1
def parse_struct(rows, ix):
struct_name = get_name(rows[ix], "struct")
bits = get_bits(rows[ix])
fields = get_nonbits(rows[ix])
ix += 1
struct = Struct(struct_name, Bits(bits), fields)
return struct, ix
def parse(rows):
ix = 0
while ix < len(rows):
if rows[ix][0].strip():
yield Namespace(rows[ix][0].lower())
label = rows[ix][label_col]
if label.startswith('struct'):
ret, ix = parse_struct(rows, ix)
yield ret
elif label.startswith('enum' ):
ret, ix = parse_enum(rows, ix)
yield ret
else:
ix += 1
#events = list(parse(read(sys.argv[1])))
#from pprint import pprint
#pprint(events)

187
gen/template.cpp Normal file
View File

@ -0,0 +1,187 @@
#include <cstdint>
#include "imm.hpp"
#include "stmt_base.hpp"
namespace dsp {
template <typename T>
struct ins_t
{
virtual uint32_t bits() const;
uint32_t render() const
{
return T::code() | bits();
}
constexpr bool pred(uint32_t ins) const
{
return (ins & T::mask()) == T::code();
}
};
template <typename T, int N>
struct ins_imm_t : ins_t<T>
{
ins_imm_t(uimm_t<N> imm)
: imm(imm) {}
const uimm_t<N> imm;
uint32_t render(visitor_t<uint32_t> * visitor)
{
num_t value = imm.normalize(imm.expr->accept(visitor));
if (imm.in_range(value))
return render() | value;
else
throw imm_out_of_range(imm, value);
}
};
namespace load {
struct dest_t {
enum value_t {
mc0, mc1, mc2, mc3,
rx , pl ,
ra0, wa0,
lop, pc ,
};
const value_t value;
constexpr dest_t(value_t value)
: value(value) {}
constexpr dest_t(uint32_t code)
: value(to_value(code)) { }
static constexpr uint32_t mask() { return 0b1111 << 26; }
static constexpr value_t to_value(uint32_t code)
{
using enum value_t;
switch (code & mask()) {
case 0b0000 << 26: return mc0;
case 0b0001 << 26: return mc1;
case 0b0010 << 26: return mc2;
case 0b0011 << 26: return mc3;
case 0b0100 << 26: return rx;
case 0b0101 << 26: return pl;
case 0b0110 << 26: return ra0;
case 0b0111 << 26: return wa0;
case 0b1010 << 26: return lop;
case 0b1100 << 26: return pc;
default:
std::cerr << "invalid load dest code: " << (code & mask()) << std::endl;
throw std::runtime_error("invalid code");
}
}
uint32_t bits() const
{
using enum value_t;
switch (value) {
case mc0: return 0b0000 << 26;
case mc1: return 0b0001 << 26;
case mc2: return 0b0010 << 26;
case mc3: return 0b0011 << 26;
case rx: return 0b0100 << 26;
case pl: return 0b0101 << 26;
case ra0: return 0b0110 << 26;
case wa0: return 0b0111 << 26;
case lop: return 0b1010 << 26;
case pc: return 0b1100 << 26;
default: __builtin_unreachable();
}
}
};
struct cond_t {
enum value_t {
z , nz ,
s , ns ,
c , nc ,
t0, nt0,
zs, nzs,
};
const value_t value;
constexpr cond_t(value_t value)
: value(value) {}
constexpr cond_t(uint32_t code)
: value(to_value(code)) { }
static constexpr uint32_t mask() { return 0b1'0'1111 << 19; }
static constexpr value_t to_value(uint32_t code)
{
using enum value_t;
switch (code & mask()) {
case 0b1'0'0001 << 19: return z;
case 0b0'0'0001 << 19: return nz;
case 0b1'0'0010 << 19: return s;
case 0b0'0'0010 << 19: return ns;
case 0b1'0'0100 << 19: return c;
case 0b0'0'0100 << 19: return nc;
case 0b1'0'1000 << 19: return t0;
case 0b0'0'1000 << 19: return nt0;
case 0b1'0'0011 << 19: return zs;
case 0b0'0'0011 << 19: return nzs;
default:
std::cerr << "invalid load cond code: " << (code & mask()) << std::endl;
throw std::runtime_error("invalid code");
}
}
uint32_t bits() const
{
using enum value_t;
switch (value) {
case z: return 0b1'0'0001 << 19;
case nz: return 0b0'0'0001 << 19;
case s: return 0b1'0'0010 << 19;
case ns: return 0b0'0'0010 << 19;
case c: return 0b1'0'0100 << 19;
case nc: return 0b0'0'0100 << 19;
case t0: return 0b1'0'1000 << 19;
case nt0: return 0b0'0'1000 << 19;
case zs: return 0b1'0'0011 << 19;
case nzs: return 0b0'0'0011 << 19;
default: __builtin_unreachable();
}
}
};
struct mvi_cond_t : stmt_accept_t<mvi_cond_t>, ins_imm_t<mvi_cond_t, 19>
{
using imm_type = uimm_t<19>;
mvi_cond_t(dest_t dest, cond_t cond, imm_type imm)
: dest(dest), cond(cond), ins_imm_t(imm)
{ }
mvi_cond_t(uint32_t code)
: dest(code), cond(code), ins_imm_t(code)
{ }
const dest_t dest;
const cond_t cond;
static uint32_t mask() { return 0b11'0000'1 << 25; }
static uint32_t code() { return 0b10'0000'1 << 25; }
uint32_t bits() const { return dest.bits()
| cond.bits();
}
};
}
}

47
imm.hpp Normal file
View File

@ -0,0 +1,47 @@
#pragma once
#include "expr.hpp"
namespace dsp {
static const token_t null_token;
template <bool S, int N>
struct imm_t {
imm_t(const token_t& token, const expr_t * expr)
: token(token), expr(expr) {}
imm_t(const uint32_t code)
: token(null_token), expr(new literal_t(code & mask)) {}
const token_t& token;
const expr_t * expr;
static constexpr bool sign = S;
static constexpr int bits = N;
static constexpr num_t max = (1L << (bits - static_cast<num_t>(sign))) - 1;
static constexpr num_t min = sign ? -(max + 1) : 0;
static constexpr num_t mask = (1L << bits) - 1;
num_t normalize(num_t value) const
{
if (!S && value > 2147483648) { // fixme: hack
return value & max;
} else {
return value;
}
}
bool in_range(num_t value) const
{
return value <= max && value >= min;
}
};
template <int N>
using simm_t = imm_t<true, N>;
template <int N>
using uimm_t = imm_t<false, N>;
}

45
ins.hpp Normal file
View File

@ -0,0 +1,45 @@
#pragma once
#include <cstdint>
#include "imm.hpp"
namespace dsp {
template <typename T>
struct ins_t
{
/*
virtual uint32_t bits() const;
uint32_t render() const
{
return T::code() | bits();
}
*/
static bool pred(uint32_t ins)
{
return (ins & T::mask()) == T::code();
}
};
template <typename T, int N>
struct ins_imm_t : ins_t<T>
{
ins_imm_t(uimm_t<N> imm)
: imm(imm) {}
const uimm_t<N> imm;
uint32_t render(visitor_t<uint32_t> * visitor)
{
num_t value = imm.normalize(imm.expr->accept(visitor));
if (imm.in_range(value))
return render() | value;
else
throw imm_out_of_range(imm, value);
}
};
}

View File

@ -173,21 +173,22 @@ void parser_t::synchronize()
}
*/
std::optional<op::op_t *> parser_t::alu()
std::optional<op::op_t> parser_t::alu()
{
using namespace dsp::op;
if (match(_and)) return {new alu_t(alu_type_t::andl)};
else if (match(_or )) return {new alu_t(alu_type_t::orl)};
else if (match(_xor)) return {new alu_t(alu_type_t::xorl)};
else if (match(_add)) return {new alu_t(alu_type_t::add)};
else if (match(_sub)) return {new alu_t(alu_type_t::sub)};
else if (match(_ad2)) return {new alu_t(alu_type_t::ad2)};
else if (match(_sr )) return {new alu_t(alu_type_t::sr)};
else if (match(_rr )) return {new alu_t(alu_type_t::rr)};
else if (match(_sl )) return {new alu_t(alu_type_t::sl)};
else if (match(_rl )) return {new alu_t(alu_type_t::rl)};
else if (match(_rl8)) return {new alu_t(alu_type_t::rl8)};
if (match(_and)) return {op_t{std::in_place_type<andl_t>}};
else if (match(_or )) return {op_t{std::in_place_type<orl_t>}};
else if (match(_xor)) return {op_t{std::in_place_type<xorl_t>}};
else if (match(_add)) return {op_t{std::in_place_type<add_t>}};
else if (match(_sub)) return {op_t{std::in_place_type<sub_t>}};
else if (match(_ad2)) return {op_t{std::in_place_type<ad2_t>}};
else if (match(_sr )) return {op_t{std::in_place_type<sr_t>}};
else if (match(_rr )) return {op_t{std::in_place_type<rr_t>}};
else if (match(_sl )) return {op_t{std::in_place_type<sl_t>}};
else if (match(_rl )) return {op_t{std::in_place_type<rl_t>}};
else if (match(_rl8)) return {op_t{std::in_place_type<rl8_t>}};
else return {};
}
@ -199,41 +200,58 @@ bool parser_t::xyd1_src()
return mc || m || al;
}
static op::xy_src_t xy_src(const token_t& token)
static op::x_src_t x_src(const token_t& token)
{
using namespace dsp::op;
switch (token.type) {
case _m0: return xy_src_t::m0;
case _m1: return xy_src_t::m1;
case _m2: return xy_src_t::m2;
case _m3: return xy_src_t::m3;
case _mc0: return xy_src_t::mc0;
case _mc1: return xy_src_t::mc1;
case _mc2: return xy_src_t::mc2;
case _mc3: return xy_src_t::mc3;
case _m0: return x_src_t::m0;
case _m1: return x_src_t::m1;
case _m2: return x_src_t::m2;
case _m3: return x_src_t::m3;
case _mc0: return x_src_t::mc0;
case _mc1: return x_src_t::mc1;
case _mc2: return x_src_t::mc2;
case _mc3: return x_src_t::mc3;
default: assert(false); __builtin_unreachable();
}
}
std::optional<op::d1_dest_t> parser_t::d1_dest()
static op::y_src_t y_src(const token_t& token)
{
using namespace dsp::op;
if (match(_mc0)) return {d1_dest_t::mc0};
else if (match(_mc1)) return {d1_dest_t::mc1};
else if (match(_mc2)) return {d1_dest_t::mc2};
else if (match(_mc3)) return {d1_dest_t::mc3};
else if (match(_rx)) return {d1_dest_t::rx};
else if (match(_pl)) return {d1_dest_t::pl};
else if (match(_ra0)) return {d1_dest_t::ra0};
else if (match(_wa0)) return {d1_dest_t::wa0};
else if (match(_lop)) return {d1_dest_t::lop};
else if (match(_top)) return {d1_dest_t::top};
else if (match(_ct0)) return {d1_dest_t::ct0};
else if (match(_ct1)) return {d1_dest_t::ct1};
else if (match(_ct2)) return {d1_dest_t::ct2};
else if (match(_ct3)) return {d1_dest_t::ct3};
switch (token.type) {
case _m0: return y_src_t::m0;
case _m1: return y_src_t::m1;
case _m2: return y_src_t::m2;
case _m3: return y_src_t::m3;
case _mc0: return y_src_t::mc0;
case _mc1: return y_src_t::mc1;
case _mc2: return y_src_t::mc2;
case _mc3: return y_src_t::mc3;
default: assert(false); __builtin_unreachable();
}
}
std::optional<op::d1_dst_t> parser_t::d1_dst()
{
using namespace dsp::op;
if (match(_mc0)) return {d1_dst_t::mc0};
else if (match(_mc1)) return {d1_dst_t::mc1};
else if (match(_mc2)) return {d1_dst_t::mc2};
else if (match(_mc3)) return {d1_dst_t::mc3};
else if (match(_rx)) return {d1_dst_t::rx};
else if (match(_pl)) return {d1_dst_t::pl};
else if (match(_ra0)) return {d1_dst_t::ra0};
else if (match(_wa0)) return {d1_dst_t::wa0};
else if (match(_lop)) return {d1_dst_t::lop};
else if (match(_top)) return {d1_dst_t::top};
else if (match(_ct0)) return {d1_dst_t::ct0};
else if (match(_ct1)) return {d1_dst_t::ct1};
else if (match(_ct2)) return {d1_dst_t::ct2};
else if (match(_ct3)) return {d1_dst_t::ct3};
else return {};
}
@ -256,55 +274,60 @@ static op::d1_src_t d1_src(const token_t& token)
}
}
std::optional<op::op_t *> parser_t::xyd1_bus()
std::optional<op::op_t> parser_t::xyd1_bus()
{
if (match(_mov)) {
if (match(_alu)) {
consume(comma, "expected `,` after `mov alu`");
consume(_a, "expected `a` after `mov alu,`");
return {new op::mov_alu_a_t()};
return {op::mov_alu_a_t()};
} else if (match(_mul)) {
consume(comma, "expected ',' after `mov mul`");
consume(_p, "expected 'p' after `mov mul,`");
return {new op::mov_mul_p_t()};
return {op::mov_mul_p_t()};
} else if (xyd1_src()) {
const token_t& src_token = previous();
consume(comma, "expected `,` after mov src operand");
// this is starting to feel a bit ugly...
bool d1 = src_token.type == _alh || src_token.type == _alh;
if (!d1 && match(_y)) return {new op::mov_ram_y_t(xy_src(src_token))};
else if (!d1 && match(_a)) return {new op::mov_ram_a_t(xy_src(src_token))};
else if (!d1 && match(_x)) return {new op::mov_ram_x_t(xy_src(src_token))};
else if (!d1 && match(_p)) return {new op::mov_ram_p_t(xy_src(src_token))};
else if (auto dest_o = d1_dest()) return {new op::mov_ram_d1_t(d1_src(src_token), *dest_o)};
if (!d1 && match(_y)) return {op::mov_ram_y_t(y_src(src_token))};
else if (!d1 && match(_a)) return {op::mov_ram_a_t(y_src(src_token))};
else if (!d1 && match(_x)) return {op::mov_ram_x_t(x_src(src_token))};
else if (!d1 && match(_p)) return {op::mov_ram_p_t(x_src(src_token))};
else if (auto dst_o = d1_dst()) return {op::mov_ram_d1_t(*dst_o, d1_src(src_token))};
else
throw error(peek(), "expected x-bus, y-bus, or d-bus destination operand");
} else {
uimm_t<8> imm = uimm_t<8>(peek(), immediate());
consume(comma, "expected `,`");
if (auto dest_o = d1_dest())
return {new op::mov_imm_d1_t(imm, *dest_o)};
if (auto dst_o = d1_dst())
return {op::mov_imm_d1_t(imm, *dst_o)};
else
throw error(peek(), "expected d1 destination operand");
}
} else if (match(_clr)) {
consume(_a, "expected `a` after `clr`");
return {new op::clr_a_t()};
return {op::clr_a_t()};
} else {
return {};
}
}
static uint32_t op_mask(const op::op_t& op)
{
return std::visit([](auto&& arg) -> uint32_t { return arg.mask(); }, op);
}
std::optional<stmt_t *> parser_t::op()
{
bool saw_nop = false;
std::vector<const op::op_t *> ops;
std::vector<op::op_t> ops;
std::vector<const token_t *> tokens;
auto emplace_op = [&](const token_t& token, const op::op_t * a) {
for (std::vector<const op::op_t *>::size_type i = 0; i < ops.size(); i++) {
const op::op_t * b = ops[i];
if ((a->mask() & b->mask() & ~(0b11 << 30)) != 0) {
auto emplace_op = [&](const token_t& token, const op::op_t& a) {
for (decltype(ops)::size_type i = 0; i < ops.size(); i++) {
const op::op_t& b = ops[i];
if ((op_mask(a) & op_mask(b)) != 0) {
dsp::error(*tokens[i], "conflict");
throw error(token, "conflict");
}
@ -319,7 +342,7 @@ std::optional<stmt_t *> parser_t::op()
if (match(_nop)) saw_nop = 1;
else if (auto op_o = alu() ) emplace_op(token, *op_o);
else if (auto op_o = xyd1_bus()) emplace_op(token, *op_o);
else break;
else break;
}
if (ops.size() != 0 || saw_nop)
return {new op::control_word_t(ops)};
@ -327,20 +350,20 @@ std::optional<stmt_t *> parser_t::op()
return {};
}
load::dest_t parser_t::load_dest()
load::dst_t parser_t::load_dst()
{
using namespace dsp::load;
if (match(_mc0)) return dest_t::mc0;
else if (match(_mc1)) return dest_t::mc1;
else if (match(_mc2)) return dest_t::mc2;
else if (match(_mc3)) return dest_t::mc3;
else if (match(_rx)) return dest_t::rx;
else if (match(_pl)) return dest_t::pl;
else if (match(_ra0)) return dest_t::ra0;
else if (match(_wa0)) return dest_t::wa0;
else if (match(_lop)) return dest_t::lop;
else if (match(_pc)) return dest_t::pc;
if (match(_mc0)) return dst_t::mc0;
else if (match(_mc1)) return dst_t::mc1;
else if (match(_mc2)) return dst_t::mc2;
else if (match(_mc3)) return dst_t::mc3;
else if (match(_rx)) return dst_t::rx;
else if (match(_pl)) return dst_t::pl;
else if (match(_ra0)) return dst_t::ra0;
else if (match(_wa0)) return dst_t::wa0;
else if (match(_lop)) return dst_t::lop;
else if (match(_pc)) return dst_t::pc;
else
throw error(peek(), "expected mvi destination");
}
@ -371,14 +394,14 @@ std::optional<stmt_t *> parser_t::load()
const token_t& expr_token = peek();
expr_t * expr = immediate();
consume(comma, "expected `,`");
load::dest_t dest = parser_t::load_dest();
load::dst_t dst = parser_t::load_dst();
if (match(comma)) {
load::cond_t cond = load_cond();
uimm_t<19> imm = uimm_t<19>(expr_token, expr);
return {new load::mvi_cond_t(imm, dest, cond)};
return {new load::mvi_cond_t(imm, dst, cond)};
} else {
uimm_t<25> imm = uimm_t<25>(expr_token, expr);
return {new load::mvi_t(imm, dest)};
return {new load::mvi_t(imm, dst)};
}
} else
return {};
@ -434,29 +457,29 @@ static bool dma_hold_p(const token_t& token)
}
}
static dma::add_mode_t dma_add(const token_t& token)
static dma::add_t dma_add(const token_t& token)
{
using namespace dsp::dma;
switch (token.type) {
case _dma: [[fallthrough]];
case _dmah: return add_mode_t::_2;
case _dmah: return add_t::_2;
case _dma0: [[fallthrough]];
case _dmah0: return add_mode_t::_0;
case _dmah0: return add_t::_0;
case _dma1: [[fallthrough]];
case _dmah1: return add_mode_t::_1;
case _dmah1: return add_t::_1;
case _dma2: [[fallthrough]];
case _dmah2: return add_mode_t::_2;
case _dmah2: return add_t::_2;
case _dma4: [[fallthrough]];
case _dmah4: return add_mode_t::_4;
case _dmah4: return add_t::_4;
case _dma8: [[fallthrough]];
case _dmah8: return add_mode_t::_8;
case _dmah8: return add_t::_8;
case _dma16: [[fallthrough]];
case _dmah16: return add_mode_t::_16;
case _dmah16: return add_t::_16;
case _dma32: [[fallthrough]];
case _dmah32: return add_mode_t::_32;
case _dmah32: return add_t::_32;
case _dma64: [[fallthrough]];
case _dmah64: return add_mode_t::_64;
case _dmah64: return add_t::_64;
default: assert(false);
}
}
@ -486,18 +509,18 @@ dma::dst_t parser_t::dma_dst()
}
}
std::optional<dma::length_ram_t> parser_t::dma_length_ram()
std::optional<dma::ram_t> parser_t::dma_ram()
{
using namespace dsp::dma;
if (match(_m0)) return length_ram_t::m0;
else if (match(_m1)) return length_ram_t::m1;
else if (match(_m2)) return length_ram_t::m2;
else if (match(_m3)) return length_ram_t::m3;
else if (match(_mc0)) return length_ram_t::mc0;
else if (match(_mc1)) return length_ram_t::mc1;
else if (match(_mc2)) return length_ram_t::mc2;
else if (match(_mc3)) return length_ram_t::mc3;
if (match(_m0)) return ram_t::m0;
else if (match(_m1)) return ram_t::m1;
else if (match(_m2)) return ram_t::m2;
else if (match(_m3)) return ram_t::m3;
else if (match(_mc0)) return ram_t::mc0;
else if (match(_mc1)) return ram_t::mc1;
else if (match(_mc2)) return ram_t::mc2;
else if (match(_mc3)) return ram_t::mc3;
else return {};
}
@ -506,27 +529,27 @@ std::optional<stmt_t *> parser_t::dma()
if (dma_p(peek())) {
const token_t& token = advance();
bool hold = dma_hold_p(token);
dma::add_mode_t add = dma_add(token);
dma::add_t add = dma_add(token);
if (match(_d0)) {
consume(comma, "expected `,`");
dma::dst_t dst = dma_dst();
consume(comma, "expected `,`");
if (auto length_ram_o = dma_length_ram()) {
return {new dma::d0_dst_ram_t(hold, add, dst, *length_ram_o)};
if (auto ram_o = dma_ram()) {
return {new dma::d0_dst_ram_t(add, hold, dst, *ram_o)};
} else {
uimm_t<8> imm = uimm_t<8>(peek(), immediate());
return {new dma::d0_dst_imm_t(hold, add, dst, imm)};
return {new dma::d0_dst_imm_t(imm, add, hold, dst)};
}
} else {
dma::src_t src = dma_src();
consume(comma, "expected `,`");
consume(_d0, "expected `d0`");
consume(comma, "expected `,`");
if (auto length_ram_o = dma_length_ram()) {
return {new dma::src_d0_ram_t(hold, add, src, *length_ram_o)};
if (auto ram_o = dma_ram()) {
return {new dma::src_d0_ram_t(add, hold, src, *ram_o)};
} else {
uimm_t<8> imm = uimm_t<8>(peek(), immediate());
return {new dma::src_d0_imm_t(hold, add, src, imm)};
return {new dma::src_d0_imm_t(imm, add, hold, src)};
}
}
} else
@ -555,10 +578,10 @@ std::optional<stmt_t *> parser_t::jump()
if (match(_jmp)) {
if (auto cond_o = jump_cond()) {
consume(comma, "expected `,` after jump condition");
uimm_t<8> imm = uimm_t<8>(peek(), immediate());
return {new jump::jmp_cond_t(*cond_o, imm)};
uimm_t<19> imm = uimm_t<19>(peek(), immediate());
return {new jump::jmp_cond_t(imm, *cond_o)};
} else {
uimm_t<8> imm = uimm_t<8>(peek(), immediate());
uimm_t<25> imm = uimm_t<25>(peek(), immediate());
return {new jump::jmp_t(imm)};
}
} else

View File

@ -6,6 +6,8 @@
#include "token.hpp"
#include "expr.hpp"
#include "stmt.hpp"
#include "stmt_ins.hpp"
#include "control_word.hpp"
namespace dsp {
@ -49,17 +51,17 @@ struct parser_t
expr_t * orl();
expr_t * primary();
std::optional<op::op_t *> alu();
std::optional<op::op_t> alu();
bool xyd1_src();
std::optional<op::d1_dest_t> d1_dest();
std::optional<op::op_t *> xyd1_bus();
std::optional<op::d1_dst_t> d1_dst();
std::optional<op::op_t> xyd1_bus();
std::optional<stmt_t *> op();
load::dest_t load_dest();
load::dst_t load_dst();
load::cond_t load_cond();
std::optional<stmt_t *> load();
dma::src_t dma_src();
dma::dst_t dma_dst();
std::optional<dma::length_ram_t> dma_length_ram();
std::optional<dma::ram_t> dma_ram();
std::optional<stmt_t *> dma();
std::optional<jump::cond_t> jump_cond();
std::optional<stmt_t *> jump();

387
stmt.hpp
View File

@ -1,393 +1,30 @@
#pragma once
#include <vector>
#include <string>
#include <cstdint>
#include "stmt_enum.hpp"
#include "expr.hpp"
#include "bits.hpp"
#include "ins.hpp"
#include "stmt_base.hpp"
namespace dsp {
struct stmt_t
{
virtual void accept(visitor_t<void> const * visitor) const = 0;
virtual uint32_t accept(visitor_t<uint32_t> const * visitor) const = 0;
};
template <typename T>
struct stmt_accept_t : stmt_t {
virtual void accept(visitor_t<void> const * visitor) const {
return visitor->visit(static_cast<const T*>(this));
}
virtual uint32_t accept(visitor_t<uint32_t> const * visitor) const
{
return visitor->visit(static_cast<const T*>(this));
}
};
template <bool S, int N>
struct imm_t {
imm_t(const token_t& token, const expr_t * expr)
: token(token), expr(expr) {}
const token_t& token;
const expr_t * expr;
static constexpr bool sign = S;
static constexpr int bits = N;
static constexpr num_t max = (1L << (bits - static_cast<num_t>(sign))) - 1;
static constexpr num_t min = sign ? -(max + 1) : 0;
num_t normalize(num_t value) const
{
if (!S && value > 2147483648) { // fixme: hack
return value & max;
} else {
return value;
}
}
bool in_range(num_t value) const
{
return value <= max && value >= min;
}
};
template <int N>
using simm_t = imm_t<true, N>;
template <int N>
using uimm_t = imm_t<false, N>;
namespace op {
struct op_t
{
virtual uint32_t mask() const = 0;
virtual uint32_t code() const = 0;
virtual uint32_t bits() const = 0;
};
struct alu_t : op_t, stmt_accept_t<alu_t>
{
alu_t(alu_type_t type)
: type(type) {}
const alu_type_t type;
uint32_t mask() const { return 0b1111 << 26; }
uint32_t code() const { return 0b0000 << 26; }
uint32_t bits() const { return alu_bits(type); }
};
struct mov_ram_x_t : op_t, stmt_accept_t<mov_ram_x_t>
{
mov_ram_x_t(xy_src_t src)
: src(src) {}
const xy_src_t src;
uint32_t mask() const { return 0b100'111 << 20; }
uint32_t code() const { return 0b100'000 << 20; }
uint32_t bits() const { return xy_src_bits(src, 20); }
};
struct mov_mul_p_t : op_t, stmt_accept_t<mov_mul_p_t>
{
mov_mul_p_t() {}
uint32_t mask() const { return 0b011'000 << 20; }
uint32_t code() const { return 0b010'000 << 20; }
uint32_t bits() const { return 0; }
};
struct mov_ram_p_t : op_t, stmt_accept_t<mov_ram_p_t>
{
mov_ram_p_t(xy_src_t src)
: src(src) {}
const xy_src_t src;
uint32_t mask() const { return 0b011'111 << 20; }
uint32_t code() const { return 0b011'000 << 20; }
uint32_t bits() const { return xy_src_bits(src, 20); }
};
struct mov_ram_y_t : op_t, stmt_accept_t<mov_ram_y_t>
{
mov_ram_y_t(xy_src_t src)
: src(src) {}
const xy_src_t src;
uint32_t mask() const { return 0b100'111 << 14; }
uint32_t code() const { return 0b100'000 << 14; }
uint32_t bits() const { return xy_src_bits(src, 14); }
};
struct clr_a_t : op_t, stmt_accept_t<clr_a_t>
{
clr_a_t() {}
uint32_t mask() const { return 0b011'000 << 14; }
uint32_t code() const { return 0b001'000 << 14; }
uint32_t bits() const { return 0; }
};
struct mov_alu_a_t : op_t, stmt_accept_t<mov_alu_a_t>
{
mov_alu_a_t() {}
uint32_t mask() const { return 0b011'000 << 14; }
uint32_t code() const { return 0b010'000 << 14; }
uint32_t bits() const { return 0; }
};
struct mov_ram_a_t : op_t, stmt_accept_t<mov_ram_a_t>
{
mov_ram_a_t(xy_src_t src)
: src(src) {}
const xy_src_t src;
uint32_t mask() const { return 0b011'111 << 14; }
uint32_t code() const { return 0b011'000 << 14; }
uint32_t bits() const { return xy_src_bits(src, 14); }
};
struct mov_imm_d1_t : op_t, stmt_accept_t<mov_imm_d1_t>
{
mov_imm_d1_t(uimm_t<8> imm, d1_dest_t dest)
: imm(imm), dest(dest) {}
const uimm_t<8> imm;
const d1_dest_t dest;
uint32_t mask() const { return 0b11'1111'1111'1111 << 0; }
uint32_t code() const { return 0b01'0000'0000'0000 << 0; }
uint32_t bits() const { return d1_dest_bits(dest); }
};
struct mov_ram_d1_t : op_t, stmt_accept_t<mov_ram_d1_t>
{
mov_ram_d1_t(d1_src_t src, d1_dest_t dest)
: src(src), dest(dest) {}
const d1_src_t src;
const d1_dest_t dest;
uint32_t mask() const { return 0b11'1111'0000'1111 << 0; }
uint32_t code() const { return 0b11'0000'0000'0000 << 0; }
uint32_t bits() const { return d1_dest_bits(dest) | d1_src_bits(src); }
};
struct control_word_t : stmt_accept_t<control_word_t>
{
control_word_t(std::vector<const op::op_t *> ops)
: ops(ops)
{
}
const std::vector<const op_t *> ops;
uint32_t mask() const { return 0b11 << 30; }
uint32_t code() const { return 0b00 << 30; }
uint32_t bits() const { return 0; }
};
} // op
namespace load {
struct mvi_t : stmt_accept_t<mvi_t>
{
mvi_t(uimm_t<25> imm, dest_t dest)
: imm(imm), dest(dest) {}
uint32_t mask() const { return 0xffff'ffff; }
uint32_t code() const { return 0b10'0000'0 << 25; }
uint32_t bits() const { return dest_bits(dest); }
const uimm_t<25> imm;
const dest_t dest;
};
struct mvi_cond_t : stmt_accept_t<mvi_cond_t>
{
mvi_cond_t(uimm_t<19> imm, dest_t dest, cond_t cond)
: imm(imm), dest(dest), cond(cond) {}
const uimm_t<19> imm;
const dest_t dest;
const cond_t cond;
uint32_t mask() const { return 0xffff'ffff; }
uint32_t code() const { return 0b10'0000'1 << 25; }
uint32_t bits() const { return dest_bits(dest)
| cond_bits(cond);
}
};
} // load
namespace dma {
struct d0_dst_imm_t : stmt_accept_t<d0_dst_imm_t>
{
d0_dst_imm_t(bool hold, add_mode_t add, dst_t dst, uimm_t<8> imm)
: hold(hold), add(add), dst(dst), imm(imm) {}
const bool hold;
const add_mode_t add;
const dst_t dst;
const uimm_t<8> imm;
uint32_t mask() const { return 0xffff'ffff; }
uint32_t code() const { return 0b1100 << 28 | 0b00 << 12; }
uint32_t bits() const { return add_mode_bits(add)
| hold_bits(hold)
| dst_bits(dst);
}
};
struct src_d0_imm_t : stmt_accept_t<src_d0_imm_t>
{
src_d0_imm_t(bool hold, add_mode_t add, src_t src, uimm_t<8> imm)
: hold(hold), add(add), src(src), imm(imm) {}
const bool hold;
const add_mode_t add;
const src_t src;
const uimm_t<8> imm;
uint32_t mask() const { return 0xffff'ffff; }
uint32_t code() const { return 0b1100 << 28 | 0b01 << 12; }
uint32_t bits() const { return add_mode_bits(add)
| hold_bits(hold)
| src_bits(src);
}
};
struct d0_dst_ram_t : stmt_accept_t<d0_dst_ram_t>
{
d0_dst_ram_t(bool hold, add_mode_t add, dst_t dst, length_ram_t ram)
: hold(hold), add(add), dst(dst), ram(ram) {}
const bool hold;
const add_mode_t add;
const dst_t dst;
const length_ram_t ram;
uint32_t mask() const { return 0xffff'ffff; }
uint32_t code() const { return 0b1100 << 28 | 0b10 << 12; }
uint32_t bits() const { return add_mode_bits(add)
| hold_bits(hold)
| dst_bits(dst)
| length_ram_bits(ram);
}
};
struct src_d0_ram_t : stmt_accept_t<src_d0_ram_t>
{
// from src to d0
src_d0_ram_t(bool hold, add_mode_t add, src_t src, length_ram_t ram)
: hold(hold), add(add), src(src), ram(ram) {}
const bool hold;
const add_mode_t add;
const src_t src;
const length_ram_t ram;
uint32_t mask() const { return 0xffff'ffff; }
uint32_t code() const { return 0b1100 << 28 | 0b11 << 12; }
uint32_t bits() const { return add_mode_bits(add)
| hold_bits(hold)
| src_bits(src)
| length_ram_bits(ram);
}
};
} // dma
namespace jump
{
struct jmp_t : stmt_accept_t<jmp_t>
{
jmp_t(uimm_t<8> imm)
: imm(imm) {}
const uimm_t<8> imm;
uint32_t mask() const { return 0xffff'ffff; }
uint32_t code() const { return 0b1101'00'0 << 25; }
uint32_t bits() const { return 0; }
};
struct jmp_cond_t : stmt_accept_t<jmp_cond_t>
{
jmp_cond_t(cond_t cond, uimm_t<8> imm)
: cond(cond), imm(imm) {}
const cond_t cond;
const uimm_t<8> imm;
uint32_t mask() const { return 0xffff'ffff; }
uint32_t code() const { return 0b1101'00'1 << 25; }
uint32_t bits() const { return cond_bits(cond); }
};
} // jump
namespace loop {
struct btm_t : stmt_accept_t<btm_t>
{
uint32_t mask() const { return 0xffff'ffff; }
uint32_t code() const { return 0b1110'0 << 27; }
uint32_t bits() const { return 0; }
};
struct lps_t : stmt_accept_t<lps_t>
{
uint32_t mask() const { return 0xffff'ffff; }
uint32_t code() const { return 0b1110'1 << 27; }
uint32_t bits() const { return 0; }
};
} // loop
namespace end {
struct end_t : stmt_accept_t<end_t>
{
uint32_t mask() const { return 0xffff'ffff; }
uint32_t code() const { return 0b1111'0 << 27; }
uint32_t bits() const { return 0; }
};
struct endi_t : stmt_accept_t<endi_t>
{
uint32_t mask() const { return 0xffff'ffff; }
uint32_t code() const { return 0b1111'1 << 27; }
uint32_t bits() const { return 0; }
};
} // end
namespace nop {
struct nop_t : stmt_accept_t<nop_t>
struct nop_t : stmt_accept_t<nop_t>, ins_t<nop_t>
{
nop_t()
{}
nop_t(uint32_t code)
{
(void)code;
}
uint32_t mask() const { return 0xffff'ffff; }
uint32_t code() const { return 0x0000'0000; }
uint32_t bits() const { return 0; }
};
}
} // namespace nop
struct assign_t : stmt_accept_t<assign_t>
{

25
stmt_base.hpp Normal file
View File

@ -0,0 +1,25 @@
#pragma once
#include "visitor.hpp"
namespace dsp {
struct stmt_t
{
virtual void accept(visitor_t<void> const * visitor) const = 0;
virtual uint32_t accept(visitor_t<uint32_t> const * visitor) const = 0;
};
template <typename T>
struct stmt_accept_t : stmt_t {
virtual void accept(visitor_t<void> const * visitor) const {
return visitor->visit(static_cast<const T*>(this));
}
virtual uint32_t accept(visitor_t<uint32_t> const * visitor) const
{
return visitor->visit(static_cast<const T*>(this));
}
};
}

View File

@ -1,102 +0,0 @@
#pragma once
namespace dsp {
namespace op {
enum struct alu_type_t : int {
andl,
orl,
xorl,
add,
sub,
ad2,
sr,
rr,
sl,
rl,
rl8,
};
enum struct xy_src_t {
m0 , m1 , m2 , m3 ,
mc0, mc1, mc2, mc3,
};
enum struct d1_dest_t {
mc0, mc1, mc2, mc3,
rx , pl ,
ra0, wa0,
lop, top,
ct0, ct1, ct2, ct3,
};
enum struct d1_src_t {
m0 , m1 , m2 , m3 ,
mc0, mc1, mc2, mc3,
all, alh,
};
}
namespace load {
enum struct dest_t {
mc0, mc1, mc2, mc3,
rx , pl ,
ra0, wa0,
lop, pc ,
};
enum struct cond_t {
z , nz ,
s , ns ,
c , nc ,
t0, nt0,
zs, nzs,
};
} // load
namespace dma {
enum struct add_mode_t {
_0 ,
_1 ,
_2 ,
_4 ,
_8 ,
_16,
_32,
_64,
};
enum struct src_t {
mc0, mc1, mc2, mc3,
};
enum struct dst_t {
mc0, mc1, mc2, mc3,
prg,
};
enum struct length_ram_t {
m0 , m1 , m2 , m3 ,
mc0, mc1, mc2, mc3,
};
} // dma
namespace jump {
enum struct cond_t {
z , nz ,
s , ns ,
c , nc ,
t0, nt0,
zs, nzs,
};
} // jump
}

1264
stmt_ins.hpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
#include "stmt_string.hpp"
#include "stmt_enum.hpp"
#include "stmt_ins.hpp"
#define i(v) (static_cast<int>(v))
@ -7,46 +7,43 @@ namespace dsp {
namespace op {
const std::string alu_type_string[] = {
[i(alu_type_t::andl)] = "andl",
[i(alu_type_t::orl )] = "orl",
[i(alu_type_t::xorl)] = "xorl",
[i(alu_type_t::add )] = "add",
[i(alu_type_t::sub )] = "sub",
[i(alu_type_t::ad2 )] = "ad2",
[i(alu_type_t::sr )] = "sr",
[i(alu_type_t::rr )] = "rr",
[i(alu_type_t::sl )] = "sl",
[i(alu_type_t::rl )] = "rl",
[i(alu_type_t::rl8 )] = "rl8",
const std::string x_src_string[] = {
[i(x_src_t::m0 )] = "m0" ,
[i(x_src_t::m1 )] = "m1" ,
[i(x_src_t::m2 )] = "m2" ,
[i(x_src_t::m3 )] = "m3" ,
[i(x_src_t::mc0)] = "mc0",
[i(x_src_t::mc1)] = "mc1",
[i(x_src_t::mc2)] = "mc2",
[i(x_src_t::mc3)] = "mc3",
};
const std::string xy_src_string[] = {
[i(xy_src_t::m0 )] = "m0" ,
[i(xy_src_t::m1 )] = "m1" ,
[i(xy_src_t::m2 )] = "m2" ,
[i(xy_src_t::m3 )] = "m3" ,
[i(xy_src_t::mc0)] = "mc0",
[i(xy_src_t::mc1)] = "mc1",
[i(xy_src_t::mc2)] = "mc2",
[i(xy_src_t::mc3)] = "mc3",
const std::string y_src_string[] = {
[i(y_src_t::m0 )] = "m0" ,
[i(y_src_t::m1 )] = "m1" ,
[i(y_src_t::m2 )] = "m2" ,
[i(y_src_t::m3 )] = "m3" ,
[i(y_src_t::mc0)] = "mc0",
[i(y_src_t::mc1)] = "mc1",
[i(y_src_t::mc2)] = "mc2",
[i(y_src_t::mc3)] = "mc3",
};
const std::string d1_dest_string[] = {
[i(d1_dest_t::mc0)] = "mc0",
[i(d1_dest_t::mc1)] = "mc1",
[i(d1_dest_t::mc2)] = "mc2",
[i(d1_dest_t::mc3)] = "mc3",
[i(d1_dest_t::rx )] = "rx" ,
[i(d1_dest_t::pl )] = "pl" ,
[i(d1_dest_t::ra0)] = "ra0",
[i(d1_dest_t::wa0)] = "wa0",
[i(d1_dest_t::lop)] = "lop",
[i(d1_dest_t::top)] = "top",
[i(d1_dest_t::ct0)] = "ct0",
[i(d1_dest_t::ct1)] = "ct1",
[i(d1_dest_t::ct2)] = "ct2",
[i(d1_dest_t::ct3)] = "ct3",
const std::string d1_dst_string[] = {
[i(d1_dst_t::mc0)] = "mc0",
[i(d1_dst_t::mc1)] = "mc1",
[i(d1_dst_t::mc2)] = "mc2",
[i(d1_dst_t::mc3)] = "mc3",
[i(d1_dst_t::rx )] = "rx" ,
[i(d1_dst_t::pl )] = "pl" ,
[i(d1_dst_t::ra0)] = "ra0",
[i(d1_dst_t::wa0)] = "wa0",
[i(d1_dst_t::lop)] = "lop",
[i(d1_dst_t::top)] = "top",
[i(d1_dst_t::ct0)] = "ct0",
[i(d1_dst_t::ct1)] = "ct1",
[i(d1_dst_t::ct2)] = "ct2",
[i(d1_dst_t::ct3)] = "ct3",
};
const std::string d1_src_string[] = {
@ -66,17 +63,17 @@ const std::string d1_src_string[] = {
namespace load {
const std::string dest_string[] = {
[i(dest_t::mc0)] = "mc0",
[i(dest_t::mc1)] = "mc1",
[i(dest_t::mc2)] = "mc2",
[i(dest_t::mc3)] = "mc3",
[i(dest_t::rx )] = "rx" ,
[i(dest_t::pl )] = "pl" ,
[i(dest_t::ra0)] = "ra0",
[i(dest_t::wa0)] = "wa0",
[i(dest_t::lop)] = "lop",
[i(dest_t::pc )] = "pc" ,
const std::string dst_string[] = {
[i(dst_t::mc0)] = "mc0",
[i(dst_t::mc1)] = "mc1",
[i(dst_t::mc2)] = "mc2",
[i(dst_t::mc3)] = "mc3",
[i(dst_t::rx )] = "rx" ,
[i(dst_t::pl )] = "pl" ,
[i(dst_t::ra0)] = "ra0",
[i(dst_t::wa0)] = "wa0",
[i(dst_t::lop)] = "lop",
[i(dst_t::pc )] = "pc" ,
};
const std::string cond_string[] = {
@ -102,14 +99,14 @@ const std::string hold_mode_string[] = {
};
const std::string add_mode_string[] = {
[i(add_mode_t::_0 )] = "0" ,
[i(add_mode_t::_1 )] = "1" ,
[i(add_mode_t::_2 )] = "2" ,
[i(add_mode_t::_4 )] = "4" ,
[i(add_mode_t::_8 )] = "8" ,
[i(add_mode_t::_16)] = "16",
[i(add_mode_t::_32)] = "32",
[i(add_mode_t::_64)] = "64",
[i(add_t::_0 )] = "0" ,
[i(add_t::_1 )] = "1" ,
[i(add_t::_2 )] = "2" ,
[i(add_t::_4 )] = "4" ,
[i(add_t::_8 )] = "8" ,
[i(add_t::_16)] = "16",
[i(add_t::_32)] = "32",
[i(add_t::_64)] = "64",
};
const std::string src_string[] = {
@ -128,14 +125,14 @@ const std::string dst_string[] = {
};
const std::string length_ram_string[] = {
[i(length_ram_t::m0 )] = "m0" ,
[i(length_ram_t::m1 )] = "m1" ,
[i(length_ram_t::m2 )] = "m2" ,
[i(length_ram_t::m3 )] = "m3" ,
[i(length_ram_t::mc0)] = "mc0",
[i(length_ram_t::mc1)] = "mc1",
[i(length_ram_t::mc2)] = "mc2",
[i(length_ram_t::mc3)] = "mc3",
[i(ram_t::m0 )] = "m0" ,
[i(ram_t::m1 )] = "m1" ,
[i(ram_t::m2 )] = "m2" ,
[i(ram_t::m3 )] = "m3" ,
[i(ram_t::mc0)] = "mc0",
[i(ram_t::mc1)] = "mc1",
[i(ram_t::mc2)] = "mc2",
[i(ram_t::mc3)] = "mc3",
};
} // dma

View File

@ -7,15 +7,16 @@ namespace dsp {
namespace op {
extern const std::string alu_type_string[];
extern const std::string xy_src_string[];
extern const std::string d1_dest_string[];
extern const std::string x_src_string[];
extern const std::string y_src_string[];
extern const std::string d1_dst_string[];
extern const std::string d1_src_string[];
}
namespace load {
extern const std::string dest_string[];
extern const std::string dst_string[];
extern const std::string cond_string[];
} // load

View File

@ -4,12 +4,16 @@ SRC = sample1.asm sample2a.asm sample2b.asm sample3.asm
#SRC += cmpnm.asm fbtrans.asm loop_pr.asm udiv.asm
EXPECT = $(patsubst %.asm,expect/%.bin,$(SRC))
ACTUAL = $(patsubst %.asm,actual/%.bin,$(SRC))
EXPECT_TXT = $(patsubst %.bin,%.txt,$(EXPECT))
ACTUAL_TXT = $(patsubst %.bin,%.txt,$(ACTUAL))
ALL = $(EXPECT) $(ACTUAL)
ALL_TXT = $(patsubst %.bin,%.txt,$(ALL))
ALL_TXT = $(EXPECT_TXT) $(ACTUAL_TXT)
all: $(ALL)
all-expect: $(EXPECT)
all-actual: $(ACTUAL)
expect: $(EXPECT)
actual: $(ACTUAL)
expect-txt: $(EXPECT_TXT)
actual-txt: $(ACTUAL_TXT)
all-txt: $(ALL_TXT)
%.s: %.asm
@ -35,7 +39,7 @@ expect/%.bin: %.s
@mkdir -p $(dir $@)
srec_cat -Output $@ -Binary $<
actual/%.bin: %.asm
actual/%.bin: %.asm ../scu-dsp-asm
@mkdir -p $(dir $@)
../scu-dsp-asm $< $@

View File

@ -64,7 +64,9 @@ struct token_t {
const std::string_view lexeme;
const literal_t literal;
token_t() = delete;
constexpr token_t()
: pos({0, 0}), type(type_t::number), lexeme(""), literal({})
{ }
constexpr token_t(token_pos_t pos, type_t type, const std::string_view lexeme, num_type number)
: pos(pos), type(type), lexeme(lexeme), literal(number)

View File

@ -11,7 +11,18 @@ struct unary_t;
// instructions
namespace op {
struct alu_t;
struct andl_t;
struct orl_t;
struct xorl_t;
struct add_t;
struct sub_t;
struct ad2_t;
struct sr_t;
struct rr_t;
struct sl_t;
struct rl_t;
struct rl8_t;
struct mov_ram_x_t;
struct mov_ram_x_t;
struct mov_mul_p_t;
@ -22,6 +33,7 @@ struct mov_alu_a_t;
struct mov_ram_a_t;
struct mov_imm_d1_t;
struct mov_ram_d1_t;
struct control_word_t;
}

View File

@ -14,7 +14,18 @@ struct visitor_t
virtual T visit(const literal_t * expr) const = 0;
virtual T visit(const unary_t * expr) const = 0;
virtual T visit(const op::alu_t * alu) const = 0;
virtual T visit(const op::andl_t * andl) const = 0;
virtual T visit(const op::orl_t * orl) const = 0;
virtual T visit(const op::xorl_t * xorl) const = 0;
virtual T visit(const op::add_t * add) const = 0;
virtual T visit(const op::sub_t * sub) const = 0;
virtual T visit(const op::ad2_t * ad2) const = 0;
virtual T visit(const op::sr_t * sr) const = 0;
virtual T visit(const op::rr_t * rr) const = 0;
virtual T visit(const op::sl_t * sl) const = 0;
virtual T visit(const op::rl_t * rl) const = 0;
virtual T visit(const op::rl8_t * rl8) const = 0;
virtual T visit(const op::mov_ram_x_t * mov_ram_x) const = 0;
virtual T visit(const op::mov_mul_p_t * mov_mul_p) const = 0;
virtual T visit(const op::mov_ram_p_t * mov_ram_p) const = 0;
@ -24,6 +35,7 @@ struct visitor_t
virtual T visit(const op::mov_ram_a_t * mov_ram_a) const = 0;
virtual T visit(const op::mov_imm_d1_t * mov_imm_d1) const = 0;
virtual T visit(const op::mov_ram_d1_t * mov_ram_d1) const = 0;
virtual T visit(const op::control_word_t * control_word) const = 0;
virtual T visit(const load::mvi_t * mvi) const = 0;