summaryrefslogtreecommitdiff
path: root/main.cpp
blob: f17222656282db4560992714356cfdca4c435213 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include <fmt/core.h>
#include <iostream>
#include <memory>
#include <optional>
#include <string>
#include <utility>

#include "aisa/aisa.h"
#include "aisa/async.h"
#include "aisa/simple-models.h"
#include "git-tag.h"
#include "isa/fib/fib.h"

const bool show_mem_fetch = false;
const bool show_mem_store = true;
const bool show_regs = false;
const bool show_steps = true;
const bool show_tasks = false;

int main(int argc, const char *argv[])
{
    std::cout << "Version " << GIT_TAG << "\n";

    isa::fib::Fib<2> fib;

    struct Eval : public aisa::AsyncEval<Eval>, aisa::PagedMem<>, aisa::TaskStack, aisa::VectorRF {
        bool fetch_mem(aisa::byte_t *bytes, aisa::addr_t addr, aisa::addr_t size)
        {
            if (aisa::PagedMem<>::fetch_mem(bytes, addr, size)) {
                if (show_mem_fetch) {
                    fmt::print("\t\t\t");
                    for (; size; --size)
                        fmt::print("{:02x} ", *bytes++);
                    fmt::print("= [{:x}]\n", addr);
                }
                return true;
            }
            return false;
        }
        bool store_mem(aisa::addr_t addr, const aisa::byte_t *bytes, aisa::addr_t size)
        {
            if (aisa::PagedMem<>::store_mem(addr, bytes, size)) {
                if (show_mem_store) {
                    fmt::print("\t\t\t[{:x}] =", addr);
                    for (; size; --size)
                        fmt::print(" {:02x}", *bytes++);
                    fmt::print("\n");
                }
                return true;
            }
            return false;
        }

        bool store_reg(aisa::regnum_t rn, aisa::regval_t rv)
        {
            if (aisa::VectorRF::store_reg(rn, rv)) {
                if (show_regs)
                    fmt::print(".{} = {}\n", isa::fib::Reg::disasm(rn), rv);
                return true;
            }
            return false;
        }

        bool push_task(std::unique_ptr<const aisa::Task> &&task)
        {
            auto d = task->disasm();
            if (aisa::TaskStack::push_task(std::move(task))) {
                if (show_tasks)
                    fmt::print("\t\t*** ENTER {} ***\n", d);
                return true;
            }
            return false;
        }

        bool pop_task()
        {
            if (aisa::TaskStack::pop_task()) {
                if (show_tasks)
                    fmt::print("\t\t *** LEAVE ***\n");
                return true;
            }
            return false;
        }
    } eval;

    if (!eval.async_setup_initial_task(fib)()) {
        fmt::print("Failed to complete initial setup.\n");
        return 1;
    }

    while (true) {
        auto res = eval.async_fetch_and_run_step()();
        if (res.has_value()) {
            auto &es = *res;
            if (es.first) {
                auto &step = *es.first;
                auto &w = es.second;
                if (show_steps)
                    fmt::print("\t{}\n", step.disasm(&w));
            } else {
                break;
            }
        } else {
            fmt::print("Failed to complete step.\n");
            return 2;
        }
    }

    fmt::print("Functional model exited.\n");

    return 0;
}