1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21: #include "dis-asm.h"
22: #include "sysdep.h"
23: #include "opcode/cr16.h"
24: #include "libiberty.h"
25:
26:
27: #define ILLEGAL "illegal"
28:
29: #define ESCAPE_16_BIT 0xB
30:
31:
32: #define EXTRACT(a, offs, n_bits) \
33: (n_bits == 32 ? (((a) >> (offs)) & 0xffffffffL) \
34: : (((a) >> (offs)) & ((1 << (n_bits)) -1)))
35:
36:
37: #define SBM(offs) ((((1 << (32 - offs)) -1) << (offs)))
38:
39: typedef unsigned long dwordU;
40: typedef unsigned short wordU;
41:
42: typedef struct
43: {
44: dwordU val;
45: int nbits;
46: } parameter;
47:
48:
49:
50: typedef struct
51: {
52:
53: char *istr;
54:
55: char *ostr;
56: }
57: cinv_entry;
58:
59:
60: const cinv_entry cr16_cinvs[] =
61: {
62: {"cinv[i]", "cinv [i]"},
63: {"cinv[i,u]", "cinv [i,u]"},
64: {"cinv[d]", "cinv [d]"},
65: {"cinv[d,u]", "cinv [d,u]"},
66: {"cinv[d,i]", "cinv [d,i]"},
67: {"cinv[d,i,u]", "cinv [d,i,u]"}
68: };
69:
70:
71: static int NUMCINVS = ARRAY_SIZE (cr16_cinvs);
72:
73:
74: typedef enum REG_ARG_TYPE
75: {
76:
77: REG_ARG = 0,
78:
79: P_ARG,
80: }
81: REG_ARG_TYPE;
82:
83:
84: const inst *instruction;
85:
86: ins currInsn;
87:
88: wordU words[3];
89:
90: ULONGLONG allWords;
91:
92: int processing_argument_number;
93:
94: int imm4flag;
95:
96:
97: int size_changed;
98:
99:
100:
101:
102: static char *
103: print_exp_len (int size)
104: {
105: switch (size)
106: {
107: case 4:
108: case 5:
109: case 6:
110: case 8:
111: case 14:
112: case 16:
113: return ":s";
114: case 20:
115: case 24:
116: case 32:
117: return ":m";
118: case 48:
119: return ":l";
120: default:
121: return "";
122: }
123: }
124:
125:
126:
127:
128: static int
129: get_number_of_operands (void)
130: {
131: int i;
132:
133: for (i = 0; instruction->operands[i].op_type && i < MAX_OPERANDS; i++)
134: ;
135:
136: return i;
137: }
138:
139:
140:
141: static int
142: getbits (operand_type op)
143: {
144: if (op < MAX_OPRD)
145: return cr16_optab[op].bit_size;
146:
147: return 0;
148: }
149:
150:
151:
152: static argtype
153: getargtype (operand_type op)
154: {
155: if (op < MAX_OPRD)
156: return cr16_optab[op].arg_type;
157:
158: return nullargs;
159: }
160:
161:
162:
163:
164: static char *
165: getccstring (unsigned cc)
166: {
167: return (char *) cr16_b_cond_tab[cc];
168: }
169:
170:
171:
172:
173:
174: static char *
175: getcinvstring (const char *str)
176: {
177: const cinv_entry *cinv;
178:
179: for (cinv = cr16_cinvs; cinv < (cr16_cinvs + NUMCINVS); cinv++)
180: if (strcmp (cinv->istr, str) == 0)
181: return cinv->ostr;
182:
183: return ILLEGAL;
184: }
185:
186:
187:
188:
189: static char *
190: gettrapstring (unsigned int index)
191: {
192: const trap_entry *trap;
193:
194: for (trap = cr16_traps; trap < cr16_traps + NUMTRAPS; trap++)
195: if (trap->entry == index)
196: return trap->name;
197:
198: return ILLEGAL;
199: }
200:
201:
202:
203: static char *
204: getregname (reg r)
205: {
206: const reg_entry *reg = cr16_regtab + r;
207:
208: if (reg->type != CR16_R_REGTYPE)
209: return ILLEGAL;
210:
211: return reg->name;
212: }
213:
214:
215:
216: static char *
217: getregpname (reg r)
218: {
219: const reg_entry *reg = cr16_regptab + r;
220:
221: if (reg->type != CR16_RP_REGTYPE)
222: return ILLEGAL;
223:
224: return reg->name;
225: }
226:
227:
228:
229: static char *
230: getidxregpname (reg r)
231: {
232: const reg_entry *reg;
233:
234: switch (r)
235: {
236: case 0: r = 0; break;
237: case 1: r = 2; break;
238: case 2: r = 4; break;
239: case 3: r = 6; break;
240: case 4: r = 8; break;
241: case 5: r = 10; break;
242: case 6: r = 3; break;
243: case 7: r = 5; break;
244: default:
245: break;
246: }
247:
248: reg = cr16_regptab + r;
249:
250: if (reg->type != CR16_RP_REGTYPE)
251: return ILLEGAL;
252:
253: return reg->name;
254: }
255:
256:
257:
258: static char *
259: getprocregname (int index)
260: {
261: const reg_entry *r;
262:
263: for (r = cr16_pregtab; r < cr16_pregtab + NUMPREGS; r++)
264: if (r->image == index)
265: return r->name;
266:
267: return "ILLEGAL REGISTER";
268: }
269:
270:
271:
272: static char *
273: getprocpregname (int index)
274: {
275: const reg_entry *r;
276:
277: for (r = cr16_pregptab; r < cr16_pregptab + NUMPREGPS; r++)
278: if (r->image == index)
279: return r->name;
280:
281: return "ILLEGAL REGISTER";
282: }
283:
284:
285:
286:
287:
288:
289:
290:
291:
292:
293: static parameter
294: makelongparameter (ULONGLONG val, int start, int end)
295: {
296: parameter p;
297:
298: p.val = (dwordU) EXTRACT (val, 48 - end, end - start);
299: p.nbits = end - start;
300: return p;
301: }
302:
303:
304:
305:
306: static unsigned long
307: build_mask (void)
308: {
309: unsigned long mask = SBM (instruction->match_bits);
310: return mask;
311: }
312:
313:
314:
315: static int
316: match_opcode (void)
317: {
318: unsigned long mask;
319:
320: unsigned long doubleWord = words[1] + (words[0] << 16);
321:
322:
323: instruction = &cr16_instruction[NUMOPCODES - 2];
324:
325:
326: while (instruction >= cr16_instruction)
327: {
328: mask = build_mask ();
329: if ((doubleWord & mask) == BIN (instruction->match,
330: instruction->match_bits))
331: return 1;
332: else
333: instruction--;
334: }
335: return 0;
336: }
337:
338:
339:
340: static void
341: make_argument (argument * a, int start_bits)
342: {
343: int inst_bit_size;
344: parameter p;
345:
346: if ((instruction->size == 3) && a->size >= 16)
347: inst_bit_size = 48;
348: else
349: inst_bit_size = 32;
350:
351: switch (a->type)
352: {
353: case arg_r:
354: p = makelongparameter (allWords, inst_bit_size - (start_bits + a->size),
355: inst_bit_size - start_bits);
356: a->r = p.val;
357: break;
358:
359: case arg_rp:
360: p = makelongparameter (allWords, inst_bit_size - (start_bits + a->size),
361: inst_bit_size - start_bits);
362: a->rp = p.val;
363: break;
364:
365: case arg_pr:
366: p = makelongparameter (allWords, inst_bit_size - (start_bits + a->size),
367: inst_bit_size - start_bits);
368: a->pr = p.val;
369: break;
370:
371: case arg_prp:
372: p = makelongparameter (allWords, inst_bit_size - (start_bits + a->size),
373: inst_bit_size - start_bits);
374: a->prp = p.val;
375: break;
376:
377: case arg_ic:
378: p = makelongparameter (allWords, inst_bit_size - (start_bits + a->size),
379: inst_bit_size - start_bits);
380: a->constant = p.val;
381: break;
382:
383: case arg_cc:
384: p = makelongparameter (allWords, inst_bit_size - (start_bits + a->size),
385: inst_bit_size - start_bits);
386:
387: a->cc = p.val;
388: break;
389:
390: case arg_idxr:
391: if ((IS_INSN_MNEMONIC ("cbitb"))
392: || (IS_INSN_MNEMONIC ("sbitb"))
393: || (IS_INSN_MNEMONIC ("tbitb")))
394: p = makelongparameter (allWords, 8, 9);
395: else
396: p = makelongparameter (allWords, 9, 10);
397: a->i_r = p.val;
398: p = makelongparameter (allWords, inst_bit_size - a->size, inst_bit_size);
399: a->constant = p.val;
400: break;
401:
402: case arg_idxrp:
403: p = makelongparameter (allWords, start_bits + 12, start_bits + 13);
404: a->i_r = p.val;
405: p = makelongparameter (allWords, start_bits + 13, start_bits + 16);
406: a->rp = p.val;
407: if (inst_bit_size > 32)
408: {
409: p = makelongparameter (allWords, inst_bit_size - start_bits - 12,
410: inst_bit_size);
411: a->constant = ((p.val & 0xffff) | (p.val >> 8 & 0xf0000));
412: }
413: else if (instruction->size == 2)
414: {
415: p = makelongparameter (allWords, inst_bit_size - 22, inst_bit_size);
416: a->constant = (p.val & 0xf) | (((p.val >>20) & 0x3) << 4)
417: | ((p.val >>14 & 0x3) << 6) | (((p.val >>7) & 0x1f) <<7);
418: }
419: else if (instruction->size == 1 && a->size == 0)
420: a->constant = 0;
421:
422: break;
423:
424: case arg_rbase:
425: p = makelongparameter (allWords, inst_bit_size, inst_bit_size);
426: a->constant = p.val;
427: p = makelongparameter (allWords, inst_bit_size - (start_bits + 4),
428: inst_bit_size - start_bits);
429: a->r = p.val;
430: break;
431:
432: case arg_cr:
433: p = makelongparameter (allWords, start_bits + 12, start_bits + 16);
434: a->r = p.val;
435: p = makelongparameter (allWords, inst_bit_size - 16, inst_bit_size);
436: a->constant = p.val;
437: break;
438:
439: case arg_crp:
440: if (instruction->size == 1)
441: p = makelongparameter (allWords, 12, 16);
442: else
443: p = makelongparameter (allWords, start_bits + 12, start_bits + 16);
444: a->rp = p.val;
445:
446: if (inst_bit_size > 32)
447: {
448: p = makelongparameter (allWords, inst_bit_size - start_bits - 12,
449: inst_bit_size);
450: a->constant = ((p.val & 0xffff) | (p.val >> 8 & 0xf0000));
451: }
452: else if (instruction->size == 2)
453: {
454: p = makelongparameter (allWords, inst_bit_size - 16, inst_bit_size);
455: a->constant = p.val;
456: }
457: else if (instruction->size == 1 && a->size != 0)
458: {
459: p = makelongparameter (allWords, 4, 8);
460: if (IS_INSN_MNEMONIC ("loadw")
461: || IS_INSN_MNEMONIC ("loadd")
462: || IS_INSN_MNEMONIC ("storw")
463: || IS_INSN_MNEMONIC ("stord"))
464: a->constant = (p.val * 2);
465: else
466: a->constant = p.val;
467: }
468: else
469: a->constant = 0;
470:
471: break;
472:
473: case arg_c:
474:
475: if ((IS_INSN_TYPE (BRANCH_INS))
476: || (IS_INSN_MNEMONIC ("bal"))
477: || (IS_INSN_TYPE (CSTBIT_INS))
478: || (IS_INSN_TYPE (LD_STOR_INS)))
479: {
480: switch (a->size)
481: {
482: case 8 :
483: p = makelongparameter (allWords, 0, start_bits);
484: a->constant = ((((p.val&0xf00)>>4)) | (p.val&0xf));
485: break;
486:
487: case 24:
488: if (instruction->size == 3)
489: {
490: p = makelongparameter (allWords, 16, inst_bit_size);
491: a->constant = ((((p.val>>16)&0xf) << 20)
492: | (((p.val>>24)&0xf) << 16)
493: | (p.val & 0xffff));
494: }
495: else if (instruction->size == 2)
496: {
497: p = makelongparameter (allWords, 8, inst_bit_size);
498: a->constant = p.val;
499: }
500: break;
501:
502: default:
503: p = makelongparameter (allWords, inst_bit_size - (start_bits +
504: a->size), inst_bit_size - start_bits);
505: a->constant = p.val;
506: break;
507: }
508: }
509: else
510: {
511: p = makelongparameter (allWords, inst_bit_size -
512: (start_bits + a->size),
513: inst_bit_size - start_bits);
514: a->constant = p.val;
515: }
516: break;
517:
518: default:
519: break;
520: }
521: }
522:
523:
524:
525: static void
526: print_arg (argument *a, bfd_vma memaddr, struct disassemble_info *info)
527: {
528: LONGLONG longdisp, mask;
529: int sign_flag = 0;
530: int relative = 0;
531: bfd_vma number;
532: PTR stream = info->stream;
533: fprintf_ftype func = info->fprintf_func;
534:
535: switch (a->type)
536: {
537: case arg_r:
538: func (stream, "%s", getregname (a->r));
539: break;
540:
541: case arg_rp:
542: func (stream, "%s", getregpname (a->rp));
543: break;
544:
545: case arg_pr:
546: func (stream, "%s", getprocregname (a->pr));
547: break;
548:
549: case arg_prp:
550: func (stream, "%s", getprocpregname (a->prp));
551: break;
552:
553: case arg_cc:
554: func (stream, "%s", getccstring (a->cc));
555: func (stream, "%s", "\t");
556: break;
557:
558: case arg_ic:
559: if (IS_INSN_MNEMONIC ("excp"))
560: {
561: func (stream, "%s", gettrapstring (a->constant));
562: break;
563: }
564: else if ((IS_INSN_TYPE (ARITH_INS) || IS_INSN_TYPE (ARITH_BYTE_INS))
565: && ((instruction->size == 1) && (a->constant == 9)))
566: func (stream, "$%d", -1);
567: else if (INST_HAS_REG_LIST)
568: func (stream, "$0x%lx", a->constant +1);
569: else if (IS_INSN_TYPE (SHIFT_INS))
570: {
571: longdisp = a->constant;
572: mask = ((LONGLONG)1 << a->size) - 1;
573: if (longdisp & ((LONGLONG)1 << (a->size -1)))
574: {
575: sign_flag = 1;
576: longdisp = ~(longdisp) + 1;
577: }
578: a->constant = (unsigned long int) (longdisp & mask);
579: func (stream, "$%d", ((int)(sign_flag ? -a->constant :
580: a->constant)));
581: }
582: else
583: