1 /* NDS32-specific support for 32-bit ELF.
2 Copyright (C) 2012-2015 Free Software Foundation, Inc.
3 Contributed by Andes Technology Corporation.
5 This file is part of BFD, the Binary File Descriptor library.
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.
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.
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
28 #include "libiberty.h"
30 #include "bfd_stdint.h"
32 #include "nds32-asm.h"
33 #include "opcode/nds32.h"
35 /* Get fields macro define. */
36 #define MASK_OP(insn, mask) ((insn) & (0x3f << 25 | (mask)))
38 /* Default text to print if an instruction isn't recognized. */
39 #define UNKNOWN_INSN_MSG _("*unknown*")
40 #define NDS32_PARSE_INSN16 0x01
41 #define NDS32_PARSE_INSN32 0x02
42 #define NDS32_PARSE_EX9IT 0x04
43 #define NDS32_PARSE_EX9TAB 0x08
45 extern struct nds32_opcode nds32_opcodes
[];
46 extern const field_t operand_fields
[];
47 extern const keyword_t
*keywords
[];
48 extern const keyword_t keyword_gpr
[];
49 static void print_insn16 (bfd_vma pc
, disassemble_info
*info
,
50 uint32_t insn
, uint32_t parse_mode
);
51 static void print_insn32 (bfd_vma pc
, disassemble_info
*info
, uint32_t insn
,
53 static uint32_t nds32_mask_opcode (uint32_t);
54 static void nds32_special_opcode (uint32_t, struct nds32_opcode
**);
56 /* define in objdump.c. */
57 struct objdump_disasm_info
61 bfd_boolean require_sec
;
64 disassembler_ftype disassemble_fn
;
68 /* file_ptr ex9_filepos=NULL;. */
69 bfd_byte
*ex9_data
= NULL
;
70 int ex9_ready
= 0, ex9_base_offset
= 0;
72 /* Hash function for disassemble. */
74 static htab_t opcode_htab
;
77 nds32_ex9_info (bfd_vma pc ATTRIBUTE_UNUSED
,
78 disassemble_info
*info
, uint32_t ex9_index
)
81 static asymbol
*itb
= NULL
;
83 long unsigned int isec_vma
;
85 /* Lookup itb symbol. */
90 for (i
= 0; i
< info
->symtab_size
; i
++)
91 if (bfd_asymbol_name (info
->symtab
[i
])
92 && (strcmp (bfd_asymbol_name (info
->symtab
[i
]), "$_ITB_BASE_") == 0
93 || strcmp (bfd_asymbol_name (info
->symtab
[i
]),
96 itb
= info
->symtab
[i
];
100 /* Lookup it only once, in case _ITB_BASE_ doesn't exist at all. */
105 if (itb
== (void *) -1)
108 isec_vma
= itb
->section
->vma
;
109 isec_vma
= itb
->section
->vma
- bfd_asymbol_value (itb
);
110 if (!itb
->section
|| !itb
->section
->owner
)
112 bfd_get_section_contents (itb
->section
->owner
, itb
->section
, buffer
,
113 ex9_index
* 4 - isec_vma
, 4);
114 insn
= bfd_getb32 (buffer
);
115 /* 16-bit instructions in ex9 table. */
116 if (insn
& 0x80000000)
117 print_insn16 (pc
, info
, (insn
& 0x0000FFFF),
118 NDS32_PARSE_INSN16
| NDS32_PARSE_EX9IT
);
119 /* 32-bit instructions in ex9 table. */
121 print_insn32 (pc
, info
, insn
, NDS32_PARSE_INSN32
| NDS32_PARSE_EX9IT
);
124 /* Find the value map register name. */
127 nds32_find_reg_keyword (keyword_t
*reg
, int value
)
132 while (reg
->name
!= NULL
&& reg
->value
!= value
)
136 if (reg
->name
== NULL
)
142 nds32_parse_audio_ext (const field_t
*pfd
,
143 disassemble_info
*info
, uint32_t insn
)
145 fprintf_ftype func
= info
->fprintf_func
;
146 void *stream
= info
->stream
;
148 int int_value
, new_value
;
150 if (pfd
->hw_res
== HW_INT
|| pfd
->hw_res
== HW_UINT
)
152 if (pfd
->hw_res
== HW_INT
)
154 N32_IMMS ((insn
>> pfd
->bitpos
), pfd
->bitsize
) << pfd
->shift
;
156 int_value
= __GF (insn
, pfd
->bitpos
, pfd
->bitsize
) << pfd
->shift
;
159 func (stream
, "#%d", int_value
);
161 func (stream
, "#0x%x", int_value
);
165 __GF (insn
, pfd
->bitpos
, pfd
->bitsize
) << pfd
->shift
;
166 new_value
= int_value
;
167 psys_reg
= (keyword_t
*) keywords
[pfd
->hw_res
];
169 /* p = bit[4].bit[1:0], r = bit[4].bit[3:2]. */
170 if (strcmp (pfd
->name
, "im5_i") == 0)
172 new_value
= int_value
& 0x03;
173 new_value
|= ((int_value
& 0x10) >> 2);
175 else if (strcmp (pfd
->name
, "im5_m") == 0)
177 new_value
= ((int_value
& 0x1C) >> 2);
179 /* p = 0.bit[1:0], r = 0.bit[3:2]. */
180 /* q = 1.bit[1:0], s = 1.bit[5:4]. */
181 else if (strcmp (pfd
->name
, "im6_iq") == 0)
185 else if (strcmp (pfd
->name
, "im6_ms") == 0)
189 /* Rt CONCAT(c, t21, t0). */
190 else if (strcmp (pfd
->name
, "a_rt21") == 0)
192 new_value
= (insn
& 0x00000020) >> 5;
193 new_value
|= (insn
& 0x00000C00) >> 9;
194 new_value
|= (insn
& 0x00008000) >> 12;
196 else if (strcmp (pfd
->name
, "a_rte") == 0)
198 new_value
= (insn
& 0x00000C00) >> 9;
199 new_value
|= (insn
& 0x00008000) >> 12;
201 else if (strcmp (pfd
->name
, "a_rte1") == 0)
203 new_value
= (insn
& 0x00000C00) >> 9;
204 new_value
|= (insn
& 0x00008000) >> 12;
207 else if (strcmp (pfd
->name
, "a_rte69") == 0)
209 new_value
= int_value
<< 1;
211 else if (strcmp (pfd
->name
, "a_rte69_1") == 0)
213 new_value
= int_value
<< 1;
217 psys_reg
= nds32_find_reg_keyword (psys_reg
, new_value
);
219 func (stream
, "???");
221 func (stream
, "$%s", psys_reg
->name
);
224 /* Dump instruction. If the opcode is unknown, return FALSE. */
227 nds32_parse_opcode (struct nds32_opcode
*opc
, bfd_vma pc ATTRIBUTE_UNUSED
,
228 disassemble_info
*info
, uint32_t insn
,
232 fprintf_ftype func
= info
->fprintf_func
;
233 void *stream
= info
->stream
;
234 const char *pstr_src
;
237 unsigned int push25gpr
= 0, lsmwRb
, lsmwRe
, lsmwEnb4
, checkbit
, i
;
238 int int_value
, ifthe1st
= 1;
244 func (stream
, UNKNOWN_INSN_MSG
);
248 if (parse_mode
& NDS32_PARSE_EX9IT
)
251 pstr_src
= opc
->instruction
;
254 func (stream
, "%s", opc
->opcode
);
257 /* NDS32_PARSE_INSN16. */
258 if (parse_mode
& NDS32_PARSE_INSN16
)
260 func (stream
, "%s ", opc
->opcode
);
263 /* NDS32_PARSE_INSN32. */
267 if (op
== N32_OP6_LSMW
)
268 func (stream
, "%s.", opc
->opcode
);
269 else if (strstr (opc
->instruction
, "tito"))
270 func (stream
, "%s", opc
->opcode
);
272 func (stream
, "%s ", opc
->opcode
);
283 /* compare with operand_fields[].name. */
284 pstr_tmp
= &tmp_string
[0];
287 if ((*pstr_src
== ',') || (*pstr_src
== ' ')
288 || (*pstr_src
== '{') || (*pstr_src
== '}')
289 || (*pstr_src
== '[') || (*pstr_src
== ']')
290 || (*pstr_src
== '(') || (*pstr_src
== ')')
291 || (*pstr_src
== '+') || (*pstr_src
== '<'))
293 *pstr_tmp
++ = *pstr_src
++;
297 pfd
= (const field_t
*) &operand_fields
[0];
300 if (pfd
->name
== NULL
)
302 else if (strcmp (&tmp_string
[0], pfd
->name
) == 0)
308 if (parse_mode
& NDS32_PARSE_INSN16
)
310 if (pfd
->hw_res
== HW_GPR
)
313 __GF (insn
, pfd
->bitpos
, pfd
->bitsize
) << pfd
->shift
;
315 if ((opc
->value
== 0xfc00) || (opc
->value
== 0xfc80))
320 int_value
= (6 + (0x01 << int_value
));
321 push25gpr
= int_value
;
323 else if (strcmp (pfd
->name
, "rt4") == 0)
325 int_value
= nds32_r45map
[int_value
];
327 func (stream
, "$%s", keyword_gpr
[int_value
].name
);
329 else if ((pfd
->hw_res
== HW_INT
) || (pfd
->hw_res
== HW_UINT
))
331 if (pfd
->hw_res
== HW_INT
)
333 N32_IMMS ((insn
>> pfd
->bitpos
),
334 pfd
->bitsize
) << pfd
->shift
;
337 __GF (insn
, pfd
->bitpos
, pfd
->bitsize
) << pfd
->shift
;
340 if (opc
->value
== 0xfa00)
343 func (stream
, "#0x%x", int_value
);
346 else if (opc
->value
== 0xb200)
348 int_value
= 0 - (128 - int_value
);
349 func (stream
, "#%d", int_value
);
351 /* beqz38/bnez38/beqs38/bnes38/j8/beqzs8/bnezs8/ifcall9. */
352 else if ((opc
->value
== 0xc000) || (opc
->value
== 0xc800)
353 || (opc
->value
== 0xd000) || (opc
->value
== 0xd800)
354 || (opc
->value
== 0xd500) || (opc
->value
== 0xe800)
355 || (opc
->value
== 0xe900)
356 || (opc
->value
== 0xf800))
358 info
->print_address_func (int_value
+ pc
, info
);
361 else if ((opc
->value
== 0xfc00) || (opc
->value
== 0xfc80))
363 func (stream
, "#%d ! {$r6", int_value
);
365 func (stream
, "~$%s", keyword_gpr
[push25gpr
].name
);
366 func (stream
, ", $fp, $gp, $lp}");
369 else if ((opc
->value
== 0xdd40) || (opc
->value
== 0xea00))
371 func (stream
, "#%d", int_value
);
372 nds32_ex9_info (pc
, info
, int_value
);
374 else if (pfd
->hw_res
== HW_INT
)
377 func (stream
, "#%d", int_value
);
379 func (stream
, "#0x%x", int_value
);
381 else /* if(pfd->hw_res == HW_UINT). */
382 func (stream
, "#0x%x", int_value
);
387 else if (op
== N32_OP6_AEXT
)
389 nds32_parse_audio_ext (pfd
, info
, insn
);
392 else if (pfd
->hw_res
< _HW_LAST
)
395 __GF (insn
, pfd
->bitpos
, pfd
->bitsize
) << pfd
->shift
;
397 psys_reg
= (keyword_t
*) keywords
[pfd
->hw_res
];
399 psys_reg
= nds32_find_reg_keyword (psys_reg
, int_value
);
400 /* For HW_SR, dump the index when it can't
401 map the register name. */
402 if (!psys_reg
&& pfd
->hw_res
== HW_SR
)
403 func (stream
, "%d", int_value
);
405 func (stream
, "???");
408 if (pfd
->hw_res
== HW_GPR
|| pfd
->hw_res
== HW_CPR
409 || pfd
->hw_res
== HW_FDR
|| pfd
->hw_res
== HW_FSR
410 || pfd
->hw_res
== HW_DXR
|| pfd
->hw_res
== HW_SR
411 || pfd
->hw_res
== HW_USR
)
412 func (stream
, "$%s", psys_reg
->name
);
413 else if (pfd
->hw_res
== HW_DTITON
414 || pfd
->hw_res
== HW_DTITOFF
)
415 func (stream
, ".%s", psys_reg
->name
);
417 func (stream
, "%s", psys_reg
->name
);
420 else if ((pfd
->hw_res
== HW_INT
) || (pfd
->hw_res
== HW_UINT
))
422 if (pfd
->hw_res
== HW_INT
)
424 N32_IMMS ((insn
>> pfd
->bitpos
), pfd
->bitsize
) << pfd
->shift
;
427 __GF (insn
, pfd
->bitpos
, pfd
->bitsize
) << pfd
->shift
;
429 if ((op
== N32_OP6_BR1
) || (op
== N32_OP6_BR2
))
431 info
->print_address_func (int_value
+ pc
, info
);
433 else if ((op
== N32_OP6_BR3
) && (pfd
->bitpos
== 0))
435 info
->print_address_func (int_value
+ pc
, info
);
437 else if (op
== N32_OP6_JI
)
439 /* FIXME: Handle relocation. */
440 if (info
->flags
& INSN_HAS_RELOC
)
442 /* Check if insn32 in ex9 table. */
443 if (parse_mode
& NDS32_PARSE_EX9IT
)
444 info
->print_address_func ((pc
& 0xFE000000) | int_value
,
446 /* Check if decode ex9 table, PC(31,25)|Inst(23,0)<<1. */
447 else if (parse_mode
& NDS32_PARSE_EX9TAB
)
448 func (stream
, "PC(31,25)|#0x%x", int_value
);
450 info
->print_address_func (int_value
+ pc
, info
);
452 else if (op
== N32_OP6_LSMW
)
454 /* lmw.adm/smw.adm. */
455 func (stream
, "#0x%x ! {", int_value
);
456 lsmwEnb4
= int_value
;
457 lsmwRb
= ((insn
>> 20) & 0x1F);
458 lsmwRe
= ((insn
>> 10) & 0x1F);
460 /* If [Rb, Re] specifies at least one register,
461 Rb(4,0) <= Re(4,0) and 0 <= Rb(4,0), Re(4,0) < 28.
462 Disassembling does not consider this currently because of
463 the convience comparing with bsp320. */
464 if (lsmwRb
!= 31 || lsmwRe
!= 31)
466 func (stream
, "$%s", keyword_gpr
[lsmwRb
].name
);
467 if (lsmwRb
!= lsmwRe
)
468 func (stream
, "~$%s", keyword_gpr
[lsmwRe
].name
);
473 /* $fp, $gp, $lp, $sp. */
475 for (i
= 0; i
< 4; i
++)
477 if (lsmwEnb4
& checkbit
)
482 func (stream
, "$%s", keyword_gpr
[28 + i
].name
);
485 func (stream
, ", $%s", keyword_gpr
[28 + i
].name
);
492 else if (pfd
->hw_res
== HW_INT
)
495 func (stream
, "#%d", int_value
);
497 func (stream
, "#0x%x", int_value
);
499 else /* if(pfd->hw_res == HW_UINT). */
501 func (stream
, "#0x%x", int_value
);
512 func (stream
, "%c", *pstr_src
++);
514 } /* switch (*pstr_src). */
516 } /* while (*pstr_src). */
520 /* Filter instructions with some bits must be fixed. */
523 nds32_filter_unknown_insn (uint32_t insn
, struct nds32_opcode
**opc
)
528 switch ((*opc
)->value
)
533 if (__GF (insn
, 6, 2) != 0 || __GF (insn
, 15, 10) != 0)
537 if (__GF (insn
, 7, 18) != 0)
542 if (__GF (insn
, 5, 5) != 0)
546 if (__GF (insn
, 20, 5) != 0)
550 if (__GF (insn
, 5, 3) != 0 || __GF (insn
, 15, 5) != 0)
572 if (__GF (insn
, 5, 5) != 0)
578 if (__GF (insn
, 5, 20) != 0)
585 print_insn32 (bfd_vma pc
, disassemble_info
*info
, uint32_t insn
,
588 /* Get the final correct opcode and parse. */
589 struct nds32_opcode
*opc
;
590 uint32_t opcode
= nds32_mask_opcode (insn
);
591 opc
= (struct nds32_opcode
*) htab_find (opcode_htab
, &opcode
);
593 nds32_special_opcode (insn
, &opc
);
594 nds32_filter_unknown_insn (insn
, &opc
);
595 nds32_parse_opcode (opc
, pc
, info
, insn
, parse_mode
);
599 print_insn16 (bfd_vma pc
, disassemble_info
*info
,
600 uint32_t insn
, uint32_t parse_mode
)
602 struct nds32_opcode
*opc
;
605 /* Get highest 7 bit in default. */
606 unsigned int mask
= 0xfe00;
608 /* Classify 16-bit instruction to 4 sets by bit 13 and 14. */
609 switch (__GF (insn
, 13, 2))
613 if (__GF (insn
, 11, 2) == 0)
616 /* ifret16 = mov55 $sp, $sp*/
617 if (__GF (insn
, 0, 11) == 0x3ff)
620 else if (__GF (insn
, 9, 4) == 0xb)
625 if (__GF (insn
, 11, 2) == 0x3)
630 /* Exclude beqz38, bnez38, beqs38, and bnes38. */
631 if (__GF (insn
, 12, 1) == 0x1
632 && __GF (insn
, 8, 3) == 0x5)
634 if (__GF (insn
, 11, 1) == 0x0)
641 switch (__GF (insn
, 11, 2))
645 if (__GF (insn
, 9, 2) == 0x0)
648 else if (__GF(insn
, 10, 1) == 0x1)
652 /* lwi37.sp swi37.sp */
656 if (__GF (insn
, 8, 3) == 0x5)
658 else if (__GF (insn
, 8, 3) == 0x4)
660 else if (__GF (insn
, 9 , 2) == 0x3)
666 opcode
= insn
& mask
;
667 opc
= (struct nds32_opcode
*) htab_find (opcode_htab
, &opcode
);
669 nds32_special_opcode (insn
, &opc
);
670 /* Get the final correct opcode and parse it. */
671 nds32_parse_opcode (opc
, pc
, info
, insn
, parse_mode
);
675 htab_hash_hash (const void *p
)
677 return (*(unsigned int *) p
) % 49;
681 htab_hash_eq (const void *p
, const void *q
)
683 uint32_t pinsn
= ((struct nds32_opcode
*) p
)->value
;
684 uint32_t qinsn
= *((uint32_t *) q
);
686 return (pinsn
== qinsn
);
689 /* Get the format of instruction. */
692 nds32_mask_opcode (uint32_t insn
)
694 uint32_t opcode
= N32_OP6 (insn
);
716 case N32_OP6_LBSI_BI
:
717 case N32_OP6_LHSI_BI
:
718 case N32_OP6_LWSI_BI
:
730 return MASK_OP (insn
, 0);
733 if (__GF (insn
, 0, 7) == (N32_ALU2_FFBI
| __BIT (6)))
734 return MASK_OP (insn
, 0x7f);
735 else if (__GF (insn
, 0, 7) == (N32_ALU2_MFUSR
| __BIT (6))
736 || __GF (insn
, 0, 7) == (N32_ALU2_MTUSR
| __BIT (6)))
738 return MASK_OP (insn
, 0xf81ff);
739 return MASK_OP (insn
, 0x1ff);
742 return MASK_OP (insn
, 0x1f);
744 return MASK_OP (insn
, 0xff);
746 return MASK_OP (insn
, 0x7f);
748 return MASK_OP (insn
, 0x23);
751 return MASK_OP (insn
, 0x1 << 19);
753 if (__GF (insn
, 18, 2) == 0x3)
754 return MASK_OP (insn
, 0x7 << 17);
755 return MASK_OP (insn
, 0x3 << 18);
757 return MASK_OP (insn
, 0x1 << 24);
762 return MASK_OP (insn
, 0x1 << 12);
764 return MASK_OP (insn
, 0x1 << 24);
766 return MASK_OP (insn
, 0x1 << 14);
768 return MASK_OP (insn
, 0xf << 16);
770 return MASK_OP (insn
, 0x1 << 19);
772 switch (__GF (insn
, 0, 5))
775 /* SETGIE and SETEND */
776 if (__GF (insn
, 5, 5) == 0x1 || __GF (insn
, 5, 5) == 0x2)
777 return MASK_OP (insn
, 0x1fffff);
778 return MASK_OP (insn
, 0x1f);
780 if (__GF (insn
, 5, 5) == 5 || __GF (insn
, 5, 5) == 7)
782 return MASK_OP (insn
, 0x3ff);
783 return MASK_OP (insn
, 0x1f);
785 return MASK_OP (insn
, 0x1f);
788 if (__GF (insn
, 4, 2) == 0)
791 switch (__GF (insn
, 0, 4))
795 /* FS1/F2OP FD1/F2OP */
796 if (__GF (insn
, 6, 4) == 0xf)
797 return MASK_OP (insn
, 0x7fff);
799 return MASK_OP (insn
, 0x3ff);
803 return MASK_OP (insn
, 0x3ff);
807 if (__GF (insn
, 6, 4) == 0xc)
808 return MASK_OP (insn
, 0x7fff);
810 return MASK_OP (insn
, 0x3ff);
812 return MASK_OP (insn
, 0xff);
815 else if (__GF (insn
, 0, 2) == 0)
816 return MASK_OP (insn
, 0xf);
817 return MASK_OP (insn
, 0xcf);
820 switch (__GF (insn
, 23, 2))
823 if (__GF (insn
, 5, 4) == 0)
824 /* AMxxx AMAyyS AMyyS AMAWzS AMWzS */
825 return MASK_OP (insn
, (0x1f << 20) | 0x1ff);
826 else if (__GF (insn
, 5, 4) == 1)
827 /* ALR ASR ALA ASA AUPI */
828 return MASK_OP (insn
, (0x1f << 20) | (0xf << 5));
829 else if (__GF (insn
, 20, 3) == 0 && __GF (insn
, 6, 3) == 1)
831 return MASK_OP (insn
, (0x1f << 20) | (0x7 << 6));
832 else if (__GF (insn
, 20 ,3) == 2 && __GF (insn
, 6, 3) == 1)
834 return MASK_OP (insn
, (0x1f << 20) | (0xf << 5));
835 else if (__GF (insn
, 20 ,3) == 3 && __GF (insn
, 6, 3) == 1)
836 /* AMTAR AMTAR2 AMFAR AMFAR2 */
837 return MASK_OP (insn
, (0x1f << 20) | (0x1f << 5));
838 else if (__GF (insn
, 7, 2) == 3)
840 return MASK_OP (insn
, (0x1f << 20) | (0x3 << 7));
841 else if (__GF (insn
, 6, 3) == 2)
843 return MASK_OP (insn
, (0x1f << 20) | (0xf << 5));
845 /* AmxxxL.l AmxxxL2.S AMxxxL2.L */
846 return MASK_OP (insn
, (0x1f << 20) | (0x7 << 6));
848 if (__GF (insn
, 20, 3) == 0)
850 return MASK_OP (insn
, (0x1f << 20) | (0x1 << 5));
851 else if (__GF (insn
, 20, 3) == 1)
852 /* AMTARI Ix AMTARI Mx */
853 return MASK_OP (insn
, (0x1f << 20));
854 else if (__GF (insn
, 6, 3) == 2)
855 /* AMAWzSl.S AMWzSl.S */
856 return MASK_OP (insn
, (0x1f << 20) | (0xf << 5));
857 else if (__GF (insn
, 7, 2) == 3)
858 /* AMAWzSSA AMWzSSA */
859 return MASK_OP (insn
, (0x1f << 20) | (0x3 << 7));
861 /* AMAWzSL.L AMAWzSL2.S AMAWzSL2.L AMWzSL.L AMWzSL.L AMWzSL2.S */
862 return MASK_OP (insn
, (0x1f << 20) | (0x7 << 6));
864 if (__GF (insn
, 6, 3) == 2)
865 /* AMAyySl.S AMWyySl.S */
866 return MASK_OP (insn
, (0x1f << 20) | (0xf << 5));
867 else if (__GF (insn
, 7, 2) == 3)
868 /* AMAWyySSA AMWyySSA */
869 return MASK_OP (insn
, (0x1f << 20) | (0x3 << 7));
871 /* AMAWyySL.L AMAWyySL2.S AMAWyySL2.L AMWyySL.L AMWyySL.L AMWyySL2.S */
872 return MASK_OP (insn
, (0x1f << 20) | (0x7 << 6));
874 return MASK_OP (insn
, 0x1f << 20);
880 /* Define cctl subtype. */
881 static char *cctl_subtype
[] =
884 "st0", "st0", "st0", "st2", "st2", "st3", "st3", "st4",
885 "st1", "st1", "st1", "st0", "st0", NULL
, NULL
, "st5",
887 "st0", NULL
, NULL
, "st2", "st2", "st3", "st3", NULL
,
888 "st1", NULL
, NULL
, "st0", "st0", NULL
, NULL
, NULL
891 /* Check the subset of opcode. */
894 nds32_special_opcode (uint32_t insn
, struct nds32_opcode
**opc
)
902 /* Check if special case. */
903 switch ((*opc
)->value
)
909 case FPU_RA_IMMBI (LWC
):
910 case FPU_RA_IMMBI (SWC
):
911 case FPU_RA_IMMBI (LDC
):
912 case FPU_RA_IMMBI (SDC
):
913 /* Check if cp0 => FPU. */
914 if (__GF (insn
, 13, 2) == 0)
916 while (!((*opc
)->attr
& ATTR (FPU
)) && (*opc
)->next
)
925 /* Check if (add/add_slli) (sub/sub_slli) (and/and_slli). */
926 if (N32_SH5(insn
) != 0)
931 if (__GF (insn
, 10, 15) == 0)
935 string
= cctl_subtype
[__GF (insn
, 5, 5)];
939 case JREG (JR
) | JREG_RET
:
940 if (__GF (insn
, 8, 2) != 0)
947 if (__GF (insn
, 5, 4) != 0)
952 if (__GF (insn
, 0, 9) == 0)
959 while (strstr ((*opc
)->opcode
, string
) == NULL
960 && strstr ((*opc
)->instruction
, string
) == NULL
&& (*opc
)->next
)
965 /* Classify instruction is COP or FPU. */
967 if (op
== N32_OP6_COP
&& __GF (insn
, 4, 2) != 0)
969 while (((*opc
)->attr
& ATTR (FPU
)) != 0 && (*opc
)->next
)
975 print_insn_nds32 (bfd_vma pc
, disassemble_info
*info
)
982 struct nds32_opcode
*opc
;
983 struct nds32_opcode
**slot
;
987 /* Build opcode table. */
988 opcode_htab
= htab_create_alloc (1024, htab_hash_hash
, htab_hash_eq
,
989 NULL
, xcalloc
, free
);
991 while (nds32_opcodes
[i
].opcode
!= NULL
)
993 opc
= &nds32_opcodes
[i
];
995 (struct nds32_opcode
**) htab_find_slot (opcode_htab
, &opc
->value
,
999 /* This is the new one. */
1004 /* Already exists. Append to the list. */
1008 opc
->next
= &nds32_opcodes
[i
];
1015 status
= info
->read_memory_func (pc
, (bfd_byte
*) buf
, 4, info
);
1018 /* for the last 16-bit instruction. */
1019 status
= info
->read_memory_func (pc
, (bfd_byte
*) buf
, 2, info
);
1022 (*info
->memory_error_func
)(status
, pc
, info
);
1027 insn
= bfd_getb32 (buf
);
1028 /* 16-bit instruction. */
1029 if (insn
& 0x80000000)
1031 if (info
->section
&& strstr (info
->section
->name
, ".ex9.itable") != NULL
)
1033 print_insn16 (pc
, info
, (insn
& 0x0000FFFF),
1034 NDS32_PARSE_INSN16
| NDS32_PARSE_EX9TAB
);
1037 print_insn16 (pc
, info
, (insn
>> 16), NDS32_PARSE_INSN16
);
1041 /* 32-bit instructions. */
1045 && strstr (info
->section
->name
, ".ex9.itable") != NULL
)
1046 print_insn32 (pc
, info
, insn
, NDS32_PARSE_INSN32
| NDS32_PARSE_EX9TAB
);
1048 print_insn32 (pc
, info
, insn
, NDS32_PARSE_INSN32
);