Use disassemble.c:disassembler select rs6000 disassembler
[deliverable/binutils-gdb.git] / opcodes / nds32-dis.c
CommitLineData
35c08157 1/* NDS32-specific support for 32-bit ELF.
2571583a 2 Copyright (C) 2012-2017 Free Software Foundation, Inc.
35c08157
KLC
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
40c7a7cb 20 02110-1301, USA. */
35c08157
KLC
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"
40c7a7cb
KLC
31#include "hashtab.h"
32#include "nds32-asm.h"
33#include "opcode/nds32.h"
35c08157 34
40c7a7cb
KLC
35/* Get fields macro define. */
36#define MASK_OP(insn, mask) ((insn) & (0x3f << 25 | (mask)))
35c08157
KLC
37
38/* Default text to print if an instruction isn't recognized. */
39#define UNKNOWN_INSN_MSG _("*unknown*")
40c7a7cb
KLC
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
45extern struct nds32_opcode nds32_opcodes[];
46extern const field_t operand_fields[];
47extern const keyword_t *keywords[];
48extern const keyword_t keyword_gpr[];
49static void print_insn16 (bfd_vma pc, disassemble_info *info,
50 uint32_t insn, uint32_t parse_mode);
51static void print_insn32 (bfd_vma pc, disassemble_info *info, uint32_t insn,
52 uint32_t parse_mode);
53static uint32_t nds32_mask_opcode (uint32_t);
54static void nds32_special_opcode (uint32_t, struct nds32_opcode **);
55
56/* define in objdump.c. */
57struct objdump_disasm_info
35c08157 58{
40c7a7cb
KLC
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;
35c08157
KLC
66};
67
40c7a7cb
KLC
68/* file_ptr ex9_filepos=NULL;. */
69bfd_byte *ex9_data = NULL;
70int ex9_ready = 0, ex9_base_offset = 0;
35c08157 71
40c7a7cb 72/* Hash function for disassemble. */
35c08157 73
40c7a7cb 74static htab_t opcode_htab;
35c08157 75
40c7a7cb
KLC
76static void
77nds32_ex9_info (bfd_vma pc ATTRIBUTE_UNUSED,
78 disassemble_info *info, uint32_t ex9_index)
35c08157 79{
40c7a7cb
KLC
80 uint32_t insn;
81 static asymbol *itb = NULL;
82 bfd_byte buffer[4];
83 long unsigned int isec_vma;
35c08157 84
40c7a7cb
KLC
85 /* Lookup itb symbol. */
86 if (!itb)
87 {
88 int i;
35c08157 89
40c7a7cb
KLC
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 }
35c08157 99
40c7a7cb
KLC
100 /* Lookup it only once, in case _ITB_BASE_ doesn't exist at all. */
101 if (itb == NULL)
102 itb = (void *) -1;
103 }
6b9d3259 104
40c7a7cb
KLC
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}
35c08157 123
40c7a7cb 124/* Find the value map register name. */
6b9d3259 125
40c7a7cb
KLC
126static keyword_t *
127nds32_find_reg_keyword (keyword_t *reg, int value)
35c08157 128{
40c7a7cb
KLC
129 if (!reg)
130 return NULL;
6b9d3259 131
40c7a7cb
KLC
132 while (reg->name != NULL && reg->value != value)
133 {
134 reg++;
135 }
136 if (reg->name == NULL)
137 return NULL;
138 return reg;
139}
35c08157
KLC
140
141static void
40c7a7cb
KLC
142nds32_parse_audio_ext (const field_t *pfd,
143 disassemble_info *info, uint32_t insn)
35c08157 144{
35c08157
KLC
145 fprintf_ftype func = info->fprintf_func;
146 void *stream = info->stream;
40c7a7cb
KLC
147 keyword_t *psys_reg;
148 int int_value, new_value;
35c08157 149
40c7a7cb 150 if (pfd->hw_res == HW_INT || pfd->hw_res == HW_UINT)
35c08157 151 {
40c7a7cb
KLC
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;
35c08157 157
3ee6e4fb 158 if (int_value < 10)
40c7a7cb
KLC
159 func (stream, "#%d", int_value);
160 else
161 func (stream, "#0x%x", int_value);
35c08157
KLC
162 return;
163 }
40c7a7cb
KLC
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];
35c08157 168
40c7a7cb
KLC
169 /* p = bit[4].bit[1:0], r = bit[4].bit[3:2]. */
170 if (strcmp (pfd->name, "im5_i") == 0)
35c08157 171 {
40c7a7cb
KLC
172 new_value = int_value & 0x03;
173 new_value |= ((int_value & 0x10) >> 2);
35c08157 174 }
40c7a7cb 175 else if (strcmp (pfd->name, "im5_m") == 0)
35c08157 176 {
40c7a7cb 177 new_value = ((int_value & 0x1C) >> 2);
35c08157 178 }
40c7a7cb
KLC
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)
35c08157 182 {
40c7a7cb 183 new_value |= 0x04;
35c08157 184 }
40c7a7cb 185 else if (strcmp (pfd->name, "im6_ms") == 0)
35c08157 186 {
40c7a7cb
KLC
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;
35c08157 206 }
40c7a7cb
KLC
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);
35c08157
KLC
222}
223
40c7a7cb 224/* Dump instruction. If the opcode is unknown, return FALSE. */
35c08157
KLC
225
226static void
40c7a7cb
KLC
227nds32_parse_opcode (struct nds32_opcode *opc, bfd_vma pc ATTRIBUTE_UNUSED,
228 disassemble_info *info, uint32_t insn,
229 uint32_t parse_mode)
35c08157 230{
40c7a7cb 231 int op = 0;
35c08157
KLC
232 fprintf_ftype func = info->fprintf_func;
233 void *stream = info->stream;
40c7a7cb
KLC
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)
35c08157 243 {
35c08157
KLC
244 func (stream, UNKNOWN_INSN_MSG);
245 return;
246 }
35c08157 247
40c7a7cb
KLC
248 if (parse_mode & NDS32_PARSE_EX9IT)
249 func (stream, " !");
35c08157 250
40c7a7cb
KLC
251 pstr_src = opc->instruction;
252 if (*pstr_src == 0)
35c08157 253 {
40c7a7cb 254 func (stream, "%s", opc->opcode);
35c08157
KLC
255 return;
256 }
40c7a7cb
KLC
257 /* NDS32_PARSE_INSN16. */
258 if (parse_mode & NDS32_PARSE_INSN16)
259 {
260 func (stream, "%s ", opc->opcode);
261 }
35c08157 262
40c7a7cb
KLC
263 /* NDS32_PARSE_INSN32. */
264 else
35c08157 265 {
40c7a7cb
KLC
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
3ee6e4fb 272 func (stream, "%s\t", opc->opcode);
35c08157
KLC
273 }
274
40c7a7cb 275 while (*pstr_src)
35c08157 276 {
40c7a7cb
KLC
277 switch (*pstr_src)
278 {
279 case '%':
280 case '=':
281 case '&':
282 pstr_src++;
3ee6e4fb 283 /* Compare with operand_fields[].name. */
40c7a7cb
KLC
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;
35c08157 296
40c7a7cb
KLC
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 }
35c08157 306
3ee6e4fb 307 /* For insn-16. */
40c7a7cb
KLC
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 {
3ee6e4fb 376 if (int_value < 10)
40c7a7cb
KLC
377 func (stream, "#%d", int_value);
378 else
379 func (stream, "#0x%x", int_value);
380 }
3ee6e4fb
NC
381 else /* if (pfd->hw_res == HW_UINT). */
382 {
383 if (int_value < 10)
384 func (stream, "#%u", int_value);
385 else
386 func (stream, "#0x%x", int_value);
387 }
40c7a7cb 388 }
35c08157 389
40c7a7cb
KLC
390 }
391 /* for audio-ext. */
392 else if (op == N32_OP6_AEXT)
393 {
394 nds32_parse_audio_ext (pfd, info, insn);
395 }
396 /* for insn-32. */
397 else if (pfd->hw_res < _HW_LAST)
398 {
399 int_value =
400 __GF (insn, pfd->bitpos, pfd->bitsize) << pfd->shift;
401
402 psys_reg = (keyword_t*) keywords[pfd->hw_res];
403
404 psys_reg = nds32_find_reg_keyword (psys_reg, int_value);
405 /* For HW_SR, dump the index when it can't
406 map the register name. */
407 if (!psys_reg && pfd->hw_res == HW_SR)
408 func (stream, "%d", int_value);
409 else if (!psys_reg)
410 func (stream, "???");
411 else
412 {
413 if (pfd->hw_res == HW_GPR || pfd->hw_res == HW_CPR
414 || pfd->hw_res == HW_FDR || pfd->hw_res == HW_FSR
415 || pfd->hw_res == HW_DXR || pfd->hw_res == HW_SR
416 || pfd->hw_res == HW_USR)
417 func (stream, "$%s", psys_reg->name);
418 else if (pfd->hw_res == HW_DTITON
419 || pfd->hw_res == HW_DTITOFF)
420 func (stream, ".%s", psys_reg->name);
421 else
422 func (stream, "%s", psys_reg->name);
423 }
424 }
425 else if ((pfd->hw_res == HW_INT) || (pfd->hw_res == HW_UINT))
426 {
427 if (pfd->hw_res == HW_INT)
428 int_value =
429 N32_IMMS ((insn >> pfd->bitpos), pfd->bitsize) << pfd->shift;
430 else
431 int_value =
432 __GF (insn, pfd->bitpos, pfd->bitsize) << pfd->shift;
433
434 if ((op == N32_OP6_BR1) || (op == N32_OP6_BR2))
435 {
436 info->print_address_func (int_value + pc, info);
437 }
438 else if ((op == N32_OP6_BR3) && (pfd->bitpos == 0))
439 {
440 info->print_address_func (int_value + pc, info);
441 }
442 else if (op == N32_OP6_JI)
443 {
444 /* FIXME: Handle relocation. */
445 if (info->flags & INSN_HAS_RELOC)
446 pc = 0;
447 /* Check if insn32 in ex9 table. */
448 if (parse_mode & NDS32_PARSE_EX9IT)
449 info->print_address_func ((pc & 0xFE000000) | int_value,
450 info);
451 /* Check if decode ex9 table, PC(31,25)|Inst(23,0)<<1. */
452 else if (parse_mode & NDS32_PARSE_EX9TAB)
453 func (stream, "PC(31,25)|#0x%x", int_value);
454 else
455 info->print_address_func (int_value + pc, info);
456 }
457 else if (op == N32_OP6_LSMW)
458 {
459 /* lmw.adm/smw.adm. */
460 func (stream, "#0x%x ! {", int_value);
461 lsmwEnb4 = int_value;
462 lsmwRb = ((insn >> 20) & 0x1F);
463 lsmwRe = ((insn >> 10) & 0x1F);
464
465 /* If [Rb, Re] specifies at least one register,
466 Rb(4,0) <= Re(4,0) and 0 <= Rb(4,0), Re(4,0) < 28.
467 Disassembling does not consider this currently because of
468 the convience comparing with bsp320. */
469 if (lsmwRb != 31 || lsmwRe != 31)
470 {
471 func (stream, "$%s", keyword_gpr[lsmwRb].name);
472 if (lsmwRb != lsmwRe)
473 func (stream, "~$%s", keyword_gpr[lsmwRe].name);
474 ifthe1st = 0;
475 }
476 if (lsmwEnb4 != 0)
477 {
478 /* $fp, $gp, $lp, $sp. */
479 checkbit = 0x08;
480 for (i = 0; i < 4; i++)
481 {
482 if (lsmwEnb4 & checkbit)
483 {
484 if (ifthe1st == 1)
485 {
486 ifthe1st = 0;
487 func (stream, "$%s", keyword_gpr[28 + i].name);
488 }
489 else
490 func (stream, ", $%s", keyword_gpr[28 + i].name);
491 }
492 checkbit >>= 1;
493 }
494 }
495 func (stream, "}");
496 }
497 else if (pfd->hw_res == HW_INT)
498 {
3ee6e4fb 499 if (int_value < 10)
40c7a7cb
KLC
500 func (stream, "#%d", int_value);
501 else
502 func (stream, "#0x%x", int_value);
503 }
3ee6e4fb 504 else /* if (pfd->hw_res == HW_UINT). */
40c7a7cb 505 {
3ee6e4fb
NC
506 if (int_value < 10)
507 func (stream, "#%u", int_value);
508 else
509 func (stream, "#0x%x", int_value);
40c7a7cb
KLC
510 }
511 }
512 break;
35c08157 513
40c7a7cb
KLC
514 case '{':
515 case '}':
516 pstr_src++;
517 break;
518
3ee6e4fb
NC
519 case ',':
520 func (stream, ", ");
521 pstr_src++;
522 break;
523
524 case '+':
525 func (stream, " + ");
526 pstr_src++;
527 break;
528
529 case '<':
530 if (pstr_src[1] == '<')
531 {
532 func (stream, " << ");
533 pstr_src += 2;
534 }
535 else
536 {
537 func (stream, " <");
538 pstr_src++;
539 }
540 break;
541
40c7a7cb
KLC
542 default:
543 func (stream, "%c", *pstr_src++);
544 break;
3ee6e4fb
NC
545 }
546 }
35c08157
KLC
547}
548
40c7a7cb
KLC
549/* Filter instructions with some bits must be fixed. */
550
35c08157 551static void
40c7a7cb 552nds32_filter_unknown_insn (uint32_t insn, struct nds32_opcode **opc)
35c08157 553{
40c7a7cb
KLC
554 if (!(*opc))
555 return;
35c08157 556
40c7a7cb 557 switch ((*opc)->value)
35c08157 558 {
40c7a7cb
KLC
559 case JREG (JR):
560 case JREG (JRNEZ):
561 /* jr jr.xtoff */
562 if (__GF (insn, 6, 2) != 0 || __GF (insn, 15, 10) != 0)
563 *opc = NULL;
35c08157 564 break;
40c7a7cb
KLC
565 case MISC (STANDBY):
566 if (__GF (insn, 7, 18) != 0)
567 *opc = NULL;
568 break;
569 case SIMD (PBSAD):
570 case SIMD (PBSADA):
571 if (__GF (insn, 5, 5) != 0)
572 *opc = NULL;
573 break;
574 case BR2 (IFCALL):
575 if (__GF (insn, 20, 5) != 0)
576 *opc = NULL;
577 break;
578 case JREG (JRAL):
579 if (__GF (insn, 5, 3) != 0 || __GF (insn, 15, 5) != 0)
580 *opc = NULL;
581 break;
582 case ALU1 (NOR):
583 case ALU1 (SLT):
584 case ALU1 (SLTS):
585 case ALU1 (SLLI):
586 case ALU1 (SRLI):
587 case ALU1 (SRAI):
588 case ALU1 (ROTRI):
589 case ALU1 (SLL):
590 case ALU1 (SRL):
591 case ALU1 (SRA):
592 case ALU1 (ROTR):
593 case ALU1 (SEB):
594 case ALU1 (SEH):
595 case ALU1 (ZEH):
596 case ALU1 (WSBH):
597 case ALU1 (SVA):
598 case ALU1 (SVS):
599 case ALU1 (CMOVZ):
600 case ALU1 (CMOVN):
601 if (__GF (insn, 5, 5) != 0)
602 *opc = NULL;
603 break;
604 case MISC (IRET):
605 case MISC (ISB):
606 case MISC (DSB):
607 if (__GF (insn, 5, 20) != 0)
608 *opc = NULL;
35c08157
KLC
609 break;
610 }
611}
612
613static void
40c7a7cb
KLC
614print_insn32 (bfd_vma pc, disassemble_info *info, uint32_t insn,
615 uint32_t parse_mode)
35c08157 616{
40c7a7cb
KLC
617 /* Get the final correct opcode and parse. */
618 struct nds32_opcode *opc;
619 uint32_t opcode = nds32_mask_opcode (insn);
620 opc = (struct nds32_opcode *) htab_find (opcode_htab, &opcode);
621
622 nds32_special_opcode (insn, &opc);
623 nds32_filter_unknown_insn (insn, &opc);
624 nds32_parse_opcode (opc, pc, info, insn, parse_mode);
35c08157
KLC
625}
626
627static void
40c7a7cb
KLC
628print_insn16 (bfd_vma pc, disassemble_info *info,
629 uint32_t insn, uint32_t parse_mode)
35c08157 630{
40c7a7cb
KLC
631 struct nds32_opcode *opc;
632 uint32_t opcode;
633
634 /* Get highest 7 bit in default. */
635 unsigned int mask = 0xfe00;
35c08157 636
40c7a7cb
KLC
637 /* Classify 16-bit instruction to 4 sets by bit 13 and 14. */
638 switch (__GF (insn, 13, 2))
35c08157 639 {
40c7a7cb
KLC
640 case 0x0:
641 /* mov55 movi55 */
642 if (__GF (insn, 11, 2) == 0)
35c08157 643 {
40c7a7cb
KLC
644 mask = 0xfc00;
645 /* ifret16 = mov55 $sp, $sp*/
646 if (__GF (insn, 0, 11) == 0x3ff)
647 mask = 0xffff;
35c08157 648 }
40c7a7cb
KLC
649 else if (__GF (insn, 9, 4) == 0xb)
650 mask = 0xfe07;
651 break;
652 case 0x1:
653 /* lwi37 swi37 */
654 if (__GF (insn, 11, 2) == 0x3)
655 mask = 0xf880;
656 break;
657 case 0x2:
658 mask = 0xf800;
659 /* Exclude beqz38, bnez38, beqs38, and bnes38. */
660 if (__GF (insn, 12, 1) == 0x1
661 && __GF (insn, 8, 3) == 0x5)
35c08157 662 {
40c7a7cb
KLC
663 if (__GF (insn, 11, 1) == 0x0)
664 mask = 0xff00;
665 else
666 mask = 0xffe0;
35c08157 667 }
40c7a7cb
KLC
668 break;
669 case 0x3:
670 switch (__GF (insn, 11, 2))
35c08157 671 {
35c08157 672 case 0x1:
40c7a7cb
KLC
673 /* beqzs8 bnezs8 */
674 if (__GF (insn, 9, 2) == 0x0)
675 mask = 0xff00;
676 /* addi10s */
677 else if (__GF(insn, 10, 1) == 0x1)
678 mask = 0xfc00;
679 break;
35c08157 680 case 0x2:
40c7a7cb
KLC
681 /* lwi37.sp swi37.sp */
682 mask = 0xf880;
683 break;
35c08157 684 case 0x3:
40c7a7cb
KLC
685 if (__GF (insn, 8, 3) == 0x5)
686 mask = 0xff00;
687 else if (__GF (insn, 8, 3) == 0x4)
688 mask = 0xff80;
689 else if (__GF (insn, 9 , 2) == 0x3)
690 mask = 0xfe07;
691 break;
692 }
693 break;
694 }
695 opcode = insn & mask;
696 opc = (struct nds32_opcode *) htab_find (opcode_htab, &opcode);
697
698 nds32_special_opcode (insn, &opc);
699 /* Get the final correct opcode and parse it. */
700 nds32_parse_opcode (opc, pc, info, insn, parse_mode);
701}
702
703static hashval_t
704htab_hash_hash (const void *p)
705{
706 return (*(unsigned int *) p) % 49;
707}
708
709static int
710htab_hash_eq (const void *p, const void *q)
711{
712 uint32_t pinsn = ((struct nds32_opcode *) p)->value;
713 uint32_t qinsn = *((uint32_t *) q);
714
715 return (pinsn == qinsn);
716}
717
718/* Get the format of instruction. */
35c08157 719
40c7a7cb
KLC
720static uint32_t
721nds32_mask_opcode (uint32_t insn)
722{
723 uint32_t opcode = N32_OP6 (insn);
724 switch (opcode)
725 {
726 case N32_OP6_LBI:
727 case N32_OP6_LHI:
728 case N32_OP6_LWI:
729 case N32_OP6_LDI:
730 case N32_OP6_LBI_BI:
731 case N32_OP6_LHI_BI:
732 case N32_OP6_LWI_BI:
733 case N32_OP6_LDI_BI:
734 case N32_OP6_SBI:
735 case N32_OP6_SHI:
736 case N32_OP6_SWI:
737 case N32_OP6_SDI:
738 case N32_OP6_SBI_BI:
739 case N32_OP6_SHI_BI:
740 case N32_OP6_SWI_BI:
741 case N32_OP6_SDI_BI:
742 case N32_OP6_LBSI:
743 case N32_OP6_LHSI:
744 case N32_OP6_LWSI:
745 case N32_OP6_LBSI_BI:
746 case N32_OP6_LHSI_BI:
747 case N32_OP6_LWSI_BI:
748 case N32_OP6_MOVI:
749 case N32_OP6_SETHI:
750 case N32_OP6_ADDI:
751 case N32_OP6_SUBRI:
752 case N32_OP6_ANDI:
753 case N32_OP6_XORI:
754 case N32_OP6_ORI:
755 case N32_OP6_SLTI:
756 case N32_OP6_SLTSI:
757 case N32_OP6_CEXT:
758 case N32_OP6_BITCI:
759 return MASK_OP (insn, 0);
760 case N32_OP6_ALU2:
761 /* FFBI */
762 if (__GF (insn, 0, 7) == (N32_ALU2_FFBI | __BIT (6)))
763 return MASK_OP (insn, 0x7f);
764 else if (__GF (insn, 0, 7) == (N32_ALU2_MFUSR | __BIT (6))
765 || __GF (insn, 0, 7) == (N32_ALU2_MTUSR | __BIT (6)))
766 /* RDOV CLROV */
767 return MASK_OP (insn, 0xf81ff);
768 return MASK_OP (insn, 0x1ff);
769 case N32_OP6_ALU1:
770 case N32_OP6_SIMD:
771 return MASK_OP (insn, 0x1f);
772 case N32_OP6_MEM:
773 return MASK_OP (insn, 0xff);
774 case N32_OP6_JREG:
775 return MASK_OP (insn, 0x7f);
776 case N32_OP6_LSMW:
777 return MASK_OP (insn, 0x23);
778 case N32_OP6_SBGP:
779 case N32_OP6_LBGP:
780 return MASK_OP (insn, 0x1 << 19);
781 case N32_OP6_HWGP:
782 if (__GF (insn, 18, 2) == 0x3)
783 return MASK_OP (insn, 0x7 << 17);
784 return MASK_OP (insn, 0x3 << 18);
785 case N32_OP6_DPREFI:
786 return MASK_OP (insn, 0x1 << 24);
787 case N32_OP6_LWC:
788 case N32_OP6_SWC:
789 case N32_OP6_LDC:
790 case N32_OP6_SDC:
791 return MASK_OP (insn, 0x1 << 12);
792 case N32_OP6_JI:
793 return MASK_OP (insn, 0x1 << 24);
794 case N32_OP6_BR1:
795 return MASK_OP (insn, 0x1 << 14);
796 case N32_OP6_BR2:
797 return MASK_OP (insn, 0xf << 16);
798 case N32_OP6_BR3:
799 return MASK_OP (insn, 0x1 << 19);
800 case N32_OP6_MISC:
801 switch (__GF (insn, 0, 5))
802 {
803 case N32_MISC_MTSR:
804 /* SETGIE and SETEND */
805 if (__GF (insn, 5, 5) == 0x1 || __GF (insn, 5, 5) == 0x2)
806 return MASK_OP (insn, 0x1fffff);
807 return MASK_OP (insn, 0x1f);
808 case N32_MISC_TLBOP:
809 if (__GF (insn, 5, 5) == 5 || __GF (insn, 5, 5) == 7)
810 /* PB FLUA */
811 return MASK_OP (insn, 0x3ff);
812 return MASK_OP (insn, 0x1f);
813 default:
814 return MASK_OP (insn, 0x1f);
815 }
816 case N32_OP6_COP:
817 if (__GF (insn, 4, 2) == 0)
818 {
819 /* FPU */
820 switch (__GF (insn, 0, 4))
35c08157
KLC
821 {
822 case 0x0:
35c08157 823 case 0x8:
40c7a7cb
KLC
824 /* FS1/F2OP FD1/F2OP */
825 if (__GF (insn, 6, 4) == 0xf)
826 return MASK_OP (insn, 0x7fff);
827 /* FS1 FD1 */
828 return MASK_OP (insn, 0x3ff);
829 case 0x4:
35c08157 830 case 0xc:
40c7a7cb
KLC
831 /* FS2 */
832 return MASK_OP (insn, 0x3ff);
833 case 0x1:
834 case 0x9:
835 /* XR */
836 if (__GF (insn, 6, 4) == 0xc)
837 return MASK_OP (insn, 0x7fff);
838 /* MFCP MTCP */
839 return MASK_OP (insn, 0x3ff);
840 default:
841 return MASK_OP (insn, 0xff);
35c08157
KLC
842 }
843 }
40c7a7cb
KLC
844 else if (__GF (insn, 0, 2) == 0)
845 return MASK_OP (insn, 0xf);
846 return MASK_OP (insn, 0xcf);
847 case N32_OP6_AEXT:
848 /* AUDIO */
849 switch (__GF (insn, 23, 2))
35c08157
KLC
850 {
851 case 0x0:
40c7a7cb
KLC
852 if (__GF (insn, 5, 4) == 0)
853 /* AMxxx AMAyyS AMyyS AMAWzS AMWzS */
854 return MASK_OP (insn, (0x1f << 20) | 0x1ff);
855 else if (__GF (insn, 5, 4) == 1)
856 /* ALR ASR ALA ASA AUPI */
857 return MASK_OP (insn, (0x1f << 20) | (0xf << 5));
858 else if (__GF (insn, 20, 3) == 0 && __GF (insn, 6, 3) == 1)
859 /* ALR2 */
860 return MASK_OP (insn, (0x1f << 20) | (0x7 << 6));
861 else if (__GF (insn, 20 ,3) == 2 && __GF (insn, 6, 3) == 1)
862 /* AWEXT ASATS48 */
863 return MASK_OP (insn, (0x1f << 20) | (0xf << 5));
864 else if (__GF (insn, 20 ,3) == 3 && __GF (insn, 6, 3) == 1)
865 /* AMTAR AMTAR2 AMFAR AMFAR2 */
866 return MASK_OP (insn, (0x1f << 20) | (0x1f << 5));
867 else if (__GF (insn, 7, 2) == 3)
868 /* AMxxxSA */
869 return MASK_OP (insn, (0x1f << 20) | (0x3 << 7));
870 else if (__GF (insn, 6, 3) == 2)
871 /* AMxxxL.S */
872 return MASK_OP (insn, (0x1f << 20) | (0xf << 5));
35c08157 873 else
40c7a7cb
KLC
874 /* AmxxxL.l AmxxxL2.S AMxxxL2.L */
875 return MASK_OP (insn, (0x1f << 20) | (0x7 << 6));
35c08157 876 case 0x1:
40c7a7cb
KLC
877 if (__GF (insn, 20, 3) == 0)
878 /* AADDL ASUBL */
879 return MASK_OP (insn, (0x1f << 20) | (0x1 << 5));
880 else if (__GF (insn, 20, 3) == 1)
881 /* AMTARI Ix AMTARI Mx */
882 return MASK_OP (insn, (0x1f << 20));
883 else if (__GF (insn, 6, 3) == 2)
884 /* AMAWzSl.S AMWzSl.S */
885 return MASK_OP (insn, (0x1f << 20) | (0xf << 5));
886 else if (__GF (insn, 7, 2) == 3)
887 /* AMAWzSSA AMWzSSA */
888 return MASK_OP (insn, (0x1f << 20) | (0x3 << 7));
889 else
890 /* AMAWzSL.L AMAWzSL2.S AMAWzSL2.L AMWzSL.L AMWzSL.L AMWzSL2.S */
891 return MASK_OP (insn, (0x1f << 20) | (0x7 << 6));
892 case 0x2:
893 if (__GF (insn, 6, 3) == 2)
894 /* AMAyySl.S AMWyySl.S */
895 return MASK_OP (insn, (0x1f << 20) | (0xf << 5));
896 else if (__GF (insn, 7, 2) == 3)
897 /* AMAWyySSA AMWyySSA */
898 return MASK_OP (insn, (0x1f << 20) | (0x3 << 7));
899 else
900 /* AMAWyySL.L AMAWyySL2.S AMAWyySL2.L AMWyySL.L AMWyySL.L AMWyySL2.S */
901 return MASK_OP (insn, (0x1f << 20) | (0x7 << 6));
35c08157 902 }
40c7a7cb
KLC
903 return MASK_OP (insn, 0x1f << 20);
904 default:
905 return (1 << 31);
35c08157
KLC
906 }
907}
908
40c7a7cb
KLC
909/* Define cctl subtype. */
910static char *cctl_subtype [] =
35c08157 911{
40c7a7cb
KLC
912 /* 0x0 */
913 "st0", "st0", "st0", "st2", "st2", "st3", "st3", "st4",
914 "st1", "st1", "st1", "st0", "st0", NULL, NULL, "st5",
915 /* 0x10 */
916 "st0", NULL, NULL, "st2", "st2", "st3", "st3", NULL,
917 "st1", NULL, NULL, "st0", "st0", NULL, NULL, NULL
918};
35c08157 919
40c7a7cb 920/* Check the subset of opcode. */
35c08157 921
40c7a7cb
KLC
922static void
923nds32_special_opcode (uint32_t insn, struct nds32_opcode **opc)
924{
925 char *string = NULL;
926 uint32_t op;
35c08157 927
40c7a7cb
KLC
928 if (!(*opc))
929 return;
35c08157 930
40c7a7cb
KLC
931 /* Check if special case. */
932 switch ((*opc)->value)
933 {
934 case OP6 (LWC):
935 case OP6 (SWC):
936 case OP6 (LDC):
937 case OP6 (SDC):
938 case FPU_RA_IMMBI (LWC):
939 case FPU_RA_IMMBI (SWC):
940 case FPU_RA_IMMBI (LDC):
941 case FPU_RA_IMMBI (SDC):
942 /* Check if cp0 => FPU. */
35c08157 943 if (__GF (insn, 13, 2) == 0)
35c08157 944 {
40c7a7cb
KLC
945 while (!((*opc)->attr & ATTR (FPU)) && (*opc)->next)
946 *opc = (*opc)->next;
35c08157 947 }
40c7a7cb
KLC
948 break;
949 case ALU1 (ADD):
950 case ALU1 (SUB):
951 case ALU1 (AND):
952 case ALU1 (XOR):
953 case ALU1 (OR):
954 /* Check if (add/add_slli) (sub/sub_slli) (and/and_slli). */
955 if (N32_SH5(insn) != 0)
956 string = "sh";
957 break;
958 case ALU1 (SRLI):
959 /* Check if nop. */
960 if (__GF (insn, 10, 15) == 0)
961 string = "nop";
962 break;
963 case MISC (CCTL):
964 string = cctl_subtype [__GF (insn, 5, 5)];
965 break;
966 case JREG (JR):
967 case JREG (JRAL):
968 case JREG (JR) | JREG_RET:
969 if (__GF (insn, 8, 2) != 0)
970 string = "tit";
971 break;
972 case N32_OP6_COP:
973 break;
974 case 0xea00:
975 /* break16 ex9 */
976 if (__GF (insn, 5, 4) != 0)
977 string = "ex9";
978 break;
979 case 0x9200:
980 /* nop16 */
981 if (__GF (insn, 0, 9) == 0)
982 string = "nop16";
983 break;
984 }
985
986 if (string)
987 {
988 while (strstr ((*opc)->opcode, string) == NULL
989 && strstr ((*opc)->instruction, string) == NULL && (*opc)->next)
990 *opc = (*opc)->next;
35c08157
KLC
991 return;
992 }
40c7a7cb
KLC
993
994 /* Classify instruction is COP or FPU. */
995 op = N32_OP6 (insn);
996 if (op == N32_OP6_COP && __GF (insn, 4, 2) != 0)
997 {
998 while (((*opc)->attr & ATTR (FPU)) != 0 && (*opc)->next)
999 *opc = (*opc)->next;
1000 }
35c08157
KLC
1001}
1002
1003int
1004print_insn_nds32 (bfd_vma pc, disassemble_info *info)
1005{
1006 int status;
1007 bfd_byte buf[4];
1008 uint32_t insn;
40c7a7cb
KLC
1009 static int init = 1;
1010 int i = 0;
1011 struct nds32_opcode *opc;
1012 struct nds32_opcode **slot;
1013
1014 if (init)
1015 {
1016 /* Build opcode table. */
1017 opcode_htab = htab_create_alloc (1024, htab_hash_hash, htab_hash_eq,
1018 NULL, xcalloc, free);
35c08157 1019
40c7a7cb
KLC
1020 while (nds32_opcodes[i].opcode != NULL)
1021 {
1022 opc = &nds32_opcodes[i];
1023 slot =
1024 (struct nds32_opcode **) htab_find_slot (opcode_htab, &opc->value,
1025 INSERT);
1026 if (*slot == NULL)
1027 {
1028 /* This is the new one. */
1029 *slot = opc;
1030 }
1031 else
1032 {
1033 /* Already exists. Append to the list. */
1034 opc = *slot;
1035 while (opc->next)
1036 opc = opc->next;
1037 opc->next = &nds32_opcodes[i];
1038 }
1039 i++;
1040 }
1041 init = 0;
1042 }
1043
1044 status = info->read_memory_func (pc, (bfd_byte *) buf, 4, info);
35c08157 1045 if (status)
40c7a7cb
KLC
1046 {
1047 /* for the last 16-bit instruction. */
1048 status = info->read_memory_func (pc, (bfd_byte *) buf, 2, info);
1049 if (status)
1050 {
1051 (*info->memory_error_func)(status, pc, info);
1052 return -1;
1053 }
1054 }
35c08157 1055
40c7a7cb 1056 insn = bfd_getb32 (buf);
35c08157 1057 /* 16-bit instruction. */
40c7a7cb 1058 if (insn & 0x80000000)
35c08157 1059 {
40c7a7cb
KLC
1060 if (info->section && strstr (info->section->name, ".ex9.itable") != NULL)
1061 {
1062 print_insn16 (pc, info, (insn & 0x0000FFFF),
1063 NDS32_PARSE_INSN16 | NDS32_PARSE_EX9TAB);
1064 return 4;
1065 }
1066 print_insn16 (pc, info, (insn >> 16), NDS32_PARSE_INSN16);
35c08157
KLC
1067 return 2;
1068 }
1069
1070 /* 32-bit instructions. */
40c7a7cb
KLC
1071 else
1072 {
1073 if (info->section
1074 && strstr (info->section->name, ".ex9.itable") != NULL)
1075 print_insn32 (pc, info, insn, NDS32_PARSE_INSN32 | NDS32_PARSE_EX9TAB);
1076 else
1077 print_insn32 (pc, info, insn, NDS32_PARSE_INSN32);
1078 return 4;
1079 }
35c08157 1080}
This page took 0.310677 seconds and 4 git commands to generate.