1 /* NDS32-specific support for 32-bit ELF.
2 Copyright (C) 2012-2017 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
25 #include "disassemble.h"
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\t", 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). */
384 func (stream
, "#%u", int_value
);
386 func (stream
, "#0x%x", int_value
);
392 else if (op
== N32_OP6_AEXT
)
394 nds32_parse_audio_ext (pfd
, info
, insn
);
397 else if (pfd
->hw_res
< _HW_LAST
)
400 __GF (insn
, pfd
->bitpos
, pfd
->bitsize
) << pfd
->shift
;
402 psys_reg
= (keyword_t
*) keywords
[pfd
->hw_res
];
404 psys_reg
= nds32_find_reg_keyword (psys_reg
, int_value
);
405 /* For HW_SR, dump the index when it can't
406 map the register name. */
407 if (!psys_reg
&& pfd
->hw_res
== HW_SR
)
408 func (stream
, "%d", int_value
);
410 func (stream
, "???");
413 if (pfd
->hw_res
== HW_GPR
|| pfd
->hw_res
== HW_CPR
414 || pfd
->hw_res
== HW_FDR
|| pfd
->hw_res
== HW_FSR
415 || pfd
->hw_res
== HW_DXR
|| pfd
->hw_res
== HW_SR
416 || pfd
->hw_res
== HW_USR
)
417 func (stream
, "$%s", psys_reg
->name
);
418 else if (pfd
->hw_res
== HW_DTITON
419 || pfd
->hw_res
== HW_DTITOFF
)
420 func (stream
, ".%s", psys_reg
->name
);
422 func (stream
, "%s", psys_reg
->name
);
425 else if ((pfd
->hw_res
== HW_INT
) || (pfd
->hw_res
== HW_UINT
))
427 if (pfd
->hw_res
== HW_INT
)
429 N32_IMMS ((insn
>> pfd
->bitpos
), pfd
->bitsize
) << pfd
->shift
;
432 __GF (insn
, pfd
->bitpos
, pfd
->bitsize
) << pfd
->shift
;
434 if ((op
== N32_OP6_BR1
) || (op
== N32_OP6_BR2
))
436 info
->print_address_func (int_value
+ pc
, info
);
438 else if ((op
== N32_OP6_BR3
) && (pfd
->bitpos
== 0))
440 info
->print_address_func (int_value
+ pc
, info
);
442 else if (op
== N32_OP6_JI
)
444 /* FIXME: Handle relocation. */
445 if (info
->flags
& INSN_HAS_RELOC
)
447 /* Check if insn32 in ex9 table. */
448 if (parse_mode
& NDS32_PARSE_EX9IT
)
449 info
->print_address_func ((pc
& 0xFE000000) | int_value
,
451 /* Check if decode ex9 table, PC(31,25)|Inst(23,0)<<1. */
452 else if (parse_mode
& NDS32_PARSE_EX9TAB
)
453 func (stream
, "PC(31,25)|#0x%x", int_value
);
455 info
->print_address_func (int_value
+ pc
, info
);
457 else if (op
== N32_OP6_LSMW
)
459 /* lmw.adm/smw.adm. */
460 func (stream
, "#0x%x ! {", int_value
);
461 lsmwEnb4
= int_value
;
462 lsmwRb
= ((insn
>> 20) & 0x1F);
463 lsmwRe
= ((insn
>> 10) & 0x1F);
465 /* If [Rb, Re] specifies at least one register,
466 Rb(4,0) <= Re(4,0) and 0 <= Rb(4,0), Re(4,0) < 28.
467 Disassembling does not consider this currently because of
468 the convience comparing with bsp320. */
469 if (lsmwRb
!= 31 || lsmwRe
!= 31)
471 func (stream
, "$%s", keyword_gpr
[lsmwRb
].name
);
472 if (lsmwRb
!= lsmwRe
)
473 func (stream
, "~$%s", keyword_gpr
[lsmwRe
].name
);
478 /* $fp, $gp, $lp, $sp. */
480 for (i
= 0; i
< 4; i
++)
482 if (lsmwEnb4
& checkbit
)
487 func (stream
, "$%s", keyword_gpr
[28 + i
].name
);
490 func (stream
, ", $%s", keyword_gpr
[28 + i
].name
);
497 else if (pfd
->hw_res
== HW_INT
)
500 func (stream
, "#%d", int_value
);
502 func (stream
, "#0x%x", int_value
);
504 else /* if (pfd->hw_res == HW_UINT). */
507 func (stream
, "#%u", int_value
);
509 func (stream
, "#0x%x", int_value
);
525 func (stream
, " + ");
530 if (pstr_src
[1] == '<')
532 func (stream
, " << ");
543 func (stream
, "%c", *pstr_src
++);
549 /* Filter instructions with some bits must be fixed. */
552 nds32_filter_unknown_insn (uint32_t insn
, struct nds32_opcode
**opc
)
557 switch ((*opc
)->value
)
562 if (__GF (insn
, 6, 2) != 0 || __GF (insn
, 15, 10) != 0)
566 if (__GF (insn
, 7, 18) != 0)
571 if (__GF (insn
, 5, 5) != 0)
575 if (__GF (insn
, 20, 5) != 0)
579 if (__GF (insn
, 5, 3) != 0 || __GF (insn
, 15, 5) != 0)
601 if (__GF (insn
, 5, 5) != 0)
607 if (__GF (insn
, 5, 20) != 0)
614 print_insn32 (bfd_vma pc
, disassemble_info
*info
, uint32_t insn
,
617 /* Get the final correct opcode and parse. */
618 struct nds32_opcode
*opc
;
619 uint32_t opcode
= nds32_mask_opcode (insn
);
620 opc
= (struct nds32_opcode
*) htab_find (opcode_htab
, &opcode
);
622 nds32_special_opcode (insn
, &opc
);
623 nds32_filter_unknown_insn (insn
, &opc
);
624 nds32_parse_opcode (opc
, pc
, info
, insn
, parse_mode
);
628 print_insn16 (bfd_vma pc
, disassemble_info
*info
,
629 uint32_t insn
, uint32_t parse_mode
)
631 struct nds32_opcode
*opc
;
634 /* Get highest 7 bit in default. */
635 unsigned int mask
= 0xfe00;
637 /* Classify 16-bit instruction to 4 sets by bit 13 and 14. */
638 switch (__GF (insn
, 13, 2))
642 if (__GF (insn
, 11, 2) == 0)
645 /* ifret16 = mov55 $sp, $sp*/
646 if (__GF (insn
, 0, 11) == 0x3ff)
649 else if (__GF (insn
, 9, 4) == 0xb)
654 if (__GF (insn
, 11, 2) == 0x3)
659 /* Exclude beqz38, bnez38, beqs38, and bnes38. */
660 if (__GF (insn
, 12, 1) == 0x1
661 && __GF (insn
, 8, 3) == 0x5)
663 if (__GF (insn
, 11, 1) == 0x0)
670 switch (__GF (insn
, 11, 2))
674 if (__GF (insn
, 9, 2) == 0x0)
677 else if (__GF(insn
, 10, 1) == 0x1)
681 /* lwi37.sp swi37.sp */
685 if (__GF (insn
, 8, 3) == 0x5)
687 else if (__GF (insn
, 8, 3) == 0x4)
689 else if (__GF (insn
, 9 , 2) == 0x3)
695 opcode
= insn
& mask
;
696 opc
= (struct nds32_opcode
*) htab_find (opcode_htab
, &opcode
);
698 nds32_special_opcode (insn
, &opc
);
699 /* Get the final correct opcode and parse it. */
700 nds32_parse_opcode (opc
, pc
, info
, insn
, parse_mode
);
704 htab_hash_hash (const void *p
)
706 return (*(unsigned int *) p
) % 49;
710 htab_hash_eq (const void *p
, const void *q
)
712 uint32_t pinsn
= ((struct nds32_opcode
*) p
)->value
;
713 uint32_t qinsn
= *((uint32_t *) q
);
715 return (pinsn
== qinsn
);
718 /* Get the format of instruction. */
721 nds32_mask_opcode (uint32_t insn
)
723 uint32_t opcode
= N32_OP6 (insn
);
745 case N32_OP6_LBSI_BI
:
746 case N32_OP6_LHSI_BI
:
747 case N32_OP6_LWSI_BI
:
759 return MASK_OP (insn
, 0);
762 if (__GF (insn
, 0, 7) == (N32_ALU2_FFBI
| N32_BIT (6)))
763 return MASK_OP (insn
, 0x7f);
764 else if (__GF (insn
, 0, 7) == (N32_ALU2_MFUSR
| N32_BIT (6))
765 || __GF (insn
, 0, 7) == (N32_ALU2_MTUSR
| N32_BIT (6)))
767 return MASK_OP (insn
, 0xf81ff);
768 return MASK_OP (insn
, 0x1ff);
771 return MASK_OP (insn
, 0x1f);
773 return MASK_OP (insn
, 0xff);
775 return MASK_OP (insn
, 0x7f);
777 return MASK_OP (insn
, 0x23);
780 return MASK_OP (insn
, 0x1 << 19);
782 if (__GF (insn
, 18, 2) == 0x3)
783 return MASK_OP (insn
, 0x7 << 17);
784 return MASK_OP (insn
, 0x3 << 18);
786 return MASK_OP (insn
, 0x1 << 24);
791 return MASK_OP (insn
, 0x1 << 12);
793 return MASK_OP (insn
, 0x1 << 24);
795 return MASK_OP (insn
, 0x1 << 14);
797 return MASK_OP (insn
, 0xf << 16);
799 return MASK_OP (insn
, 0x1 << 19);
801 switch (__GF (insn
, 0, 5))
804 /* SETGIE and SETEND */
805 if (__GF (insn
, 5, 5) == 0x1 || __GF (insn
, 5, 5) == 0x2)
806 return MASK_OP (insn
, 0x1fffff);
807 return MASK_OP (insn
, 0x1f);
809 if (__GF (insn
, 5, 5) == 5 || __GF (insn
, 5, 5) == 7)
811 return MASK_OP (insn
, 0x3ff);
812 return MASK_OP (insn
, 0x1f);
814 return MASK_OP (insn
, 0x1f);
817 if (__GF (insn
, 4, 2) == 0)
820 switch (__GF (insn
, 0, 4))
824 /* FS1/F2OP FD1/F2OP */
825 if (__GF (insn
, 6, 4) == 0xf)
826 return MASK_OP (insn
, 0x7fff);
828 return MASK_OP (insn
, 0x3ff);
832 return MASK_OP (insn
, 0x3ff);
836 if (__GF (insn
, 6, 4) == 0xc)
837 return MASK_OP (insn
, 0x7fff);
839 return MASK_OP (insn
, 0x3ff);
841 return MASK_OP (insn
, 0xff);
844 else if (__GF (insn
, 0, 2) == 0)
845 return MASK_OP (insn
, 0xf);
846 return MASK_OP (insn
, 0xcf);
849 switch (__GF (insn
, 23, 2))
852 if (__GF (insn
, 5, 4) == 0)
853 /* AMxxx AMAyyS AMyyS AMAWzS AMWzS */
854 return MASK_OP (insn
, (0x1f << 20) | 0x1ff);
855 else if (__GF (insn
, 5, 4) == 1)
856 /* ALR ASR ALA ASA AUPI */
857 return MASK_OP (insn
, (0x1f << 20) | (0xf << 5));
858 else if (__GF (insn
, 20, 3) == 0 && __GF (insn
, 6, 3) == 1)
860 return MASK_OP (insn
, (0x1f << 20) | (0x7 << 6));
861 else if (__GF (insn
, 20 ,3) == 2 && __GF (insn
, 6, 3) == 1)
863 return MASK_OP (insn
, (0x1f << 20) | (0xf << 5));
864 else if (__GF (insn
, 20 ,3) == 3 && __GF (insn
, 6, 3) == 1)
865 /* AMTAR AMTAR2 AMFAR AMFAR2 */
866 return MASK_OP (insn
, (0x1f << 20) | (0x1f << 5));
867 else if (__GF (insn
, 7, 2) == 3)
869 return MASK_OP (insn
, (0x1f << 20) | (0x3 << 7));
870 else if (__GF (insn
, 6, 3) == 2)
872 return MASK_OP (insn
, (0x1f << 20) | (0xf << 5));
874 /* AmxxxL.l AmxxxL2.S AMxxxL2.L */
875 return MASK_OP (insn
, (0x1f << 20) | (0x7 << 6));
877 if (__GF (insn
, 20, 3) == 0)
879 return MASK_OP (insn
, (0x1f << 20) | (0x1 << 5));
880 else if (__GF (insn
, 20, 3) == 1)
881 /* AMTARI Ix AMTARI Mx */
882 return MASK_OP (insn
, (0x1f << 20));
883 else if (__GF (insn
, 6, 3) == 2)
884 /* AMAWzSl.S AMWzSl.S */
885 return MASK_OP (insn
, (0x1f << 20) | (0xf << 5));
886 else if (__GF (insn
, 7, 2) == 3)
887 /* AMAWzSSA AMWzSSA */
888 return MASK_OP (insn
, (0x1f << 20) | (0x3 << 7));
890 /* AMAWzSL.L AMAWzSL2.S AMAWzSL2.L AMWzSL.L AMWzSL.L AMWzSL2.S */
891 return MASK_OP (insn
, (0x1f << 20) | (0x7 << 6));
893 if (__GF (insn
, 6, 3) == 2)
894 /* AMAyySl.S AMWyySl.S */
895 return MASK_OP (insn
, (0x1f << 20) | (0xf << 5));
896 else if (__GF (insn
, 7, 2) == 3)
897 /* AMAWyySSA AMWyySSA */
898 return MASK_OP (insn
, (0x1f << 20) | (0x3 << 7));
900 /* AMAWyySL.L AMAWyySL2.S AMAWyySL2.L AMWyySL.L AMWyySL.L AMWyySL2.S */
901 return MASK_OP (insn
, (0x1f << 20) | (0x7 << 6));
903 return MASK_OP (insn
, 0x1f << 20);
909 /* Define cctl subtype. */
910 static char *cctl_subtype
[] =
913 "st0", "st0", "st0", "st2", "st2", "st3", "st3", "st4",
914 "st1", "st1", "st1", "st0", "st0", NULL
, NULL
, "st5",
916 "st0", NULL
, NULL
, "st2", "st2", "st3", "st3", NULL
,
917 "st1", NULL
, NULL
, "st0", "st0", NULL
, NULL
, NULL
920 /* Check the subset of opcode. */
923 nds32_special_opcode (uint32_t insn
, struct nds32_opcode
**opc
)
931 /* Check if special case. */
932 switch ((*opc
)->value
)
938 case FPU_RA_IMMBI (LWC
):
939 case FPU_RA_IMMBI (SWC
):
940 case FPU_RA_IMMBI (LDC
):
941 case FPU_RA_IMMBI (SDC
):
942 /* Check if cp0 => FPU. */
943 if (__GF (insn
, 13, 2) == 0)
945 while (!((*opc
)->attr
& ATTR (FPU
)) && (*opc
)->next
)
954 /* Check if (add/add_slli) (sub/sub_slli) (and/and_slli). */
955 if (N32_SH5(insn
) != 0)
960 if (__GF (insn
, 10, 15) == 0)
964 string
= cctl_subtype
[__GF (insn
, 5, 5)];
968 case JREG (JR
) | JREG_RET
:
969 if (__GF (insn
, 8, 2) != 0)
976 if (__GF (insn
, 5, 4) != 0)
981 if (__GF (insn
, 0, 9) == 0)
988 while (strstr ((*opc
)->opcode
, string
) == NULL
989 && strstr ((*opc
)->instruction
, string
) == NULL
&& (*opc
)->next
)
994 /* Classify instruction is COP or FPU. */
996 if (op
== N32_OP6_COP
&& __GF (insn
, 4, 2) != 0)
998 while (((*opc
)->attr
& ATTR (FPU
)) != 0 && (*opc
)->next
)
1004 print_insn_nds32 (bfd_vma pc
, disassemble_info
*info
)
1009 static int init
= 1;
1011 struct nds32_opcode
*opc
;
1012 struct nds32_opcode
**slot
;
1016 /* Build opcode table. */
1017 opcode_htab
= htab_create_alloc (1024, htab_hash_hash
, htab_hash_eq
,
1018 NULL
, xcalloc
, free
);
1020 while (nds32_opcodes
[i
].opcode
!= NULL
)
1022 opc
= &nds32_opcodes
[i
];
1024 (struct nds32_opcode
**) htab_find_slot (opcode_htab
, &opc
->value
,
1028 /* This is the new one. */
1033 /* Already exists. Append to the list. */
1037 opc
->next
= &nds32_opcodes
[i
];
1044 status
= info
->read_memory_func (pc
, (bfd_byte
*) buf
, 4, info
);
1047 /* for the last 16-bit instruction. */
1048 status
= info
->read_memory_func (pc
, (bfd_byte
*) buf
, 2, info
);
1051 (*info
->memory_error_func
)(status
, pc
, info
);
1056 insn
= bfd_getb32 (buf
);
1057 /* 16-bit instruction. */
1058 if (insn
& 0x80000000)
1060 if (info
->section
&& strstr (info
->section
->name
, ".ex9.itable") != NULL
)
1062 print_insn16 (pc
, info
, (insn
& 0x0000FFFF),
1063 NDS32_PARSE_INSN16
| NDS32_PARSE_EX9TAB
);
1066 print_insn16 (pc
, info
, (insn
>> 16), NDS32_PARSE_INSN16
);
1070 /* 32-bit instructions. */
1074 && strstr (info
->section
->name
, ".ex9.itable") != NULL
)
1075 print_insn32 (pc
, info
, insn
, NDS32_PARSE_INSN32
| NDS32_PARSE_EX9TAB
);
1077 print_insn32 (pc
, info
, insn
, NDS32_PARSE_INSN32
);