1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22: #include "sysdep.h"
23: #include "dis-asm.h"
24:
25: static const char *const reg_names[] = {
26: "pfp", "sp", "rip", "r3", "r4", "r5", "r6", "r7",
27: "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
28: "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
29: "g8", "g9", "g10", "g11", "g12", "g13", "g14", "fp",
30: "pc", "ac", "ip", "tc", "fp0", "fp1", "fp2", "fp3"
31: };
32:
33:
34: static FILE *stream;
35: static struct disassemble_info *info;
36: static void print_addr (bfd_vma);
37: static void ctrl (bfd_vma, unsigned long, unsigned long);
38: static void cobr (bfd_vma, unsigned long, unsigned long);
39: static void reg (unsigned long);
40: static int mem (bfd_vma, unsigned long, unsigned long, int);
41: static void ea (bfd_vma, int, const char *, const char *, int, unsigned int);
42: static void dstop (int, int, int);
43: static void regop (int, int, int, int);
44: static void invalid (int);
45: static int pinsn (bfd_vma, unsigned long, unsigned long);
46: static void put_abs (unsigned long, unsigned long);
47:
48:
49:
50:
51:
52: int
53: print_insn_i960 (bfd_vma memaddr, struct disassemble_info *info_arg)
54: {
55: unsigned int word1, word2 = 0xdeadbeef;
56: bfd_byte buffer[8];
57: int status;
58:
59: info = info_arg;
60: stream = info->stream;
61:
62:
63:
64:
65: status = (*info->read_memory_func) (memaddr, (bfd_byte *) buffer, 4, info);
66: if (status != 0)
67: {
68: (*info->memory_error_func) (status, memaddr, info);
69: return -1;
70: }
71:
72: word1 = bfd_getl32 (buffer);
73:
74:
75: switch ( (word1 >> 28) & 0xf )
76: {
77: default:
78: break;
79: case 0x8:
80: case 0x9:
81: case 0xa:
82: case 0xb:
83: case 0xc:
84:
85: status = (*info->read_memory_func)
86: (memaddr + 4, (bfd_byte *) (buffer + 4), 4, info);
87: if (status != 0)
88: {
89: (*info->memory_error_func) (status, memaddr, info);
90: return -1;
91: }
92: word2 = bfd_getl32 (buffer + 4);
93: break;
94: }
95:
96: return pinsn( memaddr, word1, word2 );
97: }
98: ^L
99: #define IN_GDB
100:
101:
102:
103:
104:
105:
106:
107:
108:
109: struct tabent {
110: char *name;
111: short numops;
112: };
113:
114: struct sparse_tabent {
115: int opcode;
116: char *name;
117: short numops;
118: };
119:
120: static int
121: pinsn (bfd_vma memaddr, unsigned long word1, unsigned long word2)
122: {
123: int instr_len;
124:
125: instr_len = 4;
126: put_abs (word1, word2);
127:
128:
129: switch ((word1 >> 28) & 0xf)
130: {
131: case 0x0:
132: case 0x1:
133: ctrl (memaddr, word1, word2);
134: break;
135: case 0x2:
136: case 0x3:
137: cobr (memaddr, word1, word2);
138: break;
139: case 0x5:
140: case 0x6:
141: case 0x7:
142: reg (word1);
143: break;
144: case 0x8:
145: case 0x9:
146: case 0xa:
147: case 0xb:
148: case 0xc:
149: instr_len = mem (memaddr, word1, word2, 0);
150: break;
151: default:
152:
153: invalid (word1);
154: break;
155: }
156: return instr_len;
157: }
158:
159:
160:
161: static void
162: ctrl (bfd_vma memaddr, unsigned long word1, unsigned long word2 ATTRIBUTE_UNUSED)
163: {
164: int i;
165: static const struct tabent ctrl_tab[] = {
166: { NULL, 0, },
167: { NULL, 0, },
168: { NULL, 0, },
169: { NULL, 0, },
170: { NULL, 0, },
171: { NULL, 0, },
172: { NULL, 0, },
173: { NULL, 0, },
174: { "b", 1, },
175: { "call", 1, },
176: { "ret", 0, },
177: { "bal", 1, },
178: { NULL, 0, },
179: { NULL, 0, },
180: { NULL, 0, },
181: { NULL, 0, },
182: { "bno", 1, },
183: { "bg", 1, },
184: { "be", 1, },
185: { "bge", 1, },
186: { "bl", 1, },
187: { "bne", 1, },
188: { "ble", 1, },
189: { "bo", 1, },
190: { "faultno", 0, },
191: { "faultg", 0, },
192: { "faulte", 0, },
193: { "faultge", 0, },
194: { "faultl", 0, },
195: { "faultne", 0, },
196: { "faultle", 0, },
197: { "faulto", 0, },
198: };
199:
200: i = (word1 >> 24) & 0xff;
201: if ((ctrl_tab[i].name == NULL) || ((word1 & 1) != 0))
202: {
203: invalid (word1);
204: return;
205: }
206:
207: (*info->fprintf_func) (stream, ctrl_tab[i].name);
208: if (word1 & 2)
209:
210: (*info->fprintf_func) (stream, ".f");
211:
212: if (ctrl_tab[i].numops == 1)
213: {
214:
215: word1 &= 0x00ffffff;
216:
217: if (word1 & 0x00800000)
218: {
219:
220: word1 |= (-1 & ~0xffffff);
221: }
222:
223: (*info->fprintf_func) (stream, "\t");
224: print_addr (word1 + memaddr);
225: }
226: }
227:
228:
229:
230: static void
231: cobr (bfd_vma memaddr, unsigned long word1, unsigned long word2 ATTRIBUTE_UNUSED)
232: {
233: int src1;
234: int src2;
235: int i;
236:
237: static const struct tabent cobr_tab[] = {
238: { "testno", 1, },
239: { "testg", 1, },
240: { "teste", 1, },
241: { "testge", 1, },
242: { "testl", 1, },
243: { "testne", 1, },
244: { "testle", 1, },
245: { "testo", 1, },
246: { NULL, 0, },
247: { NULL, 0, },
248: { NULL, 0, },
249: { NULL, 0, },
250: { NULL, 0, },
251: { NULL, 0, },
252: { NULL, 0, },
253: { NULL, 0, },
254: { "bbc", 3, },
255: { "cmpobg", 3, },
256: { "cmpobe", 3, },
257: { "cmpobge",3, },
258: { "cmpobl", 3, },
259: { "cmpobne",3, },
260: { "cmpoble",3, },
261: { "bbs", 3, },
262: { "cmpibno",3, },
263: { "cmpibg", 3, },
264: { "cmpibe", 3, },
265: { "cmpibge",3, },
266: { "cmpibl", 3, },
267: { "cmpibne",3, },
268: { "cmpible",3, },
269: { "cmpibo", 3, },
270: };
271:
272: i = ((word1 >> 24) & 0xff) - 0x20;
273: if (cobr_tab[i].name == NULL)
274: {
275: invalid (word1);
276: return;
277: }
278:
279: (*info->fprintf_func) (stream, cobr_tab[i].name);
280:
281:
282: if (word1 & 2)
283: (*info->fprintf_func) (stream, ".f");
284:
285: (*info->fprintf_func) (stream, "\t");
286:
287: src1 = (word1 >> 19) & 0x1f;
288: src2 = (word1 >> 14) & 0x1f;
289:
290: if (word1 & 0x02000)
291:
292: (*info->fprintf_func) (stream, "%d", src1);
293: else
294: (*info->fprintf_func) (stream, reg_names[src1]);
295:
296: if (cobr_tab[i].numops > 1)
297: {
298: if (word1 & 1)
299:
300: (*info->fprintf_func) (stream, ",sf%d,", src2);
301: else
302:
303: (*info->fprintf_func) (stream, ",%s,", reg_names[src2]);
304:
305:
306: word1 &= 0x00001ffc;
307: if (word1 & 0x00001000)
308:
309: word1 |= (-1 & ~0x1fff);
310:
311: print_addr (memaddr + word1);
312: }
313: }
314:
315:
316:
317:
318: static int
319: mem (bfd_vma memaddr, unsigned long word1, unsigned long word2, int noprint)
320: {
321: int i, j;
322: int len;
323: int mode;
324: int offset;
325: const char *reg1, *reg2, *reg3;
326:
327:
328:
329:
330:
331:
332:
333:
334:
335: static struct tabent *mem_tab;
336:
337: #define MEM_MIN 0x80
338: #define MEM_MAX 0xcf
339: #define MEM_SIZ ( * sizeof(struct tabent))
340:
341: static const struct sparse_tabent mem_init[] = {
342: { 0x80, "ldob", 2 },
343: { 0x82, "stob", -2 },
344: { 0x84, "bx", 1 },
345: { 0x85, "balx", 2 },
346: { 0x86, "callx", 1 },
347: { 0x88, "ldos", 2 },
348: { 0x8a, "stos", -2 },
349: { 0x8c, "lda", 2 },
350: { 0x90, "ld", 2 },
351: { 0x92, "st", -2 },
352: { 0x98, "ldl", 2 },
353: { 0x9a, "stl", -2 },
354: { 0xa0, "ldt", 2 },
355: { 0xa2, "stt", -2 },
356: { 0xac, "dcinva", 1 },
357: { 0xb0, "ldq", 2 },
358: { 0xb2, "stq", -2 },
359: { 0xc0, "ldib", 2 },
360: { 0xc2, "stib", -2 },
361: { 0xc8, "ldis", 2 },
362: { 0xca, "stis", -2 },
363: { 0, NULL, 0 }
364: };
365: static struct tabent mem_tab_buf[MEM_MAX - MEM_MIN + 1];
366:
367: if (mem_tab == NULL)
368: {
369: mem_tab = mem_tab_buf;
370:
371: for (i = 0; mem_init[i].opcode != 0; i++)
372: {
373: j = mem_init[i].opcode - MEM_MIN;
374: mem_tab[j].name = mem_init[i].name;
375: mem_tab[j].numops = mem_init[i].numops;
376: }
377: }
378:
379: i = ((word1 >> 24) & 0xff) - MEM_MIN;
380: mode = (word1 >> 10) & 0xf;
381:
382: if ((mem_tab[i].name != NULL)
383: && ((mode == 5) || (mode >= 12)))
384:
385: len = 8;
386: else
387: len = 4;
388:
389: if (noprint)
390: return len;
391:
392: if ((mem_tab[i].name == NULL) || (mode == 6))
393: {
394: invalid (word1);
395: return len;
396: }
397:
398: (*info->fprintf_func) (stream, "%s\t", mem_tab[i].name);
399:
400: reg1 = reg_names[ (word1 >> 19) & 0x1f ];
401: reg2 = reg_names[ (word1 >> 14) & 0x1f ];
402: reg3 = reg_names[ word1 & 0x1f ];
403: offset = word1 & 0xfff;
404:
405: switch (mem_tab[i].numops)
406: {
407: case 2:
408: if (mode & 4)
409: {
410: ea (memaddr, mode, reg2, reg3, word1, word2);
411: (*info->fprintf_func) (stream, ",%s", reg1);
412: }
413: else
414: {
415: (*info->fprintf_func) (stream, "0x%x", (unsigned) offset);
416:
417: if (mode & 8)
418: (*info->fprintf_func) (stream, "(%s)", reg2);
419:
420: (*info->fprintf_func)(stream, ",%s", reg1);
421: }
422: break;
423:
424: case -2:
425: if (mode & 4)
426: {
427:
428: (*info->fprintf_func) (stream, "%s,", reg1);
429: ea (memaddr, mode, reg2, reg3, word1, word2);
430: }
431: else
432: {
433:
434: (*info->fprintf_func) (stream, "%s,0x%x", reg1, (unsigned) offset);
435:
436: if (mode & 8)
437: (*info->fprintf_func) (stream, "(%s)", reg2);
438: }
439: break;
440:
441: case 1:
442: if (mode & 4)
443: {
444:
445: ea (memaddr, mode, reg2, reg3, word1, word2);
446: }
447: else
448: {
449:
450: (*info->fprintf_func) (stream, "0x%x", (unsigned) offset);
451: if (mode & 8)
452: (*info->fprintf_func) (stream, "(%s)", reg2);
453: }
454: break;
455: }
456:
457: return len;
458: }
459:
460:
461:
462: static void
463: reg (unsigned long word1)
464: {
465: int i, j;
466: int opcode;
467: int fp;
468: int m1, m2, m3;
469: int s1, s2;
470: int src, src2, dst;
471: char *mnemp;
472:
473:
474:
475:
476:
477:
478:
479:
480:
481:
482:
483:
484:
485:
486:
487: static struct tabent *reg_tab;
488: static const struct sparse_tabent reg_init[] =
489: {
490: #define REG_MIN 0x580
491: { 0x580, "notbit", 3 },
492: { 0x581, "and", 3 },
493: { 0x582, "andnot", 3 },
494: { 0x583, "setbit", 3 },
495: { 0x584, "notand", 3 },
496: { 0x586, "xor", 3 },
497: { 0x587, "or", 3 },
498: { 0x588, "nor", 3 },
499: { 0x589, "xnor", 3 },
500: { 0x58a, "not", -2 },
501: { 0x58b, "ornot", 3 },
502: { 0x58c, "clrbit", 3 },
503: { 0x58d, "notor", 3 },
504: { 0x58e, "nand", 3 },
505: { 0x58f, "alterbit", 3 },
506: { 0x590, "addo", 3 },
507: { 0x591, "addi", 3 },
508: { 0x592, "subo", 3 },
509: { 0x593, "subi", 3 },
510: { 0x594, "cmpob", 2 },
511: { 0x595, "cmpib", 2 },
512: { 0x596, "cmpos", 2 },
513: { 0x597, "cmpis", 2 },
514: { 0x598, "shro", 3 },
515: { 0x59a, "shrdi", 3 },
516: { 0x59b, "shri", 3 },
517: { 0x59c, "shlo", 3 },
518: { 0x59d, "rotate", 3 },
519: { 0x59e, "shli", 3 },
520: { 0x5a0, "cmpo", 2 },
521: { 0x5a1, "cmpi", 2 },
522: { 0x5a2, "concmpo", 2 },
523: { 0x5a3, "concmpi", 2 },
524: { 0x5a4, "cmpinco", 3 },
525: { 0x5a5, "cmpinci", 3 },
526: { 0x5a6, "cmpdeco", 3 },
527: { 0x5a7, "cmpdeci", 3 },
528: { 0x5ac, "scanbyte", 2 },
529: { 0x5ad, "bswap", -2 },
530: { 0x5ae, "chkbit", 2 },
531: { 0x5b0, "addc", 3 },
532: { 0x5b2, "subc", 3 },
533: { 0x5b4, "intdis", 0 },
534: { 0x5b5, "inten", 0 },
535: { 0x5cc, "mov", -2 },
536: { 0x5d8, "eshro", 3 },
537: { 0x5dc, "movl", -2 },
538: { 0x5ec, "movt", -2 },
539: { 0x5fc, "movq", -2 },
540: { 0x600, "synmov", 2 },
541: { 0x601, "synmovl", 2 },
542: { 0x602, "synmovq", 2 },
543: { 0x603, "cmpstr", 3 },
544: { 0x604, "movqstr", 3 },
545: { 0x605, "movstr", 3 },
546: { 0x610, "atmod", 3 },
547: { 0x612, "atadd", 3 },
548: { 0x613, "inspacc", -2 },
549: { 0x614, "ldphy", -2 },
550: { 0x615, "synld", -2 },
551: { 0x617, "fill", 3 },
552: