1 /* -*- mode: c; tab-width: 4; c-basic-offset: 4 -*- */
2 /********************************* disass.c ************************************
4 Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
6 See file COPYRIGHT for information on usage and disclaimer of warranties
8 A very primitive disassembler for Alpha machine code for easy debugging.
10 Authors: Reinhard Grafl EMAIL: cacao@complang.tuwien.ac.at
11 Andreas Krall EMAIL: cacao@complang.tuwien.ac.at
13 Last Change: 1997/10/22
15 *******************************************************************************/
25 static struct { int op; char *name; int itype; } ops[] = {
26 { 0x00, "", ITYPE_UNDEF},
27 { 0x01, "", ITYPE_UNDEF},
28 { 0x02, "", ITYPE_UNDEF},
29 { 0x03, "", ITYPE_UNDEF},
30 { 0x04, "", ITYPE_UNDEF},
31 { 0x05, "", ITYPE_UNDEF},
32 { 0x06, "", ITYPE_UNDEF},
33 { 0x07, "", ITYPE_UNDEF},
34 { 0x08, "LDA ", ITYPE_MEM},
35 { 0x09, "LDAH ", ITYPE_MEM},
36 { 0x0a, "LDB ", ITYPE_MEM},
37 { 0x0b, "LDQ_U ", ITYPE_MEM},
38 { 0x0c, "LDW ", ITYPE_MEM},
39 { 0x0d, "STW ", ITYPE_MEM},
40 { 0x0e, "STB ", ITYPE_MEM},
41 { 0x0f, "STQ_U ", ITYPE_MEM},
42 { 0x10, "OP ", ITYPE_OP},
43 { 0x11, "OP ", ITYPE_OP},
44 { 0x12, "OP ", ITYPE_OP},
45 { 0x13, "OP ", ITYPE_OP},
46 { 0x14, "", ITYPE_UNDEF},
47 { 0x15, "", ITYPE_UNDEF},
48 { 0x16, "FOP ", ITYPE_FOP},
49 { 0x17, "FOP ", ITYPE_FOP},
50 { 0x18, "MEMFMT ", ITYPE_MEM},
51 { 0x19, "", ITYPE_UNDEF},
52 { 0x1a, "JMP ", ITYPE_JMP},
53 { 0x1b, "", ITYPE_UNDEF},
54 { 0x1c, "OP ", ITYPE_OP},
55 { 0x1d, "", ITYPE_UNDEF},
56 { 0x1e, "", ITYPE_UNDEF},
57 { 0x1f, "", ITYPE_UNDEF},
58 { 0x20, "LDF ", ITYPE_MEM},
59 { 0x21, "LDG ", ITYPE_MEM},
60 { 0x22, "LDS ", ITYPE_MEM},
61 { 0x23, "LDT ", ITYPE_MEM},
62 { 0x24, "STF ", ITYPE_MEM},
63 { 0x25, "STG ", ITYPE_MEM},
64 { 0x26, "STS ", ITYPE_MEM},
65 { 0x27, "STT ", ITYPE_MEM},
66 { 0x28, "LDL ", ITYPE_MEM},
67 { 0x29, "LDQ ", ITYPE_MEM},
68 { 0x2a, "LDL_L ", ITYPE_MEM},
69 { 0x2b, "LDQ_L ", ITYPE_MEM},
70 { 0x2c, "STL ", ITYPE_MEM},
71 { 0x2d, "STQ ", ITYPE_MEM},
72 { 0x2e, "STL_C ", ITYPE_MEM},
73 { 0x2f, "STQ_C ", ITYPE_MEM},
74 { 0x30, "BR ", ITYPE_BRA},
75 { 0x31, "FBEQ ", ITYPE_BRA},
76 { 0x32, "FBLT ", ITYPE_BRA},
77 { 0x33, "FBLE ", ITYPE_BRA},
78 { 0x34, "BSR ", ITYPE_BRA},
79 { 0x35, "FBNE ", ITYPE_BRA},
80 { 0x36, "FBGE ", ITYPE_BRA},
81 { 0x37, "FBGT ", ITYPE_BRA},
82 { 0x38, "BLBC ", ITYPE_BRA},
83 { 0x39, "BEQ ", ITYPE_BRA},
84 { 0x3a, "BLT ", ITYPE_BRA},
85 { 0x3b, "BLE ", ITYPE_BRA},
86 { 0x3c, "BLBS ", ITYPE_BRA},
87 { 0x3d, "BNE ", ITYPE_BRA},
88 { 0x3e, "BGE ", ITYPE_BRA},
89 { 0x3f, "BGT ", ITYPE_BRA}
92 static struct { u2 op,fun; char *name; } op3s[] = {
93 { 0x10, 0x00, "ADDL " },
94 { 0x10, 0x40, "ADDL/V " },
95 { 0x10, 0x20, "ADDQ " },
96 { 0x10, 0x60, "ADDQ/V " },
97 { 0x10, 0x09, "SUBL " },
98 { 0x10, 0x49, "SUBL/V " },
99 { 0x10, 0x29, "SUBQ " },
100 { 0x10, 0x69, "SUBQ/V " },
101 { 0x10, 0x2D, "CMPEQ " },
102 { 0x10, 0x4D, "CMPLT " },
103 { 0x10, 0x6D, "CMPLE " },
104 { 0x10, 0x1D, "CMPULT " },
105 { 0x10, 0x3D, "CMPULE " },
106 { 0x10, 0x0F, "CMPBGE " },
107 { 0x10, 0x02, "S4ADDL " },
108 { 0x10, 0x0b, "S4SUBL " },
109 { 0x10, 0x22, "S4ADDQ " },
110 { 0x10, 0x2b, "S4SUBQ " },
111 { 0x10, 0x12, "S8ADDL " },
112 { 0x10, 0x1b, "S8SUBL " },
113 { 0x10, 0x32, "S8ADDQ " },
114 { 0x10, 0x3b, "S8SUBQ " },
115 { 0x11, 0x00, "AND " },
116 { 0x11, 0x20, "OR " },
117 { 0x11, 0x40, "XOR " },
118 { 0x11, 0x08, "ANDNOT " },
119 { 0x11, 0x28, "ORNOT " },
120 { 0x11, 0x48, "XORNOT " },
121 { 0x11, 0x24, "CMOVEQ " },
122 { 0x11, 0x44, "CMOVLT " },
123 { 0x11, 0x64, "CMOVLE " },
124 { 0x11, 0x26, "CMOVNE " },
125 { 0x11, 0x46, "CMOVGE " },
126 { 0x11, 0x66, "CMOVGT " },
127 { 0x11, 0x14, "CMOVLBS" },
128 { 0x11, 0x16, "CMOVLBC" },
129 { 0x12, 0x39, "SLL " },
130 { 0x12, 0x3C, "SRA " },
131 { 0x12, 0x34, "SRL " },
132 { 0x12, 0x30, "ZAP " },
133 { 0x12, 0x31, "ZAPNOT " },
134 { 0x12, 0x06, "EXTBL " },
135 { 0x12, 0x16, "EXTWL " },
136 { 0x12, 0x26, "EXTLL " },
137 { 0x12, 0x36, "EXTQL " },
138 { 0x12, 0x5a, "EXTWH " },
139 { 0x12, 0x6a, "EXTLH " },
140 { 0x12, 0x7a, "EXTQH " },
141 { 0x12, 0x0b, "INSBL " },
142 { 0x12, 0x1b, "INSWL " },
143 { 0x12, 0x2b, "INSLL " },
144 { 0x12, 0x3b, "INSQL " },
145 { 0x12, 0x57, "INSWH " },
146 { 0x12, 0x67, "INSLH " },
147 { 0x12, 0x77, "INSQH " },
148 { 0x12, 0x02, "MSKBL " },
149 { 0x12, 0x12, "MSKWL " },
150 { 0x12, 0x22, "MSKLL " },
151 { 0x12, 0x32, "MSKQL " },
152 { 0x12, 0x52, "MSKWH " },
153 { 0x12, 0x62, "MSKLH " },
154 { 0x12, 0x72, "MSKQH " },
155 { 0x13, 0x00, "MULL " },
156 { 0x13, 0x20, "MULQ " },
157 { 0x13, 0x40, "MULL/V " },
158 { 0x13, 0x60, "MULQ/V " },
159 { 0x13, 0x30, "UMULH " },
160 { 0x16, 0x080, "FADD " },
161 { 0x16, 0x0a0, "DADD " },
162 { 0x16, 0x081, "FSUB " },
163 { 0x16, 0x0a1, "DSUB " },
164 { 0x16, 0x082, "FMUL " },
165 { 0x16, 0x0a2, "DMUL " },
166 { 0x16, 0x083, "FDIV " },
167 { 0x16, 0x0a3, "DDIV " },
168 { 0x16, 0x580, "FADDS " },
169 { 0x16, 0x5a0, "DADDS " },
170 { 0x16, 0x581, "FSUBS " },
171 { 0x16, 0x5a1, "DSUBS " },
172 { 0x16, 0x582, "FMULS " },
173 { 0x16, 0x5a2, "DMULS " },
174 { 0x16, 0x583, "FDIVS " },
175 { 0x16, 0x5a3, "DDIVS " },
176 { 0x16, 0x0ac, "CVTDF " },
177 { 0x16, 0x0bc, "CVTLF " },
178 { 0x16, 0x0be, "CVTLD " },
179 { 0x16, 0x0af, "CVTDL " },
180 { 0x16, 0x02f, "CVTDLC " },
181 { 0x16, 0x5ac, "CVTDFS " },
182 { 0x16, 0x5af, "CVTDLS " },
183 { 0x16, 0x52f, "CVTDLCS" },
184 { 0x16, 0x0a4, "FCMPUN " },
185 { 0x16, 0x0a5, "FCMPEQ " },
186 { 0x16, 0x0a6, "FCMPLT " },
187 { 0x16, 0x0a7, "FCMPLE " },
188 { 0x16, 0x5a4, "FCMPUNS" },
189 { 0x16, 0x5a5, "FCMPEQS" },
190 { 0x16, 0x5a6, "FCMPLTS" },
191 { 0x16, 0x5a7, "FCMPLES" },
192 { 0x17, 0x020, "FMOV " },
193 { 0x17, 0x021, "FMOVN " },
194 { 0x1c, 0x0, "BSEXT " },
195 { 0x1c, 0x1, "WSEXT " },
201 static void disasscmd (int c, int pos)
203 int op, opfun, fopfun, i;
204 int ra, rb, rc, lit, disp;
207 opfun = (c>>5) & 0x7f;
208 fopfun = (c>>5) & 0x7ff;
212 lit = (c>>13) & 0xff;
213 disp = (c<<16) >> 16;
215 printf ("%6x: %8x ", pos, c);
217 switch ( ops[op].itype ) {
219 switch ((c>>14) & 3) {
233 printf ("$%d,$%d\n", ra, rb);
237 if (op == 0x18 && ra == 0 && ra == 0 && disp == 0)
240 printf ("%s $%d,$%d,%d\n", ops[op].name, ra, rb, disp);
244 printf ("%s $%d,%x\n", ops[op].name, ra, pos + 4 + ((c << 11) >> 9));
248 if (op == 0x17 && fopfun == 0x020 && ra == rb) {
249 if (ra == 31 && rc == 31)
252 printf ("FMOV $f%d,$f%d\n", ra, rc);
255 for (i = 0; op3s[i].name; i++)
256 if (op3s[i].op == op && op3s[i].fun == fopfun) {
257 printf ("%s $f%d,$f%d,$f%d\n", op3s[i].name, ra, rb, rc);
260 printf ("%s%x $f%d,$f%d,$f%d\n", ops[op].name, fopfun, ra, rb, rc);
264 if (op == 0x11 && opfun == 0x20 && ra == rb && ~(c&0x1000)) {
265 if (ra == 31 && rc == 31)
268 printf ("MOV $%d,$%d\n", ra, rc);
271 for (i = 0; op3s[i].name; i++) {
272 if (op3s[i].op == op && op3s[i].fun == opfun) {
274 printf ("%s $%d,#%d,$%d\n", op3s[i].name, ra, lit, rc);
276 printf ("%s $%d,$%d,$%d\n", op3s[i].name, ra, rb, rc);
283 printf ("UNDEF %x(%x) $%d,#%d,$%d\n", op, opfun, ra, lit, rc);
285 printf ("UNDEF %x(%x) $%d,$%d,$%d\n", op, opfun, ra, rb, rc);
290 /*********************** funktion disassemble **********************************
292 outputs a disassembler listing of some machine code on 'stdout'
294 *******************************************************************************/
296 static void disassemble (int *code, int len)
300 printf (" --- disassembler listing ---\n");
301 for (p = 0; p < len; p += 4, code++)
302 disasscmd (*code, p);