blob: 11a8db27f4b6134d4698532f1e20fa5d9f3e3a91 (
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>
#include "infra/pipetrace.h"
enum 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
NUM_CTLREGS,
};
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
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;
bool halt = false;
};
instruction_context decode(unsigned int df, unsigned int pc, unsigned int bits);
|