1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29: #include "sysdep.h"
30: #include <stdio.h>
31: #include "ansidecl.h"
32: #include "dis-asm.h"
33: #include "bfd.h"
34: #include "symcat.h"
35: #include "libiberty.h"
36: #include "frv-desc.h"
37: #include "frv-opc.h"
38: #include "opintl.h"
39:
40:
41: #define UNKNOWN_INSN_MSG _("*unknown*")
42:
43: static void print_normal
44: (CGEN_CPU_DESC, void *, long, unsigned int, bfd_vma, int);
45: static void print_address
46: (CGEN_CPU_DESC, void *, bfd_vma, unsigned int, bfd_vma, int) ATTRIBUTE_UNUSED;
47: static void print_keyword
48: (CGEN_CPU_DESC, void *, CGEN_KEYWORD *, long, unsigned int) ATTRIBUTE_UNUSED;
49: static void print_insn_normal
50: (CGEN_CPU_DESC, void *, const CGEN_INSN *, CGEN_FIELDS *, bfd_vma, int);
51: static int print_insn
52: (CGEN_CPU_DESC, bfd_vma, disassemble_info *, bfd_byte *, unsigned);
53: static int default_print_insn
54: (CGEN_CPU_DESC, bfd_vma, disassemble_info *) ATTRIBUTE_UNUSED;
55: static int read_insn
56: (CGEN_CPU_DESC, bfd_vma, disassemble_info *, bfd_byte *, int, CGEN_EXTRACT_INFO *,
57: unsigned long *);
58: ^L
59:
60:
61:
62: static void
63: print_at (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
64: void * dis_info,
65: long reloc_ann ATTRIBUTE_UNUSED,
66: long value ATTRIBUTE_UNUSED,
67: bfd_vma pc ATTRIBUTE_UNUSED,
68: int length ATTRIBUTE_UNUSED)
69: {
70: disassemble_info *info = (disassemble_info *) dis_info;
71:
72: (*info->fprintf_func) (info->stream, "@");
73: }
74:
75: static void
76: print_spr (CGEN_CPU_DESC cd,
77: void * dis_info,
78: CGEN_KEYWORD *names,
79: long regno,
80: unsigned int attrs)
81: {
82:
83: if (cgen_keyword_lookup_value (names, regno) == NULL)
84: {
85: disassemble_info *info = (disassemble_info *) dis_info;
86: (*info->fprintf_func) (info->stream, "spr[%ld]", regno);
87: }
88: else
89: print_keyword (cd, dis_info, names, regno, attrs);
90: }
91:
92: static void
93: print_hi (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
94: void * dis_info,
95: long value,
96: unsigned int attrs ATTRIBUTE_UNUSED,
97: bfd_vma pc ATTRIBUTE_UNUSED,
98: int length ATTRIBUTE_UNUSED)
99: {
100: disassemble_info *info = (disassemble_info *) dis_info;
101:
102: (*info->fprintf_func) (info->stream, value ? "0x%lx" : "hi(0x%lx)", value);
103: }
104:
105: static void
106: print_lo (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
107: void * dis_info,
108: long value,
109: unsigned int attrs ATTRIBUTE_UNUSED,
110: bfd_vma pc ATTRIBUTE_UNUSED,
111: int length ATTRIBUTE_UNUSED)
112: {
113: disassemble_info *info = (disassemble_info *) dis_info;
114: if (value)
115: (*info->fprintf_func) (info->stream, "0x%lx", value);
116: else
117: (*info->fprintf_func) (info->stream, "lo(0x%lx)", value);
118: }
119:
120:
121:
122: void frv_cgen_print_operand
123: (CGEN_CPU_DESC, int, PTR, CGEN_FIELDS *, void const *, bfd_vma, int);
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140: void
141: frv_cgen_print_operand (CGEN_CPU_DESC cd,
142: int opindex,
143: void * xinfo,
144: CGEN_FIELDS *fields,
145: void const *attrs ATTRIBUTE_UNUSED,
146: bfd_vma pc,
147: int length)
148: {
149: disassemble_info *info = (disassemble_info *) xinfo;
150:
151: switch (opindex)
152: {
153: case FRV_OPERAND_A0 :
154: print_normal (cd, info, fields->f_A, 0, pc, length);
155: break;
156: case FRV_OPERAND_A1 :
157: print_normal (cd, info, fields->f_A, 0, pc, length);
158: break;
159: case FRV_OPERAND_ACC40SI :
160: print_keyword (cd, info, & frv_cgen_opval_acc_names, fields->f_ACC40Si, 0);
161: break;
162: case FRV_OPERAND_ACC40SK :
163: print_keyword (cd, info, & frv_cgen_opval_acc_names, fields->f_ACC40Sk, 0);
164: break;
165: case FRV_OPERAND_ACC40UI :
166: print_keyword (cd, info, & frv_cgen_opval_acc_names, fields->f_ACC40Ui, 0);
167: break;
168: case FRV_OPERAND_ACC40UK :
169: print_keyword (cd, info, & frv_cgen_opval_acc_names, fields->f_ACC40Uk, 0);
170: break;
171: case FRV_OPERAND_ACCGI :
172: print_keyword (cd, info, & frv_cgen_opval_accg_names, fields->f_ACCGi, 0);
173: break;
174: case FRV_OPERAND_ACCGK :
175: print_keyword (cd, info, & frv_cgen_opval_accg_names, fields->f_ACCGk, 0);
176: break;
177: case FRV_OPERAND_CCI :
178: print_keyword (cd, info, & frv_cgen_opval_cccr_names, fields->f_CCi, 0);
179: break;
180: case FRV_OPERAND_CPRDOUBLEK :
181: print_keyword (cd, info, & frv_cgen_opval_cpr_names, fields->f_CPRk, 0);
182: break;
183: case FRV_OPERAND_CPRI :
184: print_keyword (cd, info, & frv_cgen_opval_cpr_names, fields->f_CPRi, 0);
185: break;
186: case FRV_OPERAND_CPRJ :
187: print_keyword (cd, info, & frv_cgen_opval_cpr_names, fields->f_CPRj, 0);
188: break;
189: case FRV_OPERAND_CPRK :
190: print_keyword (cd, info, & frv_cgen_opval_cpr_names, fields->f_CPRk, 0);
191: break;
192: case FRV_OPERAND_CRI :
193: print_keyword (cd, info, & frv_cgen_opval_cccr_names, fields->f_CRi, 0);
194: break;
195: case FRV_OPERAND_CRJ :
196: print_keyword (cd, info, & frv_cgen_opval_cccr_names, fields->f_CRj, 0);
197: break;
198: case FRV_OPERAND_CRJ_FLOAT :
199: print_keyword (cd, info, & frv_cgen_opval_cccr_names, fields->f_CRj_float, 0);
200: break;
201: case FRV_OPERAND_CRJ_INT :
202: print_keyword (cd, info, & frv_cgen_opval_cccr_names, fields->f_CRj_int, 0);
203: break;
204: case FRV_OPERAND_CRK :
205: print_keyword (cd, info, & frv_cgen_opval_cccr_names, fields->f_CRk, 0);
206: break;
207: case FRV_OPERAND_FCCI_1 :
208: print_keyword (cd, info, & frv_cgen_opval_fccr_names, fields->f_FCCi_1, 0);
209: break;
210: case FRV_OPERAND_FCCI_2 :
211: print_keyword (cd, info, & frv_cgen_opval_fccr_names, fields->f_FCCi_2, 0);
212: break;
213: case FRV_OPERAND_FCCI_3 :
214: print_keyword (cd, info, & frv_cgen_opval_fccr_names, fields->f_FCCi_3, 0);
215: break;
216: case FRV_OPERAND_FCCK :
217: print_keyword (cd, info, & frv_cgen_opval_fccr_names, fields->f_FCCk, 0);
218: break;
219: case FRV_OPERAND_FRDOUBLEI :
220: print_keyword (cd, info, & frv_cgen_opval_fr_names, fields->f_FRi, 0);
221: break;
222: case FRV_OPERAND_FRDOUBLEJ :
223: print_keyword (cd, info, & frv_cgen_opval_fr_names, fields->f_FRj, 0);
224: break;
225: case FRV_OPERAND_FRDOUBLEK :
226: print_keyword (cd, info, & frv_cgen_opval_fr_names, fields->f_FRk, 0);
227: break;
228: case FRV_OPERAND_FRI :
229: print_keyword (cd, info, & frv_cgen_opval_fr_names, fields->f_FRi, 0);
230: break;
231: case FRV_OPERAND_FRINTI :
232: print_keyword (cd, info, & frv_cgen_opval_fr_names, fields->f_FRi, 0);
233: break;
234: case FRV_OPERAND_FRINTIEVEN :
235: print_keyword (cd, info, & frv_cgen_opval_fr_names, fields->f_FRi, 0);
236: break;
237: case FRV_OPERAND_FRINTJ :
238: print_keyword (cd, info, & frv_cgen_opval_fr_names, fields->f_FRj, 0);
239: break;
240: case FRV_OPERAND_FRINTJEVEN :
241: print_keyword (cd, info, & frv_cgen_opval_fr_names, fields->f_FRj, 0);
242: break;
243: case FRV_OPERAND_FRINTK :
244: print_keyword (cd, info, & frv_cgen_opval_fr_names, fields->f_FRk, 0);
245: break;
246: case FRV_OPERAND_FRINTKEVEN :
247: print_keyword (cd, info, & frv_cgen_opval_fr_names, fields->f_FRk, 0);
248: break;
249: case FRV_OPERAND_FRJ :
250: print_keyword (cd, info, & frv_cgen_opval_fr_names, fields->f_FRj, 0);
251: break;
252: case FRV_OPERAND_FRK :
253: print_keyword (cd, info, & frv_cgen_opval_fr_names, fields->f_FRk, 0);
254: break;
255: case FRV_OPERAND_FRKHI :
256: print_keyword (cd, info, & frv_cgen_opval_fr_names, fields->f_FRk, 0);
257: break;
258: case FRV_OPERAND_FRKLO :
259: print_keyword (cd, info, & frv_cgen_opval_fr_names, fields->f_FRk, 0);
260: break;
261: case FRV_OPERAND_GRDOUBLEK :
262: print_keyword (cd, info, & frv_cgen_opval_gr_names, fields->f_GRk, 0);
263: break;
264: case FRV_OPERAND_GRI :
265: print_keyword (cd, info, & frv_cgen_opval_gr_names, fields->f_GRi, 0);
266: break;
267: case FRV_OPERAND_GRJ :
268: print_keyword (cd, info, & frv_cgen_opval_gr_names, fields->f_GRj, 0);
269: break;
270: case FRV_OPERAND_GRK :
271: print_keyword (cd, info, & frv_cgen_opval_gr_names, fields->f_GRk, 0);
272: break;
273: case FRV_OPERAND_GRKHI :
274: print_keyword (cd, info, & frv_cgen_opval_gr_names, fields->f_GRk, 0);
275: break;
276: case FRV_OPERAND_GRKLO :
277: print_keyword (cd, info, & frv_cgen_opval_gr_names, fields->f_GRk, 0);
278: break;
279: case FRV_OPERAND_ICCI_1 :
280: print_keyword (cd, info, & frv_cgen_opval_iccr_names, fields->f_ICCi_1, 0);
281: break;
282: case FRV_OPERAND_ICCI_2 :
283: print_keyword (cd, info, & frv_cgen_opval_iccr_names, fields->f_ICCi_2, 0);
284: break;
285: case FRV_OPERAND_ICCI_3 :
286: print_keyword (cd, info, & frv_cgen_opval_iccr_names, fields->f_ICCi_3, 0);
287: break;
288: case FRV_OPERAND_LI :
289: print_normal (cd, info, fields->f_LI, 0, pc, length);
290: break;
291: case FRV_OPERAND_LRAD :
292: print_normal (cd, info, fields->f_LRAD, 0, pc, length);
293: break;
294: case FRV_OPERAND_LRAE :
295: print_normal (cd, info, fields->f_LRAE, 0, pc, length);
296: break;
297: case FRV_OPERAND_LRAS :
298: print_normal (cd, info, fields->f_LRAS, 0, pc, length);
299: break;
300: case FRV_OPERAND_TLBPRL :
301: print_normal (cd, info, fields->f_TLBPRL, 0, pc, length);
302: break;
303: case FRV_OPERAND_TLBPROPX :
304: print_normal (cd, info, fields->f_TLBPRopx, 0, pc, length);
305: break;
306: case FRV_OPERAND_AE :
307: print_normal (cd, info, fields->f_ae, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
308: break;
309: case FRV_OPERAND_CALLANN :
310: print_at (cd, info, fields->f_reloc_ann, 0, pc, length);
311: break;
312: case FRV_OPERAND_CCOND :
313: print_normal (cd, info, fields->f_ccond, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
314: break;
315: case FRV_OPERAND_COND :
316: print_normal (cd, info, fields->f_cond, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
317: break;
318: case FRV_OPERAND_D12 :
319: print_normal (cd, info, fields->f_d12, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
320: break;
321: case FRV_OPERAND_DEBUG :
322: print_normal (cd, info, fields->f_debug, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
323: break;
324: case FRV_OPERAND_EIR :
325: print_normal (cd, info, fields->f_eir, 0, pc, length);
326: break;
327: case FRV_OPERAND_HINT :
328: print_normal (cd, info, fields->f_hint, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
329: break;
330: case FRV_OPERAND_HINT_NOT_TAKEN :
331: print_keyword (cd, info, & frv_cgen_opval_h_hint_not_taken, fields->f_hint, 0);
332: break;
333: case FRV_OPERAND_HINT_TAKEN :
334: print_keyword (cd, info, & frv_cgen_opval_h_hint_taken, fields->f_hint, 0);
335: break;
336: case FRV_OPERAND_LABEL16 :
337: print_address (cd, info, fields->f_label16, 0|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
338: break;
339: case FRV_OPERAND_LABEL24 :
340: print_address (cd, info, fields->f_label24, 0|(1<<CGEN_OPERAND_PCREL_ADDR)|(1<<CGEN_OPERAND_VIRTUAL), pc, length);
341: break;
342: case FRV_OPERAND_LDANN :
343: print_at (cd, info, fields->f_reloc_ann, 0, pc, length);
344: break;
345: case FRV_OPERAND_LDDANN :
346: print_at (cd, info, fields->f_reloc_ann, 0, pc, length);
347: break;
348: case FRV_OPERAND_LOCK :
349: print_normal (cd, info, fields->f_lock, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
350: break;
351: case FRV_OPERAND_PACK :
352: print_keyword (cd, info, & frv_cgen_opval_h_pack, fields->f_pack, 0);
353: break;
354: case FRV_OPERAND_S10 :
355: print_normal (cd, info, fields->f_s10, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
356: break;
357: case FRV_OPERAND_S12 :
358: print_normal (cd, info, fields->f_d12, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
359: break;
360: case FRV_OPERAND_S16 :
361: print_normal (cd, info, fields->f_s16, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
362: break;
363: case FRV_OPERAND_S5 :
364: print_normal (cd, info, fields->f_s5, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
365: break;
366: case FRV_OPERAND_S6 :
367: print_normal (cd, info, fields->f_s6, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
368: break;
369: case FRV_OPERAND_S6_1 :
370: print_normal (cd, info, fields->f_s6_1, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
371: break;
372: case FRV_OPERAND_SLO16 :
373: print_lo (cd, info, fields->f_s16, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
374: break;
375: case FRV_OPERAND_SPR :
376: print_spr (cd, info, & frv_cgen_opval_spr_names, fields->f_spr, 0|(1<<CGEN_OPERAND_VIRTUAL));
377: break;
378: case FRV_OPERAND_U12 :
379: print_normal (cd, info, fields->f_u12, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_VIRTUAL), pc, length);
380: break;
381: case FRV_OPERAND_U16 :
382: print_normal (cd, info, fields->f_u16, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
383: break;
384: case FRV_OPERAND_U6 :
385: print_normal (cd, info, fields->f_u6, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
386: break;
387: case FRV_OPERAND_UHI16 :
388: print_hi (cd, info, fields->f_u16, 0, pc, length);
389: break;
390: case FRV_OPERAND_ULO16 :
391: print_lo (cd, info, fields->f_u16, 0, pc, length);
392: break;
393:
394: default :
395:
396: fprintf (stderr, _("Unrecognized field %d while printing insn.\n"),
397: opindex);
398: abort ();
399: }
400: }
401:
402: cgen_print_fn * const frv_cgen_print_handlers[] =
403: {
404: print_insn_normal,
405: };
406:
407:
408: void
409: frv_cgen_init_dis (CGEN_CPU_DESC cd)
410: {
411: frv_cgen_init_opcode_table (cd);
412: frv_cgen_init_ibld_table (cd);
413: cd->print_handlers = & frv_cgen_print_handlers[0];
414: cd->print_operand = frv_cgen_print_operand;
415: }
416:
417: ^L
418:
419:
420: static void
421: print_normal (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
422: void *dis_info,
423: long value,
424: unsigned int attrs,
425: bfd_vma pc ATTRIBUTE_UNUSED,
426: int length ATTRIBUTE_UNUSED)
427: {
428: disassemble_info *info = (disassemble_info *) dis_info;
429:
430: #ifdef CGEN_PRINT_NORMAL
431: CGEN_PRINT_NORMAL (cd, info, value, attrs, pc, length);
432: #endif
433:
434:
435: if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SEM_ONLY))
436: ;
437: else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SIGNED))
438: (*info->fprintf_func) (info->stream, "%ld", value);
439: else
440: (*info->fprintf_func) (info->stream, "0x%lx", value);
441: }
442:
443:
444:
445: static void
446: print_address (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
447: void *dis_info,
448: bfd_vma value,
449: unsigned int attrs,
450: bfd_vma pc ATTRIBUTE_UNUSED,
451: int length ATTRIBUTE_UNUSED)
452: {
453: disassemble_info *info = (disassemble_info *) dis_info;
454:
455: #ifdef CGEN_PRINT_ADDRESS
456: CGEN_PRINT_ADDRESS (cd, info, value, attrs, pc, length);
457: #endif
458:
459:
460: if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SEM_ONLY))
461: ;
462: else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_PCREL_ADDR))
463: (*info->print_address_func) (value, info);
464: else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_ABS_ADDR))
465: (*info->print_address_func) (value, info);
466: else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SIGNED))
467: (*info->fprintf_func) (info->stream, "%ld", (long) value);
468: else
469: (*info->fprintf_func) (info->stream, "0x%lx", (long) value);
470: }
471:
472:
473:
474: static void
475: print_keyword (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
476: void *dis_info,
477: CGEN_KEYWORD *keyword_table,
478: long value,
479: unsigned int attrs ATTRIBUTE_UNUSED)
480: {
481: disassemble_info *info = (disassemble_info *) dis_info;
482: const CGEN_KEYWORD_ENTRY *ke;
483:
484: ke = cgen_keyword_lookup_value (keyword_table, value);
485: if (ke != NULL)
486: (*info->fprintf_func) (info->stream, "%s", ke->name);
487: else
488: (*info->fprintf_func) (info->stream, "???");
489: }
490: ^L
491:
492:
493:
494:
495:
496: static void
497: print_insn_normal (CGEN_CPU_DESC cd,
498: void *dis_info,
499: const CGEN_INSN *insn,
500: CGEN_FIELDS *fields,
501: bfd_vma pc,
502: int length)
503: {
504: const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
505: disassemble_info *info = (disassemble_info *) dis_info;
506: const CGEN_SYNTAX_CHAR_TYPE *syn;
507:
508: CGEN_INIT_PRINT (cd);
509: