870
[darwin-xtools.git] / cctools / otool / arm_disasm.c
blob1d9d726a87f10419a4b3b4ad0848b67652ccfd48
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)
12 any later version.
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
17 more details.
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,
22 USA.
25 #include <stdlib.h>
26 #include <string.h>
27 #include "stuff/arch.h"
28 #include "stuff/bool.h"
29 #include <stdio.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"
38 #include "otool.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(
48 uint32_t addr,
49 uint32_t nsorted_symbols,
50 struct symbol *sorted_symbols,
51 enum bool *in_thumb);
53 /* HACKS */
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;
69 void *stream;
71 /* new stuff needed, from /Volumes/Untitled 1/src/include/dis-asm.h */
72 /* The bfd_mach value. */
73 uint32_t mach;
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. */
79 int bytes_per_line;
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:
84 00: 00000000 00000000
85 with the chunks displayed according to "display_endian". */
86 int bytes_per_chunk;
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,
122 enum bool pool);
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. */
127 uint32_t flags;
128 #define INSN_HAS_RELOC 0x80000000
130 /* otool(1) specific stuff */
131 enum bool verbose;
132 /* Relocation information. */
133 struct relocation_info *relocs;
134 uint32_t nrelocs;
135 /* Symbol table. */
136 struct nlist *symbols;
137 uint32_t nsymbols;
138 /* Symbols sorted by address. */
139 struct symbol *sorted_symbols;
140 uint32_t nsorted_symbols;
141 /* String table. */
142 char *strings;
143 uint32_t strings_size;
144 /* Other useful info. */
145 uint32_t ncmds;
146 uint32_t sizeofcmds;
147 struct load_command *load_commands;
148 enum byte_sex object_byte_sex;
149 uint32_t *indirect_symbols;
150 uint32_t nindirect_symbols;
151 char *sect;
152 uint32_t left;
153 uint32_t addr;
154 uint32_t sect_addr;
155 LLVMDisasmContextRef arm_dc;
156 LLVMDisasmContextRef thumb_dc;
157 char *object_addr;
158 uint32_t object_size;
159 struct inst *inst;
160 struct inst *insts;
161 uint32_t ninsts;
162 char *demangled_name;
163 } dis_info;
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
179 * returns 0.
181 static
183 GetOpInfo(
184 void *DisInfo,
185 uint64_t Pc,
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 */
189 void *TagBuf)
191 struct disassemble_info *info;
192 struct LLVMOpInfo1 *op_info;
193 unsigned int value;
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;
197 uint32_t other_half;
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)
214 return(0);
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;
223 r_symbolnum = 0;
224 r_type = 0;
225 r_extern = 0;
226 r_value = 0;
227 r_scattered = 0;
228 other_half = 0;
229 pair_r_value = 0;
230 n_strx = 0;
231 r_length = 0;
233 reloc_found = 0;
234 for(i = 0; i < nrelocs; i++){
235 rp = &relocs[i];
236 if(rp->r_address & R_SCATTERED){
237 srp = (struct scattered_relocation_info *)rp;
238 r_scattered = 1;
239 r_address = srp->r_address;
240 r_extern = 0;
241 r_length = srp->r_length;
242 r_type = srp->r_type;
243 r_value = srp->r_value;
245 else{
246 r_scattered = 0;
247 r_address = rp->r_address;
248 r_symbolnum = rp->r_symbolnum;
249 r_extern = rp->r_extern;
250 r_length = rp->r_length;
251 r_type = rp->r_type;
253 if(r_type == ARM_RELOC_PAIR){
254 fprintf(stderr, "Stray ARM_RELOC_PAIR relocation entry "
255 "%u\n", i);
256 continue;
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){
263 if(i+1 < nrelocs){
264 pairp = &rp[1];
265 if(pairp->r_address & R_SCATTERED){
266 spairp = (struct scattered_relocation_info *)
267 pairp;
268 other_half = spairp->r_address & 0xffff;
269 pair_r_type = spairp->r_type;
270 pair_r_value = spairp->r_value;
272 else{
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);
279 continue;
283 reloc_found = 1;
284 break;
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){
290 if(i+1 < nrelocs){
291 pairp = &rp[1];
292 if(pairp->r_address & R_SCATTERED){
293 spairp = (struct scattered_relocation_info *)pairp;
294 pair_r_type = spairp->r_type;
296 else{
297 pair_r_type = pairp->r_type;
299 if(pair_r_type == ARM_RELOC_PAIR)
300 i++;
301 else
302 fprintf(stderr, "No ARM_RELOC_PAIR relocation "
303 "entry after entry %u\n", i);
308 if(reloc_found && r_extern == 1){
309 if(symbols != NULL)
310 n_strx = symbols[r_symbolnum].n_un.n_strx;
311 if(n_strx >= strings_size)
312 name = "bad string offset";
313 else
314 name = strings + n_strx;
315 op_info->AddSymbol.Present = 1;
316 op_info->AddSymbol.Name = name;
317 if(value != 0){
318 switch(r_type){
319 case ARM_RELOC_HALF:
320 if((r_length & 0x1) == 1){
321 op_info->Value = value << 16 | other_half;
322 op_info->VariantKind =
323 LLVMDisassembler_VariantKind_ARM_HI16;
325 else{
326 op_info->Value = other_half << 16 | value;
327 op_info->VariantKind =
328 LLVMDisassembler_VariantKind_ARM_LO16;
330 break;
331 default:
332 break;
335 else{
336 switch(r_type){
337 case ARM_RELOC_HALF:
338 if((r_length & 0x1) == 1){
339 op_info->Value = value << 16 | other_half;
340 op_info->VariantKind =
341 LLVMDisassembler_VariantKind_ARM_HI16;
343 else{
344 op_info->Value = other_half << 16 | value;
345 op_info->VariantKind =
346 LLVMDisassembler_VariantKind_ARM_LO16;
348 break;
349 default:
350 break;
353 return(1);
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))
364 return(0);
366 offset = 0;
367 if(reloc_found){
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;
372 else
373 value = other_half << 16 | value;
375 if(r_scattered &&
376 (r_type != ARM_RELOC_HALF &&
377 r_type != ARM_RELOC_HALF_SECTDIFF)){
378 offset = value - r_value;
379 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;
387 else
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;
396 if(add != NULL)
397 op_info->AddSymbol.Name = add;
398 else
399 op_info->AddSymbol.Value = r_value;
400 op_info->SubtractSymbol.Present = 1;
401 if(sub != NULL)
402 op_info->SubtractSymbol.Name = sub;
403 else
404 op_info->SubtractSymbol.Value = pair_r_value;
405 op_info->Value = offset;
406 return(1);
409 if(reloc_found == FALSE)
410 return(0);
412 op_info->AddSymbol.Present = 1;
413 op_info->Value = offset;
414 if(reloc_found){
415 if(r_type == ARM_RELOC_HALF){
416 if((r_length & 0x1) == 1)
417 op_info->VariantKind =
418 LLVMDisassembler_VariantKind_ARM_HI16;
419 else
420 op_info->VariantKind =
421 LLVMDisassembler_VariantKind_ARM_LO16;
424 low = 0;
425 high = info->nsorted_symbols - 1;
426 mid = (high - low) / 2;
427 while(high >= low){
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;
431 return(1);
433 if(info->sorted_symbols[mid].n_value > value){
434 high = mid - 1;
435 mid = (high + low) / 2;
437 else{
438 low = mid + 1;
439 mid = (high + low) / 2;
442 op_info->AddSymbol.Value = value;
443 return(1);
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.
451 static
452 const char *
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;
463 enum bool swapped;
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;
468 struct section s;
469 char *p;
470 uint64_t big_load_end;
471 const char *name;
473 host_byte_sex = get_host_byte_sex();
474 swapped = host_byte_sex != load_commands_byte_sex;
476 lc = load_commands;
477 big_load_end = 0;
478 for(i = 0 ; i < ncmds; i++){
479 memcpy((char *)&l, (char *)lc, sizeof(struct load_command));
480 if(swapped)
481 swap_load_command(&l, host_byte_sex);
482 if(l.cmdsize % sizeof(int32_t) != 0)
483 return(NULL);
484 big_load_end += l.cmdsize;
485 if(big_load_end > sizeofcmds)
486 return(NULL);
487 switch(l.cmd){
488 case LC_SEGMENT:
489 memcpy((char *)&sg, (char *)lc, sizeof(struct segment_command));
490 if(swapped)
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);
496 if(swapped)
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;
505 return(name);
507 else
508 return(NULL);
511 break;
513 if(l.cmdsize == 0){
514 return(NULL);
516 lc = (struct load_command *)((char *)lc + l.cmdsize);
517 if((char *)lc > (char *)load_commands + sizeofcmds)
518 return(NULL);
520 return(NULL);
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.
529 static
530 enum bool
531 get_literal_pool_value(
532 bfd_vma pc,
533 char const **name,
534 uint32_t *pointer_value,
535 struct disassemble_info *info)
537 int32_t reloc_found;
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;
540 uint32_t other_half;
541 struct relocation_info *rp, *pairp;
542 struct scattered_relocation_info *srp, *spairp;
543 uint32_t n_strx;
545 struct relocation_info *relocs = info->relocs;
546 uint32_t nrelocs = info->nrelocs;
547 bfd_vma sect_offset = pc - info->sect_addr;
549 r_symbolnum = 0;
550 r_type = 0;
551 r_extern = 0;
552 r_value = 0;
553 r_scattered = 0;
554 other_half = 0;
555 pair_r_value = 0;
556 n_strx = 0;
557 r_length = 0;
559 reloc_found = 0;
560 for(i = 0; i < nrelocs; i++){
561 rp = &relocs[i];
562 if(rp->r_address & R_SCATTERED){
563 srp = (struct scattered_relocation_info *)rp;
564 r_scattered = 1;
565 r_address = srp->r_address;
566 r_extern = 0;
567 r_length = srp->r_length;
568 r_type = srp->r_type;
569 r_value = srp->r_value;
571 else{
572 r_scattered = 0;
573 r_address = rp->r_address;
574 r_symbolnum = rp->r_symbolnum;
575 r_extern = rp->r_extern;
576 r_length = rp->r_length;
577 r_type = rp->r_type;
579 if(r_type == ARM_RELOC_PAIR){
580 fprintf(stderr, "Stray ARM_RELOC_PAIR relocation entry "
581 "%u\n", i);
582 continue;
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){
589 if(i+1 < nrelocs){
590 pairp = &rp[1];
591 if(pairp->r_address & R_SCATTERED){
592 spairp = (struct scattered_relocation_info *)
593 pairp;
594 other_half = spairp->r_address & 0xffff;
595 pair_r_type = spairp->r_type;
596 pair_r_value = spairp->r_value;
598 else{
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);
605 continue;
609 reloc_found = 1;
610 break;
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){
616 if(i+1 < nrelocs){
617 pairp = &rp[1];
618 if(pairp->r_address & R_SCATTERED){
619 spairp = (struct scattered_relocation_info *)pairp;
620 pair_r_type = spairp->r_type;
622 else{
623 pair_r_type = pairp->r_type;
625 if(pair_r_type == ARM_RELOC_PAIR)
626 i++;
627 else
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;
640 return(TRUE);
642 *name = NULL;
643 *pointer_value = 0;
644 return(FALSE);
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.
652 static
653 const char *
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;
662 enum bool swapped;
663 struct load_command *load_commands, *lc, l;
664 struct segment_command sg;
665 struct section s;
666 char *object_addr, *p;
667 uint64_t big_load_end;
668 const char *name;
670 ncmds = info->ncmds;
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;
681 lc = load_commands;
682 big_load_end = 0;
683 for(i = 0 ; i < ncmds; i++){
684 memcpy((char *)&l, (char *)lc, sizeof(struct load_command));
685 if(swapped)
686 swap_load_command(&l, host_byte_sex);
687 if(l.cmdsize % sizeof(int32_t) != 0)
688 return(NULL);
689 big_load_end += l.cmdsize;
690 if(big_load_end > sizeofcmds)
691 return(NULL);
692 switch(l.cmd){
693 case LC_SEGMENT:
694 memcpy((char *)&sg, (char *)lc, sizeof(struct segment_command));
695 if(swapped)
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);
701 if(swapped)
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;
711 * pool_value =
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:
721 * .long LC1-(L1+8)
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,
729 info) == FALSE){
730 return(NULL);
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.
737 if(name != NULL){
738 *reference_type =
739 LLVMDisassembler_ReferenceType_Out_LitPool_SymAddr;
740 return(name);
743 * If not, next see if the pointer value is pointing to
744 * a cstring.
746 name = guess_cstring_pointer(pointer_value, ncmds,
747 sizeofcmds, load_commands,
748 object_byte_sex, object_addr,
749 object_size);
750 if(name != NULL){
751 *reference_type =
752 LLVMDisassembler_ReferenceType_Out_LitPool_CstrAddr;
753 return(name);
757 break;
759 if(l.cmdsize == 0){
760 return(NULL);
762 lc = (struct load_command *)((char *)lc + l.cmdsize);
763 if((char *)lc > (char *)load_commands + sizeofcmds)
764 return(NULL);
766 return(NULL);
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.
794 static
795 const char *
796 SymbolLookUp(
797 void *DisInfo,
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;
805 uint32_t i;
807 info = (struct disassemble_info *)DisInfo;
808 if(info->verbose == FALSE){
809 *ReferenceName = NULL;
810 *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
811 return(NULL);
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;
819 break;
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;
838 *ReferenceType =
839 LLVMDisassembler_ReferenceType_DeMangled_Name;
841 else
842 *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
844 else
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;
863 *ReferenceType =
864 LLVMDisassembler_ReferenceType_DeMangled_Name;
867 else{
868 *ReferenceName = NULL;
869 *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
871 return(SymbolName);
874 LLVMDisasmContextRef
875 create_arm_llvm_disassembler(
876 cpu_subtype_t cpusubtype)
878 LLVMDisasmContextRef dc;
879 char *TripleName;
880 char *mcpu_default;
882 mcpu_default = mcpu;
883 switch(cpusubtype){
884 case CPU_SUBTYPE_ARM_V4T:
885 TripleName = "armv4t-apple-darwin10";
886 break;
887 case CPU_SUBTYPE_ARM_V5TEJ:
888 TripleName = "armv5-apple-darwin10";
889 break;
890 case CPU_SUBTYPE_ARM_XSCALE:
891 TripleName = "xscale-apple-darwin10";
892 break;
893 case CPU_SUBTYPE_ARM_V6:
894 TripleName = "armv6-apple-darwin10";
895 break;
896 case CPU_SUBTYPE_ARM_V6M:
897 TripleName = "armv6m-apple-darwin10";
898 if(*mcpu_default == '\0')
899 mcpu_default = "cortex-m0";
900 break;
901 default:
902 case CPU_SUBTYPE_ARM_V7:
903 TripleName = "armv7-apple-darwin10";
904 break;
905 case CPU_SUBTYPE_ARM_V7F:
906 TripleName = "armv7f-apple-darwin10";
907 break;
908 case CPU_SUBTYPE_ARM_V7S:
909 TripleName = "armv7s-apple-darwin10";
910 break;
911 case CPU_SUBTYPE_ARM_V7K:
912 TripleName = "armv7k-apple-darwin10";
913 break;
914 case CPU_SUBTYPE_ARM_V7M:
915 TripleName = "armv7m-apple-darwin10";
916 if(*mcpu_default == '\0')
917 mcpu_default = "cortex-m3";
918 break;
919 case CPU_SUBTYPE_ARM_V7EM:
920 TripleName = "armv7em-apple-darwin10";
921 if(*mcpu_default == '\0')
922 mcpu_default = "cortex-m4";
923 break;
926 dc =
927 #ifdef STATIC_LLVM
928 LLVMCreateDisasm
929 #else
930 llvm_create_disasm
931 #endif
932 (TripleName, mcpu_default, &dis_info, 1, GetOpInfo, SymbolLookUp);
933 return(dc);
936 void
937 delete_arm_llvm_disassembler(
938 LLVMDisasmContextRef dc)
940 #ifdef STATIC_LLVM
941 LLVMDisasmDispose
942 #else
943 llvm_disasm_dispose
944 #endif
945 (dc);
948 LLVMDisasmContextRef
949 create_thumb_llvm_disassembler(
950 cpu_subtype_t cpusubtype)
952 LLVMDisasmContextRef dc;
953 char *TripleName;
954 char *mcpu_default;
956 mcpu_default = mcpu;
957 switch(cpusubtype){
958 case CPU_SUBTYPE_ARM_V4T:
959 TripleName = "thumbv4t-apple-darwin10";
960 break;
961 case CPU_SUBTYPE_ARM_V5TEJ:
962 TripleName = "thumbv5-apple-darwin10";
963 break;
964 case CPU_SUBTYPE_ARM_XSCALE:
965 TripleName = "xscale-apple-darwin10";
966 break;
967 case CPU_SUBTYPE_ARM_V6:
968 TripleName = "thumbv6-apple-darwin10";
969 break;
970 case CPU_SUBTYPE_ARM_V6M:
971 TripleName = "thumbv6m-apple-darwin10";
972 if(*mcpu_default == '\0')
973 mcpu_default = "cortex-m0";
974 break;
975 default:
976 case CPU_SUBTYPE_ARM_V7:
977 TripleName = "thumbv7-apple-darwin10";
978 break;
979 case CPU_SUBTYPE_ARM_V7F:
980 TripleName = "thumbv7f-apple-darwin10";
981 break;
982 case CPU_SUBTYPE_ARM_V7S:
983 TripleName = "thumbv7s-apple-darwin10";
984 break;
985 case CPU_SUBTYPE_ARM_V7K:
986 TripleName = "thumbv7k-apple-darwin10";
987 break;
988 case CPU_SUBTYPE_ARM_V7M:
989 TripleName = "thumbv7m-apple-darwin10";
990 if(*mcpu_default == '\0')
991 mcpu_default = "cortex-m3";
992 break;
993 case CPU_SUBTYPE_ARM_V7EM:
994 TripleName = "thumbv7em-apple-darwin10";
995 if(*mcpu_default == '\0')
996 mcpu_default = "cortex-m4";
997 break;
1000 dc =
1001 #ifdef STATIC_LLVM
1002 LLVMCreateDisasm
1003 #else
1004 llvm_create_disasm
1005 #endif
1006 (TripleName, mcpu_default, &dis_info, 1, GetOpInfo,
1007 SymbolLookUp);
1008 return(dc);
1011 void
1012 delete_thumb_llvm_disassembler(
1013 LLVMDisasmContextRef dc)
1015 #ifdef STATIC_LLVM
1016 LLVMDisasmDispose
1017 #else
1018 llvm_disasm_dispose
1019 #endif
1020 (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
1028 struct opcode32
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. */
1035 struct opcode16
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:
1044 %% %
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'
1083 versions.
1084 %i print 5-bit immediate in bits 8,3..0
1085 (print "32" when 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}"},
1452 {0, 0, 0, 0}
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:
1461 %% %
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
1467 %D print scalar
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[] =
1487 /* Extract */
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]"},
1496 /* Table lookup */
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"},
1733 {0,0 ,0, 0}
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
1738 match. */
1740 /* print_insn_arm recognizes the following format control codes:
1742 %% %
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[] =
1773 /* APPLE LOCAL */
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"},
2033 /* The rest. */
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. */
2070 /* APPLE LOCAL */
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"},
2086 /* ARM V6. */
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)"},
2105 /* Format 4. */
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"},
2122 /* format 13 */
2123 {ARM_EXT_V4T, 0xB000, 0xFF80, "add%c\tsp, #%0-6W"},
2124 {ARM_EXT_V4T, 0xB080, 0xFF80, "sub%c\tsp, #%0-6W"},
2125 /* format 5 */
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"},
2130 /* format 14 */
2131 {ARM_EXT_V4T, 0xB400, 0xFE00, "push%c\t%N"},
2132 {ARM_EXT_V4T, 0xBC00, 0xFE00, "pop%c\t%O"},
2133 /* format 2 */
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"},
2138 /* format 8 */
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]"},
2142 /* format 7 */
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]"},
2145 /* format 1 */
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"},
2149 /* format 3 */
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"},
2154 /* format 6 */
2155 {ARM_EXT_V4T, 0x4800, 0xF800, "ldr%c\t%8-10r, [pc, #%0-7W]\t(%0-7a)"}, /* TODO: Disassemble PC relative "LDR rD,=<symbolic>" */
2156 /* format 9 */
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]"},
2161 /* format 10 */
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]"},
2164 /* format 11 */
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]"},
2167 /* format 12 */
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"},
2170 /* format 15 */
2171 {ARM_EXT_V4T, 0xC000, 0xF800, "stmia%c\t%8-10r!, %M"},
2172 {ARM_EXT_V4T, 0xC800, 0xF800, "ldmia%c\t%8-10R!, %M"},
2173 /* format 17 */
2174 {ARM_EXT_V4T, 0xDF00, 0xFF00, "svc%c\t%0-7d"},
2175 /* format 16 */
2176 {ARM_EXT_V4T, 0xDE00, 0xFE00, "undefined"},
2177 {ARM_EXT_V4T, 0xD000, 0xF000, "b%8-11c.n\t%0-7B%X"},
2178 /* format 18 */
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"},
2186 {0, 0, 0, 0}
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:
2195 %% %
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"},
2440 /* Fallback. */
2441 {ARM_EXT_V1, 0x00000000, 0x00000000, "undefined"},
2442 {0, 0, 0, 0}
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"};
2455 typedef struct
2457 const char *name;
2458 const char *description;
2459 const char *reg_names[16];
2461 arm_regname;
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. */
2517 enum map_type {
2518 MAP_ARM,
2519 MAP_THUMB,
2520 MAP_DATA
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. */
2532 static const char *
2533 arm_decode_bitfield (const char *ptr, uint32_t insn,
2534 uint32_t *valuep, int *widthp)
2536 uint32_t value = 0;
2537 int width = 0;
2541 int start, end;
2542 int bits;
2544 for (start = 0; *ptr >= '0' && *ptr <= '9'; ptr++)
2545 start = start * 10 + *ptr - '0';
2546 if (*ptr == '-')
2547 for (end = 0, ptr++; *ptr >= '0' && *ptr <= '9'; ptr++)
2548 end = end * 10 + *ptr - '0';
2549 else
2550 end = start;
2551 bits = end - start;
2552 if (bits < 0)
2553 abort ();
2554 value |= ((insn >> start) & ((2ul << bits) - 1)) << width;
2555 width += bits + 1;
2557 while (*ptr++ == ',');
2558 *valuep = value;
2559 if (widthp)
2560 *widthp = width;
2561 return ptr - 1;
2564 static void
2565 arm_decode_shift (int32_t given, fprintf_ftype func, void *stream,
2566 int print_shift)
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;
2577 if (amount == 0)
2579 if (shift == 3)
2581 func (stream, ", rrx");
2582 return;
2585 amount = 32;
2588 if (print_shift)
2589 func (stream, ", %s #%d", arm_shift[shift], amount);
2590 else
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]);
2596 else
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. */
2605 static bfd_boolean
2606 print_insn_coprocessor (bfd_vma pc, struct disassemble_info *info, int32_t given,
2607 bfd_boolean thumb)
2609 const struct opcode32 *insn;
2610 void *stream = info->stream;
2611 fprintf_ftype func = info->fprintf_func;
2612 uint32_t mask;
2613 uint32_t value;
2614 int cond;
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;
2624 mask = insn->mask;
2625 value = insn->value;
2626 if (thumb)
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. */
2631 mask |= 0xf0000000;
2632 value |= 0xe0000000;
2633 if (ifthen_state)
2634 cond = IFTHEN_COND;
2635 else
2636 cond = 16;
2638 else
2640 /* Only match unconditional instuctions against unconditional
2641 patterns. */
2642 if ((given & 0xf0000000) == 0xf0000000)
2644 mask |= 0xf0000000;
2645 cond = 16;
2647 else
2649 cond = (given >> 28) & 0xf;
2650 if (cond == 0xe)
2651 cond = 16;
2654 if ((given & mask) == value)
2656 const char *c;
2658 for (c = insn->assembler; *c; c++)
2660 if (*c == '%')
2662 switch (*++c)
2664 case '%':
2665 func (stream, "%%");
2666 break;
2668 case 'A':
2669 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
2671 if ((given & (1 << 24)) != 0)
2673 int offset = given & 0xff;
2675 if (offset)
2676 func (stream, ", #%s%d]%s",
2677 ((given & 0x00800000) == 0 ? "-" : ""),
2678 offset * 4,
2679 ((given & 0x00200000) != 0 ? "!" : ""));
2680 else
2681 func (stream, "]");
2683 else
2685 int offset = given & 0xff;
2687 func (stream, "]");
2689 if (given & (1 << 21))
2691 if (offset)
2692 func (stream, ", #%s%d",
2693 ((given & 0x00800000) == 0 ? "-" : ""),
2694 offset * 4);
2696 else
2697 func (stream, ", {%d}", offset);
2699 break;
2701 case 'B':
2703 int regno = ((given >> 12) & 0xf) | ((given >> (22 - 4)) & 0x10);
2704 int offset = (given >> 1) & 0x3f;
2706 if (offset == 1)
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);
2710 else
2711 func (stream, "{d%d-d%d}", regno, regno + offset - 1);
2713 break;
2715 case 'C':
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]);
2723 if (offset)
2725 if (!add)
2726 offset = -offset;
2727 func (stream, ", #%d", offset);
2729 func (stream, "]");
2730 if (rn == 15)
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);
2739 break;
2741 case 'c':
2742 func (stream, "%s", arm_conditional[cond]);
2743 break;
2745 case 'I':
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
2749 of opcode. */
2751 int imm;
2753 imm = (given & 0xf) | ((given & 0xe0) >> 1);
2755 /* Is ``imm'' a negative number? */
2756 if (imm & 0x40)
2757 imm |= (-1 << 7);
2759 func (stream, "%d", imm);
2762 break;
2764 case 'F':
2765 switch (given & 0x00408000)
2767 case 0:
2768 func (stream, "4");
2769 break;
2770 case 0x8000:
2771 func (stream, "1");
2772 break;
2773 case 0x00400000:
2774 func (stream, "2");
2775 break;
2776 default:
2777 func (stream, "3");
2779 break;
2781 case 'P':
2782 switch (given & 0x00080080)
2784 case 0:
2785 func (stream, "s");
2786 break;
2787 case 0x80:
2788 func (stream, "d");
2789 break;
2790 case 0x00080000:
2791 func (stream, "e");
2792 break;
2793 default:
2794 func (stream, _("<illegal precision>"));
2795 break;
2797 break;
2798 case 'Q':
2799 switch (given & 0x00408000)
2801 case 0:
2802 func (stream, "s");
2803 break;
2804 case 0x8000:
2805 func (stream, "d");
2806 break;
2807 case 0x00400000:
2808 func (stream, "e");
2809 break;
2810 default:
2811 func (stream, "p");
2812 break;
2814 break;
2815 case 'R':
2816 switch (given & 0x60)
2818 case 0:
2819 break;
2820 case 0x20:
2821 func (stream, "p");
2822 break;
2823 case 0x40:
2824 func (stream, "m");
2825 break;
2826 default:
2827 func (stream, "z");
2828 break;
2830 break;
2832 case '0': case '1': case '2': case '3': case '4':
2833 case '5': case '6': case '7': case '8': case '9':
2835 int width;
2836 uint32_t value;
2838 c = arm_decode_bitfield (c, given, &value, &width);
2840 switch (*c)
2842 case 'r':
2843 func (stream, "%s", arm_regnames[value]);
2844 break;
2845 case 'D':
2846 func (stream, "d%ld", value);
2847 break;
2848 case 'Q':
2849 if (value & 1)
2850 func (stream, "<illegal reg q%ld.5>", value >> 1);
2851 else
2852 func (stream, "q%ld", value >> 1);
2853 break;
2854 case 'd':
2855 func (stream, "%ld", value);
2856 break;
2857 case 'k':
2859 int from = (given & (1 << 7)) ? 32 : 16;
2860 func (stream, "%ld", from - value);
2862 break;
2864 case 'f':
2865 if (value > 7)
2866 func (stream, "#%s", arm_fp_const[value & 7]);
2867 else
2868 func (stream, "f%ld", value);
2869 break;
2871 case 'w':
2872 if (width == 2)
2873 func (stream, "%s", iwmmxt_wwnames[value]);
2874 else
2875 func (stream, "%s", iwmmxt_wwssnames[value]);
2876 break;
2878 case 'g':
2879 func (stream, "%s", iwmmxt_regnames[value]);
2880 break;
2881 case 'G':
2882 func (stream, "%s", iwmmxt_cregnames[value]);
2883 break;
2885 case 'x':
2886 func (stream, "0x%lx", value);
2887 break;
2889 case '`':
2890 c++;
2891 if (value == 0)
2892 func (stream, "%c", *c);
2893 break;
2894 case '\'':
2895 c++;
2896 if (value == ((1ul << width) - 1))
2897 func (stream, "%c", *c);
2898 break;
2899 case '?':
2900 func (stream, "%c", c[(1 << width) - (int)value]);
2901 c += 1 << width;
2902 break;
2903 default:
2904 abort ();
2906 break;
2908 case 'y':
2909 case 'z':
2911 int single = *c++ == 'y';
2912 int regno;
2914 switch (*c)
2916 case '4': /* Sm pair */
2917 func (stream, "{");
2918 /* Fall through. */
2919 case '0': /* Sm, Dm */
2920 regno = given & 0x0000000f;
2921 if (single)
2923 regno <<= 1;
2924 regno += (given >> 5) & 1;
2926 else
2927 regno += ((given >> 5) & 1) << 4;
2928 break;
2930 case '1': /* Sd, Dd */
2931 regno = (given >> 12) & 0x0000000f;
2932 if (single)
2934 regno <<= 1;
2935 regno += (given >> 22) & 1;
2937 else
2938 regno += ((given >> 22) & 1) << 4;
2939 break;
2941 case '2': /* Sn, Dn */
2942 regno = (given >> 16) & 0x0000000f;
2943 if (single)
2945 regno <<= 1;
2946 regno += (given >> 7) & 1;
2948 else
2949 regno += ((given >> 7) & 1) << 4;
2950 break;
2952 case '3': /* List */
2953 func (stream, "{");
2954 regno = (given >> 12) & 0x0000000f;
2955 if (single)
2957 regno <<= 1;
2958 regno += (given >> 22) & 1;
2960 else
2961 regno += ((given >> 22) & 1) << 4;
2962 break;
2964 default:
2965 abort ();
2968 func (stream, "%c%d", single ? 's' : 'd', regno);
2970 if (*c == '3')
2972 int count = given & 0xff;
2974 if (single == 0)
2975 count >>= 1;
2977 if (--count)
2979 func (stream, "-%c%d",
2980 single ? 's' : 'd',
2981 regno + count);
2984 func (stream, "}");
2986 else if (*c == '4')
2987 func (stream, ", %c%d}", single ? 's' : 'd',
2988 regno + 1);
2990 break;
2992 case 'L':
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;
2999 default:
3000 break;
3002 break;
3004 case 'Z':
3006 int value;
3007 /* given (20, 23) | given (0, 3) */
3008 value = ((given >> 16) & 0xf0) | (given & 0xf);
3009 func (stream, "%d", value);
3011 break;
3013 case 'l':
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]);
3023 if (offset)
3025 if ((given & 0x01000000) != 0)
3026 func (stream, ", #%s%d]%s",
3027 ((given & 0x00800000) == 0 ? "-" : ""),
3028 offset * multiplier,
3029 ((given & 0x00200000) != 0 ? "!" : ""));
3030 else
3031 func (stream, "], #%s%d",
3032 ((given & 0x00800000) == 0 ? "-" : ""),
3033 offset * multiplier);
3035 else
3036 func (stream, "]");
3038 break;
3040 case 'r':
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];
3048 switch (puw_bits)
3050 case 1:
3051 /* fall through */
3052 case 3:
3053 func (stream, "[%s], %c%s", rn, ubit ? '+' : '-', rm);
3054 if (imm4)
3055 func (stream, ", lsl #%d", imm4);
3056 break;
3058 case 4:
3059 /* fall through */
3060 case 5:
3061 /* fall through */
3062 case 6:
3063 /* fall through */
3064 case 7:
3065 func (stream, "[%s, %c%s", rn, ubit ? '+' : '-', rm);
3066 if (imm4 > 0)
3067 func (stream, ", lsl #%d", imm4);
3068 func (stream, "]");
3069 if (puw_bits == 5 || puw_bits == 7)
3070 func (stream, "!");
3071 break;
3073 default:
3074 func (stream, "INVALID");
3077 break;
3079 case 'i':
3081 int32_t imm5;
3082 imm5 = ((given & 0x100) >> 4) | (given & 0xf);
3083 func (stream, "%ld", (imm5 == 0) ? 32 : imm5);
3085 break;
3087 default:
3088 abort ();
3092 else
3093 func (stream, "%c", *c);
3095 return TRUE;
3098 return FALSE;
3101 static void
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)
3117 offset = - offset;
3119 /* Pre-indexed. */
3120 func (stream, ", #%d]", offset);
3122 offset += pc + 8;
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
3127 argue ? */
3128 if (given & 0x00200000)
3129 func (stream, "!");
3131 else
3133 /* Post indexed. */
3134 func (stream, "], #%d", offset);
3136 /* ie ignore the offset. */
3137 offset = pc + 8;
3140 func (stream, "\t@ ");
3141 info->print_address_func (pc, offset, info);
3143 else
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;
3152 if (offset)
3153 func (stream, ", #%s%d",
3154 (((given & 0x00800000) == 0)
3155 ? "-" : ""), offset);
3157 else
3159 func (stream, ", %s",
3160 (((given & 0x00800000) == 0)
3161 ? "-" : ""));
3162 arm_decode_shift (given, func, stream, 1);
3165 func (stream, "]%s",
3166 ((given & 0x00200000) != 0) ? "!" : "");
3168 else
3170 if ((given & 0x02000000) == 0)
3172 int offset = given & 0xfff;
3173 if (offset)
3174 func (stream, "], #%s%d",
3175 (((given & 0x00800000) == 0)
3176 ? "-" : ""), offset);
3177 else
3178 func (stream, "]");
3180 else
3182 func (stream, "], %s",
3183 (((given & 0x00800000) == 0)
3184 ? "-" : ""));
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. */
3195 static bfd_boolean
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;
3202 if (thumb)
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;
3210 if (bit28)
3211 given |= 0xf3000000;
3212 else
3213 given |= 0xf2000000;
3215 else if ((given & 0xff000000) == 0xf9000000)
3216 given ^= 0xf9000000 ^ 0xf4000000;
3217 else
3218 return FALSE;
3221 for (insn = neon_opcodes; insn->assembler; insn++)
3223 if ((given & insn->mask) == insn->value)
3225 const char *c;
3227 for (c = insn->assembler; *c; c++)
3229 if (*c == '%')
3231 switch (*++c)
3233 case '%':
3234 func (stream, "%%");
3235 break;
3237 case 'c':
3238 if (thumb && ifthen_state)
3239 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3240 break;
3242 case 'A':
3244 static const unsigned char enc[16] =
3246 0x4, 0x14, /* st4 0,1 */
3247 0x4, /* st1 2 */
3248 0x4, /* st2 3 */
3249 0x3, /* st3 4 */
3250 0x13, /* st3 5 */
3251 0x3, /* st1 6 */
3252 0x1, /* st1 7 */
3253 0x2, /* st2 8 */
3254 0x12, /* st2 9 */
3255 0x2, /* st1 10 */
3256 0, 0, 0, 0, 0
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;
3265 int ix;
3267 func (stream, "{");
3268 if (stride > 1)
3269 for (ix = 0; ix != n; ix++)
3270 func (stream, "%sd%d", ix ? "," : "", rd + ix * stride);
3271 else if (n == 1)
3272 func (stream, "d%d", rd);
3273 else
3274 func (stream, "d%d-d%d", rd, rd + n - 1);
3275 func (stream, "}, [%s", arm_regnames[rn]);
3276 if (align)
3277 func (stream, ", :%d", 32 << align);
3278 func (stream, "]");
3279 if (rm == 0xd)
3280 func (stream, "!");
3281 else if (rm != 0xf)
3282 func (stream, ", %s", arm_regnames[rm]);
3284 break;
3286 case 'B':
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);
3292 int align = 0;
3293 int size = ((given >> 10) & 0x3);
3294 int idx = idx_align >> (size + 1);
3295 int length = ((given >> 8) & 3) + 1;
3296 int stride = 1;
3297 int i;
3299 if (length > 1 && size > 0)
3300 stride = (idx_align & (1 << size)) ? 2 : 1;
3302 switch (length)
3304 case 1:
3306 int amask = (1 << size) - 1;
3307 if ((idx_align & (1 << size)) != 0)
3308 return FALSE;
3309 if (size > 0)
3311 if ((idx_align & amask) == amask)
3312 align = 8 << size;
3313 else if ((idx_align & amask) != 0)
3314 return FALSE;
3317 break;
3319 case 2:
3320 if (size == 2 && (idx_align & 2) != 0)
3321 return FALSE;
3322 align = (idx_align & 1) ? 16 << size : 0;
3323 break;
3325 case 3:
3326 if ((size == 2 && (idx_align & 3) != 0)
3327 || (idx_align & 1) != 0)
3328 return FALSE;
3329 break;
3331 case 4:
3332 if (size == 2)
3334 if ((idx_align & 3) == 3)
3335 return FALSE;
3336 align = (idx_align & 3) * 64;
3338 else
3339 align = (idx_align & 1) ? 32 << size : 0;
3340 break;
3342 default:
3343 abort ();
3346 func (stream, "{");
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]);
3351 if (align)
3352 func (stream, ", :%d", align);
3353 func (stream, "]");
3354 if (rm == 0xd)
3355 func (stream, "!");
3356 else if (rm != 0xf)
3357 func (stream, ", %s", arm_regnames[rm]);
3359 break;
3361 case 'C':
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);
3369 int n = type + 1;
3370 int stride = ((given >> 5) & 0x1);
3371 int ix;
3373 if (stride && (n == 1))
3374 n++;
3375 else
3376 stride++;
3378 func (stream, "{");
3379 if (stride > 1)
3380 for (ix = 0; ix != n; ix++)
3381 func (stream, "%sd%d[]", ix ? "," : "", rd + ix * stride);
3382 else if (n == 1)
3383 func (stream, "d%d[]", rd);
3384 else
3385 func (stream, "d%d[]-d%d[]", rd, rd + n - 1);
3386 func (stream, "}, [%s", arm_regnames[rn]);
3387 if (align)
3389 int align = (8 * (type + 1)) << size;
3390 if (type == 3)
3391 align = (size > 1) ? align >> 1 : align;
3392 if (type == 2 || (type == 0 && !size))
3393 func (stream, ", :<bad align %d>", align);
3394 else
3395 func (stream, ", :%d", align);
3397 func (stream, "]");
3398 if (rm == 0xd)
3399 func (stream, "!");
3400 else if (rm != 0xf)
3401 func (stream, ", %s", arm_regnames[rm]);
3403 break;
3405 case 'D':
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);
3414 break;
3416 case 'E':
3417 /* Neon encoded constant for mov, mvn, vorr, vbic */
3419 int bits = 0;
3420 int cmode = (given >> 8) & 0xf;
3421 int op = (given >> 5) & 0x1;
3422 uint32_t value = 0, hival = 0;
3423 unsigned shift;
3424 int size = 0;
3425 int isfloat = 0;
3427 bits |= ((given >> 24) & 1) << 7;
3428 bits |= ((given >> 16) & 7) << 4;
3429 bits |= ((given >> 0) & 15) << 0;
3431 if (cmode < 8)
3433 shift = (cmode >> 1) & 3;
3434 value = (uint32_t)bits << (8 * shift);
3435 size = 32;
3437 else if (cmode < 12)
3439 shift = (cmode >> 1) & 1;
3440 value = (uint32_t)bits << (8 * shift);
3441 size = 16;
3443 else if (cmode < 14)
3445 shift = (cmode & 1) + 1;
3446 value = (uint32_t)bits << (8 * shift);
3447 value |= (1ul << (8 * shift)) - 1;
3448 size = 32;
3450 else if (cmode == 14)
3452 if (op)
3454 /* bit replication into bytes */
3455 int ix;
3456 uint32_t mask;
3458 value = 0;
3459 hival = 0;
3460 for (ix = 7; ix >= 0; ix--)
3462 mask = ((bits >> ix) & 1) ? 0xff : 0;
3463 if (ix <= 3)
3464 value = (value << 8) | mask;
3465 else
3466 hival = (hival << 8) | mask;
3468 size = 64;
3470 else
3472 /* byte replication */
3473 value = (uint32_t)bits;
3474 size = 8;
3477 else if (!op)
3479 /* floating point encoding */
3480 int tmp;
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;
3486 size = 32;
3487 isfloat = 1;
3489 else
3491 func (stream, "<illegal constant %.8x:%x:%x>",
3492 bits, cmode, op);
3493 size = 32;
3494 break;
3496 switch (size)
3498 case 8:
3499 func (stream, "#%ld\t@ 0x%.2lx", value, value);
3500 break;
3502 case 16:
3503 func (stream, "#%ld\t@ 0x%.4lx", value, value);
3504 break;
3506 case 32:
3507 if (isfloat)
3509 unsigned char valbytes[4];
3510 double fvalue;
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;
3519 #ifdef NOTYET
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,
3524 &fvalue);
3525 #else /* NOTYET */
3526 if(get_host_byte_sex() !=
3527 LITTLE_ENDIAN_BYTE_SEX){
3528 float f;
3529 memcpy(&f, valbytes, 4);
3530 f = SWAP_FLOAT(f);
3531 fvalue = f;
3533 else{
3534 float f;
3535 memcpy(&f, valbytes, 4);
3536 fvalue = f;
3538 #endif /* NOTYET */
3539 func (stream, "#%.7g\t@ 0x%.8lx", fvalue,
3540 value);
3542 else
3543 func (stream, "#%ld\t@ 0x%.8lx",
3544 (int32_t) ((value & 0x80000000)
3545 ? value | ~0xffffffffl : value), value);
3546 break;
3548 case 64:
3549 func (stream, "#0x%.8lx%.8lx", hival, value);
3550 break;
3552 default:
3553 abort ();
3556 break;
3558 case 'F':
3560 int regno = ((given >> 16) & 0xf) | ((given >> (7 - 4)) & 0x10);
3561 int num = (given >> 8) & 0x3;
3563 if (!num)
3564 func (stream, "{d%d}", regno);
3565 else if (num + regno >= 32)
3566 func (stream, "{d%d-<overflow reg d%d}", regno, regno + num);
3567 else
3568 func (stream, "{d%d-d%d}", regno, regno + num);
3570 break;
3573 case '0': case '1': case '2': case '3': case '4':
3574 case '5': case '6': case '7': case '8': case '9':
3576 int width;
3577 uint32_t value;
3579 c = arm_decode_bitfield (c, given, &value, &width);
3581 switch (*c)
3583 case 'r':
3584 func (stream, "%s", arm_regnames[value]);
3585 break;
3586 case 'd':
3587 func (stream, "%ld", value);
3588 break;
3589 case 'e':
3590 func (stream, "%ld", (1ul << width) - value);
3591 break;
3593 case 'S':
3594 case 'T':
3595 case 'U':
3596 /* various width encodings */
3598 int base = 8 << (*c - 'S'); /* 8,16 or 32 */
3599 int limit;
3600 unsigned low, high;
3602 c++;
3603 if (*c >= '0' && *c <= '9')
3604 limit = *c - '0';
3605 else if (*c >= 'a' && *c <= 'f')
3606 limit = *c - 'a' + 10;
3607 else
3608 abort ();
3609 low = limit >> 2;
3610 high = limit & 3;
3612 if (value < low || value > high)
3613 func (stream, "<illegal width %d>", base << value);
3614 else
3615 func (stream, "%d", base << value);
3617 break;
3618 case 'R':
3619 if (given & (1 << 6))
3620 goto Q;
3621 /* FALLTHROUGH */
3622 case 'D':
3623 func (stream, "d%ld", value);
3624 break;
3625 case 'Q':
3627 if (value & 1)
3628 func (stream, "<illegal reg q%ld.5>", value >> 1);
3629 else
3630 func (stream, "q%ld", value >> 1);
3631 break;
3633 case '`':
3634 c++;
3635 if (value == 0)
3636 func (stream, "%c", *c);
3637 break;
3638 case '\'':
3639 c++;
3640 if (value == ((1ul << width) - 1))
3641 func (stream, "%c", *c);
3642 break;
3643 case '?':
3644 func (stream, "%c", c[(1 << width) - (int)value]);
3645 c += 1 << width;
3646 break;
3647 default:
3648 abort ();
3650 break;
3652 default:
3653 abort ();
3657 else
3658 func (stream, "%c", *c);
3660 return TRUE;
3663 return FALSE;
3666 /* Print one ARM instruction from PC on INFO->STREAM. */
3668 static void
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))
3676 return;
3678 if (print_insn_neon (info, given, FALSE))
3679 return;
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)))
3696 const char *c;
3698 for (c = insn->assembler; *c; c++)
3700 if (*c == '%')
3702 switch (*++c)
3704 case '%':
3705 func (stream, "%%");
3706 break;
3708 case 'a':
3709 print_arm_address (pc, info, given);
3710 break;
3712 case 'P':
3713 /* Set P address bit and use normal address
3714 printing routine. */
3715 print_arm_address (pc, info, given | (1 << 24));
3716 break;
3718 case 's':
3719 if ((given & 0x004f0000) == 0x004f0000)
3721 /* PC relative with immediate offset. */
3722 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
3724 if ((given & 0x00800000) == 0)
3725 offset = -offset;
3727 func (stream, "[pc, #%d]\t@ ", offset);
3728 info->print_address_func (pc, offset + pc + 8, info);
3730 else
3732 func (stream, "[%s",
3733 arm_regnames[(given >> 16) & 0xf]);
3734 if ((given & 0x01000000) != 0)
3736 /* Pre-indexed. */
3737 if ((given & 0x00400000) == 0x00400000)
3739 /* Immediate. */
3740 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
3741 if (offset)
3742 func (stream, ", #%s%d",
3743 (((given & 0x00800000) == 0)
3744 ? "-" : ""), offset);
3746 else
3748 /* Register. */
3749 func (stream, ", %s%s",
3750 (((given & 0x00800000) == 0)
3751 ? "-" : ""),
3752 arm_regnames[given & 0xf]);
3755 func (stream, "]%s",
3756 ((given & 0x00200000) != 0) ? "!" : "");
3758 else
3760 /* Post-indexed. */
3761 if ((given & 0x00400000) == 0x00400000)
3763 /* Immediate. */
3764 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
3765 if (offset)
3766 func (stream, "], #%s%d",
3767 (((given & 0x00800000) == 0)
3768 ? "-" : ""), offset);
3769 else
3770 func (stream, "]");
3772 else
3774 /* Register. */
3775 func (stream, "], %s%s",
3776 (((given & 0x00800000) == 0)
3777 ? "-" : ""),
3778 arm_regnames[given & 0xf]);
3782 break;
3784 case 'b':
3786 int disp = (((given & 0xffffff) ^ 0x800000) - 0x800000);
3787 info->print_address_func (pc, disp*4 + pc + 8, info);
3789 break;
3791 case 'c':
3792 if (((given >> 28) & 0xf) != 0xe)
3793 func (stream, "%s",
3794 arm_conditional [(given >> 28) & 0xf]);
3795 break;
3797 case 'm':
3799 int started = 0;
3800 int reg;
3802 func (stream, "{");
3803 for (reg = 0; reg < 16; reg++)
3804 if ((given & (1 << reg)) != 0)
3806 if (started)
3807 func (stream, ", ");
3808 started = 1;
3809 func (stream, "%s", arm_regnames[reg]);
3811 func (stream, "}");
3813 break;
3815 case 'q':
3816 arm_decode_shift (given, func, stream, 0);
3817 break;
3819 case 'o':
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);
3828 else
3829 arm_decode_shift (given, func, stream, 1);
3830 break;
3832 case 'p':
3833 if ((given & 0x0000f000) == 0x0000f000)
3834 func (stream, "p");
3835 break;
3837 case 't':
3838 if ((given & 0x01200000) == 0x00200000)
3839 func (stream, "t");
3840 break;
3842 case 'A':
3843 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
3845 if ((given & (1 << 24)) != 0)
3847 int offset = given & 0xff;
3849 if (offset)
3850 func (stream, ", #%s%d]%s",
3851 ((given & 0x00800000) == 0 ? "-" : ""),
3852 offset * 4,
3853 ((given & 0x00200000) != 0 ? "!" : ""));
3854 else
3855 func (stream, "]");
3857 else
3859 int offset = given & 0xff;
3861 func (stream, "]");
3863 if (given & (1 << 21))
3865 if (offset)
3866 func (stream, ", #%s%d",
3867 ((given & 0x00800000) == 0 ? "-" : ""),
3868 offset * 4);
3870 else
3871 func (stream, ", {%d}", offset);
3873 break;
3875 case 'B':
3876 /* Print ARM V5 BLX(1) address: pc+25 bits. */
3878 bfd_vma address;
3879 bfd_vma offset = 0;
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;
3887 offset <<= 2;
3888 address = offset + pc + 8;
3890 if (given & 0x01000000)
3891 /* H bit allows addressing to 2-byte boundaries. */
3892 address += 2;
3894 info->print_address_func (pc, address, info);
3896 break;
3898 case 'C':
3899 func (stream, "_");
3900 if (given & 0x80000)
3901 func (stream, "f");
3902 if (given & 0x40000)
3903 func (stream, "s");
3904 if (given & 0x20000)
3905 func (stream, "x");
3906 if (given & 0x10000)
3907 func (stream, "c");
3908 break;
3910 case 'U':
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;
3921 default:
3922 func(stream, "#%d", (int)given & 0xf);
3923 break;
3925 break;
3927 case '0': case '1': case '2': case '3': case '4':
3928 case '5': case '6': case '7': case '8': case '9':
3930 int width;
3931 uint32_t value;
3933 c = arm_decode_bitfield (c, given, &value, &width);
3935 switch (*c)
3937 case 'r':
3938 func (stream, "%s", arm_regnames[value]);
3939 break;
3940 case 'd':
3941 func (stream, "%ld", value);
3942 break;
3943 case 'b':
3944 func (stream, "%ld", value * 8);
3945 break;
3946 case 'W':
3947 func (stream, "%ld", value + 1);
3948 break;
3949 case 'x':
3950 func (stream, "0x%08lx", value);
3952 /* Some SWI instructions have special
3953 meanings. */
3954 if ((given & 0x0fffffff) == 0x0FF00000)
3955 func (stream, "\t@ IMB");
3956 else if ((given & 0x0fffffff) == 0x0FF00001)
3957 func (stream, "\t@ IMBRange");
3958 break;
3959 case 'X':
3960 func (stream, "%01lx", value & 0xf);
3961 break;
3962 case '`':
3963 c++;
3964 if (value == 0)
3965 func (stream, "%c", *c);
3966 break;
3967 case '\'':
3968 c++;
3969 if (value == ((1ul << width) - 1))
3970 func (stream, "%c", *c);
3971 break;
3972 case '?':
3973 func (stream, "%c", c[(1 << width) - (int)value]);
3974 c += 1 << width;
3975 break;
3976 default:
3977 abort ();
3979 break;
3981 case 'e':
3983 int imm;
3985 imm = (given & 0xf) | ((given & 0xfff00) >> 4);
3986 func (stream, "%d", imm);
3988 break;
3990 case 'E':
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;
3998 if (width > 0)
3999 func (stream, "#%lu, #%lu", lsb, width);
4000 else
4001 func (stream, "(invalid: %lu:%lu)", lsb, msb);
4003 break;
4005 case 'V':
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,
4013 FALSE);
4015 break;
4017 default:
4018 abort ();
4022 else
4023 func (stream, "%c", *c);
4025 return;
4028 abort ();
4031 /* Print one 16-bit Thumb instruction from PC on INFO->STREAM. */
4033 static void
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;
4044 for (; *c; c++)
4046 int domaskpc = 0;
4047 int domasklr = 0;
4049 if (*c != '%')
4051 func (stream, "%c", *c);
4052 continue;
4055 switch (*++c)
4057 case '%':
4058 func (stream, "%%");
4059 break;
4061 case 'c':
4062 if (ifthen_state)
4063 func (stream, "%s", arm_conditional[IFTHEN_COND]);
4064 break;
4066 case 'C':
4067 if (ifthen_state)
4068 func (stream, "%s", arm_conditional[IFTHEN_COND]);
4069 else
4070 func (stream, "s");
4071 break;
4073 case 'I':
4075 unsigned int tmp;
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]);
4082 break;
4084 case 'x':
4085 if (ifthen_next_state)
4086 func (stream, "\t@ unpredictable branch in IT block\n");
4087 break;
4089 case 'X':
4090 if (ifthen_state)
4091 func (stream, "\t@ unpredictable <IT:%s>",
4092 arm_conditional[IFTHEN_COND]);
4093 break;
4095 case 'S':
4097 int32_t reg;
4099 reg = (given >> 3) & 0x7;
4100 if (given & (1 << 6))
4101 reg += 8;
4103 func (stream, "%s", arm_regnames[reg]);
4105 break;
4107 case 'D':
4109 int32_t reg;
4111 reg = given & 0x7;
4112 if (given & (1 << 7))
4113 reg += 8;
4115 func (stream, "%s", arm_regnames[reg]);
4117 break;
4119 case 'N':
4120 if (given & (1 << 8))
4121 domasklr = 1;
4122 /* Fall through. */
4123 case 'O':
4124 if (*c == 'O' && (given & (1 << 8)))
4125 domaskpc = 1;
4126 /* Fall through. */
4127 case 'M':
4129 int started = 0;
4130 int reg;
4132 func (stream, "{");
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)
4139 if (started)
4140 func (stream, ", ");
4141 started = 1;
4142 func (stream, "%s", arm_regnames[reg]);
4145 if (domasklr)
4147 if (started)
4148 func (stream, ", ");
4149 started = 1;
4150 func (stream, arm_regnames[14] /* "lr" */);
4153 if (domaskpc)
4155 if (started)
4156 func (stream, ", ");
4157 func (stream, arm_regnames[15] /* "pc" */);
4160 func (stream, "}");
4162 break;
4164 case 'b':
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);
4172 break;
4174 case 's':
4175 /* Right shift immediate -- bits 6..10; 1-31 print
4176 as themselves, 0 prints as 32. */
4178 int32_t imm = (given & 0x07c0) >> 6;
4179 if (imm == 0)
4180 imm = 32;
4181 func (stream, "#%ld", imm);
4183 break;
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';
4189 int bitend = 0;
4191 while (*c >= '0' && *c <= '9')
4192 bitstart = (bitstart * 10) + *c++ - '0';
4194 switch (*c)
4196 case '-':
4198 int32_t reg;
4200 c++;
4201 while (*c >= '0' && *c <= '9')
4202 bitend = (bitend * 10) + *c++ - '0';
4203 if (!bitend)
4204 abort ();
4205 reg = given >> bitstart;
4206 reg &= (2 << (bitend - bitstart)) - 1;
4207 switch (*c)
4209 case 'r':
4210 func (stream, "%s", arm_regnames[reg]);
4211 break;
4213 case 'R':
4214 func (stream, "%s", arm_regnames[reg]);
4215 c++;
4216 if ((given & (1 << reg)) == 0)
4217 func (stream, "%c", *c);
4218 break;
4220 case 'd':
4221 func (stream, "%ld", reg);
4222 break;
4224 case 'H':
4225 func (stream, "%ld", reg << 1);
4226 break;
4228 case 'W':
4229 func (stream, "%ld", reg << 2);
4230 break;
4232 case 'a':
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);
4238 break;
4240 case 'x':
4241 func (stream, "0x%04lx", reg);
4242 break;
4244 case 'B':
4245 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
4246 info->print_address_func (pc, reg * 2 + pc+4, info);
4247 break;
4249 case 'c':
4250 func (stream, "%s", arm_conditional [reg]);
4251 break;
4253 default:
4254 abort ();
4257 break;
4259 case '\'':
4260 c++;
4261 if ((given & (1 << bitstart)) != 0)
4262 func (stream, "%c", *c);
4263 break;
4265 case '?':
4266 ++c;
4267 if ((given & (1 << bitstart)) != 0)
4268 func (stream, "%c", *c++);
4269 else
4270 func (stream, "%c", *++c);
4271 break;
4273 default:
4274 abort ();
4277 break;
4279 default:
4280 abort ();
4283 return;
4286 /* No match. */
4287 abort ();
4290 /* Return the name of an V7M special register. */
4291 static const char *
4292 psr_name (int regno)
4294 switch (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. */
4316 static void
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))
4324 return;
4326 if (print_insn_neon (info, given, TRUE))
4327 return;
4329 for (insn = thumb32_opcodes; insn->assembler; insn++)
4330 if ((given & insn->mask) == insn->value)
4332 const char *c = insn->assembler;
4333 for (; *c; c++)
4335 if (*c != '%')
4337 func (stream, "%c", *c);
4338 continue;
4341 switch (*++c)
4343 case '%':
4344 func (stream, "%%");
4345 break;
4347 case 'c':
4348 if (ifthen_state)
4349 func (stream, "%s", arm_conditional[IFTHEN_COND]);
4350 break;
4352 case 'x':
4353 if (ifthen_next_state)
4354 func (stream, "\t@ unpredictable branch in IT block\n");
4355 break;
4357 case 'X':
4358 if (ifthen_state)
4359 func (stream, "\t@ unpredictable <IT:%s>",
4360 arm_conditional[IFTHEN_COND]);
4361 break;
4363 case 'I':
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);
4371 break;
4373 case 'M':
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;
4381 switch (mod)
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;
4387 default:
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);
4394 break;
4396 case 'J':
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);
4405 break;
4407 case 'K':
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);
4415 break;
4417 case 'S':
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]);
4426 switch (stp)
4428 case 0:
4429 if (imm > 0)
4430 func (stream, ", lsl #%u", imm);
4431 break;
4433 case 1:
4434 if (imm == 0)
4435 imm = 32;
4436 func (stream, ", lsr #%u", imm);
4437 break;
4439 case 2:
4440 if (imm == 0)
4441 imm = 32;
4442 func (stream, ", asr #%u", imm);
4443 break;
4445 case 3:
4446 if (imm == 0)
4447 func (stream, ", rrx");
4448 else
4449 func (stream, ", ror #%u", imm);
4452 break;
4454 case 'a':
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;
4462 int offset = 0;
4464 func (stream, "[%s", arm_regnames[Rn]);
4465 if (U) /* 12-bit positive immediate offset */
4466 offset = i12;
4467 else if (Rn == 15) /* 12-bit negative immediate offset */
4468 offset = -(int)i12;
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]);
4474 if (sh)
4475 func (stream, ", lsl #%u", sh);
4476 func (stream, "]");
4477 break;
4479 else switch (op)
4481 case 0xE: /* 8-bit positive immediate offset */
4482 offset = i8;
4483 break;
4485 case 0xC: /* 8-bit negative immediate offset */
4486 offset = -i8;
4487 break;
4489 case 0xF: /* 8-bit + preindex with wb */
4490 offset = i8;
4491 writeback = TRUE;
4492 break;
4494 case 0xD: /* 8-bit - preindex with wb */
4495 offset = -i8;
4496 writeback = TRUE;
4497 break;
4499 case 0xB: /* 8-bit + postindex */
4500 offset = i8;
4501 postind = TRUE;
4502 break;
4504 case 0x9: /* 8-bit - postindex */
4505 offset = -i8;
4506 postind = TRUE;
4507 break;
4509 default:
4510 func (stream, ", <undefined>]");
4511 goto skip;
4514 if (postind)
4515 func (stream, "], #%d", offset);
4516 else
4518 if (offset)
4519 func (stream, ", #%d", offset);
4520 func (stream, writeback ? "]!" : "]");
4523 if (Rn == 15)
4525 func (stream, "\t@ ");
4526 info->print_address_func(pc, ((pc+4) & ~3) +offset, info);
4529 skip:
4530 break;
4532 case 'A':
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]);
4541 if (P)
4543 if (off || !U)
4544 func (stream, ", #%c%u", U ? '+' : '-', off * 4);
4545 func (stream, "]");
4546 if (W)
4547 func (stream, "!");
4549 else
4551 func (stream, "], ");
4552 if (W)
4553 func (stream, "#%c%u", U ? '+' : '-', off * 4);
4554 else
4555 func (stream, "{%u}", off);
4558 break;
4560 case 'w':
4562 unsigned int Sbit = (given & 0x01000000) >> 24;
4563 unsigned int type = (given & 0x00600000) >> 21;
4564 switch (type)
4566 case 0: func (stream, Sbit ? "sb" : "b"); break;
4567 case 1: func (stream, Sbit ? "sh" : "h"); break;
4568 case 2:
4569 if (Sbit)
4570 func (stream, "??");
4571 break;
4572 case 3:
4573 func (stream, "??");
4574 break;
4577 break;
4579 case 'm':
4581 int started = 0;
4582 int reg;
4584 func (stream, "{");
4585 for (reg = 0; reg < 16; reg++)
4586 if ((given & (1 << reg)) != 0)
4588 if (started)
4589 func (stream, ", ");
4590 started = 1;
4591 func (stream, "%s", arm_regnames[reg]);
4593 func (stream, "}");
4595 break;
4597 case 'E':
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);
4605 break;
4607 case 'F':
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);
4615 break;
4617 case 'b':
4619 unsigned int S = (given & 0x04000000u) >> 26;
4620 unsigned int J1 = (given & 0x00002000u) >> 13;
4621 unsigned int J2 = (given & 0x00000800u) >> 11;
4622 int offset = 0;
4624 offset |= !S << 20;
4625 offset |= J2 << 19;
4626 offset |= J1 << 18;
4627 offset |= (given & 0x003f0000) >> 4;
4628 offset |= (given & 0x000007ff) << 1;
4629 offset -= (1 << 20);
4631 info->print_address_func (pc, pc + 4 + offset, info);
4633 break;
4635 case 'B':
4637 unsigned int S = (given & 0x04000000u) >> 26;
4638 unsigned int I1 = (given & 0x00002000u) >> 13;
4639 unsigned int I2 = (given & 0x00000800u) >> 11;
4640 int offset = 0;
4642 offset |= !S << 24;
4643 offset |= !(I1 ^ S) << 23;
4644 offset |= !(I2 ^ S) << 22;
4645 offset |= (given & 0x03ff0000u) >> 4;
4646 offset |= (given & 0x000007ffu) << 1;
4647 offset -= (1 << 24);
4648 offset += pc + 4;
4650 /* BLX target addresses are always word aligned. */
4651 if ((given & 0x00001000u) == 0)
4652 offset &= ~2u;
4654 info->print_address_func (pc, offset, info);
4656 break;
4658 case 's':
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);
4665 else if (shift)
4666 func (stream, ", lsl #%u", shift);
4667 /* else print nothing - lsl #0 */
4669 break;
4671 case 'R':
4673 unsigned int rot = (given & 0x00000030) >> 4;
4674 if (rot)
4675 func (stream, ", ror #%u", rot * 8);
4677 break;
4679 case 'U':
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;
4690 default:
4691 func(stream, "#%d", (int)given & 0xf);
4692 break;
4694 break;
4696 case 'C':
4697 if ((given & 0xff) == 0)
4699 func (stream, "%cPSR_", (given & 0x100000) ? 'S' : 'C');
4700 if (given & 0x800)
4701 func (stream, "f");
4702 if (given & 0x400)
4703 func (stream, "s");
4704 if (given & 0x200)
4705 func (stream, "x");
4706 if (given & 0x100)
4707 func (stream, "c");
4709 else
4711 func (stream, psr_name (given & 0xff));
4713 break;
4715 case 'D':
4716 if ((given & 0xff) == 0)
4717 func (stream, "%cPSR", (given & 0x100000) ? 'S' : 'C');
4718 else
4719 func (stream, psr_name (given & 0xff));
4720 break;
4722 case '0': case '1': case '2': case '3': case '4':
4723 case '5': case '6': case '7': case '8': case '9':
4725 int width;
4726 uint32_t val;
4728 c = arm_decode_bitfield (c, given, &val, &width);
4730 switch (*c)
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;
4736 case 'c':
4737 func (stream, "%s", arm_conditional[val]);
4738 break;
4740 case '\'':
4741 c++;
4742 if (val == ((1ul << width) - 1))
4743 func (stream, "%c", *c);
4744 break;
4746 case '`':
4747 c++;
4748 if (val == 0)
4749 func (stream, "%c", *c);
4750 break;
4752 case '?':
4753 func (stream, "%c", c[(1 << width) - (int)val]);
4754 c += 1 << width;
4755 break;
4757 default:
4758 abort ();
4761 break;
4763 default:
4764 abort ();
4767 return;
4770 /* No match. */
4771 abort ();
4774 /* Print data bytes on INFO->STREAM. */
4776 static void
4777 print_insn_data (bfd_vma pc ATTRIBUTE_UNUSED, struct disassemble_info *info,
4778 int32_t given)
4780 switch (info->bytes_per_chunk)
4782 case 1:
4783 info->fprintf_func (info->stream, ".byte\t0x%02lx", given);
4784 break;
4785 case 2:
4786 info->fprintf_func (info->stream, ".short\t0x%04lx", given);
4787 break;
4788 case 4:
4789 info->fprintf_func (info->stream, ".word\t0x%08lx", given);
4790 break;
4791 default:
4792 abort ();
4796 /* Search back through the insn stream to determine if this instruction is
4797 conditionally executed. */
4798 static void
4799 find_ifthen_state (bfd_vma pc, struct disassemble_info *info,
4800 bfd_boolean little)
4802 unsigned char b[2];
4803 unsigned int insn;
4804 int status;
4805 /* COUNT is twice the number of instructions seen. It will be odd if we
4806 just crossed an instruction boundary. */
4807 int count;
4808 int it_count;
4809 unsigned int seen_it;
4810 bfd_vma addr;
4812 ifthen_address = pc;
4813 ifthen_state = 0;
4815 addr = pc;
4816 count = 1;
4817 it_count = 0;
4818 seen_it = 0;
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. */
4822 for (;;)
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))
4829 break;
4831 return;
4833 addr -= 2;
4834 status = info->read_memory_func (addr, (bfd_byte *)b, 2, info);
4835 if (status)
4836 return;
4838 if (little)
4839 insn = (b[0]) | (b[1] << 8);
4840 else
4841 insn = (b[1]) | (b[0] << 8);
4842 if (seen_it)
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
4848 IT candidate. */
4849 if (count & 1)
4850 break;
4851 seen_it = 0;
4854 if ((insn & 0xff00) == 0xbf00 && (insn & 0xf) != 0)
4856 /* This could be an IT instruction. */
4857 seen_it = insn;
4858 it_count = count >> 1;
4860 if ((insn & 0xf800) >= 0xe800)
4861 count++;
4862 else
4863 count = (count + 2) | 1;
4864 /* IT blocks contain at most 4 instructions. */
4865 if (count >= 8 && !seen_it)
4866 return;
4868 /* We found an IT instruction. */
4869 ifthen_state = (seen_it & 0xe0) | ((seen_it << it_count) & 0x1f);
4870 if ((ifthen_state & 0xf) == 0)
4871 ifthen_state = 0;
4874 /* NOTE: There are no checks in these routines that
4875 the relevant number of data bytes exist. */
4877 static int
4878 print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
4880 unsigned char b[4];
4881 int32_t given;
4882 int status;
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;
4890 #ifdef NOTDEF
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)
4906 bfd_vma addr;
4907 int n;
4908 int last_sym = -1;
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);
4914 found = FALSE;
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]);
4925 if (addr > pc)
4926 break;
4927 if ((info->section == NULL
4928 || info->section == info->symtab[n]->section)
4929 && get_sym_code_type (info, n, &type))
4931 last_sym = n;
4932 found = TRUE;
4936 if (!found)
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. */
4944 for (; n >= 0; n--)
4946 if (get_sym_code_type (info, n, &type))
4948 last_sym = n;
4949 found = TRUE;
4950 break;
4955 last_mapping_sym = last_sym;
4956 last_type = type;
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
4963 print more. */
4964 if (is_data)
4966 size = 4 - (pc & 3);
4967 for (n = last_sym + 1; n < info->symtab_size; n++)
4969 addr = bfd_asymbol_value (info->symtab[n]);
4970 if (addr > pc)
4972 if (addr - pc < size)
4973 size = addr - pc;
4974 break;
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
4979 .byte or .short. */
4980 if (size == 3)
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
4999 && !found)
5001 /* If no mapping symbol has been found then fall back to the type
5002 of the function symbol. */
5003 elf_symbol_type * es;
5004 unsigned int type;
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);
5012 #endif /* NOTDEF */
5014 /* These are the ways otool(1) determines if we are in thumb mode */
5015 if (Bflag)
5016 force_thumb = TRUE;
5017 else
5018 set_thumb_mode(pc, info->nsorted_symbols, info->sorted_symbols, &in_thumb);
5020 if (force_thumb || in_thumb)
5021 is_thumb = TRUE;
5023 info->display_endian = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
5024 info->bytes_per_line = 4;
5026 if (is_data)
5028 int i;
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);
5035 given = 0;
5036 if (little)
5037 for (i = size - 1; i >= 0; i--)
5038 given = b[i] | (given << 8);
5039 else
5040 for (i = 0; i < (int) size; i++)
5041 given = b[i] | (given << 8);
5043 else if (!is_thumb)
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";
5049 dc = info->arm_dc;
5050 info->bytes_per_chunk = 4;
5051 size = 4;
5053 status = info->read_memory_func (pc, (bfd_byte *)b, 4, info);
5054 if (little)
5055 given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
5056 else
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)
5062 if(qflag)
5063 info->fprintf_func (info->stream, "\t");
5064 info->fprintf_func (info->stream, "%08x", (unsigned int) given);
5065 if(!qflag)
5066 info->fprintf_func (info->stream, "\t");
5069 else
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;
5079 size = 2;
5081 status = info->read_memory_func (pc, (bfd_byte *)b, 2, info);
5082 if (little)
5083 given = (b[0]) | (b[1] << 8);
5084 else
5085 given = (b[1]) | (b[0] << 8);
5087 if (!status)
5089 /* These bit patterns signal a four-byte Thumb
5090 instruction. */
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);
5096 if (little)
5097 given = (b[0]) | (b[1] << 8) | (given << 16);
5098 else
5099 given = (b[1]) | (b[0] << 8) | (given << 16);
5101 /* Print the raw data, too. */
5102 if(!Xflag && !gflag && !no_show_raw_insn)
5104 if(qflag)
5105 info->fprintf_func (info->stream, "\t");
5106 info->fprintf_func (info->stream, "%08x",
5107 (unsigned int) given);
5108 if(!qflag)
5109 info->fprintf_func (info->stream, "\t");
5111 printer = print_insn_thumb32;
5112 llvm_arch_name = "thumbv7";
5113 dc = info->thumb_dc;
5114 size = 4;
5116 else {
5117 /* Print the raw data, too. */
5118 if(!Xflag && !gflag && !no_show_raw_insn)
5120 if(qflag)
5121 info->fprintf_func (info->stream, "\t");
5122 info->fprintf_func (info->stream, " %04x",
5123 (unsigned int)given);
5124 if(!qflag)
5125 info->fprintf_func (info->stream, "\t");
5130 if (ifthen_address != pc)
5131 find_ifthen_state(pc, info, little);
5133 if (ifthen_state)
5135 if ((ifthen_state & 0xf) == 0x8)
5136 ifthen_next_state = 0;
5137 else
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. */
5149 pc = 0;
5151 if (qflag)
5153 char dst[4096];
5154 dst[4095] = '\0';
5156 #ifdef STATIC_LLVM
5157 LLVMDisasmInstruction
5158 #else
5159 llvm_disasm_instruction
5160 #endif
5161 (dc, (uint8_t *)info->sect, size, pc, dst, 4095) != 0){
5162 if(info->inst == NULL || info->inst->print)
5163 printf("%s", dst);
5165 else if(info->inst == NULL || info->inst->print){
5166 if (size == 4)
5167 info->fprintf_func (info->stream, "\t.long\t0x%08x", given);
5168 else if (size == 2)
5169 info->fprintf_func (info->stream, "\t.short\t0x%04x", given);
5170 else
5171 info->fprintf_func (info->stream, "\tinvalid instruction encoding");
5174 else
5175 printer (pc, info, given);
5177 if (is_thumb)
5179 ifthen_state = ifthen_next_state;
5180 ifthen_address += size;
5182 return 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.
5200 static
5201 void
5202 print_address_func(
5203 bfd_vma pc,
5204 bfd_vma addr,
5205 struct disassemble_info *info)
5207 int32_t i;
5208 const char *name;
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;
5218 if(info->verbose){
5219 /* If there's a relocation at this address, include the referenced
5220 symbol. */
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);
5233 return;
5238 /* No relocation entries found. */
5239 name = guess_symbol(addr, info->sorted_symbols, info->nsorted_symbols,
5240 TRUE);
5241 if(name && *name){
5242 fputs(name, stream);
5243 return;
5246 fprintf(stream, "0x%x", addr);
5247 if(info->verbose){
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);
5253 if(name != NULL)
5254 fprintf(stream, "\t@ symbol stub for: %s", name);
5255 else{
5256 uint64_t reference_type;
5257 reference_type = LLVMDisassembler_ReferenceType_In_PCrel_Load;
5258 name = guess_literal_pointer(addr, pc, &reference_type, info);
5259 if(name != NULL){
5260 fprintf(stream, " literal pool for: ");
5261 if(reference_type ==
5262 LLVMDisassembler_ReferenceType_Out_LitPool_CstrAddr)
5263 fprintf(stream, "\"%s\"", name);
5264 else
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.
5279 static
5280 enum bool
5281 print_immediate_func(
5282 bfd_vma pc,
5283 unsigned int value,
5284 struct disassemble_info *info,
5285 enum bool pool)
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;
5294 uint32_t n_strx;
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;
5304 r_symbolnum = 0;
5305 r_type = 0;
5306 r_extern = 0;
5307 r_value = 0;
5308 r_scattered = 0;
5309 other_half = 0;
5310 pair_r_value = 0;
5311 n_strx = 0;
5312 r_length = 0;
5314 if(info->verbose == FALSE && pool == FALSE){
5315 fprintf(stream, "#%u\t@ 0x%x", value, value);
5316 return(TRUE);
5318 reloc_found = 0;
5319 for(i = 0; i < nrelocs; i++){
5320 rp = &relocs[i];
5321 if(rp->r_address & R_SCATTERED){
5322 srp = (struct scattered_relocation_info *)rp;
5323 r_scattered = 1;
5324 r_address = srp->r_address;
5325 r_extern = 0;
5326 r_length = srp->r_length;
5327 r_type = srp->r_type;
5328 r_value = srp->r_value;
5330 else{
5331 r_scattered = 0;
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 "
5340 "%u\n", i);
5341 continue;
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){
5348 if(i+1 < nrelocs){
5349 pairp = &rp[1];
5350 if(pairp->r_address & R_SCATTERED){
5351 spairp = (struct scattered_relocation_info *)
5352 pairp;
5353 other_half = spairp->r_address & 0xffff;
5354 pair_r_type = spairp->r_type;
5355 pair_r_value = spairp->r_value;
5357 else{
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);
5364 continue;
5368 reloc_found = 1;
5369 break;
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){
5375 if(i+1 < nrelocs){
5376 pairp = &rp[1];
5377 if(pairp->r_address & R_SCATTERED){
5378 spairp = (struct scattered_relocation_info *)pairp;
5379 pair_r_type = spairp->r_type;
5381 else{
5382 pair_r_type = pairp->r_type;
5384 if(pair_r_type == ARM_RELOC_PAIR)
5385 i++;
5386 else
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.
5398 if(pool){
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){
5403 if(qflag)
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);
5421 if(add != NULL)
5422 fprintf(stream, "%s", add);
5423 else
5424 fprintf(stream, "0x%x", (unsigned int)r_value);
5425 if(sub != NULL)
5426 fprintf(stream, "-(%s", sub);
5427 else
5428 fprintf(stream, "-(0x%x", (unsigned int)pair_r_value);
5429 if(offset != 0)
5430 fprintf(stream, "+0x%x)", (unsigned int)offset);
5431 fprintf(stream, "\n");
5432 /* return indicating we printed something */
5433 return(TRUE);
5435 /* return indicating we printed nothing */
5436 return(FALSE);
5439 if(reloc_found && r_extern == 1){
5440 if(symbols != NULL)
5441 n_strx = symbols[r_symbolnum].n_un.n_strx;
5442 if(n_strx >= strings_size)
5443 name = "bad string offset";
5444 else
5445 name = strings + n_strx;
5446 if(value != 0){
5447 switch(r_type){
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);
5454 else{
5455 value = other_half << 16 | value;
5456 fprintf(stream, ":lower16:%s+0x%x", name,
5457 (unsigned int)value);
5459 break;
5460 default:
5461 fprintf(stream, "%s+0x%x", name, (unsigned int)value);
5462 break;
5465 else{
5466 switch(r_type){
5467 case ARM_RELOC_HALF:
5468 if((r_length & 0x1) == 1){
5469 value = value << 16 | other_half;
5470 if(value == 0)
5471 fprintf(stream, ":upper16:%s", name);
5472 else
5473 fprintf(stream, ":upper16:%s+0x%x", name,
5474 (unsigned int)value);
5476 else{
5477 value = other_half << 16 | value;
5478 if(value == 0)
5479 fprintf(stream, ":lower16:%s", name);
5480 else
5481 fprintf(stream, ":lower16:%s+0x%x", name,
5482 (unsigned int)value);
5484 break;
5485 default:
5486 if(value == 0)
5487 fprintf(stream, "%s", name);
5488 else
5489 fprintf(stream, "%s+0x%x", name, (unsigned int)value);
5492 return(TRUE);
5495 offset = 0;
5496 if(reloc_found){
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;
5501 else
5502 value = other_half << 16 | value;
5504 if(r_scattered &&
5505 (r_type != ARM_RELOC_HALF &&
5506 r_type != ARM_RELOC_HALF_SECTDIFF)){
5507 offset = value - r_value;
5508 value = r_value;
5512 if(reloc_found && r_type == ARM_RELOC_HALF_SECTDIFF){
5513 if((r_length & 0x1) == 1)
5514 fprintf(stream, ":upper16:");
5515 else
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);
5522 if(add != NULL)
5523 fprintf(stream, "%s", add);
5524 else
5525 fprintf(stream, "0x%x", (unsigned int)r_value);
5526 if(sub != NULL)
5527 fprintf(stream, "-%s", sub);
5528 else
5529 fprintf(stream, "-0x%x", (unsigned int)pair_r_value);
5530 if(offset != 0)
5531 fprintf(stream, "+0x%x", (unsigned int)offset);
5532 return(TRUE);
5535 low = 0;
5536 high = info->nsorted_symbols - 1;
5537 mid = (high - low) / 2;
5538 while(high >= low){
5539 if(info->sorted_symbols[mid].n_value == value){
5540 if(reloc_found){
5541 switch(r_type){
5542 case ARM_RELOC_HALF:
5543 if((r_length & 0x1) == 1){
5544 if(offset == 0)
5545 fprintf(stream, ":upper16:%s",
5546 info->sorted_symbols[mid].name);
5547 else
5548 fprintf(stream, ":upper16:%s+0x%x",
5549 info->sorted_symbols[mid].name,
5550 (unsigned int)offset);
5552 else{
5553 if(offset == 0)
5554 fprintf(stream, ":lower16:%s",
5555 info->sorted_symbols[mid].name);
5556 else
5557 fprintf(stream, ":lower16:%s+0x%x",
5558 info->sorted_symbols[mid].name,
5559 (unsigned int)offset);
5561 break;
5562 default:
5563 if(offset == 0)
5564 fprintf(stream,"%s",info->sorted_symbols[mid].name);
5565 else
5566 fprintf(stream, "%s+0x%x",
5567 info->sorted_symbols[mid].name,
5568 (unsigned int)offset);
5569 break;
5572 else{
5573 if(offset == 0)
5574 fprintf(stream, "%s",info->sorted_symbols[mid].name);
5575 else
5576 fprintf(stream, "%s+0x%x",
5577 info->sorted_symbols[mid].name,
5578 (unsigned int)offset);
5580 return(TRUE);
5582 if(info->sorted_symbols[mid].n_value > value){
5583 high = mid - 1;
5584 mid = (high + low) / 2;
5586 else{
5587 low = mid + 1;
5588 mid = (high + low) / 2;
5591 if(offset == 0){
5592 if(reloc_found){
5593 if(r_type == ARM_RELOC_HALF){
5594 if((r_length & 0x1) == 1)
5595 fprintf(stream, ":upper16:0x%x", (unsigned int)value);
5596 else
5597 fprintf(stream, ":lower16:0x%x", (unsigned int)value);
5599 else
5600 fprintf(stream, "0x%x", (unsigned int)value);
5602 else
5603 fprintf(stream, "0x%x", (unsigned int)value);
5605 else{
5606 if(reloc_found){
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);
5611 else
5612 fprintf(stream, ":lower16:0x%x+0x%x)",
5613 (unsigned int)value, (unsigned int)offset);
5615 else
5616 fprintf(stream, "0x%x+0x%x",
5617 (unsigned int)value, (unsigned int)offset);
5619 else
5620 fprintf(stream, "0x%x+0x%x",
5621 (unsigned int)value, (unsigned int)offset);
5623 return(TRUE);
5627 * Print the section contents pointed to by sect as data .long, .short or .byte
5628 * depending on its kind.
5630 static
5631 uint32_t
5632 print_data_in_code(
5633 char *sect,
5634 uint32_t sect_left,
5635 uint32_t dice_left,
5636 uint16_t kind)
5638 uint32_t value, left, size;
5640 left = dice_left;
5641 if(left > sect_left)
5642 left = sect_left;
5643 switch(kind){
5644 default:
5645 case DICE_KIND_DATA:
5646 if(left >= 4){
5647 value = sect[3] << 24 |
5648 sect[2] << 16 |
5649 sect[1] << 8 |
5650 sect[0];
5651 if(!Xflag && !gflag && !no_show_raw_insn)
5652 printf("\t%08x", value);
5653 printf("\t.long %u\t@ ", value);
5654 size = 4;
5656 else if(left >= 2){
5657 value = sect[1] << 8 |
5658 sect[0];
5659 if(!Xflag && !gflag && !no_show_raw_insn)
5660 printf("\t %04x", value);
5661 printf("\t.short %u\t@ ", value);
5662 size = 2;
5664 else {
5665 value = sect[0];
5666 if(!Xflag && !gflag && !no_show_raw_insn)
5667 printf("\t %02x", value & 0xff);
5668 printf("\t.byte %u\t@ ", value & 0xff);
5669 size = 1;
5671 if(kind == DICE_KIND_DATA)
5672 printf("KIND_DATA\n");
5673 else
5674 printf("kind = %u\n", kind);
5675 return(size);
5676 case DICE_KIND_JUMP_TABLE8:
5677 value = sect[0];
5678 if(!Xflag && !gflag && !no_show_raw_insn)
5679 printf("\t %02x", value);
5680 printf("\t.byte %3u\t@ KIND_JUMP_TABLE8\n", value);
5681 return(1);
5682 case DICE_KIND_JUMP_TABLE16:
5683 value = sect[1] << 8 |
5684 sect[0];
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);
5688 return(2);
5689 case DICE_KIND_JUMP_TABLE32:
5690 case DICE_KIND_ABS_JUMP_TABLE32:
5691 value = sect[3] << 24 |
5692 sect[2] << 16 |
5693 sect[1] << 8 |
5694 sect[0];
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");
5700 else
5701 printf("KIND_ABS_JUMP_TABLE32\n");
5702 return(4);
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. */
5714 static
5716 symbol_at_address_func(
5717 bfd_vma addr,
5718 struct disassemble_info * info)
5721 printf("Unexpected call to stubbed out symbol_at_address_func() "
5722 " addr = 0x%x\n", addr);
5724 return(0);
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. */
5732 static
5733 int
5734 read_memory_func(
5735 bfd_vma memaddr,
5736 bfd_byte *myaddr,
5737 unsigned int length,
5738 struct disassemble_info *info)
5740 if(info->addr > memaddr)
5741 return(1);
5743 if(info->left >= length + (memaddr - info->addr)){
5744 memcpy(myaddr, info->sect + (memaddr - info->addr), length);
5745 return(0);
5747 else{
5748 memcpy(myaddr, info->sect + (memaddr - info->addr), info->left);
5749 return(1);
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. */
5758 static
5759 void memory_error_func(
5760 int status,
5761 bfd_vma memaddr,
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.
5771 uint32_t
5772 arm_disassemble(
5773 char *sect,
5774 uint32_t left,
5775 uint32_t addr,
5776 uint32_t sect_addr,
5777 enum byte_sex object_byte_sex,
5778 struct relocation_info *relocs,
5779 uint32_t nrelocs,
5780 struct nlist *symbols,
5781 uint32_t nsymbols,
5782 struct symbol *sorted_symbols,
5783 uint32_t nsorted_symbols,
5784 char *strings,
5785 uint32_t strings_size,
5786 uint32_t *indirect_symbols,
5787 uint32_t nindirect_symbols,
5788 struct load_command *load_commands,
5789 uint32_t ncmds,
5790 uint32_t sizeofcmds,
5791 cpu_subtype_t cpusubtype,
5792 enum bool verbose,
5793 LLVMDisasmContextRef arm_dc,
5794 LLVMDisasmContextRef thumb_dc,
5795 char *object_addr,
5796 uint32_t object_size,
5797 struct data_in_code_entry *dices,
5798 uint32_t ndices,
5799 uint64_t seg_addr,
5800 struct inst *inst,
5801 struct inst *insts,
5802 uint32_t ninsts)
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;
5811 dis_info.mach = 0;
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;
5818 dis_info.flags = 0;
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
5859 * 4 bytes.
5861 if(left >= 4){
5862 pool_value = sect[3] << 24 |
5863 sect[2] << 16 |
5864 sect[1] << 8 |
5865 sect[0];
5866 if(print_immediate_func(addr, pool_value, &dis_info, TRUE) == TRUE)
5867 return(4);
5871 * See if this address is has a data in code entry and if so print.
5873 if(ndices){
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;
5878 else
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,
5885 dices[i].kind);
5886 if ((dices[i].kind == DICE_KIND_JUMP_TABLE8) &&
5887 (offset == (dices[i].offset + dices[i].length - 1)) &&
5888 (dices[i].length & 1)) {
5889 ++bytes_consumed;
5891 return(bytes_consumed);
5896 bytes_consumed = print_insn_little_arm(addr, &dis_info);
5897 if(!gflag || (inst != NULL && inst->print == TRUE))
5898 printf("\n");
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.
5908 static void
5909 set_thumb_mode(
5910 uint32_t addr,
5911 uint32_t nsorted_symbols,
5912 struct symbol *sorted_symbols,
5913 enum bool *in_thumb)
5915 int32_t high, low, mid;
5917 low = 0;
5918 high = nsorted_symbols - 1;
5919 mid = (high - low) / 2;
5920 while(high >= low){
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){
5924 mid--;
5927 if(sorted_symbols[mid].is_thumb){
5928 *in_thumb = TRUE;
5929 return;
5931 mid++;
5932 if(mid > nsorted_symbols ||
5933 sorted_symbols[mid].n_value != addr){
5934 *in_thumb = FALSE;
5935 return;
5937 } while(1);
5939 if(sorted_symbols[mid].n_value > addr){
5940 high = mid - 1;
5941 mid = (high + low) / 2;
5943 else{
5944 low = mid + 1;
5945 mid = (high + low) / 2;