From b97abc776c4e2ff903fa8f47f022843a469a8381 Mon Sep 17 00:00:00 2001 From: Zack Buhman Date: Sun, 20 Aug 2023 05:54:53 +0000 Subject: [PATCH] parser: add dma and mvi parsers --- ast.cpp | 61 +++++++---- ast.hpp | 16 +-- build_radix_tree.py | 7 +- keyword.case_inc | 141 +++++++++++++----------- keyword.enum_inc | 17 +++ keyword.hpp | 88 +++++++++++++++ main.cpp | 9 +- parser.cpp | 253 +++++++++++++++++++++++++++++++++++++++++--- parser.hpp | 16 ++- stmt.hpp | 45 ++++---- stmt_enum.hpp | 4 +- stmt_string.cpp | 22 ++-- stmt_string.hpp | 4 +- visitable.hpp | 13 ++- visitor.hpp | 11 +- 15 files changed, 555 insertions(+), 152 deletions(-) diff --git a/ast.cpp b/ast.cpp index a45e010..6a240dd 100644 --- a/ast.cpp +++ b/ast.cpp @@ -15,7 +15,7 @@ void ast_printer_t::visit(const binary_t * binary) const void ast_printer_t::visit(const grouping_t * grouping) const { - parenthesize(std::string_view(""), grouping->expr); + parenthesize("grouping", grouping->expr); } void ast_printer_t::visit(const literal_t * literal) const @@ -37,18 +37,25 @@ void ast_printer_t::parenthesize(const std::string_view s1, const std::string_vi os << ')'; } +void ast_printer_t::parenthesize(const std::string_view s1, const std::string_view s2, const std::string_view s3, const expr_t * a) const +{ + os << '(' << s1 << ' ' << s2 << ' ' << s3 << ' '; + a->accept(this); + os << ')'; +} + void ast_printer_t::parenthesize(const std::string_view s1, const expr_t * a, const std::string_view s2) const { os << '(' << s1 << ' '; a->accept(this); - os << s2 << ')'; + os << ' ' << s2 << ')'; } void ast_printer_t::parenthesize(const std::string_view s1, const expr_t * a, const std::string_view s2, const std::string_view s3) const { os << '(' << s1 << ' '; a->accept(this); - os << s2 << ' ' << s3 << ')'; + os << ' ' << s2 << ' ' << s3 << ')'; } void ast_printer_t::parenthesize(const std::string_view s) const @@ -66,6 +73,11 @@ void ast_printer_t::parenthesize(const std::string_view s1, const std::string_vi os << '(' << s1 << ' ' << s2 << ' ' << s3 << ')'; } +void ast_printer_t::parenthesize(const std::string_view s1, const std::string_view s2, const std::string_view s3, const std::string_view s4) const +{ + os << '(' << s1 << ' ' << s2 << ' ' << s3 << ' ' << s4 << ')'; +} + void ast_printer_t::parenthesize(const std::string_view s, const expr_t * a, const expr_t * b) const { os << '(' << s << ' '; @@ -139,6 +151,7 @@ void ast_printer_t::visit(const op::control_word_t * control_word) const os << "(control_word "; for (const auto& op : control_word->ops) { reinterpret_cast(op)->accept(this); + os << ' '; } os << ')'; } @@ -162,32 +175,36 @@ static std::string dma_hold_add(bool hold, dma::add_mode_t add) + dma::add_mode_string[static_cast(add)]; } -void ast_printer_t::visit(const dma::ingress_imm_t * ingress_imm) const +void ast_printer_t::visit(const dma::src_d0_imm_t * src_d0_imm) const { - parenthesize(dma_hold_add(ingress_imm->hold, ingress_imm->add), - dma::ingress_string[static_cast(ingress_imm->ingress)], - ingress_imm->imm.expr); + parenthesize(dma_hold_add(src_d0_imm->hold, src_d0_imm->add), + dma::src_string[static_cast(src_d0_imm->src)], + "d0", + src_d0_imm->imm.expr); } -void ast_printer_t::visit(const dma::egress_imm_t * egress_imm) const +void ast_printer_t::visit(const dma::d0_dst_imm_t * d0_dst_imm) const { - parenthesize(dma_hold_add(egress_imm->hold, egress_imm->add), - dma::egress_string[static_cast(egress_imm->egress)], - egress_imm->imm.expr); + parenthesize(dma_hold_add(d0_dst_imm->hold, d0_dst_imm->add), + "d0", + dma::dst_string[static_cast(d0_dst_imm->dst)], + d0_dst_imm->imm.expr); } -void ast_printer_t::visit(const dma::ingress_ram_t * ingress_ram) const +void ast_printer_t::visit(const dma::src_d0_ram_t * src_d0_ram) const { - parenthesize(dma_hold_add(ingress_ram->hold, ingress_ram->add), - dma::ingress_string[static_cast(ingress_ram->ingress)], - dma::length_ram_string[static_cast(ingress_ram->ram)]); + parenthesize(dma_hold_add(src_d0_ram->hold, src_d0_ram->add), + dma::src_string[static_cast(src_d0_ram->src)], + "d0", + dma::length_ram_string[static_cast(src_d0_ram->ram)]); } -void ast_printer_t::visit(const dma::egress_ram_t * egress_ram) const +void ast_printer_t::visit(const dma::d0_dst_ram_t * d0_dst_ram) const { - parenthesize(dma_hold_add(egress_ram->hold, egress_ram->add), - dma::egress_string[static_cast(egress_ram->egress)], - dma::length_ram_string[static_cast(egress_ram->ram)]); + 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)]); } void ast_printer_t::visit(const jump::jmp_t * jmp) const @@ -226,4 +243,10 @@ void ast_printer_t::visit(const end::endi_t * endi) const parenthesize("endi"); } +void ast_printer_t::visit(const nop::nop_t * nop) const +{ + (void)nop; + parenthesize("nop"); +} + } diff --git a/ast.hpp b/ast.hpp index 39e60b0..2037ec2 100644 --- a/ast.hpp +++ b/ast.hpp @@ -37,10 +37,10 @@ struct ast_printer_t : visitor_t void visit(const load::mvi_t * mvi) const; void visit(const load::mvi_cond_t * mvi_cond) const; - void visit(const dma::ingress_imm_t * ingress_imm) const; - void visit(const dma::egress_imm_t * egress_imm) const; - void visit(const dma::ingress_ram_t * ingress_ram) const; - void visit(const dma::egress_ram_t * egress_ram) const; + void visit(const dma::src_d0_imm_t * src_d0_imm) const; + void visit(const dma::d0_dst_imm_t * d0_dst_imm) const; + void visit(const dma::src_d0_ram_t * src_d0_ram) const; + void visit(const dma::d0_dst_ram_t * d0_dst_ram) const; void visit(const jump::jmp_t * jmp) const; void visit(const jump::jmp_cond_t * jmp_cond) const; @@ -49,17 +49,21 @@ struct ast_printer_t : visitor_t void visit(const loop::lps_t * lps) const; void visit(const end::end_t * end) const; - void visit(const end::endi_t * endi) const; + void visit(const end::endi_t * endi) const; + + void visit(const nop::nop_t * nop) const; + void parenthesize(const std::string_view s, const expr_t * a) const; void parenthesize(const std::string_view s1, const std::string_view s2, const expr_t * a) const; + void parenthesize(const std::string_view s1, const std::string_view s2, const std::string_view s3, const expr_t * a) const; void parenthesize(const std::string_view s1, const expr_t * a, const std::string_view s2) const; void parenthesize(const std::string_view s1, const expr_t * a, const std::string_view s2, const std::string_view s3) const; void parenthesize(const std::string_view s, const expr_t * a, const expr_t * b) const; void parenthesize(const std::string_view s) const; void parenthesize(const std::string_view s1, const std::string_view s2) const; void parenthesize(const std::string_view s1, const std::string_view s2, const std::string_view s3) const; - + void parenthesize(const std::string_view s1, const std::string_view s2, const std::string_view s3, const std::string_view s4) const; }; } diff --git a/build_radix_tree.py b/build_radix_tree.py index 13c72cf..e395c9a 100644 --- a/build_radix_tree.py +++ b/build_radix_tree.py @@ -115,6 +115,7 @@ reg_keywords = [ "ct1", "ct2", "ct3", + "pc", ] cond_keywords = [ @@ -134,9 +135,13 @@ move_immediate_keywords = [ "mvi", ] +_dma_add = [0, 1, 2, 4, 8, 16, 32, 64] + dma_keywords = [ "dma", "dmah", + *(f"dma{i}" for i in _dma_add), + *(f"dmah{i}" for i in _dma_add), "d0", "prg", ] @@ -185,6 +190,6 @@ elif sys.argv[1] == 'enum_inc': print(f"_{k},") elif sys.argv[1] == 'case_inc': for k in keywords: - print(f'case _{k.ljust(4, " ")} : return os << "{k.upper()}";') + print(f'case _{k.ljust(7, " ")} : return os << "{k.upper()}";') else: assert False, sys.argv diff --git a/keyword.case_inc b/keyword.case_inc index e41bd03..34d7c3c 100644 --- a/keyword.case_inc +++ b/keyword.case_inc @@ -1,62 +1,79 @@ -case _a : return os << "A"; -case _ad2 : return os << "AD2"; -case _add : return os << "ADD"; -case _alh : return os << "ALH"; -case _all : return os << "ALL"; -case _alu : return os << "ALU"; -case _and : return os << "AND"; -case _btm : return os << "BTM"; -case _c : return os << "C"; -case _clr : return os << "CLR"; -case _ct0 : return os << "CT0"; -case _ct1 : return os << "CT1"; -case _ct2 : return os << "CT2"; -case _ct3 : return os << "CT3"; -case _d0 : return os << "D0"; -case _dma : return os << "DMA"; -case _dmah : return os << "DMAH"; -case _end : return os << "END"; -case _endi : return os << "ENDI"; -case _equ : return os << "EQU"; -case _jmp : return os << "JMP"; -case _lop : return os << "LOP"; -case _lps : return os << "LPS"; -case _m0 : return os << "M0"; -case _m1 : return os << "M1"; -case _m2 : return os << "M2"; -case _m3 : return os << "M3"; -case _mc0 : return os << "MC0"; -case _mc1 : return os << "MC1"; -case _mc2 : return os << "MC2"; -case _mc3 : return os << "MC3"; -case _mov : return os << "MOV"; -case _mul : return os << "MUL"; -case _mvi : return os << "MVI"; -case _nc : return os << "NC"; -case _nop : return os << "NOP"; -case _ns : return os << "NS"; -case _nt0 : return os << "NT0"; -case _nz : return os << "NZ"; -case _nzs : return os << "NZS"; -case _or : return os << "OR"; -case _org : return os << "ORG"; -case _p : return os << "P"; -case _pl : return os << "PL"; -case _prg : return os << "PRG"; -case _ra0 : return os << "RA0"; -case _rl : return os << "RL"; -case _rl8 : return os << "RL8"; -case _rr : return os << "RR"; -case _rx : return os << "RX"; -case _s : return os << "S"; -case _sl : return os << "SL"; -case _sr : return os << "SR"; -case _sub : return os << "SUB"; -case _t0 : return os << "T0"; -case _top : return os << "TOP"; -case _wa0 : return os << "WA0"; -case _x : return os << "X"; -case _xor : return os << "XOR"; -case _y : return os << "Y"; -case _z : return os << "Z"; -case _zs : return os << "ZS"; +case _a : return os << "A"; +case _ad2 : return os << "AD2"; +case _add : return os << "ADD"; +case _alh : return os << "ALH"; +case _all : return os << "ALL"; +case _alu : return os << "ALU"; +case _and : return os << "AND"; +case _btm : return os << "BTM"; +case _c : return os << "C"; +case _clr : return os << "CLR"; +case _ct0 : return os << "CT0"; +case _ct1 : return os << "CT1"; +case _ct2 : return os << "CT2"; +case _ct3 : return os << "CT3"; +case _d0 : return os << "D0"; +case _dma : return os << "DMA"; +case _dma0 : return os << "DMA0"; +case _dma1 : return os << "DMA1"; +case _dma16 : return os << "DMA16"; +case _dma2 : return os << "DMA2"; +case _dma32 : return os << "DMA32"; +case _dma4 : return os << "DMA4"; +case _dma64 : return os << "DMA64"; +case _dma8 : return os << "DMA8"; +case _dmah : return os << "DMAH"; +case _dmah0 : return os << "DMAH0"; +case _dmah1 : return os << "DMAH1"; +case _dmah16 : return os << "DMAH16"; +case _dmah2 : return os << "DMAH2"; +case _dmah32 : return os << "DMAH32"; +case _dmah4 : return os << "DMAH4"; +case _dmah64 : return os << "DMAH64"; +case _dmah8 : return os << "DMAH8"; +case _end : return os << "END"; +case _endi : return os << "ENDI"; +case _equ : return os << "EQU"; +case _jmp : return os << "JMP"; +case _lop : return os << "LOP"; +case _lps : return os << "LPS"; +case _m0 : return os << "M0"; +case _m1 : return os << "M1"; +case _m2 : return os << "M2"; +case _m3 : return os << "M3"; +case _mc0 : return os << "MC0"; +case _mc1 : return os << "MC1"; +case _mc2 : return os << "MC2"; +case _mc3 : return os << "MC3"; +case _mov : return os << "MOV"; +case _mul : return os << "MUL"; +case _mvi : return os << "MVI"; +case _nc : return os << "NC"; +case _nop : return os << "NOP"; +case _ns : return os << "NS"; +case _nt0 : return os << "NT0"; +case _nz : return os << "NZ"; +case _nzs : return os << "NZS"; +case _or : return os << "OR"; +case _org : return os << "ORG"; +case _p : return os << "P"; +case _pc : return os << "PC"; +case _pl : return os << "PL"; +case _prg : return os << "PRG"; +case _ra0 : return os << "RA0"; +case _rl : return os << "RL"; +case _rl8 : return os << "RL8"; +case _rr : return os << "RR"; +case _rx : return os << "RX"; +case _s : return os << "S"; +case _sl : return os << "SL"; +case _sr : return os << "SR"; +case _sub : return os << "SUB"; +case _t0 : return os << "T0"; +case _top : return os << "TOP"; +case _wa0 : return os << "WA0"; +case _x : return os << "X"; +case _xor : return os << "XOR"; +case _y : return os << "Y"; +case _z : return os << "Z"; +case _zs : return os << "ZS"; diff --git a/keyword.enum_inc b/keyword.enum_inc index 82b413c..ff34350 100644 --- a/keyword.enum_inc +++ b/keyword.enum_inc @@ -14,7 +14,23 @@ _ct2, _ct3, _d0, _dma, +_dma0, +_dma1, +_dma16, +_dma2, +_dma32, +_dma4, +_dma64, +_dma8, _dmah, +_dmah0, +_dmah1, +_dmah16, +_dmah2, +_dmah32, +_dmah4, +_dmah64, +_dmah8, _end, _endi, _equ, @@ -41,6 +57,7 @@ _nzs, _or, _org, _p, +_pc, _pl, _prg, _ra0, diff --git a/keyword.hpp b/keyword.hpp index c2dbafe..b4e772d 100644 --- a/keyword.hpp +++ b/keyword.hpp @@ -137,9 +137,93 @@ find(const std::string_view s) if (ix == s.length()) return { token_t::type_t::_dma }; else { switch (s[ix++]) { + case '0': + if (ix == s.length()) return { token_t::type_t::_dma0 }; + break; + case '1': + if (ix == s.length()) return { token_t::type_t::_dma1 }; + else { + switch (s[ix++]) { + case '6': + if (ix == s.length()) return { token_t::type_t::_dma16 }; + break; + } + } + break; + case '2': + if (ix == s.length()) return { token_t::type_t::_dma2 }; + break; + case '3': + if (ix < s.length()) { + switch (s[ix++]) { + case '2': + if (ix == s.length()) return { token_t::type_t::_dma32 }; + break; + } + } + break; + case '4': + if (ix == s.length()) return { token_t::type_t::_dma4 }; + break; + case '6': + if (ix < s.length()) { + switch (s[ix++]) { + case '4': + if (ix == s.length()) return { token_t::type_t::_dma64 }; + break; + } + } + break; + case '8': + if (ix == s.length()) return { token_t::type_t::_dma8 }; + break; case 'H': [[fallthrough]]; case 'h': if (ix == s.length()) return { token_t::type_t::_dmah }; + else { + switch (s[ix++]) { + case '0': + if (ix == s.length()) return { token_t::type_t::_dmah0 }; + break; + case '1': + if (ix == s.length()) return { token_t::type_t::_dmah1 }; + else { + switch (s[ix++]) { + case '6': + if (ix == s.length()) return { token_t::type_t::_dmah16 }; + break; + } + } + break; + case '2': + if (ix == s.length()) return { token_t::type_t::_dmah2 }; + break; + case '3': + if (ix < s.length()) { + switch (s[ix++]) { + case '2': + if (ix == s.length()) return { token_t::type_t::_dmah32 }; + break; + } + } + break; + case '4': + if (ix == s.length()) return { token_t::type_t::_dmah4 }; + break; + case '6': + if (ix < s.length()) { + switch (s[ix++]) { + case '4': + if (ix == s.length()) return { token_t::type_t::_dmah64 }; + break; + } + } + break; + case '8': + if (ix == s.length()) return { token_t::type_t::_dmah8 }; + break; + } + } break; } } @@ -377,6 +461,10 @@ find(const std::string_view s) if (ix == s.length()) return { token_t::type_t::_p }; else { switch (s[ix++]) { + case 'C': [[fallthrough]]; + case 'c': + if (ix == s.length()) return { token_t::type_t::_pc }; + break; case 'L': [[fallthrough]]; case 'l': if (ix == s.length()) return { token_t::type_t::_pl }; diff --git a/main.cpp b/main.cpp index 053d9db..36a9be3 100644 --- a/main.cpp +++ b/main.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include "lexer.hpp" #include "token.hpp" @@ -21,9 +22,11 @@ static void run(std::string source) lexer_t lexer(buf); std::vector tokens = lexer.lex_tokens(); parser_t parser(tokens); - expr_t * expr = parser.expression(); - dsp::ast_printer_t p(std::cout); - expr->accept(&p); + std::optional stmt_o = parser.instruction(); + if (stmt_o) { + dsp::ast_printer_t p(std::cout); + (*stmt_o)->accept(&p); + } std::cout << std::endl << std::flush; } diff --git a/parser.cpp b/parser.cpp index 8db5c75..91ac8bc 100644 --- a/parser.cpp +++ b/parser.cpp @@ -34,17 +34,17 @@ parse_error_t parser_t::error(const token_t& token, const std::string message) return parse_error_t(message); } -token_t& parser_t::previous() +const token_t& parser_t::previous() { return tokens[current_ix-1]; } -token_t& parser_t::peek() +const token_t& parser_t::peek() { return tokens[current_ix]; } -token_t& parser_t::advance() +const token_t& parser_t::advance() { if (!at_end_p()) current_ix++; return previous(); @@ -275,10 +275,9 @@ std::optional parser_t::xyd1_bus() else throw error(peek(), "expected x-bus, y-bus, or d-bus destination operand"); } else { - expr_t * expr = expression(); - simm_t<8> simm = simm_t<8>(expr); + simm_t<8> imm = simm_t<8>(expression()); if (auto dest_o = d1_dest()) - return {new op::mov_imm_d1_t(simm, *dest_o)}; + return {new op::mov_imm_d1_t(imm, *dest_o)}; else throw error(peek(), "expected d1 destination operand"); } @@ -297,7 +296,7 @@ std::optional parser_t::op() // fixme: check for emplacement here if (auto stmt_o = alu() ) ops.emplace_back(*stmt_o); else if (auto stmt_o = xyd1_bus()) ops.emplace_back(*stmt_o); - else break; + else break; } if (ops.size() != 0) return {new op::control_word_t(ops)}; @@ -305,16 +304,240 @@ std::optional parser_t::op() return {}; } +load::dest_t parser_t::load_dest() +{ + 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; + else + throw error(peek(), "expected mvi destination"); +} + +load::cond_t parser_t::load_cond() +{ + using namespace dsp::load; + + switch (advance().type) { + case _z: return cond_t::z; + case _nz: return cond_t::nz; + case _s: return cond_t::s; + case _ns: return cond_t::ns; + case _c: return cond_t::c; + case _nc: return cond_t::nc; + case _t0: return cond_t::t0; + case _nt0: return cond_t::nt0; + case _zs: return cond_t::zs; + case _nzs: return cond_t::nzs; + default: + throw error(previous(), "expected mvi condition after ','"); + } +} + +std::optional parser_t::load() +{ + if (match(_mvi)) { + expr_t * expr = expression(); + consume(comma, "expected `,`"); + load::dest_t dest = parser_t::load_dest(); + if (match(comma)) { + load::cond_t cond = load_cond(); + uimm_t<19> imm = uimm_t<19>(expr); + return {new load::mvi_cond_t(imm, dest, cond)}; + } else { + uimm_t<25> imm = uimm_t<25>(expr); + return {new load::mvi_t(imm, dest)}; + } + } else + return {}; +} + +static bool dma_p(const token_t& token) +{ + switch (token.type) { + case _dmah: [[fallthrough]]; + case _dmah0: [[fallthrough]]; + case _dmah1: [[fallthrough]]; + case _dmah2: [[fallthrough]]; + case _dmah4: [[fallthrough]]; + case _dmah8: [[fallthrough]]; + case _dmah16: [[fallthrough]]; + case _dmah32: [[fallthrough]]; + case _dmah64: [[fallthrough]]; + case _dma: [[fallthrough]]; + case _dma0: [[fallthrough]]; + case _dma1: [[fallthrough]]; + case _dma2: [[fallthrough]]; + case _dma4: [[fallthrough]]; + case _dma8: [[fallthrough]]; + case _dma16: [[fallthrough]]; + case _dma32: [[fallthrough]]; + case _dma64: return true; + default: return false; + } +} + +static bool dma_hold_p(const token_t& token) +{ + switch (token.type) { + case _dmah: [[fallthrough]]; + case _dmah0: [[fallthrough]]; + case _dmah1: [[fallthrough]]; + case _dmah2: [[fallthrough]]; + case _dmah4: [[fallthrough]]; + case _dmah8: [[fallthrough]]; + case _dmah16: [[fallthrough]]; + case _dmah32: [[fallthrough]]; + case _dmah64: return true; + case _dma: [[fallthrough]]; + case _dma0: [[fallthrough]]; + case _dma1: [[fallthrough]]; + case _dma2: [[fallthrough]]; + case _dma4: [[fallthrough]]; + case _dma8: [[fallthrough]]; + case _dma16: [[fallthrough]]; + case _dma32: [[fallthrough]]; + case _dma64: return false; + default: assert(false); + } +} + +static dma::add_mode_t dma_add(const token_t& token) +{ + using namespace dsp::dma; + + switch (token.type) { + case _dma: [[fallthrough]]; + case _dmah: return add_mode_t::_1; + case _dma0: [[fallthrough]]; + case _dmah0: return add_mode_t::_0; + case _dma1: [[fallthrough]]; + case _dmah1: return add_mode_t::_1; + case _dma2: [[fallthrough]]; + case _dmah2: return add_mode_t::_2; + case _dma4: [[fallthrough]]; + case _dmah4: return add_mode_t::_4; + case _dma8: [[fallthrough]]; + case _dmah8: return add_mode_t::_8; + case _dma16: [[fallthrough]]; + case _dmah16: return add_mode_t::_16; + case _dma32: [[fallthrough]]; + case _dmah32: return add_mode_t::_32; + case _dma64: [[fallthrough]]; + case _dmah64: return add_mode_t::_64; + default: assert(false); + } +} + +dma::src_t parser_t::dma_src() +{ + switch (advance().type) { + case _m0: return dma::src_t::m0; + case _m1: return dma::src_t::m1; + case _m2: return dma::src_t::m2; + case _m3: return dma::src_t::m3; + default: + throw error(previous(), "expected dma source operand"); + } +} + +dma::dst_t parser_t::dma_dst() +{ + switch (advance().type) { + case _m0: return dma::dst_t::m0; + case _m1: return dma::dst_t::m1; + case _m2: return dma::dst_t::m2; + case _m3: return dma::dst_t::m3; + case _prg: return dma::dst_t::prg; + default: + throw error(previous(), "expected dma destination operand"); + } +} + +std::optional parser_t::dma_length_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; + else return {}; +} + +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); + 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)}; + } else { + uimm_t<8> imm = uimm_t<8>(expression()); + return {new dma::d0_dst_imm_t(hold, add, dst, imm)}; + } + } 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)}; + } else { + uimm_t<8> imm = uimm_t<8>(expression()); + return {new dma::src_d0_imm_t(hold, add, src, imm)}; + } + } + } else + return {}; +} + +std::optional parser_t::jump() +{ + return {}; +} + +std::optional parser_t::loop() +{ + if (match(_btm)) return {new loop::btm_t()}; + else if (match(_lps)) return {new loop::lps_t()}; + else return {}; +} + +std::optional parser_t::end() +{ + if (match(_end)) return {new end::end_t()}; + else if (match(_endi)) return {new end::endi_t()}; + else return {}; +} + std::optional parser_t::instruction() { - // "nop" - // op - // load - // dma - // jump - // loop - // end - return {}; + if (match(_nop)) return {new nop::nop_t()}; + else if (auto op_o = op()) return op_o; + else if (auto load_o = load()) return load_o; + else if (auto dma_o = dma()) return dma_o; + else if (auto jump_o = jump()) return jump_o; + else if (auto loop_o = loop()) return loop_o; + else if (auto end_o = end()) return end_o; + else return {}; } std::optional parser_t::instruction_statement() diff --git a/parser.hpp b/parser.hpp index 7813c6a..389594e 100644 --- a/parser.hpp +++ b/parser.hpp @@ -29,9 +29,9 @@ struct parser_t bool at_end_p(); - token_t& previous(); - token_t& peek(); - token_t& advance(); + const token_t& previous(); + const token_t& peek(); + const token_t& advance(); bool check(enum token_t::type_t token_type); bool match(enum token_t::type_t token_type); template @@ -52,6 +52,16 @@ struct parser_t std::optional d1_dest(); std::optional xyd1_bus(); std::optional op(); + load::dest_t load_dest(); + 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(); + std::optional jump(); + std::optional loop(); + std::optional end(); std::optional instruction(); std::optional instruction_statement(); stmt_t * statement(); diff --git a/stmt.hpp b/stmt.hpp index 621ce34..ade8609 100644 --- a/stmt.hpp +++ b/stmt.hpp @@ -157,47 +157,48 @@ struct mvi_cond_t : stmt_accept_t namespace dma { -struct ingress_imm_t : stmt_accept_t +struct src_d0_imm_t : stmt_accept_t { - ingress_imm_t(bool hold, add_mode_t add, ingress_t ingress, simm_t<8> imm) - : hold(hold), add(add), ingress(ingress), imm(imm) {} + 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 ingress_t ingress; - const simm_t<8> imm; + const src_t src; + const uimm_t<8> imm; }; -struct egress_imm_t : stmt_accept_t +struct d0_dst_imm_t : stmt_accept_t { - egress_imm_t(bool hold, add_mode_t add, egress_t egress, simm_t<8> imm) - : hold(hold), add(add), egress(egress), imm(imm) {} + 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 egress_t egress; - const simm_t<8> imm; + const dst_t dst; + const uimm_t<8> imm; }; -struct ingress_ram_t : stmt_accept_t +struct src_d0_ram_t : stmt_accept_t { - ingress_ram_t(bool hold, add_mode_t add, ingress_t ingress, length_ram_t ram) - : hold(hold), add(add), ingress(ingress), ram(ram) {} + // 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 ingress_t ingress; + const src_t src; const length_ram_t ram; }; -struct egress_ram_t : stmt_accept_t +struct d0_dst_ram_t : stmt_accept_t { - egress_ram_t(bool hold, add_mode_t add, egress_t egress, length_ram_t ram) - : hold(hold), add(add), egress(egress), ram(ram) {} + 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 egress_t egress; + const dst_t dst; const length_ram_t ram; }; @@ -249,6 +250,14 @@ struct endi_t : stmt_accept_t } // end +namespace nop { + +struct nop_t : stmt_accept_t +{ +}; + +} + /* struct assign_t : stmt_accept_t { diff --git a/stmt_enum.hpp b/stmt_enum.hpp index 9d14f35..6a00b9f 100644 --- a/stmt_enum.hpp +++ b/stmt_enum.hpp @@ -70,11 +70,11 @@ enum struct add_mode_t { _64, }; -enum struct ingress_t { +enum struct src_t { m0, m1, m2, m3 }; -enum struct egress_t { +enum struct dst_t { m0, m1, m2, m3, prg, }; diff --git a/stmt_string.cpp b/stmt_string.cpp index 4513c96..7d0d988 100644 --- a/stmt_string.cpp +++ b/stmt_string.cpp @@ -106,19 +106,19 @@ const std::string add_mode_string[] = { [i(add_mode_t::_64)] = "64", }; -const std::string ingress_string[] = { - [i(ingress_t::m0)] = "m0", - [i(ingress_t::m1)] = "m1", - [i(ingress_t::m2)] = "m2", - [i(ingress_t::m3)] = "m3" +const std::string src_string[] = { + [i(src_t::m0)] = "m0", + [i(src_t::m1)] = "m1", + [i(src_t::m2)] = "m2", + [i(src_t::m3)] = "m3" }; -const std::string egress_string[] = { - [i(egress_t::m0 )] = "m0", - [i(egress_t::m1 )] = "m1", - [i(egress_t::m2 )] = "m2", - [i(egress_t::m3 )] = "m3", - [i(egress_t::prg)] = "prg", +const std::string dst_string[] = { + [i(dst_t::m0 )] = "m0", + [i(dst_t::m1 )] = "m1", + [i(dst_t::m2 )] = "m2", + [i(dst_t::m3 )] = "m3", + [i(dst_t::prg)] = "prg", }; const std::string length_ram_string[] = { diff --git a/stmt_string.hpp b/stmt_string.hpp index 985a3d7..730955b 100644 --- a/stmt_string.hpp +++ b/stmt_string.hpp @@ -24,8 +24,8 @@ namespace dma { extern const std::string hold_mode_string[]; extern const std::string add_mode_string[]; -extern const std::string ingress_string[]; -extern const std::string egress_string[]; +extern const std::string src_string[]; +extern const std::string dst_string[]; extern const std::string length_ram_string[]; } // dma diff --git a/visitable.hpp b/visitable.hpp index 25ee816..0e756a4 100644 --- a/visitable.hpp +++ b/visitable.hpp @@ -31,10 +31,10 @@ struct mvi_cond_t; } namespace dma { -struct ingress_imm_t; -struct egress_imm_t; -struct ingress_ram_t; -struct egress_ram_t; +struct src_d0_imm_t; +struct d0_dst_imm_t; +struct src_d0_ram_t; +struct d0_dst_ram_t; } namespace jump { @@ -49,8 +49,11 @@ struct lps_t; namespace end { struct end_t; -struct endi_t ; +struct endi_t; } +namespace nop { +struct nop_t; +} } diff --git a/visitor.hpp b/visitor.hpp index 402d79f..f1ba667 100644 --- a/visitor.hpp +++ b/visitor.hpp @@ -28,10 +28,10 @@ struct visitor_t virtual T visit(const load::mvi_t * mvi) const = 0; virtual T visit(const load::mvi_cond_t * mvi_cond) const = 0; - virtual T visit(const dma::ingress_imm_t * ingress_imm) const = 0; - virtual T visit(const dma::egress_imm_t * egress_imm) const = 0; - virtual T visit(const dma::ingress_ram_t * ingress_ram) const = 0; - virtual T visit(const dma::egress_ram_t * egress_ram) const = 0; + virtual T visit(const dma::src_d0_imm_t * src_d0_imm) const = 0; + virtual T visit(const dma::d0_dst_imm_t * d0_dst_imm) const = 0; + virtual T visit(const dma::src_d0_ram_t * src_d0_ram) const = 0; + virtual T visit(const dma::d0_dst_ram_t * d0_dst_ram) const = 0; virtual T visit(const jump::jmp_t * jmp) const = 0; virtual T visit(const jump::jmp_cond_t * jmp_cond) const = 0; @@ -40,8 +40,9 @@ struct visitor_t virtual T visit(const loop::lps_t * lps) const = 0; virtual T visit(const end::end_t * end) const = 0; - virtual T visit(const end::endi_t * endi) const = 0; + virtual T visit(const end::endi_t * endi) const = 0; + virtual T visit(const nop::nop_t * nop) const = 0; }; }