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

#include <functional>
#include <optional>

enum ctlreg {
    DATA_INSTRUCTION_FIELD_BUFFER,  // (df << 3) | if_buffer
    DATA_INSTRUCTION_FIELD_SAVED,   // (df_saved << 3) | if_saved
    HALTED,
    INT_ENABLE,                     // (int_enable_delay << 1) | int_enable
    TT_INPUT,                       // (tti_flag << 8) | tti_buffer
    TT_INPUT_INT_ENABLE,
    TT_OUTPUT,                      // {tto_flag_old, tto_flag, tto_tx, tto_data}
    TT_OUTPUT_INT_ENABLE,

    NUM_CTLREGS,
};

struct instruction_context {
    // 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
    bool need_read_mq = false;          // mq = %mq
    std::optional<ctlreg> read_ctlreg;  // ctlval = %[read_ctlreg]
    bool need_write_acc = false;        // %acc = acc
    bool need_write_link = false;       // %link = link
    bool need_write_mq = false;         // %mq = mq
    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;
    std::optional<unsigned int> mq;
};

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