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