diff --git a/.gitignore b/.gitignore index dd411da..ff325b4 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,5 @@ scu-dsp-asm.* *.d test/*.s test/*.txt -*.bin \ No newline at end of file +*.bin +__pycache__ \ No newline at end of file diff --git a/Makefile b/Makefile index 824bebf..99aa9f9 100644 --- a/Makefile +++ b/Makefile @@ -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 diff --git a/ast_emitter.cpp b/ast_emitter.cpp index 1d660ee..f3556c7 100644 --- a/ast_emitter.cpp +++ b/ast_emitter.cpp @@ -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(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; } diff --git a/ast_emitter.hpp b/ast_emitter.hpp index 61a179a..b5615ef 100644 --- a/ast_emitter.hpp +++ b/ast_emitter.hpp @@ -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 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; diff --git a/ast_printer.cpp b/ast_printer.cpp index 06c73ce..7da7a01 100644 --- a/ast_printer.cpp +++ b/ast_printer.cpp @@ -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(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(mov_ram_x->src)], "x"); + parenthesize("mov", op::x_src_string[static_cast(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(mov_ram_p->src)], "p"); + parenthesize("mov", op::x_src_string[static_cast(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(mov_ram_y->src)], "y"); + parenthesize("mov", op::y_src_string[static_cast(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(mov_ram_a->src)], "a"); + parenthesize("mov", op::y_src_string[static_cast(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(mov_imm_d1->dest)]); + op::d1_dst_string[static_cast(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(mov_ram_d1->src)], - op::d1_dest_string[static_cast(mov_ram_d1->dest)]); + op::d1_src_string[static_cast(mov_ram_d1->src.value)], + op::d1_dst_string[static_cast(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(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(mvi->dest)]); + parenthesize("mvi", mvi->imm.expr, load::dst_string[static_cast(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(mvi_cond->dest)], - load::cond_string[static_cast(mvi_cond->cond)]); + load::dst_string[static_cast(mvi_cond->dst.value)], + load::cond_string[static_cast(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(hold)] - + dma::add_mode_string[static_cast(add)]; + return dma::hold_mode_string[static_cast(hold.value)] + + dma::add_mode_string[static_cast(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(src_d0_imm->src)], + dma::src_string[static_cast(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(d0_dst_imm->dst)], + dma::dst_string[static_cast(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(src_d0_ram->src)], + dma::src_string[static_cast(src_d0_ram->src.value)], "d0", - dma::length_ram_string[static_cast(src_d0_ram->ram)]); + dma::length_ram_string[static_cast(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(d0_dst_ram->dst)], - dma::length_ram_string[static_cast(d0_dst_ram->ram)]); + dma::dst_string[static_cast(d0_dst_ram->dst.value)], + dma::length_ram_string[static_cast(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(jmp_cond->cond)], + jump::cond_string[static_cast(jmp_cond->cond.value)], jmp_cond->imm.expr); } diff --git a/ast_printer.hpp b/ast_printer.hpp index 5f76ae2..e762228 100644 --- a/ast_printer.hpp +++ b/ast_printer.hpp @@ -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 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; diff --git a/ast_resolver.cpp b/ast_resolver.cpp index e9ace90..47d97e4 100644 --- a/ast_resolver.cpp +++ b/ast_resolver.cpp @@ -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 diff --git a/ast_resolver.hpp b/ast_resolver.hpp index 82cb7ae..1cacc90 100644 --- a/ast_resolver.hpp +++ b/ast_resolver.hpp @@ -37,7 +37,18 @@ struct resolver_t : visitor_t 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; diff --git a/bits.hpp b/bits.hpp deleted file mode 100644 index cc6f34d..0000000 --- a/bits.hpp +++ /dev/null @@ -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 diff --git a/control_word.hpp b/control_word.hpp new file mode 100644 index 0000000..c58f773 --- /dev/null +++ b/control_word.hpp @@ -0,0 +1,84 @@ +#pragma once + +#include +#include +#include +#include + +#include "stmt_base.hpp" +#include "stmt_ins.hpp" + +namespace dsp { + +namespace op { +using op_t = std::variant; + +struct control_word_t : stmt_accept_t +{ + control_word_t(std::vector ops) + : ops(ops) + { + } + + std::vector build_ops(uint32_t code) + { + std::vector ops; + if (andl_t::pred(code)) ops.emplace_back(op_t{std::in_place_type, code}); + else if (orl_t::pred(code)) ops.emplace_back(op_t{std::in_place_type, code}); + else if (xorl_t::pred(code)) ops.emplace_back(op_t{std::in_place_type, code}); + else if (add_t::pred(code)) ops.emplace_back(op_t{std::in_place_type, code}); + else if (sub_t::pred(code)) ops.emplace_back(op_t{std::in_place_type, code}); + else if (ad2_t::pred(code)) ops.emplace_back(op_t{std::in_place_type, code}); + else if (sr_t::pred(code)) ops.emplace_back(op_t{std::in_place_type, code}); + else if (rr_t::pred(code)) ops.emplace_back(op_t{std::in_place_type, code}); + else if (sl_t::pred(code)) ops.emplace_back(op_t{std::in_place_type, code}); + else if (rl_t::pred(code)) ops.emplace_back(op_t{std::in_place_type, code}); + else if (rl8_t::pred(code)) ops.emplace_back(op_t{std::in_place_type, code}); + else if (mov_ram_x_t::pred(code)) ops.emplace_back(op_t{std::in_place_type, code}); + else if (mov_mul_p_t::pred(code)) ops.emplace_back(op_t{std::in_place_type, code}); + else if (mov_ram_p_t::pred(code)) ops.emplace_back(op_t{std::in_place_type, code}); + else if (mov_ram_y_t::pred(code)) ops.emplace_back(op_t{std::in_place_type, code}); + else if (clr_a_t::pred(code)) ops.emplace_back(op_t{std::in_place_type, code}); + else if (mov_alu_a_t::pred(code)) ops.emplace_back(op_t{std::in_place_type, code}); + else if (mov_ram_a_t::pred(code)) ops.emplace_back(op_t{std::in_place_type, code}); + else if (mov_imm_d1_t::pred(code)) ops.emplace_back(op_t{std::in_place_type, code}); + else if (mov_ram_d1_t::pred(code)) ops.emplace_back(op_t{std::in_place_type, 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 ops; + + uint32_t mask() const { return 0b11 << 30; } + uint32_t code() const { return 0b00 << 30; } + uint32_t bits() const { return 0; } +}; + +} + +} diff --git a/dsp-notes.csv b/dsp-notes.csv new file mode 100644 index 0000000..d40b7bf --- /dev/null +++ b/dsp-notes.csv @@ -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,,,,,,,,,,,,,,,,,,,,,,,,,,,, diff --git a/dsp-notes.ods b/dsp-notes.ods index fd2c836..15224e0 100644 Binary files a/dsp-notes.ods and b/dsp-notes.ods differ diff --git a/error.hpp b/error.hpp index 1dc436c..d020f12 100644 --- a/error.hpp +++ b/error.hpp @@ -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); diff --git a/build_radix_tree.py b/gen/build_radix_tree.py similarity index 100% rename from build_radix_tree.py rename to gen/build_radix_tree.py diff --git a/gen/generate.py b/gen/generate.py new file mode 100644 index 0000000..7f3c99e --- /dev/null +++ b/gen/generate.py @@ -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 diff --git a/gen/generate_notes.py b/gen/generate_notes.py new file mode 100644 index 0000000..66b7c60 --- /dev/null +++ b/gen/generate_notes.py @@ -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 " + yield "#include " + 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]) diff --git a/gen/parse_notes.py b/gen/parse_notes.py new file mode 100644 index 0000000..4afa2e1 --- /dev/null +++ b/gen/parse_notes.py @@ -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) diff --git a/gen/template.cpp b/gen/template.cpp new file mode 100644 index 0000000..3a2122e --- /dev/null +++ b/gen/template.cpp @@ -0,0 +1,187 @@ +#include + +#include "imm.hpp" +#include "stmt_base.hpp" + +namespace dsp { + +template +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 +struct ins_imm_t : ins_t +{ + ins_imm_t(uimm_t imm) + : imm(imm) {} + + const uimm_t imm; + + uint32_t render(visitor_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, ins_imm_t +{ + 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(); + } +}; + +} + +} diff --git a/imm.hpp b/imm.hpp new file mode 100644 index 0000000..ce65060 --- /dev/null +++ b/imm.hpp @@ -0,0 +1,47 @@ +#pragma once + +#include "expr.hpp" + +namespace dsp { + +static const token_t null_token; + +template +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(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 +using simm_t = imm_t; + +template +using uimm_t = imm_t; + +} diff --git a/ins.hpp b/ins.hpp new file mode 100644 index 0000000..d6a4604 --- /dev/null +++ b/ins.hpp @@ -0,0 +1,45 @@ +#pragma once + +#include + +#include "imm.hpp" + +namespace dsp { + +template +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 +struct ins_imm_t : ins_t +{ + ins_imm_t(uimm_t imm) + : imm(imm) {} + + const uimm_t imm; + + uint32_t render(visitor_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); + } +}; + +} diff --git a/parser.cpp b/parser.cpp index b1856f8..d66737b 100644 --- a/parser.cpp +++ b/parser.cpp @@ -173,21 +173,22 @@ void parser_t::synchronize() } */ -std::optional parser_t::alu() +std::optional 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}}; + else if (match(_or )) return {op_t{std::in_place_type}}; + else if (match(_xor)) return {op_t{std::in_place_type}}; + else if (match(_add)) return {op_t{std::in_place_type}}; + else if (match(_sub)) return {op_t{std::in_place_type}}; + else if (match(_ad2)) return {op_t{std::in_place_type}}; + else if (match(_sr )) return {op_t{std::in_place_type}}; + else if (match(_rr )) return {op_t{std::in_place_type}}; + else if (match(_sl )) return {op_t{std::in_place_type}}; + else if (match(_rl )) return {op_t{std::in_place_type}}; + else if (match(_rl8)) return {op_t{std::in_place_type}}; 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 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 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 parser_t::xyd1_bus() +std::optional 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 parser_t::op() { bool saw_nop = false; - std::vector ops; + std::vector ops; std::vector tokens; - auto emplace_op = [&](const token_t& token, const op::op_t * a) { - for (std::vector::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 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 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 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 parser_t::dma_length_ram() +std::optional 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 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 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 diff --git a/parser.hpp b/parser.hpp index 58e6468..b2e412d 100644 --- a/parser.hpp +++ b/parser.hpp @@ -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 alu(); + std::optional alu(); bool xyd1_src(); - std::optional d1_dest(); - std::optional xyd1_bus(); + std::optional d1_dst(); + std::optional xyd1_bus(); std::optional op(); - load::dest_t load_dest(); + load::dst_t load_dst(); load::cond_t load_cond(); std::optional load(); dma::src_t dma_src(); dma::dst_t dma_dst(); - std::optional dma_length_ram(); + std::optional dma_ram(); std::optional dma(); std::optional jump_cond(); std::optional jump(); diff --git a/stmt.hpp b/stmt.hpp index a22c807..823403a 100644 --- a/stmt.hpp +++ b/stmt.hpp @@ -1,393 +1,30 @@ #pragma once -#include -#include #include -#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 const * visitor) const = 0; - virtual uint32_t accept(visitor_t const * visitor) const = 0; -}; - -template -struct stmt_accept_t : stmt_t { - virtual void accept(visitor_t const * visitor) const { - return visitor->visit(static_cast(this)); - } - - virtual uint32_t accept(visitor_t const * visitor) const - { - return visitor->visit(static_cast(this)); - } -}; - -template -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(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 -using simm_t = imm_t; - -template -using uimm_t = imm_t; - -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_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(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() {} - - 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(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(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() {} - - 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() {} - - 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(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(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(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(std::vector ops) - : ops(ops) - { - } - - const std::vector 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(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(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(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(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(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 -{ - // 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(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(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 -{ - 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 -{ - 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 -{ - 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 -{ - 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 +struct nop_t : stmt_accept_t, ins_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 { diff --git a/stmt_base.hpp b/stmt_base.hpp new file mode 100644 index 0000000..068fcb2 --- /dev/null +++ b/stmt_base.hpp @@ -0,0 +1,25 @@ +#pragma once + +#include "visitor.hpp" + +namespace dsp { + +struct stmt_t +{ + virtual void accept(visitor_t const * visitor) const = 0; + virtual uint32_t accept(visitor_t const * visitor) const = 0; +}; + +template +struct stmt_accept_t : stmt_t { + virtual void accept(visitor_t const * visitor) const { + return visitor->visit(static_cast(this)); + } + + virtual uint32_t accept(visitor_t const * visitor) const + { + return visitor->visit(static_cast(this)); + } +}; + +} diff --git a/stmt_enum.hpp b/stmt_enum.hpp deleted file mode 100644 index 7afb8db..0000000 --- a/stmt_enum.hpp +++ /dev/null @@ -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 - -} diff --git a/stmt_ins.hpp b/stmt_ins.hpp new file mode 100644 index 0000000..45299db --- /dev/null +++ b/stmt_ins.hpp @@ -0,0 +1,1264 @@ +#pragma once + +#include +#include + +#include "imm.hpp" +#include "ins.hpp" +#include "stmt_base.hpp" + +namespace dsp { + namespace op { + + struct x_src_t { + enum value_t { + m0, + m1, + m2, + m3, + mc0, + mc1, + mc2, + mc3, + }; + + const value_t value; + + constexpr x_src_t(value_t value) + : value(value) {} + + constexpr x_src_t(uint32_t code) + : value(to_value(code)) {} + + static constexpr uint32_t mask() { return 0b111 << 20; } + + static constexpr value_t to_value(uint32_t code) + { + using enum value_t; + + switch (code & mask()) { + case 0b000 << 20: return m0; + case 0b001 << 20: return m1; + case 0b010 << 20: return m2; + case 0b011 << 20: return m3; + case 0b100 << 20: return mc0; + case 0b101 << 20: return mc1; + case 0b110 << 20: return mc2; + case 0b111 << 20: return mc3; + default: + std::cerr << "invalid op x_src code: " << (code & mask()) << std::endl; + throw std::runtime_error("invalid code"); + } + } + + uint32_t bits() const + { + using enum value_t; + + switch (value) { + case m0: return 0b000 << 20; + case m1: return 0b001 << 20; + case m2: return 0b010 << 20; + case m3: return 0b011 << 20; + case mc0: return 0b100 << 20; + case mc1: return 0b101 << 20; + case mc2: return 0b110 << 20; + case mc3: return 0b111 << 20; + default: __builtin_unreachable(); + } + } + }; + + struct y_src_t { + enum value_t { + m0, + m1, + m2, + m3, + mc0, + mc1, + mc2, + mc3, + }; + + const value_t value; + + constexpr y_src_t(value_t value) + : value(value) {} + + constexpr y_src_t(uint32_t code) + : value(to_value(code)) {} + + static constexpr uint32_t mask() { return 0b111 << 14; } + + static constexpr value_t to_value(uint32_t code) + { + using enum value_t; + + switch (code & mask()) { + case 0b000 << 14: return m0; + case 0b001 << 14: return m1; + case 0b010 << 14: return m2; + case 0b011 << 14: return m3; + case 0b100 << 14: return mc0; + case 0b101 << 14: return mc1; + case 0b110 << 14: return mc2; + case 0b111 << 14: return mc3; + default: + std::cerr << "invalid op y_src code: " << (code & mask()) << std::endl; + throw std::runtime_error("invalid code"); + } + } + + uint32_t bits() const + { + using enum value_t; + + switch (value) { + case m0: return 0b000 << 14; + case m1: return 0b001 << 14; + case m2: return 0b010 << 14; + case m3: return 0b011 << 14; + case mc0: return 0b100 << 14; + case mc1: return 0b101 << 14; + case mc2: return 0b110 << 14; + case mc3: return 0b111 << 14; + default: __builtin_unreachable(); + } + } + }; + + struct d1_src_t { + enum value_t { + m0, + m1, + m2, + m3, + mc0, + mc1, + mc2, + mc3, + all, + alh, + }; + + const value_t value; + + constexpr d1_src_t(value_t value) + : value(value) {} + + constexpr d1_src_t(uint32_t code) + : value(to_value(code)) {} + + static constexpr uint32_t mask() { return 0b1111 << 0; } + + static constexpr value_t to_value(uint32_t code) + { + using enum value_t; + + switch (code & mask()) { + case 0b0000 << 0: return m0; + case 0b0001 << 0: return m1; + case 0b0010 << 0: return m2; + case 0b0011 << 0: return m3; + case 0b0100 << 0: return mc0; + case 0b0101 << 0: return mc1; + case 0b0110 << 0: return mc2; + case 0b0111 << 0: return mc3; + case 0b1001 << 0: return all; + case 0b1010 << 0: return alh; + default: + std::cerr << "invalid op d1_src code: " << (code & mask()) << std::endl; + throw std::runtime_error("invalid code"); + } + } + + uint32_t bits() const + { + using enum value_t; + + switch (value) { + 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(); + } + } + }; + + struct d1_dst_t { + enum value_t { + mc0, + mc1, + mc2, + mc3, + rx, + pl, + ra0, + wa0, + lop, + top, + ct0, + ct1, + ct2, + ct3, + }; + + const value_t value; + + constexpr d1_dst_t(value_t value) + : value(value) {} + + constexpr d1_dst_t(uint32_t code) + : value(to_value(code)) {} + + static constexpr uint32_t mask() { return 0b1111 << 8; } + + static constexpr value_t to_value(uint32_t code) + { + using enum value_t; + + switch (code & mask()) { + case 0b0000 << 8: return mc0; + case 0b0001 << 8: return mc1; + case 0b0010 << 8: return mc2; + case 0b0011 << 8: return mc3; + case 0b0100 << 8: return rx; + case 0b0101 << 8: return pl; + case 0b0110 << 8: return ra0; + case 0b0111 << 8: return wa0; + case 0b1010 << 8: return lop; + case 0b1011 << 8: return top; + case 0b1100 << 8: return ct0; + case 0b1101 << 8: return ct1; + case 0b1110 << 8: return ct2; + case 0b1111 << 8: return ct3; + default: + std::cerr << "invalid op d1_dst 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 << 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(); + } + } + }; + + struct andl_t : stmt_accept_t, ins_t + { + + andl_t() + {} + + andl_t(uint32_t code) + { (void)code; } + + + static uint32_t mask() { return 0b1111 << 26; } + static uint32_t code() { return 0b0001 << 26; } + uint32_t bits() const { return 0; } + }; + + struct orl_t : stmt_accept_t, ins_t + { + + orl_t() + {} + + orl_t(uint32_t code) + { (void)code; } + + + static uint32_t mask() { return 0b1111 << 26; } + static uint32_t code() { return 0b0010 << 26; } + uint32_t bits() const { return 0; } + }; + + struct xorl_t : stmt_accept_t, ins_t + { + + xorl_t() + {} + + xorl_t(uint32_t code) + { (void)code; } + + + static uint32_t mask() { return 0b1111 << 26; } + static uint32_t code() { return 0b0011 << 26; } + uint32_t bits() const { return 0; } + }; + + struct add_t : stmt_accept_t, ins_t + { + + add_t() + {} + + add_t(uint32_t code) + { (void)code; } + + + static uint32_t mask() { return 0b1111 << 26; } + static uint32_t code() { return 0b0100 << 26; } + uint32_t bits() const { return 0; } + }; + + struct sub_t : stmt_accept_t, ins_t + { + + sub_t() + {} + + sub_t(uint32_t code) + { (void)code; } + + + static uint32_t mask() { return 0b1111 << 26; } + static uint32_t code() { return 0b0101 << 26; } + uint32_t bits() const { return 0; } + }; + + struct ad2_t : stmt_accept_t, ins_t + { + + ad2_t() + {} + + ad2_t(uint32_t code) + { (void)code; } + + + static uint32_t mask() { return 0b1111 << 26; } + static uint32_t code() { return 0b0110 << 26; } + uint32_t bits() const { return 0; } + }; + + struct sr_t : stmt_accept_t, ins_t + { + + sr_t() + {} + + sr_t(uint32_t code) + { (void)code; } + + + static uint32_t mask() { return 0b1111 << 26; } + static uint32_t code() { return 0b1000 << 26; } + uint32_t bits() const { return 0; } + }; + + struct rr_t : stmt_accept_t, ins_t + { + + rr_t() + {} + + rr_t(uint32_t code) + { (void)code; } + + + static uint32_t mask() { return 0b1111 << 26; } + static uint32_t code() { return 0b1001 << 26; } + uint32_t bits() const { return 0; } + }; + + struct sl_t : stmt_accept_t, ins_t + { + + sl_t() + {} + + sl_t(uint32_t code) + { (void)code; } + + + static uint32_t mask() { return 0b1111 << 26; } + static uint32_t code() { return 0b1010 << 26; } + uint32_t bits() const { return 0; } + }; + + struct rl_t : stmt_accept_t, ins_t + { + + rl_t() + {} + + rl_t(uint32_t code) + { (void)code; } + + + static uint32_t mask() { return 0b1111 << 26; } + static uint32_t code() { return 0b1011 << 26; } + uint32_t bits() const { return 0; } + }; + + struct rl8_t : stmt_accept_t, ins_t + { + + rl8_t() + {} + + rl8_t(uint32_t code) + { (void)code; } + + + static uint32_t mask() { return 0b1111 << 26; } + static uint32_t code() { return 0b1111 << 26; } + uint32_t bits() const { return 0; } + }; + + struct mov_ram_x_t : stmt_accept_t, ins_t + { + + mov_ram_x_t(x_src_t src) + : src(src) {} + + mov_ram_x_t(uint32_t code) + : src(code) { (void)code; } + + const x_src_t src; + + static uint32_t mask() { return 0b1 << 25; } + static uint32_t code() { return 0b1 << 25; } + uint32_t bits() const { return src.bits(); } + }; + + struct mov_mul_p_t : stmt_accept_t, ins_t + { + + mov_mul_p_t() + {} + + mov_mul_p_t(uint32_t code) + { (void)code; } + + + static uint32_t mask() { return 0b11 << 23; } + static uint32_t code() { return 0b10 << 23; } + uint32_t bits() const { return 0; } + }; + + struct mov_ram_p_t : stmt_accept_t, ins_t + { + + mov_ram_p_t(x_src_t src) + : src(src) {} + + mov_ram_p_t(uint32_t code) + : src(code) { (void)code; } + + const x_src_t src; + + static uint32_t mask() { return 0b11 << 23; } + static uint32_t code() { return 0b11 << 23; } + uint32_t bits() const { return src.bits(); } + }; + + struct mov_ram_y_t : stmt_accept_t, ins_t + { + + mov_ram_y_t(y_src_t src) + : src(src) {} + + mov_ram_y_t(uint32_t code) + : src(code) { (void)code; } + + const y_src_t src; + + static uint32_t mask() { return 0b1 << 19; } + static uint32_t code() { return 0b1 << 19; } + uint32_t bits() const { return src.bits(); } + }; + + struct clr_a_t : stmt_accept_t, ins_t + { + + clr_a_t() + {} + + clr_a_t(uint32_t code) + { (void)code; } + + + static uint32_t mask() { return 0b11 << 17; } + static uint32_t code() { return 0b01 << 17; } + uint32_t bits() const { return 0; } + }; + + struct mov_alu_a_t : stmt_accept_t, ins_t + { + + mov_alu_a_t() + {} + + mov_alu_a_t(uint32_t code) + { (void)code; } + + + static uint32_t mask() { return 0b11 << 17; } + static uint32_t code() { return 0b10 << 17; } + uint32_t bits() const { return 0; } + }; + + struct mov_ram_a_t : stmt_accept_t, ins_t + { + + mov_ram_a_t(y_src_t src) + : src(src) {} + + mov_ram_a_t(uint32_t code) + : src(code) { (void)code; } + + const y_src_t src; + + static uint32_t mask() { return 0b11 << 17; } + static uint32_t code() { return 0b11 << 17; } + uint32_t bits() const { return src.bits(); } + }; + + struct mov_imm_d1_t : stmt_accept_t, ins_imm_t + { + using imm_type = uimm_t<8>; + + mov_imm_d1_t(imm_type imm, d1_dst_t dst) + : ins_imm_t(imm), dst(dst) {} + + mov_imm_d1_t(uint32_t code) + : ins_imm_t(code), dst(code) { (void)code; } + + const d1_dst_t dst; + + static uint32_t mask() { return 0b11 << 12; } + static uint32_t code() { return 0b01 << 12; } + uint32_t bits() const { return dst.bits(); } + }; + + struct mov_ram_d1_t : stmt_accept_t, ins_t + { + + mov_ram_d1_t(d1_dst_t dst, d1_src_t src) + : dst(dst), src(src) {} + + mov_ram_d1_t(uint32_t code) + : dst(code), src(code) { (void)code; } + + const d1_dst_t dst; + const d1_src_t src; + + static uint32_t mask() { return 0b11 << 12; } + static uint32_t code() { return 0b11 << 12; } + uint32_t bits() const { return dst.bits() | src.bits(); } + }; + + + } // op + + namespace load { + + 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 0b111111 << 19; } + + static constexpr value_t to_value(uint32_t code) + { + using enum value_t; + + switch (code & mask()) { + case 0b100001 << 19: return z; + case 0b000001 << 19: return nz; + case 0b100010 << 19: return s; + case 0b000010 << 19: return ns; + case 0b100100 << 19: return c; + case 0b000100 << 19: return nc; + case 0b101000 << 19: return t0; + case 0b001000 << 19: return nt0; + case 0b100011 << 19: return zs; + case 0b000011 << 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 0b100001 << 19; + case nz: return 0b000001 << 19; + case s: return 0b100010 << 19; + case ns: return 0b000010 << 19; + case c: return 0b100100 << 19; + case nc: return 0b000100 << 19; + case t0: return 0b101000 << 19; + case nt0: return 0b001000 << 19; + case zs: return 0b100011 << 19; + case nzs: return 0b000011 << 19; + default: __builtin_unreachable(); + } + } + }; + + struct dst_t { + enum value_t { + mc0, + mc1, + mc2, + mc3, + rx, + pl, + ra0, + wa0, + lop, + pc, + }; + + const value_t value; + + constexpr dst_t(value_t value) + : value(value) {} + + constexpr dst_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 dst 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 mvi_t : stmt_accept_t, ins_imm_t + { + using imm_type = uimm_t<25>; + + mvi_t(imm_type imm, dst_t dst) + : ins_imm_t(imm), dst(dst) {} + + mvi_t(uint32_t code) + : ins_imm_t(code), dst(code) { (void)code; } + + const dst_t dst; + + static uint32_t mask() { return 0b1100001 << 25; } + static uint32_t code() { return 0b1000000 << 25; } + uint32_t bits() const { return dst.bits(); } + }; + + struct mvi_cond_t : stmt_accept_t, ins_imm_t + { + using imm_type = uimm_t<19>; + + mvi_cond_t(imm_type imm, dst_t dst, cond_t cond) + : ins_imm_t(imm), dst(dst), cond(cond) {} + + mvi_cond_t(uint32_t code) + : ins_imm_t(code), dst(code), cond(code) { (void)code; } + + const dst_t dst; + const cond_t cond; + + static uint32_t mask() { return 0b1100001 << 25; } + static uint32_t code() { return 0b1000001 << 25; } + uint32_t bits() const { return dst.bits() | cond.bits(); } + }; + + + } // load + + namespace dma { + + struct ram_t { + enum value_t { + m0, + m1, + m2, + m3, + mc0, + mc1, + mc2, + mc3, + }; + + const value_t value; + + constexpr ram_t(value_t value) + : value(value) {} + + constexpr ram_t(uint32_t code) + : value(to_value(code)) {} + + static constexpr uint32_t mask() { return 0b111 << 0; } + + static constexpr value_t to_value(uint32_t code) + { + using enum value_t; + + switch (code & mask()) { + case 0b000 << 0: return m0; + case 0b001 << 0: return m1; + case 0b010 << 0: return m2; + case 0b011 << 0: return m3; + case 0b100 << 0: return mc0; + case 0b101 << 0: return mc1; + case 0b110 << 0: return mc2; + case 0b111 << 0: return mc3; + default: + std::cerr << "invalid dma ram code: " << (code & mask()) << std::endl; + throw std::runtime_error("invalid code"); + } + } + + uint32_t bits() const + { + using enum value_t; + + switch (value) { + 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(); + } + } + }; + + struct src_t { + enum value_t { + mc0, + mc1, + mc2, + mc3, + }; + + const value_t value; + + constexpr src_t(value_t value) + : value(value) {} + + constexpr src_t(uint32_t code) + : value(to_value(code)) {} + + static constexpr uint32_t mask() { return 0b111 << 8; } + + static constexpr value_t to_value(uint32_t code) + { + using enum value_t; + + switch (code & mask()) { + case 0b000 << 8: return mc0; + case 0b001 << 8: return mc1; + case 0b010 << 8: return mc2; + case 0b011 << 8: return mc3; + default: + std::cerr << "invalid dma src code: " << (code & mask()) << std::endl; + throw std::runtime_error("invalid code"); + } + } + + uint32_t bits() const + { + using enum value_t; + + switch (value) { + case mc0: return 0b000 << 8; + case mc1: return 0b001 << 8; + case mc2: return 0b010 << 8; + case mc3: return 0b011 << 8; + default: __builtin_unreachable(); + } + } + }; + + struct dst_t { + enum value_t { + mc0, + mc1, + mc2, + mc3, + prg, + }; + + const value_t value; + + constexpr dst_t(value_t value) + : value(value) {} + + constexpr dst_t(uint32_t code) + : value(to_value(code)) {} + + static constexpr uint32_t mask() { return 0b111 << 8; } + + static constexpr value_t to_value(uint32_t code) + { + using enum value_t; + + switch (code & mask()) { + case 0b000 << 8: return mc0; + case 0b001 << 8: return mc1; + case 0b010 << 8: return mc2; + case 0b011 << 8: return mc3; + case 0b100 << 8: return prg; + default: + std::cerr << "invalid dma dst code: " << (code & mask()) << std::endl; + throw std::runtime_error("invalid code"); + } + } + + uint32_t bits() const + { + using enum value_t; + + switch (value) { + 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(); + } + } + }; + + struct hold_t { + enum value_t { + _false, + _true, + }; + + const value_t value; + + constexpr hold_t(value_t value) + : value(value) {} + + constexpr hold_t(uint32_t code) + : value(to_value(code)) {} + + static constexpr uint32_t mask() { return 0b1 << 14; } + + static constexpr value_t to_value(uint32_t code) + { + using enum value_t; + + switch (code & mask()) { + case 0b0 << 14: return _false; + case 0b1 << 14: return _true; + default: + std::cerr << "invalid dma hold code: " << (code & mask()) << std::endl; + throw std::runtime_error("invalid code"); + } + } + + uint32_t bits() const + { + using enum value_t; + + switch (value) { + case _false: return 0b0 << 14; + case _true: return 0b1 << 14; + default: __builtin_unreachable(); + } + } + }; + + struct add_t { + enum value_t { + _0, + _1, + _2, + _4, + _8, + _16, + _32, + _64, + }; + + const value_t value; + + constexpr add_t(value_t value) + : value(value) {} + + constexpr add_t(uint32_t code) + : value(to_value(code)) {} + + static constexpr uint32_t mask() { return 0b111 << 15; } + + static constexpr value_t to_value(uint32_t code) + { + using enum value_t; + + switch (code & mask()) { + case 0b000 << 15: return _0; + case 0b001 << 15: return _1; + case 0b010 << 15: return _2; + case 0b011 << 15: return _4; + case 0b100 << 15: return _8; + case 0b101 << 15: return _16; + case 0b110 << 15: return _32; + case 0b111 << 15: return _64; + default: + std::cerr << "invalid dma add code: " << (code & mask()) << std::endl; + throw std::runtime_error("invalid code"); + } + } + + uint32_t bits() const + { + using enum value_t; + + switch (value) { + 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(); + } + } + }; + + struct d0_dst_imm_t : stmt_accept_t, ins_imm_t + { + using imm_type = uimm_t<8>; + + d0_dst_imm_t(imm_type imm, add_t add, hold_t hold, dst_t dst) + : ins_imm_t(imm), add(add), hold(hold), dst(dst) {} + + d0_dst_imm_t(uint32_t code) + : ins_imm_t(code), add(code), hold(code), dst(code) { (void)code; } + + const add_t add; + const hold_t hold; + const dst_t dst; + + static uint32_t mask() { return 0b11110000000000000011 << 12; } + static uint32_t code() { return 0b11000000000000000000 << 12; } + uint32_t bits() const { return add.bits() | hold.bits() | dst.bits(); } + }; + + struct src_d0_imm_t : stmt_accept_t, ins_imm_t + { + using imm_type = uimm_t<8>; + + src_d0_imm_t(imm_type imm, add_t add, hold_t hold, src_t src) + : ins_imm_t(imm), add(add), hold(hold), src(src) {} + + src_d0_imm_t(uint32_t code) + : ins_imm_t(code), add(code), hold(code), src(code) { (void)code; } + + const add_t add; + const hold_t hold; + const src_t src; + + static uint32_t mask() { return 0b11110000000000000011 << 12; } + static uint32_t code() { return 0b11000000000000000001 << 12; } + uint32_t bits() const { return add.bits() | hold.bits() | src.bits(); } + }; + + struct d0_dst_ram_t : stmt_accept_t, ins_t + { + + d0_dst_ram_t(add_t add, hold_t hold, dst_t dst, ram_t ram) + : add(add), hold(hold), dst(dst), ram(ram) {} + + d0_dst_ram_t(uint32_t code) + : add(code), hold(code), dst(code), ram(code) { (void)code; } + + const add_t add; + const hold_t hold; + const dst_t dst; + const ram_t ram; + + static uint32_t mask() { return 0b11110000000000000011 << 12; } + static uint32_t code() { return 0b11000000000000000010 << 12; } + uint32_t bits() const { return add.bits() | hold.bits() | dst.bits() | ram.bits(); } + }; + + struct src_d0_ram_t : stmt_accept_t, ins_t + { + + src_d0_ram_t(add_t add, hold_t hold, src_t src, ram_t ram) + : add(add), hold(hold), src(src), ram(ram) {} + + src_d0_ram_t(uint32_t code) + : add(code), hold(code), src(code), ram(code) { (void)code; } + + const add_t add; + const hold_t hold; + const src_t src; + const ram_t ram; + + static uint32_t mask() { return 0b11110000000000000011 << 12; } + static uint32_t code() { return 0b11000000000000000011 << 12; } + uint32_t bits() const { return add.bits() | hold.bits() | src.bits() | ram.bits(); } + }; + + + } // dma + + namespace jump { + + 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 0b111111 << 19; } + + static constexpr value_t to_value(uint32_t code) + { + using enum value_t; + + switch (code & mask()) { + case 0b100001 << 19: return z; + case 0b000001 << 19: return nz; + case 0b100010 << 19: return s; + case 0b000010 << 19: return ns; + case 0b100100 << 19: return c; + case 0b000100 << 19: return nc; + case 0b101000 << 19: return t0; + case 0b001000 << 19: return nt0; + case 0b100011 << 19: return zs; + case 0b000011 << 19: return nzs; + default: + std::cerr << "invalid jump 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 0b100001 << 19; + case nz: return 0b000001 << 19; + case s: return 0b100010 << 19; + case ns: return 0b000010 << 19; + case c: return 0b100100 << 19; + case nc: return 0b000100 << 19; + case t0: return 0b101000 << 19; + case nt0: return 0b001000 << 19; + case zs: return 0b100011 << 19; + case nzs: return 0b000011 << 19; + default: __builtin_unreachable(); + } + } + }; + + struct jmp_t : stmt_accept_t, ins_imm_t + { + using imm_type = uimm_t<25>; + + jmp_t(imm_type imm) + : ins_imm_t(imm) {} + + jmp_t(uint32_t code) + : ins_imm_t(code) { (void)code; } + + + static uint32_t mask() { return 0b1111001 << 25; } + static uint32_t code() { return 0b1101000 << 25; } + uint32_t bits() const { return 0; } + }; + + struct jmp_cond_t : stmt_accept_t, ins_imm_t + { + using imm_type = uimm_t<19>; + + jmp_cond_t(imm_type imm, cond_t cond) + : ins_imm_t(imm), cond(cond) {} + + jmp_cond_t(uint32_t code) + : ins_imm_t(code), cond(code) { (void)code; } + + const cond_t cond; + + static uint32_t mask() { return 0b1111001 << 25; } + static uint32_t code() { return 0b1101001 << 25; } + uint32_t bits() const { return cond.bits(); } + }; + + + } // jump + + namespace loop { + + struct btm_t : stmt_accept_t, ins_t + { + + btm_t() + {} + + btm_t(uint32_t code) + { (void)code; } + + + static uint32_t mask() { return 0b11111 << 27; } + static uint32_t code() { return 0b11100 << 27; } + uint32_t bits() const { return 0; } + }; + + struct lps_t : stmt_accept_t, ins_t + { + + lps_t() + {} + + lps_t(uint32_t code) + { (void)code; } + + + static uint32_t mask() { return 0b11111 << 27; } + static uint32_t code() { return 0b11101 << 27; } + uint32_t bits() const { return 0; } + }; + + + } // loop + + namespace end { + + struct end_t : stmt_accept_t, ins_t + { + + end_t() + {} + + end_t(uint32_t code) + { (void)code; } + + + static uint32_t mask() { return 0b11111 << 27; } + static uint32_t code() { return 0b11110 << 27; } + uint32_t bits() const { return 0; } + }; + + struct endi_t : stmt_accept_t, ins_t + { + + endi_t() + {} + + endi_t(uint32_t code) + { (void)code; } + + + static uint32_t mask() { return 0b11111 << 27; } + static uint32_t code() { return 0b11111 << 27; } + uint32_t bits() const { return 0; } + }; + + } // namespace end + +} // namespace dsp + diff --git a/stmt_string.cpp b/stmt_string.cpp index 8d17d0b..479cf81 100644 --- a/stmt_string.cpp +++ b/stmt_string.cpp @@ -1,5 +1,5 @@ #include "stmt_string.hpp" -#include "stmt_enum.hpp" +#include "stmt_ins.hpp" #define i(v) (static_cast(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 diff --git a/stmt_string.hpp b/stmt_string.hpp index 730955b..f637204 100644 --- a/stmt_string.hpp +++ b/stmt_string.hpp @@ -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 diff --git a/test/Makefile b/test/Makefile index 418e37f..5179b30 100644 --- a/test/Makefile +++ b/test/Makefile @@ -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 $< $@ diff --git a/token.hpp b/token.hpp index d6bf8c8..c37e920 100644 --- a/token.hpp +++ b/token.hpp @@ -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) diff --git a/visitable.hpp b/visitable.hpp index d1001ae..453d055 100644 --- a/visitable.hpp +++ b/visitable.hpp @@ -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; } diff --git a/visitor.hpp b/visitor.hpp index ddc8a7b..e2ea63b 100644 --- a/visitor.hpp +++ b/visitor.hpp @@ -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;