tpu.h (3195B)
1#pragma once 2 3#include <stdint.h> 4#include <stdio.h> 5#include <stdbool.h> 6#include <stdlib.h> 7 8#define TPU_MAP_BUCKETS 64 9#define TPU_MAX_INST 256 10 11/* enum order is important ! */ 12 13enum tpu_status { 14 STATUS_IDLE, STATUS_RUN, STATUS_READ, STATUS_WRITE 15}; 16 17enum tpu_inst_type { 18 INST_NOP, INST_MOV, INST_SWP, INST_SAV, INST_ADD, 19 INST_SUB, INST_NEG, INST_XOR, INST_AND, INST_JMP, 20 INST_JEQ, INST_JNE, INST_JRO, INST_SHL, INST_SHR 21}; 22 23enum tpu_inst_op_type { 24 OP_ACC, OP_NIL, OP_LEFT, OP_RIGHT, OP_UP, OP_DOWN, 25 OP_ANY, OP_LAST, OP_LIT, OP_LABEL 26}; 27 28enum tpu_port_dir { 29 DIR_LEFT, DIR_RIGHT, DIR_UP, DIR_DOWN 30}; 31 32enum tpu_port_type { 33 PORT_IN = 0b01, PORT_OUT = 0b10, PORT_BIDI = 0b11 34}; 35 36union tpu_inst_op_val { 37 uint8_t lit; 38 char *label; 39}; 40 41struct tpu_inst_op { 42 enum tpu_inst_op_type type; 43 union tpu_inst_op_val val; 44}; 45 46struct tpu_inst { 47 enum tpu_inst_type type; 48 struct tpu_inst_op ops[2]; 49 unsigned opcnt; 50}; 51 52struct tpu_port { 53 struct tpu *dst_tpu; 54 enum tpu_port_type type; 55 struct tpu_port *dst_port; 56 bool clr_post_run; 57 bool reading, writing; 58 bool attached; 59 bool could_read; 60 bool could_write; 61 bool empty; 62 int in, out, out_pending; 63}; 64 65struct tpu { 66 struct tis *tis; 67 68 enum tpu_status status; 69 int x, y; 70 71 struct tpu_port ports[4]; 72 int io_port; 73 int last; 74 75 size_t steps; 76 size_t idle_steps; 77 78 void *user; 79 80 uint8_t acc, bak; 81 uint8_t pc; 82 char *labels[TPU_MAX_INST]; 83 int jmpdst[TPU_MAX_INST]; 84 struct tpu_inst insts[TPU_MAX_INST]; 85 size_t inst_cnt; 86}; 87 88struct tpu_map_link { 89 int x, y; 90 struct tpu *tpu; 91 struct tpu_map_link *next; 92}; 93 94struct tpu_map { 95 struct tpu_map_link *buckets[TPU_MAP_BUCKETS]; 96}; 97 98struct tpu_vec { 99 struct tpu *tpus; 100 size_t cnt, cap; 101}; 102 103struct tis { 104 size_t steps; 105 bool alive, idle, prev_idle; 106 struct tpu_vec tpu_vec; 107 struct tpu_map tpu_map; 108 FILE *stdin; 109 struct tpu_port stdin_port; 110 FILE *stdout; 111 struct tpu_port stdout_port; 112}; 113 114void tpu_port_init(struct tpu_port *port); 115void tpu_port_deinit(struct tpu_port *port); 116 117void tpu_init(struct tpu *tpu); 118void tpu_deinit(struct tpu *tpu); 119bool tpu_label_add(struct tpu *tpu, const char *name, size_t pc); 120size_t tpu_label_get(struct tpu *tpu, const char *name); 121void tpu_init_ports(struct tpu *tpu, struct tpu_map *map); 122void tpu_attach_ports(struct tpu *tpu); 123bool tpu_set_inst(struct tpu *tpu, uint8_t pc, enum tpu_inst_type inst, 124 unsigned opcnt, struct tpu_inst_op op1, struct tpu_inst_op op2); 125bool tpu_add_inst(struct tpu *tpu, enum tpu_inst_type inst, 126 unsigned opcnt, struct tpu_inst_op op1, struct tpu_inst_op op2); 127void tpu_clear_ports(struct tpu *tpu); 128enum tpu_status tpu_step(struct tpu *tpu); 129 130void tpu_vec_init(struct tpu_vec *vec); 131void tpu_vec_deinit(struct tpu_vec *vec); 132 133void tpu_map_init(struct tpu_map *map); 134void tpu_map_deinit(struct tpu_map *map); 135bool tpu_map_add(struct tpu_map *map, struct tpu *tpu); 136struct tpu *tpu_map_get(struct tpu_map *map, int x, int y); 137 138void tis_init(struct tis *tis, FILE *tis_stdin, FILE *tis_stdout); 139void tis_deinit(struct tis *tis); 140bool tis_step(struct tis *tis); 141struct tpu *tis_add_tpu(struct tis *tis); 142 143extern const char *dir_reprs[]; 144extern const char *status_reprs[]; 145extern const char *inst_reprs[]; 146extern const char *op_reprs[];