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