]>
Commit | Line | Data |
---|---|---|
1 | //#test return -293203597 | |
2 | ||
3 | struct cpustate { | |
4 | int r0, r1, r2, r3, fr, pc, sp; | |
5 | }; | |
6 | ||
7 | int abort() | |
8 | { | |
9 | puts("FAIL [abort]\n"); | |
10 | return 0; | |
11 | } | |
12 | ||
13 | int *ROM() | |
14 | { | |
15 | static int a[] = { | |
16 | 0x0E30, /* 0 */ | |
17 | 0x0009, /* 1 */ | |
18 | 0x0E00, /* 2 */ | |
19 | 0x0039, /* 3 */ | |
20 | 0x0E10, /* 4 */ | |
21 | 0x4000, /* 5 */ | |
22 | 0x0E20, /* 6 */ | |
23 | 0xFFFF, /* 7 */ | |
24 | 0x2E10, /* 8 */ | |
25 | 0x4E32, /* 9 */ | |
26 | 0x4E02, /* A */ | |
27 | 0x5E32, /* B */ | |
28 | 0x0250, /* C */ | |
29 | 0x0008, /* D */ | |
30 | 0x0E00, /* E */ | |
31 | 0x000A, /* F */ | |
32 | 0x2E10, /* 10 */ | |
33 | 0xFFFF}; /* 11 */ | |
34 | return a; | |
35 | } | |
36 | ||
37 | int crc32_update(int crc, int byte) | |
38 | { | |
39 | int i, j; | |
40 | ||
41 | crc ^= byte; | |
42 | for (i = 0; i < 8; i += 1) | |
43 | { | |
44 | if (crc & 1) | |
45 | j = 3988292384; | |
46 | else | |
47 | j = 0; | |
48 | crc = (crc >> 1) ^ j; | |
49 | } | |
50 | return crc; | |
51 | } | |
52 | ||
53 | int muxreg(int reg, struct cpustate * s) | |
54 | { | |
55 | if (reg == 0) return s->r0; | |
56 | if (reg == 1) return s->r1; | |
57 | if (reg == 2) return s->r2; | |
58 | if (reg == 3) return s->r3; | |
59 | if (reg == 4) return s->fr; | |
60 | if (reg == 5) return s->pc; | |
61 | if (reg == 6) return s->sp; | |
62 | return abort(); | |
63 | } | |
64 | ||
65 | int setreg(int reg, int d, struct cpustate *s) | |
66 | { | |
67 | if (reg == 0) s->r0 = d; | |
68 | if (reg == 1) s->r1 = d; | |
69 | if (reg == 2) s->r2 = d; | |
70 | if (reg == 3) s->r3 = d; | |
71 | if (reg == 4) s->fr = d; | |
72 | if (reg == 5) s->pc = d; | |
73 | if (reg == 6) s->sp = d; | |
74 | return 0; | |
75 | } | |
76 | ||
77 | int predcheck(int pred, struct cpustate *s) | |
78 | { | |
79 | if (pred == 0) return 0; | |
80 | if (pred == 1) return !(s->fr & 4); | |
81 | if (pred == 2) return (s->fr & 4); | |
82 | if (pred == 3) return (s->fr & 1); | |
83 | if (pred == 4) return (s->fr & 2); | |
84 | if (pred == 7) return 1; | |
85 | return abort(); | |
86 | } | |
87 | ||
88 | void testmain() | |
89 | { | |
90 | struct cpustate cs, *s; | |
91 | int crc, iv, insn, pred, rt, rs, d; | |
92 | int* rom; | |
93 | ||
94 | s = &cs; | |
95 | crc = 0; | |
96 | iv = 0; | |
97 | insn = 0; | |
98 | s->pc = 0; | |
99 | s->r0 = 0; | |
100 | s->r1 = 0; | |
101 | s->r2 = 0; | |
102 | s->r3 = 0; | |
103 | s->fr = 0; | |
104 | s->sp = 0; | |
105 | rom = ROM(); | |
106 | ||
107 | while (insn != 15) | |
108 | { | |
109 | iv = rom[s->pc]; | |
110 | insn = iv >> 12; | |
111 | pred = (iv >> 9) & 7; | |
112 | rt = (iv >> 4) & 15; | |
113 | rs = iv & 15; | |
114 | crc = crc32_update(crc, s->r0); | |
115 | crc = crc32_update(crc, s->r1); | |
116 | crc = crc32_update(crc, s->r2); | |
117 | crc = crc32_update(crc, s->r3); | |
118 | crc = crc32_update(crc, s->fr); | |
119 | crc = crc32_update(crc, s->sp); | |
120 | crc = crc32_update(crc, s->pc); | |
121 | ||
122 | if (insn == 0) | |
123 | { | |
124 | s->pc += 1; | |
125 | if (!predcheck(pred, s)) | |
126 | { | |
127 | s->pc += 1; | |
128 | continue; | |
129 | } | |
130 | d = rom[s->pc]; | |
131 | s->pc += 1; | |
132 | setreg(rt, d, s); | |
133 | } else if (insn == 1) { | |
134 | s->pc += 1; | |
135 | if (!predcheck(pred, s)) | |
136 | continue; | |
137 | d = rom[muxreg(rs, s)]; | |
138 | setreg(rt, d, s); | |
139 | } else if (insn == 2) { | |
140 | s->pc += 1; | |
141 | if (!predcheck(pred, s)) | |
142 | continue; | |
143 | d = muxreg(rs, s); | |
144 | if (muxreg(rt, s) != 16384) | |
145 | return abort(); | |
146 | putchar(d); | |
147 | } else if (insn == 3) { | |
148 | s->pc += 1; | |
149 | if (!predcheck(pred, s)) | |
150 | continue; | |
151 | d = muxreg(rs, s); | |
152 | setreg(rt, d, s); | |
153 | } else if (insn == 4) { | |
154 | s->pc += 1; | |
155 | if (!predcheck(pred, s)) | |
156 | continue; | |
157 | d = muxreg(rs, s); | |
158 | d += muxreg(rt, s); | |
159 | d &= 65535; | |
160 | setreg(rt, d, s); | |
161 | } else if (insn == 5) { | |
162 | s->pc += 1; | |
163 | if (!predcheck(pred, s)) | |
164 | continue; | |
165 | d = muxreg(rs, s); | |
166 | d -= muxreg(rt, s); | |
167 | s->fr = 0; | |
168 | if (d == 0) s->fr |= 4; | |
169 | if (d > 0) s->fr |= 1; | |
170 | if (d < 0) s->fr |= 2; | |
171 | } else if (insn == 6) { | |
172 | s->pc += 1; | |
173 | if (!predcheck(pred, s)) | |
174 | continue; | |
175 | d = muxreg(rs, s); | |
176 | d &= muxreg(rt, s); | |
177 | setreg(rt, d, s); | |
178 | } else if (insn == 7) { | |
179 | s->pc += 1; | |
180 | if (!predcheck(pred, s)) | |
181 | continue; | |
182 | d = muxreg(rt, s); | |
183 | d = ~d; | |
184 | d &= 65535; | |
185 | setreg(rt, d, s); | |
186 | } | |
187 | } | |
188 | ||
189 | if (crc != -293203597) | |
190 | { | |
191 | puthex(crc); | |
192 | puts(": FAIL\n"); | |
193 | } else | |
194 | puts("PASS\n"); | |
195 | return; | |
196 | } |