]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - opcodes/nds32-dis.c
NDS32/opcodes: Add audio ISA extension and modify the disassemble implemnt.
[thirdparty/binutils-gdb.git] / opcodes / nds32-dis.c
1 /* NDS32-specific support for 32-bit ELF.
2 Copyright (C) 2012-2014 Free Software Foundation, Inc.
3 Contributed by Andes Technology Corporation.
4
5 This file is part of BFD, the Binary File Descriptor library.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
20 02110-1301, USA. */
21
22 #include "sysdep.h"
23 #include <stdio.h>
24 #include "ansidecl.h"
25 #include "dis-asm.h"
26 #include "bfd.h"
27 #include "symcat.h"
28 #include "libiberty.h"
29 #include "opintl.h"
30 #include "bfd_stdint.h"
31 #include "hashtab.h"
32 #include "nds32-asm.h"
33 #include "opcode/nds32.h"
34
35 /* Get fields macro define. */
36 #define MASK_OP(insn, mask) ((insn) & (0x3f << 25 | (mask)))
37
38 /* Default text to print if an instruction isn't recognized. */
39 #define UNKNOWN_INSN_MSG _("*unknown*")
40 #define NDS32_PARSE_INSN16 0x01
41 #define NDS32_PARSE_INSN32 0x02
42 #define NDS32_PARSE_EX9IT 0x04
43 #define NDS32_PARSE_EX9TAB 0x08
44
45 extern struct nds32_opcode nds32_opcodes[];
46 extern const field_t operand_fields[];
47 extern const keyword_t *keywords[];
48 extern const keyword_t keyword_gpr[];
49 static void print_insn16 (bfd_vma pc, disassemble_info *info,
50 uint32_t insn, uint32_t parse_mode);
51 static void print_insn32 (bfd_vma pc, disassemble_info *info, uint32_t insn,
52 uint32_t parse_mode);
53 static uint32_t nds32_mask_opcode (uint32_t);
54 static void nds32_special_opcode (uint32_t, struct nds32_opcode **);
55
56 /* define in objdump.c. */
57 struct objdump_disasm_info
58 {
59 bfd * abfd;
60 asection * sec;
61 bfd_boolean require_sec;
62 arelent ** dynrelbuf;
63 long dynrelcount;
64 disassembler_ftype disassemble_fn;
65 arelent * reloc;
66 };
67
68 /* file_ptr ex9_filepos=NULL;. */
69 bfd_byte *ex9_data = NULL;
70 int ex9_ready = 0, ex9_base_offset = 0;
71
72 /* Hash function for disassemble. */
73
74 static htab_t opcode_htab;
75
76 static void
77 nds32_ex9_info (bfd_vma pc ATTRIBUTE_UNUSED,
78 disassemble_info *info, uint32_t ex9_index)
79 {
80 uint32_t insn;
81 static asymbol *itb = NULL;
82 bfd_byte buffer[4];
83 long unsigned int isec_vma;
84
85 /* Lookup itb symbol. */
86 if (!itb)
87 {
88 int i;
89
90 for (i = 0; i < info->symtab_size; i++)
91 if (bfd_asymbol_name (info->symtab[i])
92 && (strcmp (bfd_asymbol_name (info->symtab[i]), "$_ITB_BASE_") == 0
93 || strcmp (bfd_asymbol_name (info->symtab[i]),
94 "_ITB_BASE_") == 0))
95 {
96 itb = info->symtab[i];
97 break;
98 }
99
100 /* Lookup it only once, in case _ITB_BASE_ doesn't exist at all. */
101 if (itb == NULL)
102 itb = (void *) -1;
103 }
104
105 if (itb == (void *) -1)
106 return;
107
108 isec_vma = itb->section->vma;
109 isec_vma = itb->section->vma - bfd_asymbol_value (itb);
110 if (!itb->section || !itb->section->owner)
111 return;
112 bfd_get_section_contents (itb->section->owner, itb->section, buffer,
113 ex9_index * 4 - isec_vma, 4);
114 insn = bfd_getb32 (buffer);
115 /* 16-bit instructions in ex9 table. */
116 if (insn & 0x80000000)
117 print_insn16 (pc, info, (insn & 0x0000FFFF),
118 NDS32_PARSE_INSN16 | NDS32_PARSE_EX9IT);
119 /* 32-bit instructions in ex9 table. */
120 else
121 print_insn32 (pc, info, insn, NDS32_PARSE_INSN32 | NDS32_PARSE_EX9IT);
122 }
123
124 /* Find the value map register name. */
125
126 static keyword_t *
127 nds32_find_reg_keyword (keyword_t *reg, int value)
128 {
129 if (!reg)
130 return NULL;
131
132 while (reg->name != NULL && reg->value != value)
133 {
134 reg++;
135 }
136 if (reg->name == NULL)
137 return NULL;
138 return reg;
139 }
140
141 static void
142 nds32_parse_audio_ext (const field_t *pfd,
143 disassemble_info *info, uint32_t insn)
144 {
145 fprintf_ftype func = info->fprintf_func;
146 void *stream = info->stream;
147 keyword_t *psys_reg;
148 int int_value, new_value;
149
150 if (pfd->hw_res == HW_INT || pfd->hw_res == HW_UINT)
151 {
152 if (pfd->hw_res == HW_INT)
153 int_value =
154 N32_IMMS ((insn >> pfd->bitpos), pfd->bitsize) << pfd->shift;
155 else
156 int_value = __GF (insn, pfd->bitpos, pfd->bitsize) << pfd->shift;
157
158 if (int_value < 0)
159 func (stream, "#%d", int_value);
160 else
161 func (stream, "#0x%x", int_value);
162 return;
163 }
164 int_value =
165 __GF (insn, pfd->bitpos, pfd->bitsize) << pfd->shift;
166 new_value = int_value;
167 psys_reg = (keyword_t*) keywords[pfd->hw_res];
168
169 /* p = bit[4].bit[1:0], r = bit[4].bit[3:2]. */
170 if (strcmp (pfd->name, "im5_i") == 0)
171 {
172 new_value = int_value & 0x03;
173 new_value |= ((int_value & 0x10) >> 2);
174 }
175 else if (strcmp (pfd->name, "im5_m") == 0)
176 {
177 new_value = ((int_value & 0x1C) >> 2);
178 }
179 /* p = 0.bit[1:0], r = 0.bit[3:2]. */
180 /* q = 1.bit[1:0], s = 1.bit[5:4]. */
181 else if (strcmp (pfd->name, "im6_iq") == 0)
182 {
183 new_value |= 0x04;
184 }
185 else if (strcmp (pfd->name, "im6_ms") == 0)
186 {
187 new_value |= 0x04;
188 }
189 /* Rt CONCAT(c, t21, t0). */
190 else if (strcmp (pfd->name, "a_rt21") == 0)
191 {
192 new_value = (insn & 0x00000020) >> 5;
193 new_value |= (insn & 0x00000C00) >> 9;
194 new_value |= (insn & 0x00008000) >> 12;
195 }
196 else if (strcmp (pfd->name, "a_rte") == 0)
197 {
198 new_value = (insn & 0x00000C00) >> 9;
199 new_value |= (insn & 0x00008000) >> 12;
200 }
201 else if (strcmp (pfd->name, "a_rte1") == 0)
202 {
203 new_value = (insn & 0x00000C00) >> 9;
204 new_value |= (insn & 0x00008000) >> 12;
205 new_value |= 0x01;
206 }
207 else if (strcmp (pfd->name, "a_rte69") == 0)
208 {
209 new_value = int_value << 1;
210 }
211 else if (strcmp (pfd->name, "a_rte69_1") == 0)
212 {
213 new_value = int_value << 1;
214 new_value |= 0x01;
215 }
216
217 psys_reg = nds32_find_reg_keyword (psys_reg, new_value);
218 if (!psys_reg)
219 func (stream, "???");
220 else
221 func (stream, "$%s", psys_reg->name);
222 }
223
224 /* Dump instruction. If the opcode is unknown, return FALSE. */
225
226 static void
227 nds32_parse_opcode (struct nds32_opcode *opc, bfd_vma pc ATTRIBUTE_UNUSED,
228 disassemble_info *info, uint32_t insn,
229 uint32_t parse_mode)
230 {
231 int op = 0;
232 fprintf_ftype func = info->fprintf_func;
233 void *stream = info->stream;
234 const char *pstr_src;
235 char *pstr_tmp;
236 char tmp_string[16];
237 unsigned int push25gpr = 0, lsmwRb, lsmwRe, lsmwEnb4, checkbit, i;
238 int int_value, ifthe1st = 1;
239 const field_t *pfd;
240 keyword_t *psys_reg;
241
242 if (opc == NULL)
243 {
244 func (stream, UNKNOWN_INSN_MSG);
245 return;
246 }
247
248 if (parse_mode & NDS32_PARSE_EX9IT)
249 func (stream, " !");
250
251 pstr_src = opc->instruction;
252 if (*pstr_src == 0)
253 {
254 func (stream, "%s", opc->opcode);
255 return;
256 }
257 /* NDS32_PARSE_INSN16. */
258 if (parse_mode & NDS32_PARSE_INSN16)
259 {
260 func (stream, "%s ", opc->opcode);
261 }
262
263 /* NDS32_PARSE_INSN32. */
264 else
265 {
266 op = N32_OP6 (insn);
267 if (op == N32_OP6_LSMW)
268 func (stream, "%s.", opc->opcode);
269 else if (strstr (opc->instruction, "tito"))
270 func (stream, "%s", opc->opcode);
271 else
272 func (stream, "%s ", opc->opcode);
273 }
274
275 while (*pstr_src)
276 {
277 switch (*pstr_src)
278 {
279 case '%':
280 case '=':
281 case '&':
282 pstr_src++;
283 /* compare with operand_fields[].name. */
284 pstr_tmp = &tmp_string[0];
285 while (*pstr_src)
286 {
287 if ((*pstr_src == ',') || (*pstr_src == ' ')
288 || (*pstr_src == '{') || (*pstr_src == '}')
289 || (*pstr_src == '[') || (*pstr_src == ']')
290 || (*pstr_src == '(') || (*pstr_src == ')')
291 || (*pstr_src == '+') || (*pstr_src == '<'))
292 break;
293 *pstr_tmp++ = *pstr_src++;
294 }
295 *pstr_tmp = 0;
296
297 pfd = (const field_t *) &operand_fields[0];
298 while (1)
299 {
300 if (pfd->name == NULL)
301 return;
302 else if (strcmp (&tmp_string[0], pfd->name) == 0)
303 break;
304 pfd++;
305 }
306
307 /* for insn-16. */
308 if (parse_mode & NDS32_PARSE_INSN16)
309 {
310 if (pfd->hw_res == HW_GPR)
311 {
312 int_value =
313 __GF (insn, pfd->bitpos, pfd->bitsize) << pfd->shift;
314 /* push25/pop25. */
315 if ((opc->value == 0xfc00) || (opc->value == 0xfc80))
316 {
317 if (int_value == 0)
318 int_value = 6;
319 else
320 int_value = (6 + (0x01 << int_value));
321 push25gpr = int_value;
322 }
323 else if (strcmp (pfd->name, "rt4") == 0)
324 {
325 int_value = nds32_r45map[int_value];
326 }
327 func (stream, "$%s", keyword_gpr[int_value].name);
328 }
329 else if ((pfd->hw_res == HW_INT) || (pfd->hw_res == HW_UINT))
330 {
331 if (pfd->hw_res == HW_INT)
332 int_value =
333 N32_IMMS ((insn >> pfd->bitpos),
334 pfd->bitsize) << pfd->shift;
335 else
336 int_value =
337 __GF (insn, pfd->bitpos, pfd->bitsize) << pfd->shift;
338
339 /* movpi45. */
340 if (opc->value == 0xfa00)
341 {
342 int_value += 16;
343 func (stream, "#0x%x", int_value);
344 }
345 /* lwi45.fe. */
346 else if (opc->value == 0xb200)
347 {
348 int_value = 0 - (128 - int_value);
349 func (stream, "#%d", int_value);
350 }
351 /* beqz38/bnez38/beqs38/bnes38/j8/beqzs8/bnezs8/ifcall9. */
352 else if ((opc->value == 0xc000) || (opc->value == 0xc800)
353 || (opc->value == 0xd000) || (opc->value == 0xd800)
354 || (opc->value == 0xd500) || (opc->value == 0xe800)
355 || (opc->value == 0xe900)
356 || (opc->value == 0xf800))
357 {
358 info->print_address_func (int_value + pc, info);
359 }
360 /* push25/pop25. */
361 else if ((opc->value == 0xfc00) || (opc->value == 0xfc80))
362 {
363 func (stream, "#%d ! {$r6", int_value);
364 if (push25gpr != 6)
365 func (stream, "~$%s", keyword_gpr[push25gpr].name);
366 func (stream, ", $fp, $gp, $lp}");
367 }
368 /* ex9.it. */
369 else if ((opc->value == 0xdd40) || (opc->value == 0xea00))
370 {
371 func (stream, "#%d", int_value);
372 nds32_ex9_info (pc, info, int_value);
373 }
374 else if (pfd->hw_res == HW_INT)
375 {
376 if (int_value < 0)
377 func (stream, "#%d", int_value);
378 else
379 func (stream, "#0x%x", int_value);
380 }
381 else /* if(pfd->hw_res == HW_UINT). */
382 func (stream, "#0x%x", int_value);
383 }
384
385 }
386 /* for audio-ext. */
387 else if (op == N32_OP6_AEXT)
388 {
389 nds32_parse_audio_ext (pfd, info, insn);
390 }
391 /* for insn-32. */
392 else if (pfd->hw_res < _HW_LAST)
393 {
394 int_value =
395 __GF (insn, pfd->bitpos, pfd->bitsize) << pfd->shift;
396
397 psys_reg = (keyword_t*) keywords[pfd->hw_res];
398
399 psys_reg = nds32_find_reg_keyword (psys_reg, int_value);
400 /* For HW_SR, dump the index when it can't
401 map the register name. */
402 if (!psys_reg && pfd->hw_res == HW_SR)
403 func (stream, "%d", int_value);
404 else if (!psys_reg)
405 func (stream, "???");
406 else
407 {
408 if (pfd->hw_res == HW_GPR || pfd->hw_res == HW_CPR
409 || pfd->hw_res == HW_FDR || pfd->hw_res == HW_FSR
410 || pfd->hw_res == HW_DXR || pfd->hw_res == HW_SR
411 || pfd->hw_res == HW_USR)
412 func (stream, "$%s", psys_reg->name);
413 else if (pfd->hw_res == HW_DTITON
414 || pfd->hw_res == HW_DTITOFF)
415 func (stream, ".%s", psys_reg->name);
416 else
417 func (stream, "%s", psys_reg->name);
418 }
419 }
420 else if ((pfd->hw_res == HW_INT) || (pfd->hw_res == HW_UINT))
421 {
422 if (pfd->hw_res == HW_INT)
423 int_value =
424 N32_IMMS ((insn >> pfd->bitpos), pfd->bitsize) << pfd->shift;
425 else
426 int_value =
427 __GF (insn, pfd->bitpos, pfd->bitsize) << pfd->shift;
428
429 if ((op == N32_OP6_BR1) || (op == N32_OP6_BR2))
430 {
431 info->print_address_func (int_value + pc, info);
432 }
433 else if ((op == N32_OP6_BR3) && (pfd->bitpos == 0))
434 {
435 info->print_address_func (int_value + pc, info);
436 }
437 else if (op == N32_OP6_JI)
438 {
439 /* FIXME: Handle relocation. */
440 if (info->flags & INSN_HAS_RELOC)
441 pc = 0;
442 /* Check if insn32 in ex9 table. */
443 if (parse_mode & NDS32_PARSE_EX9IT)
444 info->print_address_func ((pc & 0xFE000000) | int_value,
445 info);
446 /* Check if decode ex9 table, PC(31,25)|Inst(23,0)<<1. */
447 else if (parse_mode & NDS32_PARSE_EX9TAB)
448 func (stream, "PC(31,25)|#0x%x", int_value);
449 else
450 info->print_address_func (int_value + pc, info);
451 }
452 else if (op == N32_OP6_LSMW)
453 {
454 /* lmw.adm/smw.adm. */
455 func (stream, "#0x%x ! {", int_value);
456 lsmwEnb4 = int_value;
457 lsmwRb = ((insn >> 20) & 0x1F);
458 lsmwRe = ((insn >> 10) & 0x1F);
459
460 /* If [Rb, Re] specifies at least one register,
461 Rb(4,0) <= Re(4,0) and 0 <= Rb(4,0), Re(4,0) < 28.
462 Disassembling does not consider this currently because of
463 the convience comparing with bsp320. */
464 if (lsmwRb != 31 || lsmwRe != 31)
465 {
466 func (stream, "$%s", keyword_gpr[lsmwRb].name);
467 if (lsmwRb != lsmwRe)
468 func (stream, "~$%s", keyword_gpr[lsmwRe].name);
469 ifthe1st = 0;
470 }
471 if (lsmwEnb4 != 0)
472 {
473 /* $fp, $gp, $lp, $sp. */
474 checkbit = 0x08;
475 for (i = 0; i < 4; i++)
476 {
477 if (lsmwEnb4 & checkbit)
478 {
479 if (ifthe1st == 1)
480 {
481 ifthe1st = 0;
482 func (stream, "$%s", keyword_gpr[28 + i].name);
483 }
484 else
485 func (stream, ", $%s", keyword_gpr[28 + i].name);
486 }
487 checkbit >>= 1;
488 }
489 }
490 func (stream, "}");
491 }
492 else if (pfd->hw_res == HW_INT)
493 {
494 if (int_value < 0)
495 func (stream, "#%d", int_value);
496 else
497 func (stream, "#0x%x", int_value);
498 }
499 else /* if(pfd->hw_res == HW_UINT). */
500 {
501 func (stream, "#0x%x", int_value);
502 }
503 }
504 break;
505
506 case '{':
507 case '}':
508 pstr_src++;
509 break;
510
511 default:
512 func (stream, "%c", *pstr_src++);
513 break;
514 } /* switch (*pstr_src). */
515
516 } /* while (*pstr_src). */
517 return;
518 }
519
520 /* Filter instructions with some bits must be fixed. */
521
522 static void
523 nds32_filter_unknown_insn (uint32_t insn, struct nds32_opcode **opc)
524 {
525 if (!(*opc))
526 return;
527
528 switch ((*opc)->value)
529 {
530 case JREG (JR):
531 case JREG (JRNEZ):
532 /* jr jr.xtoff */
533 if (__GF (insn, 6, 2) != 0 || __GF (insn, 15, 10) != 0)
534 *opc = NULL;
535 break;
536 case MISC (STANDBY):
537 if (__GF (insn, 7, 18) != 0)
538 *opc = NULL;
539 break;
540 case SIMD (PBSAD):
541 case SIMD (PBSADA):
542 if (__GF (insn, 5, 5) != 0)
543 *opc = NULL;
544 break;
545 case BR2 (IFCALL):
546 if (__GF (insn, 20, 5) != 0)
547 *opc = NULL;
548 break;
549 case JREG (JRAL):
550 if (__GF (insn, 5, 3) != 0 || __GF (insn, 15, 5) != 0)
551 *opc = NULL;
552 break;
553 case ALU1 (NOR):
554 case ALU1 (SLT):
555 case ALU1 (SLTS):
556 case ALU1 (SLLI):
557 case ALU1 (SRLI):
558 case ALU1 (SRAI):
559 case ALU1 (ROTRI):
560 case ALU1 (SLL):
561 case ALU1 (SRL):
562 case ALU1 (SRA):
563 case ALU1 (ROTR):
564 case ALU1 (SEB):
565 case ALU1 (SEH):
566 case ALU1 (ZEH):
567 case ALU1 (WSBH):
568 case ALU1 (SVA):
569 case ALU1 (SVS):
570 case ALU1 (CMOVZ):
571 case ALU1 (CMOVN):
572 if (__GF (insn, 5, 5) != 0)
573 *opc = NULL;
574 break;
575 case MISC (IRET):
576 case MISC (ISB):
577 case MISC (DSB):
578 if (__GF (insn, 5, 20) != 0)
579 *opc = NULL;
580 break;
581 }
582 }
583
584 static void
585 print_insn32 (bfd_vma pc, disassemble_info *info, uint32_t insn,
586 uint32_t parse_mode)
587 {
588 /* Get the final correct opcode and parse. */
589 struct nds32_opcode *opc;
590 uint32_t opcode = nds32_mask_opcode (insn);
591 opc = (struct nds32_opcode *) htab_find (opcode_htab, &opcode);
592
593 nds32_special_opcode (insn, &opc);
594 nds32_filter_unknown_insn (insn, &opc);
595 nds32_parse_opcode (opc, pc, info, insn, parse_mode);
596 }
597
598 static void
599 print_insn16 (bfd_vma pc, disassemble_info *info,
600 uint32_t insn, uint32_t parse_mode)
601 {
602 struct nds32_opcode *opc;
603 uint32_t opcode;
604
605 /* Get highest 7 bit in default. */
606 unsigned int mask = 0xfe00;
607
608 /* Classify 16-bit instruction to 4 sets by bit 13 and 14. */
609 switch (__GF (insn, 13, 2))
610 {
611 case 0x0:
612 /* mov55 movi55 */
613 if (__GF (insn, 11, 2) == 0)
614 {
615 mask = 0xfc00;
616 /* ifret16 = mov55 $sp, $sp*/
617 if (__GF (insn, 0, 11) == 0x3ff)
618 mask = 0xffff;
619 }
620 else if (__GF (insn, 9, 4) == 0xb)
621 mask = 0xfe07;
622 break;
623 case 0x1:
624 /* lwi37 swi37 */
625 if (__GF (insn, 11, 2) == 0x3)
626 mask = 0xf880;
627 break;
628 case 0x2:
629 mask = 0xf800;
630 /* Exclude beqz38, bnez38, beqs38, and bnes38. */
631 if (__GF (insn, 12, 1) == 0x1
632 && __GF (insn, 8, 3) == 0x5)
633 {
634 if (__GF (insn, 11, 1) == 0x0)
635 mask = 0xff00;
636 else
637 mask = 0xffe0;
638 }
639 break;
640 case 0x3:
641 switch (__GF (insn, 11, 2))
642 {
643 case 0x1:
644 /* beqzs8 bnezs8 */
645 if (__GF (insn, 9, 2) == 0x0)
646 mask = 0xff00;
647 /* addi10s */
648 else if (__GF(insn, 10, 1) == 0x1)
649 mask = 0xfc00;
650 break;
651 case 0x2:
652 /* lwi37.sp swi37.sp */
653 mask = 0xf880;
654 break;
655 case 0x3:
656 if (__GF (insn, 8, 3) == 0x5)
657 mask = 0xff00;
658 else if (__GF (insn, 8, 3) == 0x4)
659 mask = 0xff80;
660 else if (__GF (insn, 9 , 2) == 0x3)
661 mask = 0xfe07;
662 break;
663 }
664 break;
665 }
666 opcode = insn & mask;
667 opc = (struct nds32_opcode *) htab_find (opcode_htab, &opcode);
668
669 nds32_special_opcode (insn, &opc);
670 /* Get the final correct opcode and parse it. */
671 nds32_parse_opcode (opc, pc, info, insn, parse_mode);
672 }
673
674 static hashval_t
675 htab_hash_hash (const void *p)
676 {
677 return (*(unsigned int *) p) % 49;
678 }
679
680 static int
681 htab_hash_eq (const void *p, const void *q)
682 {
683 uint32_t pinsn = ((struct nds32_opcode *) p)->value;
684 uint32_t qinsn = *((uint32_t *) q);
685
686 return (pinsn == qinsn);
687 }
688
689 /* Get the format of instruction. */
690
691 static uint32_t
692 nds32_mask_opcode (uint32_t insn)
693 {
694 uint32_t opcode = N32_OP6 (insn);
695 switch (opcode)
696 {
697 case N32_OP6_LBI:
698 case N32_OP6_LHI:
699 case N32_OP6_LWI:
700 case N32_OP6_LDI:
701 case N32_OP6_LBI_BI:
702 case N32_OP6_LHI_BI:
703 case N32_OP6_LWI_BI:
704 case N32_OP6_LDI_BI:
705 case N32_OP6_SBI:
706 case N32_OP6_SHI:
707 case N32_OP6_SWI:
708 case N32_OP6_SDI:
709 case N32_OP6_SBI_BI:
710 case N32_OP6_SHI_BI:
711 case N32_OP6_SWI_BI:
712 case N32_OP6_SDI_BI:
713 case N32_OP6_LBSI:
714 case N32_OP6_LHSI:
715 case N32_OP6_LWSI:
716 case N32_OP6_LBSI_BI:
717 case N32_OP6_LHSI_BI:
718 case N32_OP6_LWSI_BI:
719 case N32_OP6_MOVI:
720 case N32_OP6_SETHI:
721 case N32_OP6_ADDI:
722 case N32_OP6_SUBRI:
723 case N32_OP6_ANDI:
724 case N32_OP6_XORI:
725 case N32_OP6_ORI:
726 case N32_OP6_SLTI:
727 case N32_OP6_SLTSI:
728 case N32_OP6_CEXT:
729 case N32_OP6_BITCI:
730 return MASK_OP (insn, 0);
731 case N32_OP6_ALU2:
732 /* FFBI */
733 if (__GF (insn, 0, 7) == (N32_ALU2_FFBI | __BIT (6)))
734 return MASK_OP (insn, 0x7f);
735 else if (__GF (insn, 0, 7) == (N32_ALU2_MFUSR | __BIT (6))
736 || __GF (insn, 0, 7) == (N32_ALU2_MTUSR | __BIT (6)))
737 /* RDOV CLROV */
738 return MASK_OP (insn, 0xf81ff);
739 return MASK_OP (insn, 0x1ff);
740 case N32_OP6_ALU1:
741 case N32_OP6_SIMD:
742 return MASK_OP (insn, 0x1f);
743 case N32_OP6_MEM:
744 return MASK_OP (insn, 0xff);
745 case N32_OP6_JREG:
746 return MASK_OP (insn, 0x7f);
747 case N32_OP6_LSMW:
748 return MASK_OP (insn, 0x23);
749 case N32_OP6_SBGP:
750 case N32_OP6_LBGP:
751 return MASK_OP (insn, 0x1 << 19);
752 case N32_OP6_HWGP:
753 if (__GF (insn, 18, 2) == 0x3)
754 return MASK_OP (insn, 0x7 << 17);
755 return MASK_OP (insn, 0x3 << 18);
756 case N32_OP6_DPREFI:
757 return MASK_OP (insn, 0x1 << 24);
758 case N32_OP6_LWC:
759 case N32_OP6_SWC:
760 case N32_OP6_LDC:
761 case N32_OP6_SDC:
762 return MASK_OP (insn, 0x1 << 12);
763 case N32_OP6_JI:
764 return MASK_OP (insn, 0x1 << 24);
765 case N32_OP6_BR1:
766 return MASK_OP (insn, 0x1 << 14);
767 case N32_OP6_BR2:
768 return MASK_OP (insn, 0xf << 16);
769 case N32_OP6_BR3:
770 return MASK_OP (insn, 0x1 << 19);
771 case N32_OP6_MISC:
772 switch (__GF (insn, 0, 5))
773 {
774 case N32_MISC_MTSR:
775 /* SETGIE and SETEND */
776 if (__GF (insn, 5, 5) == 0x1 || __GF (insn, 5, 5) == 0x2)
777 return MASK_OP (insn, 0x1fffff);
778 return MASK_OP (insn, 0x1f);
779 case N32_MISC_TLBOP:
780 if (__GF (insn, 5, 5) == 5 || __GF (insn, 5, 5) == 7)
781 /* PB FLUA */
782 return MASK_OP (insn, 0x3ff);
783 return MASK_OP (insn, 0x1f);
784 default:
785 return MASK_OP (insn, 0x1f);
786 }
787 case N32_OP6_COP:
788 if (__GF (insn, 4, 2) == 0)
789 {
790 /* FPU */
791 switch (__GF (insn, 0, 4))
792 {
793 case 0x0:
794 case 0x8:
795 /* FS1/F2OP FD1/F2OP */
796 if (__GF (insn, 6, 4) == 0xf)
797 return MASK_OP (insn, 0x7fff);
798 /* FS1 FD1 */
799 return MASK_OP (insn, 0x3ff);
800 case 0x4:
801 case 0xc:
802 /* FS2 */
803 return MASK_OP (insn, 0x3ff);
804 case 0x1:
805 case 0x9:
806 /* XR */
807 if (__GF (insn, 6, 4) == 0xc)
808 return MASK_OP (insn, 0x7fff);
809 /* MFCP MTCP */
810 return MASK_OP (insn, 0x3ff);
811 default:
812 return MASK_OP (insn, 0xff);
813 }
814 }
815 else if (__GF (insn, 0, 2) == 0)
816 return MASK_OP (insn, 0xf);
817 return MASK_OP (insn, 0xcf);
818 case N32_OP6_AEXT:
819 /* AUDIO */
820 switch (__GF (insn, 23, 2))
821 {
822 case 0x0:
823 if (__GF (insn, 5, 4) == 0)
824 /* AMxxx AMAyyS AMyyS AMAWzS AMWzS */
825 return MASK_OP (insn, (0x1f << 20) | 0x1ff);
826 else if (__GF (insn, 5, 4) == 1)
827 /* ALR ASR ALA ASA AUPI */
828 return MASK_OP (insn, (0x1f << 20) | (0xf << 5));
829 else if (__GF (insn, 20, 3) == 0 && __GF (insn, 6, 3) == 1)
830 /* ALR2 */
831 return MASK_OP (insn, (0x1f << 20) | (0x7 << 6));
832 else if (__GF (insn, 20 ,3) == 2 && __GF (insn, 6, 3) == 1)
833 /* AWEXT ASATS48 */
834 return MASK_OP (insn, (0x1f << 20) | (0xf << 5));
835 else if (__GF (insn, 20 ,3) == 3 && __GF (insn, 6, 3) == 1)
836 /* AMTAR AMTAR2 AMFAR AMFAR2 */
837 return MASK_OP (insn, (0x1f << 20) | (0x1f << 5));
838 else if (__GF (insn, 7, 2) == 3)
839 /* AMxxxSA */
840 return MASK_OP (insn, (0x1f << 20) | (0x3 << 7));
841 else if (__GF (insn, 6, 3) == 2)
842 /* AMxxxL.S */
843 return MASK_OP (insn, (0x1f << 20) | (0xf << 5));
844 else
845 /* AmxxxL.l AmxxxL2.S AMxxxL2.L */
846 return MASK_OP (insn, (0x1f << 20) | (0x7 << 6));
847 case 0x1:
848 if (__GF (insn, 20, 3) == 0)
849 /* AADDL ASUBL */
850 return MASK_OP (insn, (0x1f << 20) | (0x1 << 5));
851 else if (__GF (insn, 20, 3) == 1)
852 /* AMTARI Ix AMTARI Mx */
853 return MASK_OP (insn, (0x1f << 20));
854 else if (__GF (insn, 6, 3) == 2)
855 /* AMAWzSl.S AMWzSl.S */
856 return MASK_OP (insn, (0x1f << 20) | (0xf << 5));
857 else if (__GF (insn, 7, 2) == 3)
858 /* AMAWzSSA AMWzSSA */
859 return MASK_OP (insn, (0x1f << 20) | (0x3 << 7));
860 else
861 /* AMAWzSL.L AMAWzSL2.S AMAWzSL2.L AMWzSL.L AMWzSL.L AMWzSL2.S */
862 return MASK_OP (insn, (0x1f << 20) | (0x7 << 6));
863 case 0x2:
864 if (__GF (insn, 6, 3) == 2)
865 /* AMAyySl.S AMWyySl.S */
866 return MASK_OP (insn, (0x1f << 20) | (0xf << 5));
867 else if (__GF (insn, 7, 2) == 3)
868 /* AMAWyySSA AMWyySSA */
869 return MASK_OP (insn, (0x1f << 20) | (0x3 << 7));
870 else
871 /* AMAWyySL.L AMAWyySL2.S AMAWyySL2.L AMWyySL.L AMWyySL.L AMWyySL2.S */
872 return MASK_OP (insn, (0x1f << 20) | (0x7 << 6));
873 }
874 return MASK_OP (insn, 0x1f << 20);
875 default:
876 return (1 << 31);
877 }
878 }
879
880 /* Define cctl subtype. */
881 static char *cctl_subtype [] =
882 {
883 /* 0x0 */
884 "st0", "st0", "st0", "st2", "st2", "st3", "st3", "st4",
885 "st1", "st1", "st1", "st0", "st0", NULL, NULL, "st5",
886 /* 0x10 */
887 "st0", NULL, NULL, "st2", "st2", "st3", "st3", NULL,
888 "st1", NULL, NULL, "st0", "st0", NULL, NULL, NULL
889 };
890
891 /* Check the subset of opcode. */
892
893 static void
894 nds32_special_opcode (uint32_t insn, struct nds32_opcode **opc)
895 {
896 char *string = NULL;
897 uint32_t op;
898
899 if (!(*opc))
900 return;
901
902 /* Check if special case. */
903 switch ((*opc)->value)
904 {
905 case OP6 (LWC):
906 case OP6 (SWC):
907 case OP6 (LDC):
908 case OP6 (SDC):
909 case FPU_RA_IMMBI (LWC):
910 case FPU_RA_IMMBI (SWC):
911 case FPU_RA_IMMBI (LDC):
912 case FPU_RA_IMMBI (SDC):
913 /* Check if cp0 => FPU. */
914 if (__GF (insn, 13, 2) == 0)
915 {
916 while (!((*opc)->attr & ATTR (FPU)) && (*opc)->next)
917 *opc = (*opc)->next;
918 }
919 break;
920 case ALU1 (ADD):
921 case ALU1 (SUB):
922 case ALU1 (AND):
923 case ALU1 (XOR):
924 case ALU1 (OR):
925 /* Check if (add/add_slli) (sub/sub_slli) (and/and_slli). */
926 if (N32_SH5(insn) != 0)
927 string = "sh";
928 break;
929 case ALU1 (SRLI):
930 /* Check if nop. */
931 if (__GF (insn, 10, 15) == 0)
932 string = "nop";
933 break;
934 case MISC (CCTL):
935 string = cctl_subtype [__GF (insn, 5, 5)];
936 break;
937 case JREG (JR):
938 case JREG (JRAL):
939 case JREG (JR) | JREG_RET:
940 if (__GF (insn, 8, 2) != 0)
941 string = "tit";
942 break;
943 case N32_OP6_COP:
944 break;
945 case 0xea00:
946 /* break16 ex9 */
947 if (__GF (insn, 5, 4) != 0)
948 string = "ex9";
949 break;
950 case 0x9200:
951 /* nop16 */
952 if (__GF (insn, 0, 9) == 0)
953 string = "nop16";
954 break;
955 }
956
957 if (string)
958 {
959 while (strstr ((*opc)->opcode, string) == NULL
960 && strstr ((*opc)->instruction, string) == NULL && (*opc)->next)
961 *opc = (*opc)->next;
962 return;
963 }
964
965 /* Classify instruction is COP or FPU. */
966 op = N32_OP6 (insn);
967 if (op == N32_OP6_COP && __GF (insn, 4, 2) != 0)
968 {
969 while (((*opc)->attr & ATTR (FPU)) != 0 && (*opc)->next)
970 *opc = (*opc)->next;
971 }
972 }
973
974 int
975 print_insn_nds32 (bfd_vma pc, disassemble_info *info)
976 {
977 int status;
978 bfd_byte buf[4];
979 uint32_t insn;
980 static int init = 1;
981 int i = 0;
982 struct nds32_opcode *opc;
983 struct nds32_opcode **slot;
984
985 if (init)
986 {
987 /* Build opcode table. */
988 opcode_htab = htab_create_alloc (1024, htab_hash_hash, htab_hash_eq,
989 NULL, xcalloc, free);
990
991 while (nds32_opcodes[i].opcode != NULL)
992 {
993 opc = &nds32_opcodes[i];
994 slot =
995 (struct nds32_opcode **) htab_find_slot (opcode_htab, &opc->value,
996 INSERT);
997 if (*slot == NULL)
998 {
999 /* This is the new one. */
1000 *slot = opc;
1001 }
1002 else
1003 {
1004 /* Already exists. Append to the list. */
1005 opc = *slot;
1006 while (opc->next)
1007 opc = opc->next;
1008 opc->next = &nds32_opcodes[i];
1009 }
1010 i++;
1011 }
1012 init = 0;
1013 }
1014
1015 status = info->read_memory_func (pc, (bfd_byte *) buf, 4, info);
1016 if (status)
1017 {
1018 /* for the last 16-bit instruction. */
1019 status = info->read_memory_func (pc, (bfd_byte *) buf, 2, info);
1020 if (status)
1021 {
1022 (*info->memory_error_func)(status, pc, info);
1023 return -1;
1024 }
1025 }
1026
1027 insn = bfd_getb32 (buf);
1028 /* 16-bit instruction. */
1029 if (insn & 0x80000000)
1030 {
1031 if (info->section && strstr (info->section->name, ".ex9.itable") != NULL)
1032 {
1033 print_insn16 (pc, info, (insn & 0x0000FFFF),
1034 NDS32_PARSE_INSN16 | NDS32_PARSE_EX9TAB);
1035 return 4;
1036 }
1037 print_insn16 (pc, info, (insn >> 16), NDS32_PARSE_INSN16);
1038 return 2;
1039 }
1040
1041 /* 32-bit instructions. */
1042 else
1043 {
1044 if (info->section
1045 && strstr (info->section->name, ".ex9.itable") != NULL)
1046 print_insn32 (pc, info, insn, NDS32_PARSE_INSN32 | NDS32_PARSE_EX9TAB);
1047 else
1048 print_insn32 (pc, info, insn, NDS32_PARSE_INSN32);
1049 return 4;
1050 }
1051 }