15 { "NOP", LOP, 0, F(0, 5) },
16 { "ADD", LOP, 1, F(0, 5) },
17 { "FADD", LOP, 1, 6 },
18 { "SUB", LOP, 2, F(0, 5) },
19 { "FSUB", LOP, 2, 6 },
20 { "MUL", LOP, 3, F(0, 5) },
21 { "FMUL", LOP, 3, 6 },
22 { "DIV", LOP, 4, F(0, 5) },
23 { "FDIV", LOP, 4, 6 },
25 { "CHAR", LOP, 5, 1 },
29 { "SLAX", LOP, 6, 2 },
30 { "SRAX", LOP, 6, 3 },
33 { "MOVE", LOP, 7, 1 },
34 { "LDA", LOP, 8, F(0, 5) },
35 { "LD1", LOP, 9, F(0, 5) },
36 { "LD2", LOP, 10, F(0, 5) },
37 { "LD3", LOP, 11, F(0, 5) },
38 { "LD4", LOP, 12, F(0, 5) },
39 { "LD5", LOP, 13, F(0, 5) },
40 { "LD6", LOP, 14, F(0, 5) },
41 { "LDX", LOP, 15, F(0, 5) },
42 { "LDAN", LOP, 16, F(0, 5) },
43 { "LD1N", LOP, 17, F(0, 5) },
44 { "LD2N", LOP, 18, F(0, 5) },
45 { "LD3N", LOP, 19, F(0, 5) },
46 { "LD4N", LOP, 20, F(0, 5) },
47 { "LD5N", LOP, 21, F(0, 5) },
48 { "LD6N", LOP, 22, F(0, 5) },
49 { "LDXN", LOP, 23, F(0, 5) },
50 { "STA", LOP, 24, F(0, 5) },
51 { "ST1", LOP, 25, F(0, 5) },
52 { "ST2", LOP, 26, F(0, 5) },
53 { "ST3", LOP, 27, F(0, 5) },
54 { "ST4", LOP, 28, F(0, 5) },
55 { "ST5", LOP, 29, F(0, 5) },
56 { "ST6", LOP, 30, F(0, 5) },
57 { "STX", LOP, 31, F(0, 5) },
58 { "STJ", LOP, 32, F(0, 2) },
59 { "STZ", LOP, 33, F(0, 5) },
60 { "JBUS", LOP, 34, 0 },
61 { "IOC", LOP, 35, 0 },
63 { "OUT", LOP, 37, 0 },
64 { "JRED", LOP, 38, 0 },
65 { "JMP", LOP, 39, 0 },
66 { "JSJ", LOP, 39, 1 },
67 { "JOV", LOP, 39, 2 },
68 { "JNOV", LOP, 39, 3 },
72 { "JGE", LOP, 39, 7 },
73 { "JNE", LOP, 39, 8 },
74 { "JLE", LOP, 39, 9 },
75 { "JAN", LOP, 40, 0 },
76 { "JAZ", LOP, 40, 1 },
77 { "JAP", LOP, 40, 2 },
78 { "JANN", LOP, 40, 3 },
79 { "JANZ", LOP, 40, 4 },
80 { "JANP", LOP, 40, 5 },
81 { "J1N", LOP, 41, 0 },
82 { "J1Z", LOP, 41, 1 },
83 { "J1P", LOP, 41, 2 },
84 { "J1NN", LOP, 41, 3 },
85 { "J1NZ", LOP, 41, 4 },
86 { "J1NP", LOP, 41, 5 },
87 { "J2N", LOP, 42, 0 },
88 { "J2Z", LOP, 42, 1 },
89 { "J2P", LOP, 42, 2 },
90 { "J2NN", LOP, 42, 3 },
91 { "J2NZ", LOP, 42, 4 },
92 { "J2NP", LOP, 42, 5 },
93 { "J3N", LOP, 43, 0 },
94 { "J3Z", LOP, 43, 1 },
95 { "J3P", LOP, 43, 2 },
96 { "J3NN", LOP, 43, 3 },
97 { "J3NZ", LOP, 43, 4 },
98 { "J3NP", LOP, 43, 5 },
99 { "J4N", LOP, 44, 0 },
100 { "J4Z", LOP, 44, 1 },
101 { "J4P", LOP, 44, 2 },
102 { "J4NN", LOP, 44, 3 },
103 { "J4NZ", LOP, 44, 4 },
104 { "J4NP", LOP, 44, 5 },
105 { "J5N", LOP, 45, 0 },
106 { "J5Z", LOP, 45, 1 },
107 { "J5P", LOP, 45, 2 },
108 { "J5NN", LOP, 45, 3 },
109 { "J5NZ", LOP, 45, 4 },
110 { "J5NP", LOP, 45, 5 },
111 { "J6N", LOP, 46, 0 },
112 { "J6Z", LOP, 46, 1 },
113 { "J6P", LOP, 46, 2 },
114 { "J6NN", LOP, 46, 3 },
115 { "J6NZ", LOP, 46, 4 },
116 { "J6NP", LOP, 46, 5 },
117 { "JXN", LOP, 47, 0 },
118 { "JXZ", LOP, 47, 1 },
119 { "JXP", LOP, 47, 2 },
120 { "JXNN", LOP, 47, 3 },
121 { "JXNZ", LOP, 47, 4 },
122 { "JXNP", LOP, 47, 5 },
123 { "INCA", LOP, 48, 0 },
124 { "DECA", LOP, 48, 1 },
125 { "ENTA", LOP, 48, 2 },
126 { "ENNA", LOP, 48, 3 },
127 { "INC1", LOP, 49, 0 },
128 { "DEC1", LOP, 49, 1 },
129 { "ENT1", LOP, 49, 2 },
130 { "ENN1", LOP, 49, 3 },
131 { "INC2", LOP, 50, 0 },
132 { "DEC2", LOP, 50, 1 },
133 { "ENT2", LOP, 50, 2 },
134 { "ENN2", LOP, 50, 3 },
135 { "INC3", LOP, 51, 0 },
136 { "DEC3", LOP, 51, 1 },
137 { "ENT3", LOP, 51, 2 },
138 { "ENN3", LOP, 51, 3 },
139 { "INC4", LOP, 52, 0 },
140 { "DEC4", LOP, 52, 1 },
141 { "ENT4", LOP, 52, 2 },
142 { "ENN4", LOP, 52, 3 },
143 { "INC5", LOP, 53, 0 },
144 { "DEC5", LOP, 53, 1 },
145 { "ENT5", LOP, 53, 2 },
146 { "ENN5", LOP, 53, 3 },
147 { "INC6", LOP, 54, 0 },
148 { "DEC6", LOP, 54, 1 },
149 { "ENT6", LOP, 54, 2 },
150 { "ENN6", LOP, 54, 3 },
151 { "INCX", LOP, 55, 0 },
152 { "DECX", LOP, 55, 1 },
153 { "ENTX", LOP, 55, 2 },
154 { "ENNX", LOP, 55, 3 },
155 { "CMPA", LOP, 56, F(0, 5) },
156 { "FCMP", LOP, 56, 6 },
157 { "CMP1", LOP, 57, F(0, 5) },
158 { "CMP2", LOP, 58, F(0, 5) },
159 { "CMP3", LOP, 59, F(0, 5) },
160 { "CMP4", LOP, 60, F(0, 5) },
161 { "CMP5", LOP, 61, F(0, 5) },
162 { "CMP6", LOP, 62, F(0, 5) },
163 { "CMPX", LOP, 63, F(0, 5) },
164 { "EQU", LEQU, -1, -1 },
165 { "ORIG", LORIG, -1, -1 },
166 { "CON", LCON, -1, -1 },
167 { "ALF", LALF, -1, -1 },
168 { "END", LEND, -1, -1 },
169 { "0H", LHERE, 0, -1 },
170 { "1H", LHERE, 1, -1 },
171 { "2H", LHERE, 2, -1 },
172 { "3H", LHERE, 3, -1 },
173 { "4H", LHERE, 4, -1 },
174 { "5H", LHERE, 5, -1 },
175 { "6H", LHERE, 6, -1 },
176 { "7H", LHERE, 7, -1 },
177 { "8H", LHERE, 8, -1 },
178 { "9H", LHERE, 9, -1 },
179 { "0B", LBACK, 0, -1 },
180 { "1B", LBACK, 1, -1 },
181 { "2B", LBACK, 2, -1 },
182 { "3B", LBACK, 3, -1 },
183 { "4B", LBACK, 4, -1 },
184 { "5B", LBACK, 5, -1 },
185 { "6B", LBACK, 6, -1 },
186 { "7B", LBACK, 7, -1 },
187 { "8B", LBACK, 8, -1 },
188 { "9B", LBACK, 9, -1 },
189 { "0F", LFORW, 0, -1 },
190 { "1F", LFORW, 1, -1 },
191 { "2F", LFORW, 2, -1 },
192 { "3F", LFORW, 3, -1 },
193 { "4F", LFORW, 4, -1 },
194 { "5F", LFORW, 5, -1 },
195 { "6F", LFORW, 6, -1 },
196 { "7F", LFORW, 7, -1 },
197 { "8F", LFORW, 8, -1 },
198 { "9F", LFORW, 9, -1 },
209 int symcmp(Avl*, Avl*);
213 main(int argc, char **argv)
220 case 'g': go++; break;
225 fmtinstall('I', Ifmt);
227 for(ap = argv; ap < argv+argc; ap++)
239 syms = avlcreate(symcmp);
240 for(r = res; r < res + nelem(res); r++) {
254 if((fd = open(file, OREAD)) == -1)
256 Binit(&bin, fd, OREAD);
259 if(setjmp(errjmp) == 0)
267 unpack(u32int inst, int *apart, int *ipart, int *fpart)
271 opc = V(inst, F(5, 5));
272 *fpart = V(inst, F(4, 4));
273 *ipart = V(inst, F(3, 3));
274 *apart = V(inst, F(0, 2));
282 int i, apart, ipart, fpart, opc, a, b;
284 inst = va_arg(f->args, u32int);
285 opc = unpack(inst, &apart, &ipart, &fpart);
286 for(i = 0; i < nelem(res); i++) {
291 if(res[i+1].c != opc || opc == 56)
292 return fmtprint(f, "%s\t%d,%d(%d | %d:%d)", res[i].name, apart, ipart, fpart, a, b);
293 while(res[i].c == opc && i < nelem(res)) {
294 if(res[i].f == fpart)
295 return fmtprint(f, "%s\t%d,%d(%d | %d:%d)", res[i].name, apart, ipart, fpart, a, b);
298 return fmtprint(f, "%d\t%d,%d(%d | %d:%d)", opc, apart, ipart, fpart, a, b);
336 static char cbuf[100];
350 case '\n': case '*': case '+':
351 case '-': case ':': case ',':
352 case '(': case ')': case '=':
362 for(bp = buf; bp < buf+5; bp++) {
366 yyerror("Bad string literal\n");
371 ep = buf+nelem(buf)-1;
374 if(runetomix(r) == -1)
375 yyerror("Invalid character %C", r);
377 yyerror("Symbol or number too long");
379 if(isnum && (r >= Runeself || !isdigit(r)))
382 case Beof: case '\t': case '\n':
383 case '+': case '-': case '*':
384 case ':': case ',': case '(':
385 case ')': case '=': case ' ':
393 seprint(cbuf, cbuf+100, "%S", buf);
395 yylval.lval = strtol(cbuf, nil, 10);
398 yylval.sym = sym(cbuf);
399 return yylval.sym->lex;
407 s = emallocz(sizeof(*s) + strlen(name));
408 strcpy(s->nbuf, name);
420 s = (Sym*)avllookup(syms, &l, 0);
429 symcmp(Avl *a, Avl *b)
435 return strcmp(sa->name, sb->name);
445 if(r != c && r != Beof)
452 mval(u32int a, int s, u32int m)
478 if(a > 5 || b > 5 || d < 0 || d > 4)
479 vmerror("Invalid fpart %d", f);
481 return mval(w, 5-b, mask[d]);
489 r = ri[i] & ~(MASK3<<2*BITS);
490 off = i == 0 ? 0 : mval(r, 0, MASK2);
501 rval = mval(ra, 0, MASK5);
502 rval += V(cells[m], f);
503 ra = rval < 0 ? -rval|SIGNB : rval;
517 rval = mval(ra, 0, MASK5);
518 rval -= V(cells[m], f);
519 ra = rval < 0 ? -rval|SIGNB : rval;
534 rval = mval(ra, 0, MASK5);
535 rval *= V(cells[m], f);
543 ra = rval>>5*BITS & MASK5 | signb;
544 rx = rval & MASK5 | signb;
553 u32int xsignb, asignb;
585 ra = quot & MASK5 | asignb;
586 rx = rem & MASK5 | xsignb;
596 for(i = 0; i < 5; i++) {
597 b = ra>>(4-i)*BITS & MASK1;
601 for(i = 0; i < 5; i++) {
602 b = rx>>(4-i)*BITS & MASK1;
617 for(i = 0; i < 5; i++) {
620 rx &= ~(MASK1 << i*BITS);
624 for(i = 0; i < 5; i++) {
627 ra &= ~(MASK1 << i*BITS);
634 mixslra(int m, int left)
639 vmerror("Bad shift A %d", m);
654 mixslrax(int m, int left)
659 vmerror("Bad shift AX %d", m);
675 ra |= rax>>5*BITS & MASK5;
684 vmerror("Bad shift SLC %d", m);
694 s = rax & mask[m]<<10-m;
700 ra |= rax>>5*BITS & MASK5;
709 vmerror("Bad shift SRC %d", m);
721 rax &= ~mask[m] << 10-m;
725 ra |= rax>>5*BITS & MASK5;
729 mixmove(int s, int f)
736 if(s < 0 || s >= 4000 || s+f < 0 || s+f > 4000)
737 vmerror("Bad src range MOVE %d:%d", s, s+f-1);
738 d = mval(ri[1], 0, MASK2);
739 if(d < 0 || d >= 4000 || d+f < 0 || d+f > 4000)
740 vmerror("Bad dst range MOVE %d:%d", d, d+f-1);
748 ri[1] = d < 0 ? -d|SIGNB : d;
752 mixld(u32int v, int f)
771 if(a > 5 || b > 5 || d < 0 || d > 4)
772 vmerror("Bad fpart (%d:%d)", a, b);
773 v &= mask[d] << (5-b) * BITS;
779 mixst(u32int w, u32int v, int f)
788 w = v>>31 ? w|SIGNB : w&~SIGNB;
795 if(a > 5 || b > 5 || d < 0 || d > 4)
796 vmerror("Bad fpart (%d:%d)", a, b);
799 w &= ~(mask[d] << (5-b)*BITS);
804 mixjbus(int /*m*/, int /*f*/, int ip)
820 void mixin(int, int){}
836 mixjred(int m, int /*f*/, int /*ip*/)
842 mixjmp(int m, int ip)
844 ri[0] = ip+1 & MASK2;
849 mixjov(int m, int ip)
853 ri[0] = ip+1 & MASK2;
860 mixjnov(int m, int ip)
866 ri[0] = ip+1 & MASK2;
871 mixjc(int m, int ip, int c1, int c2)
874 ri[0] = ip+1 & MASK2;
881 mixjaxic(int m, int ip, u32int r, u32int msk, int f)
887 default: vmerror("Bad instruction JA condition: %d", f);
888 case 0: c = v < 0; break;
889 case 1: c = v == 0; break;
890 case 2: c = v > 0; break;
891 case 3: c = v >= 0; break;
892 case 4: c = v != 0; break;
893 case 5: c = v <= 0; break;
897 ri[0] = ip+1 & MASK2;
904 mixinc(int m, u32int *r)
908 v = mval(*r, 0, MASK5);
910 *r = v < 0 ? -v|SIGNB : v;
916 mixcmp(int m, int f, u32int r)
933 mixvm(int ip, int once)
936 int a, i, f, c, m, inst;
940 if(curpc < 0 || curpc > 4000)
941 vmerror("Bad PC %d", curpc);
942 if(bp[curpc] && !once)
945 a = V(inst, F(0, 2));
946 i = V(inst, F(3, 3));
947 f = V(inst, F(4, 4));
948 c = V(inst, F(5, 5));
952 fprint(2, "Bad op!\n");
983 vmerror("Bad instruction NUM or CHAR: %d", f);
996 default: vmerror("Bad instruction shift: %d", f);
997 case 0: mixslra(m, 1); break;
998 case 1: mixslra(m, 0); break;
999 case 2: mixslrax(m, 1); break;
1000 case 3: mixslrax(m, 0); break;
1001 case 4: mixslc(m); break;
1002 case 5: mixsrc(m); break;
1009 ra = mixld(cells[m], f);
1011 case 9: case 10: case 11:
1012 case 12: case 13: case 14:
1013 ri[c-8] = mixld(cells[m], f);
1016 rx = mixld(cells[m], f);
1019 ra = mixld(cells[m], f) ^ SIGNB;
1021 case 17: case 18: case 19:
1022 case 20: case 21: case 22:
1023 ri[c-16] = mixld(cells[m], f) ^ SIGNB;
1026 rx = mixld(cells[m], f) ^ SIGNB;
1029 cells[m] = mixst(cells[m], ra, f);
1031 case 25: case 26: case 27:
1032 case 28: case 29: case 30:
1033 r = ri[c-24] & ~(MASK3 << 2*BITS);
1034 cells[m] = mixst(cells[m], r, f);
1037 cells[m] = mixst(cells[m], rx, f);
1040 r = ri[0] & ~(MASK3 << 2*BITS);
1041 cells[m] = mixst(cells[m], r, f);
1044 cells[m] = mixst(cells[m], 0, f);
1047 curpc = mixjbus(m, f, curpc);
1059 curpc = mixjred(m, f, curpc);
1063 default: vmerror("Bad jmp instruction: %d", f);
1064 case 0: curpc = mixjmp(m, curpc); break;
1065 case 1: curpc = m; break; /* JSJ */
1066 case 2: curpc = mixjov(m, curpc); break;
1067 case 3: curpc = mixjnov(m, curpc); break;
1068 case 4: curpc = mixjc(m, curpc, cl, 0); break;
1069 case 5: curpc = mixjc(m, curpc, ce, 0); break;
1070 case 6: curpc = mixjc(m, curpc, cg, 0); break;
1071 case 7: curpc = mixjc(m, curpc, cg, ce); break;
1072 case 8: curpc = mixjc(m, curpc, cl, cg); break;
1073 case 9: curpc = mixjc(m, curpc, cl, ce); break;
1077 curpc = mixjaxic(m, curpc, ra, MASK5, f);
1079 case 41: case 42: case 43:
1080 case 44: case 45: case 46:
1081 curpc = mixjaxic(m, curpc, ri[c-40], MASK2, f);
1084 curpc = mixjaxic(m, curpc, rx, MASK5, f);
1088 case 0: mixinc(m, &ra); break;
1089 case 1: mixinc(-m, &ra); break;
1093 : m < 0 ? -m|SIGNB : m;
1098 : m > 0 ? m|SIGNB : -m;
1102 case 49: case 50: case 51:
1103 case 52: case 53: case 54:
1105 case 0: mixinc(m, ri+(c-48)); break;
1106 case 1: mixinc(-m, ri+(c-48)); break;
1110 : m < 0 ? -m|SIGNB : m;
1111 break; /* ENT[1-6] */
1115 : m > 0 ? m|SIGNB : -m;
1116 break; /* ENN[1-6] */
1121 case 0: mixinc(m, &rx); break;
1122 case 1: mixinc(-m, &rx); break;
1125 : m < 0 ? -m|SIGNB : m;
1129 : m > 0 ? m|SIGNB : -m;
1139 case 57: case 58: case 59:
1140 case 60: case 61: case 62:
1141 mixcmp(m, f, ri[c-56] & ~(MASK3<<2*BITS));