-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtc3asm.c
112 lines (87 loc) · 2.12 KB
/
tc3asm.c
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
/* Assembler Library for Thacker's Tiny Computer 3
* L. Stewart <[email protected]>
*/
#include <stdio.h>
#include <stdint.h>
#include <stdargs.h>
/* Field access macros */
#define GETFIELD(field, value) \
((value >> field ## _START) & ((1 << field ## _WIDTH) - 1))
#define SETFIELD(word, field, value) \
word = (word & (~((1 << field ## _WIDTH) - 1) << field ## _START)) \
| ((value & ((1 << field ## _WIDTH) - 1)) << field ## _START)
#define RW_START 25
#define RW_WIDTH 7
#define LC_START 24
#define RA_START 17
#define RA_WIDTH 7
#define RB_START 10
#define RB_WIDTH 7
#define FUNC_START 7
#define FUNC_WIDTH 3
#define SHIFT_START 5
#define SHIFT_WIDTH 2
#define SKIP_START 3
#define SKIP_WIDTH 2
#define OP_START 0
#define OP_WIDTH 3
#define FUNC { plus, minus, plus1, minus1, and, or, xor, func_reserved };
#define SHIFT { rcy0, rcy1, rcy8, rcy16 };
#define SKIP { noskip, alult0, alueq0, inrdy};
#define OP { norm, storeDM, storeIM, out, loadDM, in, junk, op_reserved};
#define DMSIZE 1024
uint32_t dm[DMSIZE];
#define IMSIZE 1024
uint32_t im[IMSIZE];
int next_dm = 0;
int next_in = 0;
int next_reg = 0;
int label(void)
{
return(next_im);
}
int allocreg()
{
if (next_reg >= NUMREGS) return(-1);
return(next_reg++);
}
int alloc(int words)
{
int loc = next_dm;
if ((loc + words) > DMSIZE) return(-1);
next_dm = loc + words;
return(loc);
}
/* There's a function for each main type of instruction */
uint32_t inst = 0;
void pushinst()
{
im[next_im++] = inst;
inst = 0;
}
void ins(int rw, int lc, int ra, int rb, int function, int shift, int skip, int op)
{
SETFIELD(inst, RW, rw);
SETFIELD(inst, LC, lc);
SETFIELD(inst, RA, ra);
SETFIELD(inst, RB, rb);
SETFIELD(inst, FUNC, function);
SETFIELD(inst, SHIFT, shift);
SETFIELD(inst, SKIP, skip);
SETFIELD(inst, OP, op);
pushinst();
}
void constant(int rw, uint32_t value)
{
inst = value & 0xffffff;
SETFIELD(inst, LC, lc);
pushinst();
}
void t3_add(int rw, int ra, int rb)
{
ins(rw, 0, ra, rb, plus, noshift, noskip, norm)
}
void t3_add_skip(int rw, int ra, int rb, int skip)
{
ins(rw, 0, ra, rb, plus, noshift, skip, norm)
}