parser: add dma and mvi parsers
This commit is contained in:
parent
22625c7c90
commit
b97abc776c
61
ast.cpp
61
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>"), 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<const stmt_t *>(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<int>(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<int>(ingress_imm->ingress)],
|
||||
ingress_imm->imm.expr);
|
||||
parenthesize(dma_hold_add(src_d0_imm->hold, src_d0_imm->add),
|
||||
dma::src_string[static_cast<int>(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<int>(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<int>(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<int>(ingress_ram->ingress)],
|
||||
dma::length_ram_string[static_cast<int>(ingress_ram->ram)]);
|
||||
parenthesize(dma_hold_add(src_d0_ram->hold, src_d0_ram->add),
|
||||
dma::src_string[static_cast<int>(src_d0_ram->src)],
|
||||
"d0",
|
||||
dma::length_ram_string[static_cast<int>(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<int>(egress_ram->egress)],
|
||||
dma::length_ram_string[static_cast<int>(egress_ram->ram)]);
|
||||
parenthesize(dma_hold_add(d0_dst_ram->hold, d0_dst_ram->add),
|
||||
"d0",
|
||||
dma::dst_string[static_cast<int>(d0_dst_ram->dst)],
|
||||
dma::length_ram_string[static_cast<int>(d0_dst_ram->ram)]);
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
}
|
||||
|
14
ast.hpp
14
ast.hpp
@ -37,10 +37,10 @@ struct ast_printer_t : visitor_t<void>
|
||||
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;
|
||||
@ -51,15 +51,19 @@ struct ast_printer_t : visitor_t<void>
|
||||
void visit(const end::end_t * end) 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;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -14,7 +14,23 @@ 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";
|
||||
@ -41,6 +57,7 @@ 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";
|
||||
|
@ -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,
|
||||
|
88
keyword.hpp
88
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 };
|
||||
|
7
main.cpp
7
main.cpp
@ -1,6 +1,7 @@
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <optional>
|
||||
|
||||
#include "lexer.hpp"
|
||||
#include "token.hpp"
|
||||
@ -21,9 +22,11 @@ static void run(std::string source)
|
||||
lexer_t lexer(buf);
|
||||
std::vector<token_t> tokens = lexer.lex_tokens();
|
||||
parser_t parser(tokens);
|
||||
expr_t * expr = parser.expression();
|
||||
std::optional<stmt_t *> stmt_o = parser.instruction();
|
||||
if (stmt_o) {
|
||||
dsp::ast_printer_t p(std::cout);
|
||||
expr->accept(&p);
|
||||
(*stmt_o)->accept(&p);
|
||||
}
|
||||
std::cout << std::endl << std::flush;
|
||||
}
|
||||
|
||||
|
251
parser.cpp
251
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<op::op_t *> 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");
|
||||
}
|
||||
@ -305,16 +304,240 @@ std::optional<stmt_t *> 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<stmt_t *> 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<dma::length_ram_t> 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<stmt_t *> parser_t::dma()
|
||||
{
|
||||
if (dma_p(peek())) {
|
||||
const token_t& token = advance();
|
||||
bool hold = dma_hold_p(token);
|
||||
dma::add_mode_t add = dma_add(token);
|
||||
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<stmt_t *> parser_t::jump()
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
std::optional<stmt_t *> parser_t::loop()
|
||||
{
|
||||
if (match(_btm)) return {new loop::btm_t()};
|
||||
else if (match(_lps)) return {new loop::lps_t()};
|
||||
else return {};
|
||||
}
|
||||
|
||||
std::optional<stmt_t *> parser_t::end()
|
||||
{
|
||||
if (match(_end)) return {new end::end_t()};
|
||||
else if (match(_endi)) return {new end::endi_t()};
|
||||
else return {};
|
||||
}
|
||||
|
||||
std::optional<stmt_t *> 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<stmt_t *> parser_t::instruction_statement()
|
||||
|
16
parser.hpp
16
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 <typename... Targs>
|
||||
@ -52,6 +52,16 @@ struct parser_t
|
||||
std::optional<op::d1_dest_t> d1_dest();
|
||||
std::optional<op::op_t *> xyd1_bus();
|
||||
std::optional<stmt_t *> op();
|
||||
load::dest_t load_dest();
|
||||
load::cond_t load_cond();
|
||||
std::optional<stmt_t *> load();
|
||||
dma::src_t dma_src();
|
||||
dma::dst_t dma_dst();
|
||||
std::optional<dma::length_ram_t> dma_length_ram();
|
||||
std::optional<stmt_t *> dma();
|
||||
std::optional<stmt_t *> jump();
|
||||
std::optional<stmt_t *> loop();
|
||||
std::optional<stmt_t *> end();
|
||||
std::optional<stmt_t *> instruction();
|
||||
std::optional<stmt_t *> instruction_statement();
|
||||
stmt_t * statement();
|
||||
|
45
stmt.hpp
45
stmt.hpp
@ -157,47 +157,48 @@ struct mvi_cond_t : stmt_accept_t<mvi_cond_t>
|
||||
|
||||
namespace dma {
|
||||
|
||||
struct ingress_imm_t : stmt_accept_t<ingress_imm_t>
|
||||
struct src_d0_imm_t : stmt_accept_t<src_d0_imm_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<egress_imm_t>
|
||||
struct d0_dst_imm_t : stmt_accept_t<d0_dst_imm_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<ingress_ram_t>
|
||||
struct src_d0_ram_t : stmt_accept_t<src_d0_ram_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<egress_ram_t>
|
||||
struct d0_dst_ram_t : stmt_accept_t<d0_dst_ram_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<endi_t>
|
||||
|
||||
} // end
|
||||
|
||||
namespace nop {
|
||||
|
||||
struct nop_t : stmt_accept_t<nop_t>
|
||||
{
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
struct assign_t : stmt_accept_t<assign_t>
|
||||
{
|
||||
|
@ -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,
|
||||
};
|
||||
|
@ -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[] = {
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
@ -52,5 +52,8 @@ struct end_t;
|
||||
struct endi_t;
|
||||
}
|
||||
|
||||
namespace nop {
|
||||
struct nop_t;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
@ -42,6 +42,7 @@ struct visitor_t
|
||||
virtual T visit(const end::end_t * end) const = 0;
|
||||
virtual T visit(const end::endi_t * endi) const = 0;
|
||||
|
||||
virtual T visit(const nop::nop_t * nop) const = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user