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