1 /* Instruction printing code for the ARM
2 Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
3 2007, Free Software Foundation, Inc.
4 Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
5 Modification by James G. Smith (jsmith@cygnus.co.uk)
7 This file is part of libopcodes.
9 This program is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 2 of the License, or (at your option)
14 This program is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301,
27 #include "stuff/arch.h"
28 #include "stuff/bool.h"
30 #include <mach-o/loader.h>
31 #include <mach-o/nlist.h>
32 #include <mach-o/reloc.h>
33 #include <mach-o/arm/reloc.h>
34 #include "opcode/arm.h"
35 #include "stuff/bytesex.h"
36 #include "stuff/symbol.h"
37 #include "stuff/llvm.h"
39 #include "dyld_bind_info.h"
40 #include "ofile_print.h"
41 #include "arm_disasm.h"
42 #include "cxa_demangle.h"
44 /* Used by otool(1) to stay or switch out of thumb mode */
45 enum bool in_thumb
= FALSE
;
47 static void set_thumb_mode(
49 uint32_t nsorted_symbols
,
50 struct symbol
*sorted_symbols
,
54 # define _(String) (String)
55 # define ATTRIBUTE_UNUSED
57 /* HACKS for bfd_stuff */
58 typedef enum bool bfd_boolean
;
59 typedef unsigned int bfd_vma
;
60 typedef char bfd_byte
;
61 #define bfd_endian byte_sex
62 #define BFD_ENDIAN_LITTLE LITTLE_ENDIAN_BYTE_SEX
63 #define BFD_ENDIAN_BIG BIG_ENDIAN_BYTE_SEX
65 /* HACKS to avoid pulling in all of FSF binutils include/dis-asm.h */
66 typedef int (*fprintf_ftype
) (void *, const char*, ...);
67 struct disassemble_info
{ /* HACK'ed up for just what we need here */
68 fprintf_ftype fprintf_func
;
71 /* new stuff needed, from /Volumes/Untitled 1/src/include/dis-asm.h */
72 /* The bfd_mach value. */
75 /* This variable may be set by the instruction decoder. It suggests
76 the number of bytes objdump should display on a single line. If
77 the instruction decoder sets this, it should always set it to
78 the same value in order to get reasonable looking output. */
81 /* The next two variables control the way objdump displays the raw data. */
82 /* For example, if bytes_per_line is 8 and bytes_per_chunk is 4, the */
83 /* output will look like this:
85 with the chunks displayed according to "display_endian". */
87 enum bfd_endian display_endian
;
89 /* Function called to determine if there is a symbol at the given ADDR.
90 If there is, the function returns 1, otherwise it returns 0.
91 This is used by ports which support an overlay manager where
92 the overlay number is held in the top part of an address. In
93 some circumstances we want to include the overlay number in the
94 address, (normally because there is a symbol associated with
95 that address), but sometimes we want to mask out the overlay bits. */
96 int (* symbol_at_address_func
)
97 (bfd_vma addr
, struct disassemble_info
* info
);
99 /* Function used to get bytes to disassemble. MEMADDR is the
100 address of the stuff to be disassembled, MYADDR is the address to
101 put the bytes in, and LENGTH is the number of bytes to read.
102 INFO is a pointer to this struct.
103 Returns an errno value or 0 for success. */
104 int (*read_memory_func
)
105 (bfd_vma memaddr
, bfd_byte
*myaddr
, unsigned int length
,
106 struct disassemble_info
*info
);
108 /* Function which should be called if we get an error that we can't
109 recover from. STATUS is the errno value from read_memory_func and
110 MEMADDR is the address that we were trying to read. INFO is a
111 pointer to this struct. */
112 void (*memory_error_func
)
113 (int status
, bfd_vma memaddr
, struct disassemble_info
*info
);
115 /* Function called to print ADDR. */
116 void (*print_address_func
)
117 (bfd_vma pc
, bfd_vma addr
, struct disassemble_info
*info
);
119 /* Function called to print IMM for movw and movt. */
120 enum bool (*print_immediate_func
)
121 (bfd_vma pc
, unsigned int imm
, struct disassemble_info
*info
,
124 /* For use by the disassembler.
125 The top 16 bits are reserved for public use (and are documented here).
126 The bottom 16 bits are for the internal use of the disassembler. */
128 #define INSN_HAS_RELOC 0x80000000
130 /* otool(1) specific stuff */
132 /* Relocation information. */
133 struct relocation_info
*relocs
;
136 struct nlist
*symbols
;
138 /* Symbols sorted by address. */
139 struct symbol
*sorted_symbols
;
140 uint32_t nsorted_symbols
;
143 uint32_t strings_size
;
144 /* Other useful info. */
147 struct load_command
*load_commands
;
148 enum byte_sex object_byte_sex
;
149 uint32_t *indirect_symbols
;
150 uint32_t nindirect_symbols
;
155 LLVMDisasmContextRef arm_dc
;
156 LLVMDisasmContextRef thumb_dc
;
158 uint32_t object_size
;
162 char *demangled_name
;
166 * GetOpInfo() is the operand information call back function. This is called to
167 * get the symbolic information for an operand of an arm instruction. This
168 * is done from the relocation information, symbol table, etc. That block of
169 * information is a pointer to the struct disassemble_info that was passed when
170 * the disassembler context was created and passed to back to GetOpInfo() when
171 * called back by LLVMDisasmInstruction(). For arm and thumb the instruction
172 * containing operand is at the PC parameter. Since for arm and thumb they only
173 * have one operand with symbolic information the Offset parameter is zero and
174 * the Size parameter is 4 for arm and 4 or 2 for thumb, depending on the
175 * instruction width. The information is returned in TagBuf and for both
176 * arm-apple-darwin10 and thumb-apple-dawrin10 Triples is the LLVMOpInfo1 struct
177 * defined in "llvm-c/Disassembler.h". The value of TagType for both Triples is
178 * 1. If symbolic information is returned then this function returns 1 else it
186 uint64_t Offset
, /* should always be passed as 0 for arm or thumb */
187 uint64_t Size
, /* should always be passed as 4 for arm or 2 or 4 for thumb */
188 int TagType
, /* should always be passed as 1 for either Triple */
191 struct disassemble_info
*info
;
192 struct LLVMOpInfo1
*op_info
;
194 int32_t low
, high
, mid
, reloc_found
, offset
;
195 uint32_t sect_offset
, i
, r_address
, r_symbolnum
, r_type
, r_extern
, r_length
,
196 r_value
, r_scattered
, pair_r_type
, pair_r_value
;
198 const char *strings
, *name
, *add
, *sub
;
199 struct relocation_info
*relocs
, *rp
, *pairp
;
200 struct scattered_relocation_info
*srp
, *spairp
;
201 uint32_t nrelocs
, strings_size
, n_strx
;
202 struct nlist
*symbols
;
204 info
= (struct disassemble_info
*)DisInfo
;
206 op_info
= (struct LLVMOpInfo1
*)TagBuf
;
207 value
= op_info
->Value
;
208 /* make sure all fields returned are zero if we don't set them */
209 memset(op_info
, '\0', sizeof(struct LLVMOpInfo1
));
210 op_info
->Value
= value
;
212 if(Offset
!= 0 || (Size
!= 4 && Size
!= 2) || TagType
!= 1 ||
213 info
->verbose
== FALSE
)
216 sect_offset
= Pc
- info
->sect_addr
;
217 relocs
= info
->relocs
;
218 nrelocs
= info
->nrelocs
;
219 symbols
= info
->symbols
;
220 strings
= info
->strings
;
221 strings_size
= info
->strings_size
;
234 for(i
= 0; i
< nrelocs
; i
++){
236 if(rp
->r_address
& R_SCATTERED
){
237 srp
= (struct scattered_relocation_info
*)rp
;
239 r_address
= srp
->r_address
;
241 r_length
= srp
->r_length
;
242 r_type
= srp
->r_type
;
243 r_value
= srp
->r_value
;
247 r_address
= rp
->r_address
;
248 r_symbolnum
= rp
->r_symbolnum
;
249 r_extern
= rp
->r_extern
;
250 r_length
= rp
->r_length
;
253 if(r_type
== ARM_RELOC_PAIR
){
254 fprintf(stderr
, "Stray ARM_RELOC_PAIR relocation entry "
258 if(r_address
== sect_offset
){
259 if(r_type
== ARM_RELOC_HALF
||
260 r_type
== ARM_RELOC_SECTDIFF
||
261 r_type
== ARM_RELOC_LOCAL_SECTDIFF
||
262 r_type
== ARM_RELOC_HALF_SECTDIFF
){
265 if(pairp
->r_address
& R_SCATTERED
){
266 spairp
= (struct scattered_relocation_info
*)
268 other_half
= spairp
->r_address
& 0xffff;
269 pair_r_type
= spairp
->r_type
;
270 pair_r_value
= spairp
->r_value
;
273 other_half
= pairp
->r_address
& 0xffff;
274 pair_r_type
= pairp
->r_type
;
276 if(pair_r_type
!= ARM_RELOC_PAIR
){
277 fprintf(stderr
, "No ARM_RELOC_PAIR relocation "
278 "entry after entry %u\n", i
);
286 if(r_type
== ARM_RELOC_HALF
||
287 r_type
== ARM_RELOC_SECTDIFF
||
288 r_type
== ARM_RELOC_LOCAL_SECTDIFF
||
289 r_type
== ARM_RELOC_HALF_SECTDIFF
){
292 if(pairp
->r_address
& R_SCATTERED
){
293 spairp
= (struct scattered_relocation_info
*)pairp
;
294 pair_r_type
= spairp
->r_type
;
297 pair_r_type
= pairp
->r_type
;
299 if(pair_r_type
== ARM_RELOC_PAIR
)
302 fprintf(stderr
, "No ARM_RELOC_PAIR relocation "
303 "entry after entry %u\n", i
);
308 if(reloc_found
&& r_extern
== 1){
310 n_strx
= symbols
[r_symbolnum
].n_un
.n_strx
;
311 if(n_strx
>= strings_size
)
312 name
= "bad string offset";
314 name
= strings
+ n_strx
;
315 op_info
->AddSymbol
.Present
= 1;
316 op_info
->AddSymbol
.Name
= name
;
320 if((r_length
& 0x1) == 1){
321 op_info
->Value
= value
<< 16 | other_half
;
322 op_info
->VariantKind
=
323 LLVMDisassembler_VariantKind_ARM_HI16
;
326 op_info
->Value
= other_half
<< 16 | value
;
327 op_info
->VariantKind
=
328 LLVMDisassembler_VariantKind_ARM_LO16
;
338 if((r_length
& 0x1) == 1){
339 op_info
->Value
= value
<< 16 | other_half
;
340 op_info
->VariantKind
=
341 LLVMDisassembler_VariantKind_ARM_HI16
;
344 op_info
->Value
= other_half
<< 16 | value
;
345 op_info
->VariantKind
=
346 LLVMDisassembler_VariantKind_ARM_LO16
;
357 * If we have a branch that is not an external relocation entry then
358 * return false so the code in tryAddingSymbolicOperand() can use
359 * SymbolLookUp() with the branch target address to look up the symbol
360 * and possiblity add an annotation for a symbol stub.
362 if(reloc_found
&& r_extern
== 0 &&
363 (r_type
== ARM_RELOC_BR24
|| r_type
== ARM_THUMB_RELOC_BR22
))
368 if(r_type
== ARM_RELOC_HALF
||
369 r_type
== ARM_RELOC_HALF_SECTDIFF
){
370 if((r_length
& 0x1) == 1)
371 value
= value
<< 16 | other_half
;
373 value
= other_half
<< 16 | value
;
376 (r_type
!= ARM_RELOC_HALF
&&
377 r_type
!= ARM_RELOC_HALF_SECTDIFF
)){
378 offset
= value
- r_value
;
383 if(reloc_found
&& r_type
== ARM_RELOC_HALF_SECTDIFF
){
384 if((r_length
& 0x1) == 1)
385 op_info
->VariantKind
=
386 LLVMDisassembler_VariantKind_ARM_HI16
;
388 op_info
->VariantKind
=
389 LLVMDisassembler_VariantKind_ARM_LO16
;
390 add
= guess_symbol(r_value
, info
->sorted_symbols
,
391 info
->nsorted_symbols
, info
->verbose
);
392 sub
= guess_symbol(pair_r_value
, info
->sorted_symbols
,
393 info
->nsorted_symbols
, info
->verbose
);
394 offset
= value
- (r_value
- pair_r_value
);
395 op_info
->AddSymbol
.Present
= 1;
397 op_info
->AddSymbol
.Name
= add
;
399 op_info
->AddSymbol
.Value
= r_value
;
400 op_info
->SubtractSymbol
.Present
= 1;
402 op_info
->SubtractSymbol
.Name
= sub
;
404 op_info
->SubtractSymbol
.Value
= pair_r_value
;
405 op_info
->Value
= offset
;
409 if(reloc_found
== FALSE
)
412 op_info
->AddSymbol
.Present
= 1;
413 op_info
->Value
= offset
;
415 if(r_type
== ARM_RELOC_HALF
){
416 if((r_length
& 0x1) == 1)
417 op_info
->VariantKind
=
418 LLVMDisassembler_VariantKind_ARM_HI16
;
420 op_info
->VariantKind
=
421 LLVMDisassembler_VariantKind_ARM_LO16
;
425 high
= info
->nsorted_symbols
- 1;
426 mid
= (high
- low
) / 2;
428 if(info
->sorted_symbols
[mid
].n_value
== value
){
429 op_info
->AddSymbol
.Present
= 1;
430 op_info
->AddSymbol
.Name
= info
->sorted_symbols
[mid
].name
;
433 if(info
->sorted_symbols
[mid
].n_value
> value
){
435 mid
= (high
+ low
) / 2;
439 mid
= (high
+ low
) / 2;
442 op_info
->AddSymbol
.Value
= value
;
447 * guess_cstring_pointer() is passed the address of what might be a pointer to a
448 * literal string in a cstring section. If that address is in a cstring section
449 * it returns a pointer to that string. Else it returns NULL.
453 guess_cstring_pointer(
454 const uint32_t value
,
455 const uint32_t ncmds
,
456 const uint32_t sizeofcmds
,
457 const struct load_command
*load_commands
,
458 const enum byte_sex load_commands_byte_sex
,
459 const char *object_addr
,
460 const uint32_t object_size
)
462 enum byte_sex host_byte_sex
;
464 uint32_t i
, j
, section_type
, sect_offset
, object_offset
;
465 const struct load_command
*lc
;
466 struct load_command l
;
467 struct segment_command sg
;
470 uint64_t big_load_end
;
473 host_byte_sex
= get_host_byte_sex();
474 swapped
= host_byte_sex
!= load_commands_byte_sex
;
478 for(i
= 0 ; i
< ncmds
; i
++){
479 memcpy((char *)&l
, (char *)lc
, sizeof(struct load_command
));
481 swap_load_command(&l
, host_byte_sex
);
482 if(l
.cmdsize
% sizeof(int32_t) != 0)
484 big_load_end
+= l
.cmdsize
;
485 if(big_load_end
> sizeofcmds
)
489 memcpy((char *)&sg
, (char *)lc
, sizeof(struct segment_command
));
491 swap_segment_command(&sg
, host_byte_sex
);
492 p
= (char *)lc
+ sizeof(struct segment_command
);
493 for(j
= 0 ; j
< sg
.nsects
; j
++){
494 memcpy((char *)&s
, p
, sizeof(struct section
));
495 p
+= sizeof(struct section
);
497 swap_section(&s
, 1, host_byte_sex
);
498 section_type
= s
.flags
& SECTION_TYPE
;
499 if(section_type
== S_CSTRING_LITERALS
&&
500 value
>= s
.addr
&& value
< s
.addr
+ s
.size
){
501 sect_offset
= value
- s
.addr
;
502 object_offset
= s
.offset
+ sect_offset
;
503 if(object_offset
< object_size
){
504 name
= object_addr
+ object_offset
;
516 lc
= (struct load_command
*)((char *)lc
+ l
.cmdsize
);
517 if((char *)lc
> (char *)load_commands
+ sizeofcmds
)
524 * get_literal_pool_value() looks for a section difference relocation entry
525 * at the pc. And if so returns the add_symbol's value indirectly through
526 * pointer_value and if that value has a symbol name then the name of a symbol
527 * indirectly though name.
531 get_literal_pool_value(
534 uint32_t *pointer_value
,
535 struct disassemble_info
*info
)
538 uint32_t i
, r_address
, r_symbolnum
, r_type
, r_extern
, r_length
,
539 r_value
, r_scattered
, pair_r_type
, pair_r_value
;
541 struct relocation_info
*rp
, *pairp
;
542 struct scattered_relocation_info
*srp
, *spairp
;
545 struct relocation_info
*relocs
= info
->relocs
;
546 uint32_t nrelocs
= info
->nrelocs
;
547 bfd_vma sect_offset
= pc
- info
->sect_addr
;
560 for(i
= 0; i
< nrelocs
; i
++){
562 if(rp
->r_address
& R_SCATTERED
){
563 srp
= (struct scattered_relocation_info
*)rp
;
565 r_address
= srp
->r_address
;
567 r_length
= srp
->r_length
;
568 r_type
= srp
->r_type
;
569 r_value
= srp
->r_value
;
573 r_address
= rp
->r_address
;
574 r_symbolnum
= rp
->r_symbolnum
;
575 r_extern
= rp
->r_extern
;
576 r_length
= rp
->r_length
;
579 if(r_type
== ARM_RELOC_PAIR
){
580 fprintf(stderr
, "Stray ARM_RELOC_PAIR relocation entry "
584 if(r_address
== sect_offset
){
585 if(r_type
== ARM_RELOC_HALF
||
586 r_type
== ARM_RELOC_SECTDIFF
||
587 r_type
== ARM_RELOC_LOCAL_SECTDIFF
||
588 r_type
== ARM_RELOC_HALF_SECTDIFF
){
591 if(pairp
->r_address
& R_SCATTERED
){
592 spairp
= (struct scattered_relocation_info
*)
594 other_half
= spairp
->r_address
& 0xffff;
595 pair_r_type
= spairp
->r_type
;
596 pair_r_value
= spairp
->r_value
;
599 other_half
= pairp
->r_address
& 0xffff;
600 pair_r_type
= pairp
->r_type
;
602 if(pair_r_type
!= ARM_RELOC_PAIR
){
603 fprintf(stderr
, "No ARM_RELOC_PAIR relocation "
604 "entry after entry %u\n", i
);
612 if(r_type
== ARM_RELOC_HALF
||
613 r_type
== ARM_RELOC_SECTDIFF
||
614 r_type
== ARM_RELOC_LOCAL_SECTDIFF
||
615 r_type
== ARM_RELOC_HALF_SECTDIFF
){
618 if(pairp
->r_address
& R_SCATTERED
){
619 spairp
= (struct scattered_relocation_info
*)pairp
;
620 pair_r_type
= spairp
->r_type
;
623 pair_r_type
= pairp
->r_type
;
625 if(pair_r_type
== ARM_RELOC_PAIR
)
628 fprintf(stderr
, "No ARM_RELOC_PAIR relocation "
629 "entry after entry %u\n", i
);
634 if(reloc_found
&& r_length
== 2 &&
635 (r_type
== ARM_RELOC_SECTDIFF
||
636 r_type
== ARM_RELOC_LOCAL_SECTDIFF
)){
637 *name
= guess_symbol(r_value
, info
->sorted_symbols
,
638 info
->nsorted_symbols
, info
->verbose
);
639 *pointer_value
= r_value
;
648 * guess_literal_pointer() returns a name of a symbol or string if the value
649 * passed in is the address of a literal pointer and the literal pointer's value
650 * is and address of a symbol or cstring.
654 guess_literal_pointer(
655 const uint32_t value
, /* the value of the reference */
656 const uint32_t pc
, /* pc of the referencing instruction */
657 uint64_t *reference_type
, /* type returned, symbol name or string literal*/
658 struct disassemble_info
*info
)
660 uint32_t i
, j
, ncmds
, sizeofcmds
, sect_addr
, object_size
, pointer_value
;
661 enum byte_sex object_byte_sex
, host_byte_sex
;
663 struct load_command
*load_commands
, *lc
, l
;
664 struct segment_command sg
;
666 char *object_addr
, *p
;
667 uint64_t big_load_end
;
671 sizeofcmds
= info
->sizeofcmds
;
672 load_commands
= info
->load_commands
;
673 sect_addr
= info
->sect_addr
;
674 object_byte_sex
= info
->object_byte_sex
;
675 object_addr
= info
->object_addr
;
676 object_size
= info
->object_size
;
678 host_byte_sex
= get_host_byte_sex();
679 swapped
= host_byte_sex
!= object_byte_sex
;
683 for(i
= 0 ; i
< ncmds
; i
++){
684 memcpy((char *)&l
, (char *)lc
, sizeof(struct load_command
));
686 swap_load_command(&l
, host_byte_sex
);
687 if(l
.cmdsize
% sizeof(int32_t) != 0)
689 big_load_end
+= l
.cmdsize
;
690 if(big_load_end
> sizeofcmds
)
694 memcpy((char *)&sg
, (char *)lc
, sizeof(struct segment_command
));
696 swap_segment_command(&sg
, host_byte_sex
);
697 p
= (char *)lc
+ sizeof(struct segment_command
);
698 for(j
= 0 ; j
< sg
.nsects
; j
++){
699 memcpy((char *)&s
, p
, sizeof(struct section
));
700 p
+= sizeof(struct section
);
702 swap_section(&s
, 1, host_byte_sex
);
703 if(sect_addr
== s
.addr
&&
704 pc
>= s
.addr
&& pc
< s
.addr
+ s
.size
&&
705 value
>= s
.addr
&& value
+ 4 <= s
.addr
+ s
.size
){
707 * The problem here is while we can get the value in the
708 * pool with code like this:
709 * section_start = object_addr + s.offset;
710 * section_offset = value - s.addr;
712 * section_start[section_offset + 3] << 24 |
713 * section_start[section_offset + 2] << 16 |
714 * section_start[section_offset + 1] << 8 |
715 * section_start[section_offset];
716 * we don't know the pc value that will be added
717 * to it. As that is done as a separate instruction like
718 * "L1: add rx, pc, rt" where the ldr loaded up the
719 * pool_value in rt. The pool_value in a relocatable
720 * object will be something like this:
722 * where LC1 is the pointer_value we are interested in.
723 * So we call get_literal_pool_value() to see if the
724 * literal pool has a relocation entry. If so it
725 * returns the pointer_value and the name of a symbol
726 * if any for that pointer_value.
728 if(get_literal_pool_value(value
, &name
, &pointer_value
,
733 * If the value in the literal pool is the address of a
734 * symbol then get_literal_pool_value() will set name
735 * to the name of the symbol.
739 LLVMDisassembler_ReferenceType_Out_LitPool_SymAddr
;
743 * If not, next see if the pointer value is pointing to
746 name
= guess_cstring_pointer(pointer_value
, ncmds
,
747 sizeofcmds
, load_commands
,
748 object_byte_sex
, object_addr
,
752 LLVMDisassembler_ReferenceType_Out_LitPool_CstrAddr
;
762 lc
= (struct load_command
*)((char *)lc
+ l
.cmdsize
);
763 if((char *)lc
> (char *)load_commands
+ sizeofcmds
)
770 * The symbol lookup function passed to LLVMCreateDisasm(). It looks up the
771 * SymbolValue using the info passed vis the pointer to the struct
772 * disassemble_info that was passed when disassembler context is created and
773 * returns the symbol name that matches or NULL if none.
775 * When this is called to get a symbol name for a branch target then the
776 * ReferenceType can be LLVMDisassembler_ReferenceType_In_Branch and then
777 * SymbolValue will be looked for in the indirect symbol table to determine if
778 * it is an address for a symbol stub. If so then the symbol name for that
779 * stub is returned indirectly through ReferenceName and then ReferenceType is
780 * set to LLVMDisassembler_ReferenceType_Out_SymbolStub.
782 * This may be called may also be called by the disassembler for such things
783 * like adding a comment for a PC plus a constant offset load instruction to use
784 * a symbol name instead of a load address value. In this case ReferenceType
785 * can be LLVMDisassembler_ReferenceType_In_PCrel_Load and the ReferencePC is
786 * also passed. In this case if the SymbolValue is an address in a literal
787 * pool then the referenced pointer in the literal pool is used for the returned
788 * ReferenceName and then ReferenceType. Which may be a symbol name and
789 * LLVMDisassembler_ReferenceType_Out_LitPool_SymAddr when the literal pool
790 * entry is the address of a symbol. Or a pointer to a literal cstring and
791 * LLVMDisassembler_ReferenceType_Out_LitPool_CstrAddr when the literal pool
792 * entry is the address of a literal cstring.
798 uint64_t SymbolValue
,
799 uint64_t *ReferenceType
,
800 uint64_t ReferencePC
,
801 const char **ReferenceName
)
803 struct disassemble_info
*info
;
804 const char *SymbolName
;
807 info
= (struct disassemble_info
*)DisInfo
;
808 if(info
->verbose
== FALSE
){
809 *ReferenceName
= NULL
;
810 *ReferenceType
= LLVMDisassembler_ReferenceType_InOut_None
;
813 SymbolName
= guess_symbol(SymbolValue
, info
->sorted_symbols
,
814 info
->nsorted_symbols
, TRUE
);
815 if(SymbolName
== NULL
&& info
->insts
!= NULL
&& info
->ninsts
!= 0){
816 for(i
= 0; i
< info
->ninsts
; i
++){
817 if(info
->insts
[i
].address
== SymbolValue
){
818 SymbolName
= info
->insts
[i
].tmp_label
;
824 if(*ReferenceType
== LLVMDisassembler_ReferenceType_In_Branch
){
825 *ReferenceName
= guess_indirect_symbol(SymbolValue
,
826 info
->ncmds
, info
->sizeofcmds
, info
->load_commands
,
827 info
->object_byte_sex
, info
->indirect_symbols
,
828 info
->nindirect_symbols
, info
->symbols
, NULL
,
829 info
->nsymbols
, info
->strings
, info
->strings_size
);
830 if(*ReferenceName
!= NULL
)
831 *ReferenceType
= LLVMDisassembler_ReferenceType_Out_SymbolStub
;
832 else if(SymbolName
!= NULL
&& strncmp(SymbolName
, "__Z", 3) == 0){
833 if(info
->demangled_name
!= NULL
)
834 free(info
->demangled_name
);
835 info
->demangled_name
= __cxa_demangle(SymbolName
+ 1, 0, 0, 0);
836 if(info
->demangled_name
!= NULL
){
837 *ReferenceName
= info
->demangled_name
;
839 LLVMDisassembler_ReferenceType_DeMangled_Name
;
842 *ReferenceType
= LLVMDisassembler_ReferenceType_InOut_None
;
845 *ReferenceType
= LLVMDisassembler_ReferenceType_InOut_None
;
846 if(info
->inst
!= NULL
&& SymbolName
== NULL
){
847 info
->inst
->has_raw_target_address
= TRUE
;
848 info
->inst
->raw_target_address
= SymbolValue
;
851 else if(*ReferenceType
== LLVMDisassembler_ReferenceType_In_PCrel_Load
){
852 *ReferenceName
= guess_literal_pointer(SymbolValue
, ReferencePC
,
853 ReferenceType
, info
);
854 if(*ReferenceName
== NULL
)
855 *ReferenceType
= LLVMDisassembler_ReferenceType_InOut_None
;
857 else if(SymbolName
!= NULL
&& strncmp(SymbolName
, "__Z", 3) == 0){
858 if(info
->demangled_name
!= NULL
)
859 free(info
->demangled_name
);
860 info
->demangled_name
= __cxa_demangle(SymbolName
+ 1, 0, 0, 0);
861 if(info
->demangled_name
!= NULL
){
862 *ReferenceName
= info
->demangled_name
;
864 LLVMDisassembler_ReferenceType_DeMangled_Name
;
868 *ReferenceName
= NULL
;
869 *ReferenceType
= LLVMDisassembler_ReferenceType_InOut_None
;
875 create_arm_llvm_disassembler(
876 cpu_subtype_t cpusubtype
)
878 LLVMDisasmContextRef dc
;
884 case CPU_SUBTYPE_ARM_V4T
:
885 TripleName
= "armv4t-apple-darwin10";
887 case CPU_SUBTYPE_ARM_V5TEJ
:
888 TripleName
= "armv5-apple-darwin10";
890 case CPU_SUBTYPE_ARM_XSCALE
:
891 TripleName
= "xscale-apple-darwin10";
893 case CPU_SUBTYPE_ARM_V6
:
894 TripleName
= "armv6-apple-darwin10";
896 case CPU_SUBTYPE_ARM_V6M
:
897 TripleName
= "armv6m-apple-darwin10";
898 if(*mcpu_default
== '\0')
899 mcpu_default
= "cortex-m0";
902 case CPU_SUBTYPE_ARM_V7
:
903 TripleName
= "armv7-apple-darwin10";
905 case CPU_SUBTYPE_ARM_V7F
:
906 TripleName
= "armv7f-apple-darwin10";
908 case CPU_SUBTYPE_ARM_V7S
:
909 TripleName
= "armv7s-apple-darwin10";
911 case CPU_SUBTYPE_ARM_V7K
:
912 TripleName
= "armv7k-apple-darwin10";
914 case CPU_SUBTYPE_ARM_V7M
:
915 TripleName
= "armv7m-apple-darwin10";
916 if(*mcpu_default
== '\0')
917 mcpu_default
= "cortex-m3";
919 case CPU_SUBTYPE_ARM_V7EM
:
920 TripleName
= "armv7em-apple-darwin10";
921 if(*mcpu_default
== '\0')
922 mcpu_default
= "cortex-m4";
932 (TripleName
, mcpu_default
, &dis_info
, 1, GetOpInfo
, SymbolLookUp
);
937 delete_arm_llvm_disassembler(
938 LLVMDisasmContextRef dc
)
949 create_thumb_llvm_disassembler(
950 cpu_subtype_t cpusubtype
)
952 LLVMDisasmContextRef dc
;
958 case CPU_SUBTYPE_ARM_V4T
:
959 TripleName
= "thumbv4t-apple-darwin10";
961 case CPU_SUBTYPE_ARM_V5TEJ
:
962 TripleName
= "thumbv5-apple-darwin10";
964 case CPU_SUBTYPE_ARM_XSCALE
:
965 TripleName
= "xscale-apple-darwin10";
967 case CPU_SUBTYPE_ARM_V6
:
968 TripleName
= "thumbv6-apple-darwin10";
970 case CPU_SUBTYPE_ARM_V6M
:
971 TripleName
= "thumbv6m-apple-darwin10";
972 if(*mcpu_default
== '\0')
973 mcpu_default
= "cortex-m0";
976 case CPU_SUBTYPE_ARM_V7
:
977 TripleName
= "thumbv7-apple-darwin10";
979 case CPU_SUBTYPE_ARM_V7F
:
980 TripleName
= "thumbv7f-apple-darwin10";
982 case CPU_SUBTYPE_ARM_V7S
:
983 TripleName
= "thumbv7s-apple-darwin10";
985 case CPU_SUBTYPE_ARM_V7K
:
986 TripleName
= "thumbv7k-apple-darwin10";
988 case CPU_SUBTYPE_ARM_V7M
:
989 TripleName
= "thumbv7m-apple-darwin10";
990 if(*mcpu_default
== '\0')
991 mcpu_default
= "cortex-m3";
993 case CPU_SUBTYPE_ARM_V7EM
:
994 TripleName
= "thumbv7em-apple-darwin10";
995 if(*mcpu_default
== '\0')
996 mcpu_default
= "cortex-m4";
1006 (TripleName
, mcpu_default
, &dis_info
, 1, GetOpInfo
,
1012 delete_thumb_llvm_disassembler(
1013 LLVMDisasmContextRef dc
)
1023 /* HACKS to avoid pulling in FSF binutils bfd/bfd-in2.h */
1024 #define bfd_mach_arm_XScale 10
1025 #define bfd_mach_arm_iWMMXt 12
1026 #define bfd_mach_arm_iWMMXt2 13
1030 uint32_t arch
; /* Architecture defining this insn. */
1031 uint32_t value
, mask
; /* Recognise insn if (op&mask)==value. */
1032 const char *assembler
; /* How to disassemble this insn. */
1037 uint32_t arch
; /* Architecture defining this insn. */
1038 unsigned short value
, mask
; /* Recognise insn if (op&mask)==value. */
1039 const char *assembler
; /* How to disassemble this insn. */
1042 /* print_insn_coprocessor recognizes the following format control codes:
1046 %c print condition code (always bits 28-31 in ARM mode)
1047 %q print shifter argument
1048 %u print condition code (unconditional in ARM mode)
1049 %A print address for ldc/stc/ldf/stf instruction
1050 %B print vstm/vldm register list
1051 %C print vstr/vldr address operand
1052 %I print cirrus signed shift immediate: bits 0..3|4..6
1053 %F print the COUNT field of a LFM/SFM instruction.
1054 %P print floating point precision in arithmetic insn
1055 %Q print floating point precision in ldf/stf insn
1056 %R print floating point rounding mode
1058 %<bitfield>r print as an ARM register
1059 %<bitfield>d print the bitfield in decimal
1060 %<bitfield>k print immediate for VFPv3 conversion instruction
1061 %<bitfield>x print the bitfield in hex
1062 %<bitfield>X print the bitfield as 1 hex digit without leading "0x"
1063 %<bitfield>f print a floating point constant if >7 else a
1064 floating point register
1065 %<bitfield>w print as an iWMMXt width field - [bhwd]ss/us
1066 %<bitfield>g print as an iWMMXt 64-bit register
1067 %<bitfield>G print as an iWMMXt general purpose or control register
1068 %<bitfield>D print as a NEON D register
1069 %<bitfield>Q print as a NEON Q register
1071 %y<code> print a single precision VFP reg.
1072 Codes: 0=>Sm, 1=>Sd, 2=>Sn, 3=>multi-list, 4=>Sm pair
1073 %z<code> print a double precision VFP reg
1074 Codes: 0=>Dm, 1=>Dd, 2=>Dn, 3=>multi-list
1076 %<bitfield>'c print specified char iff bitfield is all ones
1077 %<bitfield>`c print specified char iff bitfield is all zeroes
1078 %<bitfield>?ab... select from array of values in big endian order
1080 %L print as an iWMMXt N/M width field.
1081 %Z print the Immediate of a WSHUFH instruction.
1082 %l like 'A' except use byte offsets for 'B' & 'H'
1084 %i print 5-bit immediate in bits 8,3..0
1086 %r print register offset address for wldt/wstr instruction
1089 /* Common coprocessor opcodes shared between Arm and Thumb-2. */
1091 static const struct opcode32 coprocessor_opcodes
[] =
1093 /* XScale instructions. */
1094 {ARM_CEXT_XSCALE
, 0x0e200010, 0x0fff0ff0, "mia%c\tacc0, %0-3r, %12-15r"},
1095 {ARM_CEXT_XSCALE
, 0x0e280010, 0x0fff0ff0, "miaph%c\tacc0, %0-3r, %12-15r"},
1096 {ARM_CEXT_XSCALE
, 0x0e2c0010, 0x0ffc0ff0, "mia%17'T%17`B%16'T%16`B%c\tacc0, %0-3r, %12-15r"},
1097 {ARM_CEXT_XSCALE
, 0x0c400000, 0x0ff00fff, "mar%c\tacc0, %12-15r, %16-19r"},
1098 {ARM_CEXT_XSCALE
, 0x0c500000, 0x0ff00fff, "mra%c\t%12-15r, %16-19r, acc0"},
1100 /* Intel Wireless MMX technology instructions. */
1101 #define FIRST_IWMMXT_INSN 0x0e130130
1102 #define IWMMXT_INSN_COUNT 73
1103 {ARM_CEXT_IWMMXT
, 0x0e130130, 0x0f3f0fff, "tandc%22-23w%c\t%12-15r"},
1104 {ARM_CEXT_XSCALE
, 0x0e400010, 0x0ff00f3f, "tbcst%6-7w%c\t%16-19g, %12-15r"},
1105 {ARM_CEXT_XSCALE
, 0x0e130170, 0x0f3f0ff8, "textrc%22-23w%c\t%12-15r, #%0-2d"},
1106 {ARM_CEXT_XSCALE
, 0x0e100070, 0x0f300ff0, "textrm%3?su%22-23w%c\t%12-15r, %16-19g, #%0-2d"},
1107 {ARM_CEXT_XSCALE
, 0x0e600010, 0x0ff00f38, "tinsr%6-7w%c\t%16-19g, %12-15r, #%0-2d"},
1108 {ARM_CEXT_XSCALE
, 0x0e000110, 0x0ff00fff, "tmcr%c\t%16-19G, %12-15r"},
1109 {ARM_CEXT_XSCALE
, 0x0c400000, 0x0ff00ff0, "tmcrr%c\t%0-3g, %12-15r, %16-19r"},
1110 {ARM_CEXT_XSCALE
, 0x0e2c0010, 0x0ffc0e10, "tmia%17?tb%16?tb%c\t%5-8g, %0-3r, %12-15r"},
1111 {ARM_CEXT_XSCALE
, 0x0e200010, 0x0fff0e10, "tmia%c\t%5-8g, %0-3r, %12-15r"},
1112 {ARM_CEXT_XSCALE
, 0x0e280010, 0x0fff0e10, "tmiaph%c\t%5-8g, %0-3r, %12-15r"},
1113 {ARM_CEXT_XSCALE
, 0x0e100030, 0x0f300fff, "tmovmsk%22-23w%c\t%12-15r, %16-19g"},
1114 {ARM_CEXT_XSCALE
, 0x0e100110, 0x0ff00ff0, "tmrc%c\t%12-15r, %16-19G"},
1115 {ARM_CEXT_XSCALE
, 0x0c500000, 0x0ff00ff0, "tmrrc%c\t%12-15r, %16-19r, %0-3g"},
1116 {ARM_CEXT_XSCALE
, 0x0e130150, 0x0f3f0fff, "torc%22-23w%c\t%12-15r"},
1117 {ARM_CEXT_XSCALE
, 0x0e130190, 0x0f3f0fff, "torvsc%22-23w%c\t%12-15r"},
1118 {ARM_CEXT_XSCALE
, 0x0e2001c0, 0x0f300fff, "wabs%22-23w%c\t%12-15g, %16-19g"},
1119 {ARM_CEXT_XSCALE
, 0x0e0001c0, 0x0f300fff, "wacc%22-23w%c\t%12-15g, %16-19g"},
1120 {ARM_CEXT_XSCALE
, 0x0e000180, 0x0f000ff0, "wadd%20-23w%c\t%12-15g, %16-19g, %0-3g"},
1121 {ARM_CEXT_XSCALE
, 0x0e2001a0, 0x0f300ff0, "waddbhus%22?ml%c\t%12-15g, %16-19g, %0-3g"},
1122 {ARM_CEXT_XSCALE
, 0x0ea001a0, 0x0ff00ff0, "waddsubhx%c\t%12-15g, %16-19g, %0-3g"},
1123 {ARM_CEXT_XSCALE
, 0x0e000020, 0x0f800ff0, "waligni%c\t%12-15g, %16-19g, %0-3g, #%20-22d"},
1124 {ARM_CEXT_XSCALE
, 0x0e800020, 0x0fc00ff0, "walignr%20-21d%c\t%12-15g, %16-19g, %0-3g"},
1125 {ARM_CEXT_XSCALE
, 0x0e200000, 0x0fe00ff0, "wand%20'n%c\t%12-15g, %16-19g, %0-3g"},
1126 {ARM_CEXT_XSCALE
, 0x0e800000, 0x0fa00ff0, "wavg2%22?hb%20'r%c\t%12-15g, %16-19g, %0-3g"},
1127 {ARM_CEXT_XSCALE
, 0x0e400000, 0x0fe00ff0, "wavg4%20'r%c\t%12-15g, %16-19g, %0-3g"},
1128 {ARM_CEXT_XSCALE
, 0x0e000060, 0x0f300ff0, "wcmpeq%22-23w%c\t%12-15g, %16-19g, %0-3g"},
1129 {ARM_CEXT_XSCALE
, 0x0e100060, 0x0f100ff0, "wcmpgt%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
1130 {ARM_CEXT_XSCALE
, 0xfc500100, 0xfe500f00, "wldrd\t%12-15g, %r"},
1131 {ARM_CEXT_XSCALE
, 0xfc100100, 0xfe500f00, "wldrw\t%12-15G, %A"},
1132 {ARM_CEXT_XSCALE
, 0x0c100000, 0x0e100e00, "wldr%L%c\t%12-15g, %l"},
1133 {ARM_CEXT_XSCALE
, 0x0e400100, 0x0fc00ff0, "wmac%21?su%20'z%c\t%12-15g, %16-19g, %0-3g"},
1134 {ARM_CEXT_XSCALE
, 0x0e800100, 0x0fc00ff0, "wmadd%21?su%20'x%c\t%12-15g, %16-19g, %0-3g"},
1135 {ARM_CEXT_XSCALE
, 0x0ec00100, 0x0fd00ff0, "wmadd%21?sun%c\t%12-15g, %16-19g, %0-3g"},
1136 {ARM_CEXT_XSCALE
, 0x0e000160, 0x0f100ff0, "wmax%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
1137 {ARM_CEXT_XSCALE
, 0x0e000080, 0x0f100fe0, "wmerge%c\t%12-15g, %16-19g, %0-3g, #%21-23d"},
1138 {ARM_CEXT_XSCALE
, 0x0e0000a0, 0x0f800ff0, "wmia%21?tb%20?tb%22'n%c\t%12-15g, %16-19g, %0-3g"},
1139 {ARM_CEXT_XSCALE
, 0x0e800120, 0x0f800ff0, "wmiaw%21?tb%20?tb%22'n%c\t%12-15g, %16-19g, %0-3g"},
1140 {ARM_CEXT_XSCALE
, 0x0e100160, 0x0f100ff0, "wmin%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
1141 {ARM_CEXT_XSCALE
, 0x0e000100, 0x0fc00ff0, "wmul%21?su%20?ml%23'r%c\t%12-15g, %16-19g, %0-3g"},
1142 {ARM_CEXT_XSCALE
, 0x0ed00100, 0x0fd00ff0, "wmul%21?sumr%c\t%12-15g, %16-19g, %0-3g"},
1143 {ARM_CEXT_XSCALE
, 0x0ee000c0, 0x0fe00ff0, "wmulwsm%20`r%c\t%12-15g, %16-19g, %0-3g"},
1144 {ARM_CEXT_XSCALE
, 0x0ec000c0, 0x0fe00ff0, "wmulwum%20`r%c\t%12-15g, %16-19g, %0-3g"},
1145 {ARM_CEXT_XSCALE
, 0x0eb000c0, 0x0ff00ff0, "wmulwl%c\t%12-15g, %16-19g, %0-3g"},
1146 {ARM_CEXT_XSCALE
, 0x0e8000a0, 0x0f800ff0, "wqmia%21?tb%20?tb%22'n%c\t%12-15g, %16-19g, %0-3g"},
1147 {ARM_CEXT_XSCALE
, 0x0e100080, 0x0fd00ff0, "wqmulm%21'r%c\t%12-15g, %16-19g, %0-3g"},
1148 {ARM_CEXT_XSCALE
, 0x0ec000e0, 0x0fd00ff0, "wqmulwm%21'r%c\t%12-15g, %16-19g, %0-3g"},
1149 {ARM_CEXT_XSCALE
, 0x0e000000, 0x0ff00ff0, "wor%c\t%12-15g, %16-19g, %0-3g"},
1150 {ARM_CEXT_XSCALE
, 0x0e000080, 0x0f000ff0, "wpack%20-23w%c\t%12-15g, %16-19g, %0-3g"},
1151 {ARM_CEXT_XSCALE
, 0xfe300040, 0xff300ef0, "wror%22-23w\t%12-15g, %16-19g, #%i"},
1152 {ARM_CEXT_XSCALE
, 0x0e300040, 0x0f300ff0, "wror%22-23w%c\t%12-15g, %16-19g, %0-3g"},
1153 {ARM_CEXT_XSCALE
, 0x0e300140, 0x0f300ff0, "wror%22-23wg%c\t%12-15g, %16-19g, %0-3G"},
1154 {ARM_CEXT_XSCALE
, 0x0e000120, 0x0fa00ff0, "wsad%22?hb%20'z%c\t%12-15g, %16-19g, %0-3g"},
1155 {ARM_CEXT_XSCALE
, 0x0e0001e0, 0x0f000ff0, "wshufh%c\t%12-15g, %16-19g, #%Z"},
1156 {ARM_CEXT_XSCALE
, 0xfe100040, 0xff300ef0, "wsll%22-23w\t%12-15g, %16-19g, #%i"},
1157 {ARM_CEXT_XSCALE
, 0x0e100040, 0x0f300ff0, "wsll%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
1158 {ARM_CEXT_XSCALE
, 0x0e100148, 0x0f300ffc, "wsll%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
1159 {ARM_CEXT_XSCALE
, 0xfe000040, 0xff300ef0, "wsra%22-23w\t%12-15g, %16-19g, #%i"},
1160 {ARM_CEXT_XSCALE
, 0x0e000040, 0x0f300ff0, "wsra%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
1161 {ARM_CEXT_XSCALE
, 0x0e000148, 0x0f300ffc, "wsra%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
1162 {ARM_CEXT_XSCALE
, 0xfe200040, 0xff300ef0, "wsrl%22-23w\t%12-15g, %16-19g, #%i"},
1163 {ARM_CEXT_XSCALE
, 0x0e200040, 0x0f300ff0, "wsrl%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
1164 {ARM_CEXT_XSCALE
, 0x0e200148, 0x0f300ffc, "wsrl%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
1165 {ARM_CEXT_XSCALE
, 0xfc400100, 0xfe500f00, "wstrd\t%12-15g, %r"},
1166 {ARM_CEXT_XSCALE
, 0xfc000100, 0xfe500f00, "wstrw\t%12-15G, %A"},
1167 {ARM_CEXT_XSCALE
, 0x0c000000, 0x0e100e00, "wstr%L%c\t%12-15g, %l"},
1168 {ARM_CEXT_XSCALE
, 0x0e0001a0, 0x0f000ff0, "wsub%20-23w%c\t%12-15g, %16-19g, %0-3g"},
1169 {ARM_CEXT_XSCALE
, 0x0ed001c0, 0x0ff00ff0, "wsubaddhx%c\t%12-15g, %16-19g, %0-3g"},
1170 {ARM_CEXT_XSCALE
, 0x0e1001c0, 0x0f300ff0, "wabsdiff%22-23w%c\t%12-15g, %16-19g, %0-3g"},
1171 {ARM_CEXT_XSCALE
, 0x0e0000c0, 0x0fd00fff, "wunpckeh%21?sub%c\t%12-15g, %16-19g"},
1172 {ARM_CEXT_XSCALE
, 0x0e4000c0, 0x0fd00fff, "wunpckeh%21?suh%c\t%12-15g, %16-19g"},
1173 {ARM_CEXT_XSCALE
, 0x0e8000c0, 0x0fd00fff, "wunpckeh%21?suw%c\t%12-15g, %16-19g"},
1174 {ARM_CEXT_XSCALE
, 0x0e0000e0, 0x0f100fff, "wunpckel%21?su%22-23w%c\t%12-15g, %16-19g"},
1175 {ARM_CEXT_XSCALE
, 0x0e1000c0, 0x0f300ff0, "wunpckih%22-23w%c\t%12-15g, %16-19g, %0-3g"},
1176 {ARM_CEXT_XSCALE
, 0x0e1000e0, 0x0f300ff0, "wunpckil%22-23w%c\t%12-15g, %16-19g, %0-3g"},
1177 {ARM_CEXT_XSCALE
, 0x0e100000, 0x0ff00ff0, "wxor%c\t%12-15g, %16-19g, %0-3g"},
1179 /* Floating point coprocessor (FPA) instructions */
1180 {FPU_FPA_EXT_V1
, 0x0e000100, 0x0ff08f10, "adf%c%P%R\t%12-14f, %16-18f, %0-3f"},
1181 {FPU_FPA_EXT_V1
, 0x0e100100, 0x0ff08f10, "muf%c%P%R\t%12-14f, %16-18f, %0-3f"},
1182 {FPU_FPA_EXT_V1
, 0x0e200100, 0x0ff08f10, "suf%c%P%R\t%12-14f, %16-18f, %0-3f"},
1183 {FPU_FPA_EXT_V1
, 0x0e300100, 0x0ff08f10, "rsf%c%P%R\t%12-14f, %16-18f, %0-3f"},
1184 {FPU_FPA_EXT_V1
, 0x0e400100, 0x0ff08f10, "dvf%c%P%R\t%12-14f, %16-18f, %0-3f"},
1185 {FPU_FPA_EXT_V1
, 0x0e500100, 0x0ff08f10, "rdf%c%P%R\t%12-14f, %16-18f, %0-3f"},
1186 {FPU_FPA_EXT_V1
, 0x0e600100, 0x0ff08f10, "pow%c%P%R\t%12-14f, %16-18f, %0-3f"},
1187 {FPU_FPA_EXT_V1
, 0x0e700100, 0x0ff08f10, "rpw%c%P%R\t%12-14f, %16-18f, %0-3f"},
1188 {FPU_FPA_EXT_V1
, 0x0e800100, 0x0ff08f10, "rmf%c%P%R\t%12-14f, %16-18f, %0-3f"},
1189 {FPU_FPA_EXT_V1
, 0x0e900100, 0x0ff08f10, "fml%c%P%R\t%12-14f, %16-18f, %0-3f"},
1190 {FPU_FPA_EXT_V1
, 0x0ea00100, 0x0ff08f10, "fdv%c%P%R\t%12-14f, %16-18f, %0-3f"},
1191 {FPU_FPA_EXT_V1
, 0x0eb00100, 0x0ff08f10, "frd%c%P%R\t%12-14f, %16-18f, %0-3f"},
1192 {FPU_FPA_EXT_V1
, 0x0ec00100, 0x0ff08f10, "pol%c%P%R\t%12-14f, %16-18f, %0-3f"},
1193 {FPU_FPA_EXT_V1
, 0x0e008100, 0x0ff08f10, "mvf%c%P%R\t%12-14f, %0-3f"},
1194 {FPU_FPA_EXT_V1
, 0x0e108100, 0x0ff08f10, "mnf%c%P%R\t%12-14f, %0-3f"},
1195 {FPU_FPA_EXT_V1
, 0x0e208100, 0x0ff08f10, "abs%c%P%R\t%12-14f, %0-3f"},
1196 {FPU_FPA_EXT_V1
, 0x0e308100, 0x0ff08f10, "rnd%c%P%R\t%12-14f, %0-3f"},
1197 {FPU_FPA_EXT_V1
, 0x0e408100, 0x0ff08f10, "sqt%c%P%R\t%12-14f, %0-3f"},
1198 {FPU_FPA_EXT_V1
, 0x0e508100, 0x0ff08f10, "log%c%P%R\t%12-14f, %0-3f"},
1199 {FPU_FPA_EXT_V1
, 0x0e608100, 0x0ff08f10, "lgn%c%P%R\t%12-14f, %0-3f"},
1200 {FPU_FPA_EXT_V1
, 0x0e708100, 0x0ff08f10, "exp%c%P%R\t%12-14f, %0-3f"},
1201 {FPU_FPA_EXT_V1
, 0x0e808100, 0x0ff08f10, "sin%c%P%R\t%12-14f, %0-3f"},
1202 {FPU_FPA_EXT_V1
, 0x0e908100, 0x0ff08f10, "cos%c%P%R\t%12-14f, %0-3f"},
1203 {FPU_FPA_EXT_V1
, 0x0ea08100, 0x0ff08f10, "tan%c%P%R\t%12-14f, %0-3f"},
1204 {FPU_FPA_EXT_V1
, 0x0eb08100, 0x0ff08f10, "asn%c%P%R\t%12-14f, %0-3f"},
1205 {FPU_FPA_EXT_V1
, 0x0ec08100, 0x0ff08f10, "acs%c%P%R\t%12-14f, %0-3f"},
1206 {FPU_FPA_EXT_V1
, 0x0ed08100, 0x0ff08f10, "atn%c%P%R\t%12-14f, %0-3f"},
1207 {FPU_FPA_EXT_V1
, 0x0ee08100, 0x0ff08f10, "urd%c%P%R\t%12-14f, %0-3f"},
1208 {FPU_FPA_EXT_V1
, 0x0ef08100, 0x0ff08f10, "nrm%c%P%R\t%12-14f, %0-3f"},
1209 {FPU_FPA_EXT_V1
, 0x0e000110, 0x0ff00f1f, "flt%c%P%R\t%16-18f, %12-15r"},
1210 {FPU_FPA_EXT_V1
, 0x0e100110, 0x0fff0f98, "fix%c%R\t%12-15r, %0-2f"},
1211 {FPU_FPA_EXT_V1
, 0x0e200110, 0x0fff0fff, "wfs%c\t%12-15r"},
1212 {FPU_FPA_EXT_V1
, 0x0e300110, 0x0fff0fff, "rfs%c\t%12-15r"},
1213 {FPU_FPA_EXT_V1
, 0x0e400110, 0x0fff0fff, "wfc%c\t%12-15r"},
1214 {FPU_FPA_EXT_V1
, 0x0e500110, 0x0fff0fff, "rfc%c\t%12-15r"},
1215 {FPU_FPA_EXT_V1
, 0x0e90f110, 0x0ff8fff0, "cmf%c\t%16-18f, %0-3f"},
1216 {FPU_FPA_EXT_V1
, 0x0eb0f110, 0x0ff8fff0, "cnf%c\t%16-18f, %0-3f"},
1217 {FPU_FPA_EXT_V1
, 0x0ed0f110, 0x0ff8fff0, "cmfe%c\t%16-18f, %0-3f"},
1218 {FPU_FPA_EXT_V1
, 0x0ef0f110, 0x0ff8fff0, "cnfe%c\t%16-18f, %0-3f"},
1219 {FPU_FPA_EXT_V1
, 0x0c000100, 0x0e100f00, "stf%c%Q\t%12-14f, %A"},
1220 {FPU_FPA_EXT_V1
, 0x0c100100, 0x0e100f00, "ldf%c%Q\t%12-14f, %A"},
1221 {FPU_FPA_EXT_V2
, 0x0c000200, 0x0e100f00, "sfm%c\t%12-14f, %F, %A"},
1222 {FPU_FPA_EXT_V2
, 0x0c100200, 0x0e100f00, "lfm%c\t%12-14f, %F, %A"},
1224 /* Register load/store */
1225 {FPU_NEON_EXT_V1
, 0x0d200b00, 0x0fb00f01, "vstmdb%c\t%16-19r%21'!, %B"},
1226 {FPU_NEON_EXT_V1
, 0x0d300b00, 0x0fb00f01, "vldmdb%c\t%16-19r%21'!, %B"},
1227 {FPU_NEON_EXT_V1
, 0x0c800b00, 0x0f900f01, "vstmia%c\t%16-19r%21'!, %B"},
1228 {FPU_NEON_EXT_V1
, 0x0c900b00, 0x0f900f01, "vldmia%c\t%16-19r%21'!, %B"},
1229 {FPU_NEON_EXT_V1
, 0x0d000b00, 0x0f300f00, "vstr%c\t%12-15,22D, %C"},
1230 {FPU_NEON_EXT_V1
, 0x0d100b00, 0x0f300f00, "vldr%c\t%12-15,22D, %C"},
1232 /* Data transfer between ARM and NEON registers */
1233 {FPU_NEON_EXT_V1
, 0x0e800b10, 0x0ff00f70, "vdup%c.32\t%16-19,7D, %12-15r"},
1234 {FPU_NEON_EXT_V1
, 0x0e800b30, 0x0ff00f70, "vdup%c.16\t%16-19,7D, %12-15r"},
1235 {FPU_NEON_EXT_V1
, 0x0ea00b10, 0x0ff00f70, "vdup%c.32\t%16-19,7Q, %12-15r"},
1236 {FPU_NEON_EXT_V1
, 0x0ea00b30, 0x0ff00f70, "vdup%c.16\t%16-19,7Q, %12-15r"},
1237 {FPU_NEON_EXT_V1
, 0x0ec00b10, 0x0ff00f70, "vdup%c.8\t%16-19,7D, %12-15r"},
1238 {FPU_NEON_EXT_V1
, 0x0ee00b10, 0x0ff00f70, "vdup%c.8\t%16-19,7Q, %12-15r"},
1239 {FPU_NEON_EXT_V1
, 0x0c400b10, 0x0ff00fd0, "vmov%c\t%0-3,5D, %12-15r, %16-19r"},
1240 {FPU_NEON_EXT_V1
, 0x0c500b10, 0x0ff00fd0, "vmov%c\t%12-15r, %16-19r, %0-3,5D"},
1241 {FPU_NEON_EXT_V1
, 0x0e000b10, 0x0fd00f70, "vmov%c.32\t%16-19,7D[%21d], %12-15r"},
1242 {FPU_NEON_EXT_V1
, 0x0e100b10, 0x0f500f70, "vmov%c.32\t%12-15r, %16-19,7D[%21d]"},
1243 {FPU_NEON_EXT_V1
, 0x0e000b30, 0x0fd00f30, "vmov%c.16\t%16-19,7D[%6,21d], %12-15r"},
1244 {FPU_NEON_EXT_V1
, 0x0e100b30, 0x0f500f30, "vmov%c.%23?us16\t%12-15r, %16-19,7D[%6,21d]"},
1245 {FPU_NEON_EXT_V1
, 0x0e400b10, 0x0fd00f10, "vmov%c.8\t%16-19,7D[%5,6,21d], %12-15r"},
1246 {FPU_NEON_EXT_V1
, 0x0e500b10, 0x0f500f10, "vmov%c.%23?us8\t%12-15r, %16-19,7D[%5,6,21d]"},
1248 /* Floating point coprocessor (VFP) instructions */
1249 {FPU_VFP_EXT_V1xD
, 0x0ef1fa10, 0x0fffffff, "fmstat%c"},
1250 {FPU_VFP_EXT_V1xD
, 0x0ee00a10, 0x0fff0fff, "fmxr%c\tfpsid, %12-15r"},
1251 {FPU_VFP_EXT_V1xD
, 0x0ee10a10, 0x0fff0fff, "fmxr%c\tfpscr, %12-15r"},
1252 {FPU_VFP_EXT_V1xD
, 0x0ee60a10, 0x0fff0fff, "fmxr%c\tmvfr1, %12-15r"},
1253 {FPU_VFP_EXT_V1xD
, 0x0ee70a10, 0x0fff0fff, "fmxr%c\tmvfr0, %12-15r"},
1254 {FPU_VFP_EXT_V1xD
, 0x0ee80a10, 0x0fff0fff, "fmxr%c\tfpexc, %12-15r"},
1255 {FPU_VFP_EXT_V1xD
, 0x0ee90a10, 0x0fff0fff, "fmxr%c\tfpinst, %12-15r\t@ Impl def"},
1256 {FPU_VFP_EXT_V1xD
, 0x0eea0a10, 0x0fff0fff, "fmxr%c\tfpinst2, %12-15r\t@ Impl def"},
1257 {FPU_VFP_EXT_V1xD
, 0x0ef00a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpsid"},
1258 {FPU_VFP_EXT_V1xD
, 0x0ef10a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpscr"},
1259 {FPU_VFP_EXT_V1xD
, 0x0ef60a10, 0x0fff0fff, "fmrx%c\t%12-15r, mvfr1"},
1260 {FPU_VFP_EXT_V1xD
, 0x0ef70a10, 0x0fff0fff, "fmrx%c\t%12-15r, mvfr0"},
1261 {FPU_VFP_EXT_V1xD
, 0x0ef80a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpexc"},
1262 {FPU_VFP_EXT_V1xD
, 0x0ef90a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpinst\t@ Impl def"},
1263 {FPU_VFP_EXT_V1xD
, 0x0efa0a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpinst2\t@ Impl def"},
1264 {FPU_VFP_EXT_V1
, 0x0e000b10, 0x0ff00fff, "fmdlr%c\t%z2, %12-15r"},
1265 {FPU_VFP_EXT_V1
, 0x0e100b10, 0x0ff00fff, "fmrdl%c\t%12-15r, %z2"},
1266 {FPU_VFP_EXT_V1
, 0x0e200b10, 0x0ff00fff, "fmdhr%c\t%z2, %12-15r"},
1267 {FPU_VFP_EXT_V1
, 0x0e300b10, 0x0ff00fff, "fmrdh%c\t%12-15r, %z2"},
1268 {FPU_VFP_EXT_V1xD
, 0x0ee00a10, 0x0ff00fff, "fmxr%c\t<impl def %16-19x>, %12-15r"},
1269 {FPU_VFP_EXT_V1xD
, 0x0ef00a10, 0x0ff00fff, "fmrx%c\t%12-15r, <impl def %16-19x>"},
1270 {FPU_VFP_EXT_V1xD
, 0x0e000a10, 0x0ff00f7f, "fmsr%c\t%y2, %12-15r"},
1271 {FPU_VFP_EXT_V1xD
, 0x0e100a10, 0x0ff00f7f, "fmrs%c\t%12-15r, %y2"},
1272 {FPU_VFP_EXT_V1xD
, 0x0eb50a40, 0x0fbf0f70, "fcmp%7'ezs%c\t%y1"},
1273 {FPU_VFP_EXT_V1
, 0x0eb50b40, 0x0fbf0f70, "fcmp%7'ezd%c\t%z1"},
1274 {FPU_VFP_EXT_V1xD
, 0x0eb00a40, 0x0fbf0fd0, "fcpys%c\t%y1, %y0"},
1275 {FPU_VFP_EXT_V1xD
, 0x0eb00ac0, 0x0fbf0fd0, "fabss%c\t%y1, %y0"},
1276 {FPU_VFP_EXT_V1
, 0x0eb00b40, 0x0fbf0fd0, "fcpyd%c\t%z1, %z0"},
1277 {FPU_VFP_EXT_V1
, 0x0eb00bc0, 0x0fbf0fd0, "fabsd%c\t%z1, %z0"},
1278 {FPU_VFP_EXT_V1xD
, 0x0eb10a40, 0x0fbf0fd0, "fnegs%c\t%y1, %y0"},
1279 {FPU_VFP_EXT_V1xD
, 0x0eb10ac0, 0x0fbf0fd0, "fsqrts%c\t%y1, %y0"},
1280 {FPU_VFP_EXT_V1
, 0x0eb10b40, 0x0fbf0fd0, "fnegd%c\t%z1, %z0"},
1281 {FPU_VFP_EXT_V1
, 0x0eb10bc0, 0x0fbf0fd0, "fsqrtd%c\t%z1, %z0"},
1282 {FPU_VFP_EXT_V1
, 0x0eb70ac0, 0x0fbf0fd0, "fcvtds%c\t%z1, %y0"},
1283 {FPU_VFP_EXT_V1
, 0x0eb70bc0, 0x0fbf0fd0, "fcvtsd%c\t%y1, %z0"},
1284 {FPU_VFP_EXT_V1
, 0x0eb30ac0, 0x0fbf0fd0, "fcvttshp%c\t%y1, %y0"},
1285 {FPU_VFP_EXT_V1
, 0x0eb30a40, 0x0fbf0fd0, "fcvtbshp%c\t%y1, %y0"},
1286 {FPU_VFP_EXT_V1
, 0x0eb20ac0, 0x0fbf0fd0, "fcvtthps%c\t%y1, %y0"},
1287 {FPU_VFP_EXT_V1
, 0x0eb20a40, 0x0fbf0fd0, "fcvtbhps%c\t%y1, %y0"},
1289 {FPU_VFP_EXT_V1xD
, 0x0eb80a40, 0x0fbf0fd0, "fuitos%c\t%y1, %y0"},
1290 {FPU_VFP_EXT_V1xD
, 0x0eb80ac0, 0x0fbf0fd0, "fsitos%c\t%y1, %y0"},
1291 {FPU_VFP_EXT_V1
, 0x0eb80b40, 0x0fbf0fd0, "fuitod%c\t%z1, %y0"},
1292 {FPU_VFP_EXT_V1
, 0x0eb80bc0, 0x0fbf0fd0, "fsitod%c\t%z1, %y0"},
1293 {FPU_VFP_EXT_V1xD
, 0x0eb40a40, 0x0fbf0f50, "fcmp%7'es%c\t%y1, %y0"},
1294 {FPU_VFP_EXT_V1
, 0x0eb40b40, 0x0fbf0f50, "fcmp%7'ed%c\t%z1, %z0"},
1295 {FPU_VFP_EXT_V3
, 0x0eba0a40, 0x0fbe0f50, "f%16?us%7?lhtos%c\t%y1, #%5,0-3k"},
1296 {FPU_VFP_EXT_V3
, 0x0eba0b40, 0x0fbe0f50, "f%16?us%7?lhtod%c\t%z1, #%5,0-3k"},
1297 {FPU_VFP_EXT_V1xD
, 0x0ebc0a40, 0x0fbe0f50, "fto%16?sui%7'zs%c\t%y1, %y0"},
1298 {FPU_VFP_EXT_V1
, 0x0ebc0b40, 0x0fbe0f50, "fto%16?sui%7'zd%c\t%y1, %z0"},
1299 {FPU_VFP_EXT_V3
, 0x0ebe0a40, 0x0fbe0f50, "fto%16?us%7?lhs%c\t%y1, #%5,0-3k"},
1300 {FPU_VFP_EXT_V3
, 0x0ebe0b40, 0x0fbe0f50, "fto%16?us%7?lhd%c\t%z1, #%5,0-3k"},
1301 {FPU_VFP_EXT_V1
, 0x0c500b10, 0x0fb00ff0, "fmrrd%c\t%12-15r, %16-19r, %z0"},
1302 {FPU_VFP_EXT_V3
, 0x0eb00a00, 0x0fb00ff0, "fconsts%c\t%y1, #%0-3,16-19d"},
1303 {FPU_VFP_EXT_V3
, 0x0eb00b00, 0x0fb00ff0, "fconstd%c\t%z1, #%0-3,16-19d"},
1304 {FPU_VFP_EXT_V2
, 0x0c400a10, 0x0ff00fd0, "fmsrr%c\t%y4, %12-15r, %16-19r"},
1305 {FPU_VFP_EXT_V2
, 0x0c400b10, 0x0ff00fd0, "fmdrr%c\t%z0, %12-15r, %16-19r"},
1306 {FPU_VFP_EXT_V2
, 0x0c500a10, 0x0ff00fd0, "fmrrs%c\t%12-15r, %16-19r, %y4"},
1307 {FPU_VFP_EXT_V1xD
, 0x0e000a00, 0x0fb00f50, "fmacs%c\t%y1, %y2, %y0"},
1308 {FPU_VFP_EXT_V1xD
, 0x0e000a40, 0x0fb00f50, "fnmacs%c\t%y1, %y2, %y0"},
1309 {FPU_VFP_EXT_V1
, 0x0e000b00, 0x0fb00f50, "fmacd%c\t%z1, %z2, %z0"},
1310 {FPU_VFP_EXT_V1
, 0x0e000b40, 0x0fb00f50, "fnmacd%c\t%z1, %z2, %z0"},
1311 {FPU_VFP_EXT_V1xD
, 0x0e100a00, 0x0fb00f50, "fmscs%c\t%y1, %y2, %y0"},
1312 {FPU_VFP_EXT_V1xD
, 0x0e100a40, 0x0fb00f50, "fnmscs%c\t%y1, %y2, %y0"},
1313 {FPU_VFP_EXT_V1
, 0x0e100b00, 0x0fb00f50, "fmscd%c\t%z1, %z2, %z0"},
1314 {FPU_VFP_EXT_V1
, 0x0e100b40, 0x0fb00f50, "fnmscd%c\t%z1, %z2, %z0"},
1315 {FPU_VFP_EXT_V1xD
, 0x0e200a00, 0x0fb00f50, "fmuls%c\t%y1, %y2, %y0"},
1316 {FPU_VFP_EXT_V1xD
, 0x0e200a40, 0x0fb00f50, "fnmuls%c\t%y1, %y2, %y0"},
1317 {FPU_VFP_EXT_V1
, 0x0e200b00, 0x0fb00f50, "fmuld%c\t%z1, %z2, %z0"},
1318 {FPU_VFP_EXT_V1
, 0x0e200b40, 0x0fb00f50, "fnmuld%c\t%z1, %z2, %z0"},
1319 {FPU_VFP_EXT_V1xD
, 0x0e300a00, 0x0fb00f50, "fadds%c\t%y1, %y2, %y0"},
1320 {FPU_VFP_EXT_V1xD
, 0x0e300a40, 0x0fb00f50, "fsubs%c\t%y1, %y2, %y0"},
1321 {FPU_VFP_EXT_V1
, 0x0e300b00, 0x0fb00f50, "faddd%c\t%z1, %z2, %z0"},
1322 {FPU_VFP_EXT_V1
, 0x0e300b40, 0x0fb00f50, "fsubd%c\t%z1, %z2, %z0"},
1323 {FPU_VFP_EXT_V1xD
, 0x0e800a00, 0x0fb00f50, "fdivs%c\t%y1, %y2, %y0"},
1324 {FPU_VFP_EXT_V1
, 0x0e800b00, 0x0fb00f50, "fdivd%c\t%z1, %z2, %z0"},
1325 {FPU_VFP_EXT_V1xD
, 0x0d200a00, 0x0fb00f00, "fstmdbs%c\t%16-19r!, %y3"},
1326 {FPU_VFP_EXT_V1xD
, 0x0d200b00, 0x0fb00f00, "fstmdb%0?xd%c\t%16-19r!, %z3"},
1327 {FPU_VFP_EXT_V1xD
, 0x0d300a00, 0x0fb00f00, "fldmdbs%c\t%16-19r!, %y3"},
1328 {FPU_VFP_EXT_V1xD
, 0x0d300b00, 0x0fb00f00, "fldmdb%0?xd%c\t%16-19r!, %z3"},
1329 {FPU_VFP_EXT_V1xD
, 0x0d000a00, 0x0f300f00, "fsts%c\t%y1, %A"},
1330 {FPU_VFP_EXT_V1
, 0x0d000b00, 0x0f300f00, "fstd%c\t%z1, %A"},
1331 {FPU_VFP_EXT_V1xD
, 0x0d100a00, 0x0f300f00, "flds%c\t%y1, %A"},
1332 {FPU_VFP_EXT_V1
, 0x0d100b00, 0x0f300f00, "fldd%c\t%z1, %A"},
1333 {FPU_VFP_EXT_V1xD
, 0x0c800a00, 0x0f900f00, "fstmias%c\t%16-19r%21'!, %y3"},
1334 {FPU_VFP_EXT_V1xD
, 0x0c800b00, 0x0f900f00, "fstmia%0?xd%c\t%16-19r%21'!, %z3"},
1335 {FPU_VFP_EXT_V1xD
, 0x0c900a00, 0x0f900f00, "fldmias%c\t%16-19r%21'!, %y3"},
1336 {FPU_VFP_EXT_V1xD
, 0x0c900b00, 0x0f900f00, "fldmia%0?xd%c\t%16-19r%21'!, %z3"},
1337 {FPU_VFP_EXT_V1
, 0x0ea00a00, 0x0fb00f50, "vfma%c.f32\t%y1, %y2, %y0"},
1338 {FPU_VFP_EXT_V1
, 0x0ea00a40, 0x0fb00f50, "vfms%c.f32\t%y1, %y2, %y0"},
1339 {FPU_VFP_EXT_V1
, 0x0ea00b00, 0x0fb00f50, "vfma%c.f64\t%z1, %z2, %z0"},
1340 {FPU_VFP_EXT_V1
, 0x0ea00b40, 0x0fb00f50, "vfms%c.f64\t%z1, %z2, %z0"},
1341 {FPU_VFP_EXT_V1
, 0x0e900a40, 0x0fb00f50, "vfnma%c.f32\t%y1, %y2, %y0"},
1342 {FPU_VFP_EXT_V1
, 0x0e900a00, 0x0fb00f50, "vfnms%c.f32\t%y1, %y2, %y0"},
1343 {FPU_VFP_EXT_V1
, 0x0e900b40, 0x0fb00f50, "vfnma%c.f64\t%z1, %z2, %z0"},
1344 {FPU_VFP_EXT_V1
, 0x0e900b00, 0x0fb00f50, "vfnms%c.f64\t%z1, %z2, %z0"},
1346 /* Cirrus coprocessor instructions. */
1347 {ARM_CEXT_MAVERICK
, 0x0d100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"},
1348 {ARM_CEXT_MAVERICK
, 0x0c100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"},
1349 {ARM_CEXT_MAVERICK
, 0x0d500400, 0x0f500f00, "cfldrd%c\tmvd%12-15d, %A"},
1350 {ARM_CEXT_MAVERICK
, 0x0c500400, 0x0f500f00, "cfldrd%c\tmvd%12-15d, %A"},
1351 {ARM_CEXT_MAVERICK
, 0x0d100500, 0x0f500f00, "cfldr32%c\tmvfx%12-15d, %A"},
1352 {ARM_CEXT_MAVERICK
, 0x0c100500, 0x0f500f00, "cfldr32%c\tmvfx%12-15d, %A"},
1353 {ARM_CEXT_MAVERICK
, 0x0d500500, 0x0f500f00, "cfldr64%c\tmvdx%12-15d, %A"},
1354 {ARM_CEXT_MAVERICK
, 0x0c500500, 0x0f500f00, "cfldr64%c\tmvdx%12-15d, %A"},
1355 {ARM_CEXT_MAVERICK
, 0x0d000400, 0x0f500f00, "cfstrs%c\tmvf%12-15d, %A"},
1356 {ARM_CEXT_MAVERICK
, 0x0c000400, 0x0f500f00, "cfstrs%c\tmvf%12-15d, %A"},
1357 {ARM_CEXT_MAVERICK
, 0x0d400400, 0x0f500f00, "cfstrd%c\tmvd%12-15d, %A"},
1358 {ARM_CEXT_MAVERICK
, 0x0c400400, 0x0f500f00, "cfstrd%c\tmvd%12-15d, %A"},
1359 {ARM_CEXT_MAVERICK
, 0x0d000500, 0x0f500f00, "cfstr32%c\tmvfx%12-15d, %A"},
1360 {ARM_CEXT_MAVERICK
, 0x0c000500, 0x0f500f00, "cfstr32%c\tmvfx%12-15d, %A"},
1361 {ARM_CEXT_MAVERICK
, 0x0d400500, 0x0f500f00, "cfstr64%c\tmvdx%12-15d, %A"},
1362 {ARM_CEXT_MAVERICK
, 0x0c400500, 0x0f500f00, "cfstr64%c\tmvdx%12-15d, %A"},
1363 {ARM_CEXT_MAVERICK
, 0x0e000450, 0x0ff00ff0, "cfmvsr%c\tmvf%16-19d, %12-15r"},
1364 {ARM_CEXT_MAVERICK
, 0x0e100450, 0x0ff00ff0, "cfmvrs%c\t%12-15r, mvf%16-19d"},
1365 {ARM_CEXT_MAVERICK
, 0x0e000410, 0x0ff00ff0, "cfmvdlr%c\tmvd%16-19d, %12-15r"},
1366 {ARM_CEXT_MAVERICK
, 0x0e100410, 0x0ff00ff0, "cfmvrdl%c\t%12-15r, mvd%16-19d"},
1367 {ARM_CEXT_MAVERICK
, 0x0e000430, 0x0ff00ff0, "cfmvdhr%c\tmvd%16-19d, %12-15r"},
1368 {ARM_CEXT_MAVERICK
, 0x0e100430, 0x0ff00fff, "cfmvrdh%c\t%12-15r, mvd%16-19d"},
1369 {ARM_CEXT_MAVERICK
, 0x0e000510, 0x0ff00fff, "cfmv64lr%c\tmvdx%16-19d, %12-15r"},
1370 {ARM_CEXT_MAVERICK
, 0x0e100510, 0x0ff00fff, "cfmvr64l%c\t%12-15r, mvdx%16-19d"},
1371 {ARM_CEXT_MAVERICK
, 0x0e000530, 0x0ff00fff, "cfmv64hr%c\tmvdx%16-19d, %12-15r"},
1372 {ARM_CEXT_MAVERICK
, 0x0e100530, 0x0ff00fff, "cfmvr64h%c\t%12-15r, mvdx%16-19d"},
1373 {ARM_CEXT_MAVERICK
, 0x0e200440, 0x0ff00fff, "cfmval32%c\tmvax%12-15d, mvfx%16-19d"},
1374 {ARM_CEXT_MAVERICK
, 0x0e100440, 0x0ff00fff, "cfmv32al%c\tmvfx%12-15d, mvax%16-19d"},
1375 {ARM_CEXT_MAVERICK
, 0x0e200460, 0x0ff00fff, "cfmvam32%c\tmvax%12-15d, mvfx%16-19d"},
1376 {ARM_CEXT_MAVERICK
, 0x0e100460, 0x0ff00fff, "cfmv32am%c\tmvfx%12-15d, mvax%16-19d"},
1377 {ARM_CEXT_MAVERICK
, 0x0e200480, 0x0ff00fff, "cfmvah32%c\tmvax%12-15d, mvfx%16-19d"},
1378 {ARM_CEXT_MAVERICK
, 0x0e100480, 0x0ff00fff, "cfmv32ah%c\tmvfx%12-15d, mvax%16-19d"},
1379 {ARM_CEXT_MAVERICK
, 0x0e2004a0, 0x0ff00fff, "cfmva32%c\tmvax%12-15d, mvfx%16-19d"},
1380 {ARM_CEXT_MAVERICK
, 0x0e1004a0, 0x0ff00fff, "cfmv32a%c\tmvfx%12-15d, mvax%16-19d"},
1381 {ARM_CEXT_MAVERICK
, 0x0e2004c0, 0x0ff00fff, "cfmva64%c\tmvax%12-15d, mvdx%16-19d"},
1382 {ARM_CEXT_MAVERICK
, 0x0e1004c0, 0x0ff00fff, "cfmv64a%c\tmvdx%12-15d, mvax%16-19d"},
1383 {ARM_CEXT_MAVERICK
, 0x0e2004e0, 0x0fff0fff, "cfmvsc32%c\tdspsc, mvdx%12-15d"},
1384 {ARM_CEXT_MAVERICK
, 0x0e1004e0, 0x0fff0fff, "cfmv32sc%c\tmvdx%12-15d, dspsc"},
1385 {ARM_CEXT_MAVERICK
, 0x0e000400, 0x0ff00fff, "cfcpys%c\tmvf%12-15d, mvf%16-19d"},
1386 {ARM_CEXT_MAVERICK
, 0x0e000420, 0x0ff00fff, "cfcpyd%c\tmvd%12-15d, mvd%16-19d"},
1387 {ARM_CEXT_MAVERICK
, 0x0e000460, 0x0ff00fff, "cfcvtsd%c\tmvd%12-15d, mvf%16-19d"},
1388 {ARM_CEXT_MAVERICK
, 0x0e000440, 0x0ff00fff, "cfcvtds%c\tmvf%12-15d, mvd%16-19d"},
1389 {ARM_CEXT_MAVERICK
, 0x0e000480, 0x0ff00fff, "cfcvt32s%c\tmvf%12-15d, mvfx%16-19d"},
1390 {ARM_CEXT_MAVERICK
, 0x0e0004a0, 0x0ff00fff, "cfcvt32d%c\tmvd%12-15d, mvfx%16-19d"},
1391 {ARM_CEXT_MAVERICK
, 0x0e0004c0, 0x0ff00fff, "cfcvt64s%c\tmvf%12-15d, mvdx%16-19d"},
1392 {ARM_CEXT_MAVERICK
, 0x0e0004e0, 0x0ff00fff, "cfcvt64d%c\tmvd%12-15d, mvdx%16-19d"},
1393 {ARM_CEXT_MAVERICK
, 0x0e100580, 0x0ff00fff, "cfcvts32%c\tmvfx%12-15d, mvf%16-19d"},
1394 {ARM_CEXT_MAVERICK
, 0x0e1005a0, 0x0ff00fff, "cfcvtd32%c\tmvfx%12-15d, mvd%16-19d"},
1395 {ARM_CEXT_MAVERICK
, 0x0e1005c0, 0x0ff00fff, "cftruncs32%c\tmvfx%12-15d, mvf%16-19d"},
1396 {ARM_CEXT_MAVERICK
, 0x0e1005e0, 0x0ff00fff, "cftruncd32%c\tmvfx%12-15d, mvd%16-19d"},
1397 {ARM_CEXT_MAVERICK
, 0x0e000550, 0x0ff00ff0, "cfrshl32%c\tmvfx%16-19d, mvfx%0-3d, %12-15r"},
1398 {ARM_CEXT_MAVERICK
, 0x0e000570, 0x0ff00ff0, "cfrshl64%c\tmvdx%16-19d, mvdx%0-3d, %12-15r"},
1399 {ARM_CEXT_MAVERICK
, 0x0e000500, 0x0ff00f10, "cfsh32%c\tmvfx%12-15d, mvfx%16-19d, #%I"},
1400 {ARM_CEXT_MAVERICK
, 0x0e200500, 0x0ff00f10, "cfsh64%c\tmvdx%12-15d, mvdx%16-19d, #%I"},
1401 {ARM_CEXT_MAVERICK
, 0x0e100490, 0x0ff00ff0, "cfcmps%c\t%12-15r, mvf%16-19d, mvf%0-3d"},
1402 {ARM_CEXT_MAVERICK
, 0x0e1004b0, 0x0ff00ff0, "cfcmpd%c\t%12-15r, mvd%16-19d, mvd%0-3d"},
1403 {ARM_CEXT_MAVERICK
, 0x0e100590, 0x0ff00ff0, "cfcmp32%c\t%12-15r, mvfx%16-19d, mvfx%0-3d"},
1404 {ARM_CEXT_MAVERICK
, 0x0e1005b0, 0x0ff00ff0, "cfcmp64%c\t%12-15r, mvdx%16-19d, mvdx%0-3d"},
1405 {ARM_CEXT_MAVERICK
, 0x0e300400, 0x0ff00fff, "cfabss%c\tmvf%12-15d, mvf%16-19d"},
1406 {ARM_CEXT_MAVERICK
, 0x0e300420, 0x0ff00fff, "cfabsd%c\tmvd%12-15d, mvd%16-19d"},
1407 {ARM_CEXT_MAVERICK
, 0x0e300440, 0x0ff00fff, "cfnegs%c\tmvf%12-15d, mvf%16-19d"},
1408 {ARM_CEXT_MAVERICK
, 0x0e300460, 0x0ff00fff, "cfnegd%c\tmvd%12-15d, mvd%16-19d"},
1409 {ARM_CEXT_MAVERICK
, 0x0e300480, 0x0ff00ff0, "cfadds%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
1410 {ARM_CEXT_MAVERICK
, 0x0e3004a0, 0x0ff00ff0, "cfaddd%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
1411 {ARM_CEXT_MAVERICK
, 0x0e3004c0, 0x0ff00ff0, "cfsubs%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
1412 {ARM_CEXT_MAVERICK
, 0x0e3004e0, 0x0ff00ff0, "cfsubd%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
1413 {ARM_CEXT_MAVERICK
, 0x0e100400, 0x0ff00ff0, "cfmuls%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
1414 {ARM_CEXT_MAVERICK
, 0x0e100420, 0x0ff00ff0, "cfmuld%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
1415 {ARM_CEXT_MAVERICK
, 0x0e300500, 0x0ff00fff, "cfabs32%c\tmvfx%12-15d, mvfx%16-19d"},
1416 {ARM_CEXT_MAVERICK
, 0x0e300520, 0x0ff00fff, "cfabs64%c\tmvdx%12-15d, mvdx%16-19d"},
1417 {ARM_CEXT_MAVERICK
, 0x0e300540, 0x0ff00fff, "cfneg32%c\tmvfx%12-15d, mvfx%16-19d"},
1418 {ARM_CEXT_MAVERICK
, 0x0e300560, 0x0ff00fff, "cfneg64%c\tmvdx%12-15d, mvdx%16-19d"},
1419 {ARM_CEXT_MAVERICK
, 0x0e300580, 0x0ff00ff0, "cfadd32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
1420 {ARM_CEXT_MAVERICK
, 0x0e3005a0, 0x0ff00ff0, "cfadd64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
1421 {ARM_CEXT_MAVERICK
, 0x0e3005c0, 0x0ff00ff0, "cfsub32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
1422 {ARM_CEXT_MAVERICK
, 0x0e3005e0, 0x0ff00ff0, "cfsub64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
1423 {ARM_CEXT_MAVERICK
, 0x0e100500, 0x0ff00ff0, "cfmul32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
1424 {ARM_CEXT_MAVERICK
, 0x0e100520, 0x0ff00ff0, "cfmul64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
1425 {ARM_CEXT_MAVERICK
, 0x0e100540, 0x0ff00ff0, "cfmac32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
1426 {ARM_CEXT_MAVERICK
, 0x0e100560, 0x0ff00ff0, "cfmsc32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
1427 {ARM_CEXT_MAVERICK
, 0x0e000600, 0x0ff00f10, "cfmadd32%c\tmvax%5-7d, mvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
1428 {ARM_CEXT_MAVERICK
, 0x0e100600, 0x0ff00f10, "cfmsub32%c\tmvax%5-7d, mvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
1429 {ARM_CEXT_MAVERICK
, 0x0e200600, 0x0ff00f10, "cfmadda32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"},
1430 {ARM_CEXT_MAVERICK
, 0x0e300600, 0x0ff00f10, "cfmsuba32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"},
1432 /* Generic coprocessor instructions */
1433 {ARM_EXT_V2
, 0x0c400000, 0x0ff00000, "mcrr%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
1434 {ARM_EXT_V2
, 0x0c500000, 0x0ff00000, "mrrc%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
1435 {ARM_EXT_V2
, 0x0e000000, 0x0f000010, "cdp%c\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"},
1436 {ARM_EXT_V2
, 0x0e100010, 0x0f100010, "mrc%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
1437 {ARM_EXT_V2
, 0x0e000010, 0x0f100010, "mcr%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
1438 {ARM_EXT_V2
, 0x0c000000, 0x0e100000, "stc%22'l%c\t%8-11d, cr%12-15d, %A"},
1439 {ARM_EXT_V2
, 0x0c100000, 0x0e100000, "ldc%22'l%c\t%8-11d, cr%12-15d, %A"},
1441 /* V6 coprocessor instructions */
1442 {ARM_EXT_V6
, 0xfc500000, 0xfff00000, "mrrc2%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
1443 {ARM_EXT_V6
, 0xfc400000, 0xfff00000, "mcrr2%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
1445 /* V5 coprocessor instructions */
1446 {ARM_EXT_V5
, 0xfc100000, 0xfe100000, "ldc2%22'l%c\t%8-11d, cr%12-15d, %A"},
1447 {ARM_EXT_V5
, 0xfc000000, 0xfe100000, "stc2%22'l%c\t%8-11d, cr%12-15d, %A"},
1448 {ARM_EXT_V5
, 0xfe000000, 0xff000010, "cdp2%c\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"},
1449 {ARM_EXT_V5
, 0xfe000010, 0xff100010, "mcr2%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
1450 {ARM_EXT_V5
, 0xfe100010, 0xff100010, "mrc2%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
1455 /* Neon opcode table: This does not encode the top byte -- that is
1456 checked by the print_insn_neon routine, as it depends on whether we are
1457 doing thumb32 or arm32 disassembly. */
1459 /* print_insn_neon recognizes the following format control codes:
1463 %c print condition code
1464 %A print v{st,ld}[1234] operands
1465 %B print v{st,ld}[1234] any one operands
1466 %C print v{st,ld}[1234] single->all operands
1468 %E print vmov, vmvn, vorr, vbic encoded constant
1469 %F print vtbl,vtbx register list
1471 %<bitfield>r print as an ARM register
1472 %<bitfield>d print the bitfield in decimal
1473 %<bitfield>e print the 2^N - bitfield in decimal
1474 %<bitfield>D print as a NEON D register
1475 %<bitfield>Q print as a NEON Q register
1476 %<bitfield>R print as a NEON D or Q register
1477 %<bitfield>Sn print byte scaled width limited by n
1478 %<bitfield>Tn print short scaled width limited by n
1479 %<bitfield>Un print long scaled width limited by n
1481 %<bitfield>'c print specified char iff bitfield is all ones
1482 %<bitfield>`c print specified char iff bitfield is all zeroes
1483 %<bitfield>?ab... select from array of values in big endian order */
1485 static const struct opcode32 neon_opcodes
[] =
1488 {FPU_NEON_EXT_V1
, 0xf2b00840, 0xffb00850, "vext%c.8\t%12-15,22R, %16-19,7R, %0-3,5R, #%8-11d"},
1489 {FPU_NEON_EXT_V1
, 0xf2b00000, 0xffb00810, "vext%c.8\t%12-15,22R, %16-19,7R, %0-3,5R, #%8-11d"},
1491 /* Move data element to all lanes */
1492 {FPU_NEON_EXT_V1
, 0xf3b40c00, 0xffb70f90, "vdup%c.32\t%12-15,22R, %0-3,5D[%19d]"},
1493 {FPU_NEON_EXT_V1
, 0xf3b20c00, 0xffb30f90, "vdup%c.16\t%12-15,22R, %0-3,5D[%18-19d]"},
1494 {FPU_NEON_EXT_V1
, 0xf3b10c00, 0xffb10f90, "vdup%c.8\t%12-15,22R, %0-3,5D[%17-19d]"},
1497 {FPU_NEON_EXT_V1
, 0xf3b00800, 0xffb00c50, "vtbl%c.8\t%12-15,22D, %F, %0-3,5D"},
1498 {FPU_NEON_EXT_V1
, 0xf3b00840, 0xffb00c50, "vtbx%c.8\t%12-15,22D, %F, %0-3,5D"},
1500 /* Two registers, miscellaneous */
1501 {FPU_NEON_EXT_V1
, 0xf2880a10, 0xfebf0fd0, "vmovl%c.%24?us8\t%12-15,22Q, %0-3,5D"},
1502 {FPU_NEON_EXT_V1
, 0xf2900a10, 0xfebf0fd0, "vmovl%c.%24?us16\t%12-15,22Q, %0-3,5D"},
1503 {FPU_NEON_EXT_V1
, 0xf2a00a10, 0xfebf0fd0, "vmovl%c.%24?us32\t%12-15,22Q, %0-3,5D"},
1504 {FPU_NEON_EXT_V1
, 0xf3b00500, 0xffbf0f90, "vcnt%c.8\t%12-15,22R, %0-3,5R"},
1505 {FPU_NEON_EXT_V1
, 0xf3b00580, 0xffbf0f90, "vmvn%c\t%12-15,22R, %0-3,5R"},
1506 {FPU_NEON_EXT_V1
, 0xf3b20000, 0xffbf0f90, "vswp%c\t%12-15,22R, %0-3,5R"},
1507 {FPU_NEON_EXT_V1
, 0xf3b20200, 0xffb30fd0, "vmovn%c.i%18-19T2\t%12-15,22D, %0-3,5Q"},
1508 {FPU_NEON_EXT_V1
, 0xf3b20240, 0xffb30fd0, "vqmovun%c.s%18-19T2\t%12-15,22D, %0-3,5Q"},
1509 {FPU_NEON_EXT_V1
, 0xf3b20280, 0xffb30fd0, "vqmovn%c.s%18-19T2\t%12-15,22D, %0-3,5Q"},
1510 {FPU_NEON_EXT_V1
, 0xf3b202c0, 0xffb30fd0, "vqmovn%c.u%18-19T2\t%12-15,22D, %0-3,5Q"},
1511 {FPU_NEON_EXT_V1
, 0xf3b20300, 0xffb30fd0, "vshll%c.i%18-19S2\t%12-15,22Q, %0-3,5D, #%18-19S2"},
1512 {FPU_NEON_EXT_V1
, 0xf3bb0400, 0xffbf0e90, "vrecpe%c.%8?fu%18-19S2\t%12-15,22R, %0-3,5R"},
1513 {FPU_NEON_EXT_V1
, 0xf3bb0480, 0xffbf0e90, "vrsqrte%c.%8?fu%18-19S2\t%12-15,22R, %0-3,5R"},
1514 {FPU_NEON_EXT_V1
, 0xf3b00000, 0xffb30f90, "vrev64%c.%18-19S2\t%12-15,22R, %0-3,5R"},
1515 {FPU_NEON_EXT_V1
, 0xf3b00080, 0xffb30f90, "vrev32%c.%18-19S2\t%12-15,22R, %0-3,5R"},
1516 {FPU_NEON_EXT_V1
, 0xf3b00100, 0xffb30f90, "vrev16%c.%18-19S2\t%12-15,22R, %0-3,5R"},
1517 {FPU_NEON_EXT_V1
, 0xf3b00400, 0xffb30f90, "vcls%c.s%18-19S2\t%12-15,22R, %0-3,5R"},
1518 {FPU_NEON_EXT_V1
, 0xf3b00480, 0xffb30f90, "vclz%c.i%18-19S2\t%12-15,22R, %0-3,5R"},
1519 {FPU_NEON_EXT_V1
, 0xf3b00700, 0xffb30f90, "vqabs%c.s%18-19S2\t%12-15,22R, %0-3,5R"},
1520 {FPU_NEON_EXT_V1
, 0xf3b00780, 0xffb30f90, "vqneg%c.s%18-19S2\t%12-15,22R, %0-3,5R"},
1521 {FPU_NEON_EXT_V1
, 0xf3b20080, 0xffb30f90, "vtrn%c.%18-19S2\t%12-15,22R, %0-3,5R"},
1522 {FPU_NEON_EXT_V1
, 0xf3b20100, 0xffb30f90, "vuzp%c.%18-19S2\t%12-15,22R, %0-3,5R"},
1523 {FPU_NEON_EXT_V1
, 0xf3b20180, 0xffb30f90, "vzip%c.%18-19S2\t%12-15,22R, %0-3,5R"},
1524 {FPU_NEON_EXT_V1
, 0xf3b10000, 0xffb30b90, "vcgt%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
1525 {FPU_NEON_EXT_V1
, 0xf3b10080, 0xffb30b90, "vcge%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
1526 {FPU_NEON_EXT_V1
, 0xf3b10100, 0xffb30b90, "vceq%c.%10?fi%18-19S2\t%12-15,22R, %0-3,5R, #0"},
1527 {FPU_NEON_EXT_V1
, 0xf3b10180, 0xffb30b90, "vcle%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
1528 {FPU_NEON_EXT_V1
, 0xf3b10200, 0xffb30b90, "vclt%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
1529 {FPU_NEON_EXT_V1
, 0xf3b10300, 0xffb30b90, "vabs%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R"},
1530 {FPU_NEON_EXT_V1
, 0xf3b10380, 0xffb30b90, "vneg%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R"},
1531 {FPU_NEON_EXT_V1
, 0xf3b00200, 0xffb30f10, "vpaddl%c.%7?us%18-19S2\t%12-15,22R, %0-3,5R"},
1532 {FPU_NEON_EXT_V1
, 0xf3b00600, 0xffb30f10, "vpadal%c.%7?us%18-19S2\t%12-15,22R, %0-3,5R"},
1533 {FPU_NEON_EXT_V1
, 0xf3b30600, 0xffb30e10, "vcvt%c.%7-8?usff%18-19Sa.%7-8?ffus%18-19Sa\t%12-15,22R, %0-3,5R"},
1534 {FPU_NEON_EXT_V1
, 0xf3b60700, 0xffbf0fd0, "fcvtshp%c\t%12-15,22Q, %0-3,5D"},
1535 {FPU_NEON_EXT_V1
, 0xf3b60600, 0xffbf0fd0, "fcvthps%c\t%12-15,22D, %0-3,5Q"},
1537 /* Three registers of the same length */
1538 {FPU_NEON_EXT_V1
, 0xf2000110, 0xffb00f10, "vand%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
1539 {FPU_NEON_EXT_V1
, 0xf2100110, 0xffb00f10, "vbic%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
1540 {FPU_NEON_EXT_V1
, 0xf2200110, 0xffb00f10, "vorr%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
1541 {FPU_NEON_EXT_V1
, 0xf2300110, 0xffb00f10, "vorn%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
1542 {FPU_NEON_EXT_V1
, 0xf3000110, 0xffb00f10, "veor%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
1543 {FPU_NEON_EXT_V1
, 0xf3100110, 0xffb00f10, "vbsl%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
1544 {FPU_NEON_EXT_V1
, 0xf3200110, 0xffb00f10, "vbit%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
1545 {FPU_NEON_EXT_V1
, 0xf3300110, 0xffb00f10, "vbif%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
1546 {FPU_NEON_EXT_V1
, 0xf2000d00, 0xffa00f10, "vadd%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
1547 {FPU_NEON_EXT_V1
, 0xf2000d10, 0xffa00f10, "vmla%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
1548 {FPU_NEON_EXT_V1
, 0xf2000c10, 0xffa00f10, "vfma%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
1549 {FPU_NEON_EXT_V1
, 0xf2200c10, 0xffa00f10, "vfms%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
1550 {FPU_NEON_EXT_V1
, 0xf2000e00, 0xffa00f10, "vceq%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
1551 {FPU_NEON_EXT_V1
, 0xf2000f00, 0xffa00f10, "vmax%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
1552 {FPU_NEON_EXT_V1
, 0xf2000f10, 0xffa00f10, "vrecps%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
1553 {FPU_NEON_EXT_V1
, 0xf2200d00, 0xffa00f10, "vsub%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
1554 {FPU_NEON_EXT_V1
, 0xf2200d10, 0xffa00f10, "vmls%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
1555 {FPU_NEON_EXT_V1
, 0xf2200f00, 0xffa00f10, "vmin%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
1556 {FPU_NEON_EXT_V1
, 0xf2200f10, 0xffa00f10, "vrsqrts%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
1557 {FPU_NEON_EXT_V1
, 0xf3000d00, 0xffa00f10, "vpadd%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
1558 {FPU_NEON_EXT_V1
, 0xf3000d10, 0xffa00f10, "vmul%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
1559 {FPU_NEON_EXT_V1
, 0xf3000e00, 0xffa00f10, "vcge%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
1560 {FPU_NEON_EXT_V1
, 0xf3000e10, 0xffa00f10, "vacge%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
1561 {FPU_NEON_EXT_V1
, 0xf3000f00, 0xffa00f10, "vpmax%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
1562 {FPU_NEON_EXT_V1
, 0xf3200d00, 0xffa00f10, "vabd%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
1563 {FPU_NEON_EXT_V1
, 0xf3200e00, 0xffa00f10, "vcgt%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
1564 {FPU_NEON_EXT_V1
, 0xf3200e10, 0xffa00f10, "vacgt%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
1565 {FPU_NEON_EXT_V1
, 0xf3200f00, 0xffa00f10, "vpmin%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
1566 {FPU_NEON_EXT_V1
, 0xf2000800, 0xff800f10, "vadd%c.i%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
1567 {FPU_NEON_EXT_V1
, 0xf2000810, 0xff800f10, "vtst%c.%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
1568 {FPU_NEON_EXT_V1
, 0xf2000900, 0xff800f10, "vmla%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
1569 {FPU_NEON_EXT_V1
, 0xf2000b00, 0xff800f10, "vqdmulh%c.s%20-21S6\t%12-15,22R, %16-19,7R, %0-3,5R"},
1570 {FPU_NEON_EXT_V1
, 0xf2000b10, 0xff800f10, "vpadd%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
1571 {FPU_NEON_EXT_V1
, 0xf3000800, 0xff800f10, "vsub%c.i%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
1572 {FPU_NEON_EXT_V1
, 0xf3000810, 0xff800f10, "vceq%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
1573 {FPU_NEON_EXT_V1
, 0xf3000900, 0xff800f10, "vmls%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
1574 {FPU_NEON_EXT_V1
, 0xf3000b00, 0xff800f10, "vqrdmulh%c.s%20-21S6\t%12-15,22R, %16-19,7R, %0-3,5R"},
1575 {FPU_NEON_EXT_V1
, 0xf2000000, 0xfe800f10, "vhadd%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
1576 {FPU_NEON_EXT_V1
, 0xf2000010, 0xfe800f10, "vqadd%c.%24?us%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
1577 {FPU_NEON_EXT_V1
, 0xf2000100, 0xfe800f10, "vrhadd%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
1578 {FPU_NEON_EXT_V1
, 0xf2000200, 0xfe800f10, "vhsub%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
1579 {FPU_NEON_EXT_V1
, 0xf2000210, 0xfe800f10, "vqsub%c.%24?us%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
1580 {FPU_NEON_EXT_V1
, 0xf2000300, 0xfe800f10, "vcgt%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
1581 {FPU_NEON_EXT_V1
, 0xf2000310, 0xfe800f10, "vcge%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
1582 {FPU_NEON_EXT_V1
, 0xf2000400, 0xfe800f10, "vshl%c.%24?us%20-21S3\t%12-15,22R, %0-3,5R, %16-19,7R"},
1583 {FPU_NEON_EXT_V1
, 0xf2000410, 0xfe800f10, "vqshl%c.%24?us%20-21S3\t%12-15,22R, %0-3,5R, %16-19,7R"},
1584 {FPU_NEON_EXT_V1
, 0xf2000500, 0xfe800f10, "vrshl%c.%24?us%20-21S3\t%12-15,22R, %0-3,5R, %16-19,7R"},
1585 {FPU_NEON_EXT_V1
, 0xf2000510, 0xfe800f10, "vqrshl%c.%24?us%20-21S3\t%12-15,22R, %0-3,5R, %16-19,7R"},
1586 {FPU_NEON_EXT_V1
, 0xf2000600, 0xfe800f10, "vmax%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
1587 {FPU_NEON_EXT_V1
, 0xf2000610, 0xfe800f10, "vmin%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
1588 {FPU_NEON_EXT_V1
, 0xf2000700, 0xfe800f10, "vabd%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
1589 {FPU_NEON_EXT_V1
, 0xf2000710, 0xfe800f10, "vaba%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
1590 {FPU_NEON_EXT_V1
, 0xf2000910, 0xfe800f10, "vmul%c.%24?pi%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
1591 {FPU_NEON_EXT_V1
, 0xf2000a00, 0xfe800f10, "vpmax%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
1592 {FPU_NEON_EXT_V1
, 0xf2000a10, 0xfe800f10, "vpmin%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
1594 /* One register and an immediate value */
1595 {FPU_NEON_EXT_V1
, 0xf2800e10, 0xfeb80fb0, "vmov%c.i8\t%12-15,22R, %E"},
1596 {FPU_NEON_EXT_V1
, 0xf2800e30, 0xfeb80fb0, "vmov%c.i64\t%12-15,22R, %E"},
1597 {FPU_NEON_EXT_V1
, 0xf2800f10, 0xfeb80fb0, "vmov%c.f32\t%12-15,22R, %E"},
1598 {FPU_NEON_EXT_V1
, 0xf2800810, 0xfeb80db0, "vmov%c.i16\t%12-15,22R, %E"},
1599 {FPU_NEON_EXT_V1
, 0xf2800830, 0xfeb80db0, "vmvn%c.i16\t%12-15,22R, %E"},
1600 {FPU_NEON_EXT_V1
, 0xf2800910, 0xfeb80db0, "vorr%c.i16\t%12-15,22R, %E"},
1601 {FPU_NEON_EXT_V1
, 0xf2800930, 0xfeb80db0, "vbic%c.i16\t%12-15,22R, %E"},
1602 {FPU_NEON_EXT_V1
, 0xf2800c10, 0xfeb80eb0, "vmov%c.i32\t%12-15,22R, %E"},
1603 {FPU_NEON_EXT_V1
, 0xf2800c30, 0xfeb80eb0, "vmvn%c.i32\t%12-15,22R, %E"},
1604 {FPU_NEON_EXT_V1
, 0xf2800110, 0xfeb809b0, "vorr%c.i32\t%12-15,22R, %E"},
1605 {FPU_NEON_EXT_V1
, 0xf2800130, 0xfeb809b0, "vbic%c.i32\t%12-15,22R, %E"},
1606 {FPU_NEON_EXT_V1
, 0xf2800010, 0xfeb808b0, "vmov%c.i32\t%12-15,22R, %E"},
1607 {FPU_NEON_EXT_V1
, 0xf2800030, 0xfeb808b0, "vmvn%c.i32\t%12-15,22R, %E"},
1609 /* Two registers and a shift amount */
1610 {FPU_NEON_EXT_V1
, 0xf2880810, 0xffb80fd0, "vshrn%c.i16\t%12-15,22D, %0-3,5Q, #%16-18e"},
1611 {FPU_NEON_EXT_V1
, 0xf2880850, 0xffb80fd0, "vrshrn%c.i16\t%12-15,22D, %0-3,5Q, #%16-18e"},
1612 {FPU_NEON_EXT_V1
, 0xf2880810, 0xfeb80fd0, "vqshrun%c.s16\t%12-15,22D, %0-3,5Q, #%16-18e"},
1613 {FPU_NEON_EXT_V1
, 0xf2880850, 0xfeb80fd0, "vqrshrun%c.s16\t%12-15,22D, %0-3,5Q, #%16-18e"},
1614 {FPU_NEON_EXT_V1
, 0xf2880910, 0xfeb80fd0, "vqshrn%c.%24?us16\t%12-15,22D, %0-3,5Q, #%16-18e"},
1615 {FPU_NEON_EXT_V1
, 0xf2880950, 0xfeb80fd0, "vqrshrn%c.%24?us16\t%12-15,22D, %0-3,5Q, #%16-18e"},
1616 {FPU_NEON_EXT_V1
, 0xf2880a10, 0xfeb80fd0, "vshll%c.%24?us8\t%12-15,22D, %0-3,5Q, #%16-18d"},
1617 {FPU_NEON_EXT_V1
, 0xf2900810, 0xffb00fd0, "vshrn%c.i32\t%12-15,22D, %0-3,5Q, #%16-19e"},
1618 {FPU_NEON_EXT_V1
, 0xf2900850, 0xffb00fd0, "vrshrn%c.i32\t%12-15,22D, %0-3,5Q, #%16-19e"},
1619 {FPU_NEON_EXT_V1
, 0xf2880510, 0xffb80f90, "vshl%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18d"},
1620 {FPU_NEON_EXT_V1
, 0xf3880410, 0xffb80f90, "vsri%c.8\t%12-15,22R, %0-3,5R, #%16-18e"},
1621 {FPU_NEON_EXT_V1
, 0xf3880510, 0xffb80f90, "vsli%c.8\t%12-15,22R, %0-3,5R, #%16-18d"},
1622 {FPU_NEON_EXT_V1
, 0xf3880610, 0xffb80f90, "vqshlu%c.s8\t%12-15,22R, %0-3,5R, #%16-18d"},
1623 {FPU_NEON_EXT_V1
, 0xf2800810, 0xfe800fd0, "vqshrun%c.s32\t%12-15,22D, %0-3,5Q, #%16-19e"},
1624 {FPU_NEON_EXT_V1
, 0xf2800850, 0xfe800fd0, "vqrshrun%c.s32\t%12-15,22D, %0-3,5Q, #%16-19e"},
1625 {FPU_NEON_EXT_V1
, 0xf2800910, 0xfe800fd0, "vqshrn%c.%24?us32\t%12-15,22D, %0-3,5Q, #%16-19e"},
1626 {FPU_NEON_EXT_V1
, 0xf2800950, 0xfe800fd0, "vqrshrn%c.%24?us32\t%12-15,22D, %0-3,5Q, #%16-19e"},
1627 {FPU_NEON_EXT_V1
, 0xf2900a10, 0xfeb00fd0, "vshll%c.%24?us16\t%12-15,22D, %0-3,5Q, #%16-19d"},
1628 {FPU_NEON_EXT_V1
, 0xf2880010, 0xfeb80f90, "vshr%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
1629 {FPU_NEON_EXT_V1
, 0xf2880110, 0xfeb80f90, "vsra%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
1630 {FPU_NEON_EXT_V1
, 0xf2880210, 0xfeb80f90, "vrshr%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
1631 {FPU_NEON_EXT_V1
, 0xf2880310, 0xfeb80f90, "vrsra%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
1632 {FPU_NEON_EXT_V1
, 0xf2880710, 0xfeb80f90, "vqshl%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18d"},
1633 {FPU_NEON_EXT_V1
, 0xf2a00810, 0xffa00fd0, "vshrn%c.i64\t%12-15,22D, %0-3,5Q, #%16-20e"},
1634 {FPU_NEON_EXT_V1
, 0xf2a00850, 0xffa00fd0, "vrshrn%c.i64\t%12-15,22D, %0-3,5Q, #%16-20e"},
1635 {FPU_NEON_EXT_V1
, 0xf2900510, 0xffb00f90, "vshl%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19d"},
1636 {FPU_NEON_EXT_V1
, 0xf3900410, 0xffb00f90, "vsri%c.16\t%12-15,22R, %0-3,5R, #%16-19e"},
1637 {FPU_NEON_EXT_V1
, 0xf3900510, 0xffb00f90, "vsli%c.16\t%12-15,22R, %0-3,5R, #%16-19d"},
1638 {FPU_NEON_EXT_V1
, 0xf3900610, 0xffb00f90, "vqshlu%c.s16\t%12-15,22R, %0-3,5R, #%16-19d"},
1639 {FPU_NEON_EXT_V1
, 0xf2a00a10, 0xfea00fd0, "vshll%c.%24?us32\t%12-15,22Q, %0-3,5D, #%16-20d"},
1640 {FPU_NEON_EXT_V1
, 0xf2900010, 0xfeb00f90, "vshr%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
1641 {FPU_NEON_EXT_V1
, 0xf2900110, 0xfeb00f90, "vsra%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
1642 {FPU_NEON_EXT_V1
, 0xf2900210, 0xfeb00f90, "vrshr%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
1643 {FPU_NEON_EXT_V1
, 0xf2900310, 0xfeb00f90, "vrsra%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
1644 {FPU_NEON_EXT_V1
, 0xf2900710, 0xfeb00f90, "vqshl%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19d"},
1645 {FPU_NEON_EXT_V1
, 0xf2800810, 0xfec00fd0, "vqshrun%c.s64\t%12-15,22D, %0-3,5Q, #%16-20e"},
1646 {FPU_NEON_EXT_V1
, 0xf2800850, 0xfec00fd0, "vqrshrun%c.s64\t%12-15,22D, %0-3,5Q, #%16-20e"},
1647 {FPU_NEON_EXT_V1
, 0xf2800910, 0xfec00fd0, "vqshrn%c.%24?us64\t%12-15,22D, %0-3,5Q, #%16-20e"},
1648 {FPU_NEON_EXT_V1
, 0xf2800950, 0xfec00fd0, "vqrshrn%c.%24?us64\t%12-15,22D, %0-3,5Q, #%16-20e"},
1649 {FPU_NEON_EXT_V1
, 0xf2a00510, 0xffa00f90, "vshl%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20d"},
1650 {FPU_NEON_EXT_V1
, 0xf3a00410, 0xffa00f90, "vsri%c.32\t%12-15,22R, %0-3,5R, #%16-20e"},
1651 {FPU_NEON_EXT_V1
, 0xf3a00510, 0xffa00f90, "vsli%c.32\t%12-15,22R, %0-3,5R, #%16-20d"},
1652 {FPU_NEON_EXT_V1
, 0xf3a00610, 0xffa00f90, "vqshlu%c.s32\t%12-15,22R, %0-3,5R, #%16-20d"},
1653 {FPU_NEON_EXT_V1
, 0xf2a00010, 0xfea00f90, "vshr%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
1654 {FPU_NEON_EXT_V1
, 0xf2a00110, 0xfea00f90, "vsra%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
1655 {FPU_NEON_EXT_V1
, 0xf2a00210, 0xfea00f90, "vrshr%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
1656 {FPU_NEON_EXT_V1
, 0xf2a00310, 0xfea00f90, "vrsra%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
1657 {FPU_NEON_EXT_V1
, 0xf2a00710, 0xfea00f90, "vqshl%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20d"},
1658 {FPU_NEON_EXT_V1
, 0xf2800590, 0xff800f90, "vshl%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21d"},
1659 {FPU_NEON_EXT_V1
, 0xf3800490, 0xff800f90, "vsri%c.64\t%12-15,22R, %0-3,5R, #%16-21e"},
1660 {FPU_NEON_EXT_V1
, 0xf3800590, 0xff800f90, "vsli%c.64\t%12-15,22R, %0-3,5R, #%16-21d"},
1661 {FPU_NEON_EXT_V1
, 0xf3800690, 0xff800f90, "vqshlu%c.s64\t%12-15,22R, %0-3,5R, #%16-21d"},
1662 {FPU_NEON_EXT_V1
, 0xf2800090, 0xfe800f90, "vshr%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
1663 {FPU_NEON_EXT_V1
, 0xf2800190, 0xfe800f90, "vsra%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
1664 {FPU_NEON_EXT_V1
, 0xf2800290, 0xfe800f90, "vrshr%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
1665 {FPU_NEON_EXT_V1
, 0xf2800390, 0xfe800f90, "vrsra%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
1666 {FPU_NEON_EXT_V1
, 0xf2800790, 0xfe800f90, "vqshl%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21d"},
1667 {FPU_NEON_EXT_V1
, 0xf2a00e10, 0xfea00e90, "vcvt%c.%24,8?usff32.%24,8?ffus32\t%12-15,22R, %0-3,5R, #%16-20e"},
1669 /* Three registers of different lengths */
1670 {FPU_NEON_EXT_V1
, 0xf2800e00, 0xfea00f50, "vmull%c.p%20S0\t%12-15,22Q, %16-19,7D, %0-3,5D"},
1671 {FPU_NEON_EXT_V1
, 0xf2800400, 0xff800f50, "vaddhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
1672 {FPU_NEON_EXT_V1
, 0xf2800600, 0xff800f50, "vsubhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
1673 {FPU_NEON_EXT_V1
, 0xf2800900, 0xff800f50, "vqdmlal%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %0-3,5D"},
1674 {FPU_NEON_EXT_V1
, 0xf2800b00, 0xff800f50, "vqdmlsl%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %0-3,5D"},
1675 {FPU_NEON_EXT_V1
, 0xf2800d00, 0xff800f50, "vqdmull%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %0-3,5D"},
1676 {FPU_NEON_EXT_V1
, 0xf3800400, 0xff800f50, "vraddhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
1677 {FPU_NEON_EXT_V1
, 0xf3800600, 0xff800f50, "vrsubhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
1678 {FPU_NEON_EXT_V1
, 0xf2800000, 0xfe800f50, "vaddl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
1679 {FPU_NEON_EXT_V1
, 0xf2800100, 0xfe800f50, "vaddw%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7Q, %0-3,5D"},
1680 {FPU_NEON_EXT_V1
, 0xf2800200, 0xfe800f50, "vsubl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
1681 {FPU_NEON_EXT_V1
, 0xf2800300, 0xfe800f50, "vsubw%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7Q, %0-3,5D"},
1682 {FPU_NEON_EXT_V1
, 0xf2800500, 0xfe800f50, "vabal%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
1683 {FPU_NEON_EXT_V1
, 0xf2800700, 0xfe800f50, "vabdl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
1684 {FPU_NEON_EXT_V1
, 0xf2800800, 0xfe800f50, "vmlal%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
1685 {FPU_NEON_EXT_V1
, 0xf2800a00, 0xfe800f50, "vmlsl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
1686 {FPU_NEON_EXT_V1
, 0xf2800c00, 0xfe800f50, "vmull%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
1688 /* Two registers and a scalar */
1689 {FPU_NEON_EXT_V1
, 0xf2800040, 0xff800f50, "vmla%c.i%20-21S6\t%12-15,22D, %16-19,7D, %D"},
1690 {FPU_NEON_EXT_V1
, 0xf2800140, 0xff800f50, "vmla%c.f%20-21Sa\t%12-15,22D, %16-19,7D, %D"},
1691 {FPU_NEON_EXT_V1
, 0xf2800340, 0xff800f50, "vqdmlal%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
1692 {FPU_NEON_EXT_V1
, 0xf2800440, 0xff800f50, "vmls%c.i%20-21S6\t%12-15,22D, %16-19,7D, %D"},
1693 {FPU_NEON_EXT_V1
, 0xf2800540, 0xff800f50, "vmls%c.f%20-21S6\t%12-15,22D, %16-19,7D, %D"},
1694 {FPU_NEON_EXT_V1
, 0xf2800740, 0xff800f50, "vqdmlsl%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
1695 {FPU_NEON_EXT_V1
, 0xf2800840, 0xff800f50, "vmul%c.i%20-21S6\t%12-15,22D, %16-19,7D, %D"},
1696 {FPU_NEON_EXT_V1
, 0xf2800940, 0xff800f50, "vmul%c.f%20-21Sa\t%12-15,22D, %16-19,7D, %D"},
1697 {FPU_NEON_EXT_V1
, 0xf2800b40, 0xff800f50, "vqdmull%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
1698 {FPU_NEON_EXT_V1
, 0xf2800c40, 0xff800f50, "vqdmulh%c.s%20-21S6\t%12-15,22D, %16-19,7D, %D"},
1699 {FPU_NEON_EXT_V1
, 0xf2800d40, 0xff800f50, "vqrdmulh%c.s%20-21S6\t%12-15,22D, %16-19,7D, %D"},
1700 {FPU_NEON_EXT_V1
, 0xf3800040, 0xff800f50, "vmla%c.i%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
1701 {FPU_NEON_EXT_V1
, 0xf3800140, 0xff800f50, "vmla%c.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"},
1702 {FPU_NEON_EXT_V1
, 0xf3800440, 0xff800f50, "vmls%c.i%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
1703 {FPU_NEON_EXT_V1
, 0xf3800540, 0xff800f50, "vmls%c.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"},
1704 {FPU_NEON_EXT_V1
, 0xf3800840, 0xff800f50, "vmul%c.i%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
1705 {FPU_NEON_EXT_V1
, 0xf3800940, 0xff800f50, "vmul%c.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"},
1706 {FPU_NEON_EXT_V1
, 0xf3800c40, 0xff800f50, "vqdmulh%c.s%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
1707 {FPU_NEON_EXT_V1
, 0xf3800d40, 0xff800f50, "vqrdmulh%c.s%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
1708 {FPU_NEON_EXT_V1
, 0xf2800240, 0xfe800f50, "vmlal%c.%24?us%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
1709 {FPU_NEON_EXT_V1
, 0xf2800640, 0xfe800f50, "vmlsl%c.%24?us%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
1710 {FPU_NEON_EXT_V1
, 0xf2800a40, 0xfe800f50, "vmull%c.%24?us%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
1712 /* Element and structure load/store */
1713 {FPU_NEON_EXT_V1
, 0xf4a00fc0, 0xffb00fc0, "vld4%c.32\t%C"},
1714 {FPU_NEON_EXT_V1
, 0xf4a00c00, 0xffb00f00, "vld1%c.%6-7S2\t%C"},
1715 {FPU_NEON_EXT_V1
, 0xf4a00d00, 0xffb00f00, "vld2%c.%6-7S2\t%C"},
1716 {FPU_NEON_EXT_V1
, 0xf4a00e00, 0xffb00f00, "vld3%c.%6-7S2\t%C"},
1717 {FPU_NEON_EXT_V1
, 0xf4a00f00, 0xffb00f00, "vld4%c.%6-7S2\t%C"},
1718 {FPU_NEON_EXT_V1
, 0xf4000200, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"},
1719 {FPU_NEON_EXT_V1
, 0xf4000300, 0xff900f00, "v%21?ls%21?dt2%c.%6-7S2\t%A"},
1720 {FPU_NEON_EXT_V1
, 0xf4000400, 0xff900f00, "v%21?ls%21?dt3%c.%6-7S2\t%A"},
1721 {FPU_NEON_EXT_V1
, 0xf4000500, 0xff900f00, "v%21?ls%21?dt3%c.%6-7S2\t%A"},
1722 {FPU_NEON_EXT_V1
, 0xf4000600, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"},
1723 {FPU_NEON_EXT_V1
, 0xf4000700, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"},
1724 {FPU_NEON_EXT_V1
, 0xf4000800, 0xff900f00, "v%21?ls%21?dt2%c.%6-7S2\t%A"},
1725 {FPU_NEON_EXT_V1
, 0xf4000900, 0xff900f00, "v%21?ls%21?dt2%c.%6-7S2\t%A"},
1726 {FPU_NEON_EXT_V1
, 0xf4000a00, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"},
1727 {FPU_NEON_EXT_V1
, 0xf4000000, 0xff900e00, "v%21?ls%21?dt4%c.%6-7S2\t%A"},
1728 {FPU_NEON_EXT_V1
, 0xf4800000, 0xff900300, "v%21?ls%21?dt1%c.%10-11S2\t%B"},
1729 {FPU_NEON_EXT_V1
, 0xf4800100, 0xff900300, "v%21?ls%21?dt2%c.%10-11S2\t%B"},
1730 {FPU_NEON_EXT_V1
, 0xf4800200, 0xff900300, "v%21?ls%21?dt3%c.%10-11S2\t%B"},
1731 {FPU_NEON_EXT_V1
, 0xf4800300, 0xff900300, "v%21?ls%21?dt4%c.%10-11S2\t%B"},
1736 /* Opcode tables: ARM, 16-bit Thumb, 32-bit Thumb. All three are partially
1737 ordered: they must be searched linearly from the top to obtain a correct
1740 /* print_insn_arm recognizes the following format control codes:
1744 %a print address for ldr/str instruction
1745 %s print address for ldr/str halfword/signextend instruction
1746 %b print branch destination
1747 %c print condition code (always bits 28-31)
1748 %m print register mask for ldm/stm instruction
1749 %o print operand2 (immediate or register + shift)
1750 %p print 'p' iff bits 12-15 are 15
1751 %t print 't' iff bit 21 set and bit 24 clear
1752 %B print arm BLX(1) destination
1753 %C print the PSR sub type.
1754 %U print barrier type.
1755 %P print address for pli instruction.
1757 %<bitfield>r print as an ARM register
1758 %<bitfield>d print the bitfield in decimal
1759 %<bitfield>W print the bitfield plus one in decimal
1760 %<bitfield>x print the bitfield in hex
1761 %<bitfield>X print the bitfield as 1 hex digit without leading "0x"
1763 %<bitfield>'c print specified char iff bitfield is all ones
1764 %<bitfield>`c print specified char iff bitfield is all zeroes
1765 %<bitfield>?ab... select from array of values in big endian order
1767 %e print arm SMI operand (bits 0..7,8..19).
1768 %E print the LSB and WIDTH fields of a BFI or BFC instruction.
1769 %V print the 16-bit immediate field of a MOVT or MOVW instruction. */
1771 static const struct opcode32 arm_opcodes
[] =
1774 {ARM_EXT_V1
, 0xe7ffdefe, 0xffffffff, "trap"},
1776 /* ARM instructions. */
1777 {ARM_EXT_V1
, 0xe1a00000, 0xffffffff, "nop\t\t\t(mov r0,r0)"},
1778 {ARM_EXT_V4T
| ARM_EXT_V5
, 0x012FFF10, 0x0ffffff0, "bx%c\t%0-3r"},
1779 {ARM_EXT_V2
, 0x00000090, 0x0fe000f0, "mul%20's%c\t%16-19r, %0-3r, %8-11r"},
1780 {ARM_EXT_V2
, 0x00200090, 0x0fe000f0, "mla%20's%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
1781 {ARM_EXT_V2S
, 0x01000090, 0x0fb00ff0, "swp%22'b%c\t%12-15r, %0-3r, [%16-19r]"},
1782 {ARM_EXT_V3M
, 0x00800090, 0x0fa000f0, "%22?sumull%20's%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
1783 {ARM_EXT_V3M
, 0x00a00090, 0x0fa000f0, "%22?sumlal%20's%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
1785 /* V7 instructions. */
1786 {ARM_EXT_V7
, 0xf410f000, 0xfc70f000, "pldw\t%a"},
1787 {ARM_EXT_V7
, 0xf450f000, 0xfd70f000, "pli\t%P"},
1788 {ARM_EXT_V7
, 0x0320f0f0, 0x0ffffff0, "dbg%c\t#%0-3d"},
1789 {ARM_EXT_V7
, 0xf57ff050, 0xfffffff0, "dmb\t%U"},
1790 {ARM_EXT_V7
, 0xf57ff040, 0xfffffff0, "dsb\t%U"},
1791 {ARM_EXT_V7
, 0xf57ff060, 0xfffffff0, "isb\t%U"},
1793 /* V7A optional instructions. */
1794 {ARM_EXT_V7A
, 0x0710f010, 0x0ff0f0f0, "sdiv%c\t%16-19r, %0-3r, %8-11r"},
1795 {ARM_EXT_V7A
, 0x0730f010, 0x0ff0f0f0, "udiv%c\t%16-19r, %0-3r, %8-11r"},
1797 /* ARM V6T2 instructions. */
1798 {ARM_EXT_V6T2
, 0x07c0001f, 0x0fe0007f, "bfc%c\t%12-15r, %E"},
1799 {ARM_EXT_V6T2
, 0x07c00010, 0x0fe00070, "bfi%c\t%12-15r, %0-3r, %E"},
1800 {ARM_EXT_V6T2
, 0x00600090, 0x0ff000f0, "mls%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
1801 {ARM_EXT_V6T2
, 0x006000b0, 0x0f7000f0, "strht%c\t%12-15r, %s"},
1802 {ARM_EXT_V6T2
, 0x00300090, 0x0f300090, "ldr%6's%5?hbt%c\t%12-15r, %s"},
1803 {ARM_EXT_V6T2
, 0x03000000, 0x0ff00000, "movw%c\t%12-15r, %V"},
1804 {ARM_EXT_V6T2
, 0x03400000, 0x0ff00000, "movt%c\t%12-15r, %V"},
1805 {ARM_EXT_V6T2
, 0x06ff0f30, 0x0fff0ff0, "rbit%c\t%12-15r, %0-3r"},
1806 {ARM_EXT_V6T2
, 0x07a00050, 0x0fa00070, "%22?usbfx%c\t%12-15r, %0-3r, #%7-11d, #%16-20W"},
1808 /* ARM V6Z instructions. */
1809 {ARM_EXT_V6Z
, 0x01600070, 0x0ff000f0, "smc%c\t%e"},
1811 /* ARM V6K instructions. */
1812 {ARM_EXT_V6K
, 0xf57ff01f, 0xffffffff, "clrex"},
1813 {ARM_EXT_V6K
, 0x01d00f9f, 0x0ff00fff, "ldrexb%c\t%12-15r, [%16-19r]"},
1814 {ARM_EXT_V6K
, 0x01b00f9f, 0x0ff00fff, "ldrexd%c\t%12-15r, [%16-19r]"},
1815 {ARM_EXT_V6K
, 0x01f00f9f, 0x0ff00fff, "ldrexh%c\t%12-15r, [%16-19r]"},
1816 {ARM_EXT_V6K
, 0x01c00f90, 0x0ff00ff0, "strexb%c\t%12-15r, %0-3r, [%16-19r]"},
1817 {ARM_EXT_V6K
, 0x01a00f90, 0x0ff00ff0, "strexd%c\t%12-15r, %0-3r, [%16-19r]"},
1818 {ARM_EXT_V6K
, 0x01e00f90, 0x0ff00ff0, "strexh%c\t%12-15r, %0-3r, [%16-19r]"},
1820 /* ARM V6K NOP hints. */
1821 {ARM_EXT_V6K
, 0x0320f001, 0x0fffffff, "yield%c"},
1822 {ARM_EXT_V6K
, 0x0320f002, 0x0fffffff, "wfe%c"},
1823 {ARM_EXT_V6K
, 0x0320f003, 0x0fffffff, "wfi%c"},
1824 {ARM_EXT_V6K
, 0x0320f004, 0x0fffffff, "sev%c"},
1825 {ARM_EXT_V6K
, 0x0320f000, 0x0fffff00, "nop%c\t{%0-7d}"},
1827 /* ARM V6 instructions. */
1828 {ARM_EXT_V6
, 0xf1080000, 0xfffffe3f, "cpsie\t%8'a%7'i%6'f"},
1829 {ARM_EXT_V6
, 0xf10a0000, 0xfffffe20, "cpsie\t%8'a%7'i%6'f,#%0-4d"},
1830 {ARM_EXT_V6
, 0xf10C0000, 0xfffffe3f, "cpsid\t%8'a%7'i%6'f"},
1831 {ARM_EXT_V6
, 0xf10e0000, 0xfffffe20, "cpsid\t%8'a%7'i%6'f,#%0-4d"},
1832 {ARM_EXT_V6
, 0xf1000000, 0xfff1fe20, "cps\t#%0-4d"},
1833 {ARM_EXT_V6
, 0x06800010, 0x0ff00ff0, "pkhbt%c\t%12-15r, %16-19r, %0-3r"},
1834 {ARM_EXT_V6
, 0x06800010, 0x0ff00070, "pkhbt%c\t%12-15r, %16-19r, %0-3r, lsl #%7-11d"},
1835 {ARM_EXT_V6
, 0x06800050, 0x0ff00ff0, "pkhtb%c\t%12-15r, %16-19r, %0-3r, asr #32"},
1836 {ARM_EXT_V6
, 0x06800050, 0x0ff00070, "pkhtb%c\t%12-15r, %16-19r, %0-3r, asr #%7-11d"},
1837 {ARM_EXT_V6
, 0x01900f9f, 0x0ff00fff, "ldrex%c\tr%12-15d, [%16-19r]"},
1838 {ARM_EXT_V6
, 0x06200f10, 0x0ff00ff0, "qadd16%c\t%12-15r, %16-19r, %0-3r"},
1839 {ARM_EXT_V6
, 0x06200f90, 0x0ff00ff0, "qadd8%c\t%12-15r, %16-19r, %0-3r"},
1840 {ARM_EXT_V6
, 0x06200f30, 0x0ff00ff0, "qaddsubx%c\t%12-15r, %16-19r, %0-3r"},
1841 {ARM_EXT_V6
, 0x06200f70, 0x0ff00ff0, "qsub16%c\t%12-15r, %16-19r, %0-3r"},
1842 {ARM_EXT_V6
, 0x06200ff0, 0x0ff00ff0, "qsub8%c\t%12-15r, %16-19r, %0-3r"},
1843 {ARM_EXT_V6
, 0x06200f50, 0x0ff00ff0, "qsubaddx%c\t%12-15r, %16-19r, %0-3r"},
1844 {ARM_EXT_V6
, 0x06100f10, 0x0ff00ff0, "sadd16%c\t%12-15r, %16-19r, %0-3r"},
1845 {ARM_EXT_V6
, 0x06100f90, 0x0ff00ff0, "sadd8%c\t%12-15r, %16-19r, %0-3r"},
1846 {ARM_EXT_V6
, 0x06100f30, 0x0ff00ff0, "saddaddx%c\t%12-15r, %16-19r, %0-3r"},
1847 {ARM_EXT_V6
, 0x06300f10, 0x0ff00ff0, "shadd16%c\t%12-15r, %16-19r, %0-3r"},
1848 {ARM_EXT_V6
, 0x06300f90, 0x0ff00ff0, "shadd8%c\t%12-15r, %16-19r, %0-3r"},
1849 {ARM_EXT_V6
, 0x06300f30, 0x0ff00ff0, "shaddsubx%c\t%12-15r, %16-19r, %0-3r"},
1850 {ARM_EXT_V6
, 0x06300f70, 0x0ff00ff0, "shsub16%c\t%12-15r, %16-19r, %0-3r"},
1851 {ARM_EXT_V6
, 0x06300ff0, 0x0ff00ff0, "shsub8%c\t%12-15r, %16-19r, %0-3r"},
1852 {ARM_EXT_V6
, 0x06300f50, 0x0ff00ff0, "shsubaddx%c\t%12-15r, %16-19r, %0-3r"},
1853 {ARM_EXT_V6
, 0x06100f70, 0x0ff00ff0, "ssub16%c\t%12-15r, %16-19r, %0-3r"},
1854 {ARM_EXT_V6
, 0x06100ff0, 0x0ff00ff0, "ssub8%c\t%12-15r, %16-19r, %0-3r"},
1855 {ARM_EXT_V6
, 0x06100f50, 0x0ff00ff0, "ssubaddx%c\t%12-15r, %16-19r, %0-3r"},
1856 {ARM_EXT_V6
, 0x06500f10, 0x0ff00ff0, "uadd16%c\t%12-15r, %16-19r, %0-3r"},
1857 {ARM_EXT_V6
, 0x06500f90, 0x0ff00ff0, "uadd8%c\t%12-15r, %16-19r, %0-3r"},
1858 {ARM_EXT_V6
, 0x06500f30, 0x0ff00ff0, "uaddsubx%c\t%12-15r, %16-19r, %0-3r"},
1859 {ARM_EXT_V6
, 0x06700f10, 0x0ff00ff0, "uhadd16%c\t%12-15r, %16-19r, %0-3r"},
1860 {ARM_EXT_V6
, 0x06700f90, 0x0ff00ff0, "uhadd8%c\t%12-15r, %16-19r, %0-3r"},
1861 {ARM_EXT_V6
, 0x06700f30, 0x0ff00ff0, "uhaddsubx%c\t%12-15r, %16-19r, %0-3r"},
1862 {ARM_EXT_V6
, 0x06700f70, 0x0ff00ff0, "uhsub16%c\t%12-15r, %16-19r, %0-3r"},
1863 {ARM_EXT_V6
, 0x06700ff0, 0x0ff00ff0, "uhsub8%c\t%12-15r, %16-19r, %0-3r"},
1864 {ARM_EXT_V6
, 0x06700f50, 0x0ff00ff0, "uhsubaddx%c\t%12-15r, %16-19r, %0-3r"},
1865 {ARM_EXT_V6
, 0x06600f10, 0x0ff00ff0, "uqadd16%c\t%12-15r, %16-19r, %0-3r"},
1866 {ARM_EXT_V6
, 0x06600f90, 0x0ff00ff0, "uqadd8%c\t%12-15r, %16-19r, %0-3r"},
1867 {ARM_EXT_V6
, 0x06600f30, 0x0ff00ff0, "uqaddsubx%c\t%12-15r, %16-19r, %0-3r"},
1868 {ARM_EXT_V6
, 0x06600f70, 0x0ff00ff0, "uqsub16%c\t%12-15r, %16-19r, %0-3r"},
1869 {ARM_EXT_V6
, 0x06600ff0, 0x0ff00ff0, "uqsub8%c\t%12-15r, %16-19r, %0-3r"},
1870 {ARM_EXT_V6
, 0x06600f50, 0x0ff00ff0, "uqsubaddx%c\t%12-15r, %16-19r, %0-3r"},
1871 {ARM_EXT_V6
, 0x06500f70, 0x0ff00ff0, "usub16%c\t%12-15r, %16-19r, %0-3r"},
1872 {ARM_EXT_V6
, 0x06500ff0, 0x0ff00ff0, "usub8%c\t%12-15r, %16-19r, %0-3r"},
1873 {ARM_EXT_V6
, 0x06500f50, 0x0ff00ff0, "usubaddx%c\t%12-15r, %16-19r, %0-3r"},
1874 {ARM_EXT_V6
, 0x06bf0f30, 0x0fff0ff0, "rev%c\t\%12-15r, %0-3r"},
1875 {ARM_EXT_V6
, 0x06bf0fb0, 0x0fff0ff0, "rev16%c\t\%12-15r, %0-3r"},
1876 {ARM_EXT_V6
, 0x06ff0fb0, 0x0fff0ff0, "revsh%c\t\%12-15r, %0-3r"},
1877 {ARM_EXT_V6
, 0xf8100a00, 0xfe50ffff, "rfe%23?id%24?ba\t\%16-19r%21'!"},
1878 {ARM_EXT_V6
, 0x06bf0070, 0x0fff0ff0, "sxth%c\t%12-15r, %0-3r"},
1879 {ARM_EXT_V6
, 0x06bf0470, 0x0fff0ff0, "sxth%c\t%12-15r, %0-3r, ror #8"},
1880 {ARM_EXT_V6
, 0x06bf0870, 0x0fff0ff0, "sxth%c\t%12-15r, %0-3r, ror #16"},
1881 {ARM_EXT_V6
, 0x06bf0c70, 0x0fff0ff0, "sxth%c\t%12-15r, %0-3r, ror #24"},
1882 {ARM_EXT_V6
, 0x068f0070, 0x0fff0ff0, "sxtb16%c\t%12-15r, %0-3r"},
1883 {ARM_EXT_V6
, 0x068f0470, 0x0fff0ff0, "sxtb16%c\t%12-15r, %0-3r, ror #8"},
1884 {ARM_EXT_V6
, 0x068f0870, 0x0fff0ff0, "sxtb16%c\t%12-15r, %0-3r, ror #16"},
1885 {ARM_EXT_V6
, 0x068f0c70, 0x0fff0ff0, "sxtb16%c\t%12-15r, %0-3r, ror #24"},
1886 {ARM_EXT_V6
, 0x06af0070, 0x0fff0ff0, "sxtb%c\t%12-15r, %0-3r"},
1887 {ARM_EXT_V6
, 0x06af0470, 0x0fff0ff0, "sxtb%c\t%12-15r, %0-3r, ror #8"},
1888 {ARM_EXT_V6
, 0x06af0870, 0x0fff0ff0, "sxtb%c\t%12-15r, %0-3r, ror #16"},
1889 {ARM_EXT_V6
, 0x06af0c70, 0x0fff0ff0, "sxtb%c\t%12-15r, %0-3r, ror #24"},
1890 {ARM_EXT_V6
, 0x06ff0070, 0x0fff0ff0, "uxth%c\t%12-15r, %0-3r"},
1891 {ARM_EXT_V6
, 0x06ff0470, 0x0fff0ff0, "uxth%c\t%12-15r, %0-3r, ror #8"},
1892 {ARM_EXT_V6
, 0x06ff0870, 0x0fff0ff0, "uxth%c\t%12-15r, %0-3r, ror #16"},
1893 {ARM_EXT_V6
, 0x06ff0c70, 0x0fff0ff0, "uxth%c\t%12-15r, %0-3r, ror #24"},
1894 {ARM_EXT_V6
, 0x06cf0070, 0x0fff0ff0, "uxtb16%c\t%12-15r, %0-3r"},
1895 {ARM_EXT_V6
, 0x06cf0470, 0x0fff0ff0, "uxtb16%c\t%12-15r, %0-3r, ror #8"},
1896 {ARM_EXT_V6
, 0x06cf0870, 0x0fff0ff0, "uxtb16%c\t%12-15r, %0-3r, ror #16"},
1897 {ARM_EXT_V6
, 0x06cf0c70, 0x0fff0ff0, "uxtb16%c\t%12-15r, %0-3r, ror #24"},
1898 {ARM_EXT_V6
, 0x06ef0070, 0x0fff0ff0, "uxtb%c\t%12-15r, %0-3r"},
1899 {ARM_EXT_V6
, 0x06ef0470, 0x0fff0ff0, "uxtb%c\t%12-15r, %0-3r, ror #8"},
1900 {ARM_EXT_V6
, 0x06ef0870, 0x0fff0ff0, "uxtb%c\t%12-15r, %0-3r, ror #16"},
1901 {ARM_EXT_V6
, 0x06ef0c70, 0x0fff0ff0, "uxtb%c\t%12-15r, %0-3r, ror #24"},
1902 {ARM_EXT_V6
, 0x06b00070, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r"},
1903 {ARM_EXT_V6
, 0x06b00470, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ror #8"},
1904 {ARM_EXT_V6
, 0x06b00870, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ror #16"},
1905 {ARM_EXT_V6
, 0x06b00c70, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ror #24"},
1906 {ARM_EXT_V6
, 0x06800070, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r"},
1907 {ARM_EXT_V6
, 0x06800470, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ror #8"},
1908 {ARM_EXT_V6
, 0x06800870, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ror #16"},
1909 {ARM_EXT_V6
, 0x06800c70, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ror #24"},
1910 {ARM_EXT_V6
, 0x06a00070, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r"},
1911 {ARM_EXT_V6
, 0x06a00470, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ror #8"},
1912 {ARM_EXT_V6
, 0x06a00870, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ror #16"},
1913 {ARM_EXT_V6
, 0x06a00c70, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ror #24"},
1914 {ARM_EXT_V6
, 0x06f00070, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r"},
1915 {ARM_EXT_V6
, 0x06f00470, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ror #8"},
1916 {ARM_EXT_V6
, 0x06f00870, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ror #16"},
1917 {ARM_EXT_V6
, 0x06f00c70, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ror #24"},
1918 {ARM_EXT_V6
, 0x06c00070, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r"},
1919 {ARM_EXT_V6
, 0x06c00470, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ror #8"},
1920 {ARM_EXT_V6
, 0x06c00870, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ror #16"},
1921 {ARM_EXT_V6
, 0x06c00c70, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
1922 {ARM_EXT_V6
, 0x06e00070, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r"},
1923 {ARM_EXT_V6
, 0x06e00470, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ror #8"},
1924 {ARM_EXT_V6
, 0x06e00870, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ror #16"},
1925 {ARM_EXT_V6
, 0x06e00c70, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ror #24"},
1926 {ARM_EXT_V6
, 0x06800fb0, 0x0ff00ff0, "sel%c\t%12-15r, %16-19r, %0-3r"},
1927 {ARM_EXT_V6
, 0xf1010000, 0xfffffc00, "setend\t%9?ble"},
1928 {ARM_EXT_V6
, 0x0700f010, 0x0ff0f0d0, "smuad%5'x%c\t%16-19r, %0-3r, %8-11r"},
1929 {ARM_EXT_V6
, 0x0700f050, 0x0ff0f0d0, "smusd%5'x%c\t%16-19r, %0-3r, %8-11r"},
1930 {ARM_EXT_V6
, 0x07000010, 0x0ff000d0, "smlad%5'x%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
1931 {ARM_EXT_V6
, 0x07400010, 0x0ff000d0, "smlald%5'x%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
1932 {ARM_EXT_V6
, 0x07000050, 0x0ff000d0, "smlsd%5'x%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
1933 {ARM_EXT_V6
, 0x07400050, 0x0ff000d0, "smlsld%5'x%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
1934 {ARM_EXT_V6
, 0x0750f010, 0x0ff0f0d0, "smmul%5'r%c\t%16-19r, %0-3r, %8-11r"},
1935 {ARM_EXT_V6
, 0x07500010, 0x0ff000d0, "smmla%5'r%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
1936 {ARM_EXT_V6
, 0x075000d0, 0x0ff000d0, "smmls%5'r%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
1937 {ARM_EXT_V6
, 0xf84d0500, 0xfe5fffe0, "srs%23?id%24?ba\t%16-19r%21'!, #%0-4d"},
1938 {ARM_EXT_V6
, 0x06a00010, 0x0fe00ff0, "ssat%c\t%12-15r, #%16-20W, %0-3r"},
1939 {ARM_EXT_V6
, 0x06a00010, 0x0fe00070, "ssat%c\t%12-15r, #%16-20W, %0-3r, lsl #%7-11d"},
1940 {ARM_EXT_V6
, 0x06a00050, 0x0fe00070, "ssat%c\t%12-15r, #%16-20W, %0-3r, asr #%7-11d"},
1941 {ARM_EXT_V6
, 0x06a00f30, 0x0ff00ff0, "ssat16%c\t%12-15r, #%16-19W, %0-3r"},
1942 {ARM_EXT_V6
, 0x01800f90, 0x0ff00ff0, "strex%c\t%12-15r, %0-3r, [%16-19r]"},
1943 {ARM_EXT_V6
, 0x00400090, 0x0ff000f0, "umaal%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
1944 {ARM_EXT_V6
, 0x0780f010, 0x0ff0f0f0, "usad8%c\t%16-19r, %0-3r, %8-11r"},
1945 {ARM_EXT_V6
, 0x07800010, 0x0ff000f0, "usada8%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
1946 {ARM_EXT_V6
, 0x06e00010, 0x0fe00ff0, "usat%c\t%12-15r, #%16-20d, %0-3r"},
1947 {ARM_EXT_V6
, 0x06e00010, 0x0fe00070, "usat%c\t%12-15r, #%16-20d, %0-3r, lsl #%7-11d"},
1948 {ARM_EXT_V6
, 0x06e00050, 0x0fe00070, "usat%c\t%12-15r, #%16-20d, %0-3r, asr #%7-11d"},
1949 {ARM_EXT_V6
, 0x06e00f30, 0x0ff00ff0, "usat16%c\t%12-15r, #%16-19d, %0-3r"},
1951 /* V5J instruction. */
1952 {ARM_EXT_V5J
, 0x012fff20, 0x0ffffff0, "bxj%c\t%0-3r"},
1954 /* V5 Instructions. */
1955 {ARM_EXT_V5
, 0xe1200070, 0xfff000f0, "bkpt\t0x%16-19X%12-15X%8-11X%0-3X"},
1956 {ARM_EXT_V5
, 0xfa000000, 0xfe000000, "blx\t%B"},
1957 {ARM_EXT_V5
, 0x012fff30, 0x0ffffff0, "blx%c\t%0-3r"},
1958 {ARM_EXT_V5
, 0x016f0f10, 0x0fff0ff0, "clz%c\t%12-15r, %0-3r"},
1960 /* V5E "El Segundo" Instructions. */
1961 {ARM_EXT_V5E
, 0x000000d0, 0x0e1000f0, "ldrd%c\t%12-15r, %s"},
1962 {ARM_EXT_V5E
, 0x000000f0, 0x0e1000f0, "strd%c\t%12-15r, %s"},
1963 {ARM_EXT_V5E
, 0xf450f000, 0xfc70f000, "pld\t%a"},
1964 {ARM_EXT_V5ExP
, 0x01000080, 0x0ff000f0, "smlabb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
1965 {ARM_EXT_V5ExP
, 0x010000a0, 0x0ff000f0, "smlatb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
1966 {ARM_EXT_V5ExP
, 0x010000c0, 0x0ff000f0, "smlabt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
1967 {ARM_EXT_V5ExP
, 0x010000e0, 0x0ff000f0, "smlatt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
1969 {ARM_EXT_V5ExP
, 0x01200080, 0x0ff000f0, "smlawb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
1970 {ARM_EXT_V5ExP
, 0x012000c0, 0x0ff000f0, "smlawt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
1972 {ARM_EXT_V5ExP
, 0x01400080, 0x0ff000f0, "smlalbb%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
1973 {ARM_EXT_V5ExP
, 0x014000a0, 0x0ff000f0, "smlaltb%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
1974 {ARM_EXT_V5ExP
, 0x014000c0, 0x0ff000f0, "smlalbt%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
1975 {ARM_EXT_V5ExP
, 0x014000e0, 0x0ff000f0, "smlaltt%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
1977 {ARM_EXT_V5ExP
, 0x01600080, 0x0ff0f0f0, "smulbb%c\t%16-19r, %0-3r, %8-11r"},
1978 {ARM_EXT_V5ExP
, 0x016000a0, 0x0ff0f0f0, "smultb%c\t%16-19r, %0-3r, %8-11r"},
1979 {ARM_EXT_V5ExP
, 0x016000c0, 0x0ff0f0f0, "smulbt%c\t%16-19r, %0-3r, %8-11r"},
1980 {ARM_EXT_V5ExP
, 0x016000e0, 0x0ff0f0f0, "smultt%c\t%16-19r, %0-3r, %8-11r"},
1982 {ARM_EXT_V5ExP
, 0x012000a0, 0x0ff0f0f0, "smulwb%c\t%16-19r, %0-3r, %8-11r"},
1983 {ARM_EXT_V5ExP
, 0x012000e0, 0x0ff0f0f0, "smulwt%c\t%16-19r, %0-3r, %8-11r"},
1985 {ARM_EXT_V5ExP
, 0x01000050, 0x0ff00ff0, "qadd%c\t%12-15r, %0-3r, %16-19r"},
1986 {ARM_EXT_V5ExP
, 0x01400050, 0x0ff00ff0, "qdadd%c\t%12-15r, %0-3r, %16-19r"},
1987 {ARM_EXT_V5ExP
, 0x01200050, 0x0ff00ff0, "qsub%c\t%12-15r, %0-3r, %16-19r"},
1988 {ARM_EXT_V5ExP
, 0x01600050, 0x0ff00ff0, "qdsub%c\t%12-15r, %0-3r, %16-19r"},
1990 /* ARM Instructions. */
1991 {ARM_EXT_V1
, 0x00000090, 0x0e100090, "str%6's%5?hb%c\t%12-15r, %s"},
1992 {ARM_EXT_V1
, 0x00100090, 0x0e100090, "ldr%6's%5?hb%c\t%12-15r, %s"},
1993 {ARM_EXT_V1
, 0x00000000, 0x0de00000, "and%20's%c\t%12-15r, %16-19r, %o"},
1994 {ARM_EXT_V1
, 0x00200000, 0x0de00000, "eor%20's%c\t%12-15r, %16-19r, %o"},
1995 {ARM_EXT_V1
, 0x00400000, 0x0de00000, "sub%20's%c\t%12-15r, %16-19r, %o"},
1996 {ARM_EXT_V1
, 0x00600000, 0x0de00000, "rsb%20's%c\t%12-15r, %16-19r, %o"},
1997 {ARM_EXT_V1
, 0x00800000, 0x0de00000, "add%20's%c\t%12-15r, %16-19r, %o"},
1998 {ARM_EXT_V1
, 0x00a00000, 0x0de00000, "adc%20's%c\t%12-15r, %16-19r, %o"},
1999 {ARM_EXT_V1
, 0x00c00000, 0x0de00000, "sbc%20's%c\t%12-15r, %16-19r, %o"},
2000 {ARM_EXT_V1
, 0x00e00000, 0x0de00000, "rsc%20's%c\t%12-15r, %16-19r, %o"},
2001 {ARM_EXT_V3
, 0x0120f000, 0x0db0f000, "msr%c\t%22?SCPSR%C, %o"},
2002 {ARM_EXT_V3
, 0x010f0000, 0x0fbf0fff, "mrs%c\t%12-15r, %22?SCPSR"},
2003 {ARM_EXT_V1
, 0x01000000, 0x0de00000, "tst%p%c\t%16-19r, %o"},
2004 {ARM_EXT_V1
, 0x01200000, 0x0de00000, "teq%p%c\t%16-19r, %o"},
2005 {ARM_EXT_V1
, 0x01400000, 0x0de00000, "cmp%p%c\t%16-19r, %o"},
2006 {ARM_EXT_V1
, 0x01600000, 0x0de00000, "cmn%p%c\t%16-19r, %o"},
2007 {ARM_EXT_V1
, 0x01800000, 0x0de00000, "orr%20's%c\t%12-15r, %16-19r, %o"},
2008 {ARM_EXT_V1
, 0x03a00000, 0x0fef0000, "mov%20's%c\t%12-15r, %o"},
2009 {ARM_EXT_V1
, 0x01a00000, 0x0def0ff0, "mov%20's%c\t%12-15r, %0-3r"},
2010 {ARM_EXT_V1
, 0x01a00000, 0x0def0060, "lsl%20's%c\t%12-15r, %q"},
2011 {ARM_EXT_V1
, 0x01a00020, 0x0def0060, "lsr%20's%c\t%12-15r, %q"},
2012 {ARM_EXT_V1
, 0x01a00040, 0x0def0060, "asr%20's%c\t%12-15r, %q"},
2013 {ARM_EXT_V1
, 0x01a00060, 0x0def0ff0, "rrx%20's%c\t%12-15r, %0-3r"},
2014 {ARM_EXT_V1
, 0x01a00060, 0x0def0060, "ror%20's%c\t%12-15r, %q"},
2015 {ARM_EXT_V1
, 0x01c00000, 0x0de00000, "bic%20's%c\t%12-15r, %16-19r, %o"},
2016 {ARM_EXT_V1
, 0x01e00000, 0x0de00000, "mvn%20's%c\t%12-15r, %o"},
2017 {ARM_EXT_V1
, 0x052d0004, 0x0fff0fff, "push%c\t{%12-15r}\t\t@ (str%c %12-15r, %a)"},
2018 {ARM_EXT_V1
, 0x04000000, 0x0e100000, "str%22'b%t%c\t%12-15r, %a"},
2019 {ARM_EXT_V1
, 0x06000000, 0x0e100ff0, "str%22'b%t%c\t%12-15r, %a"},
2020 {ARM_EXT_V1
, 0x04000000, 0x0c100010, "str%22'b%t%c\t%12-15r, %a"},
2021 {ARM_EXT_V1
, 0x06000010, 0x0e000010, "undefined"},
2022 {ARM_EXT_V1
, 0x049d0004, 0x0fff0fff, "pop%c\t{%12-15r}\t\t@ (ldr%c %12-15r, %a)"},
2023 {ARM_EXT_V1
, 0x04100000, 0x0c100000, "ldr%22'b%t%c\t%12-15r, %a"},
2024 {ARM_EXT_V1
, 0x092d0000, 0x0fff0000, "push%c\t%m"},
2025 {ARM_EXT_V1
, 0x08800000, 0x0ff00000, "stm%c\t%16-19r%21'!, %m%22'^"},
2026 {ARM_EXT_V1
, 0x08000000, 0x0e100000, "stm%23?id%24?ba%c\t%16-19r%21'!, %m%22'^"},
2027 {ARM_EXT_V1
, 0x08bd0000, 0x0fff0000, "pop%c\t%m"},
2028 {ARM_EXT_V1
, 0x08900000, 0x0f900000, "ldm%c\t%16-19r%21'!, %m%22'^"},
2029 {ARM_EXT_V1
, 0x08100000, 0x0e100000, "ldm%23?id%24?ba%c\t%16-19r%21'!, %m%22'^"},
2030 {ARM_EXT_V1
, 0x0a000000, 0x0e000000, "b%24'l%c\t%b"},
2031 {ARM_EXT_V1
, 0x0f000000, 0x0f000000, "svc%c\t%0-23x"},
2034 {ARM_EXT_V1
, 0x00000000, 0x00000000, "undefined instruction %0-31x"},
2035 {0, 0x00000000, 0x00000000, 0}
2038 /* print_insn_thumb16 recognizes the following format control codes:
2040 %S print Thumb register (bits 3..5 as high number if bit 6 set)
2041 %D print Thumb register (bits 0..2 as high number if bit 7 set)
2042 %<bitfield>I print bitfield as a signed decimal
2043 (top bit of range being the sign bit)
2044 %N print Thumb register mask (with LR)
2045 %O print Thumb register mask (with PC)
2046 %M print Thumb register mask
2047 %b print CZB's 6-bit unsigned branch destination
2048 %s print Thumb right-shift immediate (6..10; 0 == 32).
2049 %c print the condition code
2050 %C print the condition code, or "s" if not conditional
2051 %x print warning if conditional an not at end of IT block"
2052 %X print "\t@ unpredictable <IT:code>" if conditional
2053 %I print IT instruction suffix and operands
2054 %<bitfield>r print bitfield as an ARM register
2055 %<bitfield>Rc print bitfield as an ARM register and follow it with
2056 char c if the register mentioned in the bitfield is
2057 NOT in the register list in bits 0..7
2058 %<bitfield>d print bitfield as a decimal
2059 %<bitfield>H print (bitfield * 2) as a decimal
2060 %<bitfield>W print (bitfield * 4) as a decimal
2061 %<bitfield>a print (bitfield * 4) as a pc-rel offset + decoded symbol
2062 %<bitfield>B print Thumb branch destination (signed displacement)
2063 %<bitfield>c print bitfield as a condition code
2064 %<bitnum>'c print specified char iff bit is one
2065 %<bitnum>?ab print a if bit is one else print b. */
2067 static const struct opcode16 thumb_opcodes
[] =
2069 /* Thumb instructions. */
2071 {ARM_EXT_V4T
, 0xdefe, 0xffff, "trap"},
2073 /* ARM V6K no-argument instructions. */
2074 {ARM_EXT_V6K
, 0xbf00, 0xffff, "nop%c"},
2075 {ARM_EXT_V6K
, 0xbf10, 0xffff, "yield%c"},
2076 {ARM_EXT_V6K
, 0xbf20, 0xffff, "wfe%c"},
2077 {ARM_EXT_V6K
, 0xbf30, 0xffff, "wfi%c"},
2078 {ARM_EXT_V6K
, 0xbf40, 0xffff, "sev%c"},
2079 {ARM_EXT_V6K
, 0xbf00, 0xff0f, "nop%c\t{%4-7d}"},
2081 /* ARM V6T2 instructions. */
2082 {ARM_EXT_V6T2
, 0xb900, 0xfd00, "cbnz\t%0-2r, %b%X"},
2083 {ARM_EXT_V6T2
, 0xb100, 0xfd00, "cbz\t%0-2r, %b%X"},
2084 {ARM_EXT_V6T2
, 0xbf00, 0xff00, "it%I%X"},
2087 {ARM_EXT_V6
, 0xb660, 0xfff8, "cpsie\t%2'a%1'i%0'f%X"},
2088 {ARM_EXT_V6
, 0xb670, 0xfff8, "cpsid\t%2'a%1'i%0'f%X"},
2089 {ARM_EXT_V6
, 0x4600, 0xffc0, "mov%c\t%0-2r, %3-5r"},
2090 {ARM_EXT_V6
, 0xba00, 0xffc0, "rev%c\t%0-2r, %3-5r"},
2091 {ARM_EXT_V6
, 0xba40, 0xffc0, "rev16%c\t%0-2r, %3-5r"},
2092 {ARM_EXT_V6
, 0xbac0, 0xffc0, "revsh%c\t%0-2r, %3-5r"},
2093 {ARM_EXT_V6
, 0xb650, 0xfff7, "setend\t%3?ble%X"},
2094 {ARM_EXT_V6
, 0xb200, 0xffc0, "sxth%c\t%0-2r, %3-5r"},
2095 {ARM_EXT_V6
, 0xb240, 0xffc0, "sxtb%c\t%0-2r, %3-5r"},
2096 {ARM_EXT_V6
, 0xb280, 0xffc0, "uxth%c\t%0-2r, %3-5r"},
2097 {ARM_EXT_V6
, 0xb2c0, 0xffc0, "uxtb%c\t%0-2r, %3-5r"},
2099 /* ARM V5 ISA extends Thumb. */
2100 {ARM_EXT_V5T
, 0xbe00, 0xff00, "bkpt\t%0-7x"}, /* Is always unconditional. */
2101 /* This is BLX(2). BLX(1) is a 32-bit instruction. */
2102 {ARM_EXT_V5T
, 0x4780, 0xff87, "blx%c\t%3-6r%x"}, /* note: 4 bit register number. */
2103 /* ARM V4T ISA (Thumb v1). */
2104 {ARM_EXT_V4T
, 0x46C0, 0xFFFF, "nop%c\t\t\t(mov r8, r8)"},
2106 {ARM_EXT_V4T
, 0x4000, 0xFFC0, "and%C\t%0-2r, %3-5r"},
2107 {ARM_EXT_V4T
, 0x4040, 0xFFC0, "eor%C\t%0-2r, %3-5r"},
2108 {ARM_EXT_V4T
, 0x4080, 0xFFC0, "lsl%C\t%0-2r, %3-5r"},
2109 {ARM_EXT_V4T
, 0x40C0, 0xFFC0, "lsr%C\t%0-2r, %3-5r"},
2110 {ARM_EXT_V4T
, 0x4100, 0xFFC0, "asr%C\t%0-2r, %3-5r"},
2111 {ARM_EXT_V4T
, 0x4140, 0xFFC0, "adc%C\t%0-2r, %3-5r"},
2112 {ARM_EXT_V4T
, 0x4180, 0xFFC0, "sbc%C\t%0-2r, %3-5r"},
2113 {ARM_EXT_V4T
, 0x41C0, 0xFFC0, "ror%C\t%0-2r, %3-5r"},
2114 {ARM_EXT_V4T
, 0x4200, 0xFFC0, "tst%c\t%0-2r, %3-5r"},
2115 {ARM_EXT_V4T
, 0x4240, 0xFFC0, "neg%C\t%0-2r, %3-5r"},
2116 {ARM_EXT_V4T
, 0x4280, 0xFFC0, "cmp%c\t%0-2r, %3-5r"},
2117 {ARM_EXT_V4T
, 0x42C0, 0xFFC0, "cmn%c\t%0-2r, %3-5r"},
2118 {ARM_EXT_V4T
, 0x4300, 0xFFC0, "orr%C\t%0-2r, %3-5r"},
2119 {ARM_EXT_V4T
, 0x4340, 0xFFC0, "mul%C\t%0-2r, %3-5r"},
2120 {ARM_EXT_V4T
, 0x4380, 0xFFC0, "bic%C\t%0-2r, %3-5r"},
2121 {ARM_EXT_V4T
, 0x43C0, 0xFFC0, "mvn%C\t%0-2r, %3-5r"},
2123 {ARM_EXT_V4T
, 0xB000, 0xFF80, "add%c\tsp, #%0-6W"},
2124 {ARM_EXT_V4T
, 0xB080, 0xFF80, "sub%c\tsp, #%0-6W"},
2126 {ARM_EXT_V4T
, 0x4700, 0xFF80, "bx%c\t%S%x"},
2127 {ARM_EXT_V4T
, 0x4400, 0xFF00, "add%c\t%D, %S"},
2128 {ARM_EXT_V4T
, 0x4500, 0xFF00, "cmp%c\t%D, %S"},
2129 {ARM_EXT_V4T
, 0x4600, 0xFF00, "mov%c\t%D, %S"},
2131 {ARM_EXT_V4T
, 0xB400, 0xFE00, "push%c\t%N"},
2132 {ARM_EXT_V4T
, 0xBC00, 0xFE00, "pop%c\t%O"},
2134 {ARM_EXT_V4T
, 0x1800, 0xFE00, "add%C\t%0-2r, %3-5r, %6-8r"},
2135 {ARM_EXT_V4T
, 0x1A00, 0xFE00, "sub%C\t%0-2r, %3-5r, %6-8r"},
2136 {ARM_EXT_V4T
, 0x1C00, 0xFE00, "add%C\t%0-2r, %3-5r, #%6-8d"},
2137 {ARM_EXT_V4T
, 0x1E00, 0xFE00, "sub%C\t%0-2r, %3-5r, #%6-8d"},
2139 {ARM_EXT_V4T
, 0x5200, 0xFE00, "strh%c\t%0-2r, [%3-5r, %6-8r]"},
2140 {ARM_EXT_V4T
, 0x5A00, 0xFE00, "ldrh%c\t%0-2r, [%3-5r, %6-8r]"},
2141 {ARM_EXT_V4T
, 0x5600, 0xF600, "ldrs%11?hb%c\t%0-2r, [%3-5r, %6-8r]"},
2143 {ARM_EXT_V4T
, 0x5000, 0xFA00, "str%10'b%c\t%0-2r, [%3-5r, %6-8r]"},
2144 {ARM_EXT_V4T
, 0x5800, 0xFA00, "ldr%10'b%c\t%0-2r, [%3-5r, %6-8r]"},
2146 {ARM_EXT_V4T
, 0x0000, 0xF800, "lsl%C\t%0-2r, %3-5r, #%6-10d"},
2147 {ARM_EXT_V4T
, 0x0800, 0xF800, "lsr%C\t%0-2r, %3-5r, %s"},
2148 {ARM_EXT_V4T
, 0x1000, 0xF800, "asr%C\t%0-2r, %3-5r, %s"},
2150 {ARM_EXT_V4T
, 0x2000, 0xF800, "mov%C\t%8-10r, #%0-7d"},
2151 {ARM_EXT_V4T
, 0x2800, 0xF800, "cmp%c\t%8-10r, #%0-7d"},
2152 {ARM_EXT_V4T
, 0x3000, 0xF800, "add%C\t%8-10r, #%0-7d"},
2153 {ARM_EXT_V4T
, 0x3800, 0xF800, "sub%C\t%8-10r, #%0-7d"},
2155 {ARM_EXT_V4T
, 0x4800, 0xF800, "ldr%c\t%8-10r, [pc, #%0-7W]\t(%0-7a)"}, /* TODO: Disassemble PC relative "LDR rD,=<symbolic>" */
2157 {ARM_EXT_V4T
, 0x6000, 0xF800, "str%c\t%0-2r, [%3-5r, #%6-10W]"},
2158 {ARM_EXT_V4T
, 0x6800, 0xF800, "ldr%c\t%0-2r, [%3-5r, #%6-10W]"},
2159 {ARM_EXT_V4T
, 0x7000, 0xF800, "strb%c\t%0-2r, [%3-5r, #%6-10d]"},
2160 {ARM_EXT_V4T
, 0x7800, 0xF800, "ldrb%c\t%0-2r, [%3-5r, #%6-10d]"},
2162 {ARM_EXT_V4T
, 0x8000, 0xF800, "strh%c\t%0-2r, [%3-5r, #%6-10H]"},
2163 {ARM_EXT_V4T
, 0x8800, 0xF800, "ldrh%c\t%0-2r, [%3-5r, #%6-10H]"},
2165 {ARM_EXT_V4T
, 0x9000, 0xF800, "str%c\t%8-10r, [sp, #%0-7W]"},
2166 {ARM_EXT_V4T
, 0x9800, 0xF800, "ldr%c\t%8-10r, [sp, #%0-7W]"},
2168 {ARM_EXT_V4T
, 0xA000, 0xF800, "add%c\t%8-10r, pc, #%0-7W\t(adr %8-10r, %0-7a)"},
2169 {ARM_EXT_V4T
, 0xA800, 0xF800, "add%c\t%8-10r, sp, #%0-7W"},
2171 {ARM_EXT_V4T
, 0xC000, 0xF800, "stmia%c\t%8-10r!, %M"},
2172 {ARM_EXT_V4T
, 0xC800, 0xF800, "ldmia%c\t%8-10R!, %M"},
2174 {ARM_EXT_V4T
, 0xDF00, 0xFF00, "svc%c\t%0-7d"},
2176 {ARM_EXT_V4T
, 0xDE00, 0xFE00, "undefined"},
2177 {ARM_EXT_V4T
, 0xD000, 0xF000, "b%8-11c.n\t%0-7B%X"},
2179 {ARM_EXT_V4T
, 0xE000, 0xF800, "b%c.n\t%0-10B%x"},
2181 /* The E800 .. FFFF range is unconditionally redirected to the
2182 32-bit table, because even in pre-V6T2 ISAs, BL and BLX(1) pairs
2183 are processed via that table. Thus, we can never encounter a
2184 bare "second half of BL/BLX(1)" instruction here. */
2185 {ARM_EXT_V1
, 0x0000, 0x0000, "undefined"},
2189 /* Thumb32 opcodes use the same table structure as the ARM opcodes.
2190 We adopt the convention that hw1 is the high 16 bits of .value and
2191 .mask, hw2 the low 16 bits.
2193 print_insn_thumb32 recognizes the following format control codes:
2197 %I print a 12-bit immediate from hw1[10],hw2[14:12,7:0]
2198 %M print a modified 12-bit immediate (same location)
2199 %J print a 16-bit immediate from hw1[3:0,10],hw2[14:12,7:0]
2200 %K print a 16-bit immediate from hw2[3:0],hw1[3:0],hw2[11:4]
2201 %S print a possibly-shifted Rm
2203 %a print the address of a plain load/store
2204 %w print the width and signedness of a core load/store
2205 %m print register mask for ldm/stm
2207 %E print the lsb and width fields of a bfc/bfi instruction
2208 %F print the lsb and width fields of a sbfx/ubfx instruction
2209 %b print a conditional branch offset
2210 %B print an unconditional branch offset
2211 %s print the shift field of an SSAT instruction
2212 %R print the rotation field of an SXT instruction
2213 %U print barrier type.
2214 %P print address for pli instruction.
2215 %c print the condition code
2216 %x print warning if conditional an not at end of IT block"
2217 %X print "\t@ unpredictable <IT:code>" if conditional
2219 %<bitfield>d print bitfield in decimal
2220 %<bitfield>W print bitfield*4 in decimal
2221 %<bitfield>r print bitfield as an ARM register
2222 %<bitfield>c print bitfield as a condition code
2224 %<bitfield>'c print specified char iff bitfield is all ones
2225 %<bitfield>`c print specified char iff bitfield is all zeroes
2226 %<bitfield>?ab... select from array of values in big endian order
2228 With one exception at the bottom (done because BL and BLX(1) need
2229 to come dead last), this table was machine-sorted first in
2230 decreasing order of number of bits set in the mask, then in
2231 increasing numeric order of mask, then in increasing numeric order
2232 of opcode. This order is not the clearest for a human reader, but
2233 is guaranteed never to catch a special-case bit pattern with a more
2234 general mask, which is important, because this instruction encoding
2235 makes heavy use of special-case bit patterns. */
2236 static const struct opcode32 thumb32_opcodes
[] =
2238 /* V7 instructions. */
2239 {ARM_EXT_V7
, 0xf910f000, 0xff70f000, "pli%c\t%a"},
2240 {ARM_EXT_V7
, 0xf830f000, 0xff70f000, "pldw%c\t%a"},
2241 {ARM_EXT_V7
, 0xf3af80f0, 0xfffffff0, "dbg%c\t#%0-3d"},
2242 {ARM_EXT_V7
, 0xf3bf8f50, 0xfffffff0, "dmb%c\t%U"},
2243 {ARM_EXT_V7
, 0xf3bf8f40, 0xfffffff0, "dsb%c\t%U"},
2244 {ARM_EXT_V7
, 0xf3bf8f60, 0xfffffff0, "isb%c\t%U"},
2245 {ARM_EXT_DIV
, 0xfb90f0f0, 0xfff0f0f0, "sdiv%c\t%8-11r, %16-19r, %0-3r"},
2246 {ARM_EXT_DIV
, 0xfbb0f0f0, 0xfff0f0f0, "udiv%c\t%8-11r, %16-19r, %0-3r"},
2248 /* Instructions defined in the basic V6T2 set. */
2249 {ARM_EXT_V6T2
, 0xf3af8000, 0xffffffff, "nop%c.w"},
2250 {ARM_EXT_V6T2
, 0xf3af8001, 0xffffffff, "yield%c.w"},
2251 {ARM_EXT_V6T2
, 0xf3af8002, 0xffffffff, "wfe%c.w"},
2252 {ARM_EXT_V6T2
, 0xf3af8003, 0xffffffff, "wfi%c.w"},
2253 {ARM_EXT_V6T2
, 0xf3af8004, 0xffffffff, "sev%c.w"},
2254 {ARM_EXT_V6T2
, 0xf3af8000, 0xffffff00, "nop%c.w\t{%0-7d}"},
2256 {ARM_EXT_V6T2
, 0xf3bf8f2f, 0xffffffff, "clrex%c"},
2257 {ARM_EXT_V6T2
, 0xf3af8400, 0xffffff1f, "cpsie.w\t%7'a%6'i%5'f%X"},
2258 {ARM_EXT_V6T2
, 0xf3af8600, 0xffffff1f, "cpsid.w\t%7'a%6'i%5'f%X"},
2259 {ARM_EXT_V6T2
, 0xf3c08f00, 0xfff0ffff, "bxj%c\t%16-19r%x"},
2260 {ARM_EXT_V6T2
, 0xe810c000, 0xffd0ffff, "rfedb%c\t%16-19r%21'!"},
2261 {ARM_EXT_V6T2
, 0xe990c000, 0xffd0ffff, "rfeia%c\t%16-19r%21'!"},
2262 {ARM_EXT_V6T2
, 0xf3ef8000, 0xffeff000, "mrs%c\t%8-11r, %D"},
2263 {ARM_EXT_V6T2
, 0xf3af8100, 0xffffffe0, "cps\t#%0-4d%X"},
2264 {ARM_EXT_V6T2
, 0xe8d0f000, 0xfff0fff0, "tbb%c\t[%16-19r, %0-3r]%x"},
2265 {ARM_EXT_V6T2
, 0xe8d0f010, 0xfff0fff0, "tbh%c\t[%16-19r, %0-3r, lsl #1]%x"},
2266 {ARM_EXT_V6T2
, 0xf3af8500, 0xffffff00, "cpsie\t%7'a%6'i%5'f, #%0-4d%X"},
2267 {ARM_EXT_V6T2
, 0xf3af8700, 0xffffff00, "cpsid\t%7'a%6'i%5'f, #%0-4d%X"},
2268 {ARM_EXT_V6T2
, 0xf3de8f00, 0xffffff00, "subs%c\tpc, lr, #%0-7d"},
2269 {ARM_EXT_V6T2
, 0xf3808000, 0xffe0f000, "msr%c\t%C, %16-19r"},
2270 {ARM_EXT_V6T2
, 0xe8500f00, 0xfff00fff, "ldrex%c\t%12-15r, [%16-19r]"},
2271 {ARM_EXT_V6T2
, 0xe8d00f4f, 0xfff00fef, "ldrex%4?hb%c\t%12-15r, [%16-19r]"},
2272 {ARM_EXT_V6T2
, 0xe800c000, 0xffd0ffe0, "srsdb%c\t%16-19r%21'!, #%0-4d"},
2273 {ARM_EXT_V6T2
, 0xe980c000, 0xffd0ffe0, "srsia%c\t%16-19r%21'!, #%0-4d"},
2274 {ARM_EXT_V6T2
, 0xfa0ff080, 0xfffff0c0, "sxth%c.w\t%8-11r, %0-3r%R"},
2275 {ARM_EXT_V6T2
, 0xfa1ff080, 0xfffff0c0, "uxth%c.w\t%8-11r, %0-3r%R"},
2276 {ARM_EXT_V6T2
, 0xfa2ff080, 0xfffff0c0, "sxtb16%c\t%8-11r, %0-3r%R"},
2277 {ARM_EXT_V6T2
, 0xfa3ff080, 0xfffff0c0, "uxtb16%c\t%8-11r, %0-3r%R"},
2278 {ARM_EXT_V6T2
, 0xfa4ff080, 0xfffff0c0, "sxtb%c.w\t%8-11r, %0-3r%R"},
2279 {ARM_EXT_V6T2
, 0xfa5ff080, 0xfffff0c0, "uxtb%c.w\t%8-11r, %0-3r%R"},
2280 {ARM_EXT_V6T2
, 0xe8400000, 0xfff000ff, "strex%c\t%8-11r, %12-15r, [%16-19r]"},
2281 {ARM_EXT_V6T2
, 0xe8d0007f, 0xfff000ff, "ldrexd%c\t%12-15r, %8-11r, [%16-19r]"},
2282 {ARM_EXT_V6T2
, 0xfa80f000, 0xfff0f0f0, "sadd8%c\t%8-11r, %16-19r, %0-3r"},
2283 {ARM_EXT_V6T2
, 0xfa80f010, 0xfff0f0f0, "qadd8%c\t%8-11r, %16-19r, %0-3r"},
2284 {ARM_EXT_V6T2
, 0xfa80f020, 0xfff0f0f0, "shadd8%c\t%8-11r, %16-19r, %0-3r"},
2285 {ARM_EXT_V6T2
, 0xfa80f040, 0xfff0f0f0, "uadd8%c\t%8-11r, %16-19r, %0-3r"},
2286 {ARM_EXT_V6T2
, 0xfa80f050, 0xfff0f0f0, "uqadd8%c\t%8-11r, %16-19r, %0-3r"},
2287 {ARM_EXT_V6T2
, 0xfa80f060, 0xfff0f0f0, "uhadd8%c\t%8-11r, %16-19r, %0-3r"},
2288 {ARM_EXT_V6T2
, 0xfa80f080, 0xfff0f0f0, "qadd%c\t%8-11r, %0-3r, %16-19r"},
2289 {ARM_EXT_V6T2
, 0xfa80f090, 0xfff0f0f0, "qdadd%c\t%8-11r, %0-3r, %16-19r"},
2290 {ARM_EXT_V6T2
, 0xfa80f0a0, 0xfff0f0f0, "qsub%c\t%8-11r, %0-3r, %16-19r"},
2291 {ARM_EXT_V6T2
, 0xfa80f0b0, 0xfff0f0f0, "qdsub%c\t%8-11r, %0-3r, %16-19r"},
2292 {ARM_EXT_V6T2
, 0xfa90f000, 0xfff0f0f0, "sadd16%c\t%8-11r, %16-19r, %0-3r"},
2293 {ARM_EXT_V6T2
, 0xfa90f010, 0xfff0f0f0, "qadd16%c\t%8-11r, %16-19r, %0-3r"},
2294 {ARM_EXT_V6T2
, 0xfa90f020, 0xfff0f0f0, "shadd16%c\t%8-11r, %16-19r, %0-3r"},
2295 {ARM_EXT_V6T2
, 0xfa90f040, 0xfff0f0f0, "uadd16%c\t%8-11r, %16-19r, %0-3r"},
2296 {ARM_EXT_V6T2
, 0xfa90f050, 0xfff0f0f0, "uqadd16%c\t%8-11r, %16-19r, %0-3r"},
2297 {ARM_EXT_V6T2
, 0xfa90f060, 0xfff0f0f0, "uhadd16%c\t%8-11r, %16-19r, %0-3r"},
2298 {ARM_EXT_V6T2
, 0xfa90f080, 0xfff0f0f0, "rev%c.w\t%8-11r, %16-19r"},
2299 {ARM_EXT_V6T2
, 0xfa90f090, 0xfff0f0f0, "rev16%c.w\t%8-11r, %16-19r"},
2300 {ARM_EXT_V6T2
, 0xfa90f0a0, 0xfff0f0f0, "rbit%c\t%8-11r, %16-19r"},
2301 {ARM_EXT_V6T2
, 0xfa90f0b0, 0xfff0f0f0, "revsh%c.w\t%8-11r, %16-19r"},
2302 {ARM_EXT_V6T2
, 0xfaa0f000, 0xfff0f0f0, "saddsubx%c\t%8-11r, %16-19r, %0-3r"},
2303 {ARM_EXT_V6T2
, 0xfaa0f010, 0xfff0f0f0, "qaddsubx%c\t%8-11r, %16-19r, %0-3r"},
2304 {ARM_EXT_V6T2
, 0xfaa0f020, 0xfff0f0f0, "shaddsubx%c\t%8-11r, %16-19r, %0-3r"},
2305 {ARM_EXT_V6T2
, 0xfaa0f040, 0xfff0f0f0, "uaddsubx%c\t%8-11r, %16-19r, %0-3r"},
2306 {ARM_EXT_V6T2
, 0xfaa0f050, 0xfff0f0f0, "uqaddsubx%c\t%8-11r, %16-19r, %0-3r"},
2307 {ARM_EXT_V6T2
, 0xfaa0f060, 0xfff0f0f0, "uhaddsubx%c\t%8-11r, %16-19r, %0-3r"},
2308 {ARM_EXT_V6T2
, 0xfaa0f080, 0xfff0f0f0, "sel%c\t%8-11r, %16-19r, %0-3r"},
2309 {ARM_EXT_V6T2
, 0xfab0f080, 0xfff0f0f0, "clz%c\t%8-11r, %16-19r"},
2310 {ARM_EXT_V6T2
, 0xfac0f000, 0xfff0f0f0, "ssub8%c\t%8-11r, %16-19r, %0-3r"},
2311 {ARM_EXT_V6T2
, 0xfac0f010, 0xfff0f0f0, "qsub8%c\t%8-11r, %16-19r, %0-3r"},
2312 {ARM_EXT_V6T2
, 0xfac0f020, 0xfff0f0f0, "shsub8%c\t%8-11r, %16-19r, %0-3r"},
2313 {ARM_EXT_V6T2
, 0xfac0f040, 0xfff0f0f0, "usub8%c\t%8-11r, %16-19r, %0-3r"},
2314 {ARM_EXT_V6T2
, 0xfac0f050, 0xfff0f0f0, "uqsub8%c\t%8-11r, %16-19r, %0-3r"},
2315 {ARM_EXT_V6T2
, 0xfac0f060, 0xfff0f0f0, "uhsub8%c\t%8-11r, %16-19r, %0-3r"},
2316 {ARM_EXT_V6T2
, 0xfad0f000, 0xfff0f0f0, "ssub16%c\t%8-11r, %16-19r, %0-3r"},
2317 {ARM_EXT_V6T2
, 0xfad0f010, 0xfff0f0f0, "qsub16%c\t%8-11r, %16-19r, %0-3r"},
2318 {ARM_EXT_V6T2
, 0xfad0f020, 0xfff0f0f0, "shsub16%c\t%8-11r, %16-19r, %0-3r"},
2319 {ARM_EXT_V6T2
, 0xfad0f040, 0xfff0f0f0, "usub16%c\t%8-11r, %16-19r, %0-3r"},
2320 {ARM_EXT_V6T2
, 0xfad0f050, 0xfff0f0f0, "uqsub16%c\t%8-11r, %16-19r, %0-3r"},
2321 {ARM_EXT_V6T2
, 0xfad0f060, 0xfff0f0f0, "uhsub16%c\t%8-11r, %16-19r, %0-3r"},
2322 {ARM_EXT_V6T2
, 0xfae0f000, 0xfff0f0f0, "ssubaddx%c\t%8-11r, %16-19r, %0-3r"},
2323 {ARM_EXT_V6T2
, 0xfae0f010, 0xfff0f0f0, "qsubaddx%c\t%8-11r, %16-19r, %0-3r"},
2324 {ARM_EXT_V6T2
, 0xfae0f020, 0xfff0f0f0, "shsubaddx%c\t%8-11r, %16-19r, %0-3r"},
2325 {ARM_EXT_V6T2
, 0xfae0f040, 0xfff0f0f0, "usubaddx%c\t%8-11r, %16-19r, %0-3r"},
2326 {ARM_EXT_V6T2
, 0xfae0f050, 0xfff0f0f0, "uqsubaddx%c\t%8-11r, %16-19r, %0-3r"},
2327 {ARM_EXT_V6T2
, 0xfae0f060, 0xfff0f0f0, "uhsubaddx%c\t%8-11r, %16-19r, %0-3r"},
2328 {ARM_EXT_V6T2
, 0xfb00f000, 0xfff0f0f0, "mul%c.w\t%8-11r, %16-19r, %0-3r"},
2329 {ARM_EXT_V6T2
, 0xfb70f000, 0xfff0f0f0, "usad8%c\t%8-11r, %16-19r, %0-3r"},
2330 {ARM_EXT_V6T2
, 0xfa00f000, 0xffe0f0f0, "lsl%20's%c.w\t%8-11r, %16-19r, %0-3r"},
2331 {ARM_EXT_V6T2
, 0xfa20f000, 0xffe0f0f0, "lsr%20's%c.w\t%8-11r, %16-19r, %0-3r"},
2332 {ARM_EXT_V6T2
, 0xfa40f000, 0xffe0f0f0, "asr%20's%c.w\t%8-11r, %16-19r, %0-3r"},
2333 {ARM_EXT_V6T2
, 0xfa60f000, 0xffe0f0f0, "ror%20's%c.w\t%8-11r, %16-19r, %0-3r"},
2334 {ARM_EXT_V6T2
, 0xe8c00f40, 0xfff00fe0, "strex%4?hb%c\t%0-3r, %12-15r, [%16-19r]"},
2335 {ARM_EXT_V6T2
, 0xf3200000, 0xfff0f0e0, "ssat16%c\t%8-11r, #%0-4d, %16-19r"},
2336 {ARM_EXT_V6T2
, 0xf3a00000, 0xfff0f0e0, "usat16%c\t%8-11r, #%0-4d, %16-19r"},
2337 {ARM_EXT_V6T2
, 0xfb20f000, 0xfff0f0e0, "smuad%4'x%c\t%8-11r, %16-19r, %0-3r"},
2338 {ARM_EXT_V6T2
, 0xfb30f000, 0xfff0f0e0, "smulw%4?tb%c\t%8-11r, %16-19r, %0-3r"},
2339 {ARM_EXT_V6T2
, 0xfb40f000, 0xfff0f0e0, "smusd%4'x%c\t%8-11r, %16-19r, %0-3r"},
2340 {ARM_EXT_V6T2
, 0xfb50f000, 0xfff0f0e0, "smmul%4'r%c\t%8-11r, %16-19r, %0-3r"},
2341 {ARM_EXT_V6T2
, 0xfa00f080, 0xfff0f0c0, "sxtah%c\t%8-11r, %16-19r, %0-3r%R"},
2342 {ARM_EXT_V6T2
, 0xfa10f080, 0xfff0f0c0, "uxtah%c\t%8-11r, %16-19r, %0-3r%R"},
2343 {ARM_EXT_V6T2
, 0xfa20f080, 0xfff0f0c0, "sxtab16%c\t%8-11r, %16-19r, %0-3r%R"},
2344 {ARM_EXT_V6T2
, 0xfa30f080, 0xfff0f0c0, "uxtab16%c\t%8-11r, %16-19r, %0-3r%R"},
2345 {ARM_EXT_V6T2
, 0xfa40f080, 0xfff0f0c0, "sxtab%c\t%8-11r, %16-19r, %0-3r%R"},
2346 {ARM_EXT_V6T2
, 0xfa50f080, 0xfff0f0c0, "uxtab%c\t%8-11r, %16-19r, %0-3r%R"},
2347 {ARM_EXT_V6T2
, 0xfb10f000, 0xfff0f0c0, "smul%5?tb%4?tb%c\t%8-11r, %16-19r, %0-3r"},
2348 {ARM_EXT_V6T2
, 0xf36f0000, 0xffff8020, "bfc%c\t%8-11r, %E"},
2349 {ARM_EXT_V6T2
, 0xea100f00, 0xfff08f00, "tst%c.w\t%16-19r, %S"},
2350 {ARM_EXT_V6T2
, 0xea900f00, 0xfff08f00, "teq%c\t%16-19r, %S"},
2351 {ARM_EXT_V6T2
, 0xeb100f00, 0xfff08f00, "cmn%c.w\t%16-19r, %S"},
2352 {ARM_EXT_V6T2
, 0xebb00f00, 0xfff08f00, "cmp%c.w\t%16-19r, %S"},
2353 {ARM_EXT_V6T2
, 0xf0100f00, 0xfbf08f00, "tst%c.w\t%16-19r, %M"},
2354 {ARM_EXT_V6T2
, 0xf0900f00, 0xfbf08f00, "teq%c\t%16-19r, %M"},
2355 {ARM_EXT_V6T2
, 0xf1100f00, 0xfbf08f00, "cmn%c.w\t%16-19r, %M"},
2356 {ARM_EXT_V6T2
, 0xf1b00f00, 0xfbf08f00, "cmp%c.w\t%16-19r, %M"},
2357 {ARM_EXT_V6T2
, 0xea4f0030, 0xffef80f0, "rrx%20's\t%8-11r, %0-3r"},
2358 {ARM_EXT_V6T2
, 0xea4f0000, 0xffef8000, "mov%20's%c.w\t%8-11r, %S"},
2359 {ARM_EXT_V6T2
, 0xea6f0000, 0xffef8000, "mvn%20's%c.w\t%8-11r, %S"},
2360 {ARM_EXT_V6T2
, 0xe8c00070, 0xfff000f0, "strexd%c\t%0-3r, %12-15r, %8-11r, [%16-19r]"},
2361 {ARM_EXT_V6T2
, 0xfb000000, 0xfff000f0, "mla%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
2362 {ARM_EXT_V6T2
, 0xfb000010, 0xfff000f0, "mls%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
2363 {ARM_EXT_V6T2
, 0xfb700000, 0xfff000f0, "usada8%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
2364 {ARM_EXT_V6T2
, 0xfb800000, 0xfff000f0, "smull%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
2365 {ARM_EXT_V6T2
, 0xfba00000, 0xfff000f0, "umull%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
2366 {ARM_EXT_V6T2
, 0xfbc00000, 0xfff000f0, "smlal%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
2367 {ARM_EXT_V6T2
, 0xfbe00000, 0xfff000f0, "umlal%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
2368 {ARM_EXT_V6T2
, 0xfbe00060, 0xfff000f0, "umaal%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
2369 {ARM_EXT_V6T2
, 0xe8500f00, 0xfff00f00, "ldrex%c\t%12-15r, [%16-19r, #%0-7W]"},
2370 {ARM_EXT_V6T2
, 0xf7f08000, 0xfff0f000, "smc%c\t%K"},
2371 {ARM_EXT_V6T2
, 0xf04f0000, 0xfbef8000, "mov%20's%c.w\t%8-11r, %M"},
2372 {ARM_EXT_V6T2
, 0xf06f0000, 0xfbef8000, "mvn%20's%c.w\t%8-11r, %M"},
2373 {ARM_EXT_V6T2
, 0xf810f000, 0xff70f000, "pld%c\t%a"},
2374 {ARM_EXT_V6T2
, 0xfb200000, 0xfff000e0, "smlad%4'x%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
2375 {ARM_EXT_V6T2
, 0xfb300000, 0xfff000e0, "smlaw%4?tb%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
2376 {ARM_EXT_V6T2
, 0xfb400000, 0xfff000e0, "smlsd%4'x%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
2377 {ARM_EXT_V6T2
, 0xfb500000, 0xfff000e0, "smmla%4'r%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
2378 {ARM_EXT_V6T2
, 0xfb600000, 0xfff000e0, "smmls%4'r%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
2379 {ARM_EXT_V6T2
, 0xfbc000c0, 0xfff000e0, "smlald%4'x%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
2380 {ARM_EXT_V6T2
, 0xfbd000c0, 0xfff000e0, "smlsld%4'x%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
2381 {ARM_EXT_V6T2
, 0xeac00000, 0xfff08030, "pkhbt%c\t%8-11r, %16-19r, %S"},
2382 {ARM_EXT_V6T2
, 0xeac00020, 0xfff08030, "pkhtb%c\t%8-11r, %16-19r, %S"},
2383 {ARM_EXT_V6T2
, 0xf3400000, 0xfff08020, "sbfx%c\t%8-11r, %16-19r, %F"},
2384 {ARM_EXT_V6T2
, 0xf3c00000, 0xfff08020, "ubfx%c\t%8-11r, %16-19r, %F"},
2385 {ARM_EXT_V6T2
, 0xf8000e00, 0xff900f00, "str%wt%c\t%12-15r, %a"},
2386 {ARM_EXT_V6T2
, 0xfb100000, 0xfff000c0, "smla%5?tb%4?tb%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
2387 {ARM_EXT_V6T2
, 0xfbc00080, 0xfff000c0, "smlal%5?tb%4?tb%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
2388 {ARM_EXT_V6T2
, 0xf3600000, 0xfff08020, "bfi%c\t%8-11r, %16-19r, %E"},
2389 {ARM_EXT_V6T2
, 0xf8100e00, 0xfe900f00, "ldr%wt%c\t%12-15r, %a"},
2390 {ARM_EXT_V6T2
, 0xf3000000, 0xffd08020, "ssat%c\t%8-11r, #%0-4d, %16-19r%s"},
2391 {ARM_EXT_V6T2
, 0xf3800000, 0xffd08020, "usat%c\t%8-11r, #%0-4d, %16-19r%s"},
2392 {ARM_EXT_V6T2
, 0xf2000000, 0xfbf08000, "addw%c\t%8-11r, %16-19r, %I"},
2393 {ARM_EXT_V6T2
, 0xf2400000, 0xfbf08000, "movw%c\t%8-11r, %J"},
2394 {ARM_EXT_V6T2
, 0xf2a00000, 0xfbf08000, "subw%c\t%8-11r, %16-19r, %I"},
2395 {ARM_EXT_V6T2
, 0xf2c00000, 0xfbf08000, "movt%c\t%8-11r, %J"},
2396 {ARM_EXT_V6T2
, 0xea000000, 0xffe08000, "and%20's%c.w\t%8-11r, %16-19r, %S"},
2397 {ARM_EXT_V6T2
, 0xea200000, 0xffe08000, "bic%20's%c.w\t%8-11r, %16-19r, %S"},
2398 {ARM_EXT_V6T2
, 0xea400000, 0xffe08000, "orr%20's%c.w\t%8-11r, %16-19r, %S"},
2399 {ARM_EXT_V6T2
, 0xea600000, 0xffe08000, "orn%20's%c\t%8-11r, %16-19r, %S"},
2400 {ARM_EXT_V6T2
, 0xea800000, 0xffe08000, "eor%20's%c.w\t%8-11r, %16-19r, %S"},
2401 {ARM_EXT_V6T2
, 0xeb000000, 0xffe08000, "add%20's%c.w\t%8-11r, %16-19r, %S"},
2402 {ARM_EXT_V6T2
, 0xeb400000, 0xffe08000, "adc%20's%c.w\t%8-11r, %16-19r, %S"},
2403 {ARM_EXT_V6T2
, 0xeb600000, 0xffe08000, "sbc%20's%c.w\t%8-11r, %16-19r, %S"},
2404 {ARM_EXT_V6T2
, 0xeba00000, 0xffe08000, "sub%20's%c.w\t%8-11r, %16-19r, %S"},
2405 {ARM_EXT_V6T2
, 0xebc00000, 0xffe08000, "rsb%20's%c\t%8-11r, %16-19r, %S"},
2406 {ARM_EXT_V6T2
, 0xe8400000, 0xfff00000, "strex%c\t%8-11r, %12-15r, [%16-19r, #%0-7W]"},
2407 {ARM_EXT_V6T2
, 0xf0000000, 0xfbe08000, "and%20's%c.w\t%8-11r, %16-19r, %M"},
2408 {ARM_EXT_V6T2
, 0xf0200000, 0xfbe08000, "bic%20's%c.w\t%8-11r, %16-19r, %M"},
2409 {ARM_EXT_V6T2
, 0xf0400000, 0xfbe08000, "orr%20's%c.w\t%8-11r, %16-19r, %M"},
2410 {ARM_EXT_V6T2
, 0xf0600000, 0xfbe08000, "orn%20's%c\t%8-11r, %16-19r, %M"},
2411 {ARM_EXT_V6T2
, 0xf0800000, 0xfbe08000, "eor%20's%c.w\t%8-11r, %16-19r, %M"},
2412 {ARM_EXT_V6T2
, 0xf1000000, 0xfbe08000, "add%20's%c.w\t%8-11r, %16-19r, %M"},
2413 {ARM_EXT_V6T2
, 0xf1400000, 0xfbe08000, "adc%20's%c.w\t%8-11r, %16-19r, %M"},
2414 {ARM_EXT_V6T2
, 0xf1600000, 0xfbe08000, "sbc%20's%c.w\t%8-11r, %16-19r, %M"},
2415 {ARM_EXT_V6T2
, 0xf1a00000, 0xfbe08000, "sub%20's%c.w\t%8-11r, %16-19r, %M"},
2416 {ARM_EXT_V6T2
, 0xf1c00000, 0xfbe08000, "rsb%20's%c\t%8-11r, %16-19r, %M"},
2417 {ARM_EXT_V6T2
, 0xe8800000, 0xffd00000, "stmia%c.w\t%16-19r%21'!, %m"},
2418 {ARM_EXT_V6T2
, 0xe8900000, 0xffd00000, "ldmia%c.w\t%16-19r%21'!, %m"},
2419 {ARM_EXT_V6T2
, 0xe9000000, 0xffd00000, "stmdb%c\t%16-19r%21'!, %m"},
2420 {ARM_EXT_V6T2
, 0xe9100000, 0xffd00000, "ldmdb%c\t%16-19r%21'!, %m"},
2421 {ARM_EXT_V6T2
, 0xe9c00000, 0xffd000ff, "strd%c\t%12-15r, %8-11r, [%16-19r]"},
2422 {ARM_EXT_V6T2
, 0xe9d00000, 0xffd000ff, "ldrd%c\t%12-15r, %8-11r, [%16-19r]"},
2423 {ARM_EXT_V6T2
, 0xe9400000, 0xff500000, "strd%c\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]%21'!"},
2424 {ARM_EXT_V6T2
, 0xe9500000, 0xff500000, "ldrd%c\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]%21'!"},
2425 {ARM_EXT_V6T2
, 0xe8600000, 0xff700000, "strd%c\t%12-15r, %8-11r, [%16-19r], #%23`-%0-7W"},
2426 {ARM_EXT_V6T2
, 0xe8700000, 0xff700000, "ldrd%c\t%12-15r, %8-11r, [%16-19r], #%23`-%0-7W"},
2427 {ARM_EXT_V6T2
, 0xf8000000, 0xff100000, "str%w%c.w\t%12-15r, %a"},
2428 {ARM_EXT_V6T2
, 0xf8100000, 0xfe100000, "ldr%w%c.w\t%12-15r, %a"},
2430 /* Filter out Bcc with cond=E or F, which are used for other instructions. */
2431 {ARM_EXT_V6T2
, 0xf3c08000, 0xfbc0d000, "undefined (bcc, cond=0xF)"},
2432 {ARM_EXT_V6T2
, 0xf3808000, 0xfbc0d000, "undefined (bcc, cond=0xE)"},
2433 {ARM_EXT_V6T2
, 0xf0008000, 0xf800d000, "b%22-25c.w\t%b%X"},
2434 {ARM_EXT_V6T2
, 0xf0009000, 0xf800d000, "b%c.w\t%B%x"},
2436 /* These have been 32-bit since the invention of Thumb. */
2437 {ARM_EXT_V4T
, 0xf000c000, 0xf800d000, "blx%c\t%B%x"},
2438 {ARM_EXT_V4T
, 0xf000d000, 0xf800d000, "bl%c\t%B%x"},
2441 {ARM_EXT_V1
, 0x00000000, 0x00000000, "undefined"},
2445 static const char *const arm_conditional
[] =
2446 {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
2447 "hi", "ls", "ge", "lt", "gt", "le", "al", "<und>", ""};
2449 static const char *const arm_fp_const
[] =
2450 {"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
2452 static const char *const arm_shift
[] =
2453 {"lsl", "lsr", "asr", "ror"};
2458 const char *description
;
2459 const char *reg_names
[16];
2463 static const arm_regname regnames
[] =
2465 { "raw" , "Select raw register names",
2466 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}},
2467 { "gcc", "Select register names used by GCC",
2468 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc" }},
2469 { "std", "Select register names used in ARM's ISA documentation",
2470 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc" }},
2471 { "apcs", "Select register names used in the APCS",
2472 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "sl", "fp", "ip", "sp", "lr", "pc" }},
2473 { "atpcs", "Select register names used in the ATPCS",
2474 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "IP", "SP", "LR", "PC" }},
2475 { "special-atpcs", "Select special register names used in the ATPCS",
2476 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL", "FP", "IP", "SP", "LR", "PC" }},
2479 static const char *const iwmmxt_wwnames
[] =
2480 {"b", "h", "w", "d"};
2482 static const char *const iwmmxt_wwssnames
[] =
2483 {"b", "bus", "bc", "bss",
2484 "h", "hus", "hc", "hss",
2485 "w", "wus", "wc", "wss",
2486 "d", "dus", "dc", "dss"
2489 static const char *const iwmmxt_regnames
[] =
2490 { "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6", "wr7",
2491 "wr8", "wr9", "wr10", "wr11", "wr12", "wr13", "wr14", "wr15"
2494 static const char *const iwmmxt_cregnames
[] =
2495 { "wcid", "wcon", "wcssf", "wcasf", "reserved", "reserved", "reserved", "reserved",
2496 "wcgr0", "wcgr1", "wcgr2", "wcgr3", "reserved", "reserved", "reserved", "reserved"
2499 /* Default to GCC register name set. */
2500 static unsigned int regname_selected
= 1;
2502 #define NUM_ARM_REGNAMES NUM_ELEM (regnames)
2503 #define arm_regnames regnames[regname_selected].reg_names
2505 static bfd_boolean force_thumb
= FALSE
;
2507 /* Current IT instruction state. This contains the same state as the IT
2508 bits in the CPSR. */
2509 static unsigned int ifthen_state
;
2510 /* IT state for the next instruction. */
2511 static unsigned int ifthen_next_state
;
2512 /* The address of the insn for which the IT state is valid. */
2513 static bfd_vma ifthen_address
;
2514 #define IFTHEN_COND ((ifthen_state >> 4) & 0xf)
2516 /* Cached mapping symbol state. */
2523 enum map_type last_type
;
2524 int last_mapping_sym
= -1;
2525 bfd_vma last_mapping_addr
= 0;
2527 /* Decode a bitfield of the form matching regexp (N(-N)?,)*N(-N)?.
2528 Returns pointer to following character of the format string and
2529 fills in *VALUEP and *WIDTHP with the extracted value and number of
2530 bits extracted. WIDTHP can be NULL. */
2533 arm_decode_bitfield (const char *ptr
, uint32_t insn
,
2534 uint32_t *valuep
, int *widthp
)
2544 for (start
= 0; *ptr
>= '0' && *ptr
<= '9'; ptr
++)
2545 start
= start
* 10 + *ptr
- '0';
2547 for (end
= 0, ptr
++; *ptr
>= '0' && *ptr
<= '9'; ptr
++)
2548 end
= end
* 10 + *ptr
- '0';
2554 value
|= ((insn
>> start
) & ((2ul << bits
) - 1)) << width
;
2557 while (*ptr
++ == ',');
2565 arm_decode_shift (int32_t given
, fprintf_ftype func
, void *stream
,
2568 func (stream
, "%s", arm_regnames
[given
& 0xf]);
2570 if ((given
& 0xff0) != 0)
2572 if ((given
& 0x10) == 0)
2574 int amount
= (given
& 0xf80) >> 7;
2575 int shift
= (given
& 0x60) >> 5;
2581 func (stream
, ", rrx");
2589 func (stream
, ", %s #%d", arm_shift
[shift
], amount
);
2591 func (stream
, ", #%d", amount
);
2593 else if (print_shift
)
2594 func (stream
, ", %s %s", arm_shift
[(given
& 0x60) >> 5],
2595 arm_regnames
[(given
& 0xf00) >> 8]);
2597 func (stream
, ", %s", arm_regnames
[(given
& 0xf00) >> 8]);
2601 /* Print one coprocessor instruction on INFO->STREAM.
2602 Return TRUE if the instuction matched, FALSE if this is not a
2603 recognised coprocessor instruction. */
2606 print_insn_coprocessor (bfd_vma pc
, struct disassemble_info
*info
, int32_t given
,
2609 const struct opcode32
*insn
;
2610 void *stream
= info
->stream
;
2611 fprintf_ftype func
= info
->fprintf_func
;
2616 for (insn
= coprocessor_opcodes
; insn
->assembler
; insn
++)
2618 if (insn
->value
== FIRST_IWMMXT_INSN
2619 && info
->mach
!= bfd_mach_arm_XScale
2620 && info
->mach
!= bfd_mach_arm_iWMMXt
2621 && info
->mach
!= bfd_mach_arm_iWMMXt2
)
2622 insn
= insn
+ IWMMXT_INSN_COUNT
;
2625 value
= insn
->value
;
2628 /* The high 4 bits are 0xe for Arm conditional instructions, and
2629 0xe for arm unconditional instructions. The rest of the
2630 encoding is the same. */
2632 value
|= 0xe0000000;
2640 /* Only match unconditional instuctions against unconditional
2642 if ((given
& 0xf0000000) == 0xf0000000)
2649 cond
= (given
>> 28) & 0xf;
2654 if ((given
& mask
) == value
)
2658 for (c
= insn
->assembler
; *c
; c
++)
2665 func (stream
, "%%");
2669 func (stream
, "[%s", arm_regnames
[(given
>> 16) & 0xf]);
2671 if ((given
& (1 << 24)) != 0)
2673 int offset
= given
& 0xff;
2676 func (stream
, ", #%s%d]%s",
2677 ((given
& 0x00800000) == 0 ? "-" : ""),
2679 ((given
& 0x00200000) != 0 ? "!" : ""));
2685 int offset
= given
& 0xff;
2689 if (given
& (1 << 21))
2692 func (stream
, ", #%s%d",
2693 ((given
& 0x00800000) == 0 ? "-" : ""),
2697 func (stream
, ", {%d}", offset
);
2703 int regno
= ((given
>> 12) & 0xf) | ((given
>> (22 - 4)) & 0x10);
2704 int offset
= (given
>> 1) & 0x3f;
2707 func (stream
, "{d%d}", regno
);
2708 else if (regno
+ offset
> 32)
2709 func (stream
, "{d%d-<overflow reg d%d>}", regno
, regno
+ offset
- 1);
2711 func (stream
, "{d%d-d%d}", regno
, regno
+ offset
- 1);
2717 int rn
= (given
>> 16) & 0xf;
2718 int offset
= (given
& 0xff) * 4;
2719 int add
= (given
>> 23) & 1;
2721 func (stream
, "[%s", arm_regnames
[rn
]);
2727 func (stream
, ", #%d", offset
);
2732 func (stream
, "\t@ ");
2733 /* FIXME: Unsure if info->bytes_per_chunk is the
2734 right thing to use here. */
2735 info
->print_address_func (pc
, offset
+ pc
2736 + info
->bytes_per_chunk
* 2, info
);
2742 func (stream
, "%s", arm_conditional
[cond
]);
2746 /* Print a Cirrus/DSP shift immediate. */
2747 /* Immediates are 7bit signed ints with bits 0..3 in
2748 bits 0..3 of opcode and bits 4..6 in bits 5..7
2753 imm
= (given
& 0xf) | ((given
& 0xe0) >> 1);
2755 /* Is ``imm'' a negative number? */
2759 func (stream
, "%d", imm
);
2765 switch (given
& 0x00408000)
2782 switch (given
& 0x00080080)
2794 func (stream
, _("<illegal precision>"));
2799 switch (given
& 0x00408000)
2816 switch (given
& 0x60)
2832 case '0': case '1': case '2': case '3': case '4':
2833 case '5': case '6': case '7': case '8': case '9':
2838 c
= arm_decode_bitfield (c
, given
, &value
, &width
);
2843 func (stream
, "%s", arm_regnames
[value
]);
2846 func (stream
, "d%ld", value
);
2850 func (stream
, "<illegal reg q%ld.5>", value
>> 1);
2852 func (stream
, "q%ld", value
>> 1);
2855 func (stream
, "%ld", value
);
2859 int from
= (given
& (1 << 7)) ? 32 : 16;
2860 func (stream
, "%ld", from
- value
);
2866 func (stream
, "#%s", arm_fp_const
[value
& 7]);
2868 func (stream
, "f%ld", value
);
2873 func (stream
, "%s", iwmmxt_wwnames
[value
]);
2875 func (stream
, "%s", iwmmxt_wwssnames
[value
]);
2879 func (stream
, "%s", iwmmxt_regnames
[value
]);
2882 func (stream
, "%s", iwmmxt_cregnames
[value
]);
2886 func (stream
, "0x%lx", value
);
2892 func (stream
, "%c", *c
);
2896 if (value
== ((1ul << width
) - 1))
2897 func (stream
, "%c", *c
);
2900 func (stream
, "%c", c
[(1 << width
) - (int)value
]);
2911 int single
= *c
++ == 'y';
2916 case '4': /* Sm pair */
2919 case '0': /* Sm, Dm */
2920 regno
= given
& 0x0000000f;
2924 regno
+= (given
>> 5) & 1;
2927 regno
+= ((given
>> 5) & 1) << 4;
2930 case '1': /* Sd, Dd */
2931 regno
= (given
>> 12) & 0x0000000f;
2935 regno
+= (given
>> 22) & 1;
2938 regno
+= ((given
>> 22) & 1) << 4;
2941 case '2': /* Sn, Dn */
2942 regno
= (given
>> 16) & 0x0000000f;
2946 regno
+= (given
>> 7) & 1;
2949 regno
+= ((given
>> 7) & 1) << 4;
2952 case '3': /* List */
2954 regno
= (given
>> 12) & 0x0000000f;
2958 regno
+= (given
>> 22) & 1;
2961 regno
+= ((given
>> 22) & 1) << 4;
2968 func (stream
, "%c%d", single
? 's' : 'd', regno
);
2972 int count
= given
& 0xff;
2979 func (stream
, "-%c%d",
2987 func (stream
, ", %c%d}", single
? 's' : 'd',
2993 switch (given
& 0x00400100)
2995 case 0x00000000: func (stream
, "b"); break;
2996 case 0x00400000: func (stream
, "h"); break;
2997 case 0x00000100: func (stream
, "w"); break;
2998 case 0x00400100: func (stream
, "d"); break;
3007 /* given (20, 23) | given (0, 3) */
3008 value
= ((given
>> 16) & 0xf0) | (given
& 0xf);
3009 func (stream
, "%d", value
);
3014 /* This is like the 'A' operator, except that if
3015 the width field "M" is zero, then the offset is
3016 *not* multiplied by four. */
3018 int offset
= given
& 0xff;
3019 int multiplier
= (given
& 0x00000100) ? 4 : 1;
3021 func (stream
, "[%s", arm_regnames
[(given
>> 16) & 0xf]);
3025 if ((given
& 0x01000000) != 0)
3026 func (stream
, ", #%s%d]%s",
3027 ((given
& 0x00800000) == 0 ? "-" : ""),
3028 offset
* multiplier
,
3029 ((given
& 0x00200000) != 0 ? "!" : ""));
3031 func (stream
, "], #%s%d",
3032 ((given
& 0x00800000) == 0 ? "-" : ""),
3033 offset
* multiplier
);
3042 int imm4
= (given
>> 4) & 0xf;
3043 int puw_bits
= ((given
>> 22) & 6) | ((given
>> 21) & 1);
3044 int ubit
= (given
>> 23) & 1;
3045 const char *rm
= arm_regnames
[given
& 0xf];
3046 const char *rn
= arm_regnames
[(given
>> 16) & 0xf];
3053 func (stream
, "[%s], %c%s", rn
, ubit
? '+' : '-', rm
);
3055 func (stream
, ", lsl #%d", imm4
);
3065 func (stream
, "[%s, %c%s", rn
, ubit
? '+' : '-', rm
);
3067 func (stream
, ", lsl #%d", imm4
);
3069 if (puw_bits
== 5 || puw_bits
== 7)
3074 func (stream
, "INVALID");
3082 imm5
= ((given
& 0x100) >> 4) | (given
& 0xf);
3083 func (stream
, "%ld", (imm5
== 0) ? 32 : imm5
);
3093 func (stream
, "%c", *c
);
3102 print_arm_address (bfd_vma pc
, struct disassemble_info
*info
, int32_t given
)
3104 void *stream
= info
->stream
;
3105 fprintf_ftype func
= info
->fprintf_func
;
3107 if (((given
& 0x000f0000) == 0x000f0000)
3108 && ((given
& 0x02000000) == 0))
3110 int offset
= given
& 0xfff;
3112 func (stream
, "[pc");
3114 if (given
& 0x01000000)
3116 if ((given
& 0x00800000) == 0)
3120 func (stream
, ", #%d]", offset
);
3124 /* Cope with the possibility of write-back
3125 being used. Probably a very dangerous thing
3126 for the programmer to do, but who are we to
3128 if (given
& 0x00200000)
3134 func (stream
, "], #%d", offset
);
3136 /* ie ignore the offset. */
3140 func (stream
, "\t@ ");
3141 info
->print_address_func (pc
, offset
, info
);
3145 func (stream
, "[%s",
3146 arm_regnames
[(given
>> 16) & 0xf]);
3147 if ((given
& 0x01000000) != 0)
3149 if ((given
& 0x02000000) == 0)
3151 int offset
= given
& 0xfff;
3153 func (stream
, ", #%s%d",
3154 (((given
& 0x00800000) == 0)
3155 ? "-" : ""), offset
);
3159 func (stream
, ", %s",
3160 (((given
& 0x00800000) == 0)
3162 arm_decode_shift (given
, func
, stream
, 1);
3165 func (stream
, "]%s",
3166 ((given
& 0x00200000) != 0) ? "!" : "");
3170 if ((given
& 0x02000000) == 0)
3172 int offset
= given
& 0xfff;
3174 func (stream
, "], #%s%d",
3175 (((given
& 0x00800000) == 0)
3176 ? "-" : ""), offset
);
3182 func (stream
, "], %s",
3183 (((given
& 0x00800000) == 0)
3185 arm_decode_shift (given
, func
, stream
, 1);
3191 /* Print one neon instruction on INFO->STREAM.
3192 Return TRUE if the instuction matched, FALSE if this is not a
3193 recognised neon instruction. */
3196 print_insn_neon (struct disassemble_info
*info
, int32_t given
, bfd_boolean thumb
)
3198 const struct opcode32
*insn
;
3199 void *stream
= info
->stream
;
3200 fprintf_ftype func
= info
->fprintf_func
;
3204 if ((given
& 0xef000000) == 0xef000000)
3206 /* move bit 28 to bit 24 to translate Thumb2 to ARM encoding. */
3207 uint32_t bit28
= given
& (1 << 28);
3209 given
&= 0x00ffffff;
3211 given
|= 0xf3000000;
3213 given
|= 0xf2000000;
3215 else if ((given
& 0xff000000) == 0xf9000000)
3216 given
^= 0xf9000000 ^ 0xf4000000;
3221 for (insn
= neon_opcodes
; insn
->assembler
; insn
++)
3223 if ((given
& insn
->mask
) == insn
->value
)
3227 for (c
= insn
->assembler
; *c
; c
++)
3234 func (stream
, "%%");
3238 if (thumb
&& ifthen_state
)
3239 func (stream
, "%s", arm_conditional
[IFTHEN_COND
]);
3244 static const unsigned char enc
[16] =
3246 0x4, 0x14, /* st4 0,1 */
3258 int rd
= ((given
>> 12) & 0xf) | (((given
>> 22) & 1) << 4);
3259 int rn
= ((given
>> 16) & 0xf);
3260 int rm
= ((given
>> 0) & 0xf);
3261 int align
= ((given
>> 4) & 0x3);
3262 int type
= ((given
>> 8) & 0xf);
3263 int n
= enc
[type
] & 0xf;
3264 int stride
= (enc
[type
] >> 4) + 1;
3269 for (ix
= 0; ix
!= n
; ix
++)
3270 func (stream
, "%sd%d", ix
? "," : "", rd
+ ix
* stride
);
3272 func (stream
, "d%d", rd
);
3274 func (stream
, "d%d-d%d", rd
, rd
+ n
- 1);
3275 func (stream
, "}, [%s", arm_regnames
[rn
]);
3277 func (stream
, ", :%d", 32 << align
);
3282 func (stream
, ", %s", arm_regnames
[rm
]);
3288 int rd
= ((given
>> 12) & 0xf) | (((given
>> 22) & 1) << 4);
3289 int rn
= ((given
>> 16) & 0xf);
3290 int rm
= ((given
>> 0) & 0xf);
3291 int idx_align
= ((given
>> 4) & 0xf);
3293 int size
= ((given
>> 10) & 0x3);
3294 int idx
= idx_align
>> (size
+ 1);
3295 int length
= ((given
>> 8) & 3) + 1;
3299 if (length
> 1 && size
> 0)
3300 stride
= (idx_align
& (1 << size
)) ? 2 : 1;
3306 int amask
= (1 << size
) - 1;
3307 if ((idx_align
& (1 << size
)) != 0)
3311 if ((idx_align
& amask
) == amask
)
3313 else if ((idx_align
& amask
) != 0)
3320 if (size
== 2 && (idx_align
& 2) != 0)
3322 align
= (idx_align
& 1) ? 16 << size
: 0;
3326 if ((size
== 2 && (idx_align
& 3) != 0)
3327 || (idx_align
& 1) != 0)
3334 if ((idx_align
& 3) == 3)
3336 align
= (idx_align
& 3) * 64;
3339 align
= (idx_align
& 1) ? 32 << size
: 0;
3347 for (i
= 0; i
< length
; i
++)
3348 func (stream
, "%sd%d[%d]", (i
== 0) ? "" : ",",
3349 rd
+ i
* stride
, idx
);
3350 func (stream
, "}, [%s", arm_regnames
[rn
]);
3352 func (stream
, ", :%d", align
);
3357 func (stream
, ", %s", arm_regnames
[rm
]);
3363 int rd
= ((given
>> 12) & 0xf) | (((given
>> 22) & 1) << 4);
3364 int rn
= ((given
>> 16) & 0xf);
3365 int rm
= ((given
>> 0) & 0xf);
3366 int align
= ((given
>> 4) & 0x1);
3367 int size
= ((given
>> 6) & 0x3);
3368 int type
= ((given
>> 8) & 0x3);
3370 int stride
= ((given
>> 5) & 0x1);
3373 if (stride
&& (n
== 1))
3380 for (ix
= 0; ix
!= n
; ix
++)
3381 func (stream
, "%sd%d[]", ix
? "," : "", rd
+ ix
* stride
);
3383 func (stream
, "d%d[]", rd
);
3385 func (stream
, "d%d[]-d%d[]", rd
, rd
+ n
- 1);
3386 func (stream
, "}, [%s", arm_regnames
[rn
]);
3389 int align
= (8 * (type
+ 1)) << size
;
3391 align
= (size
> 1) ? align
>> 1 : align
;
3392 if (type
== 2 || (type
== 0 && !size
))
3393 func (stream
, ", :<bad align %d>", align
);
3395 func (stream
, ", :%d", align
);
3401 func (stream
, ", %s", arm_regnames
[rm
]);
3407 int raw_reg
= (given
& 0xf) | ((given
>> 1) & 0x10);
3408 int size
= (given
>> 20) & 3;
3409 int reg
= raw_reg
& ((4 << size
) - 1);
3410 int ix
= raw_reg
>> size
>> 2;
3412 func (stream
, "d%d[%d]", reg
, ix
);
3417 /* Neon encoded constant for mov, mvn, vorr, vbic */
3420 int cmode
= (given
>> 8) & 0xf;
3421 int op
= (given
>> 5) & 0x1;
3422 uint32_t value
= 0, hival
= 0;
3427 bits
|= ((given
>> 24) & 1) << 7;
3428 bits
|= ((given
>> 16) & 7) << 4;
3429 bits
|= ((given
>> 0) & 15) << 0;
3433 shift
= (cmode
>> 1) & 3;
3434 value
= (uint32_t)bits
<< (8 * shift
);
3437 else if (cmode
< 12)
3439 shift
= (cmode
>> 1) & 1;
3440 value
= (uint32_t)bits
<< (8 * shift
);
3443 else if (cmode
< 14)
3445 shift
= (cmode
& 1) + 1;
3446 value
= (uint32_t)bits
<< (8 * shift
);
3447 value
|= (1ul << (8 * shift
)) - 1;
3450 else if (cmode
== 14)
3454 /* bit replication into bytes */
3460 for (ix
= 7; ix
>= 0; ix
--)
3462 mask
= ((bits
>> ix
) & 1) ? 0xff : 0;
3464 value
= (value
<< 8) | mask
;
3466 hival
= (hival
<< 8) | mask
;
3472 /* byte replication */
3473 value
= (uint32_t)bits
;
3479 /* floating point encoding */
3482 value
= (uint32_t)(bits
& 0x7f) << 19;
3483 value
|= (uint32_t)(bits
& 0x80) << 24;
3484 tmp
= bits
& 0x40 ? 0x3c : 0x40;
3485 value
|= (uint32_t)tmp
<< 24;
3491 func (stream
, "<illegal constant %.8x:%x:%x>",
3499 func (stream
, "#%ld\t@ 0x%.2lx", value
, value
);
3503 func (stream
, "#%ld\t@ 0x%.4lx", value
, value
);
3509 unsigned char valbytes
[4];
3512 /* Do this a byte at a time so we don't have to
3513 worry about the host's endianness. */
3514 valbytes
[0] = value
& 0xff;
3515 valbytes
[1] = (value
>> 8) & 0xff;
3516 valbytes
[2] = (value
>> 16) & 0xff;
3517 valbytes
[3] = (value
>> 24) & 0xff;
3520 /* HACK to avoid pulling in FSR binutils include/floatformat.h */
3521 /* HACK to avoid pulling in FSR binutils libiberty/floatformat.c */
3522 floatformat_to_double
3523 (&floatformat_ieee_single_little
, valbytes
,
3526 if(get_host_byte_sex() !=
3527 LITTLE_ENDIAN_BYTE_SEX
){
3529 memcpy(&f
, valbytes
, 4);
3535 memcpy(&f
, valbytes
, 4);
3539 func (stream
, "#%.7g\t@ 0x%.8lx", fvalue
,
3543 func (stream
, "#%ld\t@ 0x%.8lx",
3544 (int32_t) ((value
& 0x80000000)
3545 ? value
| ~0xffffffffl
: value
), value
);
3549 func (stream
, "#0x%.8lx%.8lx", hival
, value
);
3560 int regno
= ((given
>> 16) & 0xf) | ((given
>> (7 - 4)) & 0x10);
3561 int num
= (given
>> 8) & 0x3;
3564 func (stream
, "{d%d}", regno
);
3565 else if (num
+ regno
>= 32)
3566 func (stream
, "{d%d-<overflow reg d%d}", regno
, regno
+ num
);
3568 func (stream
, "{d%d-d%d}", regno
, regno
+ num
);
3573 case '0': case '1': case '2': case '3': case '4':
3574 case '5': case '6': case '7': case '8': case '9':
3579 c
= arm_decode_bitfield (c
, given
, &value
, &width
);
3584 func (stream
, "%s", arm_regnames
[value
]);
3587 func (stream
, "%ld", value
);
3590 func (stream
, "%ld", (1ul << width
) - value
);
3596 /* various width encodings */
3598 int base
= 8 << (*c
- 'S'); /* 8,16 or 32 */
3603 if (*c
>= '0' && *c
<= '9')
3605 else if (*c
>= 'a' && *c
<= 'f')
3606 limit
= *c
- 'a' + 10;
3612 if (value
< low
|| value
> high
)
3613 func (stream
, "<illegal width %d>", base
<< value
);
3615 func (stream
, "%d", base
<< value
);
3619 if (given
& (1 << 6))
3623 func (stream
, "d%ld", value
);
3628 func (stream
, "<illegal reg q%ld.5>", value
>> 1);
3630 func (stream
, "q%ld", value
>> 1);
3636 func (stream
, "%c", *c
);
3640 if (value
== ((1ul << width
) - 1))
3641 func (stream
, "%c", *c
);
3644 func (stream
, "%c", c
[(1 << width
) - (int)value
]);
3658 func (stream
, "%c", *c
);
3666 /* Print one ARM instruction from PC on INFO->STREAM. */
3669 print_insn_arm (bfd_vma pc
, struct disassemble_info
*info
, int32_t given
)
3671 const struct opcode32
*insn
;
3672 void *stream
= info
->stream
;
3673 fprintf_ftype func
= info
->fprintf_func
;
3675 if (print_insn_coprocessor (pc
, info
, given
, FALSE
))
3678 if (print_insn_neon (info
, given
, FALSE
))
3681 for (insn
= arm_opcodes
; insn
->assembler
; insn
++)
3683 if (insn
->value
== FIRST_IWMMXT_INSN
3684 && info
->mach
!= bfd_mach_arm_XScale
3685 && info
->mach
!= bfd_mach_arm_iWMMXt
)
3686 insn
= insn
+ IWMMXT_INSN_COUNT
;
3688 if ((given
& insn
->mask
) == insn
->value
3689 /* Special case: an instruction with all bits set in the condition field
3690 (0xFnnn_nnnn) is only matched if all those bits are set in insn->mask,
3691 or by the catchall at the end of the table. */
3692 && ((given
& 0xF0000000) != 0xF0000000
3693 || (insn
->mask
& 0xF0000000) == 0xF0000000
3694 || (insn
->mask
== 0 && insn
->value
== 0)))
3698 for (c
= insn
->assembler
; *c
; c
++)
3705 func (stream
, "%%");
3709 print_arm_address (pc
, info
, given
);
3713 /* Set P address bit and use normal address
3714 printing routine. */
3715 print_arm_address (pc
, info
, given
| (1 << 24));
3719 if ((given
& 0x004f0000) == 0x004f0000)
3721 /* PC relative with immediate offset. */
3722 int offset
= ((given
& 0xf00) >> 4) | (given
& 0xf);
3724 if ((given
& 0x00800000) == 0)
3727 func (stream
, "[pc, #%d]\t@ ", offset
);
3728 info
->print_address_func (pc
, offset
+ pc
+ 8, info
);
3732 func (stream
, "[%s",
3733 arm_regnames
[(given
>> 16) & 0xf]);
3734 if ((given
& 0x01000000) != 0)
3737 if ((given
& 0x00400000) == 0x00400000)
3740 int offset
= ((given
& 0xf00) >> 4) | (given
& 0xf);
3742 func (stream
, ", #%s%d",
3743 (((given
& 0x00800000) == 0)
3744 ? "-" : ""), offset
);
3749 func (stream
, ", %s%s",
3750 (((given
& 0x00800000) == 0)
3752 arm_regnames
[given
& 0xf]);
3755 func (stream
, "]%s",
3756 ((given
& 0x00200000) != 0) ? "!" : "");
3761 if ((given
& 0x00400000) == 0x00400000)
3764 int offset
= ((given
& 0xf00) >> 4) | (given
& 0xf);
3766 func (stream
, "], #%s%d",
3767 (((given
& 0x00800000) == 0)
3768 ? "-" : ""), offset
);
3775 func (stream
, "], %s%s",
3776 (((given
& 0x00800000) == 0)
3778 arm_regnames
[given
& 0xf]);
3786 int disp
= (((given
& 0xffffff) ^ 0x800000) - 0x800000);
3787 info
->print_address_func (pc
, disp
*4 + pc
+ 8, info
);
3792 if (((given
>> 28) & 0xf) != 0xe)
3794 arm_conditional
[(given
>> 28) & 0xf]);
3803 for (reg
= 0; reg
< 16; reg
++)
3804 if ((given
& (1 << reg
)) != 0)
3807 func (stream
, ", ");
3809 func (stream
, "%s", arm_regnames
[reg
]);
3816 arm_decode_shift (given
, func
, stream
, 0);
3820 if ((given
& 0x02000000) != 0)
3822 int rotate
= (given
& 0xf00) >> 7;
3823 int immed
= (given
& 0xff);
3824 immed
= (((immed
<< (32 - rotate
))
3825 | (immed
>> rotate
)) & 0xffffffff);
3826 func (stream
, "#%d\t@ 0x%x", immed
, immed
);
3829 arm_decode_shift (given
, func
, stream
, 1);
3833 if ((given
& 0x0000f000) == 0x0000f000)
3838 if ((given
& 0x01200000) == 0x00200000)
3843 func (stream
, "[%s", arm_regnames
[(given
>> 16) & 0xf]);
3845 if ((given
& (1 << 24)) != 0)
3847 int offset
= given
& 0xff;
3850 func (stream
, ", #%s%d]%s",
3851 ((given
& 0x00800000) == 0 ? "-" : ""),
3853 ((given
& 0x00200000) != 0 ? "!" : ""));
3859 int offset
= given
& 0xff;
3863 if (given
& (1 << 21))
3866 func (stream
, ", #%s%d",
3867 ((given
& 0x00800000) == 0 ? "-" : ""),
3871 func (stream
, ", {%d}", offset
);
3876 /* Print ARM V5 BLX(1) address: pc+25 bits. */
3881 if (given
& 0x00800000)
3882 /* Is signed, hi bits should be ones. */
3883 offset
= (-1) ^ 0x00ffffff;
3885 /* Offset is (SignExtend(offset field)<<2). */
3886 offset
+= given
& 0x00ffffff;
3888 address
= offset
+ pc
+ 8;
3890 if (given
& 0x01000000)
3891 /* H bit allows addressing to 2-byte boundaries. */
3894 info
->print_address_func (pc
, address
, info
);
3900 if (given
& 0x80000)
3902 if (given
& 0x40000)
3904 if (given
& 0x20000)
3906 if (given
& 0x10000)
3911 switch (given
& 0xf)
3913 case 0xf: func(stream
, "sy"); break;
3914 case 0x7: func(stream
, "nsh"); break;
3915 case 0xe: func(stream
, "st"); break;
3916 case 0x6: func(stream
, "nshst"); break;
3917 case 0xb: func(stream
, "ish"); break;
3918 case 0xa: func(stream
, "ishst"); break;
3919 case 0x3: func(stream
, "osh"); break;
3920 case 0x2: func(stream
, "oshst"); break;
3922 func(stream
, "#%d", (int)given
& 0xf);
3927 case '0': case '1': case '2': case '3': case '4':
3928 case '5': case '6': case '7': case '8': case '9':
3933 c
= arm_decode_bitfield (c
, given
, &value
, &width
);
3938 func (stream
, "%s", arm_regnames
[value
]);
3941 func (stream
, "%ld", value
);
3944 func (stream
, "%ld", value
* 8);
3947 func (stream
, "%ld", value
+ 1);
3950 func (stream
, "0x%08lx", value
);
3952 /* Some SWI instructions have special
3954 if ((given
& 0x0fffffff) == 0x0FF00000)
3955 func (stream
, "\t@ IMB");
3956 else if ((given
& 0x0fffffff) == 0x0FF00001)
3957 func (stream
, "\t@ IMBRange");
3960 func (stream
, "%01lx", value
& 0xf);
3965 func (stream
, "%c", *c
);
3969 if (value
== ((1ul << width
) - 1))
3970 func (stream
, "%c", *c
);
3973 func (stream
, "%c", c
[(1 << width
) - (int)value
]);
3985 imm
= (given
& 0xf) | ((given
& 0xfff00) >> 4);
3986 func (stream
, "%d", imm
);
3991 /* LSB and WIDTH fields of BFI or BFC. The machine-
3992 language instruction encodes LSB and MSB. */
3994 int32_t msb
= (given
& 0x001f0000) >> 16;
3995 int32_t lsb
= (given
& 0x00000f80) >> 7;
3997 int32_t width
= msb
- lsb
+ 1;
3999 func (stream
, "#%lu, #%lu", lsb
, width
);
4001 func (stream
, "(invalid: %lu:%lu)", lsb
, msb
);
4006 /* 16-bit unsigned immediate from a MOVT or MOVW
4007 instruction, encoded in bits 0:11 and 15:19. */
4009 int32_t hi
= (given
& 0x000f0000) >> 4;
4010 int32_t lo
= (given
& 0x00000fff);
4011 int32_t imm16
= hi
| lo
;
4012 (void)info
->print_immediate_func (pc
, imm16
, info
,
4023 func (stream
, "%c", *c
);
4031 /* Print one 16-bit Thumb instruction from PC on INFO->STREAM. */
4034 print_insn_thumb16 (bfd_vma pc
, struct disassemble_info
*info
, int32_t given
)
4036 const struct opcode16
*insn
;
4037 void *stream
= info
->stream
;
4038 fprintf_ftype func
= info
->fprintf_func
;
4040 for (insn
= thumb_opcodes
; insn
->assembler
; insn
++)
4041 if ((given
& insn
->mask
) == insn
->value
)
4043 const char *c
= insn
->assembler
;
4051 func (stream
, "%c", *c
);
4058 func (stream
, "%%");
4063 func (stream
, "%s", arm_conditional
[IFTHEN_COND
]);
4068 func (stream
, "%s", arm_conditional
[IFTHEN_COND
]);
4077 ifthen_next_state
= given
& 0xff;
4078 for (tmp
= given
<< 1; tmp
& 0xf; tmp
<<= 1)
4079 func (stream
, ((given
^ tmp
) & 0x10) ? "e" : "t");
4080 func (stream
, "\t%s", arm_conditional
[(given
>> 4) & 0xf]);
4085 if (ifthen_next_state
)
4086 func (stream
, "\t@ unpredictable branch in IT block\n");
4091 func (stream
, "\t@ unpredictable <IT:%s>",
4092 arm_conditional
[IFTHEN_COND
]);
4099 reg
= (given
>> 3) & 0x7;
4100 if (given
& (1 << 6))
4103 func (stream
, "%s", arm_regnames
[reg
]);
4112 if (given
& (1 << 7))
4115 func (stream
, "%s", arm_regnames
[reg
]);
4120 if (given
& (1 << 8))
4124 if (*c
== 'O' && (given
& (1 << 8)))
4134 /* It would be nice if we could spot
4135 ranges, and generate the rS-rE format: */
4136 for (reg
= 0; (reg
< 8); reg
++)
4137 if ((given
& (1 << reg
)) != 0)
4140 func (stream
, ", ");
4142 func (stream
, "%s", arm_regnames
[reg
]);
4148 func (stream
, ", ");
4150 func (stream
, arm_regnames
[14] /* "lr" */);
4156 func (stream
, ", ");
4157 func (stream
, arm_regnames
[15] /* "pc" */);
4165 /* Print ARM V6T2 CZB address: pc+4+6 bits. */
4167 bfd_vma address
= (pc
+ 4
4168 + ((given
& 0x00f8) >> 2)
4169 + ((given
& 0x0200) >> 3));
4170 info
->print_address_func (pc
, address
, info
);
4175 /* Right shift immediate -- bits 6..10; 1-31 print
4176 as themselves, 0 prints as 32. */
4178 int32_t imm
= (given
& 0x07c0) >> 6;
4181 func (stream
, "#%ld", imm
);
4185 case '0': case '1': case '2': case '3': case '4':
4186 case '5': case '6': case '7': case '8': case '9':
4188 int bitstart
= *c
++ - '0';
4191 while (*c
>= '0' && *c
<= '9')
4192 bitstart
= (bitstart
* 10) + *c
++ - '0';
4201 while (*c
>= '0' && *c
<= '9')
4202 bitend
= (bitend
* 10) + *c
++ - '0';
4205 reg
= given
>> bitstart
;
4206 reg
&= (2 << (bitend
- bitstart
)) - 1;
4210 func (stream
, "%s", arm_regnames
[reg
]);
4214 func (stream
, "%s", arm_regnames
[reg
]);
4216 if ((given
& (1 << reg
)) == 0)
4217 func (stream
, "%c", *c
);
4221 func (stream
, "%ld", reg
);
4225 func (stream
, "%ld", reg
<< 1);
4229 func (stream
, "%ld", reg
<< 2);
4233 /* PC-relative address -- the bottom two
4234 bits of the address are dropped
4235 before the calculation. */
4236 info
->print_address_func
4237 (pc
, ((pc
+ 4) & ~3) + (reg
<< 2), info
);
4241 func (stream
, "0x%04lx", reg
);
4245 reg
= ((reg
^ (1 << bitend
)) - (1 << bitend
));
4246 info
->print_address_func (pc
, reg
* 2 + pc
+4, info
);
4250 func (stream
, "%s", arm_conditional
[reg
]);
4261 if ((given
& (1 << bitstart
)) != 0)
4262 func (stream
, "%c", *c
);
4267 if ((given
& (1 << bitstart
)) != 0)
4268 func (stream
, "%c", *c
++);
4270 func (stream
, "%c", *++c
);
4290 /* Return the name of an V7M special register. */
4292 psr_name (int regno
)
4296 case 0: return "APSR";
4297 case 1: return "IAPSR";
4298 case 2: return "EAPSR";
4299 case 3: return "PSR";
4300 case 5: return "IPSR";
4301 case 6: return "EPSR";
4302 case 7: return "IEPSR";
4303 case 8: return "MSP";
4304 case 9: return "PSP";
4305 case 16: return "PRIMASK";
4306 case 17: return "BASEPRI";
4307 case 18: return "BASEPRI_MASK";
4308 case 19: return "FAULTMASK";
4309 case 20: return "CONTROL";
4310 default: return "<unknown>";
4314 /* Print one 32-bit Thumb instruction from PC on INFO->STREAM. */
4317 print_insn_thumb32 (bfd_vma pc
, struct disassemble_info
*info
, int32_t given
)
4319 const struct opcode32
*insn
;
4320 void *stream
= info
->stream
;
4321 fprintf_ftype func
= info
->fprintf_func
;
4323 if (print_insn_coprocessor (pc
, info
, given
, TRUE
))
4326 if (print_insn_neon (info
, given
, TRUE
))
4329 for (insn
= thumb32_opcodes
; insn
->assembler
; insn
++)
4330 if ((given
& insn
->mask
) == insn
->value
)
4332 const char *c
= insn
->assembler
;
4337 func (stream
, "%c", *c
);
4344 func (stream
, "%%");
4349 func (stream
, "%s", arm_conditional
[IFTHEN_COND
]);
4353 if (ifthen_next_state
)
4354 func (stream
, "\t@ unpredictable branch in IT block\n");
4359 func (stream
, "\t@ unpredictable <IT:%s>",
4360 arm_conditional
[IFTHEN_COND
]);
4365 unsigned int imm12
= 0;
4366 imm12
|= (given
& 0x000000ffu
);
4367 imm12
|= (given
& 0x00007000u
) >> 4;
4368 imm12
|= (given
& 0x04000000u
) >> 15;
4369 func (stream
, "#%u\t@ 0x%x", imm12
, imm12
);
4375 unsigned int bits
= 0, imm
, imm8
, mod
;
4376 bits
|= (given
& 0x000000ffu
);
4377 bits
|= (given
& 0x00007000u
) >> 4;
4378 bits
|= (given
& 0x04000000u
) >> 15;
4379 imm8
= (bits
& 0x0ff);
4380 mod
= (bits
& 0xf00) >> 8;
4383 case 0: imm
= imm8
; break;
4384 case 1: imm
= ((imm8
<<16) | imm8
); break;
4385 case 2: imm
= ((imm8
<<24) | (imm8
<< 8)); break;
4386 case 3: imm
= ((imm8
<<24) | (imm8
<< 16) | (imm8
<< 8) | imm8
); break;
4388 mod
= (bits
& 0xf80) >> 7;
4389 imm8
= (bits
& 0x07f) | 0x80;
4390 imm
= (((imm8
<< (32 - mod
)) | (imm8
>> mod
)) & 0xffffffff);
4392 func (stream
, "#%u\t@ 0x%x", imm
, imm
);
4398 unsigned int imm
= 0;
4399 imm
|= (given
& 0x000000ffu
);
4400 imm
|= (given
& 0x00007000u
) >> 4;
4401 imm
|= (given
& 0x04000000u
) >> 15;
4402 imm
|= (given
& 0x000f0000u
) >> 4;
4403 (void)info
->print_immediate_func (pc
, imm
, info
, FALSE
);
4409 unsigned int imm
= 0;
4410 imm
|= (given
& 0x000f0000u
) >> 16;
4411 imm
|= (given
& 0x00000ff0u
) >> 0;
4412 imm
|= (given
& 0x0000000fu
) << 12;
4413 (void)info
->print_immediate_func (pc
, imm
, info
, FALSE
);
4419 unsigned int reg
= (given
& 0x0000000fu
);
4420 unsigned int stp
= (given
& 0x00000030u
) >> 4;
4421 unsigned int imm
= 0;
4422 imm
|= (given
& 0x000000c0u
) >> 6;
4423 imm
|= (given
& 0x00007000u
) >> 10;
4425 func (stream
, "%s", arm_regnames
[reg
]);
4430 func (stream
, ", lsl #%u", imm
);
4436 func (stream
, ", lsr #%u", imm
);
4442 func (stream
, ", asr #%u", imm
);
4447 func (stream
, ", rrx");
4449 func (stream
, ", ror #%u", imm
);
4456 unsigned int Rn
= (given
& 0x000f0000) >> 16;
4457 unsigned int U
= (given
& 0x00800000) >> 23;
4458 unsigned int op
= (given
& 0x00000f00) >> 8;
4459 unsigned int i12
= (given
& 0x00000fff);
4460 unsigned int i8
= (given
& 0x000000ff);
4461 bfd_boolean writeback
= FALSE
, postind
= FALSE
;
4464 func (stream
, "[%s", arm_regnames
[Rn
]);
4465 if (U
) /* 12-bit positive immediate offset */
4467 else if (Rn
== 15) /* 12-bit negative immediate offset */
4469 else if (op
== 0x0) /* shifted register offset */
4471 unsigned int Rm
= (i8
& 0x0f);
4472 unsigned int sh
= (i8
& 0x30) >> 4;
4473 func (stream
, ", %s", arm_regnames
[Rm
]);
4475 func (stream
, ", lsl #%u", sh
);
4481 case 0xE: /* 8-bit positive immediate offset */
4485 case 0xC: /* 8-bit negative immediate offset */
4489 case 0xF: /* 8-bit + preindex with wb */
4494 case 0xD: /* 8-bit - preindex with wb */
4499 case 0xB: /* 8-bit + postindex */
4504 case 0x9: /* 8-bit - postindex */
4510 func (stream
, ", <undefined>]");
4515 func (stream
, "], #%d", offset
);
4519 func (stream
, ", #%d", offset
);
4520 func (stream
, writeback
? "]!" : "]");
4525 func (stream
, "\t@ ");
4526 info
->print_address_func(pc
, ((pc
+4) & ~3) +offset
, info
);
4534 unsigned int P
= (given
& 0x01000000) >> 24;
4535 unsigned int U
= (given
& 0x00800000) >> 23;
4536 unsigned int W
= (given
& 0x00400000) >> 21;
4537 unsigned int Rn
= (given
& 0x000f0000) >> 16;
4538 unsigned int off
= (given
& 0x000000ff);
4540 func (stream
, "[%s", arm_regnames
[Rn
]);
4544 func (stream
, ", #%c%u", U
? '+' : '-', off
* 4);
4551 func (stream
, "], ");
4553 func (stream
, "#%c%u", U
? '+' : '-', off
* 4);
4555 func (stream
, "{%u}", off
);
4562 unsigned int Sbit
= (given
& 0x01000000) >> 24;
4563 unsigned int type
= (given
& 0x00600000) >> 21;
4566 case 0: func (stream
, Sbit
? "sb" : "b"); break;
4567 case 1: func (stream
, Sbit
? "sh" : "h"); break;
4570 func (stream
, "??");
4573 func (stream
, "??");
4585 for (reg
= 0; reg
< 16; reg
++)
4586 if ((given
& (1 << reg
)) != 0)
4589 func (stream
, ", ");
4591 func (stream
, "%s", arm_regnames
[reg
]);
4599 unsigned int msb
= (given
& 0x0000001f);
4600 unsigned int lsb
= 0;
4601 lsb
|= (given
& 0x000000c0u
) >> 6;
4602 lsb
|= (given
& 0x00007000u
) >> 10;
4603 func (stream
, "#%u, #%u", lsb
, msb
- lsb
+ 1);
4609 unsigned int width
= (given
& 0x0000001f) + 1;
4610 unsigned int lsb
= 0;
4611 lsb
|= (given
& 0x000000c0u
) >> 6;
4612 lsb
|= (given
& 0x00007000u
) >> 10;
4613 func (stream
, "#%u, #%u", lsb
, width
);
4619 unsigned int S
= (given
& 0x04000000u
) >> 26;
4620 unsigned int J1
= (given
& 0x00002000u
) >> 13;
4621 unsigned int J2
= (given
& 0x00000800u
) >> 11;
4627 offset
|= (given
& 0x003f0000) >> 4;
4628 offset
|= (given
& 0x000007ff) << 1;
4629 offset
-= (1 << 20);
4631 info
->print_address_func (pc
, pc
+ 4 + offset
, info
);
4637 unsigned int S
= (given
& 0x04000000u
) >> 26;
4638 unsigned int I1
= (given
& 0x00002000u
) >> 13;
4639 unsigned int I2
= (given
& 0x00000800u
) >> 11;
4643 offset
|= !(I1
^ S
) << 23;
4644 offset
|= !(I2
^ S
) << 22;
4645 offset
|= (given
& 0x03ff0000u
) >> 4;
4646 offset
|= (given
& 0x000007ffu
) << 1;
4647 offset
-= (1 << 24);
4650 /* BLX target addresses are always word aligned. */
4651 if ((given
& 0x00001000u
) == 0)
4654 info
->print_address_func (pc
, offset
, info
);
4660 unsigned int shift
= 0;
4661 shift
|= (given
& 0x000000c0u
) >> 6;
4662 shift
|= (given
& 0x00007000u
) >> 10;
4663 if (given
& 0x00200000u
)
4664 func (stream
, ", asr #%u", shift
);
4666 func (stream
, ", lsl #%u", shift
);
4667 /* else print nothing - lsl #0 */
4673 unsigned int rot
= (given
& 0x00000030) >> 4;
4675 func (stream
, ", ror #%u", rot
* 8);
4680 switch (given
& 0xf)
4682 case 0xf: func(stream
, "sy"); break;
4683 case 0xe: func(stream
, "st"); break;
4684 case 0x7: func(stream
, "nsh"); break;
4685 case 0x6: func(stream
, "nshst"); break;
4686 case 0xb: func(stream
, "ish"); break;
4687 case 0xa: func(stream
, "ishst"); break;
4688 case 0x3: func(stream
, "osh"); break;
4689 case 0x2: func(stream
, "oshst"); break;
4691 func(stream
, "#%d", (int)given
& 0xf);
4697 if ((given
& 0xff) == 0)
4699 func (stream
, "%cPSR_", (given
& 0x100000) ? 'S' : 'C');
4711 func (stream
, psr_name (given
& 0xff));
4716 if ((given
& 0xff) == 0)
4717 func (stream
, "%cPSR", (given
& 0x100000) ? 'S' : 'C');
4719 func (stream
, psr_name (given
& 0xff));
4722 case '0': case '1': case '2': case '3': case '4':
4723 case '5': case '6': case '7': case '8': case '9':
4728 c
= arm_decode_bitfield (c
, given
, &val
, &width
);
4732 case 'd': func (stream
, "%lu", val
); break;
4733 case 'W': func (stream
, "%lu", val
* 4); break;
4734 case 'r': func (stream
, "%s", arm_regnames
[val
]); break;
4737 func (stream
, "%s", arm_conditional
[val
]);
4742 if (val
== ((1ul << width
) - 1))
4743 func (stream
, "%c", *c
);
4749 func (stream
, "%c", *c
);
4753 func (stream
, "%c", c
[(1 << width
) - (int)val
]);
4774 /* Print data bytes on INFO->STREAM. */
4777 print_insn_data (bfd_vma pc ATTRIBUTE_UNUSED
, struct disassemble_info
*info
,
4780 switch (info
->bytes_per_chunk
)
4783 info
->fprintf_func (info
->stream
, ".byte\t0x%02lx", given
);
4786 info
->fprintf_func (info
->stream
, ".short\t0x%04lx", given
);
4789 info
->fprintf_func (info
->stream
, ".word\t0x%08lx", given
);
4796 /* Search back through the insn stream to determine if this instruction is
4797 conditionally executed. */
4799 find_ifthen_state (bfd_vma pc
, struct disassemble_info
*info
,
4805 /* COUNT is twice the number of instructions seen. It will be odd if we
4806 just crossed an instruction boundary. */
4809 unsigned int seen_it
;
4812 ifthen_address
= pc
;
4819 /* Scan backwards looking for IT instructions, keeping track of where
4820 instruction boundaries are. We don't know if something is actually an
4821 IT instruction until we find a definite instruction boundary. */
4824 if (addr
== 0 || info
->symbol_at_address_func(addr
, info
))
4826 /* A symbol must be on an instruction boundary, and will not
4827 be within an IT block. */
4828 if (seen_it
&& (count
& 1))
4834 status
= info
->read_memory_func (addr
, (bfd_byte
*)b
, 2, info
);
4839 insn
= (b
[0]) | (b
[1] << 8);
4841 insn
= (b
[1]) | (b
[0] << 8);
4844 if ((insn
& 0xf800) < 0xe800)
4846 /* Addr + 2 is an instruction boundary. See if this matches
4847 the expected boundary based on the position of the last
4854 if ((insn
& 0xff00) == 0xbf00 && (insn
& 0xf) != 0)
4856 /* This could be an IT instruction. */
4858 it_count
= count
>> 1;
4860 if ((insn
& 0xf800) >= 0xe800)
4863 count
= (count
+ 2) | 1;
4864 /* IT blocks contain at most 4 instructions. */
4865 if (count
>= 8 && !seen_it
)
4868 /* We found an IT instruction. */
4869 ifthen_state
= (seen_it
& 0xe0) | ((seen_it
<< it_count
) & 0x1f);
4870 if ((ifthen_state
& 0xf) == 0)
4874 /* NOTE: There are no checks in these routines that
4875 the relevant number of data bytes exist. */
4878 print_insn (bfd_vma pc
, struct disassemble_info
*info
, bfd_boolean little
)
4883 int is_thumb
= FALSE
;
4884 int is_data
= FALSE
;
4885 unsigned int size
= 4;
4886 void (*printer
) (bfd_vma
, struct disassemble_info
*, int32_t);
4887 char *llvm_arch_name
;
4888 LLVMDisasmContextRef dc
;
4891 bfd_boolean found
= FALSE
;
4893 if (info
->disassembler_options
)
4895 parse_disassembler_options (info
->disassembler_options
);
4897 /* To avoid repeated parsing of these options, we remove them here. */
4898 info
->disassembler_options
= NULL
;
4901 /* First check the full symtab for a mapping symbol, even if there
4902 are no usable non-mapping symbols for this address. */
4903 if (info
->symtab
!= NULL
4904 && bfd_asymbol_flavour (*info
->symtab
) == bfd_target_elf_flavour
)
4909 enum map_type type
= MAP_ARM
;
4911 if (pc
<= last_mapping_addr
)
4912 last_mapping_sym
= -1;
4913 is_thumb
= (last_type
== MAP_THUMB
);
4915 /* Start scanning at the start of the function, or wherever
4916 we finished last time. */
4917 n
= info
->symtab_pos
+ 1;
4918 if (n
< last_mapping_sym
)
4919 n
= last_mapping_sym
;
4921 /* Scan up to the location being disassembled. */
4922 for (; n
< info
->symtab_size
; n
++)
4924 addr
= bfd_asymbol_value (info
->symtab
[n
]);
4927 if ((info
->section
== NULL
4928 || info
->section
== info
->symtab
[n
]->section
)
4929 && get_sym_code_type (info
, n
, &type
))
4938 n
= info
->symtab_pos
;
4939 if (n
< last_mapping_sym
- 1)
4940 n
= last_mapping_sym
- 1;
4942 /* No mapping symbol found at this address. Look backwards
4943 for a preceeding one. */
4946 if (get_sym_code_type (info
, n
, &type
))
4955 last_mapping_sym
= last_sym
;
4957 is_thumb
= (last_type
== MAP_THUMB
);
4958 is_data
= (last_type
== MAP_DATA
);
4960 /* Look a little bit ahead to see if we should print out
4961 two or four bytes of data. If there's a symbol,
4962 mapping or otherwise, after two bytes then don't
4966 size
= 4 - (pc
& 3);
4967 for (n
= last_sym
+ 1; n
< info
->symtab_size
; n
++)
4969 addr
= bfd_asymbol_value (info
->symtab
[n
]);
4972 if (addr
- pc
< size
)
4977 /* If the next symbol is after three bytes, we need to
4978 print only part of the data, so that we can use either
4981 size
= (pc
& 1) ? 1 : 2;
4985 if (info
->symbols
!= NULL
)
4987 if (bfd_asymbol_flavour (*info
->symbols
) == bfd_target_coff_flavour
)
4989 coff_symbol_type
* cs
;
4991 cs
= coffsymbol (*info
->symbols
);
4992 is_thumb
= ( cs
->native
->u
.syment
.n_sclass
== C_THUMBEXT
4993 || cs
->native
->u
.syment
.n_sclass
== C_THUMBSTAT
4994 || cs
->native
->u
.syment
.n_sclass
== C_THUMBLABEL
4995 || cs
->native
->u
.syment
.n_sclass
== C_THUMBEXTFUNC
4996 || cs
->native
->u
.syment
.n_sclass
== C_THUMBSTATFUNC
);
4998 else if (bfd_asymbol_flavour (*info
->symbols
) == bfd_target_elf_flavour
5001 /* If no mapping symbol has been found then fall back to the type
5002 of the function symbol. */
5003 elf_symbol_type
* es
;
5006 es
= *(elf_symbol_type
**)(info
->symbols
);
5007 type
= ELF_ST_TYPE (es
->internal_elf_sym
.st_info
);
5009 is_thumb
= (type
== STT_ARM_TFUNC
) || (type
== STT_ARM_16BIT
);
5014 /* These are the ways otool(1) determines if we are in thumb mode */
5018 set_thumb_mode(pc
, info
->nsorted_symbols
, info
->sorted_symbols
, &in_thumb
);
5020 if (force_thumb
|| in_thumb
)
5023 info
->display_endian
= little
? BFD_ENDIAN_LITTLE
: BFD_ENDIAN_BIG
;
5024 info
->bytes_per_line
= 4;
5030 /* size was already set above. */
5031 info
->bytes_per_chunk
= size
;
5032 printer
= print_insn_data
;
5034 status
= info
->read_memory_func (pc
, (bfd_byte
*)b
, size
, info
);
5037 for (i
= size
- 1; i
>= 0; i
--)
5038 given
= b
[i
] | (given
<< 8);
5040 for (i
= 0; i
< (int) size
; i
++)
5041 given
= b
[i
] | (given
<< 8);
5045 /* In ARM mode endianness is a straightforward issue: the instruction
5046 is four bytes long and is either ordered 0123 or 3210. */
5047 printer
= print_insn_arm
;
5048 llvm_arch_name
= "arm";
5050 info
->bytes_per_chunk
= 4;
5053 status
= info
->read_memory_func (pc
, (bfd_byte
*)b
, 4, info
);
5055 given
= (b
[0]) | (b
[1] << 8) | (b
[2] << 16) | (b
[3] << 24);
5057 given
= (b
[3]) | (b
[2] << 8) | (b
[1] << 16) | (b
[0] << 24);
5059 /* Print the raw data, too. */
5060 if(!Xflag
&& !gflag
&& !no_show_raw_insn
)
5063 info
->fprintf_func (info
->stream
, "\t");
5064 info
->fprintf_func (info
->stream
, "%08x", (unsigned int) given
);
5066 info
->fprintf_func (info
->stream
, "\t");
5071 /* In Thumb mode we have the additional wrinkle of two
5072 instruction lengths. Fortunately, the bits that determine
5073 the length of the current instruction are always to be found
5074 in the first two bytes. */
5075 printer
= print_insn_thumb16
;
5076 llvm_arch_name
= "thumb";
5077 dc
= info
->thumb_dc
;
5078 info
->bytes_per_chunk
= 2;
5081 status
= info
->read_memory_func (pc
, (bfd_byte
*)b
, 2, info
);
5083 given
= (b
[0]) | (b
[1] << 8);
5085 given
= (b
[1]) | (b
[0] << 8);
5089 /* These bit patterns signal a four-byte Thumb
5091 if ((given
& 0xF800) == 0xF800
5092 || (given
& 0xF800) == 0xF000
5093 || (given
& 0xF800) == 0xE800)
5095 status
= info
->read_memory_func (pc
+ 2, (bfd_byte
*)b
, 2, info
);
5097 given
= (b
[0]) | (b
[1] << 8) | (given
<< 16);
5099 given
= (b
[1]) | (b
[0] << 8) | (given
<< 16);
5101 /* Print the raw data, too. */
5102 if(!Xflag
&& !gflag
&& !no_show_raw_insn
)
5105 info
->fprintf_func (info
->stream
, "\t");
5106 info
->fprintf_func (info
->stream
, "%08x",
5107 (unsigned int) given
);
5109 info
->fprintf_func (info
->stream
, "\t");
5111 printer
= print_insn_thumb32
;
5112 llvm_arch_name
= "thumbv7";
5113 dc
= info
->thumb_dc
;
5117 /* Print the raw data, too. */
5118 if(!Xflag
&& !gflag
&& !no_show_raw_insn
)
5121 info
->fprintf_func (info
->stream
, "\t");
5122 info
->fprintf_func (info
->stream
, " %04x",
5123 (unsigned int)given
);
5125 info
->fprintf_func (info
->stream
, "\t");
5130 if (ifthen_address
!= pc
)
5131 find_ifthen_state(pc
, info
, little
);
5135 if ((ifthen_state
& 0xf) == 0x8)
5136 ifthen_next_state
= 0;
5138 ifthen_next_state
= (ifthen_state
& 0xe0)
5139 | ((ifthen_state
& 0xf) << 1);
5143 if (info
->flags
& INSN_HAS_RELOC
)
5144 /* If the instruction has a reloc associated with it, then
5145 the offset field in the instruction will actually be the
5146 addend for the reloc. (We are using REL type relocs).
5147 In such cases, we can ignore the pc when computing
5148 addresses, since the addend is not currently pc-relative. */
5157 LLVMDisasmInstruction
5159 llvm_disasm_instruction
5161 (dc
, (uint8_t *)info
->sect
, size
, pc
, dst
, 4095) != 0){
5162 if(info
->inst
== NULL
|| info
->inst
->print
)
5165 else if(info
->inst
== NULL
|| info
->inst
->print
){
5167 info
->fprintf_func (info
->stream
, "\t.long\t0x%08x", given
);
5169 info
->fprintf_func (info
->stream
, "\t.short\t0x%04x", given
);
5171 info
->fprintf_func (info
->stream
, "\tinvalid instruction encoding");
5175 printer (pc
, info
, given
);
5179 ifthen_state
= ifthen_next_state
;
5180 ifthen_address
+= size
;
5186 print_insn_big_arm (bfd_vma pc
, struct disassemble_info
*info
)
5188 return print_insn (pc
, info
, FALSE
);
5192 print_insn_little_arm (bfd_vma pc
, struct disassemble_info
*info
)
5194 return print_insn (pc
, info
, TRUE
);
5198 * An otool(1) specific glue function to be used by the FSF disassembler code.
5205 struct disassemble_info
*info
)
5209 void *stream
= info
->stream
;
5210 struct relocation_info
*relocs
= info
->relocs
;
5211 uint32_t nrelocs
= info
->nrelocs
;
5212 struct nlist
*symbols
= info
->symbols
;
5213 uint32_t nsymbols
= info
->nsymbols
;
5214 char *strings
= info
->strings
;
5215 uint32_t strings_size
= info
->strings_size
;
5216 bfd_vma r_address
= pc
- info
->sect_addr
;
5219 /* If there's a relocation at this address, include the referenced
5221 for(i
= 0; i
< nrelocs
; i
++){
5222 if(relocs
[i
].r_address
== r_address
&& relocs
[i
].r_extern
){
5223 unsigned int r_symbolnum
= relocs
[i
].r_symbolnum
;
5224 if(r_symbolnum
< nsymbols
){
5225 uint32_t n_strx
= symbols
[r_symbolnum
].n_un
.n_strx
;
5226 if(n_strx
< strings_size
){
5227 fputs(strings
+ n_strx
, stream
);
5228 if((int32_t) addr
> 0) {
5229 fprintf(stream
, "+%#x", addr
);
5230 } else if((int32_t) addr
< 0) {
5231 fprintf(stream
, "-%#x", -addr
);
5238 /* No relocation entries found. */
5239 name
= guess_symbol(addr
, info
->sorted_symbols
, info
->nsorted_symbols
,
5242 fputs(name
, stream
);
5246 fprintf(stream
, "0x%x", addr
);
5248 name
= guess_indirect_symbol(addr
, info
->ncmds
, info
->sizeofcmds
,
5249 info
->load_commands
, info
->object_byte_sex
,
5250 info
->indirect_symbols
, info
->nindirect_symbols
,
5251 info
->symbols
, NULL
, info
->nsymbols
, info
->strings
,
5252 info
->strings_size
);
5254 fprintf(stream
, "\t@ symbol stub for: %s", name
);
5256 uint64_t reference_type
;
5257 reference_type
= LLVMDisassembler_ReferenceType_In_PCrel_Load
;
5258 name
= guess_literal_pointer(addr
, pc
, &reference_type
, info
);
5260 fprintf(stream
, " literal pool for: ");
5261 if(reference_type
==
5262 LLVMDisassembler_ReferenceType_Out_LitPool_CstrAddr
)
5263 fprintf(stream
, "\"%s\"", name
);
5265 fprintf(stream
, "%s", name
);
5272 * print_immediate_func() prints the 'immediate' value passed to it which is
5273 * at the pc by using the relocation entries, symbol and string tables in the
5274 * disassemble_info. If pool is TRUE then it only looks for what might be a
5275 * literal pool pointer that has a section difference relocation entry and
5276 * if found prints it as a .long. If pool is TRUE and it does not print
5277 * anything then FALSE is returned, else TRUE is returned in all other cases.
5281 print_immediate_func(
5284 struct disassemble_info
*info
,
5287 int32_t low
, high
, mid
, reloc_found
, offset
;
5288 uint32_t i
, r_address
, r_symbolnum
, r_type
, r_extern
, r_length
,
5289 r_value
, r_scattered
, pair_r_type
, pair_r_value
;
5290 uint32_t other_half
;
5291 const char *name
, *add
, *sub
;
5292 struct relocation_info
*rp
, *pairp
;
5293 struct scattered_relocation_info
*srp
, *spairp
;
5296 void *stream
= info
->stream
;
5297 struct relocation_info
*relocs
= info
->relocs
;
5298 uint32_t nrelocs
= info
->nrelocs
;
5299 struct nlist
*symbols
= info
->symbols
;
5300 char *strings
= info
->strings
;
5301 uint32_t strings_size
= info
->strings_size
;
5302 bfd_vma sect_offset
= pc
- info
->sect_addr
;
5314 if(info
->verbose
== FALSE
&& pool
== FALSE
){
5315 fprintf(stream
, "#%u\t@ 0x%x", value
, value
);
5319 for(i
= 0; i
< nrelocs
; i
++){
5321 if(rp
->r_address
& R_SCATTERED
){
5322 srp
= (struct scattered_relocation_info
*)rp
;
5324 r_address
= srp
->r_address
;
5326 r_length
= srp
->r_length
;
5327 r_type
= srp
->r_type
;
5328 r_value
= srp
->r_value
;
5332 r_address
= rp
->r_address
;
5333 r_symbolnum
= rp
->r_symbolnum
;
5334 r_extern
= rp
->r_extern
;
5335 r_length
= rp
->r_length
;
5336 r_type
= rp
->r_type
;
5338 if(r_type
== ARM_RELOC_PAIR
){
5339 fprintf(stderr
, "Stray ARM_RELOC_PAIR relocation entry "
5343 if(r_address
== sect_offset
){
5344 if(r_type
== ARM_RELOC_HALF
||
5345 r_type
== ARM_RELOC_SECTDIFF
||
5346 r_type
== ARM_RELOC_LOCAL_SECTDIFF
||
5347 r_type
== ARM_RELOC_HALF_SECTDIFF
){
5350 if(pairp
->r_address
& R_SCATTERED
){
5351 spairp
= (struct scattered_relocation_info
*)
5353 other_half
= spairp
->r_address
& 0xffff;
5354 pair_r_type
= spairp
->r_type
;
5355 pair_r_value
= spairp
->r_value
;
5358 other_half
= pairp
->r_address
& 0xffff;
5359 pair_r_type
= pairp
->r_type
;
5361 if(pair_r_type
!= ARM_RELOC_PAIR
){
5362 fprintf(stderr
, "No ARM_RELOC_PAIR relocation "
5363 "entry after entry %u\n", i
);
5371 if(r_type
== ARM_RELOC_HALF
||
5372 r_type
== ARM_RELOC_SECTDIFF
||
5373 r_type
== ARM_RELOC_LOCAL_SECTDIFF
||
5374 r_type
== ARM_RELOC_HALF_SECTDIFF
){
5377 if(pairp
->r_address
& R_SCATTERED
){
5378 spairp
= (struct scattered_relocation_info
*)pairp
;
5379 pair_r_type
= spairp
->r_type
;
5382 pair_r_type
= pairp
->r_type
;
5384 if(pair_r_type
== ARM_RELOC_PAIR
)
5387 fprintf(stderr
, "No ARM_RELOC_PAIR relocation "
5388 "entry after entry %u\n", i
);
5394 * If we are looking for possible literal pools, then only print
5395 * something if we find a relocation entry for .long that is a
5396 * section difference.
5399 if(reloc_found
&& r_length
== 2 &&
5400 (r_type
== ARM_RELOC_SECTDIFF
||
5401 r_type
== ARM_RELOC_LOCAL_SECTDIFF
)){
5402 if(!Xflag
&& !no_show_raw_insn
){
5404 fprintf(stream
, "\t");
5405 fprintf(stream
, "%08x\t", value
);
5407 fprintf(stream
, ".long\t");
5408 add
= guess_symbol(r_value
, info
->sorted_symbols
,
5409 info
->nsorted_symbols
, info
->verbose
);
5410 sub
= guess_symbol(pair_r_value
, info
->sorted_symbols
,
5411 info
->nsorted_symbols
, info
->verbose
);
5413 * Since most literal pool pointers are something like:
5414 * .long symbol - (pic_base + offset)
5415 * we calculate the offset this way and print the expression
5416 * this way instead of:
5417 * .long symbol - picbase + offset
5418 * as offset would appear to be a negative number.
5420 offset
= - (value
+ pair_r_value
- r_value
);
5422 fprintf(stream
, "%s", add
);
5424 fprintf(stream
, "0x%x", (unsigned int)r_value
);
5426 fprintf(stream
, "-(%s", sub
);
5428 fprintf(stream
, "-(0x%x", (unsigned int)pair_r_value
);
5430 fprintf(stream
, "+0x%x)", (unsigned int)offset
);
5431 fprintf(stream
, "\n");
5432 /* return indicating we printed something */
5435 /* return indicating we printed nothing */
5439 if(reloc_found
&& r_extern
== 1){
5441 n_strx
= symbols
[r_symbolnum
].n_un
.n_strx
;
5442 if(n_strx
>= strings_size
)
5443 name
= "bad string offset";
5445 name
= strings
+ n_strx
;
5448 case ARM_RELOC_HALF
:
5449 if((r_length
& 0x1) == 1){
5450 value
= value
<< 16 | other_half
;
5451 fprintf(stream
, ":upper16:%s+0x%x", name
,
5452 (unsigned int)value
);
5455 value
= other_half
<< 16 | value
;
5456 fprintf(stream
, ":lower16:%s+0x%x", name
,
5457 (unsigned int)value
);
5461 fprintf(stream
, "%s+0x%x", name
, (unsigned int)value
);
5467 case ARM_RELOC_HALF
:
5468 if((r_length
& 0x1) == 1){
5469 value
= value
<< 16 | other_half
;
5471 fprintf(stream
, ":upper16:%s", name
);
5473 fprintf(stream
, ":upper16:%s+0x%x", name
,
5474 (unsigned int)value
);
5477 value
= other_half
<< 16 | value
;
5479 fprintf(stream
, ":lower16:%s", name
);
5481 fprintf(stream
, ":lower16:%s+0x%x", name
,
5482 (unsigned int)value
);
5487 fprintf(stream
, "%s", name
);
5489 fprintf(stream
, "%s+0x%x", name
, (unsigned int)value
);
5497 if(r_type
== ARM_RELOC_HALF
||
5498 r_type
== ARM_RELOC_HALF_SECTDIFF
){
5499 if((r_length
& 0x1) == 1)
5500 value
= value
<< 16 | other_half
;
5502 value
= other_half
<< 16 | value
;
5505 (r_type
!= ARM_RELOC_HALF
&&
5506 r_type
!= ARM_RELOC_HALF_SECTDIFF
)){
5507 offset
= value
- r_value
;
5512 if(reloc_found
&& r_type
== ARM_RELOC_HALF_SECTDIFF
){
5513 if((r_length
& 0x1) == 1)
5514 fprintf(stream
, ":upper16:");
5516 fprintf(stream
, ":lower16:");
5517 add
= guess_symbol(r_value
, info
->sorted_symbols
,
5518 info
->nsorted_symbols
, info
->verbose
);
5519 sub
= guess_symbol(pair_r_value
, info
->sorted_symbols
,
5520 info
->nsorted_symbols
, info
->verbose
);
5521 offset
= value
- (r_value
- pair_r_value
);
5523 fprintf(stream
, "%s", add
);
5525 fprintf(stream
, "0x%x", (unsigned int)r_value
);
5527 fprintf(stream
, "-%s", sub
);
5529 fprintf(stream
, "-0x%x", (unsigned int)pair_r_value
);
5531 fprintf(stream
, "+0x%x", (unsigned int)offset
);
5536 high
= info
->nsorted_symbols
- 1;
5537 mid
= (high
- low
) / 2;
5539 if(info
->sorted_symbols
[mid
].n_value
== value
){
5542 case ARM_RELOC_HALF
:
5543 if((r_length
& 0x1) == 1){
5545 fprintf(stream
, ":upper16:%s",
5546 info
->sorted_symbols
[mid
].name
);
5548 fprintf(stream
, ":upper16:%s+0x%x",
5549 info
->sorted_symbols
[mid
].name
,
5550 (unsigned int)offset
);
5554 fprintf(stream
, ":lower16:%s",
5555 info
->sorted_symbols
[mid
].name
);
5557 fprintf(stream
, ":lower16:%s+0x%x",
5558 info
->sorted_symbols
[mid
].name
,
5559 (unsigned int)offset
);
5564 fprintf(stream
,"%s",info
->sorted_symbols
[mid
].name
);
5566 fprintf(stream
, "%s+0x%x",
5567 info
->sorted_symbols
[mid
].name
,
5568 (unsigned int)offset
);
5574 fprintf(stream
, "%s",info
->sorted_symbols
[mid
].name
);
5576 fprintf(stream
, "%s+0x%x",
5577 info
->sorted_symbols
[mid
].name
,
5578 (unsigned int)offset
);
5582 if(info
->sorted_symbols
[mid
].n_value
> value
){
5584 mid
= (high
+ low
) / 2;
5588 mid
= (high
+ low
) / 2;
5593 if(r_type
== ARM_RELOC_HALF
){
5594 if((r_length
& 0x1) == 1)
5595 fprintf(stream
, ":upper16:0x%x", (unsigned int)value
);
5597 fprintf(stream
, ":lower16:0x%x", (unsigned int)value
);
5600 fprintf(stream
, "0x%x", (unsigned int)value
);
5603 fprintf(stream
, "0x%x", (unsigned int)value
);
5607 if(r_type
== ARM_RELOC_HALF
){
5608 if((r_length
& 0x1) == 1)
5609 fprintf(stream
, ":upper16:0x%x+0x%x",
5610 (unsigned int)value
, (unsigned int)offset
);
5612 fprintf(stream
, ":lower16:0x%x+0x%x)",
5613 (unsigned int)value
, (unsigned int)offset
);
5616 fprintf(stream
, "0x%x+0x%x",
5617 (unsigned int)value
, (unsigned int)offset
);
5620 fprintf(stream
, "0x%x+0x%x",
5621 (unsigned int)value
, (unsigned int)offset
);
5627 * Print the section contents pointed to by sect as data .long, .short or .byte
5628 * depending on its kind.
5638 uint32_t value
, left
, size
;
5641 if(left
> sect_left
)
5645 case DICE_KIND_DATA
:
5647 value
= sect
[3] << 24 |
5651 if(!Xflag
&& !gflag
&& !no_show_raw_insn
)
5652 printf("\t%08x", value
);
5653 printf("\t.long %u\t@ ", value
);
5657 value
= sect
[1] << 8 |
5659 if(!Xflag
&& !gflag
&& !no_show_raw_insn
)
5660 printf("\t %04x", value
);
5661 printf("\t.short %u\t@ ", value
);
5666 if(!Xflag
&& !gflag
&& !no_show_raw_insn
)
5667 printf("\t %02x", value
& 0xff);
5668 printf("\t.byte %u\t@ ", value
& 0xff);
5671 if(kind
== DICE_KIND_DATA
)
5672 printf("KIND_DATA\n");
5674 printf("kind = %u\n", kind
);
5676 case DICE_KIND_JUMP_TABLE8
:
5678 if(!Xflag
&& !gflag
&& !no_show_raw_insn
)
5679 printf("\t %02x", value
);
5680 printf("\t.byte %3u\t@ KIND_JUMP_TABLE8\n", value
);
5682 case DICE_KIND_JUMP_TABLE16
:
5683 value
= sect
[1] << 8 |
5685 if(!Xflag
&& !gflag
&& !no_show_raw_insn
)
5686 printf("\t %04x", value
& 0xffff);
5687 printf("\t.short %5u\t@ KIND_JUMP_TABLE16\n", value
& 0xffff);
5689 case DICE_KIND_JUMP_TABLE32
:
5690 case DICE_KIND_ABS_JUMP_TABLE32
:
5691 value
= sect
[3] << 24 |
5695 if(!Xflag
&& !gflag
&& !no_show_raw_insn
)
5696 printf("\t%08x", value
);
5697 printf("\t.long %u\t@ ", value
);
5698 if(kind
== DICE_KIND_JUMP_TABLE32
)
5699 printf("KIND_JUMP_TABLE32\n");
5701 printf("KIND_ABS_JUMP_TABLE32\n");
5706 /* Stubbed out for now */
5707 /* Function called to determine if there is a symbol at the given ADDR.
5708 If there is, the function returns 1, otherwise it returns 0.
5709 This is used by ports which support an overlay manager where
5710 the overlay number is held in the top part of an address. In
5711 some circumstances we want to include the overlay number in the
5712 address, (normally because there is a symbol associated with
5713 that address), but sometimes we want to mask out the overlay bits. */
5716 symbol_at_address_func(
5718 struct disassemble_info
* info
)
5721 printf("Unexpected call to stubbed out symbol_at_address_func() "
5722 " addr = 0x%x\n", addr);
5727 /* Function used to get bytes to disassemble. MEMADDR is the
5728 address of the stuff to be disassembled, MYADDR is the address to
5729 put the bytes in, and LENGTH is the number of bytes to read.
5730 INFO is a pointer to this struct.
5731 Returns an errno value or 0 for success. */
5737 unsigned int length
,
5738 struct disassemble_info
*info
)
5740 if(info
->addr
> memaddr
)
5743 if(info
->left
>= length
+ (memaddr
- info
->addr
)){
5744 memcpy(myaddr
, info
->sect
+ (memaddr
- info
->addr
), length
);
5748 memcpy(myaddr
, info
->sect
+ (memaddr
- info
->addr
), info
->left
);
5753 /* Stubbed out for now */
5754 /* Function which should be called if we get an error that we can't
5755 recover from. STATUS is the errno value from read_memory_func and
5756 MEMADDR is the address that we were trying to read. INFO is a
5757 pointer to this struct. */
5759 void memory_error_func(
5762 struct disassemble_info
*info
)
5764 printf("Unexpected call to stubbed out memory_error_func()\n");
5768 * This is the routine called by Apple's otool(1)'s main() routine in otool.c
5769 * and is written as the glue between the otool(1) code and the GNU code.
5777 enum byte_sex object_byte_sex
,
5778 struct relocation_info
*relocs
,
5780 struct nlist
*symbols
,
5782 struct symbol
*sorted_symbols
,
5783 uint32_t nsorted_symbols
,
5785 uint32_t strings_size
,
5786 uint32_t *indirect_symbols
,
5787 uint32_t nindirect_symbols
,
5788 struct load_command
*load_commands
,
5790 uint32_t sizeofcmds
,
5791 cpu_subtype_t cpusubtype
,
5793 LLVMDisasmContextRef arm_dc
,
5794 LLVMDisasmContextRef thumb_dc
,
5796 uint32_t object_size
,
5797 struct data_in_code_entry
*dices
,
5804 uint32_t bytes_consumed
, pool_value
, i
, offset
;
5806 dis_info
.fprintf_func
= (fprintf_ftype
)fprintf
;
5807 dis_info
.stream
= stdout
;
5808 dis_info
.print_address_func
= print_address_func
;
5809 dis_info
.print_immediate_func
= print_immediate_func
;
5812 dis_info
.bytes_per_line
= 8;
5813 dis_info
.bytes_per_chunk
= 4;
5814 dis_info
.display_endian
= LITTLE_ENDIAN_BYTE_SEX
;
5815 dis_info
.symbol_at_address_func
= symbol_at_address_func
;
5816 dis_info
.read_memory_func
= read_memory_func
;
5817 dis_info
.memory_error_func
= memory_error_func
;
5820 dis_info
.verbose
= verbose
;
5821 dis_info
.relocs
= relocs
;
5822 dis_info
.nrelocs
= nrelocs
;
5823 dis_info
.symbols
= symbols
;
5824 dis_info
.nsymbols
= nsymbols
;
5825 dis_info
.sorted_symbols
= sorted_symbols
;
5826 dis_info
.nsorted_symbols
= nsorted_symbols
;
5827 dis_info
.strings
= strings
;
5828 dis_info
.strings_size
= strings_size
;
5829 dis_info
.load_commands
= load_commands
;
5830 dis_info
.object_byte_sex
= object_byte_sex
;
5831 dis_info
.indirect_symbols
= indirect_symbols
;
5832 dis_info
.nindirect_symbols
= nindirect_symbols
;
5833 dis_info
.ncmds
= ncmds
;
5834 dis_info
.sizeofcmds
= sizeofcmds
;
5836 dis_info
.sect
= sect
;
5837 dis_info
.left
= left
;
5838 dis_info
.addr
= addr
;
5839 dis_info
.sect_addr
= sect_addr
;
5841 dis_info
.arm_dc
= arm_dc
;
5842 dis_info
.thumb_dc
= thumb_dc
;
5844 dis_info
.object_addr
= object_addr
;
5845 dis_info
.object_size
= object_size
;
5847 dis_info
.inst
= inst
;
5848 dis_info
.insts
= insts
;
5849 dis_info
.ninsts
= ninsts
;
5851 dis_info
.demangled_name
= NULL
;
5854 * If we have at least 4 bytes left, see if these 4 bytes are a pointer
5855 * in a literal pool by calling print_immediate_func() with the 4 byte
5856 * value and TRUE as the last argument to look for a section difference
5857 * relocation entry for these 4 bytes as a possible pointer at this
5858 * address. If it does it will print a ".long a-b+offset" for these
5862 pool_value
= sect
[3] << 24 |
5866 if(print_immediate_func(addr
, pool_value
, &dis_info
, TRUE
) == TRUE
)
5871 * See if this address is has a data in code entry and if so print.
5874 /* Note: in final linked images, offset is from the base address */
5875 /* Note: in object files, offset is from first section address */
5876 if(nrelocs
== 0) /* TODO better test for final linked image */
5877 offset
= addr
- seg_addr
;
5879 offset
= addr
- sect_addr
;
5880 for(i
= 0; i
< ndices
; i
++){
5881 if(offset
>= dices
[i
].offset
&&
5882 offset
< dices
[i
].offset
+ dices
[i
].length
){
5883 bytes_consumed
= print_data_in_code(sect
, left
,
5884 dices
[i
].offset
+ dices
[i
].length
- offset
,
5886 if ((dices
[i
].kind
== DICE_KIND_JUMP_TABLE8
) &&
5887 (offset
== (dices
[i
].offset
+ dices
[i
].length
- 1)) &&
5888 (dices
[i
].length
& 1)) {
5891 return(bytes_consumed
);
5896 bytes_consumed
= print_insn_little_arm(addr
, &dis_info
);
5897 if(!gflag
|| (inst
!= NULL
&& inst
->print
== TRUE
))
5900 return(bytes_consumed
);
5903 /* Set in_thumb accordingly:
5904 * If no symbols are at addr, don't change it.
5905 * If there are symbols at addr, and any of them are THUMB_DEFs, set it.
5906 * If there are symbols at addr, but none of them are THUMB_DEFs, clear it.
5911 uint32_t nsorted_symbols
,
5912 struct symbol
*sorted_symbols
,
5913 enum bool *in_thumb
)
5915 int32_t high
, low
, mid
;
5918 high
= nsorted_symbols
- 1;
5919 mid
= (high
- low
) / 2;
5921 if(sorted_symbols
[mid
].n_value
== addr
){
5922 /* Find the first symbol at this address */
5923 while(mid
&& sorted_symbols
[mid
-1].n_value
== addr
){
5927 if(sorted_symbols
[mid
].is_thumb
){
5932 if(mid
> nsorted_symbols
||
5933 sorted_symbols
[mid
].n_value
!= addr
){
5939 if(sorted_symbols
[mid
].n_value
> addr
){
5941 mid
= (high
+ low
) / 2;
5945 mid
= (high
+ low
) / 2;