summaryrefslogtreecommitdiff
path: root/isa/isa.h
blob: 3effb5b28556d5fe18860f0eb07da13db10a38e8 (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
#pragma once

#include <functional>
#include <optional>

#include "infra/pipetrace.h"

enum class ctlreg {
    DATA_INSTRUCTION_FIELD_BUFFER,  // (df << 3) | if_buffer
    DATA_INSTRUCTION_FIELD_SAVED,   // (df_saved << 3) | if_saved
    INT_ENABLE,                     // (int_enable_delay << 1) | int_enable
};

struct instruction_context {
    infra::transaction transaction;

    // Known statically at decode time
    bool need_indirect_load = false;    // final_address = mem[init_address]
    bool need_autoinc_store = false;    // mem[init_address] += 1
    bool need_exec_load = false;        // data = mem[final_address]
    bool need_read_acc = false;         // acc = %acc
    bool need_read_link = false;        // link = %link
    std::optional<ctlreg> read_ctlreg;  // ctlval = %[read_ctlreg]
    bool need_write_acc = false;        // %acc = acc
    bool need_write_link = false;       // %link = link
    std::optional<ctlreg> write_ctlreg; // %[write_ctlreg] = ctlval
    bool need_exec_store = false;       // mem[final_address] = data
    bool possibly_redirects = false;    // %pc = next_pc

    std::function<void(instruction_context &ctx)> ef;
    void execute() { ef(*this); }

    // May change over the lifetime of the instruction execution
    unsigned int next_pc;                       // includes IF
    std::optional<unsigned int> init_address;   // includes DF
    std::optional<unsigned int> final_address;  // includes DF
    std::optional<unsigned int> ctlval;
    std::optional<unsigned int> data;
    std::optional<unsigned int> acc;
    std::optional<bool> link;
    bool halt = false;
};

instruction_context decode(unsigned int df, unsigned int pc, unsigned int bits);