1 /* NDS32-specific support for 32-bit ELF.
2    Copyright (C) 2012-2020 Free Software Foundation, Inc.
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
20    02110-1301, USA.  */
21 
22 #include "sysdep.h"
23 #include <stdio.h>
24 #include "ansidecl.h"
25 #include "disassemble.h"
26 #include "bfd.h"
27 #include "symcat.h"
28 #include "libiberty.h"
29 #include "opintl.h"
30 #include "bfd_stdint.h"
31 #include "hashtab.h"
32 #include "nds32-asm.h"
33 #include "opcode/nds32.h"
34 
35 /* Get fields macro define.  */
36 #define MASK_OP(insn, mask)	((insn) & (0x3f << 25 | (mask)))
37 
38 /* For mapping symbol.  */
39 enum map_type
40 {
41   MAP_DATA0,
42   MAP_DATA1,
43   MAP_DATA2,
44   MAP_DATA3,
45   MAP_DATA4,
46   MAP_CODE,
47 };
48 
49 struct 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 
63 /* Default text to print if an instruction isn't recognized.  */
64 #define UNKNOWN_INSN_MSG _("*unknown*")
65 #define NDS32_PARSE_INSN16      0x01
66 #define NDS32_PARSE_INSN32      0x02
67 
68 extern const field_t *nds32_field_table[NDS32_CORE_COUNT];
69 extern opcode_t *nds32_opcode_table[NDS32_CORE_COUNT];
70 extern keyword_t **nds32_keyword_table[NDS32_CORE_COUNT];
71 extern struct nds32_opcode nds32_opcodes[];
72 extern const field_t operand_fields[];
73 extern keyword_t *keywords[];
74 extern const keyword_t keyword_gpr[];
75 
76 static uint32_t nds32_mask_opcode (uint32_t);
77 static void nds32_special_opcode (uint32_t, struct nds32_opcode **);
78 static int get_mapping_symbol_type (struct disassemble_info *, int,
79 				    enum map_type *);
80 static int is_mapping_symbol (struct disassemble_info *, int,
81 			      enum map_type *);
82 
83 /* Hash function for disassemble.  */
84 
85 static htab_t opcode_htab;
86 
87 /* Find the value map register name.  */
88 
89 static keyword_t *
nds32_find_reg_keyword(keyword_t * reg,int value)90 nds32_find_reg_keyword (keyword_t *reg, int value)
91 {
92   if (!reg)
93     return NULL;
94 
95   while (reg->name != NULL && reg->value != value)
96     {
97       reg++;
98     }
99   if (reg->name == NULL)
100     return NULL;
101   return reg;
102 }
103 
104 static void
nds32_parse_audio_ext(const field_t * pfd,disassemble_info * info,uint32_t insn)105 nds32_parse_audio_ext (const field_t *pfd,
106 		       disassemble_info *info, uint32_t insn)
107 {
108   fprintf_ftype func = info->fprintf_func;
109   void *stream = info->stream;
110   keyword_t *psys_reg;
111   int int_value, new_value;
112 
113   if (pfd->hw_res == HW_INT || pfd->hw_res == HW_UINT)
114     {
115       if (pfd->hw_res == HW_INT)
116 	int_value = (unsigned) N32_IMMS (insn >> pfd->bitpos,
117 					 pfd->bitsize) << pfd->shift;
118       else
119 	int_value = __GF (insn, pfd->bitpos, pfd->bitsize) << pfd->shift;
120 
121       if (int_value < 10)
122 	func (stream, "#%d", int_value);
123       else
124 	func (stream, "#0x%x", int_value);
125       return;
126     }
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];
131 
132   /* p = bit[4].bit[1:0], r = bit[4].bit[3:2].  */
133   if (strcmp (pfd->name, "im5_i") == 0)
134     {
135       new_value = int_value & 0x03;
136       new_value |= ((int_value & 0x10) >> 2);
137     }
138   else if (strcmp (pfd->name, "im5_m") == 0)
139     {
140       new_value = ((int_value & 0x1C) >> 2);
141     }
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)
145     {
146       new_value |= 0x04;
147     }
148   else if (strcmp (pfd->name, "im6_ms") == 0)
149     {
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;
169     }
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);
185 }
186 
187 /* Match instruction opcode with keyword table.  */
188 
189 static field_t *
match_field(char * name)190 match_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 
211 /* Dump instruction.  If the opcode is unknown, return FALSE.  */
212 
213 static void
nds32_parse_opcode(struct nds32_opcode * opc,bfd_vma pc ATTRIBUTE_UNUSED,disassemble_info * info,uint32_t insn,uint32_t parse_mode)214 nds32_parse_opcode (struct nds32_opcode *opc, bfd_vma pc ATTRIBUTE_UNUSED,
215 		    disassemble_info *info, uint32_t insn,
216 		    uint32_t parse_mode)
217 {
218   int op = 0;
219   fprintf_ftype func = info->fprintf_func;
220   void *stream = info->stream;
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)
230     {
231       func (stream, UNKNOWN_INSN_MSG);
232       return;
233     }
234 
235   pstr_src = opc->instruction;
236   if (*pstr_src == 0)
237     {
238       func (stream, "%s", opc->opcode);
239       return;
240     }
241   /* NDS32_PARSE_INSN16.  */
242   if (parse_mode & NDS32_PARSE_INSN16)
243     {
244       func (stream, "%s ", opc->opcode);
245     }
246 
247   /* NDS32_PARSE_INSN32.  */
248   else
249     {
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
256 	func (stream, "%s\t", opc->opcode);
257     }
258 
259   while (*pstr_src)
260     {
261       switch (*pstr_src)
262 	{
263 	case '%':
264 	case '=':
265 	case '&':
266 	  pstr_src++;
267 	  /* Compare with operand_fields[].name.  */
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;
280 
281 	  if ((pfd = match_field (&tmp_string[0])) == NULL)
282 	    return;
283 
284 	  /* For insn-16.  */
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)
309 		    int_value
310 		      = (unsigned) N32_IMMS (insn >> pfd->bitpos,
311 					     pfd->bitsize) << pfd->shift;
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 		    }
328 		  /* beqz38/bnez38/beqs38/bnes38/j8/beqzs8/bnezs8.  */
329 		  else if ((opc->value == 0xc000) || (opc->value == 0xc800)
330 			   || (opc->value == 0xd000) || (opc->value == 0xd800)
331 			   || (opc->value == 0xd500) || (opc->value == 0xe800)
332 			   || (opc->value == 0xe900))
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 		    }
344 		  else if (pfd->hw_res == HW_INT)
345 		    {
346 		      if (int_value < 10)
347 			func (stream, "#%d", int_value);
348 		      else
349 			func (stream, "#0x%x", int_value);
350 		    }
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 		    }
358 		}
359 
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.  */
367 	  else if (pfd->hw_res < HW_INT)
368 	    {
369 	      int_value =
370 		__GF (insn, pfd->bitpos, pfd->bitsize) << pfd->shift;
371 
372 	      psys_reg = *(nds32_keyword_table[pfd->hw_res >> 8]
373 			   + (pfd->hw_res & 0xff));
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)
399 		int_value = (unsigned) N32_IMMS (insn >> pfd->bitpos,
400 						 pfd->bitsize) << pfd->shift;
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;
418 		  info->print_address_func (int_value + pc, info);
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 		{
462 		  if (int_value < 10)
463 		    func (stream, "#%d", int_value);
464 		  else
465 		    func (stream, "#0x%x", int_value);
466 		}
467 	      else /* if (pfd->hw_res == HW_UINT).  */
468 		{
469 		  if (int_value < 10)
470 		    func (stream, "#%u", int_value);
471 		  else
472 		    func (stream, "#0x%x", int_value);
473 		}
474 	    }
475 	  break;
476 
477 	case '{':
478 	case '}':
479 	  pstr_src++;
480 	  break;
481 
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 
505 	default:
506 	  func (stream, "%c", *pstr_src++);
507 	  break;
508 	}
509     }
510 }
511 
512 /* Filter instructions with some bits must be fixed.  */
513 
514 static void
nds32_filter_unknown_insn(uint32_t insn,struct nds32_opcode ** opc)515 nds32_filter_unknown_insn (uint32_t insn, struct nds32_opcode **opc)
516 {
517   if (!(*opc))
518     return;
519 
520   switch ((*opc)->value)
521     {
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;
527       break;
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;
537     case BR2 (SOP0):
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;
572       break;
573     }
574 }
575 
576 static void
print_insn32(bfd_vma pc,disassemble_info * info,uint32_t insn,uint32_t parse_mode)577 print_insn32 (bfd_vma pc, disassemble_info *info, uint32_t insn,
578 	      uint32_t parse_mode)
579 {
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);
588 }
589 
590 static void
print_insn16(bfd_vma pc,disassemble_info * info,uint32_t insn,uint32_t parse_mode)591 print_insn16 (bfd_vma pc, disassemble_info *info,
592 	      uint32_t insn, uint32_t parse_mode)
593 {
594   struct nds32_opcode *opc;
595   uint32_t opcode;
596 
597   /* Get highest 7 bit in default.  */
598   unsigned int mask = 0xfe00;
599 
600   /* Classify 16-bit instruction to 4 sets by bit 13 and 14.  */
601   switch (__GF (insn, 13, 2))
602     {
603     case 0x0:
604       /* mov55 movi55 */
605       if (__GF (insn, 11, 2) == 0)
606 	{
607 	  mask = 0xfc00;
608 	  /* ifret16 = mov55 $sp, $sp*/
609 	  if (__GF (insn, 0, 11) == 0x3ff)
610 	    mask = 0xffff;
611 	}
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)
625 	{
626 	  if (__GF (insn, 11, 1) == 0x0)
627 	    mask = 0xff00;
628 	  else
629 	    mask = 0xffe0;
630 	}
631       break;
632     case 0x3:
633       switch (__GF (insn, 11, 2))
634 	{
635 	case 0x1:
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;
643 	case 0x2:
644 	  /* lwi37.sp swi37.sp */
645 	  mask = 0xf880;
646 	  break;
647 	case 0x3:
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 
666 static hashval_t
htab_hash_hash(const void * p)667 htab_hash_hash (const void *p)
668 {
669   return (*(unsigned int *) p) % 49;
670 }
671 
672 static int
htab_hash_eq(const void * p,const void * q)673 htab_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.  */
682 
683 static uint32_t
nds32_mask_opcode(uint32_t insn)684 nds32_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 */
725       if (__GF (insn, 0, 7) == (N32_ALU2_FFBI | N32_BIT (6)))
726 	return MASK_OP (insn, 0x7f);
727       else if (__GF (insn, 0, 7) == (N32_ALU2_MFUSR | N32_BIT (6))
728 	       || __GF (insn, 0, 7) == (N32_ALU2_MTUSR | N32_BIT (6)))
729 	/* RDOV CLROV */
730 	return MASK_OP (insn, 0xf81ff);
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);
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:
767       if (__GF (insn, 16, 4) == 0)
768 	return MASK_OP (insn, 0x1ff << 16);
769       else
770 	return MASK_OP (insn, 0xf << 16);
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))
794 	    {
795 	    case 0x0:
796 	    case 0x8:
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:
803 	    case 0xc:
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);
815 	    }
816 	}
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))
823 	{
824 	case 0x0:
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));
846 	  else
847 	    /* AmxxxL.l AmxxxL2.S AMxxxL2.L  */
848 	    return MASK_OP (insn, (0x1f << 20) | (0x7 << 6));
849 	case 0x1:
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
863 	    /* AMAWzSL.L AMAWzSL2.S AMAWzSL2.L
864 	       AMWzSL.L AMWzSL.L AMWzSL2.S */
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
874 	    /* AMAWyySL.L AMAWyySL2.S AMAWyySL2.L
875 	       AMWyySL.L AMWyySL.L AMWyySL2.S */
876 	    return MASK_OP (insn, (0x1f << 20) | (0x7 << 6));
877 	}
878       return MASK_OP (insn, 0x1f << 20);
879     default:
880       return 1u << 31;
881     }
882 }
883 
884 /* Define cctl subtype.  */
885 static char *cctl_subtype [] =
886 {
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 };
894 
895 /* Check the subset of opcode.  */
896 
897 static void
nds32_special_opcode(uint32_t insn,struct nds32_opcode ** opc)898 nds32_special_opcode (uint32_t insn, struct nds32_opcode **opc)
899 {
900   char *string = NULL;
901   uint32_t op;
902 
903   if (!(*opc))
904     return;
905 
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.  */
918       if (__GF (insn, 13, 2) == 0)
919       {
920 	while (!((*opc)->attr & ATTR (FPU)) && (*opc)->next)
921 	  *opc = (*opc)->next;
922       }
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";
946       break;
947     case N32_OP6_COP:
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;
961       return;
962     }
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     }
971 }
972 
973 int
print_insn_nds32(bfd_vma pc,disassemble_info * info)974 print_insn_nds32 (bfd_vma pc, disassemble_info *info)
975 {
976   int status;
977   bfd_byte buf[4];
978   bfd_byte buf_data[16];
979   uint64_t given;
980   uint64_t given1;
981   uint32_t insn;
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;
988   unsigned int size = 16;
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;
1001 
1002   if (info->symtab_size != 0)
1003     {
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;
1016 
1017       if (private_data->has_mapping_symbols != 0
1018 	  && ((strncmp (".text", info->section->name, 5) == 0)))
1019 	{
1020 	  for (n = start; n < info->symtab_size; n++)
1021 	    {
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 		}
1030 	    }
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 */
1066       if (last_symbol_index + 1 >= info->symtab_size)
1067 	{
1068 	  if (mapping_type == MAP_DATA0)
1069 	    size = 1;
1070 	  if (mapping_type == MAP_DATA1)
1071 	    size = 2;
1072 	  if (mapping_type == MAP_DATA2)
1073 	    size = 4;
1074 	  if (mapping_type == MAP_DATA3)
1075 	    size = 8;
1076 	  if (mapping_type == MAP_DATA4)
1077 	    size = 16;
1078 	}
1079       for (n = last_symbol_index + 1; n < info->symtab_size; n++)
1080 	{
1081 	  addr = bfd_asymbol_value (info->symtab[n]);
1082 
1083 	  enum map_type fake_mapping_type;
1084 	  if (get_mapping_symbol_type (info, n, &fake_mapping_type)
1085 	      && (addr > pc
1086 		  && ((info->section == NULL)
1087 		      || (info->section == info->symtab[n]->section)))
1088 	      && (addr - pc < size))
1089 	    {
1090 	      size = addr - pc;
1091 	      break;
1092 	    }
1093 	}
1094 
1095       if (size == 3)
1096 	size = (pc & 1) ? 1 : 2;
1097 
1098       /* Read bytes from BFD.  */
1099       info->read_memory_func (pc, (bfd_byte *) buf_data, size, info);
1100       given = 0;
1101       given1 = 0;
1102       /* Start assembling data.  */
1103       /* Little endian of data.  */
1104       if (info->endian == BFD_ENDIAN_LITTLE)
1105 	{
1106 	  for (i1 = size - 1;; i1--)
1107 	    {
1108 	      if (i1 >= 8)
1109 		given1 = buf_data[i1] | (given1 << 8);
1110 	      else
1111 		given = buf_data[i1] | (given << 8);
1112 
1113 	      if (i1 == 0)
1114 		break;
1115 	    }
1116 	}
1117       else
1118 	{
1119 	  /* Big endian of data.  */
1120 	  for (i1 = 0; i1 < size; i1++)
1121 	    {
1122 	      if (i1 <= 7)
1123 		given = buf_data[i1] | (given << 8);
1124 	      else
1125 		given1 = buf_data[i1] | (given1 << 8);
1126 	    }
1127 	}
1128 
1129       info->bytes_per_line = 4;
1130 
1131       if (size == 16)
1132 	info->fprintf_func (info->stream, ".qword\t0x%016" PRIx64 "%016" PRIx64,
1133 			    given, given1);
1134       else if (size == 8)
1135 	info->fprintf_func (info->stream, ".dword\t0x%016" PRIx64, given);
1136       else if (size == 4)
1137 	info->fprintf_func (info->stream, ".word\t0x%08" PRIx64, given);
1138       else if (size == 2)
1139 	{
1140 	  /* short */
1141 	  if (mapping_type == MAP_DATA0)
1142 	    info->fprintf_func (info->stream, ".byte\t0x%02" PRIx64,
1143 				given & 0xFF);
1144 	  else
1145 	    info->fprintf_func (info->stream, ".short\t0x%04" PRIx64, given);
1146 	}
1147       else
1148 	{
1149 	  /* byte */
1150 	  info->fprintf_func (info->stream, ".byte\t0x%02" PRIx64, given);
1151 	}
1152 
1153       return size;
1154     }
1155 
1156   status = info->read_memory_func (pc, (bfd_byte *) buf, 4, info);
1157   if (status)
1158     {
1159       /* For the last 16-bit instruction.  */
1160       status = info->read_memory_func (pc, (bfd_byte *) buf, 2, info);
1161       if (status)
1162 	{
1163 	  (*info->memory_error_func)(status, pc, info);
1164 	  return -1;
1165 	}
1166     }
1167 
1168   insn = bfd_getb32 (buf);
1169   /* 16-bit instruction.  */
1170   if (insn & 0x80000000)
1171     {
1172       print_insn16 (pc, info, (insn >> 16), NDS32_PARSE_INSN16);
1173       return 2;
1174     }
1175 
1176   /* 32-bit instructions.  */
1177   else
1178     {
1179       print_insn32 (pc, info, insn, NDS32_PARSE_INSN32);
1180       return 4;
1181     }
1182 }
1183 
1184 /* Ignore disassembling unnecessary name.  */
1185 
1186 static bfd_boolean
nds32_symbol_is_valid(asymbol * sym,struct disassemble_info * info ATTRIBUTE_UNUSED)1187 nds32_symbol_is_valid (asymbol *sym,
1188 		       struct disassemble_info *info ATTRIBUTE_UNUSED)
1189 {
1190   const char *name;
1191 
1192   if (sym == NULL)
1193     return FALSE;
1194 
1195   name = bfd_asymbol_name (sym);
1196 
1197   /* Mapping symbol is invalid.  */
1198   if (name[0] == '$')
1199     return FALSE;
1200   return TRUE;
1201 }
1202 
1203 static void
nds32_add_opcode_hash_table(unsigned indx)1204 nds32_add_opcode_hash_table (unsigned indx)
1205 {
1206   opcode_t *opc;
1207 
1208   opc = nds32_opcode_table[indx];
1209   if (opc == NULL)
1210     return;
1211 
1212   while (opc->opcode != NULL)
1213     {
1214       opcode_t **slot;
1215 
1216       slot = (opcode_t **) htab_find_slot
1217 	(opcode_htab, &opc->value, INSERT);
1218       if (*slot == NULL)
1219 	{
1220 	  /* This is the new one.  */
1221 	  *slot = opc;
1222 	}
1223       else
1224 	{
1225 	  opcode_t *tmp;
1226 
1227 	  /* Already exists.  Append to the list.  */
1228 	  tmp = *slot;
1229 	  while (tmp->next)
1230 	    tmp = tmp->next;
1231 	  tmp->next = opc;
1232 	  opc->next = NULL;
1233 	}
1234       opc++;
1235     }
1236 }
1237 
1238 void
disassemble_init_nds32(struct disassemble_info * info)1239 disassemble_init_nds32 (struct disassemble_info *info)
1240 {
1241   static unsigned init_done = 0;
1242   unsigned k;
1243 
1244   /* Set up symbol checking function.  */
1245   info->symbol_is_valid = nds32_symbol_is_valid;
1246 
1247   /* Only need to initialize once:
1248      High level will call this function for every object file.
1249      For example, when disassemble all members of a library.  */
1250   if (init_done)
1251     return;
1252 
1253   /* Setup main core.  */
1254   nds32_keyword_table[NDS32_MAIN_CORE] = &keywords[0];
1255   nds32_opcode_table[NDS32_MAIN_CORE] = &nds32_opcodes[0];
1256   nds32_field_table[NDS32_MAIN_CORE] = &operand_fields[0];
1257 
1258   /* Build opcode table.  */
1259   opcode_htab = htab_create_alloc (1024, htab_hash_hash, htab_hash_eq,
1260 				   NULL, xcalloc, free);
1261 
1262   for (k = 0; k < NDS32_CORE_COUNT; k++)
1263     {
1264       /* Add op-codes.  */
1265       nds32_add_opcode_hash_table (k);
1266     }
1267 
1268   init_done = 1;
1269 }
1270 
1271 static int
is_mapping_symbol(struct disassemble_info * info,int n,enum map_type * map_type)1272 is_mapping_symbol (struct disassemble_info *info, int n,
1273 		   enum map_type *map_type)
1274 {
1275   const char *name = NULL;
1276 
1277   /* Get symbol name.  */
1278   name = bfd_asymbol_name (info->symtab[n]);
1279 
1280   if (name[1] == 'c')
1281     {
1282       *map_type = MAP_CODE;
1283       return TRUE;
1284     }
1285   else if (name[1] == 'd' && name[2] == '0')
1286     {
1287       *map_type = MAP_DATA0;
1288       return TRUE;
1289     }
1290   else if (name[1] == 'd' && name[2] == '1')
1291     {
1292       *map_type = MAP_DATA1;
1293       return TRUE;
1294     }
1295   else if (name[1] == 'd' && name[2] == '2')
1296     {
1297       *map_type = MAP_DATA2;
1298       return TRUE;
1299     }
1300   else if (name[1] == 'd' && name[2] == '3')
1301     {
1302       *map_type = MAP_DATA3;
1303       return TRUE;
1304     }
1305   else if (name[1] == 'd' && name[2] == '4')
1306     {
1307       *map_type = MAP_DATA4;
1308       return TRUE;
1309     }
1310 
1311   return FALSE;
1312 }
1313 
1314 static int
get_mapping_symbol_type(struct disassemble_info * info,int n,enum map_type * map_type)1315 get_mapping_symbol_type (struct disassemble_info *info, int n,
1316 			 enum map_type *map_type)
1317 {
1318   /* If the symbol is in a different section, ignore it.  */
1319   if (info->section != NULL
1320       && info->section != info->symtab[n]->section)
1321     return FALSE;
1322 
1323   return is_mapping_symbol (info, n, map_type);
1324 }
1325