+
+/* Ignore disassembling unnecessary name. */
+
+static bfd_boolean
+nds32_symbol_is_valid (asymbol *sym,
+ struct disassemble_info *info ATTRIBUTE_UNUSED)
+{
+ const char *name;
+
+ if (sym == NULL)
+ return FALSE;
+
+ name = bfd_asymbol_name (sym);
+
+ /* Mapping symbol is invalid. */
+ if (name[0] == '$')
+ return FALSE;
+ return TRUE;
+}
+
+static void
+nds32_add_opcode_hash_table (unsigned indx)
+{
+ opcode_t *opc;
+
+ opc = nds32_opcode_table[indx];
+ if (opc == NULL)
+ return;
+
+ while (opc->opcode != NULL)
+ {
+ opcode_t **slot;
+
+ slot = (opcode_t **) htab_find_slot
+ (opcode_htab, &opc->value, INSERT);
+ if (*slot == NULL)
+ {
+ /* This is the new one. */
+ *slot = opc;
+ }
+ else
+ {
+ opcode_t *tmp;
+
+ /* Already exists. Append to the list. */
+ tmp = *slot;
+ while (tmp->next)
+ tmp = tmp->next;
+ tmp->next = opc;
+ opc->next = NULL;
+ }
+ opc++;
+ }
+}
+
+void
+disassemble_init_nds32 (struct disassemble_info *info)
+{
+ static unsigned init_done = 0;
+ unsigned k;
+
+ /* Set up symbol checking function. */
+ info->symbol_is_valid = nds32_symbol_is_valid;
+
+ /* Only need to initialize once:
+ High level will call this function for every object file.
+ For example, when disassemble all members of a library. */
+ if (init_done)
+ return;
+
+ /* Setup main core. */
+ nds32_keyword_table[NDS32_MAIN_CORE] = &keywords[0];
+ nds32_opcode_table[NDS32_MAIN_CORE] = &nds32_opcodes[0];
+ nds32_field_table[NDS32_MAIN_CORE] = &operand_fields[0];
+
+ /* Build opcode table. */
+ opcode_htab = htab_create_alloc (1024, htab_hash_hash, htab_hash_eq,
+ NULL, xcalloc, free);
+
+ for (k = 0; k < NDS32_CORE_COUNT; k++)
+ {
+ /* Add op-codes. */
+ nds32_add_opcode_hash_table (k);
+ }
+
+ init_done = 1;
+}
+
+static int
+is_mapping_symbol (struct disassemble_info *info, int n,
+ enum map_type *map_type)
+{
+ const char *name = NULL;
+
+ /* Get symbol name. */
+ name = bfd_asymbol_name (info->symtab[n]);
+
+ if (name[1] == 'c')
+ {
+ *map_type = MAP_CODE;
+ return TRUE;
+ }
+ else if (name[1] == 'd' && name[2] == '0')
+ {
+ *map_type = MAP_DATA0;
+ return TRUE;
+ }
+ else if (name[1] == 'd' && name[2] == '1')
+ {
+ *map_type = MAP_DATA1;
+ return TRUE;
+ }
+ else if (name[1] == 'd' && name[2] == '2')
+ {
+ *map_type = MAP_DATA2;
+ return TRUE;
+ }
+ else if (name[1] == 'd' && name[2] == '3')
+ {
+ *map_type = MAP_DATA3;
+ return TRUE;
+ }
+ else if (name[1] == 'd' && name[2] == '4')
+ {
+ *map_type = MAP_DATA4;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static int
+get_mapping_symbol_type (struct disassemble_info *info, int n,
+ enum map_type *map_type)
+{
+ /* If the symbol is in a different section, ignore it. */
+ if (info->section != NULL
+ && info->section != info->symtab[n]->section)
+ return FALSE;
+
+ return is_mapping_symbol (info, n, map_type);
+}