gdb: fix vfork with multiple threads
[deliverable/binutils-gdb.git] / opcodes / nds32-dis.c
CommitLineData
35c08157 1/* NDS32-specific support for 32-bit ELF.
250d07de 2 Copyright (C) 2012-2021 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"
88c1242d 25#include "disassemble.h"
35c08157
KLC
26#include "bfd.h"
27#include "symcat.h"
28#include "libiberty.h"
29#include "opintl.h"
3dfb1b6d 30#include <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 37
fbaf61ad
NC
38/* For mapping symbol. */
39enum map_type
40{
41 MAP_DATA0,
42 MAP_DATA1,
43 MAP_DATA2,
44 MAP_DATA3,
45 MAP_DATA4,
46 MAP_CODE,
47};
48
49struct nds32_private_data
50{
51 /* Whether any mapping symbols are present in the provided symbol
52 table. -1 if we do not know yet, otherwise 0 or 1. */
53 int has_mapping_symbols;
54
55 /* Track the last type (although this doesn't seem to be useful). */
56 enum map_type last_mapping_type;
57
58 /* Tracking symbol table information. */
59 int last_symbol_index;
60 bfd_vma last_addr;
61};
62
35c08157
KLC
63/* Default text to print if an instruction isn't recognized. */
64#define UNKNOWN_INSN_MSG _("*unknown*")
40c7a7cb
KLC
65#define NDS32_PARSE_INSN16 0x01
66#define NDS32_PARSE_INSN32 0x02
40c7a7cb 67
40c7a7cb
KLC
68static uint32_t nds32_mask_opcode (uint32_t);
69static void nds32_special_opcode (uint32_t, struct nds32_opcode **);
fbaf61ad
NC
70static int get_mapping_symbol_type (struct disassemble_info *, int,
71 enum map_type *);
72static int is_mapping_symbol (struct disassemble_info *, int,
73 enum map_type *);
40c7a7cb 74
40c7a7cb 75/* Hash function for disassemble. */
35c08157 76
40c7a7cb 77static htab_t opcode_htab;
35c08157 78
40c7a7cb 79/* Find the value map register name. */
6b9d3259 80
62194b63
AM
81static const keyword_t *
82nds32_find_reg_keyword (const keyword_t *reg, int value)
35c08157 83{
40c7a7cb
KLC
84 if (!reg)
85 return NULL;
6b9d3259 86
40c7a7cb
KLC
87 while (reg->name != NULL && reg->value != value)
88 {
89 reg++;
90 }
91 if (reg->name == NULL)
92 return NULL;
93 return reg;
94}
35c08157
KLC
95
96static void
40c7a7cb
KLC
97nds32_parse_audio_ext (const field_t *pfd,
98 disassemble_info *info, uint32_t insn)
35c08157 99{
35c08157
KLC
100 fprintf_ftype func = info->fprintf_func;
101 void *stream = info->stream;
62194b63 102 const keyword_t *psys_reg;
40c7a7cb 103 int int_value, new_value;
35c08157 104
40c7a7cb 105 if (pfd->hw_res == HW_INT || pfd->hw_res == HW_UINT)
35c08157 106 {
40c7a7cb 107 if (pfd->hw_res == HW_INT)
4bdb25fe
AM
108 int_value = (unsigned) N32_IMMS (insn >> pfd->bitpos,
109 pfd->bitsize) << pfd->shift;
40c7a7cb
KLC
110 else
111 int_value = __GF (insn, pfd->bitpos, pfd->bitsize) << pfd->shift;
35c08157 112
3ee6e4fb 113 if (int_value < 10)
40c7a7cb
KLC
114 func (stream, "#%d", int_value);
115 else
116 func (stream, "#0x%x", int_value);
35c08157
KLC
117 return;
118 }
40c7a7cb
KLC
119 int_value =
120 __GF (insn, pfd->bitpos, pfd->bitsize) << pfd->shift;
121 new_value = int_value;
9b2beaf7 122 psys_reg = (keyword_t*) nds32_keywords[pfd->hw_res];
35c08157 123
40c7a7cb
KLC
124 /* p = bit[4].bit[1:0], r = bit[4].bit[3:2]. */
125 if (strcmp (pfd->name, "im5_i") == 0)
35c08157 126 {
40c7a7cb
KLC
127 new_value = int_value & 0x03;
128 new_value |= ((int_value & 0x10) >> 2);
35c08157 129 }
40c7a7cb 130 else if (strcmp (pfd->name, "im5_m") == 0)
35c08157 131 {
40c7a7cb 132 new_value = ((int_value & 0x1C) >> 2);
35c08157 133 }
40c7a7cb
KLC
134 /* p = 0.bit[1:0], r = 0.bit[3:2]. */
135 /* q = 1.bit[1:0], s = 1.bit[5:4]. */
136 else if (strcmp (pfd->name, "im6_iq") == 0)
35c08157 137 {
40c7a7cb 138 new_value |= 0x04;
35c08157 139 }
40c7a7cb 140 else if (strcmp (pfd->name, "im6_ms") == 0)
35c08157 141 {
40c7a7cb
KLC
142 new_value |= 0x04;
143 }
144 /* Rt CONCAT(c, t21, t0). */
145 else if (strcmp (pfd->name, "a_rt21") == 0)
146 {
147 new_value = (insn & 0x00000020) >> 5;
148 new_value |= (insn & 0x00000C00) >> 9;
149 new_value |= (insn & 0x00008000) >> 12;
150 }
151 else if (strcmp (pfd->name, "a_rte") == 0)
152 {
153 new_value = (insn & 0x00000C00) >> 9;
154 new_value |= (insn & 0x00008000) >> 12;
155 }
156 else if (strcmp (pfd->name, "a_rte1") == 0)
157 {
158 new_value = (insn & 0x00000C00) >> 9;
159 new_value |= (insn & 0x00008000) >> 12;
160 new_value |= 0x01;
35c08157 161 }
40c7a7cb
KLC
162 else if (strcmp (pfd->name, "a_rte69") == 0)
163 {
164 new_value = int_value << 1;
165 }
166 else if (strcmp (pfd->name, "a_rte69_1") == 0)
167 {
168 new_value = int_value << 1;
169 new_value |= 0x01;
170 }
171
172 psys_reg = nds32_find_reg_keyword (psys_reg, new_value);
173 if (!psys_reg)
174 func (stream, "???");
175 else
176 func (stream, "$%s", psys_reg->name);
35c08157
KLC
177}
178
fbaf61ad
NC
179/* Match instruction opcode with keyword table. */
180
181static field_t *
182match_field (char *name)
183{
184 field_t *pfd;
185 int k;
186
187 for (k = 0; k < NDS32_CORE_COUNT; k++)
188 {
189 pfd = (field_t *) nds32_field_table[k];
190 while (1)
191 {
192 if (pfd->name == NULL)
193 break;
194 if (strcmp (name, pfd->name) == 0)
195 return pfd;
196 pfd++;
197 }
198 }
199
200 return NULL;
201}
202
40c7a7cb 203/* Dump instruction. If the opcode is unknown, return FALSE. */
35c08157
KLC
204
205static void
40c7a7cb
KLC
206nds32_parse_opcode (struct nds32_opcode *opc, bfd_vma pc ATTRIBUTE_UNUSED,
207 disassemble_info *info, uint32_t insn,
208 uint32_t parse_mode)
35c08157 209{
40c7a7cb 210 int op = 0;
35c08157
KLC
211 fprintf_ftype func = info->fprintf_func;
212 void *stream = info->stream;
40c7a7cb
KLC
213 const char *pstr_src;
214 char *pstr_tmp;
215 char tmp_string[16];
216 unsigned int push25gpr = 0, lsmwRb, lsmwRe, lsmwEnb4, checkbit, i;
217 int int_value, ifthe1st = 1;
218 const field_t *pfd;
62194b63 219 const keyword_t *psys_reg;
40c7a7cb
KLC
220
221 if (opc == NULL)
35c08157 222 {
35c08157
KLC
223 func (stream, UNKNOWN_INSN_MSG);
224 return;
225 }
35c08157 226
40c7a7cb
KLC
227 pstr_src = opc->instruction;
228 if (*pstr_src == 0)
35c08157 229 {
40c7a7cb 230 func (stream, "%s", opc->opcode);
35c08157
KLC
231 return;
232 }
40c7a7cb
KLC
233 /* NDS32_PARSE_INSN16. */
234 if (parse_mode & NDS32_PARSE_INSN16)
235 {
236 func (stream, "%s ", opc->opcode);
237 }
35c08157 238
40c7a7cb
KLC
239 /* NDS32_PARSE_INSN32. */
240 else
35c08157 241 {
40c7a7cb
KLC
242 op = N32_OP6 (insn);
243 if (op == N32_OP6_LSMW)
244 func (stream, "%s.", opc->opcode);
245 else if (strstr (opc->instruction, "tito"))
246 func (stream, "%s", opc->opcode);
247 else
3ee6e4fb 248 func (stream, "%s\t", opc->opcode);
35c08157
KLC
249 }
250
40c7a7cb 251 while (*pstr_src)
35c08157 252 {
40c7a7cb
KLC
253 switch (*pstr_src)
254 {
255 case '%':
256 case '=':
257 case '&':
258 pstr_src++;
9b2beaf7 259 /* Compare with nds32_operand_fields[].name. */
40c7a7cb
KLC
260 pstr_tmp = &tmp_string[0];
261 while (*pstr_src)
262 {
263 if ((*pstr_src == ',') || (*pstr_src == ' ')
264 || (*pstr_src == '{') || (*pstr_src == '}')
265 || (*pstr_src == '[') || (*pstr_src == ']')
266 || (*pstr_src == '(') || (*pstr_src == ')')
267 || (*pstr_src == '+') || (*pstr_src == '<'))
268 break;
269 *pstr_tmp++ = *pstr_src++;
270 }
271 *pstr_tmp = 0;
35c08157 272
fbaf61ad
NC
273 if ((pfd = match_field (&tmp_string[0])) == NULL)
274 return;
35c08157 275
3ee6e4fb 276 /* For insn-16. */
40c7a7cb
KLC
277 if (parse_mode & NDS32_PARSE_INSN16)
278 {
279 if (pfd->hw_res == HW_GPR)
280 {
281 int_value =
282 __GF (insn, pfd->bitpos, pfd->bitsize) << pfd->shift;
283 /* push25/pop25. */
284 if ((opc->value == 0xfc00) || (opc->value == 0xfc80))
285 {
286 if (int_value == 0)
287 int_value = 6;
288 else
289 int_value = (6 + (0x01 << int_value));
290 push25gpr = int_value;
291 }
292 else if (strcmp (pfd->name, "rt4") == 0)
293 {
294 int_value = nds32_r45map[int_value];
295 }
9b2beaf7 296 func (stream, "$%s", nds32_keyword_gpr[int_value].name);
40c7a7cb
KLC
297 }
298 else if ((pfd->hw_res == HW_INT) || (pfd->hw_res == HW_UINT))
299 {
300 if (pfd->hw_res == HW_INT)
4bdb25fe
AM
301 int_value
302 = (unsigned) N32_IMMS (insn >> pfd->bitpos,
303 pfd->bitsize) << pfd->shift;
40c7a7cb
KLC
304 else
305 int_value =
306 __GF (insn, pfd->bitpos, pfd->bitsize) << pfd->shift;
307
308 /* movpi45. */
309 if (opc->value == 0xfa00)
310 {
311 int_value += 16;
312 func (stream, "#0x%x", int_value);
313 }
314 /* lwi45.fe. */
315 else if (opc->value == 0xb200)
316 {
317 int_value = 0 - (128 - int_value);
318 func (stream, "#%d", int_value);
319 }
fbaf61ad 320 /* beqz38/bnez38/beqs38/bnes38/j8/beqzs8/bnezs8. */
40c7a7cb
KLC
321 else if ((opc->value == 0xc000) || (opc->value == 0xc800)
322 || (opc->value == 0xd000) || (opc->value == 0xd800)
323 || (opc->value == 0xd500) || (opc->value == 0xe800)
fbaf61ad 324 || (opc->value == 0xe900))
40c7a7cb
KLC
325 {
326 info->print_address_func (int_value + pc, info);
327 }
328 /* push25/pop25. */
329 else if ((opc->value == 0xfc00) || (opc->value == 0xfc80))
330 {
331 func (stream, "#%d ! {$r6", int_value);
332 if (push25gpr != 6)
9b2beaf7 333 func (stream, "~$%s", nds32_keyword_gpr[push25gpr].name);
40c7a7cb
KLC
334 func (stream, ", $fp, $gp, $lp}");
335 }
40c7a7cb
KLC
336 else if (pfd->hw_res == HW_INT)
337 {
3ee6e4fb 338 if (int_value < 10)
40c7a7cb
KLC
339 func (stream, "#%d", int_value);
340 else
341 func (stream, "#0x%x", int_value);
342 }
3ee6e4fb
NC
343 else /* if (pfd->hw_res == HW_UINT). */
344 {
345 if (int_value < 10)
346 func (stream, "#%u", int_value);
347 else
348 func (stream, "#0x%x", int_value);
349 }
40c7a7cb 350 }
35c08157 351
40c7a7cb
KLC
352 }
353 /* for audio-ext. */
354 else if (op == N32_OP6_AEXT)
355 {
356 nds32_parse_audio_ext (pfd, info, insn);
357 }
358 /* for insn-32. */
fbaf61ad 359 else if (pfd->hw_res < HW_INT)
40c7a7cb
KLC
360 {
361 int_value =
362 __GF (insn, pfd->bitpos, pfd->bitsize) << pfd->shift;
363
fbaf61ad
NC
364 psys_reg = *(nds32_keyword_table[pfd->hw_res >> 8]
365 + (pfd->hw_res & 0xff));
40c7a7cb
KLC
366
367 psys_reg = nds32_find_reg_keyword (psys_reg, int_value);
368 /* For HW_SR, dump the index when it can't
369 map the register name. */
370 if (!psys_reg && pfd->hw_res == HW_SR)
371 func (stream, "%d", int_value);
372 else if (!psys_reg)
373 func (stream, "???");
374 else
375 {
376 if (pfd->hw_res == HW_GPR || pfd->hw_res == HW_CPR
377 || pfd->hw_res == HW_FDR || pfd->hw_res == HW_FSR
378 || pfd->hw_res == HW_DXR || pfd->hw_res == HW_SR
379 || pfd->hw_res == HW_USR)
380 func (stream, "$%s", psys_reg->name);
381 else if (pfd->hw_res == HW_DTITON
382 || pfd->hw_res == HW_DTITOFF)
383 func (stream, ".%s", psys_reg->name);
384 else
385 func (stream, "%s", psys_reg->name);
386 }
387 }
388 else if ((pfd->hw_res == HW_INT) || (pfd->hw_res == HW_UINT))
389 {
390 if (pfd->hw_res == HW_INT)
4bdb25fe
AM
391 int_value = (unsigned) N32_IMMS (insn >> pfd->bitpos,
392 pfd->bitsize) << pfd->shift;
40c7a7cb
KLC
393 else
394 int_value =
395 __GF (insn, pfd->bitpos, pfd->bitsize) << pfd->shift;
396
397 if ((op == N32_OP6_BR1) || (op == N32_OP6_BR2))
398 {
399 info->print_address_func (int_value + pc, info);
400 }
401 else if ((op == N32_OP6_BR3) && (pfd->bitpos == 0))
402 {
403 info->print_address_func (int_value + pc, info);
404 }
405 else if (op == N32_OP6_JI)
406 {
407 /* FIXME: Handle relocation. */
408 if (info->flags & INSN_HAS_RELOC)
409 pc = 0;
fbaf61ad 410 info->print_address_func (int_value + pc, info);
40c7a7cb
KLC
411 }
412 else if (op == N32_OP6_LSMW)
413 {
414 /* lmw.adm/smw.adm. */
415 func (stream, "#0x%x ! {", int_value);
416 lsmwEnb4 = int_value;
417 lsmwRb = ((insn >> 20) & 0x1F);
418 lsmwRe = ((insn >> 10) & 0x1F);
419
420 /* If [Rb, Re] specifies at least one register,
421 Rb(4,0) <= Re(4,0) and 0 <= Rb(4,0), Re(4,0) < 28.
422 Disassembling does not consider this currently because of
423 the convience comparing with bsp320. */
424 if (lsmwRb != 31 || lsmwRe != 31)
425 {
9b2beaf7 426 func (stream, "$%s", nds32_keyword_gpr[lsmwRb].name);
40c7a7cb 427 if (lsmwRb != lsmwRe)
9b2beaf7 428 func (stream, "~$%s", nds32_keyword_gpr[lsmwRe].name);
40c7a7cb
KLC
429 ifthe1st = 0;
430 }
431 if (lsmwEnb4 != 0)
432 {
433 /* $fp, $gp, $lp, $sp. */
434 checkbit = 0x08;
435 for (i = 0; i < 4; i++)
436 {
437 if (lsmwEnb4 & checkbit)
438 {
439 if (ifthe1st == 1)
440 {
441 ifthe1st = 0;
9b2beaf7 442 func (stream, "$%s", nds32_keyword_gpr[28 + i].name);
40c7a7cb
KLC
443 }
444 else
9b2beaf7 445 func (stream, ", $%s", nds32_keyword_gpr[28 + i].name);
40c7a7cb
KLC
446 }
447 checkbit >>= 1;
448 }
449 }
450 func (stream, "}");
451 }
452 else if (pfd->hw_res == HW_INT)
453 {
3ee6e4fb 454 if (int_value < 10)
40c7a7cb
KLC
455 func (stream, "#%d", int_value);
456 else
457 func (stream, "#0x%x", int_value);
458 }
3ee6e4fb 459 else /* if (pfd->hw_res == HW_UINT). */
40c7a7cb 460 {
3ee6e4fb
NC
461 if (int_value < 10)
462 func (stream, "#%u", int_value);
463 else
464 func (stream, "#0x%x", int_value);
40c7a7cb
KLC
465 }
466 }
467 break;
35c08157 468
40c7a7cb
KLC
469 case '{':
470 case '}':
471 pstr_src++;
472 break;
473
3ee6e4fb
NC
474 case ',':
475 func (stream, ", ");
476 pstr_src++;
477 break;
478
479 case '+':
480 func (stream, " + ");
481 pstr_src++;
482 break;
483
484 case '<':
485 if (pstr_src[1] == '<')
486 {
487 func (stream, " << ");
488 pstr_src += 2;
489 }
490 else
491 {
492 func (stream, " <");
493 pstr_src++;
494 }
495 break;
496
40c7a7cb
KLC
497 default:
498 func (stream, "%c", *pstr_src++);
499 break;
3ee6e4fb
NC
500 }
501 }
35c08157
KLC
502}
503
40c7a7cb
KLC
504/* Filter instructions with some bits must be fixed. */
505
35c08157 506static void
40c7a7cb 507nds32_filter_unknown_insn (uint32_t insn, struct nds32_opcode **opc)
35c08157 508{
40c7a7cb
KLC
509 if (!(*opc))
510 return;
35c08157 511
40c7a7cb 512 switch ((*opc)->value)
35c08157 513 {
40c7a7cb
KLC
514 case JREG (JR):
515 case JREG (JRNEZ):
516 /* jr jr.xtoff */
517 if (__GF (insn, 6, 2) != 0 || __GF (insn, 15, 10) != 0)
518 *opc = NULL;
35c08157 519 break;
40c7a7cb
KLC
520 case MISC (STANDBY):
521 if (__GF (insn, 7, 18) != 0)
522 *opc = NULL;
523 break;
524 case SIMD (PBSAD):
525 case SIMD (PBSADA):
526 if (__GF (insn, 5, 5) != 0)
527 *opc = NULL;
528 break;
fbaf61ad 529 case BR2 (SOP0):
40c7a7cb
KLC
530 if (__GF (insn, 20, 5) != 0)
531 *opc = NULL;
532 break;
533 case JREG (JRAL):
534 if (__GF (insn, 5, 3) != 0 || __GF (insn, 15, 5) != 0)
535 *opc = NULL;
536 break;
537 case ALU1 (NOR):
538 case ALU1 (SLT):
539 case ALU1 (SLTS):
540 case ALU1 (SLLI):
541 case ALU1 (SRLI):
542 case ALU1 (SRAI):
543 case ALU1 (ROTRI):
544 case ALU1 (SLL):
545 case ALU1 (SRL):
546 case ALU1 (SRA):
547 case ALU1 (ROTR):
548 case ALU1 (SEB):
549 case ALU1 (SEH):
550 case ALU1 (ZEH):
551 case ALU1 (WSBH):
552 case ALU1 (SVA):
553 case ALU1 (SVS):
554 case ALU1 (CMOVZ):
555 case ALU1 (CMOVN):
556 if (__GF (insn, 5, 5) != 0)
557 *opc = NULL;
558 break;
559 case MISC (IRET):
560 case MISC (ISB):
561 case MISC (DSB):
562 if (__GF (insn, 5, 20) != 0)
563 *opc = NULL;
35c08157
KLC
564 break;
565 }
566}
567
568static void
40c7a7cb
KLC
569print_insn32 (bfd_vma pc, disassemble_info *info, uint32_t insn,
570 uint32_t parse_mode)
35c08157 571{
40c7a7cb
KLC
572 /* Get the final correct opcode and parse. */
573 struct nds32_opcode *opc;
574 uint32_t opcode = nds32_mask_opcode (insn);
575 opc = (struct nds32_opcode *) htab_find (opcode_htab, &opcode);
576
577 nds32_special_opcode (insn, &opc);
578 nds32_filter_unknown_insn (insn, &opc);
579 nds32_parse_opcode (opc, pc, info, insn, parse_mode);
35c08157
KLC
580}
581
582static void
40c7a7cb
KLC
583print_insn16 (bfd_vma pc, disassemble_info *info,
584 uint32_t insn, uint32_t parse_mode)
35c08157 585{
40c7a7cb
KLC
586 struct nds32_opcode *opc;
587 uint32_t opcode;
588
589 /* Get highest 7 bit in default. */
590 unsigned int mask = 0xfe00;
35c08157 591
40c7a7cb
KLC
592 /* Classify 16-bit instruction to 4 sets by bit 13 and 14. */
593 switch (__GF (insn, 13, 2))
35c08157 594 {
40c7a7cb
KLC
595 case 0x0:
596 /* mov55 movi55 */
597 if (__GF (insn, 11, 2) == 0)
35c08157 598 {
40c7a7cb
KLC
599 mask = 0xfc00;
600 /* ifret16 = mov55 $sp, $sp*/
601 if (__GF (insn, 0, 11) == 0x3ff)
602 mask = 0xffff;
35c08157 603 }
40c7a7cb
KLC
604 else if (__GF (insn, 9, 4) == 0xb)
605 mask = 0xfe07;
606 break;
607 case 0x1:
608 /* lwi37 swi37 */
609 if (__GF (insn, 11, 2) == 0x3)
610 mask = 0xf880;
611 break;
612 case 0x2:
613 mask = 0xf800;
614 /* Exclude beqz38, bnez38, beqs38, and bnes38. */
615 if (__GF (insn, 12, 1) == 0x1
616 && __GF (insn, 8, 3) == 0x5)
35c08157 617 {
40c7a7cb
KLC
618 if (__GF (insn, 11, 1) == 0x0)
619 mask = 0xff00;
620 else
621 mask = 0xffe0;
35c08157 622 }
40c7a7cb
KLC
623 break;
624 case 0x3:
625 switch (__GF (insn, 11, 2))
35c08157 626 {
35c08157 627 case 0x1:
40c7a7cb
KLC
628 /* beqzs8 bnezs8 */
629 if (__GF (insn, 9, 2) == 0x0)
630 mask = 0xff00;
631 /* addi10s */
632 else if (__GF(insn, 10, 1) == 0x1)
633 mask = 0xfc00;
634 break;
35c08157 635 case 0x2:
40c7a7cb
KLC
636 /* lwi37.sp swi37.sp */
637 mask = 0xf880;
638 break;
35c08157 639 case 0x3:
40c7a7cb
KLC
640 if (__GF (insn, 8, 3) == 0x5)
641 mask = 0xff00;
642 else if (__GF (insn, 8, 3) == 0x4)
643 mask = 0xff80;
644 else if (__GF (insn, 9 , 2) == 0x3)
645 mask = 0xfe07;
646 break;
647 }
648 break;
649 }
650 opcode = insn & mask;
651 opc = (struct nds32_opcode *) htab_find (opcode_htab, &opcode);
652
653 nds32_special_opcode (insn, &opc);
654 /* Get the final correct opcode and parse it. */
655 nds32_parse_opcode (opc, pc, info, insn, parse_mode);
656}
657
658static hashval_t
659htab_hash_hash (const void *p)
660{
661 return (*(unsigned int *) p) % 49;
662}
663
664static int
665htab_hash_eq (const void *p, const void *q)
666{
667 uint32_t pinsn = ((struct nds32_opcode *) p)->value;
668 uint32_t qinsn = *((uint32_t *) q);
669
670 return (pinsn == qinsn);
671}
672
673/* Get the format of instruction. */
35c08157 674
40c7a7cb
KLC
675static uint32_t
676nds32_mask_opcode (uint32_t insn)
677{
678 uint32_t opcode = N32_OP6 (insn);
679 switch (opcode)
680 {
681 case N32_OP6_LBI:
682 case N32_OP6_LHI:
683 case N32_OP6_LWI:
684 case N32_OP6_LDI:
685 case N32_OP6_LBI_BI:
686 case N32_OP6_LHI_BI:
687 case N32_OP6_LWI_BI:
688 case N32_OP6_LDI_BI:
689 case N32_OP6_SBI:
690 case N32_OP6_SHI:
691 case N32_OP6_SWI:
692 case N32_OP6_SDI:
693 case N32_OP6_SBI_BI:
694 case N32_OP6_SHI_BI:
695 case N32_OP6_SWI_BI:
696 case N32_OP6_SDI_BI:
697 case N32_OP6_LBSI:
698 case N32_OP6_LHSI:
699 case N32_OP6_LWSI:
700 case N32_OP6_LBSI_BI:
701 case N32_OP6_LHSI_BI:
702 case N32_OP6_LWSI_BI:
703 case N32_OP6_MOVI:
704 case N32_OP6_SETHI:
705 case N32_OP6_ADDI:
706 case N32_OP6_SUBRI:
707 case N32_OP6_ANDI:
708 case N32_OP6_XORI:
709 case N32_OP6_ORI:
710 case N32_OP6_SLTI:
711 case N32_OP6_SLTSI:
712 case N32_OP6_CEXT:
713 case N32_OP6_BITCI:
714 return MASK_OP (insn, 0);
715 case N32_OP6_ALU2:
716 /* FFBI */
4ec521f2 717 if (__GF (insn, 0, 7) == (N32_ALU2_FFBI | N32_BIT (6)))
40c7a7cb 718 return MASK_OP (insn, 0x7f);
4ec521f2
KLC
719 else if (__GF (insn, 0, 7) == (N32_ALU2_MFUSR | N32_BIT (6))
720 || __GF (insn, 0, 7) == (N32_ALU2_MTUSR | N32_BIT (6)))
40c7a7cb
KLC
721 /* RDOV CLROV */
722 return MASK_OP (insn, 0xf81ff);
fbaf61ad
NC
723 else if (__GF (insn, 0, 10) == (N32_ALU2_ONEOP | N32_BIT (7)))
724 {
725 /* INSB */
726 if (__GF (insn, 12, 3) == 4)
727 return MASK_OP (insn, 0x73ff);
728 return MASK_OP (insn, 0x7fff);
729 }
730 return MASK_OP (insn, 0x3ff);
40c7a7cb
KLC
731 case N32_OP6_ALU1:
732 case N32_OP6_SIMD:
733 return MASK_OP (insn, 0x1f);
734 case N32_OP6_MEM:
735 return MASK_OP (insn, 0xff);
736 case N32_OP6_JREG:
737 return MASK_OP (insn, 0x7f);
738 case N32_OP6_LSMW:
739 return MASK_OP (insn, 0x23);
740 case N32_OP6_SBGP:
741 case N32_OP6_LBGP:
742 return MASK_OP (insn, 0x1 << 19);
743 case N32_OP6_HWGP:
744 if (__GF (insn, 18, 2) == 0x3)
745 return MASK_OP (insn, 0x7 << 17);
746 return MASK_OP (insn, 0x3 << 18);
747 case N32_OP6_DPREFI:
748 return MASK_OP (insn, 0x1 << 24);
749 case N32_OP6_LWC:
750 case N32_OP6_SWC:
751 case N32_OP6_LDC:
752 case N32_OP6_SDC:
753 return MASK_OP (insn, 0x1 << 12);
754 case N32_OP6_JI:
755 return MASK_OP (insn, 0x1 << 24);
756 case N32_OP6_BR1:
757 return MASK_OP (insn, 0x1 << 14);
758 case N32_OP6_BR2:
fbaf61ad
NC
759 if (__GF (insn, 16, 4) == 0)
760 return MASK_OP (insn, 0x1ff << 16);
761 else
762 return MASK_OP (insn, 0xf << 16);
40c7a7cb
KLC
763 case N32_OP6_BR3:
764 return MASK_OP (insn, 0x1 << 19);
765 case N32_OP6_MISC:
766 switch (__GF (insn, 0, 5))
767 {
768 case N32_MISC_MTSR:
769 /* SETGIE and SETEND */
770 if (__GF (insn, 5, 5) == 0x1 || __GF (insn, 5, 5) == 0x2)
771 return MASK_OP (insn, 0x1fffff);
772 return MASK_OP (insn, 0x1f);
773 case N32_MISC_TLBOP:
774 if (__GF (insn, 5, 5) == 5 || __GF (insn, 5, 5) == 7)
775 /* PB FLUA */
776 return MASK_OP (insn, 0x3ff);
777 return MASK_OP (insn, 0x1f);
778 default:
779 return MASK_OP (insn, 0x1f);
780 }
781 case N32_OP6_COP:
782 if (__GF (insn, 4, 2) == 0)
783 {
784 /* FPU */
785 switch (__GF (insn, 0, 4))
35c08157
KLC
786 {
787 case 0x0:
35c08157 788 case 0x8:
40c7a7cb
KLC
789 /* FS1/F2OP FD1/F2OP */
790 if (__GF (insn, 6, 4) == 0xf)
791 return MASK_OP (insn, 0x7fff);
792 /* FS1 FD1 */
793 return MASK_OP (insn, 0x3ff);
794 case 0x4:
35c08157 795 case 0xc:
40c7a7cb
KLC
796 /* FS2 */
797 return MASK_OP (insn, 0x3ff);
798 case 0x1:
799 case 0x9:
800 /* XR */
801 if (__GF (insn, 6, 4) == 0xc)
802 return MASK_OP (insn, 0x7fff);
803 /* MFCP MTCP */
804 return MASK_OP (insn, 0x3ff);
805 default:
806 return MASK_OP (insn, 0xff);
35c08157
KLC
807 }
808 }
40c7a7cb
KLC
809 else if (__GF (insn, 0, 2) == 0)
810 return MASK_OP (insn, 0xf);
811 return MASK_OP (insn, 0xcf);
812 case N32_OP6_AEXT:
813 /* AUDIO */
814 switch (__GF (insn, 23, 2))
35c08157
KLC
815 {
816 case 0x0:
40c7a7cb
KLC
817 if (__GF (insn, 5, 4) == 0)
818 /* AMxxx AMAyyS AMyyS AMAWzS AMWzS */
819 return MASK_OP (insn, (0x1f << 20) | 0x1ff);
820 else if (__GF (insn, 5, 4) == 1)
821 /* ALR ASR ALA ASA AUPI */
822 return MASK_OP (insn, (0x1f << 20) | (0xf << 5));
823 else if (__GF (insn, 20, 3) == 0 && __GF (insn, 6, 3) == 1)
824 /* ALR2 */
825 return MASK_OP (insn, (0x1f << 20) | (0x7 << 6));
826 else if (__GF (insn, 20 ,3) == 2 && __GF (insn, 6, 3) == 1)
827 /* AWEXT ASATS48 */
828 return MASK_OP (insn, (0x1f << 20) | (0xf << 5));
829 else if (__GF (insn, 20 ,3) == 3 && __GF (insn, 6, 3) == 1)
830 /* AMTAR AMTAR2 AMFAR AMFAR2 */
831 return MASK_OP (insn, (0x1f << 20) | (0x1f << 5));
832 else if (__GF (insn, 7, 2) == 3)
833 /* AMxxxSA */
834 return MASK_OP (insn, (0x1f << 20) | (0x3 << 7));
835 else if (__GF (insn, 6, 3) == 2)
836 /* AMxxxL.S */
837 return MASK_OP (insn, (0x1f << 20) | (0xf << 5));
35c08157 838 else
40c7a7cb
KLC
839 /* AmxxxL.l AmxxxL2.S AMxxxL2.L */
840 return MASK_OP (insn, (0x1f << 20) | (0x7 << 6));
35c08157 841 case 0x1:
40c7a7cb
KLC
842 if (__GF (insn, 20, 3) == 0)
843 /* AADDL ASUBL */
844 return MASK_OP (insn, (0x1f << 20) | (0x1 << 5));
845 else if (__GF (insn, 20, 3) == 1)
846 /* AMTARI Ix AMTARI Mx */
847 return MASK_OP (insn, (0x1f << 20));
848 else if (__GF (insn, 6, 3) == 2)
849 /* AMAWzSl.S AMWzSl.S */
850 return MASK_OP (insn, (0x1f << 20) | (0xf << 5));
851 else if (__GF (insn, 7, 2) == 3)
852 /* AMAWzSSA AMWzSSA */
853 return MASK_OP (insn, (0x1f << 20) | (0x3 << 7));
854 else
fbaf61ad
NC
855 /* AMAWzSL.L AMAWzSL2.S AMAWzSL2.L
856 AMWzSL.L AMWzSL.L AMWzSL2.S */
40c7a7cb
KLC
857 return MASK_OP (insn, (0x1f << 20) | (0x7 << 6));
858 case 0x2:
859 if (__GF (insn, 6, 3) == 2)
860 /* AMAyySl.S AMWyySl.S */
861 return MASK_OP (insn, (0x1f << 20) | (0xf << 5));
862 else if (__GF (insn, 7, 2) == 3)
863 /* AMAWyySSA AMWyySSA */
864 return MASK_OP (insn, (0x1f << 20) | (0x3 << 7));
865 else
fbaf61ad
NC
866 /* AMAWyySL.L AMAWyySL2.S AMAWyySL2.L
867 AMWyySL.L AMWyySL.L AMWyySL2.S */
40c7a7cb 868 return MASK_OP (insn, (0x1f << 20) | (0x7 << 6));
35c08157 869 }
40c7a7cb
KLC
870 return MASK_OP (insn, 0x1f << 20);
871 default:
e46d79a7 872 return 1u << 31;
35c08157
KLC
873 }
874}
875
40c7a7cb
KLC
876/* Define cctl subtype. */
877static char *cctl_subtype [] =
35c08157 878{
40c7a7cb
KLC
879 /* 0x0 */
880 "st0", "st0", "st0", "st2", "st2", "st3", "st3", "st4",
881 "st1", "st1", "st1", "st0", "st0", NULL, NULL, "st5",
882 /* 0x10 */
883 "st0", NULL, NULL, "st2", "st2", "st3", "st3", NULL,
884 "st1", NULL, NULL, "st0", "st0", NULL, NULL, NULL
885};
35c08157 886
40c7a7cb 887/* Check the subset of opcode. */
35c08157 888
40c7a7cb
KLC
889static void
890nds32_special_opcode (uint32_t insn, struct nds32_opcode **opc)
891{
892 char *string = NULL;
893 uint32_t op;
35c08157 894
40c7a7cb
KLC
895 if (!(*opc))
896 return;
35c08157 897
40c7a7cb
KLC
898 /* Check if special case. */
899 switch ((*opc)->value)
900 {
901 case OP6 (LWC):
902 case OP6 (SWC):
903 case OP6 (LDC):
904 case OP6 (SDC):
905 case FPU_RA_IMMBI (LWC):
906 case FPU_RA_IMMBI (SWC):
907 case FPU_RA_IMMBI (LDC):
908 case FPU_RA_IMMBI (SDC):
909 /* Check if cp0 => FPU. */
35c08157 910 if (__GF (insn, 13, 2) == 0)
35c08157 911 {
40c7a7cb
KLC
912 while (!((*opc)->attr & ATTR (FPU)) && (*opc)->next)
913 *opc = (*opc)->next;
35c08157 914 }
40c7a7cb
KLC
915 break;
916 case ALU1 (ADD):
917 case ALU1 (SUB):
918 case ALU1 (AND):
919 case ALU1 (XOR):
920 case ALU1 (OR):
921 /* Check if (add/add_slli) (sub/sub_slli) (and/and_slli). */
922 if (N32_SH5(insn) != 0)
923 string = "sh";
924 break;
925 case ALU1 (SRLI):
926 /* Check if nop. */
927 if (__GF (insn, 10, 15) == 0)
928 string = "nop";
929 break;
930 case MISC (CCTL):
931 string = cctl_subtype [__GF (insn, 5, 5)];
932 break;
933 case JREG (JR):
934 case JREG (JRAL):
935 case JREG (JR) | JREG_RET:
936 if (__GF (insn, 8, 2) != 0)
937 string = "tit";
fbaf61ad 938 break;
40c7a7cb 939 case N32_OP6_COP:
40c7a7cb
KLC
940 break;
941 case 0x9200:
942 /* nop16 */
943 if (__GF (insn, 0, 9) == 0)
944 string = "nop16";
945 break;
946 }
947
948 if (string)
949 {
950 while (strstr ((*opc)->opcode, string) == NULL
951 && strstr ((*opc)->instruction, string) == NULL && (*opc)->next)
952 *opc = (*opc)->next;
35c08157
KLC
953 return;
954 }
40c7a7cb
KLC
955
956 /* Classify instruction is COP or FPU. */
957 op = N32_OP6 (insn);
958 if (op == N32_OP6_COP && __GF (insn, 4, 2) != 0)
959 {
960 while (((*opc)->attr & ATTR (FPU)) != 0 && (*opc)->next)
961 *opc = (*opc)->next;
962 }
35c08157
KLC
963}
964
965int
966print_insn_nds32 (bfd_vma pc, disassemble_info *info)
967{
968 int status;
969 bfd_byte buf[4];
fbaf61ad 970 bfd_byte buf_data[16];
e46d79a7
AM
971 uint64_t given;
972 uint64_t given1;
35c08157 973 uint32_t insn;
fbaf61ad
NC
974 int n;
975 int last_symbol_index = -1;
976 bfd_vma addr;
78933a4a
AM
977 int is_data = false;
978 bool found = false;
fbaf61ad 979 struct nds32_private_data *private_data;
fe90ae8a 980 unsigned int size;
fbaf61ad
NC
981 enum map_type mapping_type = MAP_CODE;
982
983 if (info->private_data == NULL)
984 {
985 /* Note: remain lifecycle throughout whole execution. */
986 static struct nds32_private_data private;
987 private.has_mapping_symbols = -1; /* unknown yet. */
988 private.last_symbol_index = -1;
989 private.last_addr = 0;
990 info->private_data = &private;
991 }
992 private_data = info->private_data;
40c7a7cb 993
fbaf61ad 994 if (info->symtab_size != 0)
40c7a7cb 995 {
fbaf61ad
NC
996 int start;
997 if (pc == 0)
998 start = 0;
999 else
1000 {
1001 start = info->symtab_pos;
1002 if (start < private_data->last_symbol_index)
1003 start = private_data->last_symbol_index;
1004 }
1005
1006 if (0 > start)
1007 start = 0;
35c08157 1008
fbaf61ad
NC
1009 if (private_data->has_mapping_symbols != 0
1010 && ((strncmp (".text", info->section->name, 5) == 0)))
40c7a7cb 1011 {
fbaf61ad 1012 for (n = start; n < info->symtab_size; n++)
40c7a7cb 1013 {
fbaf61ad
NC
1014 addr = bfd_asymbol_value (info->symtab[n]);
1015 if (addr > pc)
1016 break;
1017 if (get_mapping_symbol_type (info, n, &mapping_type))
1018 {
1019 last_symbol_index = n;
78933a4a 1020 found = true;
fbaf61ad 1021 }
40c7a7cb 1022 }
fbaf61ad
NC
1023
1024 if (found)
1025 private_data->has_mapping_symbols = 1;
1026 else if (!found && private_data->has_mapping_symbols == -1)
1027 {
1028 /* Make sure there are no any mapping symbol. */
1029 for (n = 0; n < info->symtab_size; n++)
1030 {
1031 if (is_mapping_symbol (info, n, &mapping_type))
1032 {
1033 private_data->has_mapping_symbols = -1;
1034 break;
1035 }
1036 }
1037 if (private_data->has_mapping_symbols == -1)
1038 private_data->has_mapping_symbols = 0;
1039 }
1040
1041 private_data->last_symbol_index = last_symbol_index;
1042 private_data->last_mapping_type = mapping_type;
1043 is_data = (private_data->last_mapping_type == MAP_DATA0
1044 || private_data->last_mapping_type == MAP_DATA1
1045 || private_data->last_mapping_type == MAP_DATA2
1046 || private_data->last_mapping_type == MAP_DATA3
1047 || private_data->last_mapping_type == MAP_DATA4);
1048 }
1049 }
1050
1051 /* Wonder data or instruction. */
1052 if (is_data)
1053 {
1054 unsigned int i1;
1055
1056 /* Fix corner case: there is no next mapping symbol,
1057 let mapping type decides size */
fe90ae8a 1058 size = 16;
fbaf61ad
NC
1059 if (last_symbol_index + 1 >= info->symtab_size)
1060 {
1061 if (mapping_type == MAP_DATA0)
1062 size = 1;
1063 if (mapping_type == MAP_DATA1)
1064 size = 2;
1065 if (mapping_type == MAP_DATA2)
1066 size = 4;
1067 if (mapping_type == MAP_DATA3)
1068 size = 8;
1069 if (mapping_type == MAP_DATA4)
1070 size = 16;
1071 }
1072 for (n = last_symbol_index + 1; n < info->symtab_size; n++)
1073 {
1074 addr = bfd_asymbol_value (info->symtab[n]);
1075
1076 enum map_type fake_mapping_type;
1077 if (get_mapping_symbol_type (info, n, &fake_mapping_type)
1078 && (addr > pc
1079 && ((info->section == NULL)
1080 || (info->section == info->symtab[n]->section)))
1081 && (addr - pc < size))
1082 {
1083 size = addr - pc;
1084 break;
1085 }
1086 }
1087
1088 if (size == 3)
1089 size = (pc & 1) ? 1 : 2;
1090
1091 /* Read bytes from BFD. */
fe90ae8a 1092 info->read_memory_func (pc, buf_data, size, info);
fbaf61ad
NC
1093 given = 0;
1094 given1 = 0;
1095 /* Start assembling data. */
1096 /* Little endian of data. */
1097 if (info->endian == BFD_ENDIAN_LITTLE)
1098 {
1099 for (i1 = size - 1;; i1--)
40c7a7cb 1100 {
fbaf61ad
NC
1101 if (i1 >= 8)
1102 given1 = buf_data[i1] | (given1 << 8);
1103 else
1104 given = buf_data[i1] | (given << 8);
1105
1106 if (i1 == 0)
1107 break;
40c7a7cb 1108 }
40c7a7cb 1109 }
fbaf61ad
NC
1110 else
1111 {
1112 /* Big endian of data. */
1113 for (i1 = 0; i1 < size; i1++)
1114 {
1115 if (i1 <= 7)
1116 given = buf_data[i1] | (given << 8);
1117 else
1118 given1 = buf_data[i1] | (given1 << 8);
1119 }
1120 }
1121
1122 info->bytes_per_line = 4;
1123
1124 if (size == 16)
e46d79a7 1125 info->fprintf_func (info->stream, ".qword\t0x%016" PRIx64 "%016" PRIx64,
fbaf61ad
NC
1126 given, given1);
1127 else if (size == 8)
e46d79a7 1128 info->fprintf_func (info->stream, ".dword\t0x%016" PRIx64, given);
fbaf61ad 1129 else if (size == 4)
e46d79a7 1130 info->fprintf_func (info->stream, ".word\t0x%08" PRIx64, given);
fbaf61ad
NC
1131 else if (size == 2)
1132 {
1133 /* short */
1134 if (mapping_type == MAP_DATA0)
e46d79a7
AM
1135 info->fprintf_func (info->stream, ".byte\t0x%02" PRIx64,
1136 given & 0xFF);
fbaf61ad 1137 else
e46d79a7 1138 info->fprintf_func (info->stream, ".short\t0x%04" PRIx64, given);
fbaf61ad
NC
1139 }
1140 else
1141 {
1142 /* byte */
e46d79a7 1143 info->fprintf_func (info->stream, ".byte\t0x%02" PRIx64, given);
fbaf61ad
NC
1144 }
1145
1146 return size;
40c7a7cb
KLC
1147 }
1148
fe90ae8a
AM
1149 size = 4;
1150 status = info->read_memory_func (pc, buf, 4, info);
35c08157 1151 if (status)
40c7a7cb 1152 {
fbaf61ad 1153 /* For the last 16-bit instruction. */
fe90ae8a
AM
1154 size = 2;
1155 status = info->read_memory_func (pc, buf, 2, info);
40c7a7cb
KLC
1156 if (status)
1157 {
fe90ae8a 1158 (*info->memory_error_func) (status, pc, info);
40c7a7cb
KLC
1159 return -1;
1160 }
fe90ae8a
AM
1161 buf[2] = 0;
1162 buf[3] = 0;
40c7a7cb 1163 }
35c08157 1164
40c7a7cb 1165 insn = bfd_getb32 (buf);
35c08157 1166 /* 16-bit instruction. */
40c7a7cb 1167 if (insn & 0x80000000)
35c08157 1168 {
40c7a7cb 1169 print_insn16 (pc, info, (insn >> 16), NDS32_PARSE_INSN16);
35c08157
KLC
1170 return 2;
1171 }
1172
1173 /* 32-bit instructions. */
fe90ae8a
AM
1174 if (size == 4)
1175 print_insn32 (pc, info, insn, NDS32_PARSE_INSN32);
40c7a7cb 1176 else
fe90ae8a
AM
1177 info->fprintf_func (info->stream,
1178 _("insufficient data to decode instruction"));
1179 return 4;
35c08157 1180}
fbaf61ad
NC
1181
1182/* Ignore disassembling unnecessary name. */
1183
78933a4a 1184static bool
fbaf61ad
NC
1185nds32_symbol_is_valid (asymbol *sym,
1186 struct disassemble_info *info ATTRIBUTE_UNUSED)
1187{
1188 const char *name;
1189
1190 if (sym == NULL)
78933a4a 1191 return false;
fbaf61ad
NC
1192
1193 name = bfd_asymbol_name (sym);
1194
1195 /* Mapping symbol is invalid. */
1196 if (name[0] == '$')
78933a4a
AM
1197 return false;
1198 return true;
fbaf61ad
NC
1199}
1200
1201static void
1202nds32_add_opcode_hash_table (unsigned indx)
1203{
1204 opcode_t *opc;
1205
1206 opc = nds32_opcode_table[indx];
1207 if (opc == NULL)
1208 return;
1209
1210 while (opc->opcode != NULL)
1211 {
1212 opcode_t **slot;
1213
1214 slot = (opcode_t **) htab_find_slot
1215 (opcode_htab, &opc->value, INSERT);
1216 if (*slot == NULL)
1217 {
1218 /* This is the new one. */
1219 *slot = opc;
1220 }
1221 else
1222 {
1223 opcode_t *tmp;
1224
1225 /* Already exists. Append to the list. */
1226 tmp = *slot;
1227 while (tmp->next)
1228 tmp = tmp->next;
1229 tmp->next = opc;
1230 opc->next = NULL;
1231 }
1232 opc++;
1233 }
1234}
1235
1236void
1237disassemble_init_nds32 (struct disassemble_info *info)
1238{
1239 static unsigned init_done = 0;
1240 unsigned k;
1241
1242 /* Set up symbol checking function. */
1243 info->symbol_is_valid = nds32_symbol_is_valid;
1244
1245 /* Only need to initialize once:
1246 High level will call this function for every object file.
1247 For example, when disassemble all members of a library. */
1248 if (init_done)
1249 return;
1250
1251 /* Setup main core. */
9b2beaf7 1252 nds32_keyword_table[NDS32_MAIN_CORE] = &nds32_keywords[0];
fbaf61ad 1253 nds32_opcode_table[NDS32_MAIN_CORE] = &nds32_opcodes[0];
9b2beaf7 1254 nds32_field_table[NDS32_MAIN_CORE] = &nds32_operand_fields[0];
fbaf61ad
NC
1255
1256 /* Build opcode table. */
1257 opcode_htab = htab_create_alloc (1024, htab_hash_hash, htab_hash_eq,
1258 NULL, xcalloc, free);
1259
1260 for (k = 0; k < NDS32_CORE_COUNT; k++)
1261 {
1262 /* Add op-codes. */
1263 nds32_add_opcode_hash_table (k);
1264 }
1265
1266 init_done = 1;
1267}
1268
1269static int
1270is_mapping_symbol (struct disassemble_info *info, int n,
1271 enum map_type *map_type)
1272{
1273 const char *name = NULL;
1274
1275 /* Get symbol name. */
1276 name = bfd_asymbol_name (info->symtab[n]);
1277
1278 if (name[1] == 'c')
1279 {
1280 *map_type = MAP_CODE;
78933a4a 1281 return true;
fbaf61ad
NC
1282 }
1283 else if (name[1] == 'd' && name[2] == '0')
1284 {
1285 *map_type = MAP_DATA0;
78933a4a 1286 return true;
fbaf61ad
NC
1287 }
1288 else if (name[1] == 'd' && name[2] == '1')
1289 {
1290 *map_type = MAP_DATA1;
78933a4a 1291 return true;
fbaf61ad
NC
1292 }
1293 else if (name[1] == 'd' && name[2] == '2')
1294 {
1295 *map_type = MAP_DATA2;
78933a4a 1296 return true;
fbaf61ad
NC
1297 }
1298 else if (name[1] == 'd' && name[2] == '3')
1299 {
1300 *map_type = MAP_DATA3;
78933a4a 1301 return true;
fbaf61ad
NC
1302 }
1303 else if (name[1] == 'd' && name[2] == '4')
1304 {
1305 *map_type = MAP_DATA4;
78933a4a 1306 return true;
fbaf61ad
NC
1307 }
1308
78933a4a 1309 return false;
fbaf61ad
NC
1310}
1311
1312static int
1313get_mapping_symbol_type (struct disassemble_info *info, int n,
1314 enum map_type *map_type)
1315{
1316 /* If the symbol is in a different section, ignore it. */
1317 if (info->section != NULL
1318 && info->section != info->symtab[n]->section)
78933a4a 1319 return false;
fbaf61ad
NC
1320
1321 return is_mapping_symbol (info, n, map_type);
1322}
This page took 0.461882 seconds and 4 git commands to generate.