summaryrefslogtreecommitdiffstats
path: root/tpu.h
blob: 1805d7c203cab935c8b6ba2540ab03ca2cf1e88d (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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
#pragma once

#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>

#define TPU_MAP_BUCKETS 64
#define LABEL_MAP_BUCKETS 64
#define TPU_MAX_INST_CNT 15
#define TPU_MAX_ROWS 15
#define TPU_MAX_COLS 18
#define TIS_MAX_IO_PORTS 36

/* what tpu will attempt next (order important) */
enum tpu_mode {
	MODE_IDLE, MODE_RUN, MODE_READ, MODE_WRITE
};

enum tpu_inst_type {
	INST_NOP, INST_MOV, INST_SWP, INST_SAV,
	INST_ADD, INST_SUB, INST_NEG, INST_JMP,
	INST_JEZ, INST_JNZ, INST_JGZ, INST_JLZ,
	INST_JRO
};

enum tpu_inst_op_type {
	OP_ACC, OP_NIL, OP_LEFT, OP_RIGHT, OP_UP, OP_DOWN,
	OP_ANY, OP_LAST, OP_LIT, OP_LABEL
};

enum tpu_port_dir {
	DIR_LEFT, DIR_RIGHT, DIR_UP, DIR_DOWN
};

enum tpu_port_type {
	PORT_IN = 0b01, PORT_OUT = 0b10, PORT_BIDI = 0b11
};

union tpu_inst_op_val {
	int lit;
	char *label;
};

struct label_map_link {
	int pc;
	bool prefix;
	struct label_map_link *next;
};

struct label {
	char *str;
	bool prefix;
};

struct label_map {
	struct label labels[TPU_MAX_INST_CNT];
	struct label_map_link *buckets[LABEL_MAP_BUCKETS];
};

struct tpu_inst_op {
	enum tpu_inst_op_type type;
	union tpu_inst_op_val val;
};

struct tpu_inst {
	enum tpu_inst_type type;
	struct tpu_inst_op ops[2];
	unsigned opcnt;
};

struct tpu_port {
	struct tpu *tpu;
	enum tpu_port_type type;

	/* NOTE: dont access dst_port during execution,
	 * values are transfered in post execution phase */
	struct tpu_port *dst_port;
	bool attached;

	int in, out;
	bool avail, writing;

	bool reset_in;
};

struct tpu {
	enum tpu_mode mode;
	bool idle;

	bool disabled;

	int x, y;

	struct tpu_port ports[4];
	int io_port;
	int last;

	size_t steps;
	size_t idle_steps;

	int acc, bak;
	int pc;

	struct label_map label_map;
	struct tpu_inst insts[TPU_MAX_INST_CNT];
	size_t inst_cnt, rows;
};

struct tpu_map_link {
	int x, y;
	struct tpu *tpu;
	struct tpu_map_link *next;
};

struct tpu_map {
	struct tpu_map_link *buckets[TPU_MAP_BUCKETS];
};

struct tpu_io_port {
	struct tpu_port port;
	enum tpu_port_dir dir;
	enum tpu_port_type type;
	size_t io_step;
	FILE *file;
	int x, y;
	char c;
};

struct tis {
	struct tpu_map tpu_map;
	struct tpu_io_port *in_ports[TIS_MAX_IO_PORTS];
	struct tpu_io_port *out_ports[TIS_MAX_IO_PORTS];
	size_t steps;
	bool show_stats;
	char *asm_filepath;
};

struct tis_stats {
	size_t steps;
	size_t nodes;
	size_t insts;
	float idle;
};

void label_map_init(struct label_map *map);
void label_map_deinit(struct label_map *map);
bool label_map_add(struct label_map *map, const char *name, int pc, bool prefix);
int label_map_get(struct label_map *map, const char *name);

void tpu_port_init(struct tpu_port *port, struct tpu *tpu);
void tpu_port_deinit(struct tpu_port *port);

void tpu_io_port_init(struct tpu_io_port *io_port, char c,
	enum tpu_port_dir dir, enum tpu_port_type type, int x, int y);
void tpu_io_port_deinit(struct tpu_io_port *io_port);
void tpu_io_port_attach(struct tpu_io_port *io_port, FILE *file);

void tpu_init(struct tpu *tpu);
void tpu_deinit(struct tpu *tpu);
struct tpu_inst *tpu_current_inst(struct tpu *tpu);
void tpu_init_ports(struct tpu *tpu, struct tpu_map *map);
void tpu_update_ports(struct tpu *tpu);
bool tpu_set_inst(struct tpu *tpu, int pc, enum tpu_inst_type inst,
	unsigned opcnt, struct tpu_inst_op op1, struct tpu_inst_op op2);
struct tpu_inst *tpu_add_inst(struct tpu *tpu, enum tpu_inst_type inst,
	unsigned opcnt, struct tpu_inst_op op1, struct tpu_inst_op op2);
void tpu_clear_ports(struct tpu *tpu);
enum tpu_mode tpu_exec(struct tpu *tpu, struct tpu_inst *inst);
void tpu_step(struct tpu *tpu);

void tpu_map_init(struct tpu_map *map);
void tpu_map_deinit(struct tpu_map *map);
bool tpu_map_add(struct tpu_map *map, struct tpu *tpu);
struct tpu *tpu_map_get(struct tpu_map *map, int x, int y);

void tis_init(struct tis *tis);
void tis_deinit(struct tis *tis);
bool tis_step(struct tis *tis);
void tis_communicate(struct tis *tis);
struct tis_stats tis_gen_stats(struct tis *tis);

extern const char *dir_reprs[];
extern const char *mode_reprs[];
extern const char *inst_reprs[];
extern const char *op_reprs[];