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) 6 7 This file is part of libopcodes. 8 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. 13 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. 18 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, USA. */ 22 23#include "sysdep.h" 24 25#include "dis-asm.h" 26#include "opcode/arm.h" 27#include "opintl.h" 28#include "safe-ctype.h" 29#include "floatformat.h" 30 31/* FIXME: This shouldn't be done here. */ 32#include "coff/internal.h" 33#include "libcoff.h" 34#include "elf-bfd.h" 35#include "elf/internal.h" 36#include "elf/arm.h" 37 38/* FIXME: Belongs in global header. */ 39#ifndef strneq 40#define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0) 41#endif 42 43#ifndef NUM_ELEM 44#define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0]) 45#endif 46 47struct opcode32 48{ 49 unsigned long arch; /* Architecture defining this insn. */ 50 unsigned long value, mask; /* Recognise insn if (op&mask)==value. */ 51 const char *assembler; /* How to disassemble this insn. */ 52}; 53 54struct opcode16 55{ 56 unsigned long arch; /* Architecture defining this insn. */ 57 unsigned short value, mask; /* Recognise insn if (op&mask)==value. */ 58 const char *assembler; /* How to disassemble this insn. */ 59}; 60 61/* print_insn_coprocessor recognizes the following format control codes: 62 63 %% % 64 65 %c print condition code (always bits 28-31 in ARM mode) 66 %q print shifter argument 67 %u print condition code (unconditional in ARM mode) 68 %A print address for ldc/stc/ldf/stf instruction 69 %B print vstm/vldm register list 70 %C print vstr/vldr address operand 71 %I print cirrus signed shift immediate: bits 0..3|4..6 72 %F print the COUNT field of a LFM/SFM instruction. 73 %P print floating point precision in arithmetic insn 74 %Q print floating point precision in ldf/stf insn 75 %R print floating point rounding mode 76 77 %<bitfield>r print as an ARM register 78 %<bitfield>d print the bitfield in decimal 79 %<bitfield>k print immediate for VFPv3 conversion instruction 80 %<bitfield>x print the bitfield in hex 81 %<bitfield>X print the bitfield as 1 hex digit without leading "0x" 82 %<bitfield>f print a floating point constant if >7 else a 83 floating point register 84 %<bitfield>w print as an iWMMXt width field - [bhwd]ss/us 85 %<bitfield>g print as an iWMMXt 64-bit register 86 %<bitfield>G print as an iWMMXt general purpose or control register 87 %<bitfield>D print as a NEON D register 88 %<bitfield>Q print as a NEON Q register 89 90 %y<code> print a single precision VFP reg. 91 Codes: 0=>Sm, 1=>Sd, 2=>Sn, 3=>multi-list, 4=>Sm pair 92 %z<code> print a double precision VFP reg 93 Codes: 0=>Dm, 1=>Dd, 2=>Dn, 3=>multi-list 94 95 %<bitfield>'c print specified char iff bitfield is all ones 96 %<bitfield>`c print specified char iff bitfield is all zeroes 97 %<bitfield>?ab... select from array of values in big endian order 98 99 %L print as an iWMMXt N/M width field. 100 %Z print the Immediate of a WSHUFH instruction. 101 %l like 'A' except use byte offsets for 'B' & 'H' 102 versions. 103 %i print 5-bit immediate in bits 8,3..0 104 (print "32" when 0) 105 %r print register offset address for wldt/wstr instruction 106*/ 107 108/* Common coprocessor opcodes shared between Arm and Thumb-2. */ 109 110static const struct opcode32 coprocessor_opcodes[] = 111{ 112 /* XScale instructions. */ 113 {ARM_CEXT_XSCALE, 0x0e200010, 0x0fff0ff0, "mia%c\tacc0, %0-3r, %12-15r"}, 114 {ARM_CEXT_XSCALE, 0x0e280010, 0x0fff0ff0, "miaph%c\tacc0, %0-3r, %12-15r"}, 115 {ARM_CEXT_XSCALE, 0x0e2c0010, 0x0ffc0ff0, "mia%17'T%17`B%16'T%16`B%c\tacc0, %0-3r, %12-15r"}, 116 {ARM_CEXT_XSCALE, 0x0c400000, 0x0ff00fff, "mar%c\tacc0, %12-15r, %16-19r"}, 117 {ARM_CEXT_XSCALE, 0x0c500000, 0x0ff00fff, "mra%c\t%12-15r, %16-19r, acc0"}, 118 119 /* Intel Wireless MMX technology instructions. */ 120#define FIRST_IWMMXT_INSN 0x0e130130 121#define IWMMXT_INSN_COUNT 73 122 {ARM_CEXT_IWMMXT, 0x0e130130, 0x0f3f0fff, "tandc%22-23w%c\t%12-15r"}, 123 {ARM_CEXT_XSCALE, 0x0e400010, 0x0ff00f3f, "tbcst%6-7w%c\t%16-19g, %12-15r"}, 124 {ARM_CEXT_XSCALE, 0x0e130170, 0x0f3f0ff8, "textrc%22-23w%c\t%12-15r, #%0-2d"}, 125 {ARM_CEXT_XSCALE, 0x0e100070, 0x0f300ff0, "textrm%3?su%22-23w%c\t%12-15r, %16-19g, #%0-2d"}, 126 {ARM_CEXT_XSCALE, 0x0e600010, 0x0ff00f38, "tinsr%6-7w%c\t%16-19g, %12-15r, #%0-2d"}, 127 {ARM_CEXT_XSCALE, 0x0e000110, 0x0ff00fff, "tmcr%c\t%16-19G, %12-15r"}, 128 {ARM_CEXT_XSCALE, 0x0c400000, 0x0ff00ff0, "tmcrr%c\t%0-3g, %12-15r, %16-19r"}, 129 {ARM_CEXT_XSCALE, 0x0e2c0010, 0x0ffc0e10, "tmia%17?tb%16?tb%c\t%5-8g, %0-3r, %12-15r"}, 130 {ARM_CEXT_XSCALE, 0x0e200010, 0x0fff0e10, "tmia%c\t%5-8g, %0-3r, %12-15r"}, 131 {ARM_CEXT_XSCALE, 0x0e280010, 0x0fff0e10, "tmiaph%c\t%5-8g, %0-3r, %12-15r"}, 132 {ARM_CEXT_XSCALE, 0x0e100030, 0x0f300fff, "tmovmsk%22-23w%c\t%12-15r, %16-19g"}, 133 {ARM_CEXT_XSCALE, 0x0e100110, 0x0ff00ff0, "tmrc%c\t%12-15r, %16-19G"}, 134 {ARM_CEXT_XSCALE, 0x0c500000, 0x0ff00ff0, "tmrrc%c\t%12-15r, %16-19r, %0-3g"}, 135 {ARM_CEXT_XSCALE, 0x0e130150, 0x0f3f0fff, "torc%22-23w%c\t%12-15r"}, 136 {ARM_CEXT_XSCALE, 0x0e130190, 0x0f3f0fff, "torvsc%22-23w%c\t%12-15r"}, 137 {ARM_CEXT_XSCALE, 0x0e2001c0, 0x0f300fff, "wabs%22-23w%c\t%12-15g, %16-19g"}, 138 {ARM_CEXT_XSCALE, 0x0e0001c0, 0x0f300fff, "wacc%22-23w%c\t%12-15g, %16-19g"}, 139 {ARM_CEXT_XSCALE, 0x0e000180, 0x0f000ff0, "wadd%20-23w%c\t%12-15g, %16-19g, %0-3g"}, 140 {ARM_CEXT_XSCALE, 0x0e2001a0, 0x0f300ff0, "waddbhus%22?ml%c\t%12-15g, %16-19g, %0-3g"}, 141 {ARM_CEXT_XSCALE, 0x0ea001a0, 0x0ff00ff0, "waddsubhx%c\t%12-15g, %16-19g, %0-3g"}, 142 {ARM_CEXT_XSCALE, 0x0e000020, 0x0f800ff0, "waligni%c\t%12-15g, %16-19g, %0-3g, #%20-22d"}, 143 {ARM_CEXT_XSCALE, 0x0e800020, 0x0fc00ff0, "walignr%20-21d%c\t%12-15g, %16-19g, %0-3g"}, 144 {ARM_CEXT_XSCALE, 0x0e200000, 0x0fe00ff0, "wand%20'n%c\t%12-15g, %16-19g, %0-3g"}, 145 {ARM_CEXT_XSCALE, 0x0e800000, 0x0fa00ff0, "wavg2%22?hb%20'r%c\t%12-15g, %16-19g, %0-3g"}, 146 {ARM_CEXT_XSCALE, 0x0e400000, 0x0fe00ff0, "wavg4%20'r%c\t%12-15g, %16-19g, %0-3g"}, 147 {ARM_CEXT_XSCALE, 0x0e000060, 0x0f300ff0, "wcmpeq%22-23w%c\t%12-15g, %16-19g, %0-3g"}, 148 {ARM_CEXT_XSCALE, 0x0e100060, 0x0f100ff0, "wcmpgt%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"}, 149 {ARM_CEXT_XSCALE, 0xfc500100, 0xfe500f00, "wldrd\t%12-15g, %r"}, 150 {ARM_CEXT_XSCALE, 0xfc100100, 0xfe500f00, "wldrw\t%12-15G, %A"}, 151 {ARM_CEXT_XSCALE, 0x0c100000, 0x0e100e00, "wldr%L%c\t%12-15g, %l"}, 152 {ARM_CEXT_XSCALE, 0x0e400100, 0x0fc00ff0, "wmac%21?su%20'z%c\t%12-15g, %16-19g, %0-3g"}, 153 {ARM_CEXT_XSCALE, 0x0e800100, 0x0fc00ff0, "wmadd%21?su%20'x%c\t%12-15g, %16-19g, %0-3g"}, 154 {ARM_CEXT_XSCALE, 0x0ec00100, 0x0fd00ff0, "wmadd%21?sun%c\t%12-15g, %16-19g, %0-3g"}, 155 {ARM_CEXT_XSCALE, 0x0e000160, 0x0f100ff0, "wmax%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"}, 156 {ARM_CEXT_XSCALE, 0x0e000080, 0x0f100fe0, "wmerge%c\t%12-15g, %16-19g, %0-3g, #%21-23d"}, 157 {ARM_CEXT_XSCALE, 0x0e0000a0, 0x0f800ff0, "wmia%21?tb%20?tb%22'n%c\t%12-15g, %16-19g, %0-3g"}, 158 {ARM_CEXT_XSCALE, 0x0e800120, 0x0f800ff0, "wmiaw%21?tb%20?tb%22'n%c\t%12-15g, %16-19g, %0-3g"}, 159 {ARM_CEXT_XSCALE, 0x0e100160, 0x0f100ff0, "wmin%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"}, 160 {ARM_CEXT_XSCALE, 0x0e000100, 0x0fc00ff0, "wmul%21?su%20?ml%23'r%c\t%12-15g, %16-19g, %0-3g"}, 161 {ARM_CEXT_XSCALE, 0x0ed00100, 0x0fd00ff0, "wmul%21?sumr%c\t%12-15g, %16-19g, %0-3g"}, 162 {ARM_CEXT_XSCALE, 0x0ee000c0, 0x0fe00ff0, "wmulwsm%20`r%c\t%12-15g, %16-19g, %0-3g"}, 163 {ARM_CEXT_XSCALE, 0x0ec000c0, 0x0fe00ff0, "wmulwum%20`r%c\t%12-15g, %16-19g, %0-3g"}, 164 {ARM_CEXT_XSCALE, 0x0eb000c0, 0x0ff00ff0, "wmulwl%c\t%12-15g, %16-19g, %0-3g"}, 165 {ARM_CEXT_XSCALE, 0x0e8000a0, 0x0f800ff0, "wqmia%21?tb%20?tb%22'n%c\t%12-15g, %16-19g, %0-3g"}, 166 {ARM_CEXT_XSCALE, 0x0e100080, 0x0fd00ff0, "wqmulm%21'r%c\t%12-15g, %16-19g, %0-3g"}, 167 {ARM_CEXT_XSCALE, 0x0ec000e0, 0x0fd00ff0, "wqmulwm%21'r%c\t%12-15g, %16-19g, %0-3g"}, 168 {ARM_CEXT_XSCALE, 0x0e000000, 0x0ff00ff0, "wor%c\t%12-15g, %16-19g, %0-3g"}, 169 {ARM_CEXT_XSCALE, 0x0e000080, 0x0f000ff0, "wpack%20-23w%c\t%12-15g, %16-19g, %0-3g"}, 170 {ARM_CEXT_XSCALE, 0xfe300040, 0xff300ef0, "wror%22-23w\t%12-15g, %16-19g, #%i"}, 171 {ARM_CEXT_XSCALE, 0x0e300040, 0x0f300ff0, "wror%22-23w%c\t%12-15g, %16-19g, %0-3g"}, 172 {ARM_CEXT_XSCALE, 0x0e300140, 0x0f300ff0, "wror%22-23wg%c\t%12-15g, %16-19g, %0-3G"}, 173 {ARM_CEXT_XSCALE, 0x0e000120, 0x0fa00ff0, "wsad%22?hb%20'z%c\t%12-15g, %16-19g, %0-3g"}, 174 {ARM_CEXT_XSCALE, 0x0e0001e0, 0x0f000ff0, "wshufh%c\t%12-15g, %16-19g, #%Z"}, 175 {ARM_CEXT_XSCALE, 0xfe100040, 0xff300ef0, "wsll%22-23w\t%12-15g, %16-19g, #%i"}, 176 {ARM_CEXT_XSCALE, 0x0e100040, 0x0f300ff0, "wsll%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"}, 177 {ARM_CEXT_XSCALE, 0x0e100148, 0x0f300ffc, "wsll%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"}, 178 {ARM_CEXT_XSCALE, 0xfe000040, 0xff300ef0, "wsra%22-23w\t%12-15g, %16-19g, #%i"}, 179 {ARM_CEXT_XSCALE, 0x0e000040, 0x0f300ff0, "wsra%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"}, 180 {ARM_CEXT_XSCALE, 0x0e000148, 0x0f300ffc, "wsra%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"}, 181 {ARM_CEXT_XSCALE, 0xfe200040, 0xff300ef0, "wsrl%22-23w\t%12-15g, %16-19g, #%i"}, 182 {ARM_CEXT_XSCALE, 0x0e200040, 0x0f300ff0, "wsrl%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"}, 183 {ARM_CEXT_XSCALE, 0x0e200148, 0x0f300ffc, "wsrl%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"}, 184 {ARM_CEXT_XSCALE, 0xfc400100, 0xfe500f00, "wstrd\t%12-15g, %r"}, 185 {ARM_CEXT_XSCALE, 0xfc000100, 0xfe500f00, "wstrw\t%12-15G, %A"}, 186 {ARM_CEXT_XSCALE, 0x0c000000, 0x0e100e00, "wstr%L%c\t%12-15g, %l"}, 187 {ARM_CEXT_XSCALE, 0x0e0001a0, 0x0f000ff0, "wsub%20-23w%c\t%12-15g, %16-19g, %0-3g"}, 188 {ARM_CEXT_XSCALE, 0x0ed001c0, 0x0ff00ff0, "wsubaddhx%c\t%12-15g, %16-19g, %0-3g"}, 189 {ARM_CEXT_XSCALE, 0x0e1001c0, 0x0f300ff0, "wabsdiff%22-23w%c\t%12-15g, %16-19g, %0-3g"}, 190 {ARM_CEXT_XSCALE, 0x0e0000c0, 0x0fd00fff, "wunpckeh%21?sub%c\t%12-15g, %16-19g"}, 191 {ARM_CEXT_XSCALE, 0x0e4000c0, 0x0fd00fff, "wunpckeh%21?suh%c\t%12-15g, %16-19g"}, 192 {ARM_CEXT_XSCALE, 0x0e8000c0, 0x0fd00fff, "wunpckeh%21?suw%c\t%12-15g, %16-19g"}, 193 {ARM_CEXT_XSCALE, 0x0e0000e0, 0x0f100fff, "wunpckel%21?su%22-23w%c\t%12-15g, %16-19g"}, 194 {ARM_CEXT_XSCALE, 0x0e1000c0, 0x0f300ff0, "wunpckih%22-23w%c\t%12-15g, %16-19g, %0-3g"}, 195 {ARM_CEXT_XSCALE, 0x0e1000e0, 0x0f300ff0, "wunpckil%22-23w%c\t%12-15g, %16-19g, %0-3g"}, 196 {ARM_CEXT_XSCALE, 0x0e100000, 0x0ff00ff0, "wxor%c\t%12-15g, %16-19g, %0-3g"}, 197 198 /* Floating point coprocessor (FPA) instructions */ 199 {FPU_FPA_EXT_V1, 0x0e000100, 0x0ff08f10, "adf%c%P%R\t%12-14f, %16-18f, %0-3f"}, 200 {FPU_FPA_EXT_V1, 0x0e100100, 0x0ff08f10, "muf%c%P%R\t%12-14f, %16-18f, %0-3f"}, 201 {FPU_FPA_EXT_V1, 0x0e200100, 0x0ff08f10, "suf%c%P%R\t%12-14f, %16-18f, %0-3f"}, 202 {FPU_FPA_EXT_V1, 0x0e300100, 0x0ff08f10, "rsf%c%P%R\t%12-14f, %16-18f, %0-3f"}, 203 {FPU_FPA_EXT_V1, 0x0e400100, 0x0ff08f10, "dvf%c%P%R\t%12-14f, %16-18f, %0-3f"}, 204 {FPU_FPA_EXT_V1, 0x0e500100, 0x0ff08f10, "rdf%c%P%R\t%12-14f, %16-18f, %0-3f"}, 205 {FPU_FPA_EXT_V1, 0x0e600100, 0x0ff08f10, "pow%c%P%R\t%12-14f, %16-18f, %0-3f"}, 206 {FPU_FPA_EXT_V1, 0x0e700100, 0x0ff08f10, "rpw%c%P%R\t%12-14f, %16-18f, %0-3f"}, 207 {FPU_FPA_EXT_V1, 0x0e800100, 0x0ff08f10, "rmf%c%P%R\t%12-14f, %16-18f, %0-3f"}, 208 {FPU_FPA_EXT_V1, 0x0e900100, 0x0ff08f10, "fml%c%P%R\t%12-14f, %16-18f, %0-3f"}, 209 {FPU_FPA_EXT_V1, 0x0ea00100, 0x0ff08f10, "fdv%c%P%R\t%12-14f, %16-18f, %0-3f"}, 210 {FPU_FPA_EXT_V1, 0x0eb00100, 0x0ff08f10, "frd%c%P%R\t%12-14f, %16-18f, %0-3f"}, 211 {FPU_FPA_EXT_V1, 0x0ec00100, 0x0ff08f10, "pol%c%P%R\t%12-14f, %16-18f, %0-3f"}, 212 {FPU_FPA_EXT_V1, 0x0e008100, 0x0ff08f10, "mvf%c%P%R\t%12-14f, %0-3f"}, 213 {FPU_FPA_EXT_V1, 0x0e108100, 0x0ff08f10, "mnf%c%P%R\t%12-14f, %0-3f"}, 214 {FPU_FPA_EXT_V1, 0x0e208100, 0x0ff08f10, "abs%c%P%R\t%12-14f, %0-3f"}, 215 {FPU_FPA_EXT_V1, 0x0e308100, 0x0ff08f10, "rnd%c%P%R\t%12-14f, %0-3f"}, 216 {FPU_FPA_EXT_V1, 0x0e408100, 0x0ff08f10, "sqt%c%P%R\t%12-14f, %0-3f"}, 217 {FPU_FPA_EXT_V1, 0x0e508100, 0x0ff08f10, "log%c%P%R\t%12-14f, %0-3f"}, 218 {FPU_FPA_EXT_V1, 0x0e608100, 0x0ff08f10, "lgn%c%P%R\t%12-14f, %0-3f"}, 219 {FPU_FPA_EXT_V1, 0x0e708100, 0x0ff08f10, "exp%c%P%R\t%12-14f, %0-3f"}, 220 {FPU_FPA_EXT_V1, 0x0e808100, 0x0ff08f10, "sin%c%P%R\t%12-14f, %0-3f"}, 221 {FPU_FPA_EXT_V1, 0x0e908100, 0x0ff08f10, "cos%c%P%R\t%12-14f, %0-3f"}, 222 {FPU_FPA_EXT_V1, 0x0ea08100, 0x0ff08f10, "tan%c%P%R\t%12-14f, %0-3f"}, 223 {FPU_FPA_EXT_V1, 0x0eb08100, 0x0ff08f10, "asn%c%P%R\t%12-14f, %0-3f"}, 224 {FPU_FPA_EXT_V1, 0x0ec08100, 0x0ff08f10, "acs%c%P%R\t%12-14f, %0-3f"}, 225 {FPU_FPA_EXT_V1, 0x0ed08100, 0x0ff08f10, "atn%c%P%R\t%12-14f, %0-3f"}, 226 {FPU_FPA_EXT_V1, 0x0ee08100, 0x0ff08f10, "urd%c%P%R\t%12-14f, %0-3f"}, 227 {FPU_FPA_EXT_V1, 0x0ef08100, 0x0ff08f10, "nrm%c%P%R\t%12-14f, %0-3f"}, 228 {FPU_FPA_EXT_V1, 0x0e000110, 0x0ff00f1f, "flt%c%P%R\t%16-18f, %12-15r"}, 229 {FPU_FPA_EXT_V1, 0x0e100110, 0x0fff0f98, "fix%c%R\t%12-15r, %0-2f"}, 230 {FPU_FPA_EXT_V1, 0x0e200110, 0x0fff0fff, "wfs%c\t%12-15r"}, 231 {FPU_FPA_EXT_V1, 0x0e300110, 0x0fff0fff, "rfs%c\t%12-15r"}, 232 {FPU_FPA_EXT_V1, 0x0e400110, 0x0fff0fff, "wfc%c\t%12-15r"}, 233 {FPU_FPA_EXT_V1, 0x0e500110, 0x0fff0fff, "rfc%c\t%12-15r"}, 234 {FPU_FPA_EXT_V1, 0x0e90f110, 0x0ff8fff0, "cmf%c\t%16-18f, %0-3f"}, 235 {FPU_FPA_EXT_V1, 0x0eb0f110, 0x0ff8fff0, "cnf%c\t%16-18f, %0-3f"}, 236 {FPU_FPA_EXT_V1, 0x0ed0f110, 0x0ff8fff0, "cmfe%c\t%16-18f, %0-3f"}, 237 {FPU_FPA_EXT_V1, 0x0ef0f110, 0x0ff8fff0, "cnfe%c\t%16-18f, %0-3f"}, 238 {FPU_FPA_EXT_V1, 0x0c000100, 0x0e100f00, "stf%c%Q\t%12-14f, %A"}, 239 {FPU_FPA_EXT_V1, 0x0c100100, 0x0e100f00, "ldf%c%Q\t%12-14f, %A"}, 240 {FPU_FPA_EXT_V2, 0x0c000200, 0x0e100f00, "sfm%c\t%12-14f, %F, %A"}, 241 {FPU_FPA_EXT_V2, 0x0c100200, 0x0e100f00, "lfm%c\t%12-14f, %F, %A"}, 242 243 /* Register load/store */ 244 {FPU_NEON_EXT_V1, 0x0d200b00, 0x0fb00f01, "vstmdb%c\t%16-19r%21'!, %B"}, 245 {FPU_NEON_EXT_V1, 0x0d300b00, 0x0fb00f01, "vldmdb%c\t%16-19r%21'!, %B"}, 246 {FPU_NEON_EXT_V1, 0x0c800b00, 0x0f900f01, "vstmia%c\t%16-19r%21'!, %B"}, 247 {FPU_NEON_EXT_V1, 0x0c900b00, 0x0f900f01, "vldmia%c\t%16-19r%21'!, %B"}, 248 {FPU_NEON_EXT_V1, 0x0d000b00, 0x0f300f00, "vstr%c\t%12-15,22D, %C"}, 249 {FPU_NEON_EXT_V1, 0x0d100b00, 0x0f300f00, "vldr%c\t%12-15,22D, %C"}, 250 251 /* Data transfer between ARM and NEON registers */ 252 {FPU_NEON_EXT_V1, 0x0e800b10, 0x0ff00f70, "vdup%c.32\t%16-19,7D, %12-15r"}, 253 {FPU_NEON_EXT_V1, 0x0e800b30, 0x0ff00f70, "vdup%c.16\t%16-19,7D, %12-15r"}, 254 {FPU_NEON_EXT_V1, 0x0ea00b10, 0x0ff00f70, "vdup%c.32\t%16-19,7Q, %12-15r"}, 255 {FPU_NEON_EXT_V1, 0x0ea00b30, 0x0ff00f70, "vdup%c.16\t%16-19,7Q, %12-15r"}, 256 {FPU_NEON_EXT_V1, 0x0ec00b10, 0x0ff00f70, "vdup%c.8\t%16-19,7D, %12-15r"}, 257 {FPU_NEON_EXT_V1, 0x0ee00b10, 0x0ff00f70, "vdup%c.8\t%16-19,7Q, %12-15r"}, 258 {FPU_NEON_EXT_V1, 0x0c400b10, 0x0ff00fd0, "vmov%c\t%0-3,5D, %12-15r, %16-19r"}, 259 {FPU_NEON_EXT_V1, 0x0c500b10, 0x0ff00fd0, "vmov%c\t%12-15r, %16-19r, %0-3,5D"}, 260 {FPU_NEON_EXT_V1, 0x0e000b10, 0x0fd00f70, "vmov%c.32\t%16-19,7D[%21d], %12-15r"}, 261 {FPU_NEON_EXT_V1, 0x0e100b10, 0x0f500f70, "vmov%c.32\t%12-15r, %16-19,7D[%21d]"}, 262 {FPU_NEON_EXT_V1, 0x0e000b30, 0x0fd00f30, "vmov%c.16\t%16-19,7D[%6,21d], %12-15r"}, 263 {FPU_NEON_EXT_V1, 0x0e100b30, 0x0f500f30, "vmov%c.%23?us16\t%12-15r, %16-19,7D[%6,21d]"}, 264 {FPU_NEON_EXT_V1, 0x0e400b10, 0x0fd00f10, "vmov%c.8\t%16-19,7D[%5,6,21d], %12-15r"}, 265 {FPU_NEON_EXT_V1, 0x0e500b10, 0x0f500f10, "vmov%c.%23?us8\t%12-15r, %16-19,7D[%5,6,21d]"}, 266 267 /* Floating point coprocessor (VFP) instructions */ 268 {FPU_VFP_EXT_V1xD, 0x0ef1fa10, 0x0fffffff, "fmstat%c"}, 269 {FPU_VFP_EXT_V1xD, 0x0ee00a10, 0x0fff0fff, "fmxr%c\tfpsid, %12-15r"}, 270 {FPU_VFP_EXT_V1xD, 0x0ee10a10, 0x0fff0fff, "fmxr%c\tfpscr, %12-15r"}, 271 {FPU_VFP_EXT_V1xD, 0x0ee60a10, 0x0fff0fff, "fmxr%c\tmvfr1, %12-15r"}, 272 {FPU_VFP_EXT_V1xD, 0x0ee70a10, 0x0fff0fff, "fmxr%c\tmvfr0, %12-15r"}, 273 {FPU_VFP_EXT_V1xD, 0x0ee80a10, 0x0fff0fff, "fmxr%c\tfpexc, %12-15r"}, 274 {FPU_VFP_EXT_V1xD, 0x0ee90a10, 0x0fff0fff, "fmxr%c\tfpinst, %12-15r\t@ Impl def"}, 275 {FPU_VFP_EXT_V1xD, 0x0eea0a10, 0x0fff0fff, "fmxr%c\tfpinst2, %12-15r\t@ Impl def"}, 276 {FPU_VFP_EXT_V1xD, 0x0ef00a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpsid"}, 277 {FPU_VFP_EXT_V1xD, 0x0ef10a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpscr"}, 278 {FPU_VFP_EXT_V1xD, 0x0ef60a10, 0x0fff0fff, "fmrx%c\t%12-15r, mvfr1"}, 279 {FPU_VFP_EXT_V1xD, 0x0ef70a10, 0x0fff0fff, "fmrx%c\t%12-15r, mvfr0"}, 280 {FPU_VFP_EXT_V1xD, 0x0ef80a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpexc"}, 281 {FPU_VFP_EXT_V1xD, 0x0ef90a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpinst\t@ Impl def"}, 282 {FPU_VFP_EXT_V1xD, 0x0efa0a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpinst2\t@ Impl def"}, 283 {FPU_VFP_EXT_V1, 0x0e000b10, 0x0ff00fff, "fmdlr%c\t%z2, %12-15r"}, 284 {FPU_VFP_EXT_V1, 0x0e100b10, 0x0ff00fff, "fmrdl%c\t%12-15r, %z2"}, 285 {FPU_VFP_EXT_V1, 0x0e200b10, 0x0ff00fff, "fmdhr%c\t%z2, %12-15r"}, 286 {FPU_VFP_EXT_V1, 0x0e300b10, 0x0ff00fff, "fmrdh%c\t%12-15r, %z2"}, 287 {FPU_VFP_EXT_V1xD, 0x0ee00a10, 0x0ff00fff, "fmxr%c\t<impl def %16-19x>, %12-15r"}, 288 {FPU_VFP_EXT_V1xD, 0x0ef00a10, 0x0ff00fff, "fmrx%c\t%12-15r, <impl def %16-19x>"}, 289 {FPU_VFP_EXT_V1xD, 0x0e000a10, 0x0ff00f7f, "fmsr%c\t%y2, %12-15r"}, 290 {FPU_VFP_EXT_V1xD, 0x0e100a10, 0x0ff00f7f, "fmrs%c\t%12-15r, %y2"}, 291 {FPU_VFP_EXT_V1xD, 0x0eb50a40, 0x0fbf0f70, "fcmp%7'ezs%c\t%y1"}, 292 {FPU_VFP_EXT_V1, 0x0eb50b40, 0x0fbf0f70, "fcmp%7'ezd%c\t%z1"}, 293 {FPU_VFP_EXT_V1xD, 0x0eb00a40, 0x0fbf0fd0, "fcpys%c\t%y1, %y0"}, 294 {FPU_VFP_EXT_V1xD, 0x0eb00ac0, 0x0fbf0fd0, "fabss%c\t%y1, %y0"}, 295 {FPU_VFP_EXT_V1, 0x0eb00b40, 0x0fbf0fd0, "fcpyd%c\t%z1, %z0"}, 296 {FPU_VFP_EXT_V1, 0x0eb00bc0, 0x0fbf0fd0, "fabsd%c\t%z1, %z0"}, 297 {FPU_VFP_EXT_V1xD, 0x0eb10a40, 0x0fbf0fd0, "fnegs%c\t%y1, %y0"}, 298 {FPU_VFP_EXT_V1xD, 0x0eb10ac0, 0x0fbf0fd0, "fsqrts%c\t%y1, %y0"}, 299 {FPU_VFP_EXT_V1, 0x0eb10b40, 0x0fbf0fd0, "fnegd%c\t%z1, %z0"}, 300 {FPU_VFP_EXT_V1, 0x0eb10bc0, 0x0fbf0fd0, "fsqrtd%c\t%z1, %z0"}, 301 {FPU_VFP_EXT_V1, 0x0eb70ac0, 0x0fbf0fd0, "fcvtds%c\t%z1, %y0"}, 302 {FPU_VFP_EXT_V1, 0x0eb70bc0, 0x0fbf0fd0, "fcvtsd%c\t%y1, %z0"}, 303 {FPU_VFP_EXT_V1xD, 0x0eb80a40, 0x0fbf0fd0, "fuitos%c\t%y1, %y0"}, 304 {FPU_VFP_EXT_V1xD, 0x0eb80ac0, 0x0fbf0fd0, "fsitos%c\t%y1, %y0"}, 305 {FPU_VFP_EXT_V1, 0x0eb80b40, 0x0fbf0fd0, "fuitod%c\t%z1, %y0"}, 306 {FPU_VFP_EXT_V1, 0x0eb80bc0, 0x0fbf0fd0, "fsitod%c\t%z1, %y0"}, 307 {FPU_VFP_EXT_V1xD, 0x0eb40a40, 0x0fbf0f50, "fcmp%7'es%c\t%y1, %y0"}, 308 {FPU_VFP_EXT_V1, 0x0eb40b40, 0x0fbf0f50, "fcmp%7'ed%c\t%z1, %z0"}, 309 {FPU_VFP_EXT_V3, 0x0eba0a40, 0x0fbe0f50, "f%16?us%7?lhtos%c\t%y1, #%5,0-3k"}, 310 {FPU_VFP_EXT_V3, 0x0eba0b40, 0x0fbe0f50, "f%16?us%7?lhtod%c\t%z1, #%5,0-3k"}, 311 {FPU_VFP_EXT_V1xD, 0x0ebc0a40, 0x0fbe0f50, "fto%16?sui%7'zs%c\t%y1, %y0"}, 312 {FPU_VFP_EXT_V1, 0x0ebc0b40, 0x0fbe0f50, "fto%16?sui%7'zd%c\t%y1, %z0"}, 313 {FPU_VFP_EXT_V3, 0x0ebe0a40, 0x0fbe0f50, "fto%16?us%7?lhs%c\t%y1, #%5,0-3k"}, 314 {FPU_VFP_EXT_V3, 0x0ebe0b40, 0x0fbe0f50, "fto%16?us%7?lhd%c\t%z1, #%5,0-3k"}, 315 {FPU_VFP_EXT_V1, 0x0c500b10, 0x0fb00ff0, "fmrrd%c\t%12-15r, %16-19r, %z0"}, 316 {FPU_VFP_EXT_V3, 0x0eb00a00, 0x0fb00ff0, "fconsts%c\t%y1, #%0-3,16-19d"}, 317 {FPU_VFP_EXT_V3, 0x0eb00b00, 0x0fb00ff0, "fconstd%c\t%z1, #%0-3,16-19d"}, 318 {FPU_VFP_EXT_V2, 0x0c400a10, 0x0ff00fd0, "fmsrr%c\t%y4, %12-15r, %16-19r"}, 319 {FPU_VFP_EXT_V2, 0x0c400b10, 0x0ff00fd0, "fmdrr%c\t%z0, %12-15r, %16-19r"}, 320 {FPU_VFP_EXT_V2, 0x0c500a10, 0x0ff00fd0, "fmrrs%c\t%12-15r, %16-19r, %y4"}, 321 {FPU_VFP_EXT_V1xD, 0x0e000a00, 0x0fb00f50, "fmacs%c\t%y1, %y2, %y0"}, 322 {FPU_VFP_EXT_V1xD, 0x0e000a40, 0x0fb00f50, "fnmacs%c\t%y1, %y2, %y0"}, 323 {FPU_VFP_EXT_V1, 0x0e000b00, 0x0fb00f50, "fmacd%c\t%z1, %z2, %z0"}, 324 {FPU_VFP_EXT_V1, 0x0e000b40, 0x0fb00f50, "fnmacd%c\t%z1, %z2, %z0"}, 325 {FPU_VFP_EXT_V1xD, 0x0e100a00, 0x0fb00f50, "fmscs%c\t%y1, %y2, %y0"}, 326 {FPU_VFP_EXT_V1xD, 0x0e100a40, 0x0fb00f50, "fnmscs%c\t%y1, %y2, %y0"}, 327 {FPU_VFP_EXT_V1, 0x0e100b00, 0x0fb00f50, "fmscd%c\t%z1, %z2, %z0"}, 328 {FPU_VFP_EXT_V1, 0x0e100b40, 0x0fb00f50, "fnmscd%c\t%z1, %z2, %z0"}, 329 {FPU_VFP_EXT_V1xD, 0x0e200a00, 0x0fb00f50, "fmuls%c\t%y1, %y2, %y0"}, 330 {FPU_VFP_EXT_V1xD, 0x0e200a40, 0x0fb00f50, "fnmuls%c\t%y1, %y2, %y0"}, 331 {FPU_VFP_EXT_V1, 0x0e200b00, 0x0fb00f50, "fmuld%c\t%z1, %z2, %z0"}, 332 {FPU_VFP_EXT_V1, 0x0e200b40, 0x0fb00f50, "fnmuld%c\t%z1, %z2, %z0"}, 333 {FPU_VFP_EXT_V1xD, 0x0e300a00, 0x0fb00f50, "fadds%c\t%y1, %y2, %y0"}, 334 {FPU_VFP_EXT_V1xD, 0x0e300a40, 0x0fb00f50, "fsubs%c\t%y1, %y2, %y0"}, 335 {FPU_VFP_EXT_V1, 0x0e300b00, 0x0fb00f50, "faddd%c\t%z1, %z2, %z0"}, 336 {FPU_VFP_EXT_V1, 0x0e300b40, 0x0fb00f50, "fsubd%c\t%z1, %z2, %z0"}, 337 {FPU_VFP_EXT_V1xD, 0x0e800a00, 0x0fb00f50, "fdivs%c\t%y1, %y2, %y0"}, 338 {FPU_VFP_EXT_V1, 0x0e800b00, 0x0fb00f50, "fdivd%c\t%z1, %z2, %z0"}, 339 {FPU_VFP_EXT_V1xD, 0x0d200a00, 0x0fb00f00, "fstmdbs%c\t%16-19r!, %y3"}, 340 {FPU_VFP_EXT_V1xD, 0x0d200b00, 0x0fb00f00, "fstmdb%0?xd%c\t%16-19r!, %z3"}, 341 {FPU_VFP_EXT_V1xD, 0x0d300a00, 0x0fb00f00, "fldmdbs%c\t%16-19r!, %y3"}, 342 {FPU_VFP_EXT_V1xD, 0x0d300b00, 0x0fb00f00, "fldmdb%0?xd%c\t%16-19r!, %z3"}, 343 {FPU_VFP_EXT_V1xD, 0x0d000a00, 0x0f300f00, "fsts%c\t%y1, %A"}, 344 {FPU_VFP_EXT_V1, 0x0d000b00, 0x0f300f00, "fstd%c\t%z1, %A"}, 345 {FPU_VFP_EXT_V1xD, 0x0d100a00, 0x0f300f00, "flds%c\t%y1, %A"}, 346 {FPU_VFP_EXT_V1, 0x0d100b00, 0x0f300f00, "fldd%c\t%z1, %A"}, 347 {FPU_VFP_EXT_V1xD, 0x0c800a00, 0x0f900f00, "fstmias%c\t%16-19r%21'!, %y3"}, 348 {FPU_VFP_EXT_V1xD, 0x0c800b00, 0x0f900f00, "fstmia%0?xd%c\t%16-19r%21'!, %z3"}, 349 {FPU_VFP_EXT_V1xD, 0x0c900a00, 0x0f900f00, "fldmias%c\t%16-19r%21'!, %y3"}, 350 {FPU_VFP_EXT_V1xD, 0x0c900b00, 0x0f900f00, "fldmia%0?xd%c\t%16-19r%21'!, %z3"}, 351 352 /* Cirrus coprocessor instructions. */ 353 {ARM_CEXT_MAVERICK, 0x0d100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"}, 354 {ARM_CEXT_MAVERICK, 0x0c100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"}, 355 {ARM_CEXT_MAVERICK, 0x0d500400, 0x0f500f00, "cfldrd%c\tmvd%12-15d, %A"}, 356 {ARM_CEXT_MAVERICK, 0x0c500400, 0x0f500f00, "cfldrd%c\tmvd%12-15d, %A"}, 357 {ARM_CEXT_MAVERICK, 0x0d100500, 0x0f500f00, "cfldr32%c\tmvfx%12-15d, %A"}, 358 {ARM_CEXT_MAVERICK, 0x0c100500, 0x0f500f00, "cfldr32%c\tmvfx%12-15d, %A"}, 359 {ARM_CEXT_MAVERICK, 0x0d500500, 0x0f500f00, "cfldr64%c\tmvdx%12-15d, %A"}, 360 {ARM_CEXT_MAVERICK, 0x0c500500, 0x0f500f00, "cfldr64%c\tmvdx%12-15d, %A"}, 361 {ARM_CEXT_MAVERICK, 0x0d000400, 0x0f500f00, "cfstrs%c\tmvf%12-15d, %A"}, 362 {ARM_CEXT_MAVERICK, 0x0c000400, 0x0f500f00, "cfstrs%c\tmvf%12-15d, %A"}, 363 {ARM_CEXT_MAVERICK, 0x0d400400, 0x0f500f00, "cfstrd%c\tmvd%12-15d, %A"}, 364 {ARM_CEXT_MAVERICK, 0x0c400400, 0x0f500f00, "cfstrd%c\tmvd%12-15d, %A"}, 365 {ARM_CEXT_MAVERICK, 0x0d000500, 0x0f500f00, "cfstr32%c\tmvfx%12-15d, %A"}, 366 {ARM_CEXT_MAVERICK, 0x0c000500, 0x0f500f00, "cfstr32%c\tmvfx%12-15d, %A"}, 367 {ARM_CEXT_MAVERICK, 0x0d400500, 0x0f500f00, "cfstr64%c\tmvdx%12-15d, %A"}, 368 {ARM_CEXT_MAVERICK, 0x0c400500, 0x0f500f00, "cfstr64%c\tmvdx%12-15d, %A"}, 369 {ARM_CEXT_MAVERICK, 0x0e000450, 0x0ff00ff0, "cfmvsr%c\tmvf%16-19d, %12-15r"}, 370 {ARM_CEXT_MAVERICK, 0x0e100450, 0x0ff00ff0, "cfmvrs%c\t%12-15r, mvf%16-19d"}, 371 {ARM_CEXT_MAVERICK, 0x0e000410, 0x0ff00ff0, "cfmvdlr%c\tmvd%16-19d, %12-15r"}, 372 {ARM_CEXT_MAVERICK, 0x0e100410, 0x0ff00ff0, "cfmvrdl%c\t%12-15r, mvd%16-19d"}, 373 {ARM_CEXT_MAVERICK, 0x0e000430, 0x0ff00ff0, "cfmvdhr%c\tmvd%16-19d, %12-15r"}, 374 {ARM_CEXT_MAVERICK, 0x0e100430, 0x0ff00fff, "cfmvrdh%c\t%12-15r, mvd%16-19d"}, 375 {ARM_CEXT_MAVERICK, 0x0e000510, 0x0ff00fff, "cfmv64lr%c\tmvdx%16-19d, %12-15r"}, 376 {ARM_CEXT_MAVERICK, 0x0e100510, 0x0ff00fff, "cfmvr64l%c\t%12-15r, mvdx%16-19d"}, 377 {ARM_CEXT_MAVERICK, 0x0e000530, 0x0ff00fff, "cfmv64hr%c\tmvdx%16-19d, %12-15r"}, 378 {ARM_CEXT_MAVERICK, 0x0e100530, 0x0ff00fff, "cfmvr64h%c\t%12-15r, mvdx%16-19d"}, 379 {ARM_CEXT_MAVERICK, 0x0e200440, 0x0ff00fff, "cfmval32%c\tmvax%12-15d, mvfx%16-19d"}, 380 {ARM_CEXT_MAVERICK, 0x0e100440, 0x0ff00fff, "cfmv32al%c\tmvfx%12-15d, mvax%16-19d"}, 381 {ARM_CEXT_MAVERICK, 0x0e200460, 0x0ff00fff, "cfmvam32%c\tmvax%12-15d, mvfx%16-19d"}, 382 {ARM_CEXT_MAVERICK, 0x0e100460, 0x0ff00fff, "cfmv32am%c\tmvfx%12-15d, mvax%16-19d"}, 383 {ARM_CEXT_MAVERICK, 0x0e200480, 0x0ff00fff, "cfmvah32%c\tmvax%12-15d, mvfx%16-19d"}, 384 {ARM_CEXT_MAVERICK, 0x0e100480, 0x0ff00fff, "cfmv32ah%c\tmvfx%12-15d, mvax%16-19d"}, 385 {ARM_CEXT_MAVERICK, 0x0e2004a0, 0x0ff00fff, "cfmva32%c\tmvax%12-15d, mvfx%16-19d"}, 386 {ARM_CEXT_MAVERICK, 0x0e1004a0, 0x0ff00fff, "cfmv32a%c\tmvfx%12-15d, mvax%16-19d"}, 387 {ARM_CEXT_MAVERICK, 0x0e2004c0, 0x0ff00fff, "cfmva64%c\tmvax%12-15d, mvdx%16-19d"}, 388 {ARM_CEXT_MAVERICK, 0x0e1004c0, 0x0ff00fff, "cfmv64a%c\tmvdx%12-15d, mvax%16-19d"}, 389 {ARM_CEXT_MAVERICK, 0x0e2004e0, 0x0fff0fff, "cfmvsc32%c\tdspsc, mvdx%12-15d"}, 390 {ARM_CEXT_MAVERICK, 0x0e1004e0, 0x0fff0fff, "cfmv32sc%c\tmvdx%12-15d, dspsc"}, 391 {ARM_CEXT_MAVERICK, 0x0e000400, 0x0ff00fff, "cfcpys%c\tmvf%12-15d, mvf%16-19d"}, 392 {ARM_CEXT_MAVERICK, 0x0e000420, 0x0ff00fff, "cfcpyd%c\tmvd%12-15d, mvd%16-19d"}, 393 {ARM_CEXT_MAVERICK, 0x0e000460, 0x0ff00fff, "cfcvtsd%c\tmvd%12-15d, mvf%16-19d"}, 394 {ARM_CEXT_MAVERICK, 0x0e000440, 0x0ff00fff, "cfcvtds%c\tmvf%12-15d, mvd%16-19d"}, 395 {ARM_CEXT_MAVERICK, 0x0e000480, 0x0ff00fff, "cfcvt32s%c\tmvf%12-15d, mvfx%16-19d"}, 396 {ARM_CEXT_MAVERICK, 0x0e0004a0, 0x0ff00fff, "cfcvt32d%c\tmvd%12-15d, mvfx%16-19d"}, 397 {ARM_CEXT_MAVERICK, 0x0e0004c0, 0x0ff00fff, "cfcvt64s%c\tmvf%12-15d, mvdx%16-19d"}, 398 {ARM_CEXT_MAVERICK, 0x0e0004e0, 0x0ff00fff, "cfcvt64d%c\tmvd%12-15d, mvdx%16-19d"}, 399 {ARM_CEXT_MAVERICK, 0x0e100580, 0x0ff00fff, "cfcvts32%c\tmvfx%12-15d, mvf%16-19d"}, 400 {ARM_CEXT_MAVERICK, 0x0e1005a0, 0x0ff00fff, "cfcvtd32%c\tmvfx%12-15d, mvd%16-19d"}, 401 {ARM_CEXT_MAVERICK, 0x0e1005c0, 0x0ff00fff, "cftruncs32%c\tmvfx%12-15d, mvf%16-19d"}, 402 {ARM_CEXT_MAVERICK, 0x0e1005e0, 0x0ff00fff, "cftruncd32%c\tmvfx%12-15d, mvd%16-19d"}, 403 {ARM_CEXT_MAVERICK, 0x0e000550, 0x0ff00ff0, "cfrshl32%c\tmvfx%16-19d, mvfx%0-3d, %12-15r"}, 404 {ARM_CEXT_MAVERICK, 0x0e000570, 0x0ff00ff0, "cfrshl64%c\tmvdx%16-19d, mvdx%0-3d, %12-15r"}, 405 {ARM_CEXT_MAVERICK, 0x0e000500, 0x0ff00f10, "cfsh32%c\tmvfx%12-15d, mvfx%16-19d, #%I"}, 406 {ARM_CEXT_MAVERICK, 0x0e200500, 0x0ff00f10, "cfsh64%c\tmvdx%12-15d, mvdx%16-19d, #%I"}, 407 {ARM_CEXT_MAVERICK, 0x0e100490, 0x0ff00ff0, "cfcmps%c\t%12-15r, mvf%16-19d, mvf%0-3d"}, 408 {ARM_CEXT_MAVERICK, 0x0e1004b0, 0x0ff00ff0, "cfcmpd%c\t%12-15r, mvd%16-19d, mvd%0-3d"}, 409 {ARM_CEXT_MAVERICK, 0x0e100590, 0x0ff00ff0, "cfcmp32%c\t%12-15r, mvfx%16-19d, mvfx%0-3d"}, 410 {ARM_CEXT_MAVERICK, 0x0e1005b0, 0x0ff00ff0, "cfcmp64%c\t%12-15r, mvdx%16-19d, mvdx%0-3d"}, 411 {ARM_CEXT_MAVERICK, 0x0e300400, 0x0ff00fff, "cfabss%c\tmvf%12-15d, mvf%16-19d"}, 412 {ARM_CEXT_MAVERICK, 0x0e300420, 0x0ff00fff, "cfabsd%c\tmvd%12-15d, mvd%16-19d"}, 413 {ARM_CEXT_MAVERICK, 0x0e300440, 0x0ff00fff, "cfnegs%c\tmvf%12-15d, mvf%16-19d"}, 414 {ARM_CEXT_MAVERICK, 0x0e300460, 0x0ff00fff, "cfnegd%c\tmvd%12-15d, mvd%16-19d"}, 415 {ARM_CEXT_MAVERICK, 0x0e300480, 0x0ff00ff0, "cfadds%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"}, 416 {ARM_CEXT_MAVERICK, 0x0e3004a0, 0x0ff00ff0, "cfaddd%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"}, 417 {ARM_CEXT_MAVERICK, 0x0e3004c0, 0x0ff00ff0, "cfsubs%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"}, 418 {ARM_CEXT_MAVERICK, 0x0e3004e0, 0x0ff00ff0, "cfsubd%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"}, 419 {ARM_CEXT_MAVERICK, 0x0e100400, 0x0ff00ff0, "cfmuls%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"}, 420 {ARM_CEXT_MAVERICK, 0x0e100420, 0x0ff00ff0, "cfmuld%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"}, 421 {ARM_CEXT_MAVERICK, 0x0e300500, 0x0ff00fff, "cfabs32%c\tmvfx%12-15d, mvfx%16-19d"}, 422 {ARM_CEXT_MAVERICK, 0x0e300520, 0x0ff00fff, "cfabs64%c\tmvdx%12-15d, mvdx%16-19d"}, 423 {ARM_CEXT_MAVERICK, 0x0e300540, 0x0ff00fff, "cfneg32%c\tmvfx%12-15d, mvfx%16-19d"}, 424 {ARM_CEXT_MAVERICK, 0x0e300560, 0x0ff00fff, "cfneg64%c\tmvdx%12-15d, mvdx%16-19d"}, 425 {ARM_CEXT_MAVERICK, 0x0e300580, 0x0ff00ff0, "cfadd32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"}, 426 {ARM_CEXT_MAVERICK, 0x0e3005a0, 0x0ff00ff0, "cfadd64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"}, 427 {ARM_CEXT_MAVERICK, 0x0e3005c0, 0x0ff00ff0, "cfsub32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"}, 428 {ARM_CEXT_MAVERICK, 0x0e3005e0, 0x0ff00ff0, "cfsub64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"}, 429 {ARM_CEXT_MAVERICK, 0x0e100500, 0x0ff00ff0, "cfmul32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"}, 430 {ARM_CEXT_MAVERICK, 0x0e100520, 0x0ff00ff0, "cfmul64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"}, 431 {ARM_CEXT_MAVERICK, 0x0e100540, 0x0ff00ff0, "cfmac32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"}, 432 {ARM_CEXT_MAVERICK, 0x0e100560, 0x0ff00ff0, "cfmsc32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"}, 433 {ARM_CEXT_MAVERICK, 0x0e000600, 0x0ff00f10, "cfmadd32%c\tmvax%5-7d, mvfx%12-15d, mvfx%16-19d, mvfx%0-3d"}, 434 {ARM_CEXT_MAVERICK, 0x0e100600, 0x0ff00f10, "cfmsub32%c\tmvax%5-7d, mvfx%12-15d, mvfx%16-19d, mvfx%0-3d"}, 435 {ARM_CEXT_MAVERICK, 0x0e200600, 0x0ff00f10, "cfmadda32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"}, 436 {ARM_CEXT_MAVERICK, 0x0e300600, 0x0ff00f10, "cfmsuba32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"}, 437 438 /* Generic coprocessor instructions */ 439 {ARM_EXT_V2, 0x0c400000, 0x0ff00000, "mcrr%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"}, 440 {ARM_EXT_V2, 0x0c500000, 0x0ff00000, "mrrc%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"}, 441 {ARM_EXT_V2, 0x0e000000, 0x0f000010, "cdp%c\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"}, 442 {ARM_EXT_V2, 0x0e100010, 0x0f100010, "mrc%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"}, 443 {ARM_EXT_V2, 0x0e000010, 0x0f100010, "mcr%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"}, 444 {ARM_EXT_V2, 0x0c000000, 0x0e100000, "stc%22'l%c\t%8-11d, cr%12-15d, %A"}, 445 {ARM_EXT_V2, 0x0c100000, 0x0e100000, "ldc%22'l%c\t%8-11d, cr%12-15d, %A"}, 446 447 /* V6 coprocessor instructions */ 448 {ARM_EXT_V6, 0xfc500000, 0xfff00000, "mrrc2%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"}, 449 {ARM_EXT_V6, 0xfc400000, 0xfff00000, "mcrr2%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"}, 450 451 /* V5 coprocessor instructions */ 452 {ARM_EXT_V5, 0xfc100000, 0xfe100000, "ldc2%22'l%c\t%8-11d, cr%12-15d, %A"}, 453 {ARM_EXT_V5, 0xfc000000, 0xfe100000, "stc2%22'l%c\t%8-11d, cr%12-15d, %A"}, 454 {ARM_EXT_V5, 0xfe000000, 0xff000010, "cdp2%c\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"}, 455 {ARM_EXT_V5, 0xfe000010, 0xff100010, "mcr2%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"}, 456 {ARM_EXT_V5, 0xfe100010, 0xff100010, "mrc2%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"}, 457 458 {0, 0, 0, 0} 459}; 460 461/* Neon opcode table: This does not encode the top byte -- that is 462 checked by the print_insn_neon routine, as it depends on whether we are 463 doing thumb32 or arm32 disassembly. */ 464 465/* print_insn_neon recognizes the following format control codes: 466 467 %% % 468 469 %c print condition code 470 %A print v{st,ld}[1234] operands 471 %B print v{st,ld}[1234] any one operands 472 %C print v{st,ld}[1234] single->all operands 473 %D print scalar 474 %E print vmov, vmvn, vorr, vbic encoded constant 475 %F print vtbl,vtbx register list 476 477 %<bitfield>r print as an ARM register 478 %<bitfield>d print the bitfield in decimal 479 %<bitfield>e print the 2^N - bitfield in decimal 480 %<bitfield>D print as a NEON D register 481 %<bitfield>Q print as a NEON Q register 482 %<bitfield>R print as a NEON D or Q register 483 %<bitfield>Sn print byte scaled width limited by n 484 %<bitfield>Tn print short scaled width limited by n 485 %<bitfield>Un print long scaled width limited by n 486 487 %<bitfield>'c print specified char iff bitfield is all ones 488 %<bitfield>`c print specified char iff bitfield is all zeroes 489 %<bitfield>?ab... select from array of values in big endian order */ 490 491static const struct opcode32 neon_opcodes[] = 492{ 493 /* Extract */ 494 {FPU_NEON_EXT_V1, 0xf2b00840, 0xffb00850, "vext%c.8\t%12-15,22R, %16-19,7R, %0-3,5R, #%8-11d"}, 495 {FPU_NEON_EXT_V1, 0xf2b00000, 0xffb00810, "vext%c.8\t%12-15,22R, %16-19,7R, %0-3,5R, #%8-11d"}, 496 497 /* Move data element to all lanes */ 498 {FPU_NEON_EXT_V1, 0xf3b40c00, 0xffb70f90, "vdup%c.32\t%12-15,22R, %0-3,5D[%19d]"}, 499 {FPU_NEON_EXT_V1, 0xf3b20c00, 0xffb30f90, "vdup%c.16\t%12-15,22R, %0-3,5D[%18-19d]"}, 500 {FPU_NEON_EXT_V1, 0xf3b10c00, 0xffb10f90, "vdup%c.8\t%12-15,22R, %0-3,5D[%17-19d]"}, 501 502 /* Table lookup */ 503 {FPU_NEON_EXT_V1, 0xf3b00800, 0xffb00c50, "vtbl%c.8\t%12-15,22D, %F, %0-3,5D"}, 504 {FPU_NEON_EXT_V1, 0xf3b00840, 0xffb00c50, "vtbx%c.8\t%12-15,22D, %F, %0-3,5D"}, 505 506 /* Two registers, miscellaneous */ 507 {FPU_NEON_EXT_V1, 0xf2880a10, 0xfebf0fd0, "vmovl%c.%24?us8\t%12-15,22Q, %0-3,5D"}, 508 {FPU_NEON_EXT_V1, 0xf2900a10, 0xfebf0fd0, "vmovl%c.%24?us16\t%12-15,22Q, %0-3,5D"}, 509 {FPU_NEON_EXT_V1, 0xf2a00a10, 0xfebf0fd0, "vmovl%c.%24?us32\t%12-15,22Q, %0-3,5D"}, 510 {FPU_NEON_EXT_V1, 0xf3b00500, 0xffbf0f90, "vcnt%c.8\t%12-15,22R, %0-3,5R"}, 511 {FPU_NEON_EXT_V1, 0xf3b00580, 0xffbf0f90, "vmvn%c\t%12-15,22R, %0-3,5R"}, 512 {FPU_NEON_EXT_V1, 0xf3b20000, 0xffbf0f90, "vswp%c\t%12-15,22R, %0-3,5R"}, 513 {FPU_NEON_EXT_V1, 0xf3b20200, 0xffb30fd0, "vmovn%c.i%18-19T2\t%12-15,22D, %0-3,5Q"}, 514 {FPU_NEON_EXT_V1, 0xf3b20240, 0xffb30fd0, "vqmovun%c.s%18-19T2\t%12-15,22D, %0-3,5Q"}, 515 {FPU_NEON_EXT_V1, 0xf3b20280, 0xffb30fd0, "vqmovn%c.s%18-19T2\t%12-15,22D, %0-3,5Q"}, 516 {FPU_NEON_EXT_V1, 0xf3b202c0, 0xffb30fd0, "vqmovn%c.u%18-19T2\t%12-15,22D, %0-3,5Q"}, 517 {FPU_NEON_EXT_V1, 0xf3b20300, 0xffb30fd0, "vshll%c.i%18-19S2\t%12-15,22Q, %0-3,5D, #%18-19S2"}, 518 {FPU_NEON_EXT_V1, 0xf3bb0400, 0xffbf0e90, "vrecpe%c.%8?fu%18-19S2\t%12-15,22R, %0-3,5R"}, 519 {FPU_NEON_EXT_V1, 0xf3bb0480, 0xffbf0e90, "vrsqrte%c.%8?fu%18-19S2\t%12-15,22R, %0-3,5R"}, 520 {FPU_NEON_EXT_V1, 0xf3b00000, 0xffb30f90, "vrev64%c.%18-19S2\t%12-15,22R, %0-3,5R"}, 521 {FPU_NEON_EXT_V1, 0xf3b00080, 0xffb30f90, "vrev32%c.%18-19S2\t%12-15,22R, %0-3,5R"}, 522 {FPU_NEON_EXT_V1, 0xf3b00100, 0xffb30f90, "vrev16%c.%18-19S2\t%12-15,22R, %0-3,5R"}, 523 {FPU_NEON_EXT_V1, 0xf3b00400, 0xffb30f90, "vcls%c.s%18-19S2\t%12-15,22R, %0-3,5R"}, 524 {FPU_NEON_EXT_V1, 0xf3b00480, 0xffb30f90, "vclz%c.i%18-19S2\t%12-15,22R, %0-3,5R"}, 525 {FPU_NEON_EXT_V1, 0xf3b00700, 0xffb30f90, "vqabs%c.s%18-19S2\t%12-15,22R, %0-3,5R"}, 526 {FPU_NEON_EXT_V1, 0xf3b00780, 0xffb30f90, "vqneg%c.s%18-19S2\t%12-15,22R, %0-3,5R"}, 527 {FPU_NEON_EXT_V1, 0xf3b20080, 0xffb30f90, "vtrn%c.%18-19S2\t%12-15,22R, %0-3,5R"}, 528 {FPU_NEON_EXT_V1, 0xf3b20100, 0xffb30f90, "vuzp%c.%18-19S2\t%12-15,22R, %0-3,5R"}, 529 {FPU_NEON_EXT_V1, 0xf3b20180, 0xffb30f90, "vzip%c.%18-19S2\t%12-15,22R, %0-3,5R"}, 530 {FPU_NEON_EXT_V1, 0xf3b10000, 0xffb30b90, "vcgt%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"}, 531 {FPU_NEON_EXT_V1, 0xf3b10080, 0xffb30b90, "vcge%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"}, 532 {FPU_NEON_EXT_V1, 0xf3b10100, 0xffb30b90, "vceq%c.%10?fi%18-19S2\t%12-15,22R, %0-3,5R, #0"}, 533 {FPU_NEON_EXT_V1, 0xf3b10180, 0xffb30b90, "vcle%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"}, 534 {FPU_NEON_EXT_V1, 0xf3b10200, 0xffb30b90, "vclt%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"}, 535 {FPU_NEON_EXT_V1, 0xf3b10300, 0xffb30b90, "vabs%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R"}, 536 {FPU_NEON_EXT_V1, 0xf3b10380, 0xffb30b90, "vneg%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R"}, 537 {FPU_NEON_EXT_V1, 0xf3b00200, 0xffb30f10, "vpaddl%c.%7?us%18-19S2\t%12-15,22R, %0-3,5R"}, 538 {FPU_NEON_EXT_V1, 0xf3b00600, 0xffb30f10, "vpadal%c.%7?us%18-19S2\t%12-15,22R, %0-3,5R"}, 539 {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"}, 540 541 /* Three registers of the same length */ 542 {FPU_NEON_EXT_V1, 0xf2000110, 0xffb00f10, "vand%c\t%12-15,22R, %16-19,7R, %0-3,5R"}, 543 {FPU_NEON_EXT_V1, 0xf2100110, 0xffb00f10, "vbic%c\t%12-15,22R, %16-19,7R, %0-3,5R"}, 544 {FPU_NEON_EXT_V1, 0xf2200110, 0xffb00f10, "vorr%c\t%12-15,22R, %16-19,7R, %0-3,5R"}, 545 {FPU_NEON_EXT_V1, 0xf2300110, 0xffb00f10, "vorn%c\t%12-15,22R, %16-19,7R, %0-3,5R"}, 546 {FPU_NEON_EXT_V1, 0xf3000110, 0xffb00f10, "veor%c\t%12-15,22R, %16-19,7R, %0-3,5R"}, 547 {FPU_NEON_EXT_V1, 0xf3100110, 0xffb00f10, "vbsl%c\t%12-15,22R, %16-19,7R, %0-3,5R"}, 548 {FPU_NEON_EXT_V1, 0xf3200110, 0xffb00f10, "vbit%c\t%12-15,22R, %16-19,7R, %0-3,5R"}, 549 {FPU_NEON_EXT_V1, 0xf3300110, 0xffb00f10, "vbif%c\t%12-15,22R, %16-19,7R, %0-3,5R"}, 550 {FPU_NEON_EXT_V1, 0xf2000d00, 0xffa00f10, "vadd%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, 551 {FPU_NEON_EXT_V1, 0xf2000d10, 0xffa00f10, "vmla%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, 552 {FPU_NEON_EXT_V1, 0xf2000e00, 0xffa00f10, "vceq%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, 553 {FPU_NEON_EXT_V1, 0xf2000f00, 0xffa00f10, "vmax%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, 554 {FPU_NEON_EXT_V1, 0xf2000f10, 0xffa00f10, "vrecps%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, 555 {FPU_NEON_EXT_V1, 0xf2200d00, 0xffa00f10, "vsub%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, 556 {FPU_NEON_EXT_V1, 0xf2200d10, 0xffa00f10, "vmls%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, 557 {FPU_NEON_EXT_V1, 0xf2200f00, 0xffa00f10, "vmin%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, 558 {FPU_NEON_EXT_V1, 0xf2200f10, 0xffa00f10, "vrsqrts%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, 559 {FPU_NEON_EXT_V1, 0xf3000d00, 0xffa00f10, "vpadd%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, 560 {FPU_NEON_EXT_V1, 0xf3000d10, 0xffa00f10, "vmul%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, 561 {FPU_NEON_EXT_V1, 0xf3000e00, 0xffa00f10, "vcge%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, 562 {FPU_NEON_EXT_V1, 0xf3000e10, 0xffa00f10, "vacge%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, 563 {FPU_NEON_EXT_V1, 0xf3000f00, 0xffa00f10, "vpmax%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, 564 {FPU_NEON_EXT_V1, 0xf3200d00, 0xffa00f10, "vabd%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, 565 {FPU_NEON_EXT_V1, 0xf3200e00, 0xffa00f10, "vcgt%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, 566 {FPU_NEON_EXT_V1, 0xf3200e10, 0xffa00f10, "vacgt%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, 567 {FPU_NEON_EXT_V1, 0xf3200f00, 0xffa00f10, "vpmin%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"}, 568 {FPU_NEON_EXT_V1, 0xf2000800, 0xff800f10, "vadd%c.i%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"}, 569 {FPU_NEON_EXT_V1, 0xf2000810, 0xff800f10, "vtst%c.%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"}, 570 {FPU_NEON_EXT_V1, 0xf2000900, 0xff800f10, "vmla%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"}, 571 {FPU_NEON_EXT_V1, 0xf2000b00, 0xff800f10, "vqdmulh%c.s%20-21S6\t%12-15,22R, %16-19,7R, %0-3,5R"}, 572 {FPU_NEON_EXT_V1, 0xf2000b10, 0xff800f10, "vpadd%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"}, 573 {FPU_NEON_EXT_V1, 0xf3000800, 0xff800f10, "vsub%c.i%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"}, 574 {FPU_NEON_EXT_V1, 0xf3000810, 0xff800f10, "vceq%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"}, 575 {FPU_NEON_EXT_V1, 0xf3000900, 0xff800f10, "vmls%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"}, 576 {FPU_NEON_EXT_V1, 0xf3000b00, 0xff800f10, "vqrdmulh%c.s%20-21S6\t%12-15,22R, %16-19,7R, %0-3,5R"}, 577 {FPU_NEON_EXT_V1, 0xf2000000, 0xfe800f10, "vhadd%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"}, 578 {FPU_NEON_EXT_V1, 0xf2000010, 0xfe800f10, "vqadd%c.%24?us%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"}, 579 {FPU_NEON_EXT_V1, 0xf2000100, 0xfe800f10, "vrhadd%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"}, 580 {FPU_NEON_EXT_V1, 0xf2000200, 0xfe800f10, "vhsub%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"}, 581 {FPU_NEON_EXT_V1, 0xf2000210, 0xfe800f10, "vqsub%c.%24?us%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"}, 582 {FPU_NEON_EXT_V1, 0xf2000300, 0xfe800f10, "vcgt%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"}, 583 {FPU_NEON_EXT_V1, 0xf2000310, 0xfe800f10, "vcge%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"}, 584 {FPU_NEON_EXT_V1, 0xf2000400, 0xfe800f10, "vshl%c.%24?us%20-21S3\t%12-15,22R, %0-3,5R, %16-19,7R"}, 585 {FPU_NEON_EXT_V1, 0xf2000410, 0xfe800f10, "vqshl%c.%24?us%20-21S3\t%12-15,22R, %0-3,5R, %16-19,7R"}, 586 {FPU_NEON_EXT_V1, 0xf2000500, 0xfe800f10, "vrshl%c.%24?us%20-21S3\t%12-15,22R, %0-3,5R, %16-19,7R"}, 587 {FPU_NEON_EXT_V1, 0xf2000510, 0xfe800f10, "vqrshl%c.%24?us%20-21S3\t%12-15,22R, %0-3,5R, %16-19,7R"}, 588 {FPU_NEON_EXT_V1, 0xf2000600, 0xfe800f10, "vmax%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"}, 589 {FPU_NEON_EXT_V1, 0xf2000610, 0xfe800f10, "vmin%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"}, 590 {FPU_NEON_EXT_V1, 0xf2000700, 0xfe800f10, "vabd%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"}, 591 {FPU_NEON_EXT_V1, 0xf2000710, 0xfe800f10, "vaba%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"}, 592 {FPU_NEON_EXT_V1, 0xf2000910, 0xfe800f10, "vmul%c.%24?pi%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"}, 593 {FPU_NEON_EXT_V1, 0xf2000a00, 0xfe800f10, "vpmax%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"}, 594 {FPU_NEON_EXT_V1, 0xf2000a10, 0xfe800f10, "vpmin%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"}, 595 596 /* One register and an immediate value */ 597 {FPU_NEON_EXT_V1, 0xf2800e10, 0xfeb80fb0, "vmov%c.i8\t%12-15,22R, %E"}, 598 {FPU_NEON_EXT_V1, 0xf2800e30, 0xfeb80fb0, "vmov%c.i64\t%12-15,22R, %E"}, 599 {FPU_NEON_EXT_V1, 0xf2800f10, 0xfeb80fb0, "vmov%c.f32\t%12-15,22R, %E"}, 600 {FPU_NEON_EXT_V1, 0xf2800810, 0xfeb80db0, "vmov%c.i16\t%12-15,22R, %E"}, 601 {FPU_NEON_EXT_V1, 0xf2800830, 0xfeb80db0, "vmvn%c.i16\t%12-15,22R, %E"}, 602 {FPU_NEON_EXT_V1, 0xf2800910, 0xfeb80db0, "vorr%c.i16\t%12-15,22R, %E"}, 603 {FPU_NEON_EXT_V1, 0xf2800930, 0xfeb80db0, "vbic%c.i16\t%12-15,22R, %E"}, 604 {FPU_NEON_EXT_V1, 0xf2800c10, 0xfeb80eb0, "vmov%c.i32\t%12-15,22R, %E"}, 605 {FPU_NEON_EXT_V1, 0xf2800c30, 0xfeb80eb0, "vmvn%c.i32\t%12-15,22R, %E"}, 606 {FPU_NEON_EXT_V1, 0xf2800110, 0xfeb809b0, "vorr%c.i32\t%12-15,22R, %E"}, 607 {FPU_NEON_EXT_V1, 0xf2800130, 0xfeb809b0, "vbic%c.i32\t%12-15,22R, %E"}, 608 {FPU_NEON_EXT_V1, 0xf2800010, 0xfeb808b0, "vmov%c.i32\t%12-15,22R, %E"}, 609 {FPU_NEON_EXT_V1, 0xf2800030, 0xfeb808b0, "vmvn%c.i32\t%12-15,22R, %E"}, 610 611 /* Two registers and a shift amount */ 612 {FPU_NEON_EXT_V1, 0xf2880810, 0xffb80fd0, "vshrn%c.i16\t%12-15,22D, %0-3,5Q, #%16-18e"}, 613 {FPU_NEON_EXT_V1, 0xf2880850, 0xffb80fd0, "vrshrn%c.i16\t%12-15,22D, %0-3,5Q, #%16-18e"}, 614 {FPU_NEON_EXT_V1, 0xf2880810, 0xfeb80fd0, "vqshrun%c.s16\t%12-15,22D, %0-3,5Q, #%16-18e"}, 615 {FPU_NEON_EXT_V1, 0xf2880850, 0xfeb80fd0, "vqrshrun%c.s16\t%12-15,22D, %0-3,5Q, #%16-18e"}, 616 {FPU_NEON_EXT_V1, 0xf2880910, 0xfeb80fd0, "vqshrn%c.%24?us16\t%12-15,22D, %0-3,5Q, #%16-18e"}, 617 {FPU_NEON_EXT_V1, 0xf2880950, 0xfeb80fd0, "vqrshrn%c.%24?us16\t%12-15,22D, %0-3,5Q, #%16-18e"}, 618 {FPU_NEON_EXT_V1, 0xf2880a10, 0xfeb80fd0, "vshll%c.%24?us8\t%12-15,22D, %0-3,5Q, #%16-18d"}, 619 {FPU_NEON_EXT_V1, 0xf2900810, 0xffb00fd0, "vshrn%c.i32\t%12-15,22D, %0-3,5Q, #%16-19e"}, 620 {FPU_NEON_EXT_V1, 0xf2900850, 0xffb00fd0, "vrshrn%c.i32\t%12-15,22D, %0-3,5Q, #%16-19e"}, 621 {FPU_NEON_EXT_V1, 0xf2880510, 0xffb80f90, "vshl%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18d"}, 622 {FPU_NEON_EXT_V1, 0xf3880410, 0xffb80f90, "vsri%c.8\t%12-15,22R, %0-3,5R, #%16-18e"}, 623 {FPU_NEON_EXT_V1, 0xf3880510, 0xffb80f90, "vsli%c.8\t%12-15,22R, %0-3,5R, #%16-18d"}, 624 {FPU_NEON_EXT_V1, 0xf3880610, 0xffb80f90, "vqshlu%c.s8\t%12-15,22R, %0-3,5R, #%16-18d"}, 625 {FPU_NEON_EXT_V1, 0xf2900810, 0xfeb00fd0, "vqshrun%c.s32\t%12-15,22D, %0-3,5Q, #%16-19e"}, 626 {FPU_NEON_EXT_V1, 0xf2900850, 0xfeb00fd0, "vqrshrun%c.s32\t%12-15,22D, %0-3,5Q, #%16-19e"}, 627 {FPU_NEON_EXT_V1, 0xf2900910, 0xfeb00fd0, "vqshrn%c.%24?us32\t%12-15,22D, %0-3,5Q, #%16-19e"}, 628 {FPU_NEON_EXT_V1, 0xf2900950, 0xfeb00fd0, "vqrshrn%c.%24?us32\t%12-15,22D, %0-3,5Q, #%16-19e"}, 629 {FPU_NEON_EXT_V1, 0xf2900a10, 0xfeb00fd0, "vshll%c.%24?us16\t%12-15,22D, %0-3,5Q, #%16-19d"}, 630 {FPU_NEON_EXT_V1, 0xf2880010, 0xfeb80f90, "vshr%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"}, 631 {FPU_NEON_EXT_V1, 0xf2880110, 0xfeb80f90, "vsra%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"}, 632 {FPU_NEON_EXT_V1, 0xf2880210, 0xfeb80f90, "vrshr%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"}, 633 {FPU_NEON_EXT_V1, 0xf2880310, 0xfeb80f90, "vrsra%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"}, 634 {FPU_NEON_EXT_V1, 0xf2880710, 0xfeb80f90, "vqshl%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18d"}, 635 {FPU_NEON_EXT_V1, 0xf2a00810, 0xffa00fd0, "vshrn%c.i64\t%12-15,22D, %0-3,5Q, #%16-20e"}, 636 {FPU_NEON_EXT_V1, 0xf2a00850, 0xffa00fd0, "vrshrn%c.i64\t%12-15,22D, %0-3,5Q, #%16-20e"}, 637 {FPU_NEON_EXT_V1, 0xf2900510, 0xffb00f90, "vshl%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19d"}, 638 {FPU_NEON_EXT_V1, 0xf3900410, 0xffb00f90, "vsri%c.16\t%12-15,22R, %0-3,5R, #%16-19e"}, 639 {FPU_NEON_EXT_V1, 0xf3900510, 0xffb00f90, "vsli%c.16\t%12-15,22R, %0-3,5R, #%16-19d"}, 640 {FPU_NEON_EXT_V1, 0xf3900610, 0xffb00f90, "vqshlu%c.s16\t%12-15,22R, %0-3,5R, #%16-19d"}, 641 {FPU_NEON_EXT_V1, 0xf2a00a10, 0xfea00fd0, "vshll%c.%24?us32\t%12-15,22D, %0-3,5Q, #%16-20d"}, 642 {FPU_NEON_EXT_V1, 0xf2900010, 0xfeb00f90, "vshr%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"}, 643 {FPU_NEON_EXT_V1, 0xf2900110, 0xfeb00f90, "vsra%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"}, 644 {FPU_NEON_EXT_V1, 0xf2900210, 0xfeb00f90, "vrshr%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"}, 645 {FPU_NEON_EXT_V1, 0xf2900310, 0xfeb00f90, "vrsra%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"}, 646 {FPU_NEON_EXT_V1, 0xf2900710, 0xfeb00f90, "vqshl%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19d"}, 647 {FPU_NEON_EXT_V1, 0xf2800810, 0xfec00fd0, "vqshrun%c.s64\t%12-15,22D, %0-3,5Q, #%16-20e"}, 648 {FPU_NEON_EXT_V1, 0xf2800850, 0xfec00fd0, "vqrshrun%c.s64\t%12-15,22D, %0-3,5Q, #%16-20e"}, 649 {FPU_NEON_EXT_V1, 0xf2800910, 0xfec00fd0, "vqshrn%c.%24?us64\t%12-15,22D, %0-3,5Q, #%16-20e"}, 650 {FPU_NEON_EXT_V1, 0xf2800950, 0xfec00fd0, "vqrshrn%c.%24?us64\t%12-15,22D, %0-3,5Q, #%16-20e"}, 651 {FPU_NEON_EXT_V1, 0xf2a00510, 0xffa00f90, "vshl%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20d"}, 652 {FPU_NEON_EXT_V1, 0xf3a00410, 0xffa00f90, "vsri%c.32\t%12-15,22R, %0-3,5R, #%16-20e"}, 653 {FPU_NEON_EXT_V1, 0xf3a00510, 0xffa00f90, "vsli%c.32\t%12-15,22R, %0-3,5R, #%16-20d"}, 654 {FPU_NEON_EXT_V1, 0xf3a00610, 0xffa00f90, "vqshlu%c.s32\t%12-15,22R, %0-3,5R, #%16-20d"}, 655 {FPU_NEON_EXT_V1, 0xf2a00010, 0xfea00f90, "vshr%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"}, 656 {FPU_NEON_EXT_V1, 0xf2a00110, 0xfea00f90, "vsra%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"}, 657 {FPU_NEON_EXT_V1, 0xf2a00210, 0xfea00f90, "vrshr%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"}, 658 {FPU_NEON_EXT_V1, 0xf2a00310, 0xfea00f90, "vrsra%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"}, 659 {FPU_NEON_EXT_V1, 0xf2a00710, 0xfea00f90, "vqshl%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20d"}, 660 {FPU_NEON_EXT_V1, 0xf2800590, 0xff800f90, "vshl%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21d"}, 661 {FPU_NEON_EXT_V1, 0xf3800490, 0xff800f90, "vsri%c.64\t%12-15,22R, %0-3,5R, #%16-21e"}, 662 {FPU_NEON_EXT_V1, 0xf3800590, 0xff800f90, "vsli%c.64\t%12-15,22R, %0-3,5R, #%16-21d"}, 663 {FPU_NEON_EXT_V1, 0xf3800690, 0xff800f90, "vqshlu%c.s64\t%12-15,22R, %0-3,5R, #%16-21d"}, 664 {FPU_NEON_EXT_V1, 0xf2800090, 0xfe800f90, "vshr%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"}, 665 {FPU_NEON_EXT_V1, 0xf2800190, 0xfe800f90, "vsra%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"}, 666 {FPU_NEON_EXT_V1, 0xf2800290, 0xfe800f90, "vrshr%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"}, 667 {FPU_NEON_EXT_V1, 0xf2800390, 0xfe800f90, "vrsra%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"}, 668 {FPU_NEON_EXT_V1, 0xf2800790, 0xfe800f90, "vqshl%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21d"}, 669 {FPU_NEON_EXT_V1, 0xf2a00e10, 0xfea00e90, "vcvt%c.%24,8?usff32.%24,8?ffus32\t%12-15,22R, %0-3,5R, #%16-20e"}, 670 671 /* Three registers of different lengths */ 672 {FPU_NEON_EXT_V1, 0xf2800e00, 0xfea00f50, "vmull%c.p%20S0\t%12-15,22Q, %16-19,7D, %0-3,5D"}, 673 {FPU_NEON_EXT_V1, 0xf2800400, 0xff800f50, "vaddhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"}, 674 {FPU_NEON_EXT_V1, 0xf2800600, 0xff800f50, "vsubhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"}, 675 {FPU_NEON_EXT_V1, 0xf2800900, 0xff800f50, "vqdmlal%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %0-3,5D"}, 676 {FPU_NEON_EXT_V1, 0xf2800b00, 0xff800f50, "vqdmlsl%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %0-3,5D"}, 677 {FPU_NEON_EXT_V1, 0xf2800d00, 0xff800f50, "vqdmull%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %0-3,5D"}, 678 {FPU_NEON_EXT_V1, 0xf3800400, 0xff800f50, "vraddhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"}, 679 {FPU_NEON_EXT_V1, 0xf3800600, 0xff800f50, "vrsubhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"}, 680 {FPU_NEON_EXT_V1, 0xf2800000, 0xfe800f50, "vaddl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"}, 681 {FPU_NEON_EXT_V1, 0xf2800100, 0xfe800f50, "vaddw%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7Q, %0-3,5D"}, 682 {FPU_NEON_EXT_V1, 0xf2800200, 0xfe800f50, "vsubl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"}, 683 {FPU_NEON_EXT_V1, 0xf2800300, 0xfe800f50, "vsubw%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7Q, %0-3,5D"}, 684 {FPU_NEON_EXT_V1, 0xf2800500, 0xfe800f50, "vabal%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"}, 685 {FPU_NEON_EXT_V1, 0xf2800700, 0xfe800f50, "vabdl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"}, 686 {FPU_NEON_EXT_V1, 0xf2800800, 0xfe800f50, "vmlal%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"}, 687 {FPU_NEON_EXT_V1, 0xf2800a00, 0xfe800f50, "vmlsl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"}, 688 {FPU_NEON_EXT_V1, 0xf2800c00, 0xfe800f50, "vmull%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"}, 689 690 /* Two registers and a scalar */ 691 {FPU_NEON_EXT_V1, 0xf2800040, 0xff800f50, "vmla%c.i%20-21S6\t%12-15,22D, %16-19,7D, %D"}, 692 {FPU_NEON_EXT_V1, 0xf2800140, 0xff800f50, "vmla%c.f%20-21Sa\t%12-15,22D, %16-19,7D, %D"}, 693 {FPU_NEON_EXT_V1, 0xf2800340, 0xff800f50, "vqdmlal%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"}, 694 {FPU_NEON_EXT_V1, 0xf2800440, 0xff800f50, "vmls%c.i%20-21S6\t%12-15,22D, %16-19,7D, %D"}, 695 {FPU_NEON_EXT_V1, 0xf2800540, 0xff800f50, "vmls%c.f%20-21S6\t%12-15,22D, %16-19,7D, %D"}, 696 {FPU_NEON_EXT_V1, 0xf2800740, 0xff800f50, "vqdmlsl%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"}, 697 {FPU_NEON_EXT_V1, 0xf2800840, 0xff800f50, "vmul%c.i%20-21S6\t%12-15,22D, %16-19,7D, %D"}, 698 {FPU_NEON_EXT_V1, 0xf2800940, 0xff800f50, "vmul%c.f%20-21Sa\t%12-15,22D, %16-19,7D, %D"}, 699 {FPU_NEON_EXT_V1, 0xf2800b40, 0xff800f50, "vqdmull%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"}, 700 {FPU_NEON_EXT_V1, 0xf2800c40, 0xff800f50, "vqdmulh%c.s%20-21S6\t%12-15,22D, %16-19,7D, %D"}, 701 {FPU_NEON_EXT_V1, 0xf2800d40, 0xff800f50, "vqrdmulh%c.s%20-21S6\t%12-15,22D, %16-19,7D, %D"}, 702 {FPU_NEON_EXT_V1, 0xf3800040, 0xff800f50, "vmla%c.i%20-21S6\t%12-15,22Q, %16-19,7Q, %D"}, 703 {FPU_NEON_EXT_V1, 0xf3800140, 0xff800f50, "vmla%c.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"}, 704 {FPU_NEON_EXT_V1, 0xf3800440, 0xff800f50, "vmls%c.i%20-21S6\t%12-15,22Q, %16-19,7Q, %D"}, 705 {FPU_NEON_EXT_V1, 0xf3800540, 0xff800f50, "vmls%c.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"}, 706 {FPU_NEON_EXT_V1, 0xf3800840, 0xff800f50, "vmul%c.i%20-21S6\t%12-15,22Q, %16-19,7Q, %D"}, 707 {FPU_NEON_EXT_V1, 0xf3800940, 0xff800f50, "vmul%c.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"}, 708 {FPU_NEON_EXT_V1, 0xf3800c40, 0xff800f50, "vqdmulh%c.s%20-21S6\t%12-15,22Q, %16-19,7Q, %D"}, 709 {FPU_NEON_EXT_V1, 0xf3800d40, 0xff800f50, "vqrdmulh%c.s%20-21S6\t%12-15,22Q, %16-19,7Q, %D"}, 710 {FPU_NEON_EXT_V1, 0xf2800240, 0xfe800f50, "vmlal%c.%24?us%20-21S6\t%12-15,22Q, %16-19,7D, %D"}, 711 {FPU_NEON_EXT_V1, 0xf2800640, 0xfe800f50, "vmlsl%c.%24?us%20-21S6\t%12-15,22Q, %16-19,7D, %D"}, 712 {FPU_NEON_EXT_V1, 0xf2800a40, 0xfe800f50, "vmull%c.%24?us%20-21S6\t%12-15,22Q, %16-19,7D, %D"}, 713 714 /* Element and structure load/store */ 715 {FPU_NEON_EXT_V1, 0xf4a00fc0, 0xffb00fc0, "vld4%c.32\t%C"}, 716 {FPU_NEON_EXT_V1, 0xf4a00c00, 0xffb00f00, "vld1%c.%6-7S2\t%C"}, 717 {FPU_NEON_EXT_V1, 0xf4a00d00, 0xffb00f00, "vld2%c.%6-7S2\t%C"}, 718 {FPU_NEON_EXT_V1, 0xf4a00e00, 0xffb00f00, "vld3%c.%6-7S2\t%C"}, 719 {FPU_NEON_EXT_V1, 0xf4a00f00, 0xffb00f00, "vld4%c.%6-7S2\t%C"}, 720 {FPU_NEON_EXT_V1, 0xf4000200, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"}, 721 {FPU_NEON_EXT_V1, 0xf4000300, 0xff900f00, "v%21?ls%21?dt2%c.%6-7S2\t%A"}, 722 {FPU_NEON_EXT_V1, 0xf4000400, 0xff900f00, "v%21?ls%21?dt3%c.%6-7S2\t%A"}, 723 {FPU_NEON_EXT_V1, 0xf4000500, 0xff900f00, "v%21?ls%21?dt3%c.%6-7S2\t%A"}, 724 {FPU_NEON_EXT_V1, 0xf4000600, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"}, 725 {FPU_NEON_EXT_V1, 0xf4000700, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"}, 726 {FPU_NEON_EXT_V1, 0xf4000800, 0xff900f00, "v%21?ls%21?dt2%c.%6-7S2\t%A"}, 727 {FPU_NEON_EXT_V1, 0xf4000900, 0xff900f00, "v%21?ls%21?dt2%c.%6-7S2\t%A"}, 728 {FPU_NEON_EXT_V1, 0xf4000a00, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"}, 729 {FPU_NEON_EXT_V1, 0xf4000000, 0xff900e00, "v%21?ls%21?dt4%c.%6-7S2\t%A"}, 730 {FPU_NEON_EXT_V1, 0xf4800000, 0xff900300, "v%21?ls%21?dt1%c.%10-11S2\t%B"}, 731 {FPU_NEON_EXT_V1, 0xf4800100, 0xff900300, "v%21?ls%21?dt2%c.%10-11S2\t%B"}, 732 {FPU_NEON_EXT_V1, 0xf4800200, 0xff900300, "v%21?ls%21?dt3%c.%10-11S2\t%B"}, 733 {FPU_NEON_EXT_V1, 0xf4800300, 0xff900300, "v%21?ls%21?dt4%c.%10-11S2\t%B"}, 734 735 {0,0 ,0, 0} 736}; 737 738/* Opcode tables: ARM, 16-bit Thumb, 32-bit Thumb. All three are partially 739 ordered: they must be searched linearly from the top to obtain a correct 740 match. */ 741 742/* print_insn_arm recognizes the following format control codes: 743 744 %% % 745 746 %a print address for ldr/str instruction 747 %s print address for ldr/str halfword/signextend instruction 748 %b print branch destination 749 %c print condition code (always bits 28-31) 750 %m print register mask for ldm/stm instruction 751 %o print operand2 (immediate or register + shift) 752 %p print 'p' iff bits 12-15 are 15 753 %t print 't' iff bit 21 set and bit 24 clear 754 %B print arm BLX(1) destination 755 %C print the PSR sub type. 756 %U print barrier type. 757 %P print address for pli instruction. 758 759 %<bitfield>r print as an ARM register 760 %<bitfield>d print the bitfield in decimal 761 %<bitfield>W print the bitfield plus one in decimal 762 %<bitfield>x print the bitfield in hex 763 %<bitfield>X print the bitfield as 1 hex digit without leading "0x" 764 765 %<bitfield>'c print specified char iff bitfield is all ones 766 %<bitfield>`c print specified char iff bitfield is all zeroes 767 %<bitfield>?ab... select from array of values in big endian order 768 769 %e print arm SMI operand (bits 0..7,8..19). 770 %E print the LSB and WIDTH fields of a BFI or BFC instruction. 771 %V print the 16-bit immediate field of a MOVT or MOVW instruction. */ 772 773static const struct opcode32 arm_opcodes[] = 774{ 775 /* ARM instructions. */ 776 {ARM_EXT_V1, 0xe1a00000, 0xffffffff, "nop\t\t\t(mov r0,r0)"}, 777 {ARM_EXT_V4T | ARM_EXT_V5, 0x012FFF10, 0x0ffffff0, "bx%c\t%0-3r"}, 778 {ARM_EXT_V2, 0x00000090, 0x0fe000f0, "mul%20's%c\t%16-19r, %0-3r, %8-11r"}, 779 {ARM_EXT_V2, 0x00200090, 0x0fe000f0, "mla%20's%c\t%16-19r, %0-3r, %8-11r, %12-15r"}, 780 {ARM_EXT_V2S, 0x01000090, 0x0fb00ff0, "swp%22'b%c\t%12-15r, %0-3r, [%16-19r]"}, 781 {ARM_EXT_V3M, 0x00800090, 0x0fa000f0, "%22?sumull%20's%c\t%12-15r, %16-19r, %0-3r, %8-11r"}, 782 {ARM_EXT_V3M, 0x00a00090, 0x0fa000f0, "%22?sumlal%20's%c\t%12-15r, %16-19r, %0-3r, %8-11r"}, 783 784 /* V7 instructions. */ 785 {ARM_EXT_V7, 0xf450f000, 0xfd70f000, "pli\t%P"}, 786 {ARM_EXT_V7, 0x0320f0f0, 0x0ffffff0, "dbg%c\t#%0-3d"}, 787 {ARM_EXT_V7, 0xf57ff050, 0xfffffff0, "dmb\t%U"}, 788 {ARM_EXT_V7, 0xf57ff040, 0xfffffff0, "dsb\t%U"}, 789 {ARM_EXT_V7, 0xf57ff060, 0xfffffff0, "isb\t%U"}, 790 791 /* ARM V6T2 instructions. */ 792 {ARM_EXT_V6T2, 0x07c0001f, 0x0fe0007f, "bfc%c\t%12-15r, %E"}, 793 {ARM_EXT_V6T2, 0x07c00010, 0x0fe00070, "bfi%c\t%12-15r, %0-3r, %E"}, 794 {ARM_EXT_V6T2, 0x00600090, 0x0ff000f0, "mls%c\t%16-19r, %0-3r, %8-11r, %12-15r"}, 795 {ARM_EXT_V6T2, 0x006000b0, 0x0f7000f0, "strht%c\t%12-15r, %s"}, 796 {ARM_EXT_V6T2, 0x00300090, 0x0f300090, "ldr%6's%5?hbt%c\t%12-15r, %s"}, 797 {ARM_EXT_V6T2, 0x03000000, 0x0ff00000, "movw%c\t%12-15r, %V"}, 798 {ARM_EXT_V6T2, 0x03400000, 0x0ff00000, "movt%c\t%12-15r, %V"}, 799 {ARM_EXT_V6T2, 0x06ff0f30, 0x0fff0ff0, "rbit%c\t%12-15r, %0-3r"}, 800 {ARM_EXT_V6T2, 0x07a00050, 0x0fa00070, "%22?usbfx%c\t%12-15r, %0-3r, #%7-11d, #%16-20W"}, 801 802 /* ARM V6Z instructions. */ 803 {ARM_EXT_V6Z, 0x01600070, 0x0ff000f0, "smc%c\t%e"}, 804 805 /* ARM V6K instructions. */ 806 {ARM_EXT_V6K, 0xf57ff01f, 0xffffffff, "clrex"}, 807 {ARM_EXT_V6K, 0x01d00f9f, 0x0ff00fff, "ldrexb%c\t%12-15r, [%16-19r]"}, 808 {ARM_EXT_V6K, 0x01b00f9f, 0x0ff00fff, "ldrexd%c\t%12-15r, [%16-19r]"}, 809 {ARM_EXT_V6K, 0x01f00f9f, 0x0ff00fff, "ldrexh%c\t%12-15r, [%16-19r]"}, 810 {ARM_EXT_V6K, 0x01c00f90, 0x0ff00ff0, "strexb%c\t%12-15r, %0-3r, [%16-19r]"}, 811 {ARM_EXT_V6K, 0x01a00f90, 0x0ff00ff0, "strexd%c\t%12-15r, %0-3r, [%16-19r]"}, 812 {ARM_EXT_V6K, 0x01e00f90, 0x0ff00ff0, "strexh%c\t%12-15r, %0-3r, [%16-19r]"}, 813 814 /* ARM V6K NOP hints. */ 815 {ARM_EXT_V6K, 0x0320f001, 0x0fffffff, "yield%c"}, 816 {ARM_EXT_V6K, 0x0320f002, 0x0fffffff, "wfe%c"}, 817 {ARM_EXT_V6K, 0x0320f003, 0x0fffffff, "wfi%c"}, 818 {ARM_EXT_V6K, 0x0320f004, 0x0fffffff, "sev%c"}, 819 {ARM_EXT_V6K, 0x0320f000, 0x0fffff00, "nop%c\t{%0-7d}"}, 820 821 /* ARM V6 instructions. */ 822 {ARM_EXT_V6, 0xf1080000, 0xfffffe3f, "cpsie\t%8'a%7'i%6'f"}, 823 {ARM_EXT_V6, 0xf10a0000, 0xfffffe20, "cpsie\t%8'a%7'i%6'f,#%0-4d"}, 824 {ARM_EXT_V6, 0xf10C0000, 0xfffffe3f, "cpsid\t%8'a%7'i%6'f"}, 825 {ARM_EXT_V6, 0xf10e0000, 0xfffffe20, "cpsid\t%8'a%7'i%6'f,#%0-4d"}, 826 {ARM_EXT_V6, 0xf1000000, 0xfff1fe20, "cps\t#%0-4d"}, 827 {ARM_EXT_V6, 0x06800010, 0x0ff00ff0, "pkhbt%c\t%12-15r, %16-19r, %0-3r"}, 828 {ARM_EXT_V6, 0x06800010, 0x0ff00070, "pkhbt%c\t%12-15r, %16-19r, %0-3r, lsl #%7-11d"}, 829 {ARM_EXT_V6, 0x06800050, 0x0ff00ff0, "pkhtb%c\t%12-15r, %16-19r, %0-3r, asr #32"}, 830 {ARM_EXT_V6, 0x06800050, 0x0ff00070, "pkhtb%c\t%12-15r, %16-19r, %0-3r, asr #%7-11d"}, 831 {ARM_EXT_V6, 0x01900f9f, 0x0ff00fff, "ldrex%c\tr%12-15d, [%16-19r]"}, 832 {ARM_EXT_V6, 0x06200f10, 0x0ff00ff0, "qadd16%c\t%12-15r, %16-19r, %0-3r"}, 833 {ARM_EXT_V6, 0x06200f90, 0x0ff00ff0, "qadd8%c\t%12-15r, %16-19r, %0-3r"}, 834 {ARM_EXT_V6, 0x06200f30, 0x0ff00ff0, "qaddsubx%c\t%12-15r, %16-19r, %0-3r"}, 835 {ARM_EXT_V6, 0x06200f70, 0x0ff00ff0, "qsub16%c\t%12-15r, %16-19r, %0-3r"}, 836 {ARM_EXT_V6, 0x06200ff0, 0x0ff00ff0, "qsub8%c\t%12-15r, %16-19r, %0-3r"}, 837 {ARM_EXT_V6, 0x06200f50, 0x0ff00ff0, "qsubaddx%c\t%12-15r, %16-19r, %0-3r"}, 838 {ARM_EXT_V6, 0x06100f10, 0x0ff00ff0, "sadd16%c\t%12-15r, %16-19r, %0-3r"}, 839 {ARM_EXT_V6, 0x06100f90, 0x0ff00ff0, "sadd8%c\t%12-15r, %16-19r, %0-3r"}, 840 {ARM_EXT_V6, 0x06100f30, 0x0ff00ff0, "saddaddx%c\t%12-15r, %16-19r, %0-3r"}, 841 {ARM_EXT_V6, 0x06300f10, 0x0ff00ff0, "shadd16%c\t%12-15r, %16-19r, %0-3r"}, 842 {ARM_EXT_V6, 0x06300f90, 0x0ff00ff0, "shadd8%c\t%12-15r, %16-19r, %0-3r"}, 843 {ARM_EXT_V6, 0x06300f30, 0x0ff00ff0, "shaddsubx%c\t%12-15r, %16-19r, %0-3r"}, 844 {ARM_EXT_V6, 0x06300f70, 0x0ff00ff0, "shsub16%c\t%12-15r, %16-19r, %0-3r"}, 845 {ARM_EXT_V6, 0x06300ff0, 0x0ff00ff0, "shsub8%c\t%12-15r, %16-19r, %0-3r"}, 846 {ARM_EXT_V6, 0x06300f50, 0x0ff00ff0, "shsubaddx%c\t%12-15r, %16-19r, %0-3r"}, 847 {ARM_EXT_V6, 0x06100f70, 0x0ff00ff0, "ssub16%c\t%12-15r, %16-19r, %0-3r"}, 848 {ARM_EXT_V6, 0x06100ff0, 0x0ff00ff0, "ssub8%c\t%12-15r, %16-19r, %0-3r"}, 849 {ARM_EXT_V6, 0x06100f50, 0x0ff00ff0, "ssubaddx%c\t%12-15r, %16-19r, %0-3r"}, 850 {ARM_EXT_V6, 0x06500f10, 0x0ff00ff0, "uadd16%c\t%12-15r, %16-19r, %0-3r"}, 851 {ARM_EXT_V6, 0x06500f90, 0x0ff00ff0, "uadd8%c\t%12-15r, %16-19r, %0-3r"}, 852 {ARM_EXT_V6, 0x06500f30, 0x0ff00ff0, "uaddsubx%c\t%12-15r, %16-19r, %0-3r"}, 853 {ARM_EXT_V6, 0x06700f10, 0x0ff00ff0, "uhadd16%c\t%12-15r, %16-19r, %0-3r"}, 854 {ARM_EXT_V6, 0x06700f90, 0x0ff00ff0, "uhadd8%c\t%12-15r, %16-19r, %0-3r"}, 855 {ARM_EXT_V6, 0x06700f30, 0x0ff00ff0, "uhaddsubx%c\t%12-15r, %16-19r, %0-3r"}, 856 {ARM_EXT_V6, 0x06700f70, 0x0ff00ff0, "uhsub16%c\t%12-15r, %16-19r, %0-3r"}, 857 {ARM_EXT_V6, 0x06700ff0, 0x0ff00ff0, "uhsub8%c\t%12-15r, %16-19r, %0-3r"}, 858 {ARM_EXT_V6, 0x06700f50, 0x0ff00ff0, "uhsubaddx%c\t%12-15r, %16-19r, %0-3r"}, 859 {ARM_EXT_V6, 0x06600f10, 0x0ff00ff0, "uqadd16%c\t%12-15r, %16-19r, %0-3r"}, 860 {ARM_EXT_V6, 0x06600f90, 0x0ff00ff0, "uqadd8%c\t%12-15r, %16-19r, %0-3r"}, 861 {ARM_EXT_V6, 0x06600f30, 0x0ff00ff0, "uqaddsubx%c\t%12-15r, %16-19r, %0-3r"}, 862 {ARM_EXT_V6, 0x06600f70, 0x0ff00ff0, "uqsub16%c\t%12-15r, %16-19r, %0-3r"}, 863 {ARM_EXT_V6, 0x06600ff0, 0x0ff00ff0, "uqsub8%c\t%12-15r, %16-19r, %0-3r"}, 864 {ARM_EXT_V6, 0x06600f50, 0x0ff00ff0, "uqsubaddx%c\t%12-15r, %16-19r, %0-3r"}, 865 {ARM_EXT_V6, 0x06500f70, 0x0ff00ff0, "usub16%c\t%12-15r, %16-19r, %0-3r"}, 866 {ARM_EXT_V6, 0x06500ff0, 0x0ff00ff0, "usub8%c\t%12-15r, %16-19r, %0-3r"}, 867 {ARM_EXT_V6, 0x06500f50, 0x0ff00ff0, "usubaddx%c\t%12-15r, %16-19r, %0-3r"}, 868 {ARM_EXT_V6, 0x06bf0f30, 0x0fff0ff0, "rev%c\t\%12-15r, %0-3r"}, 869 {ARM_EXT_V6, 0x06bf0fb0, 0x0fff0ff0, "rev16%c\t\%12-15r, %0-3r"}, 870 {ARM_EXT_V6, 0x06ff0fb0, 0x0fff0ff0, "revsh%c\t\%12-15r, %0-3r"}, 871 {ARM_EXT_V6, 0xf8100a00, 0xfe50ffff, "rfe%23?id%24?ba\t\%16-19r%21'!"}, 872 {ARM_EXT_V6, 0x06bf0070, 0x0fff0ff0, "sxth%c\t%12-15r, %0-3r"}, 873 {ARM_EXT_V6, 0x06bf0470, 0x0fff0ff0, "sxth%c\t%12-15r, %0-3r, ror #8"}, 874 {ARM_EXT_V6, 0x06bf0870, 0x0fff0ff0, "sxth%c\t%12-15r, %0-3r, ror #16"}, 875 {ARM_EXT_V6, 0x06bf0c70, 0x0fff0ff0, "sxth%c\t%12-15r, %0-3r, ror #24"}, 876 {ARM_EXT_V6, 0x068f0070, 0x0fff0ff0, "sxtb16%c\t%12-15r, %0-3r"}, 877 {ARM_EXT_V6, 0x068f0470, 0x0fff0ff0, "sxtb16%c\t%12-15r, %0-3r, ror #8"}, 878 {ARM_EXT_V6, 0x068f0870, 0x0fff0ff0, "sxtb16%c\t%12-15r, %0-3r, ror #16"}, 879 {ARM_EXT_V6, 0x068f0c70, 0x0fff0ff0, "sxtb16%c\t%12-15r, %0-3r, ror #24"}, 880 {ARM_EXT_V6, 0x06af0070, 0x0fff0ff0, "sxtb%c\t%12-15r, %0-3r"}, 881 {ARM_EXT_V6, 0x06af0470, 0x0fff0ff0, "sxtb%c\t%12-15r, %0-3r, ror #8"}, 882 {ARM_EXT_V6, 0x06af0870, 0x0fff0ff0, "sxtb%c\t%12-15r, %0-3r, ror #16"}, 883 {ARM_EXT_V6, 0x06af0c70, 0x0fff0ff0, "sxtb%c\t%12-15r, %0-3r, ror #24"}, 884 {ARM_EXT_V6, 0x06ff0070, 0x0fff0ff0, "uxth%c\t%12-15r, %0-3r"}, 885 {ARM_EXT_V6, 0x06ff0470, 0x0fff0ff0, "uxth%c\t%12-15r, %0-3r, ror #8"}, 886 {ARM_EXT_V6, 0x06ff0870, 0x0fff0ff0, "uxth%c\t%12-15r, %0-3r, ror #16"}, 887 {ARM_EXT_V6, 0x06ff0c70, 0x0fff0ff0, "uxth%c\t%12-15r, %0-3r, ror #24"}, 888 {ARM_EXT_V6, 0x06cf0070, 0x0fff0ff0, "uxtb16%c\t%12-15r, %0-3r"}, 889 {ARM_EXT_V6, 0x06cf0470, 0x0fff0ff0, "uxtb16%c\t%12-15r, %0-3r, ror #8"}, 890 {ARM_EXT_V6, 0x06cf0870, 0x0fff0ff0, "uxtb16%c\t%12-15r, %0-3r, ror #16"}, 891 {ARM_EXT_V6, 0x06cf0c70, 0x0fff0ff0, "uxtb16%c\t%12-15r, %0-3r, ror #24"}, 892 {ARM_EXT_V6, 0x06ef0070, 0x0fff0ff0, "uxtb%c\t%12-15r, %0-3r"}, 893 {ARM_EXT_V6, 0x06ef0470, 0x0fff0ff0, "uxtb%c\t%12-15r, %0-3r, ror #8"}, 894 {ARM_EXT_V6, 0x06ef0870, 0x0fff0ff0, "uxtb%c\t%12-15r, %0-3r, ror #16"}, 895 {ARM_EXT_V6, 0x06ef0c70, 0x0fff0ff0, "uxtb%c\t%12-15r, %0-3r, ror #24"}, 896 {ARM_EXT_V6, 0x06b00070, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r"}, 897 {ARM_EXT_V6, 0x06b00470, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ror #8"}, 898 {ARM_EXT_V6, 0x06b00870, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ror #16"}, 899 {ARM_EXT_V6, 0x06b00c70, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ror #24"}, 900 {ARM_EXT_V6, 0x06800070, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r"}, 901 {ARM_EXT_V6, 0x06800470, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ror #8"}, 902 {ARM_EXT_V6, 0x06800870, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ror #16"}, 903 {ARM_EXT_V6, 0x06800c70, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ror #24"}, 904 {ARM_EXT_V6, 0x06a00070, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r"}, 905 {ARM_EXT_V6, 0x06a00470, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ror #8"}, 906 {ARM_EXT_V6, 0x06a00870, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ror #16"}, 907 {ARM_EXT_V6, 0x06a00c70, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ror #24"}, 908 {ARM_EXT_V6, 0x06f00070, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r"}, 909 {ARM_EXT_V6, 0x06f00470, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ror #8"}, 910 {ARM_EXT_V6, 0x06f00870, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ror #16"}, 911 {ARM_EXT_V6, 0x06f00c70, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ror #24"}, 912 {ARM_EXT_V6, 0x06c00070, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r"}, 913 {ARM_EXT_V6, 0x06c00470, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ror #8"}, 914 {ARM_EXT_V6, 0x06c00870, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ror #16"}, 915 {ARM_EXT_V6, 0x06c00c70, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #24"}, 916 {ARM_EXT_V6, 0x06e00070, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r"}, 917 {ARM_EXT_V6, 0x06e00470, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ror #8"}, 918 {ARM_EXT_V6, 0x06e00870, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ror #16"}, 919 {ARM_EXT_V6, 0x06e00c70, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ror #24"}, 920 {ARM_EXT_V6, 0x06800fb0, 0x0ff00ff0, "sel%c\t%12-15r, %16-19r, %0-3r"}, 921 {ARM_EXT_V6, 0xf1010000, 0xfffffc00, "setend\t%9?ble"}, 922 {ARM_EXT_V6, 0x0700f010, 0x0ff0f0d0, "smuad%5'x%c\t%16-19r, %0-3r, %8-11r"}, 923 {ARM_EXT_V6, 0x0700f050, 0x0ff0f0d0, "smusd%5'x%c\t%16-19r, %0-3r, %8-11r"}, 924 {ARM_EXT_V6, 0x07000010, 0x0ff000d0, "smlad%5'x%c\t%16-19r, %0-3r, %8-11r, %12-15r"}, 925 {ARM_EXT_V6, 0x07400010, 0x0ff000d0, "smlald%5'x%c\t%12-15r, %16-19r, %0-3r, %8-11r"}, 926 {ARM_EXT_V6, 0x07000050, 0x0ff000d0, "smlsd%5'x%c\t%16-19r, %0-3r, %8-11r, %12-15r"}, 927 {ARM_EXT_V6, 0x07400050, 0x0ff000d0, "smlsld%5'x%c\t%12-15r, %16-19r, %0-3r, %8-11r"}, 928 {ARM_EXT_V6, 0x0750f010, 0x0ff0f0d0, "smmul%5'r%c\t%16-19r, %0-3r, %8-11r"}, 929 {ARM_EXT_V6, 0x07500010, 0x0ff000d0, "smmla%5'r%c\t%16-19r, %0-3r, %8-11r, %12-15r"}, 930 {ARM_EXT_V6, 0x075000d0, 0x0ff000d0, "smmls%5'r%c\t%16-19r, %0-3r, %8-11r, %12-15r"}, 931 {ARM_EXT_V6, 0xf84d0500, 0xfe5fffe0, "srs%23?id%24?ba\t%16-19r%21'!, #%0-4d"}, 932 {ARM_EXT_V6, 0x06a00010, 0x0fe00ff0, "ssat%c\t%12-15r, #%16-20W, %0-3r"}, 933 {ARM_EXT_V6, 0x06a00010, 0x0fe00070, "ssat%c\t%12-15r, #%16-20W, %0-3r, lsl #%7-11d"}, 934 {ARM_EXT_V6, 0x06a00050, 0x0fe00070, "ssat%c\t%12-15r, #%16-20W, %0-3r, asr #%7-11d"}, 935 {ARM_EXT_V6, 0x06a00f30, 0x0ff00ff0, "ssat16%c\t%12-15r, #%16-19W, %0-3r"}, 936 {ARM_EXT_V6, 0x01800f90, 0x0ff00ff0, "strex%c\t%12-15r, %0-3r, [%16-19r]"}, 937 {ARM_EXT_V6, 0x00400090, 0x0ff000f0, "umaal%c\t%12-15r, %16-19r, %0-3r, %8-11r"}, 938 {ARM_EXT_V6, 0x0780f010, 0x0ff0f0f0, "usad8%c\t%16-19r, %0-3r, %8-11r"}, 939 {ARM_EXT_V6, 0x07800010, 0x0ff000f0, "usada8%c\t%16-19r, %0-3r, %8-11r, %12-15r"}, 940 {ARM_EXT_V6, 0x06e00010, 0x0fe00ff0, "usat%c\t%12-15r, #%16-20d, %0-3r"}, 941 {ARM_EXT_V6, 0x06e00010, 0x0fe00070, "usat%c\t%12-15r, #%16-20d, %0-3r, lsl #%7-11d"}, 942 {ARM_EXT_V6, 0x06e00050, 0x0fe00070, "usat%c\t%12-15r, #%16-20d, %0-3r, asr #%7-11d"}, 943 {ARM_EXT_V6, 0x06e00f30, 0x0ff00ff0, "usat16%c\t%12-15r, #%16-19d, %0-3r"}, 944 945 /* V5J instruction. */ 946 {ARM_EXT_V5J, 0x012fff20, 0x0ffffff0, "bxj%c\t%0-3r"}, 947 948 /* V5 Instructions. */ 949 {ARM_EXT_V5, 0xe1200070, 0xfff000f0, "bkpt\t0x%16-19X%12-15X%8-11X%0-3X"}, 950 {ARM_EXT_V5, 0xfa000000, 0xfe000000, "blx\t%B"}, 951 {ARM_EXT_V5, 0x012fff30, 0x0ffffff0, "blx%c\t%0-3r"}, 952 {ARM_EXT_V5, 0x016f0f10, 0x0fff0ff0, "clz%c\t%12-15r, %0-3r"}, 953 954 /* V5E "El Segundo" Instructions. */ 955 {ARM_EXT_V5E, 0x000000d0, 0x0e1000f0, "ldrd%c\t%12-15r, %s"}, 956 {ARM_EXT_V5E, 0x000000f0, 0x0e1000f0, "strd%c\t%12-15r, %s"}, 957 {ARM_EXT_V5E, 0xf450f000, 0xfc70f000, "pld\t%a"}, 958 {ARM_EXT_V5ExP, 0x01000080, 0x0ff000f0, "smlabb%c\t%16-19r, %0-3r, %8-11r, %12-15r"}, 959 {ARM_EXT_V5ExP, 0x010000a0, 0x0ff000f0, "smlatb%c\t%16-19r, %0-3r, %8-11r, %12-15r"}, 960 {ARM_EXT_V5ExP, 0x010000c0, 0x0ff000f0, "smlabt%c\t%16-19r, %0-3r, %8-11r, %12-15r"}, 961 {ARM_EXT_V5ExP, 0x010000e0, 0x0ff000f0, "smlatt%c\t%16-19r, %0-3r, %8-11r, %12-15r"}, 962 963 {ARM_EXT_V5ExP, 0x01200080, 0x0ff000f0, "smlawb%c\t%16-19r, %0-3r, %8-11r, %12-15r"}, 964 {ARM_EXT_V5ExP, 0x012000c0, 0x0ff000f0, "smlawt%c\t%16-19r, %0-3r, %8-11r, %12-15r"}, 965 966 {ARM_EXT_V5ExP, 0x01400080, 0x0ff000f0, "smlalbb%c\t%12-15r, %16-19r, %0-3r, %8-11r"}, 967 {ARM_EXT_V5ExP, 0x014000a0, 0x0ff000f0, "smlaltb%c\t%12-15r, %16-19r, %0-3r, %8-11r"}, 968 {ARM_EXT_V5ExP, 0x014000c0, 0x0ff000f0, "smlalbt%c\t%12-15r, %16-19r, %0-3r, %8-11r"}, 969 {ARM_EXT_V5ExP, 0x014000e0, 0x0ff000f0, "smlaltt%c\t%12-15r, %16-19r, %0-3r, %8-11r"}, 970 971 {ARM_EXT_V5ExP, 0x01600080, 0x0ff0f0f0, "smulbb%c\t%16-19r, %0-3r, %8-11r"}, 972 {ARM_EXT_V5ExP, 0x016000a0, 0x0ff0f0f0, "smultb%c\t%16-19r, %0-3r, %8-11r"}, 973 {ARM_EXT_V5ExP, 0x016000c0, 0x0ff0f0f0, "smulbt%c\t%16-19r, %0-3r, %8-11r"}, 974 {ARM_EXT_V5ExP, 0x016000e0, 0x0ff0f0f0, "smultt%c\t%16-19r, %0-3r, %8-11r"}, 975 976 {ARM_EXT_V5ExP, 0x012000a0, 0x0ff0f0f0, "smulwb%c\t%16-19r, %0-3r, %8-11r"}, 977 {ARM_EXT_V5ExP, 0x012000e0, 0x0ff0f0f0, "smulwt%c\t%16-19r, %0-3r, %8-11r"}, 978 979 {ARM_EXT_V5ExP, 0x01000050, 0x0ff00ff0, "qadd%c\t%12-15r, %0-3r, %16-19r"}, 980 {ARM_EXT_V5ExP, 0x01400050, 0x0ff00ff0, "qdadd%c\t%12-15r, %0-3r, %16-19r"}, 981 {ARM_EXT_V5ExP, 0x01200050, 0x0ff00ff0, "qsub%c\t%12-15r, %0-3r, %16-19r"}, 982 {ARM_EXT_V5ExP, 0x01600050, 0x0ff00ff0, "qdsub%c\t%12-15r, %0-3r, %16-19r"}, 983 984 /* ARM Instructions. */ 985 {ARM_EXT_V1, 0x00000090, 0x0e100090, "str%6's%5?hb%c\t%12-15r, %s"}, 986 {ARM_EXT_V1, 0x00100090, 0x0e100090, "ldr%6's%5?hb%c\t%12-15r, %s"}, 987 {ARM_EXT_V1, 0x00000000, 0x0de00000, "and%20's%c\t%12-15r, %16-19r, %o"}, 988 {ARM_EXT_V1, 0x00200000, 0x0de00000, "eor%20's%c\t%12-15r, %16-19r, %o"}, 989 {ARM_EXT_V1, 0x00400000, 0x0de00000, "sub%20's%c\t%12-15r, %16-19r, %o"}, 990 {ARM_EXT_V1, 0x00600000, 0x0de00000, "rsb%20's%c\t%12-15r, %16-19r, %o"}, 991 {ARM_EXT_V1, 0x00800000, 0x0de00000, "add%20's%c\t%12-15r, %16-19r, %o"}, 992 {ARM_EXT_V1, 0x00a00000, 0x0de00000, "adc%20's%c\t%12-15r, %16-19r, %o"}, 993 {ARM_EXT_V1, 0x00c00000, 0x0de00000, "sbc%20's%c\t%12-15r, %16-19r, %o"}, 994 {ARM_EXT_V1, 0x00e00000, 0x0de00000, "rsc%20's%c\t%12-15r, %16-19r, %o"}, 995 {ARM_EXT_V3, 0x0120f000, 0x0db0f000, "msr%c\t%22?SCPSR%C, %o"}, 996 {ARM_EXT_V3, 0x010f0000, 0x0fbf0fff, "mrs%c\t%12-15r, %22?SCPSR"}, 997 {ARM_EXT_V1, 0x01000000, 0x0de00000, "tst%p%c\t%16-19r, %o"}, 998 {ARM_EXT_V1, 0x01200000, 0x0de00000, "teq%p%c\t%16-19r, %o"}, 999 {ARM_EXT_V1, 0x01400000, 0x0de00000, "cmp%p%c\t%16-19r, %o"}, 1000 {ARM_EXT_V1, 0x01600000, 0x0de00000, "cmn%p%c\t%16-19r, %o"}, 1001 {ARM_EXT_V1, 0x01800000, 0x0de00000, "orr%20's%c\t%12-15r, %16-19r, %o"}, 1002 {ARM_EXT_V1, 0x03a00000, 0x0fef0000, "mov%20's%c\t%12-15r, %o"}, 1003 {ARM_EXT_V1, 0x01a00000, 0x0def0ff0, "mov%20's%c\t%12-15r, %0-3r"}, 1004 {ARM_EXT_V1, 0x01a00000, 0x0def0060, "lsl%20's%c\t%12-15r, %q"}, 1005 {ARM_EXT_V1, 0x01a00020, 0x0def0060, "lsr%20's%c\t%12-15r, %q"}, 1006 {ARM_EXT_V1, 0x01a00040, 0x0def0060, "asr%20's%c\t%12-15r, %q"}, 1007 {ARM_EXT_V1, 0x01a00060, 0x0def0ff0, "rrx%20's%c\t%12-15r, %0-3r"}, 1008 {ARM_EXT_V1, 0x01a00060, 0x0def0060, "ror%20's%c\t%12-15r, %q"}, 1009 {ARM_EXT_V1, 0x01c00000, 0x0de00000, "bic%20's%c\t%12-15r, %16-19r, %o"}, 1010 {ARM_EXT_V1, 0x01e00000, 0x0de00000, "mvn%20's%c\t%12-15r, %o"}, 1011 {ARM_EXT_V1, 0x052d0004, 0x0fff0fff, "push%c\t{%12-15r}\t\t; (str%c %12-15r, %a)"}, 1012 {ARM_EXT_V1, 0x04000000, 0x0e100000, "str%22'b%t%c\t%12-15r, %a"}, 1013 {ARM_EXT_V1, 0x06000000, 0x0e100ff0, "str%22'b%t%c\t%12-15r, %a"}, 1014 {ARM_EXT_V1, 0x04000000, 0x0c100010, "str%22'b%t%c\t%12-15r, %a"}, 1015 {ARM_EXT_V1, 0x06000010, 0x0e000010, "undefined"}, 1016 {ARM_EXT_V1, 0x049d0004, 0x0fff0fff, "pop%c\t{%12-15r}\t\t; (ldr%c %12-15r, %a)"}, 1017 {ARM_EXT_V1, 0x04100000, 0x0c100000, "ldr%22'b%t%c\t%12-15r, %a"}, 1018 {ARM_EXT_V1, 0x092d0000, 0x0fff0000, "push%c\t%m"}, 1019 {ARM_EXT_V1, 0x08800000, 0x0ff00000, "stm%c\t%16-19r%21'!, %m%22'^"}, 1020 {ARM_EXT_V1, 0x08000000, 0x0e100000, "stm%23?id%24?ba%c\t%16-19r%21'!, %m%22'^"}, 1021 {ARM_EXT_V1, 0x08bd0000, 0x0fff0000, "pop%c\t%m"}, 1022 {ARM_EXT_V1, 0x08900000, 0x0f900000, "ldm%c\t%16-19r%21'!, %m%22'^"}, 1023 {ARM_EXT_V1, 0x08100000, 0x0e100000, "ldm%23?id%24?ba%c\t%16-19r%21'!, %m%22'^"}, 1024 {ARM_EXT_V1, 0x0a000000, 0x0e000000, "b%24'l%c\t%b"}, 1025 {ARM_EXT_V1, 0x0f000000, 0x0f000000, "svc%c\t%0-23x"}, 1026 1027 /* The rest. */ 1028 {ARM_EXT_V1, 0x00000000, 0x00000000, "undefined instruction %0-31x"}, 1029 {0, 0x00000000, 0x00000000, 0} 1030}; 1031 1032/* print_insn_thumb16 recognizes the following format control codes: 1033 1034 %S print Thumb register (bits 3..5 as high number if bit 6 set) 1035 %D print Thumb register (bits 0..2 as high number if bit 7 set) 1036 %<bitfield>I print bitfield as a signed decimal 1037 (top bit of range being the sign bit) 1038 %N print Thumb register mask (with LR) 1039 %O print Thumb register mask (with PC) 1040 %M print Thumb register mask 1041 %b print CZB's 6-bit unsigned branch destination 1042 %s print Thumb right-shift immediate (6..10; 0 == 32). 1043 %c print the condition code 1044 %C print the condition code, or "s" if not conditional 1045 %x print warning if conditional an not at end of IT block" 1046 %X print "\t; unpredictable <IT:code>" if conditional 1047 %I print IT instruction suffix and operands 1048 %<bitfield>r print bitfield as an ARM register 1049 %<bitfield>d print bitfield as a decimal 1050 %<bitfield>H print (bitfield * 2) as a decimal 1051 %<bitfield>W print (bitfield * 4) as a decimal 1052 %<bitfield>a print (bitfield * 4) as a pc-rel offset + decoded symbol 1053 %<bitfield>B print Thumb branch destination (signed displacement) 1054 %<bitfield>c print bitfield as a condition code 1055 %<bitnum>'c print specified char iff bit is one 1056 %<bitnum>?ab print a if bit is one else print b. */ 1057 1058static const struct opcode16 thumb_opcodes[] = 1059{ 1060 /* Thumb instructions. */ 1061 1062 /* ARM V6K no-argument instructions. */ 1063 {ARM_EXT_V6K, 0xbf00, 0xffff, "nop%c"}, 1064 {ARM_EXT_V6K, 0xbf10, 0xffff, "yield%c"}, 1065 {ARM_EXT_V6K, 0xbf20, 0xffff, "wfe%c"}, 1066 {ARM_EXT_V6K, 0xbf30, 0xffff, "wfi%c"}, 1067 {ARM_EXT_V6K, 0xbf40, 0xffff, "sev%c"}, 1068 {ARM_EXT_V6K, 0xbf00, 0xff0f, "nop%c\t{%4-7d}"}, 1069 1070 /* ARM V6T2 instructions. */ 1071 {ARM_EXT_V6T2, 0xb900, 0xfd00, "cbnz\t%0-2r, %b%X"}, 1072 {ARM_EXT_V6T2, 0xb100, 0xfd00, "cbz\t%0-2r, %b%X"}, 1073 {ARM_EXT_V6T2, 0xbf00, 0xff00, "it%I%X"}, 1074 1075 /* ARM V6. */ 1076 {ARM_EXT_V6, 0xb660, 0xfff8, "cpsie\t%2'a%1'i%0'f%X"}, 1077 {ARM_EXT_V6, 0xb670, 0xfff8, "cpsid\t%2'a%1'i%0'f%X"}, 1078 {ARM_EXT_V6, 0x4600, 0xffc0, "mov%c\t%0-2r, %3-5r"}, 1079 {ARM_EXT_V6, 0xba00, 0xffc0, "rev%c\t%0-2r, %3-5r"}, 1080 {ARM_EXT_V6, 0xba40, 0xffc0, "rev16%c\t%0-2r, %3-5r"}, 1081 {ARM_EXT_V6, 0xbac0, 0xffc0, "revsh%c\t%0-2r, %3-5r"}, 1082 {ARM_EXT_V6, 0xb650, 0xfff7, "setend\t%3?ble%X"}, 1083 {ARM_EXT_V6, 0xb200, 0xffc0, "sxth%c\t%0-2r, %3-5r"}, 1084 {ARM_EXT_V6, 0xb240, 0xffc0, "sxtb%c\t%0-2r, %3-5r"}, 1085 {ARM_EXT_V6, 0xb280, 0xffc0, "uxth%c\t%0-2r, %3-5r"}, 1086 {ARM_EXT_V6, 0xb2c0, 0xffc0, "uxtb%c\t%0-2r, %3-5r"}, 1087 1088 /* ARM V5 ISA extends Thumb. */ 1089 {ARM_EXT_V5T, 0xbe00, 0xff00, "bkpt\t%0-7x"}, /* Is always unconditional. */ 1090 /* This is BLX(2). BLX(1) is a 32-bit instruction. */ 1091 {ARM_EXT_V5T, 0x4780, 0xff87, "blx%c\t%3-6r%x"}, /* note: 4 bit register number. */ 1092 /* ARM V4T ISA (Thumb v1). */ 1093 {ARM_EXT_V4T, 0x46C0, 0xFFFF, "nop%c\t\t\t(mov r8, r8)"}, 1094 /* Format 4. */ 1095 {ARM_EXT_V4T, 0x4000, 0xFFC0, "and%C\t%0-2r, %3-5r"}, 1096 {ARM_EXT_V4T, 0x4040, 0xFFC0, "eor%C\t%0-2r, %3-5r"}, 1097 {ARM_EXT_V4T, 0x4080, 0xFFC0, "lsl%C\t%0-2r, %3-5r"}, 1098 {ARM_EXT_V4T, 0x40C0, 0xFFC0, "lsr%C\t%0-2r, %3-5r"}, 1099 {ARM_EXT_V4T, 0x4100, 0xFFC0, "asr%C\t%0-2r, %3-5r"}, 1100 {ARM_EXT_V4T, 0x4140, 0xFFC0, "adc%C\t%0-2r, %3-5r"}, 1101 {ARM_EXT_V4T, 0x4180, 0xFFC0, "sbc%C\t%0-2r, %3-5r"}, 1102 {ARM_EXT_V4T, 0x41C0, 0xFFC0, "ror%C\t%0-2r, %3-5r"}, 1103 {ARM_EXT_V4T, 0x4200, 0xFFC0, "tst%c\t%0-2r, %3-5r"}, 1104 {ARM_EXT_V4T, 0x4240, 0xFFC0, "neg%C\t%0-2r, %3-5r"}, 1105 {ARM_EXT_V4T, 0x4280, 0xFFC0, "cmp%c\t%0-2r, %3-5r"}, 1106 {ARM_EXT_V4T, 0x42C0, 0xFFC0, "cmn%c\t%0-2r, %3-5r"}, 1107 {ARM_EXT_V4T, 0x4300, 0xFFC0, "orr%C\t%0-2r, %3-5r"}, 1108 {ARM_EXT_V4T, 0x4340, 0xFFC0, "mul%C\t%0-2r, %3-5r"}, 1109 {ARM_EXT_V4T, 0x4380, 0xFFC0, "bic%C\t%0-2r, %3-5r"}, 1110 {ARM_EXT_V4T, 0x43C0, 0xFFC0, "mvn%C\t%0-2r, %3-5r"}, 1111 /* format 13 */ 1112 {ARM_EXT_V4T, 0xB000, 0xFF80, "add%c\tsp, #%0-6W"}, 1113 {ARM_EXT_V4T, 0xB080, 0xFF80, "sub%c\tsp, #%0-6W"}, 1114 /* format 5 */ 1115 {ARM_EXT_V4T, 0x4700, 0xFF80, "bx%c\t%S%x"}, 1116 {ARM_EXT_V4T, 0x4400, 0xFF00, "add%c\t%D, %S"}, 1117 {ARM_EXT_V4T, 0x4500, 0xFF00, "cmp%c\t%D, %S"}, 1118 {ARM_EXT_V4T, 0x4600, 0xFF00, "mov%c\t%D, %S"}, 1119 /* format 14 */ 1120 {ARM_EXT_V4T, 0xB400, 0xFE00, "push%c\t%N"}, 1121 {ARM_EXT_V4T, 0xBC00, 0xFE00, "pop%c\t%O"}, 1122 /* format 2 */ 1123 {ARM_EXT_V4T, 0x1800, 0xFE00, "add%C\t%0-2r, %3-5r, %6-8r"}, 1124 {ARM_EXT_V4T, 0x1A00, 0xFE00, "sub%C\t%0-2r, %3-5r, %6-8r"}, 1125 {ARM_EXT_V4T, 0x1C00, 0xFE00, "add%C\t%0-2r, %3-5r, #%6-8d"}, 1126 {ARM_EXT_V4T, 0x1E00, 0xFE00, "sub%C\t%0-2r, %3-5r, #%6-8d"}, 1127 /* format 8 */ 1128 {ARM_EXT_V4T, 0x5200, 0xFE00, "strh%c\t%0-2r, [%3-5r, %6-8r]"}, 1129 {ARM_EXT_V4T, 0x5A00, 0xFE00, "ldrh%c\t%0-2r, [%3-5r, %6-8r]"}, 1130 {ARM_EXT_V4T, 0x5600, 0xF600, "ldrs%11?hb%c\t%0-2r, [%3-5r, %6-8r]"}, 1131 /* format 7 */ 1132 {ARM_EXT_V4T, 0x5000, 0xFA00, "str%10'b%c\t%0-2r, [%3-5r, %6-8r]"}, 1133 {ARM_EXT_V4T, 0x5800, 0xFA00, "ldr%10'b%c\t%0-2r, [%3-5r, %6-8r]"}, 1134 /* format 1 */ 1135 {ARM_EXT_V4T, 0x0000, 0xF800, "lsl%C\t%0-2r, %3-5r, #%6-10d"}, 1136 {ARM_EXT_V4T, 0x0800, 0xF800, "lsr%C\t%0-2r, %3-5r, %s"}, 1137 {ARM_EXT_V4T, 0x1000, 0xF800, "asr%C\t%0-2r, %3-5r, %s"}, 1138 /* format 3 */ 1139 {ARM_EXT_V4T, 0x2000, 0xF800, "mov%C\t%8-10r, #%0-7d"}, 1140 {ARM_EXT_V4T, 0x2800, 0xF800, "cmp%c\t%8-10r, #%0-7d"}, 1141 {ARM_EXT_V4T, 0x3000, 0xF800, "add%C\t%8-10r, #%0-7d"}, 1142 {ARM_EXT_V4T, 0x3800, 0xF800, "sub%C\t%8-10r, #%0-7d"}, 1143 /* format 6 */ 1144 {ARM_EXT_V4T, 0x4800, 0xF800, "ldr%c\t%8-10r, [pc, #%0-7W]\t(%0-7a)"}, /* TODO: Disassemble PC relative "LDR rD,=<symbolic>" */ 1145 /* format 9 */ 1146 {ARM_EXT_V4T, 0x6000, 0xF800, "str%c\t%0-2r, [%3-5r, #%6-10W]"}, 1147 {ARM_EXT_V4T, 0x6800, 0xF800, "ldr%c\t%0-2r, [%3-5r, #%6-10W]"}, 1148 {ARM_EXT_V4T, 0x7000, 0xF800, "strb%c\t%0-2r, [%3-5r, #%6-10d]"}, 1149 {ARM_EXT_V4T, 0x7800, 0xF800, "ldrb%c\t%0-2r, [%3-5r, #%6-10d]"}, 1150 /* format 10 */ 1151 {ARM_EXT_V4T, 0x8000, 0xF800, "strh%c\t%0-2r, [%3-5r, #%6-10H]"}, 1152 {ARM_EXT_V4T, 0x8800, 0xF800, "ldrh%c\t%0-2r, [%3-5r, #%6-10H]"}, 1153 /* format 11 */ 1154 {ARM_EXT_V4T, 0x9000, 0xF800, "str%c\t%8-10r, [sp, #%0-7W]"}, 1155 {ARM_EXT_V4T, 0x9800, 0xF800, "ldr%c\t%8-10r, [sp, #%0-7W]"}, 1156 /* format 12 */ 1157 {ARM_EXT_V4T, 0xA000, 0xF800, "add%c\t%8-10r, pc, #%0-7W\t(adr %8-10r, %0-7a)"}, 1158 {ARM_EXT_V4T, 0xA800, 0xF800, "add%c\t%8-10r, sp, #%0-7W"}, 1159 /* format 15 */ 1160 {ARM_EXT_V4T, 0xC000, 0xF800, "stmia%c\t%8-10r!, %M"}, 1161 {ARM_EXT_V4T, 0xC800, 0xF800, "ldmia%c\t%8-10r!, %M"}, 1162 /* format 17 */ 1163 {ARM_EXT_V4T, 0xDF00, 0xFF00, "svc%c\t%0-7d"}, 1164 /* format 16 */ 1165 {ARM_EXT_V4T, 0xDE00, 0xFE00, "undefined"}, 1166 {ARM_EXT_V4T, 0xD000, 0xF000, "b%8-11c.n\t%0-7B%X"}, 1167 /* format 18 */ 1168 {ARM_EXT_V4T, 0xE000, 0xF800, "b%c.n\t%0-10B%x"}, 1169 1170 /* The E800 .. FFFF range is unconditionally redirected to the 1171 32-bit table, because even in pre-V6T2 ISAs, BL and BLX(1) pairs 1172 are processed via that table. Thus, we can never encounter a 1173 bare "second half of BL/BLX(1)" instruction here. */ 1174 {ARM_EXT_V1, 0x0000, 0x0000, "undefined"}, 1175 {0, 0, 0, 0} 1176}; 1177 1178/* Thumb32 opcodes use the same table structure as the ARM opcodes. 1179 We adopt the convention that hw1 is the high 16 bits of .value and 1180 .mask, hw2 the low 16 bits. 1181 1182 print_insn_thumb32 recognizes the following format control codes: 1183 1184 %% % 1185 1186 %I print a 12-bit immediate from hw1[10],hw2[14:12,7:0] 1187 %M print a modified 12-bit immediate (same location) 1188 %J print a 16-bit immediate from hw1[3:0,10],hw2[14:12,7:0] 1189 %K print a 16-bit immediate from hw2[3:0],hw1[3:0],hw2[11:4] 1190 %S print a possibly-shifted Rm 1191 1192 %a print the address of a plain load/store 1193 %w print the width and signedness of a core load/store 1194 %m print register mask for ldm/stm 1195 1196 %E print the lsb and width fields of a bfc/bfi instruction 1197 %F print the lsb and width fields of a sbfx/ubfx instruction 1198 %b print a conditional branch offset 1199 %B print an unconditional branch offset 1200 %s print the shift field of an SSAT instruction 1201 %R print the rotation field of an SXT instruction 1202 %U print barrier type. 1203 %P print address for pli instruction. 1204 %c print the condition code 1205 %x print warning if conditional an not at end of IT block" 1206 %X print "\t; unpredictable <IT:code>" if conditional 1207 1208 %<bitfield>d print bitfield in decimal 1209 %<bitfield>W print bitfield*4 in decimal 1210 %<bitfield>r print bitfield as an ARM register 1211 %<bitfield>c print bitfield as a condition code 1212 1213 %<bitfield>'c print specified char iff bitfield is all ones 1214 %<bitfield>`c print specified char iff bitfield is all zeroes 1215 %<bitfield>?ab... select from array of values in big endian order 1216 1217 With one exception at the bottom (done because BL and BLX(1) need 1218 to come dead last), this table was machine-sorted first in 1219 decreasing order of number of bits set in the mask, then in 1220 increasing numeric order of mask, then in increasing numeric order 1221 of opcode. This order is not the clearest for a human reader, but 1222 is guaranteed never to catch a special-case bit pattern with a more 1223 general mask, which is important, because this instruction encoding 1224 makes heavy use of special-case bit patterns. */ 1225static const struct opcode32 thumb32_opcodes[] = 1226{ 1227 /* V7 instructions. */ 1228 {ARM_EXT_V7, 0xf910f000, 0xff70f000, "pli%c\t%a"}, 1229 {ARM_EXT_V7, 0xf3af80f0, 0xfffffff0, "dbg%c\t#%0-3d"}, 1230 {ARM_EXT_V7, 0xf3bf8f50, 0xfffffff0, "dmb%c\t%U"}, 1231 {ARM_EXT_V7, 0xf3bf8f40, 0xfffffff0, "dsb%c\t%U"}, 1232 {ARM_EXT_V7, 0xf3bf8f60, 0xfffffff0, "isb%c\t%U"}, 1233 {ARM_EXT_DIV, 0xfb90f0f0, 0xfff0f0f0, "sdiv%c\t%8-11r, %16-19r, %0-3r"}, 1234 {ARM_EXT_DIV, 0xfbb0f0f0, 0xfff0f0f0, "udiv%c\t%8-11r, %16-19r, %0-3r"}, 1235 1236 /* Instructions defined in the basic V6T2 set. */ 1237 {ARM_EXT_V6T2, 0xf3af8000, 0xffffffff, "nop%c.w"}, 1238 {ARM_EXT_V6T2, 0xf3af8001, 0xffffffff, "yield%c.w"}, 1239 {ARM_EXT_V6T2, 0xf3af8002, 0xffffffff, "wfe%c.w"}, 1240 {ARM_EXT_V6T2, 0xf3af8003, 0xffffffff, "wfi%c.w"}, 1241 {ARM_EXT_V6T2, 0xf3af9004, 0xffffffff, "sev%c.w"}, 1242 {ARM_EXT_V6T2, 0xf3af8000, 0xffffff00, "nop%c.w\t{%0-7d}"}, 1243 1244 {ARM_EXT_V6T2, 0xf3bf8f2f, 0xffffffff, "clrex%c"}, 1245 {ARM_EXT_V6T2, 0xf3af8400, 0xffffff1f, "cpsie.w\t%7'a%6'i%5'f%X"}, 1246 {ARM_EXT_V6T2, 0xf3af8600, 0xffffff1f, "cpsid.w\t%7'a%6'i%5'f%X"}, 1247 {ARM_EXT_V6T2, 0xf3c08f00, 0xfff0ffff, "bxj%c\t%16-19r%x"}, 1248 {ARM_EXT_V6T2, 0xe810c000, 0xffd0ffff, "rfedb%c\t%16-19r%21'!"}, 1249 {ARM_EXT_V6T2, 0xe990c000, 0xffd0ffff, "rfeia%c\t%16-19r%21'!"}, 1250 {ARM_EXT_V6T2, 0xf3ef8000, 0xffeff000, "mrs%c\t%8-11r, %D"}, 1251 {ARM_EXT_V6T2, 0xf3af8100, 0xffffffe0, "cps\t#%0-4d%X"}, 1252 {ARM_EXT_V6T2, 0xe8d0f000, 0xfff0fff0, "tbb%c\t[%16-19r, %0-3r]%x"}, 1253 {ARM_EXT_V6T2, 0xe8d0f010, 0xfff0fff0, "tbh%c\t[%16-19r, %0-3r, lsl #1]%x"}, 1254 {ARM_EXT_V6T2, 0xf3af8500, 0xffffff00, "cpsie\t%7'a%6'i%5'f, #%0-4d%X"}, 1255 {ARM_EXT_V6T2, 0xf3af8700, 0xffffff00, "cpsid\t%7'a%6'i%5'f, #%0-4d%X"}, 1256 {ARM_EXT_V6T2, 0xf3de8f00, 0xffffff00, "subs%c\tpc, lr, #%0-7d"}, 1257 {ARM_EXT_V6T2, 0xf3808000, 0xffe0f000, "msr%c\t%C, %16-19r"}, 1258 {ARM_EXT_V6T2, 0xe8500f00, 0xfff00fff, "ldrex%c\t%12-15r, [%16-19r]"}, 1259 {ARM_EXT_V6T2, 0xe8d00f4f, 0xfff00fef, "ldrex%4?hb%c\t%12-15r, [%16-19r]"}, 1260 {ARM_EXT_V6T2, 0xe800c000, 0xffd0ffe0, "srsdb%c\t%16-19r%21'!, #%0-4d"}, 1261 {ARM_EXT_V6T2, 0xe980c000, 0xffd0ffe0, "srsia%c\t%16-19r%21'!, #%0-4d"}, 1262 {ARM_EXT_V6T2, 0xfa0ff080, 0xfffff0c0, "sxth%c.w\t%8-11r, %0-3r%R"}, 1263 {ARM_EXT_V6T2, 0xfa1ff080, 0xfffff0c0, "uxth%c.w\t%8-11r, %0-3r%R"}, 1264 {ARM_EXT_V6T2, 0xfa2ff080, 0xfffff0c0, "sxtb16%c\t%8-11r, %0-3r%R"}, 1265 {ARM_EXT_V6T2, 0xfa3ff080, 0xfffff0c0, "uxtb16%c\t%8-11r, %0-3r%R"}, 1266 {ARM_EXT_V6T2, 0xfa4ff080, 0xfffff0c0, "sxtb%c.w\t%8-11r, %0-3r%R"}, 1267 {ARM_EXT_V6T2, 0xfa5ff080, 0xfffff0c0, "uxtb%c.w\t%8-11r, %0-3r%R"}, 1268 {ARM_EXT_V6T2, 0xe8400000, 0xfff000ff, "strex%c\t%8-11r, %12-15r, [%16-19r]"}, 1269 {ARM_EXT_V6T2, 0xe8d0007f, 0xfff000ff, "ldrexd%c\t%12-15r, %8-11r, [%16-19r]"}, 1270 {ARM_EXT_V6T2, 0xfa80f000, 0xfff0f0f0, "sadd8%c\t%8-11r, %16-19r, %0-3r"}, 1271 {ARM_EXT_V6T2, 0xfa80f010, 0xfff0f0f0, "qadd8%c\t%8-11r, %16-19r, %0-3r"}, 1272 {ARM_EXT_V6T2, 0xfa80f020, 0xfff0f0f0, "shadd8%c\t%8-11r, %16-19r, %0-3r"}, 1273 {ARM_EXT_V6T2, 0xfa80f040, 0xfff0f0f0, "uadd8%c\t%8-11r, %16-19r, %0-3r"}, 1274 {ARM_EXT_V6T2, 0xfa80f050, 0xfff0f0f0, "uqadd8%c\t%8-11r, %16-19r, %0-3r"}, 1275 {ARM_EXT_V6T2, 0xfa80f060, 0xfff0f0f0, "uhadd8%c\t%8-11r, %16-19r, %0-3r"}, 1276 {ARM_EXT_V6T2, 0xfa80f080, 0xfff0f0f0, "qadd%c\t%8-11r, %0-3r, %16-19r"}, 1277 {ARM_EXT_V6T2, 0xfa80f090, 0xfff0f0f0, "qdadd%c\t%8-11r, %0-3r, %16-19r"}, 1278 {ARM_EXT_V6T2, 0xfa80f0a0, 0xfff0f0f0, "qsub%c\t%8-11r, %0-3r, %16-19r"}, 1279 {ARM_EXT_V6T2, 0xfa80f0b0, 0xfff0f0f0, "qdsub%c\t%8-11r, %0-3r, %16-19r"}, 1280 {ARM_EXT_V6T2, 0xfa90f000, 0xfff0f0f0, "sadd16%c\t%8-11r, %16-19r, %0-3r"}, 1281 {ARM_EXT_V6T2, 0xfa90f010, 0xfff0f0f0, "qadd16%c\t%8-11r, %16-19r, %0-3r"}, 1282 {ARM_EXT_V6T2, 0xfa90f020, 0xfff0f0f0, "shadd16%c\t%8-11r, %16-19r, %0-3r"}, 1283 {ARM_EXT_V6T2, 0xfa90f040, 0xfff0f0f0, "uadd16%c\t%8-11r, %16-19r, %0-3r"}, 1284 {ARM_EXT_V6T2, 0xfa90f050, 0xfff0f0f0, "uqadd16%c\t%8-11r, %16-19r, %0-3r"}, 1285 {ARM_EXT_V6T2, 0xfa90f060, 0xfff0f0f0, "uhadd16%c\t%8-11r, %16-19r, %0-3r"}, 1286 {ARM_EXT_V6T2, 0xfa90f080, 0xfff0f0f0, "rev%c.w\t%8-11r, %16-19r"}, 1287 {ARM_EXT_V6T2, 0xfa90f090, 0xfff0f0f0, "rev16%c.w\t%8-11r, %16-19r"}, 1288 {ARM_EXT_V6T2, 0xfa90f0a0, 0xfff0f0f0, "rbit%c\t%8-11r, %16-19r"}, 1289 {ARM_EXT_V6T2, 0xfa90f0b0, 0xfff0f0f0, "revsh%c.w\t%8-11r, %16-19r"}, 1290 {ARM_EXT_V6T2, 0xfaa0f000, 0xfff0f0f0, "saddsubx%c\t%8-11r, %16-19r, %0-3r"}, 1291 {ARM_EXT_V6T2, 0xfaa0f010, 0xfff0f0f0, "qaddsubx%c\t%8-11r, %16-19r, %0-3r"}, 1292 {ARM_EXT_V6T2, 0xfaa0f020, 0xfff0f0f0, "shaddsubx%c\t%8-11r, %16-19r, %0-3r"}, 1293 {ARM_EXT_V6T2, 0xfaa0f040, 0xfff0f0f0, "uaddsubx%c\t%8-11r, %16-19r, %0-3r"}, 1294 {ARM_EXT_V6T2, 0xfaa0f050, 0xfff0f0f0, "uqaddsubx%c\t%8-11r, %16-19r, %0-3r"}, 1295 {ARM_EXT_V6T2, 0xfaa0f060, 0xfff0f0f0, "uhaddsubx%c\t%8-11r, %16-19r, %0-3r"}, 1296 {ARM_EXT_V6T2, 0xfaa0f080, 0xfff0f0f0, "sel%c\t%8-11r, %16-19r, %0-3r"}, 1297 {ARM_EXT_V6T2, 0xfab0f080, 0xfff0f0f0, "clz%c\t%8-11r, %16-19r"}, 1298 {ARM_EXT_V6T2, 0xfac0f000, 0xfff0f0f0, "ssub8%c\t%8-11r, %16-19r, %0-3r"}, 1299 {ARM_EXT_V6T2, 0xfac0f010, 0xfff0f0f0, "qsub8%c\t%8-11r, %16-19r, %0-3r"}, 1300 {ARM_EXT_V6T2, 0xfac0f020, 0xfff0f0f0, "shsub8%c\t%8-11r, %16-19r, %0-3r"}, 1301 {ARM_EXT_V6T2, 0xfac0f040, 0xfff0f0f0, "usub8%c\t%8-11r, %16-19r, %0-3r"}, 1302 {ARM_EXT_V6T2, 0xfac0f050, 0xfff0f0f0, "uqsub8%c\t%8-11r, %16-19r, %0-3r"}, 1303 {ARM_EXT_V6T2, 0xfac0f060, 0xfff0f0f0, "uhsub8%c\t%8-11r, %16-19r, %0-3r"}, 1304 {ARM_EXT_V6T2, 0xfad0f000, 0xfff0f0f0, "ssub16%c\t%8-11r, %16-19r, %0-3r"}, 1305 {ARM_EXT_V6T2, 0xfad0f010, 0xfff0f0f0, "qsub16%c\t%8-11r, %16-19r, %0-3r"}, 1306 {ARM_EXT_V6T2, 0xfad0f020, 0xfff0f0f0, "shsub16%c\t%8-11r, %16-19r, %0-3r"}, 1307 {ARM_EXT_V6T2, 0xfad0f040, 0xfff0f0f0, "usub16%c\t%8-11r, %16-19r, %0-3r"}, 1308 {ARM_EXT_V6T2, 0xfad0f050, 0xfff0f0f0, "uqsub16%c\t%8-11r, %16-19r, %0-3r"}, 1309 {ARM_EXT_V6T2, 0xfad0f060, 0xfff0f0f0, "uhsub16%c\t%8-11r, %16-19r, %0-3r"}, 1310 {ARM_EXT_V6T2, 0xfae0f000, 0xfff0f0f0, "ssubaddx%c\t%8-11r, %16-19r, %0-3r"}, 1311 {ARM_EXT_V6T2, 0xfae0f010, 0xfff0f0f0, "qsubaddx%c\t%8-11r, %16-19r, %0-3r"}, 1312 {ARM_EXT_V6T2, 0xfae0f020, 0xfff0f0f0, "shsubaddx%c\t%8-11r, %16-19r, %0-3r"}, 1313 {ARM_EXT_V6T2, 0xfae0f040, 0xfff0f0f0, "usubaddx%c\t%8-11r, %16-19r, %0-3r"}, 1314 {ARM_EXT_V6T2, 0xfae0f050, 0xfff0f0f0, "uqsubaddx%c\t%8-11r, %16-19r, %0-3r"}, 1315 {ARM_EXT_V6T2, 0xfae0f060, 0xfff0f0f0, "uhsubaddx%c\t%8-11r, %16-19r, %0-3r"}, 1316 {ARM_EXT_V6T2, 0xfb00f000, 0xfff0f0f0, "mul%c.w\t%8-11r, %16-19r, %0-3r"}, 1317 {ARM_EXT_V6T2, 0xfb70f000, 0xfff0f0f0, "usad8%c\t%8-11r, %16-19r, %0-3r"}, 1318 {ARM_EXT_V6T2, 0xfa00f000, 0xffe0f0f0, "lsl%20's%c.w\t%8-11r, %16-19r, %0-3r"}, 1319 {ARM_EXT_V6T2, 0xfa20f000, 0xffe0f0f0, "lsr%20's%c.w\t%8-11r, %16-19r, %0-3r"}, 1320 {ARM_EXT_V6T2, 0xfa40f000, 0xffe0f0f0, "asr%20's%c.w\t%8-11r, %16-19r, %0-3r"}, 1321 {ARM_EXT_V6T2, 0xfa60f000, 0xffe0f0f0, "ror%20's%c.w\t%8-11r, %16-19r, %0-3r"}, 1322 {ARM_EXT_V6T2, 0xe8c00f40, 0xfff00fe0, "strex%4?hb%c\t%0-3r, %12-15r, [%16-19r]"}, 1323 {ARM_EXT_V6T2, 0xf3200000, 0xfff0f0e0, "ssat16%c\t%8-11r, #%0-4d, %16-19r"}, 1324 {ARM_EXT_V6T2, 0xf3a00000, 0xfff0f0e0, "usat16%c\t%8-11r, #%0-4d, %16-19r"}, 1325 {ARM_EXT_V6T2, 0xfb20f000, 0xfff0f0e0, "smuad%4'x%c\t%8-11r, %16-19r, %0-3r"}, 1326 {ARM_EXT_V6T2, 0xfb30f000, 0xfff0f0e0, "smulw%4?tb%c\t%8-11r, %16-19r, %0-3r"}, 1327 {ARM_EXT_V6T2, 0xfb40f000, 0xfff0f0e0, "smusd%4'x%c\t%8-11r, %16-19r, %0-3r"}, 1328 {ARM_EXT_V6T2, 0xfb50f000, 0xfff0f0e0, "smmul%4'r%c\t%8-11r, %16-19r, %0-3r"}, 1329 {ARM_EXT_V6T2, 0xfa00f080, 0xfff0f0c0, "sxtah%c\t%8-11r, %16-19r, %0-3r%R"}, 1330 {ARM_EXT_V6T2, 0xfa10f080, 0xfff0f0c0, "uxtah%c\t%8-11r, %16-19r, %0-3r%R"}, 1331 {ARM_EXT_V6T2, 0xfa20f080, 0xfff0f0c0, "sxtab16%c\t%8-11r, %16-19r, %0-3r%R"}, 1332 {ARM_EXT_V6T2, 0xfa30f080, 0xfff0f0c0, "uxtab16%c\t%8-11r, %16-19r, %0-3r%R"}, 1333 {ARM_EXT_V6T2, 0xfa40f080, 0xfff0f0c0, "sxtab%c\t%8-11r, %16-19r, %0-3r%R"}, 1334 {ARM_EXT_V6T2, 0xfa50f080, 0xfff0f0c0, "uxtab%c\t%8-11r, %16-19r, %0-3r%R"}, 1335 {ARM_EXT_V6T2, 0xfb10f000, 0xfff0f0c0, "smul%5?tb%4?tb%c\t%8-11r, %16-19r, %0-3r"}, 1336 {ARM_EXT_V6T2, 0xf36f0000, 0xffff8020, "bfc%c\t%8-11r, %E"}, 1337 {ARM_EXT_V6T2, 0xea100f00, 0xfff08f00, "tst%c.w\t%16-19r, %S"}, 1338 {ARM_EXT_V6T2, 0xea900f00, 0xfff08f00, "teq%c\t%16-19r, %S"}, 1339 {ARM_EXT_V6T2, 0xeb100f00, 0xfff08f00, "cmn%c.w\t%16-19r, %S"}, 1340 {ARM_EXT_V6T2, 0xebb00f00, 0xfff08f00, "cmp%c.w\t%16-19r, %S"}, 1341 {ARM_EXT_V6T2, 0xf0100f00, 0xfbf08f00, "tst%c.w\t%16-19r, %M"}, 1342 {ARM_EXT_V6T2, 0xf0900f00, 0xfbf08f00, "teq%c\t%16-19r, %M"}, 1343 {ARM_EXT_V6T2, 0xf1100f00, 0xfbf08f00, "cmn%c.w\t%16-19r, %M"}, 1344 {ARM_EXT_V6T2, 0xf1b00f00, 0xfbf08f00, "cmp%c.w\t%16-19r, %M"}, 1345 {ARM_EXT_V6T2, 0xea4f0000, 0xffef8000, "mov%20's%c.w\t%8-11r, %S"}, 1346 {ARM_EXT_V6T2, 0xea6f0000, 0xffef8000, "mvn%20's%c.w\t%8-11r, %S"}, 1347 {ARM_EXT_V6T2, 0xe8c00070, 0xfff000f0, "strexd%c\t%0-3r, %12-15r, %8-11r, [%16-19r]"}, 1348 {ARM_EXT_V6T2, 0xfb000000, 0xfff000f0, "mla%c\t%8-11r, %16-19r, %0-3r, %12-15r"}, 1349 {ARM_EXT_V6T2, 0xfb000010, 0xfff000f0, "mls%c\t%8-11r, %16-19r, %0-3r, %12-15r"}, 1350 {ARM_EXT_V6T2, 0xfb700000, 0xfff000f0, "usada8%c\t%8-11r, %16-19r, %0-3r, %12-15r"}, 1351 {ARM_EXT_V6T2, 0xfb800000, 0xfff000f0, "smull%c\t%12-15r, %8-11r, %16-19r, %0-3r"}, 1352 {ARM_EXT_V6T2, 0xfba00000, 0xfff000f0, "umull%c\t%12-15r, %8-11r, %16-19r, %0-3r"}, 1353 {ARM_EXT_V6T2, 0xfbc00000, 0xfff000f0, "smlal%c\t%12-15r, %8-11r, %16-19r, %0-3r"}, 1354 {ARM_EXT_V6T2, 0xfbe00000, 0xfff000f0, "umlal%c\t%12-15r, %8-11r, %16-19r, %0-3r"}, 1355 {ARM_EXT_V6T2, 0xfbe00060, 0xfff000f0, "umaal%c\t%12-15r, %8-11r, %16-19r, %0-3r"}, 1356 {ARM_EXT_V6T2, 0xe8500f00, 0xfff00f00, "ldrex%c\t%12-15r, [%16-19r, #%0-7W]"}, 1357 {ARM_EXT_V6T2, 0xf7f08000, 0xfff0f000, "smc%c\t%K"}, 1358 {ARM_EXT_V6T2, 0xf04f0000, 0xfbef8000, "mov%20's%c.w\t%8-11r, %M"}, 1359 {ARM_EXT_V6T2, 0xf06f0000, 0xfbef8000, "mvn%20's%c.w\t%8-11r, %M"}, 1360 {ARM_EXT_V6T2, 0xf810f000, 0xff70f000, "pld%c\t%a"}, 1361 {ARM_EXT_V6T2, 0xfb200000, 0xfff000e0, "smlad%4'x%c\t%8-11r, %16-19r, %0-3r, %12-15r"}, 1362 {ARM_EXT_V6T2, 0xfb300000, 0xfff000e0, "smlaw%4?tb%c\t%8-11r, %16-19r, %0-3r, %12-15r"}, 1363 {ARM_EXT_V6T2, 0xfb400000, 0xfff000e0, "smlsd%4'x%c\t%8-11r, %16-19r, %0-3r, %12-15r"}, 1364 {ARM_EXT_V6T2, 0xfb500000, 0xfff000e0, "smmla%4'r%c\t%8-11r, %16-19r, %0-3r, %12-15r"}, 1365 {ARM_EXT_V6T2, 0xfb600000, 0xfff000e0, "smmls%4'r%c\t%8-11r, %16-19r, %0-3r, %12-15r"}, 1366 {ARM_EXT_V6T2, 0xfbc000c0, 0xfff000e0, "smlald%4'x%c\t%12-15r, %8-11r, %16-19r, %0-3r"}, 1367 {ARM_EXT_V6T2, 0xfbd000c0, 0xfff000e0, "smlsld%4'x%c\t%12-15r, %8-11r, %16-19r, %0-3r"}, 1368 {ARM_EXT_V6T2, 0xeac00000, 0xfff08030, "pkhbt%c\t%8-11r, %16-19r, %S"}, 1369 {ARM_EXT_V6T2, 0xeac00020, 0xfff08030, "pkhtb%c\t%8-11r, %16-19r, %S"}, 1370 {ARM_EXT_V6T2, 0xf3400000, 0xfff08020, "sbfx%c\t%8-11r, %16-19r, %F"}, 1371 {ARM_EXT_V6T2, 0xf3c00000, 0xfff08020, "ubfx%c\t%8-11r, %16-19r, %F"}, 1372 {ARM_EXT_V6T2, 0xf8000e00, 0xff900f00, "str%wt%c\t%12-15r, %a"}, 1373 {ARM_EXT_V6T2, 0xfb100000, 0xfff000c0, "smla%5?tb%4?tb%c\t%8-11r, %16-19r, %0-3r, %12-15r"}, 1374 {ARM_EXT_V6T2, 0xfbc00080, 0xfff000c0, "smlal%5?tb%4?tb%c\t%12-15r, %8-11r, %16-19r, %0-3r"}, 1375 {ARM_EXT_V6T2, 0xf3600000, 0xfff08020, "bfi%c\t%8-11r, %16-19r, %E"}, 1376 {ARM_EXT_V6T2, 0xf8100e00, 0xfe900f00, "ldr%wt%c\t%12-15r, %a"}, 1377 {ARM_EXT_V6T2, 0xf3000000, 0xffd08020, "ssat%c\t%8-11r, #%0-4d, %16-19r%s"}, 1378 {ARM_EXT_V6T2, 0xf3800000, 0xffd08020, "usat%c\t%8-11r, #%0-4d, %16-19r%s"}, 1379 {ARM_EXT_V6T2, 0xf2000000, 0xfbf08000, "addw%c\t%8-11r, %16-19r, %I"}, 1380 {ARM_EXT_V6T2, 0xf2400000, 0xfbf08000, "movw%c\t%8-11r, %J"}, 1381 {ARM_EXT_V6T2, 0xf2a00000, 0xfbf08000, "subw%c\t%8-11r, %16-19r, %I"}, 1382 {ARM_EXT_V6T2, 0xf2c00000, 0xfbf08000, "movt%c\t%8-11r, %J"}, 1383 {ARM_EXT_V6T2, 0xea000000, 0xffe08000, "and%20's%c.w\t%8-11r, %16-19r, %S"}, 1384 {ARM_EXT_V6T2, 0xea200000, 0xffe08000, "bic%20's%c.w\t%8-11r, %16-19r, %S"}, 1385 {ARM_EXT_V6T2, 0xea400000, 0xffe08000, "orr%20's%c.w\t%8-11r, %16-19r, %S"}, 1386 {ARM_EXT_V6T2, 0xea600000, 0xffe08000, "orn%20's%c\t%8-11r, %16-19r, %S"}, 1387 {ARM_EXT_V6T2, 0xea800000, 0xffe08000, "eor%20's%c.w\t%8-11r, %16-19r, %S"}, 1388 {ARM_EXT_V6T2, 0xeb000000, 0xffe08000, "add%20's%c.w\t%8-11r, %16-19r, %S"}, 1389 {ARM_EXT_V6T2, 0xeb400000, 0xffe08000, "adc%20's%c.w\t%8-11r, %16-19r, %S"}, 1390 {ARM_EXT_V6T2, 0xeb600000, 0xffe08000, "sbc%20's%c.w\t%8-11r, %16-19r, %S"}, 1391 {ARM_EXT_V6T2, 0xeba00000, 0xffe08000, "sub%20's%c.w\t%8-11r, %16-19r, %S"}, 1392 {ARM_EXT_V6T2, 0xebc00000, 0xffe08000, "rsb%20's%c\t%8-11r, %16-19r, %S"}, 1393 {ARM_EXT_V6T2, 0xe8400000, 0xfff00000, "strex%c\t%8-11r, %12-15r, [%16-19r, #%0-7W]"}, 1394 {ARM_EXT_V6T2, 0xf0000000, 0xfbe08000, "and%20's%c.w\t%8-11r, %16-19r, %M"}, 1395 {ARM_EXT_V6T2, 0xf0200000, 0xfbe08000, "bic%20's%c.w\t%8-11r, %16-19r, %M"}, 1396 {ARM_EXT_V6T2, 0xf0400000, 0xfbe08000, "orr%20's%c.w\t%8-11r, %16-19r, %M"}, 1397 {ARM_EXT_V6T2, 0xf0600000, 0xfbe08000, "orn%20's%c\t%8-11r, %16-19r, %M"}, 1398 {ARM_EXT_V6T2, 0xf0800000, 0xfbe08000, "eor%20's%c.w\t%8-11r, %16-19r, %M"}, 1399 {ARM_EXT_V6T2, 0xf1000000, 0xfbe08000, "add%20's%c.w\t%8-11r, %16-19r, %M"}, 1400 {ARM_EXT_V6T2, 0xf1400000, 0xfbe08000, "adc%20's%c.w\t%8-11r, %16-19r, %M"}, 1401 {ARM_EXT_V6T2, 0xf1600000, 0xfbe08000, "sbc%20's%c.w\t%8-11r, %16-19r, %M"}, 1402 {ARM_EXT_V6T2, 0xf1a00000, 0xfbe08000, "sub%20's%c.w\t%8-11r, %16-19r, %M"}, 1403 {ARM_EXT_V6T2, 0xf1c00000, 0xfbe08000, "rsb%20's%c\t%8-11r, %16-19r, %M"}, 1404 {ARM_EXT_V6T2, 0xe8800000, 0xffd00000, "stmia%c.w\t%16-19r%21'!, %m"}, 1405 {ARM_EXT_V6T2, 0xe8900000, 0xffd00000, "ldmia%c.w\t%16-19r%21'!, %m"}, 1406 {ARM_EXT_V6T2, 0xe9000000, 0xffd00000, "stmdb%c\t%16-19r%21'!, %m"}, 1407 {ARM_EXT_V6T2, 0xe9100000, 0xffd00000, "ldmdb%c\t%16-19r%21'!, %m"}, 1408 {ARM_EXT_V6T2, 0xe9c00000, 0xffd000ff, "strd%c\t%12-15r, %8-11r, [%16-19r]"}, 1409 {ARM_EXT_V6T2, 0xe9d00000, 0xffd000ff, "ldrd%c\t%12-15r, %8-11r, [%16-19r]"}, 1410 {ARM_EXT_V6T2, 0xe9400000, 0xff500000, "strd%c\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]%21'!"}, 1411 {ARM_EXT_V6T2, 0xe9500000, 0xff500000, "ldrd%c\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]%21'!"}, 1412 {ARM_EXT_V6T2, 0xe8600000, 0xff700000, "strd%c\t%12-15r, %8-11r, [%16-19r], #%23`-%0-7W"}, 1413 {ARM_EXT_V6T2, 0xe8700000, 0xff700000, "ldrd%c\t%12-15r, %8-11r, [%16-19r], #%23`-%0-7W"}, 1414 {ARM_EXT_V6T2, 0xf8000000, 0xff100000, "str%w%c.w\t%12-15r, %a"}, 1415 {ARM_EXT_V6T2, 0xf8100000, 0xfe100000, "ldr%w%c.w\t%12-15r, %a"}, 1416 1417 /* Filter out Bcc with cond=E or F, which are used for other instructions. */ 1418 {ARM_EXT_V6T2, 0xf3c08000, 0xfbc0d000, "undefined (bcc, cond=0xF)"}, 1419 {ARM_EXT_V6T2, 0xf3808000, 0xfbc0d000, "undefined (bcc, cond=0xE)"}, 1420 {ARM_EXT_V6T2, 0xf0008000, 0xf800d000, "b%22-25c.w\t%b%X"}, 1421 {ARM_EXT_V6T2, 0xf0009000, 0xf800d000, "b%c.w\t%B%x"}, 1422 1423 /* These have been 32-bit since the invention of Thumb. */ 1424 {ARM_EXT_V4T, 0xf000c000, 0xf800d000, "blx%c\t%B%x"}, 1425 {ARM_EXT_V4T, 0xf000d000, 0xf800d000, "bl%c\t%B%x"}, 1426 1427 /* Fallback. */ 1428 {ARM_EXT_V1, 0x00000000, 0x00000000, "undefined"}, 1429 {0, 0, 0, 0} 1430}; 1431 1432static const char *const arm_conditional[] = 1433{"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc", 1434 "hi", "ls", "ge", "lt", "gt", "le", "al", "<und>", ""}; 1435 1436static const char *const arm_fp_const[] = 1437{"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"}; 1438 1439static const char *const arm_shift[] = 1440{"lsl", "lsr", "asr", "ror"}; 1441 1442typedef struct 1443{ 1444 const char *name; 1445 const char *description; 1446 const char *reg_names[16]; 1447} 1448arm_regname; 1449 1450static const arm_regname regnames[] = 1451{ 1452 { "raw" , "Select raw register names", 1453 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}}, 1454 { "gcc", "Select register names used by GCC", 1455 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc" }}, 1456 { "std", "Select register names used in ARM's ISA documentation", 1457 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc" }}, 1458 { "apcs", "Select register names used in the APCS", 1459 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "sl", "fp", "ip", "sp", "lr", "pc" }}, 1460 { "atpcs", "Select register names used in the ATPCS", 1461 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "IP", "SP", "LR", "PC" }}, 1462 { "special-atpcs", "Select special register names used in the ATPCS", 1463 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL", "FP", "IP", "SP", "LR", "PC" }}, 1464}; 1465 1466static const char *const iwmmxt_wwnames[] = 1467{"b", "h", "w", "d"}; 1468 1469static const char *const iwmmxt_wwssnames[] = 1470{"b", "bus", "bc", "bss", 1471 "h", "hus", "hc", "hss", 1472 "w", "wus", "wc", "wss", 1473 "d", "dus", "dc", "dss" 1474}; 1475 1476static const char *const iwmmxt_regnames[] = 1477{ "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6", "wr7", 1478 "wr8", "wr9", "wr10", "wr11", "wr12", "wr13", "wr14", "wr15" 1479}; 1480 1481static const char *const iwmmxt_cregnames[] = 1482{ "wcid", "wcon", "wcssf", "wcasf", "reserved", "reserved", "reserved", "reserved", 1483 "wcgr0", "wcgr1", "wcgr2", "wcgr3", "reserved", "reserved", "reserved", "reserved" 1484}; 1485 1486/* Default to GCC register name set. */ 1487static unsigned int regname_selected = 1; 1488 1489#define NUM_ARM_REGNAMES NUM_ELEM (regnames) 1490#define arm_regnames regnames[regname_selected].reg_names 1491 1492static bfd_boolean force_thumb = FALSE; 1493 1494/* Current IT instruction state. This contains the same state as the IT 1495 bits in the CPSR. */ 1496static unsigned int ifthen_state; 1497/* IT state for the next instruction. */ 1498static unsigned int ifthen_next_state; 1499/* The address of the insn for which the IT state is valid. */ 1500static bfd_vma ifthen_address; 1501#define IFTHEN_COND ((ifthen_state >> 4) & 0xf) 1502 1503/* Cached mapping symbol state. */ 1504enum map_type { 1505 MAP_ARM, 1506 MAP_THUMB, 1507 MAP_DATA 1508}; 1509 1510enum map_type last_type; 1511int last_mapping_sym = -1; 1512bfd_vma last_mapping_addr = 0; 1513 1514 1515/* Functions. */ 1516int 1517get_arm_regname_num_options (void) 1518{ 1519 return NUM_ARM_REGNAMES; 1520} 1521 1522int 1523set_arm_regname_option (int option) 1524{ 1525 int old = regname_selected; 1526 regname_selected = option; 1527 return old; 1528} 1529 1530int 1531get_arm_regnames (int option, const char **setname, const char **setdescription, 1532 const char *const **register_names) 1533{ 1534 *setname = regnames[option].name; 1535 *setdescription = regnames[option].description; 1536 *register_names = regnames[option].reg_names; 1537 return 16; 1538} 1539 1540/* Decode a bitfield of the form matching regexp (N(-N)?,)*N(-N)?. 1541 Returns pointer to following character of the format string and 1542 fills in *VALUEP and *WIDTHP with the extracted value and number of 1543 bits extracted. WIDTHP can be NULL. */ 1544 1545static const char * 1546arm_decode_bitfield (const char *ptr, unsigned long insn, 1547 unsigned long *valuep, int *widthp) 1548{ 1549 unsigned long value = 0; 1550 int width = 0; 1551 1552 do 1553 { 1554 int start, end; 1555 int bits; 1556 1557 for (start = 0; *ptr >= '0' && *ptr <= '9'; ptr++) 1558 start = start * 10 + *ptr - '0'; 1559 if (*ptr == '-') 1560 for (end = 0, ptr++; *ptr >= '0' && *ptr <= '9'; ptr++) 1561 end = end * 10 + *ptr - '0'; 1562 else 1563 end = start; 1564 bits = end - start; 1565 if (bits < 0) 1566 abort (); 1567 value |= ((insn >> start) & ((2ul << bits) - 1)) << width; 1568 width += bits + 1; 1569 } 1570 while (*ptr++ == ','); 1571 *valuep = value; 1572 if (widthp) 1573 *widthp = width; 1574 return ptr - 1; 1575} 1576 1577static void 1578arm_decode_shift (long given, fprintf_ftype func, void *stream, 1579 int print_shift) 1580{ 1581 func (stream, "%s", arm_regnames[given & 0xf]); 1582 1583 if ((given & 0xff0) != 0) 1584 { 1585 if ((given & 0x10) == 0) 1586 { 1587 int amount = (given & 0xf80) >> 7; 1588 int shift = (given & 0x60) >> 5; 1589 1590 if (amount == 0) 1591 { 1592 if (shift == 3) 1593 { 1594 func (stream, ", rrx"); 1595 return; 1596 } 1597 1598 amount = 32; 1599 } 1600 1601 if (print_shift) 1602 func (stream, ", %s #%d", arm_shift[shift], amount); 1603 else 1604 func (stream, ", #%d", amount); 1605 } 1606 else if (print_shift) 1607 func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5], 1608 arm_regnames[(given & 0xf00) >> 8]); 1609 else 1610 func (stream, ", %s", arm_regnames[(given & 0xf00) >> 8]); 1611 } 1612} 1613 1614/* Print one coprocessor instruction on INFO->STREAM. 1615 Return TRUE if the instuction matched, FALSE if this is not a 1616 recognised coprocessor instruction. */ 1617 1618static bfd_boolean 1619print_insn_coprocessor (bfd_vma pc, struct disassemble_info *info, long given, 1620 bfd_boolean thumb) 1621{ 1622 const struct opcode32 *insn; 1623 void *stream = info->stream; 1624 fprintf_ftype func = info->fprintf_func; 1625 unsigned long mask; 1626 unsigned long value; 1627 int cond; 1628 1629 for (insn = coprocessor_opcodes; insn->assembler; insn++) 1630 { 1631 if (insn->value == FIRST_IWMMXT_INSN 1632 && info->mach != bfd_mach_arm_XScale 1633 && info->mach != bfd_mach_arm_iWMMXt 1634 && info->mach != bfd_mach_arm_iWMMXt2) 1635 insn = insn + IWMMXT_INSN_COUNT; 1636 1637 mask = insn->mask; 1638 value = insn->value; 1639 if (thumb) 1640 { 1641 /* The high 4 bits are 0xe for Arm conditional instructions, and 1642 0xe for arm unconditional instructions. The rest of the 1643 encoding is the same. */ 1644 mask |= 0xf0000000; 1645 value |= 0xe0000000; 1646 if (ifthen_state) 1647 cond = IFTHEN_COND; 1648 else 1649 cond = 16; 1650 } 1651 else 1652 { 1653 /* Only match unconditional instuctions against unconditional 1654 patterns. */ 1655 if ((given & 0xf0000000) == 0xf0000000) 1656 { 1657 mask |= 0xf0000000; 1658 cond = 16; 1659 } 1660 else 1661 { 1662 cond = (given >> 28) & 0xf; 1663 if (cond == 0xe) 1664 cond = 16; 1665 } 1666 } 1667 if ((given & mask) == value) 1668 { 1669 const char *c; 1670 1671 for (c = insn->assembler; *c; c++) 1672 { 1673 if (*c == '%') 1674 { 1675 switch (*++c) 1676 { 1677 case '%': 1678 func (stream, "%%"); 1679 break; 1680 1681 case 'A': 1682 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]); 1683 1684 if ((given & (1 << 24)) != 0) 1685 { 1686 int offset = given & 0xff; 1687 1688 if (offset) 1689 func (stream, ", #%s%d]%s", 1690 ((given & 0x00800000) == 0 ? "-" : ""), 1691 offset * 4, 1692 ((given & 0x00200000) != 0 ? "!" : "")); 1693 else 1694 func (stream, "]"); 1695 } 1696 else 1697 { 1698 int offset = given & 0xff; 1699 1700 func (stream, "]"); 1701 1702 if (given & (1 << 21)) 1703 { 1704 if (offset) 1705 func (stream, ", #%s%d", 1706 ((given & 0x00800000) == 0 ? "-" : ""), 1707 offset * 4); 1708 } 1709 else 1710 func (stream, ", {%d}", offset); 1711 } 1712 break; 1713 1714 case 'B': 1715 { 1716 int regno = ((given >> 12) & 0xf) | ((given >> (22 - 4)) & 0x10); 1717 int offset = (given >> 1) & 0x3f; 1718 1719 if (offset == 1) 1720 func (stream, "{d%d}", regno); 1721 else if (regno + offset > 32) 1722 func (stream, "{d%d-<overflow reg d%d>}", regno, regno + offset - 1); 1723 else 1724 func (stream, "{d%d-d%d}", regno, regno + offset - 1); 1725 } 1726 break; 1727 1728 case 'C': 1729 { 1730 int rn = (given >> 16) & 0xf; 1731 int offset = (given & 0xff) * 4; 1732 int add = (given >> 23) & 1; 1733 1734 func (stream, "[%s", arm_regnames[rn]); 1735 1736 if (offset) 1737 { 1738 if (!add) 1739 offset = -offset; 1740 func (stream, ", #%d", offset); 1741 } 1742 func (stream, "]"); 1743 if (rn == 15) 1744 { 1745 func (stream, "\t; "); 1746 /* FIXME: Unsure if info->bytes_per_chunk is the 1747 right thing to use here. */ 1748 info->print_address_func (offset + pc 1749 + info->bytes_per_chunk * 2, info); 1750 } 1751 } 1752 break; 1753 1754 case 'c': 1755 func (stream, "%s", arm_conditional[cond]); 1756 break; 1757 1758 case 'I': 1759 /* Print a Cirrus/DSP shift immediate. */ 1760 /* Immediates are 7bit signed ints with bits 0..3 in 1761 bits 0..3 of opcode and bits 4..6 in bits 5..7 1762 of opcode. */ 1763 { 1764 int imm; 1765 1766 imm = (given & 0xf) | ((given & 0xe0) >> 1); 1767 1768 /* Is ``imm'' a negative number? */ 1769 if (imm & 0x40) 1770 imm |= -(1 << 7); 1771 1772 func (stream, "%d", imm); 1773 } 1774 1775 break; 1776 1777 case 'F': 1778 switch (given & 0x00408000) 1779 { 1780 case 0: 1781 func (stream, "4"); 1782 break; 1783 case 0x8000: 1784 func (stream, "1"); 1785 break; 1786 case 0x00400000: 1787 func (stream, "2"); 1788 break; 1789 default: 1790 func (stream, "3"); 1791 } 1792 break; 1793 1794 case 'P': 1795 switch (given & 0x00080080) 1796 { 1797 case 0: 1798 func (stream, "s"); 1799 break; 1800 case 0x80: 1801 func (stream, "d"); 1802 break; 1803 case 0x00080000: 1804 func (stream, "e"); 1805 break; 1806 default: 1807 func (stream, _("<illegal precision>")); 1808 break; 1809 } 1810 break; 1811 case 'Q': 1812 switch (given & 0x00408000) 1813 { 1814 case 0: 1815 func (stream, "s"); 1816 break; 1817 case 0x8000: 1818 func (stream, "d"); 1819 break; 1820 case 0x00400000: 1821 func (stream, "e"); 1822 break; 1823 default: 1824 func (stream, "p"); 1825 break; 1826 } 1827 break; 1828 case 'R': 1829 switch (given & 0x60) 1830 { 1831 case 0: 1832 break; 1833 case 0x20: 1834 func (stream, "p"); 1835 break; 1836 case 0x40: 1837 func (stream, "m"); 1838 break; 1839 default: 1840 func (stream, "z"); 1841 break; 1842 } 1843 break; 1844 1845 case '0': case '1': case '2': case '3': case '4': 1846 case '5': case '6': case '7': case '8': case '9': 1847 { 1848 int width; 1849 unsigned long value; 1850 1851 c = arm_decode_bitfield (c, given, &value, &width); 1852 1853 switch (*c) 1854 { 1855 case 'r': 1856 func (stream, "%s", arm_regnames[value]); 1857 break; 1858 case 'D': 1859 func (stream, "d%ld", value); 1860 break; 1861 case 'Q': 1862 if (value & 1) 1863 func (stream, "<illegal reg q%ld.5>", value >> 1); 1864 else 1865 func (stream, "q%ld", value >> 1); 1866 break; 1867 case 'd': 1868 func (stream, "%ld", value); 1869 break; 1870 case 'k': 1871 { 1872 int from = (given & (1 << 7)) ? 32 : 16; 1873 func (stream, "%ld", from - value); 1874 } 1875 break; 1876 1877 case 'f': 1878 if (value > 7) 1879 func (stream, "#%s", arm_fp_const[value & 7]); 1880 else 1881 func (stream, "f%ld", value); 1882 break; 1883 1884 case 'w': 1885 if (width == 2) 1886 func (stream, "%s", iwmmxt_wwnames[value]); 1887 else 1888 func (stream, "%s", iwmmxt_wwssnames[value]); 1889 break; 1890 1891 case 'g': 1892 func (stream, "%s", iwmmxt_regnames[value]); 1893 break; 1894 case 'G': 1895 func (stream, "%s", iwmmxt_cregnames[value]); 1896 break; 1897 1898 case 'x': 1899 func (stream, "0x%lx", value); 1900 break; 1901 1902 case '`': 1903 c++; 1904 if (value == 0) 1905 func (stream, "%c", *c); 1906 break; 1907 case '\'': 1908 c++; 1909 if (value == ((1ul << width) - 1)) 1910 func (stream, "%c", *c); 1911 break; 1912 case '?': 1913 func (stream, "%c", c[(1 << width) - (int)value]); 1914 c += 1 << width; 1915 break; 1916 default: 1917 abort (); 1918 } 1919 break; 1920 1921 case 'y': 1922 case 'z': 1923 { 1924 int single = *c++ == 'y'; 1925 int regno; 1926 1927 switch (*c) 1928 { 1929 case '4': /* Sm pair */ 1930 func (stream, "{"); 1931 /* Fall through. */ 1932 case '0': /* Sm, Dm */ 1933 regno = given & 0x0000000f; 1934 if (single) 1935 { 1936 regno <<= 1; 1937 regno += (given >> 5) & 1; 1938 } 1939 else 1940 regno += ((given >> 5) & 1) << 4; 1941 break; 1942 1943 case '1': /* Sd, Dd */ 1944 regno = (given >> 12) & 0x0000000f; 1945 if (single) 1946 { 1947 regno <<= 1; 1948 regno += (given >> 22) & 1; 1949 } 1950 else 1951 regno += ((given >> 22) & 1) << 4; 1952 break; 1953 1954 case '2': /* Sn, Dn */ 1955 regno = (given >> 16) & 0x0000000f; 1956 if (single) 1957 { 1958 regno <<= 1; 1959 regno += (given >> 7) & 1; 1960 } 1961 else 1962 regno += ((given >> 7) & 1) << 4; 1963 break; 1964 1965 case '3': /* List */ 1966 func (stream, "{"); 1967 regno = (given >> 12) & 0x0000000f; 1968 if (single) 1969 { 1970 regno <<= 1; 1971 regno += (given >> 22) & 1; 1972 } 1973 else 1974 regno += ((given >> 22) & 1) << 4; 1975 break; 1976 1977 default: 1978 abort (); 1979 } 1980 1981 func (stream, "%c%d", single ? 's' : 'd', regno); 1982 1983 if (*c == '3') 1984 { 1985 int count = given & 0xff; 1986 1987 if (single == 0) 1988 count >>= 1; 1989 1990 if (--count) 1991 { 1992 func (stream, "-%c%d", 1993 single ? 's' : 'd', 1994 regno + count); 1995 } 1996 1997 func (stream, "}"); 1998 } 1999 else if (*c == '4') 2000 func (stream, ", %c%d}", single ? 's' : 'd', 2001 regno + 1); 2002 } 2003 break; 2004 2005 case 'L': 2006 switch (given & 0x00400100) 2007 { 2008 case 0x00000000: func (stream, "b"); break; 2009 case 0x00400000: func (stream, "h"); break; 2010 case 0x00000100: func (stream, "w"); break; 2011 case 0x00400100: func (stream, "d"); break; 2012 default: 2013 break; 2014 } 2015 break; 2016 2017 case 'Z': 2018 { 2019 int value; 2020 /* given (20, 23) | given (0, 3) */ 2021 value = ((given >> 16) & 0xf0) | (given & 0xf); 2022 func (stream, "%d", value); 2023 } 2024 break; 2025 2026 case 'l': 2027 /* This is like the 'A' operator, except that if 2028 the width field "M" is zero, then the offset is 2029 *not* multiplied by four. */ 2030 { 2031 int offset = given & 0xff; 2032 int multiplier = (given & 0x00000100) ? 4 : 1; 2033 2034 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]); 2035 2036 if (offset) 2037 { 2038 if ((given & 0x01000000) != 0) 2039 func (stream, ", #%s%d]%s", 2040 ((given & 0x00800000) == 0 ? "-" : ""), 2041 offset * multiplier, 2042 ((given & 0x00200000) != 0 ? "!" : "")); 2043 else 2044 func (stream, "], #%s%d", 2045 ((given & 0x00800000) == 0 ? "-" : ""), 2046 offset * multiplier); 2047 } 2048 else 2049 func (stream, "]"); 2050 } 2051 break; 2052 2053 case 'r': 2054 { 2055 int imm4 = (given >> 4) & 0xf; 2056 int puw_bits = ((given >> 22) & 6) | ((given >> 21) & 1); 2057 int ubit = (given >> 23) & 1; 2058 const char *rm = arm_regnames [given & 0xf]; 2059 const char *rn = arm_regnames [(given >> 16) & 0xf]; 2060 2061 switch (puw_bits) 2062 { 2063 case 1: 2064 /* fall through */ 2065 case 3: 2066 func (stream, "[%s], %c%s", rn, ubit ? '+' : '-', rm); 2067 if (imm4) 2068 func (stream, ", lsl #%d", imm4); 2069 break; 2070 2071 case 4: 2072 /* fall through */ 2073 case 5: 2074 /* fall through */ 2075 case 6: 2076 /* fall through */ 2077 case 7: 2078 func (stream, "[%s, %c%s", rn, ubit ? '+' : '-', rm); 2079 if (imm4 > 0) 2080 func (stream, ", lsl #%d", imm4); 2081 func (stream, "]"); 2082 if (puw_bits == 5 || puw_bits == 7) 2083 func (stream, "!"); 2084 break; 2085 2086 default: 2087 func (stream, "INVALID"); 2088 } 2089 } 2090 break; 2091 2092 case 'i': 2093 { 2094 long imm5; 2095 imm5 = ((given & 0x100) >> 4) | (given & 0xf); 2096 func (stream, "%ld", (imm5 == 0) ? 32 : imm5); 2097 } 2098 break; 2099 2100 default: 2101 abort (); 2102 } 2103 } 2104 } 2105 else 2106 func (stream, "%c", *c); 2107 } 2108 return TRUE; 2109 } 2110 } 2111 return FALSE; 2112} 2113 2114static void 2115print_arm_address (bfd_vma pc, struct disassemble_info *info, long given) 2116{ 2117 void *stream = info->stream; 2118 fprintf_ftype func = info->fprintf_func; 2119 2120 if (((given & 0x000f0000) == 0x000f0000) 2121 && ((given & 0x02000000) == 0)) 2122 { 2123 int offset = given & 0xfff; 2124 2125 func (stream, "[pc"); 2126 2127 if (given & 0x01000000) 2128 { 2129 if ((given & 0x00800000) == 0) 2130 offset = - offset; 2131 2132 /* Pre-indexed. */ 2133 func (stream, ", #%d]", offset); 2134 2135 offset += pc + 8; 2136 2137 /* Cope with the possibility of write-back 2138 being used. Probably a very dangerous thing 2139 for the programmer to do, but who are we to 2140 argue ? */ 2141 if (given & 0x00200000) 2142 func (stream, "!"); 2143 } 2144 else 2145 { 2146 /* Post indexed. */ 2147 func (stream, "], #%d", offset); 2148 2149 /* ie ignore the offset. */ 2150 offset = pc + 8; 2151 } 2152 2153 func (stream, "\t; "); 2154 info->print_address_func (offset, info); 2155 } 2156 else 2157 { 2158 func (stream, "[%s", 2159 arm_regnames[(given >> 16) & 0xf]); 2160 if ((given & 0x01000000) != 0) 2161 { 2162 if ((given & 0x02000000) == 0) 2163 { 2164 int offset = given & 0xfff; 2165 if (offset) 2166 func (stream, ", #%s%d", 2167 (((given & 0x00800000) == 0) 2168 ? "-" : ""), offset); 2169 } 2170 else 2171 { 2172 func (stream, ", %s", 2173 (((given & 0x00800000) == 0) 2174 ? "-" : "")); 2175 arm_decode_shift (given, func, stream, 1); 2176 } 2177 2178 func (stream, "]%s", 2179 ((given & 0x00200000) != 0) ? "!" : ""); 2180 } 2181 else 2182 { 2183 if ((given & 0x02000000) == 0) 2184 { 2185 int offset = given & 0xfff; 2186 if (offset) 2187 func (stream, "], #%s%d", 2188 (((given & 0x00800000) == 0) 2189 ? "-" : ""), offset); 2190 else 2191 func (stream, "]"); 2192 } 2193 else 2194 { 2195 func (stream, "], %s", 2196 (((given & 0x00800000) == 0) 2197 ? "-" : "")); 2198 arm_decode_shift (given, func, stream, 1); 2199 } 2200 } 2201 } 2202} 2203 2204/* Print one neon instruction on INFO->STREAM. 2205 Return TRUE if the instuction matched, FALSE if this is not a 2206 recognised neon instruction. */ 2207 2208static bfd_boolean 2209print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb) 2210{ 2211 const struct opcode32 *insn; 2212 void *stream = info->stream; 2213 fprintf_ftype func = info->fprintf_func; 2214 2215 if (thumb) 2216 { 2217 if ((given & 0xef000000) == 0xef000000) 2218 { 2219 /* move bit 28 to bit 24 to translate Thumb2 to ARM encoding. */ 2220 unsigned long bit28 = given & (1 << 28); 2221 2222 given &= 0x00ffffff; 2223 if (bit28) 2224 given |= 0xf3000000; 2225 else 2226 given |= 0xf2000000; 2227 } 2228 else if ((given & 0xff000000) == 0xf9000000) 2229 given ^= 0xf9000000 ^ 0xf4000000; 2230 else 2231 return FALSE; 2232 } 2233 2234 for (insn = neon_opcodes; insn->assembler; insn++) 2235 { 2236 if ((given & insn->mask) == insn->value) 2237 { 2238 const char *c; 2239 2240 for (c = insn->assembler; *c; c++) 2241 { 2242 if (*c == '%') 2243 { 2244 switch (*++c) 2245 { 2246 case '%': 2247 func (stream, "%%"); 2248 break; 2249 2250 case 'c': 2251 if (thumb && ifthen_state) 2252 func (stream, "%s", arm_conditional[IFTHEN_COND]); 2253 break; 2254 2255 case 'A': 2256 { 2257 static const unsigned char enc[16] = 2258 { 2259 0x4, 0x14, /* st4 0,1 */ 2260 0x4, /* st1 2 */ 2261 0x4, /* st2 3 */ 2262 0x3, /* st3 4 */ 2263 0x13, /* st3 5 */ 2264 0x3, /* st1 6 */ 2265 0x1, /* st1 7 */ 2266 0x2, /* st2 8 */ 2267 0x12, /* st2 9 */ 2268 0x2, /* st1 10 */ 2269 0, 0, 0, 0, 0 2270 }; 2271 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4); 2272 int rn = ((given >> 16) & 0xf); 2273 int rm = ((given >> 0) & 0xf); 2274 int align = ((given >> 4) & 0x3); 2275 int type = ((given >> 8) & 0xf); 2276 int n = enc[type] & 0xf; 2277 int stride = (enc[type] >> 4) + 1; 2278 int ix; 2279 2280 func (stream, "{"); 2281 if (stride > 1) 2282 for (ix = 0; ix != n; ix++) 2283 func (stream, "%sd%d", ix ? "," : "", rd + ix * stride); 2284 else if (n == 1) 2285 func (stream, "d%d", rd); 2286 else 2287 func (stream, "d%d-d%d", rd, rd + n - 1); 2288 func (stream, "}, [%s", arm_regnames[rn]); 2289 if (align) 2290 func (stream, ", :%d", 32 << align); 2291 func (stream, "]"); 2292 if (rm == 0xd) 2293 func (stream, "!"); 2294 else if (rm != 0xf) 2295 func (stream, ", %s", arm_regnames[rm]); 2296 } 2297 break; 2298 2299 case 'B': 2300 { 2301 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4); 2302 int rn = ((given >> 16) & 0xf); 2303 int rm = ((given >> 0) & 0xf); 2304 int idx_align = ((given >> 4) & 0xf); 2305 int align = 0; 2306 int size = ((given >> 10) & 0x3); 2307 int idx = idx_align >> (size + 1); 2308 int length = ((given >> 8) & 3) + 1; 2309 int stride = 1; 2310 int i; 2311 2312 if (length > 1 && size > 0) 2313 stride = (idx_align & (1 << size)) ? 2 : 1; 2314 2315 switch (length) 2316 { 2317 case 1: 2318 { 2319 int amask = (1 << size) - 1; 2320 if ((idx_align & (1 << size)) != 0) 2321 return FALSE; 2322 if (size > 0) 2323 { 2324 if ((idx_align & amask) == amask) 2325 align = 8 << size; 2326 else if ((idx_align & amask) != 0) 2327 return FALSE; 2328 } 2329 } 2330 break; 2331 2332 case 2: 2333 if (size == 2 && (idx_align & 2) != 0) 2334 return FALSE; 2335 align = (idx_align & 1) ? 16 << size : 0; 2336 break; 2337 2338 case 3: 2339 if ((size == 2 && (idx_align & 3) != 0) 2340 || (idx_align & 1) != 0) 2341 return FALSE; 2342 break; 2343 2344 case 4: 2345 if (size == 2) 2346 { 2347 if ((idx_align & 3) == 3) 2348 return FALSE; 2349 align = (idx_align & 3) * 64; 2350 } 2351 else 2352 align = (idx_align & 1) ? 32 << size : 0; 2353 break; 2354 2355 default: 2356 abort (); 2357 } 2358 2359 func (stream, "{"); 2360 for (i = 0; i < length; i++) 2361 func (stream, "%sd%d[%d]", (i == 0) ? "" : ",", 2362 rd + i * stride, idx); 2363 func (stream, "}, [%s", arm_regnames[rn]); 2364 if (align) 2365 func (stream, ", :%d", align); 2366 func (stream, "]"); 2367 if (rm == 0xd) 2368 func (stream, "!"); 2369 else if (rm != 0xf) 2370 func (stream, ", %s", arm_regnames[rm]); 2371 } 2372 break; 2373 2374 case 'C': 2375 { 2376 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4); 2377 int rn = ((given >> 16) & 0xf); 2378 int rm = ((given >> 0) & 0xf); 2379 int align = ((given >> 4) & 0x1); 2380 int size = ((given >> 6) & 0x3); 2381 int type = ((given >> 8) & 0x3); 2382 int n = type + 1; 2383 int stride = ((given >> 5) & 0x1); 2384 int ix; 2385 2386 if (stride && (n == 1)) 2387 n++; 2388 else 2389 stride++; 2390 2391 func (stream, "{"); 2392 if (stride > 1) 2393 for (ix = 0; ix != n; ix++) 2394 func (stream, "%sd%d[]", ix ? "," : "", rd + ix * stride); 2395 else if (n == 1) 2396 func (stream, "d%d[]", rd); 2397 else 2398 func (stream, "d%d[]-d%d[]", rd, rd + n - 1); 2399 func (stream, "}, [%s", arm_regnames[rn]); 2400 if (align) 2401 { 2402 int align = (8 * (type + 1)) << size; 2403 if (type == 3) 2404 align = (size > 1) ? align >> 1 : align; 2405 if (type == 2 || (type == 0 && !size)) 2406 func (stream, ", :<bad align %d>", align); 2407 else 2408 func (stream, ", :%d", align); 2409 } 2410 func (stream, "]"); 2411 if (rm == 0xd) 2412 func (stream, "!"); 2413 else if (rm != 0xf) 2414 func (stream, ", %s", arm_regnames[rm]); 2415 } 2416 break; 2417 2418 case 'D': 2419 { 2420 int raw_reg = (given & 0xf) | ((given >> 1) & 0x10); 2421 int size = (given >> 20) & 3; 2422 int reg = raw_reg & ((4 << size) - 1); 2423 int ix = raw_reg >> size >> 2; 2424 2425 func (stream, "d%d[%d]", reg, ix); 2426 } 2427 break; 2428 2429 case 'E': 2430 /* Neon encoded constant for mov, mvn, vorr, vbic */ 2431 { 2432 int bits = 0; 2433 int cmode = (given >> 8) & 0xf; 2434 int op = (given >> 5) & 0x1; 2435 unsigned long value = 0, hival = 0; 2436 unsigned shift; 2437 int size = 0; 2438 int isfloat = 0; 2439 2440 bits |= ((given >> 24) & 1) << 7; 2441 bits |= ((given >> 16) & 7) << 4; 2442 bits |= ((given >> 0) & 15) << 0; 2443 2444 if (cmode < 8) 2445 { 2446 shift = (cmode >> 1) & 3; 2447 value = (unsigned long)bits << (8 * shift); 2448 size = 32; 2449 } 2450 else if (cmode < 12) 2451 { 2452 shift = (cmode >> 1) & 1; 2453 value = (unsigned long)bits << (8 * shift); 2454 size = 16; 2455 } 2456 else if (cmode < 14) 2457 { 2458 shift = (cmode & 1) + 1; 2459 value = (unsigned long)bits << (8 * shift); 2460 value |= (1ul << (8 * shift)) - 1; 2461 size = 32; 2462 } 2463 else if (cmode == 14) 2464 { 2465 if (op) 2466 { 2467 /* bit replication into bytes */ 2468 int ix; 2469 unsigned long mask; 2470 2471 value = 0; 2472 hival = 0; 2473 for (ix = 7; ix >= 0; ix--) 2474 { 2475 mask = ((bits >> ix) & 1) ? 0xff : 0; 2476 if (ix <= 3) 2477 value = (value << 8) | mask; 2478 else 2479 hival = (hival << 8) | mask; 2480 } 2481 size = 64; 2482 } 2483 else 2484 { 2485 /* byte replication */ 2486 value = (unsigned long)bits; 2487 size = 8; 2488 } 2489 } 2490 else if (!op) 2491 { 2492 /* floating point encoding */ 2493 int tmp; 2494 2495 value = (unsigned long)(bits & 0x7f) << 19; 2496 value |= (unsigned long)(bits & 0x80) << 24; 2497 tmp = bits & 0x40 ? 0x3c : 0x40; 2498 value |= (unsigned long)tmp << 24; 2499 size = 32; 2500 isfloat = 1; 2501 } 2502 else 2503 { 2504 func (stream, "<illegal constant %.8x:%x:%x>", 2505 bits, cmode, op); 2506 size = 32; 2507 break; 2508 } 2509 switch (size) 2510 { 2511 case 8: 2512 func (stream, "#%ld\t; 0x%.2lx", value, value); 2513 break; 2514 2515 case 16: 2516 func (stream, "#%ld\t; 0x%.4lx", value, value); 2517 break; 2518 2519 case 32: 2520 if (isfloat) 2521 { 2522 unsigned char valbytes[4]; 2523 double fvalue; 2524 2525 /* Do this a byte at a time so we don't have to 2526 worry about the host's endianness. */ 2527 valbytes[0] = value & 0xff; 2528 valbytes[1] = (value >> 8) & 0xff; 2529 valbytes[2] = (value >> 16) & 0xff; 2530 valbytes[3] = (value >> 24) & 0xff; 2531 2532 floatformat_to_double 2533 (&floatformat_ieee_single_little, valbytes, 2534 &fvalue); 2535 2536 func (stream, "#%.7g\t; 0x%.8lx", fvalue, 2537 value); 2538 } 2539 else 2540 func (stream, "#%ld\t; 0x%.8lx", 2541 (long) ((value & 0x80000000) 2542 ? value | ~0xffffffffl : value), value); 2543 break; 2544 2545 case 64: 2546 func (stream, "#0x%.8lx%.8lx", hival, value); 2547 break; 2548 2549 default: 2550 abort (); 2551 } 2552 } 2553 break; 2554 2555 case 'F': 2556 { 2557 int regno = ((given >> 16) & 0xf) | ((given >> (7 - 4)) & 0x10); 2558 int num = (given >> 8) & 0x3; 2559 2560 if (!num) 2561 func (stream, "{d%d}", regno); 2562 else if (num + regno >= 32) 2563 func (stream, "{d%d-<overflow reg d%d}", regno, regno + num); 2564 else 2565 func (stream, "{d%d-d%d}", regno, regno + num); 2566 } 2567 break; 2568 2569 2570 case '0': case '1': case '2': case '3': case '4': 2571 case '5': case '6': case '7': case '8': case '9': 2572 { 2573 int width; 2574 unsigned long value; 2575 2576 c = arm_decode_bitfield (c, given, &value, &width); 2577 2578 switch (*c) 2579 { 2580 case 'r': 2581 func (stream, "%s", arm_regnames[value]); 2582 break; 2583 case 'd': 2584 func (stream, "%ld", value); 2585 break; 2586 case 'e': 2587 func (stream, "%ld", (1ul << width) - value); 2588 break; 2589 2590 case 'S': 2591 case 'T': 2592 case 'U': 2593 /* various width encodings */ 2594 { 2595 int base = 8 << (*c - 'S'); /* 8,16 or 32 */ 2596 int limit; 2597 unsigned low, high; 2598 2599 c++; 2600 if (*c >= '0' && *c <= '9') 2601 limit = *c - '0'; 2602 else if (*c >= 'a' && *c <= 'f') 2603 limit = *c - 'a' + 10; 2604 else 2605 abort (); 2606 low = limit >> 2; 2607 high = limit & 3; 2608 2609 if (value < low || value > high) 2610 func (stream, "<illegal width %d>", base << value); 2611 else 2612 func (stream, "%d", base << value); 2613 } 2614 break; 2615 case 'R': 2616 if (given & (1 << 6)) 2617 goto Q; 2618 /* FALLTHROUGH */ 2619 case 'D': 2620 func (stream, "d%ld", value); 2621 break; 2622 case 'Q': 2623 Q: 2624 if (value & 1) 2625 func (stream, "<illegal reg q%ld.5>", value >> 1); 2626 else 2627 func (stream, "q%ld", value >> 1); 2628 break; 2629 2630 case '`': 2631 c++; 2632 if (value == 0) 2633 func (stream, "%c", *c); 2634 break; 2635 case '\'': 2636 c++; 2637 if (value == ((1ul << width) - 1)) 2638 func (stream, "%c", *c); 2639 break; 2640 case '?': 2641 func (stream, "%c", c[(1 << width) - (int)value]); 2642 c += 1 << width; 2643 break; 2644 default: 2645 abort (); 2646 } 2647 break; 2648 2649 default: 2650 abort (); 2651 } 2652 } 2653 } 2654 else 2655 func (stream, "%c", *c); 2656 } 2657 return TRUE; 2658 } 2659 } 2660 return FALSE; 2661} 2662 2663/* Print one ARM instruction from PC on INFO->STREAM. */ 2664 2665static void 2666print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given) 2667{ 2668 const struct opcode32 *insn; 2669 void *stream = info->stream; 2670 fprintf_ftype func = info->fprintf_func; 2671 2672 if (print_insn_coprocessor (pc, info, given, FALSE)) 2673 return; 2674 2675 if (print_insn_neon (info, given, FALSE)) 2676 return; 2677 2678 for (insn = arm_opcodes; insn->assembler; insn++) 2679 { 2680 if (insn->value == FIRST_IWMMXT_INSN 2681 && info->mach != bfd_mach_arm_XScale 2682 && info->mach != bfd_mach_arm_iWMMXt) 2683 insn = insn + IWMMXT_INSN_COUNT; 2684 2685 if ((given & insn->mask) == insn->value 2686 /* Special case: an instruction with all bits set in the condition field 2687 (0xFnnn_nnnn) is only matched if all those bits are set in insn->mask, 2688 or by the catchall at the end of the table. */ 2689 && ((given & 0xF0000000) != 0xF0000000 2690 || (insn->mask & 0xF0000000) == 0xF0000000 2691 || (insn->mask == 0 && insn->value == 0))) 2692 { 2693 const char *c; 2694 2695 for (c = insn->assembler; *c; c++) 2696 { 2697 if (*c == '%') 2698 { 2699 switch (*++c) 2700 { 2701 case '%': 2702 func (stream, "%%"); 2703 break; 2704 2705 case 'a': 2706 print_arm_address (pc, info, given); 2707 break; 2708 2709 case 'P': 2710 /* Set P address bit and use normal address 2711 printing routine. */ 2712 print_arm_address (pc, info, given | (1 << 24)); 2713 break; 2714 2715 case 's': 2716 if ((given & 0x004f0000) == 0x004f0000) 2717 { 2718 /* PC relative with immediate offset. */ 2719 int offset = ((given & 0xf00) >> 4) | (given & 0xf); 2720 2721 if ((given & 0x00800000) == 0) 2722 offset = -offset; 2723 2724 func (stream, "[pc, #%d]\t; ", offset); 2725 info->print_address_func (offset + pc + 8, info); 2726 } 2727 else 2728 { 2729 func (stream, "[%s", 2730 arm_regnames[(given >> 16) & 0xf]); 2731 if ((given & 0x01000000) != 0) 2732 { 2733 /* Pre-indexed. */ 2734 if ((given & 0x00400000) == 0x00400000) 2735 { 2736 /* Immediate. */ 2737 int offset = ((given & 0xf00) >> 4) | (given & 0xf); 2738 if (offset) 2739 func (stream, ", #%s%d", 2740 (((given & 0x00800000) == 0) 2741 ? "-" : ""), offset); 2742 } 2743 else 2744 { 2745 /* Register. */ 2746 func (stream, ", %s%s", 2747 (((given & 0x00800000) == 0) 2748 ? "-" : ""), 2749 arm_regnames[given & 0xf]); 2750 } 2751 2752 func (stream, "]%s", 2753 ((given & 0x00200000) != 0) ? "!" : ""); 2754 } 2755 else 2756 { 2757 /* Post-indexed. */ 2758 if ((given & 0x00400000) == 0x00400000) 2759 { 2760 /* Immediate. */ 2761 int offset = ((given & 0xf00) >> 4) | (given & 0xf); 2762 if (offset) 2763 func (stream, "], #%s%d", 2764 (((given & 0x00800000) == 0) 2765 ? "-" : ""), offset); 2766 else 2767 func (stream, "]"); 2768 } 2769 else 2770 { 2771 /* Register. */ 2772 func (stream, "], %s%s", 2773 (((given & 0x00800000) == 0) 2774 ? "-" : ""), 2775 arm_regnames[given & 0xf]); 2776 } 2777 } 2778 } 2779 break; 2780 2781 case 'b': 2782 { 2783 int disp = (((given & 0xffffff) ^ 0x800000) - 0x800000); 2784 info->print_address_func (disp*4 + pc + 8, info); 2785 } 2786 break; 2787 2788 case 'c': 2789 if (((given >> 28) & 0xf) != 0xe) 2790 func (stream, "%s", 2791 arm_conditional [(given >> 28) & 0xf]); 2792 break; 2793 2794 case 'm': 2795 { 2796 int started = 0; 2797 int reg; 2798 2799 func (stream, "{"); 2800 for (reg = 0; reg < 16; reg++) 2801 if ((given & (1 << reg)) != 0) 2802 { 2803 if (started) 2804 func (stream, ", "); 2805 started = 1; 2806 func (stream, "%s", arm_regnames[reg]); 2807 } 2808 func (stream, "}"); 2809 } 2810 break; 2811 2812 case 'q': 2813 arm_decode_shift (given, func, stream, 0); 2814 break; 2815 2816 case 'o': 2817 if ((given & 0x02000000) != 0) 2818 { 2819 int rotate = (given & 0xf00) >> 7; 2820 int immed = (given & 0xff); 2821 immed = (((immed << (32 - rotate)) 2822 | (immed >> rotate)) & 0xffffffff); 2823 func (stream, "#%d\t; 0x%x", immed, immed); 2824 } 2825 else 2826 arm_decode_shift (given, func, stream, 1); 2827 break; 2828 2829 case 'p': 2830 if ((given & 0x0000f000) == 0x0000f000) 2831 func (stream, "p"); 2832 break; 2833 2834 case 't': 2835 if ((given & 0x01200000) == 0x00200000) 2836 func (stream, "t"); 2837 break; 2838 2839 case 'A': 2840 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]); 2841 2842 if ((given & (1 << 24)) != 0) 2843 { 2844 int offset = given & 0xff; 2845 2846 if (offset) 2847 func (stream, ", #%s%d]%s", 2848 ((given & 0x00800000) == 0 ? "-" : ""), 2849 offset * 4, 2850 ((given & 0x00200000) != 0 ? "!" : "")); 2851 else 2852 func (stream, "]"); 2853 } 2854 else 2855 { 2856 int offset = given & 0xff; 2857 2858 func (stream, "]"); 2859 2860 if (given & (1 << 21)) 2861 { 2862 if (offset) 2863 func (stream, ", #%s%d", 2864 ((given & 0x00800000) == 0 ? "-" : ""), 2865 offset * 4); 2866 } 2867 else 2868 func (stream, ", {%d}", offset); 2869 } 2870 break; 2871 2872 case 'B': 2873 /* Print ARM V5 BLX(1) address: pc+25 bits. */ 2874 { 2875 bfd_vma address; 2876 bfd_vma offset = 0; 2877 2878 if (given & 0x00800000) 2879 /* Is signed, hi bits should be ones. */ 2880 offset = (-1) ^ 0x00ffffff; 2881 2882 /* Offset is (SignExtend(offset field)<<2). */ 2883 offset += given & 0x00ffffff; 2884 offset <<= 2; 2885 address = offset + pc + 8; 2886 2887 if (given & 0x01000000) 2888 /* H bit allows addressing to 2-byte boundaries. */ 2889 address += 2; 2890 2891 info->print_address_func (address, info); 2892 } 2893 break; 2894 2895 case 'C': 2896 func (stream, "_"); 2897 if (given & 0x80000) 2898 func (stream, "f"); 2899 if (given & 0x40000) 2900 func (stream, "s"); 2901 if (given & 0x20000) 2902 func (stream, "x"); 2903 if (given & 0x10000) 2904 func (stream, "c"); 2905 break; 2906 2907 case 'U': 2908 switch (given & 0xf) 2909 { 2910 case 0xf: func(stream, "sy"); break; 2911 case 0x7: func(stream, "un"); break; 2912 case 0xe: func(stream, "st"); break; 2913 case 0x6: func(stream, "unst"); break; 2914 default: 2915 func(stream, "#%d", (int)given & 0xf); 2916 break; 2917 } 2918 break; 2919 2920 case '0': case '1': case '2': case '3': case '4': 2921 case '5': case '6': case '7': case '8': case '9': 2922 { 2923 int width; 2924 unsigned long value; 2925 2926 c = arm_decode_bitfield (c, given, &value, &width); 2927 2928 switch (*c) 2929 { 2930 case 'r': 2931 func (stream, "%s", arm_regnames[value]); 2932 break; 2933 case 'd': 2934 func (stream, "%ld", value); 2935 break; 2936 case 'b': 2937 func (stream, "%ld", value * 8); 2938 break; 2939 case 'W': 2940 func (stream, "%ld", value + 1); 2941 break; 2942 case 'x': 2943 func (stream, "0x%08lx", value); 2944 2945 /* Some SWI instructions have special 2946 meanings. */ 2947 if ((given & 0x0fffffff) == 0x0FF00000) 2948 func (stream, "\t; IMB"); 2949 else if ((given & 0x0fffffff) == 0x0FF00001) 2950 func (stream, "\t; IMBRange"); 2951 break; 2952 case 'X': 2953 func (stream, "%01lx", value & 0xf); 2954 break; 2955 case '`': 2956 c++; 2957 if (value == 0) 2958 func (stream, "%c", *c); 2959 break; 2960 case '\'': 2961 c++; 2962 if (value == ((1ul << width) - 1)) 2963 func (stream, "%c", *c); 2964 break; 2965 case '?': 2966 func (stream, "%c", c[(1 << width) - (int)value]); 2967 c += 1 << width; 2968 break; 2969 default: 2970 abort (); 2971 } 2972 break; 2973 2974 case 'e': 2975 { 2976 int imm; 2977 2978 imm = (given & 0xf) | ((given & 0xfff00) >> 4); 2979 func (stream, "%d", imm); 2980 } 2981 break; 2982 2983 case 'E': 2984 /* LSB and WIDTH fields of BFI or BFC. The machine- 2985 language instruction encodes LSB and MSB. */ 2986 { 2987 long msb = (given & 0x001f0000) >> 16; 2988 long lsb = (given & 0x00000f80) >> 7; 2989 2990 long width = msb - lsb + 1; 2991 if (width > 0) 2992 func (stream, "#%lu, #%lu", lsb, width); 2993 else 2994 func (stream, "(invalid: %lu:%lu)", lsb, msb); 2995 } 2996 break; 2997 2998 case 'V': 2999 /* 16-bit unsigned immediate from a MOVT or MOVW 3000 instruction, encoded in bits 0:11 and 15:19. */ 3001 { 3002 long hi = (given & 0x000f0000) >> 4; 3003 long lo = (given & 0x00000fff); 3004 long imm16 = hi | lo; 3005 func (stream, "#%lu\t; 0x%lx", imm16, imm16); 3006 } 3007 break; 3008 3009 default: 3010 abort (); 3011 } 3012 } 3013 } 3014 else 3015 func (stream, "%c", *c); 3016 } 3017 return; 3018 } 3019 } 3020 abort (); 3021} 3022 3023/* Print one 16-bit Thumb instruction from PC on INFO->STREAM. */ 3024 3025static void 3026print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given) 3027{ 3028 const struct opcode16 *insn; 3029 void *stream = info->stream; 3030 fprintf_ftype func = info->fprintf_func; 3031 3032 for (insn = thumb_opcodes; insn->assembler; insn++) 3033 if ((given & insn->mask) == insn->value) 3034 { 3035 const char *c = insn->assembler; 3036 for (; *c; c++) 3037 { 3038 int domaskpc = 0; 3039 int domasklr = 0; 3040 3041 if (*c != '%') 3042 { 3043 func (stream, "%c", *c); 3044 continue; 3045 } 3046 3047 switch (*++c) 3048 { 3049 case '%': 3050 func (stream, "%%"); 3051 break; 3052 3053 case 'c': 3054 if (ifthen_state) 3055 func (stream, "%s", arm_conditional[IFTHEN_COND]); 3056 break; 3057 3058 case 'C': 3059 if (ifthen_state) 3060 func (stream, "%s", arm_conditional[IFTHEN_COND]); 3061 else 3062 func (stream, "s"); 3063 break; 3064 3065 case 'I': 3066 { 3067 unsigned int tmp; 3068 3069 ifthen_next_state = given & 0xff; 3070 for (tmp = given << 1; tmp & 0xf; tmp <<= 1) 3071 func (stream, ((given ^ tmp) & 0x10) ? "e" : "t"); 3072 func (stream, "\t%s", arm_conditional[(given >> 4) & 0xf]); 3073 } 3074 break; 3075 3076 case 'x': 3077 if (ifthen_next_state) 3078 func (stream, "\t; unpredictable branch in IT block\n"); 3079 break; 3080 3081 case 'X': 3082 if (ifthen_state) 3083 func (stream, "\t; unpredictable <IT:%s>", 3084 arm_conditional[IFTHEN_COND]); 3085 break; 3086 3087 case 'S': 3088 { 3089 long reg; 3090 3091 reg = (given >> 3) & 0x7; 3092 if (given & (1 << 6)) 3093 reg += 8; 3094 3095 func (stream, "%s", arm_regnames[reg]); 3096 } 3097 break; 3098 3099 case 'D': 3100 { 3101 long reg; 3102 3103 reg = given & 0x7; 3104 if (given & (1 << 7)) 3105 reg += 8; 3106 3107 func (stream, "%s", arm_regnames[reg]); 3108 } 3109 break; 3110 3111 case 'N': 3112 if (given & (1 << 8)) 3113 domasklr = 1; 3114 /* Fall through. */ 3115 case 'O': 3116 if (*c == 'O' && (given & (1 << 8))) 3117 domaskpc = 1; 3118 /* Fall through. */ 3119 case 'M': 3120 { 3121 int started = 0; 3122 int reg; 3123 3124 func (stream, "{"); 3125 3126 /* It would be nice if we could spot 3127 ranges, and generate the rS-rE format: */ 3128 for (reg = 0; (reg < 8); reg++) 3129 if ((given & (1 << reg)) != 0) 3130 { 3131 if (started) 3132 func (stream, ", "); 3133 started = 1; 3134 func (stream, "%s", arm_regnames[reg]); 3135 } 3136 3137 if (domasklr) 3138 { 3139 if (started) 3140 func (stream, ", "); 3141 started = 1; 3142 func (stream, arm_regnames[14] /* "lr" */); 3143 } 3144 3145 if (domaskpc) 3146 { 3147 if (started) 3148 func (stream, ", "); 3149 func (stream, arm_regnames[15] /* "pc" */); 3150 } 3151 3152 func (stream, "}"); 3153 } 3154 break; 3155 3156 case 'b': 3157 /* Print ARM V6T2 CZB address: pc+4+6 bits. */ 3158 { 3159 bfd_vma address = (pc + 4 3160 + ((given & 0x00f8) >> 2) 3161 + ((given & 0x0200) >> 3)); 3162 info->print_address_func (address, info); 3163 } 3164 break; 3165 3166 case 's': 3167 /* Right shift immediate -- bits 6..10; 1-31 print 3168 as themselves, 0 prints as 32. */ 3169 { 3170 long imm = (given & 0x07c0) >> 6; 3171 if (imm == 0) 3172 imm = 32; 3173 func (stream, "#%ld", imm); 3174 } 3175 break; 3176 3177 case '0': case '1': case '2': case '3': case '4': 3178 case '5': case '6': case '7': case '8': case '9': 3179 { 3180 int bitstart = *c++ - '0'; 3181 int bitend = 0; 3182 3183 while (*c >= '0' && *c <= '9') 3184 bitstart = (bitstart * 10) + *c++ - '0'; 3185 3186 switch (*c) 3187 { 3188 case '-': 3189 { 3190 long reg; 3191 3192 c++; 3193 while (*c >= '0' && *c <= '9') 3194 bitend = (bitend * 10) + *c++ - '0'; 3195 if (!bitend) 3196 abort (); 3197 reg = given >> bitstart; 3198 reg &= (2 << (bitend - bitstart)) - 1; 3199 switch (*c) 3200 { 3201 case 'r': 3202 func (stream, "%s", arm_regnames[reg]); 3203 break; 3204 3205 case 'd': 3206 func (stream, "%ld", reg); 3207 break; 3208 3209 case 'H': 3210 func (stream, "%ld", reg << 1); 3211 break; 3212 3213 case 'W': 3214 func (stream, "%ld", reg << 2); 3215 break; 3216 3217 case 'a': 3218 /* PC-relative address -- the bottom two 3219 bits of the address are dropped 3220 before the calculation. */ 3221 info->print_address_func 3222 (((pc + 4) & ~3) + (reg << 2), info); 3223 break; 3224 3225 case 'x': 3226 func (stream, "0x%04lx", reg); 3227 break; 3228 3229 case 'B': 3230 reg = ((reg ^ (1 << bitend)) - (1 << bitend)); 3231 info->print_address_func (reg * 2 + pc + 4, info); 3232 break; 3233 3234 case 'c': 3235 func (stream, "%s", arm_conditional [reg]); 3236 break; 3237 3238 default: 3239 abort (); 3240 } 3241 } 3242 break; 3243 3244 case '\'': 3245 c++; 3246 if ((given & (1 << bitstart)) != 0) 3247 func (stream, "%c", *c); 3248 break; 3249 3250 case '?': 3251 ++c; 3252 if ((given & (1 << bitstart)) != 0) 3253 func (stream, "%c", *c++); 3254 else 3255 func (stream, "%c", *++c); 3256 break; 3257 3258 default: 3259 abort (); 3260 } 3261 } 3262 break; 3263 3264 default: 3265 abort (); 3266 } 3267 } 3268 return; 3269 } 3270 3271 /* No match. */ 3272 abort (); 3273} 3274 3275/* Return the name of an V7M special register. */ 3276static const char * 3277psr_name (int regno) 3278{ 3279 switch (regno) 3280 { 3281 case 0: return "APSR"; 3282 case 1: return "IAPSR"; 3283 case 2: return "EAPSR"; 3284 case 3: return "PSR"; 3285 case 5: return "IPSR"; 3286 case 6: return "EPSR"; 3287 case 7: return "IEPSR"; 3288 case 8: return "MSP"; 3289 case 9: return "PSP"; 3290 case 16: return "PRIMASK"; 3291 case 17: return "BASEPRI"; 3292 case 18: return "BASEPRI_MASK"; 3293 case 19: return "FAULTMASK"; 3294 case 20: return "CONTROL"; 3295 default: return "<unknown>"; 3296 } 3297} 3298 3299/* Print one 32-bit Thumb instruction from PC on INFO->STREAM. */ 3300 3301static void 3302print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given) 3303{ 3304 const struct opcode32 *insn; 3305 void *stream = info->stream; 3306 fprintf_ftype func = info->fprintf_func; 3307 3308 if (print_insn_coprocessor (pc, info, given, TRUE)) 3309 return; 3310 3311 if (print_insn_neon (info, given, TRUE)) 3312 return; 3313 3314 for (insn = thumb32_opcodes; insn->assembler; insn++) 3315 if ((given & insn->mask) == insn->value) 3316 { 3317 const char *c = insn->assembler; 3318 for (; *c; c++) 3319 { 3320 if (*c != '%') 3321 { 3322 func (stream, "%c", *c); 3323 continue; 3324 } 3325 3326 switch (*++c) 3327 { 3328 case '%': 3329 func (stream, "%%"); 3330 break; 3331 3332 case 'c': 3333 if (ifthen_state) 3334 func (stream, "%s", arm_conditional[IFTHEN_COND]); 3335 break; 3336 3337 case 'x': 3338 if (ifthen_next_state) 3339 func (stream, "\t; unpredictable branch in IT block\n"); 3340 break; 3341 3342 case 'X': 3343 if (ifthen_state) 3344 func (stream, "\t; unpredictable <IT:%s>", 3345 arm_conditional[IFTHEN_COND]); 3346 break; 3347 3348 case 'I': 3349 { 3350 unsigned int imm12 = 0; 3351 imm12 |= (given & 0x000000ffu); 3352 imm12 |= (given & 0x00007000u) >> 4; 3353 imm12 |= (given & 0x04000000u) >> 15; 3354 func (stream, "#%u\t; 0x%x", imm12, imm12); 3355 } 3356 break; 3357 3358 case 'M': 3359 { 3360 unsigned int bits = 0, imm, imm8, mod; 3361 bits |= (given & 0x000000ffu); 3362 bits |= (given & 0x00007000u) >> 4; 3363 bits |= (given & 0x04000000u) >> 15; 3364 imm8 = (bits & 0x0ff); 3365 mod = (bits & 0xf00) >> 8; 3366 switch (mod) 3367 { 3368 case 0: imm = imm8; break; 3369 case 1: imm = ((imm8<<16) | imm8); break; 3370 case 2: imm = ((imm8<<24) | (imm8 << 8)); break; 3371 case 3: imm = ((imm8<<24) | (imm8 << 16) | (imm8 << 8) | imm8); break; 3372 default: 3373 mod = (bits & 0xf80) >> 7; 3374 imm8 = (bits & 0x07f) | 0x80; 3375 imm = (((imm8 << (32 - mod)) | (imm8 >> mod)) & 0xffffffff); 3376 } 3377 func (stream, "#%u\t; 0x%x", imm, imm); 3378 } 3379 break; 3380 3381 case 'J': 3382 { 3383 unsigned int imm = 0; 3384 imm |= (given & 0x000000ffu); 3385 imm |= (given & 0x00007000u) >> 4; 3386 imm |= (given & 0x04000000u) >> 15; 3387 imm |= (given & 0x000f0000u) >> 4; 3388 func (stream, "#%u\t; 0x%x", imm, imm); 3389 } 3390 break; 3391 3392 case 'K': 3393 { 3394 unsigned int imm = 0; 3395 imm |= (given & 0x000f0000u) >> 16; 3396 imm |= (given & 0x00000ff0u) >> 0; 3397 imm |= (given & 0x0000000fu) << 12; 3398 func (stream, "#%u\t; 0x%x", imm, imm); 3399 } 3400 break; 3401 3402 case 'S': 3403 { 3404 unsigned int reg = (given & 0x0000000fu); 3405 unsigned int stp = (given & 0x00000030u) >> 4; 3406 unsigned int imm = 0; 3407 imm |= (given & 0x000000c0u) >> 6; 3408 imm |= (given & 0x00007000u) >> 10; 3409 3410 func (stream, "%s", arm_regnames[reg]); 3411 switch (stp) 3412 { 3413 case 0: 3414 if (imm > 0) 3415 func (stream, ", lsl #%u", imm); 3416 break; 3417 3418 case 1: 3419 if (imm == 0) 3420 imm = 32; 3421 func (stream, ", lsr #%u", imm); 3422 break; 3423 3424 case 2: 3425 if (imm == 0) 3426 imm = 32; 3427 func (stream, ", asr #%u", imm); 3428 break; 3429 3430 case 3: 3431 if (imm == 0) 3432 func (stream, ", rrx"); 3433 else 3434 func (stream, ", ror #%u", imm); 3435 } 3436 } 3437 break; 3438 3439 case 'a': 3440 { 3441 unsigned int Rn = (given & 0x000f0000) >> 16; 3442 unsigned int U = (given & 0x00800000) >> 23; 3443 unsigned int op = (given & 0x00000f00) >> 8; 3444 unsigned int i12 = (given & 0x00000fff); 3445 unsigned int i8 = (given & 0x000000ff); 3446 bfd_boolean writeback = FALSE, postind = FALSE; 3447 int offset = 0; 3448 3449 func (stream, "[%s", arm_regnames[Rn]); 3450 if (U) /* 12-bit positive immediate offset */ 3451 offset = i12; 3452 else if (Rn == 15) /* 12-bit negative immediate offset */ 3453 offset = -(int)i12; 3454 else if (op == 0x0) /* shifted register offset */ 3455 { 3456 unsigned int Rm = (i8 & 0x0f); 3457 unsigned int sh = (i8 & 0x30) >> 4; 3458 func (stream, ", %s", arm_regnames[Rm]); 3459 if (sh) 3460 func (stream, ", lsl #%u", sh); 3461 func (stream, "]"); 3462 break; 3463 } 3464 else switch (op) 3465 { 3466 case 0xE: /* 8-bit positive immediate offset */ 3467 offset = i8; 3468 break; 3469 3470 case 0xC: /* 8-bit negative immediate offset */ 3471 offset = -i8; 3472 break; 3473 3474 case 0xF: /* 8-bit + preindex with wb */ 3475 offset = i8; 3476 writeback = TRUE; 3477 break; 3478 3479 case 0xD: /* 8-bit - preindex with wb */ 3480 offset = -i8; 3481 writeback = TRUE; 3482 break; 3483 3484 case 0xB: /* 8-bit + postindex */ 3485 offset = i8; 3486 postind = TRUE; 3487 break; 3488 3489 case 0x9: /* 8-bit - postindex */ 3490 offset = -i8; 3491 postind = TRUE; 3492 break; 3493 3494 default: 3495 func (stream, ", <undefined>]"); 3496 goto skip; 3497 } 3498 3499 if (postind) 3500 func (stream, "], #%d", offset); 3501 else 3502 { 3503 if (offset) 3504 func (stream, ", #%d", offset); 3505 func (stream, writeback ? "]!" : "]"); 3506 } 3507 3508 if (Rn == 15) 3509 { 3510 func (stream, "\t; "); 3511 info->print_address_func (((pc + 4) & ~3) + offset, info); 3512 } 3513 } 3514 skip: 3515 break; 3516 3517 case 'A': 3518 { 3519 unsigned int P = (given & 0x01000000) >> 24; 3520 unsigned int U = (given & 0x00800000) >> 23; 3521 unsigned int W = (given & 0x00400000) >> 21; 3522 unsigned int Rn = (given & 0x000f0000) >> 16; 3523 unsigned int off = (given & 0x000000ff); 3524 3525 func (stream, "[%s", arm_regnames[Rn]); 3526 if (P) 3527 { 3528 if (off || !U) 3529 func (stream, ", #%c%u", U ? '+' : '-', off * 4); 3530 func (stream, "]"); 3531 if (W) 3532 func (stream, "!"); 3533 } 3534 else 3535 { 3536 func (stream, "], "); 3537 if (W) 3538 func (stream, "#%c%u", U ? '+' : '-', off * 4); 3539 else 3540 func (stream, "{%u}", off); 3541 } 3542 } 3543 break; 3544 3545 case 'w': 3546 { 3547 unsigned int Sbit = (given & 0x01000000) >> 24; 3548 unsigned int type = (given & 0x00600000) >> 21; 3549 switch (type) 3550 { 3551 case 0: func (stream, Sbit ? "sb" : "b"); break; 3552 case 1: func (stream, Sbit ? "sh" : "h"); break; 3553 case 2: 3554 if (Sbit) 3555 func (stream, "??"); 3556 break; 3557 case 3: 3558 func (stream, "??"); 3559 break; 3560 } 3561 } 3562 break; 3563 3564 case 'm': 3565 { 3566 int started = 0; 3567 int reg; 3568 3569 func (stream, "{"); 3570 for (reg = 0; reg < 16; reg++) 3571 if ((given & (1 << reg)) != 0) 3572 { 3573 if (started) 3574 func (stream, ", "); 3575 started = 1; 3576 func (stream, "%s", arm_regnames[reg]); 3577 } 3578 func (stream, "}"); 3579 } 3580 break; 3581 3582 case 'E': 3583 { 3584 unsigned int msb = (given & 0x0000001f); 3585 unsigned int lsb = 0; 3586 lsb |= (given & 0x000000c0u) >> 6; 3587 lsb |= (given & 0x00007000u) >> 10; 3588 func (stream, "#%u, #%u", lsb, msb - lsb + 1); 3589 } 3590 break; 3591 3592 case 'F': 3593 { 3594 unsigned int width = (given & 0x0000001f) + 1; 3595 unsigned int lsb = 0; 3596 lsb |= (given & 0x000000c0u) >> 6; 3597 lsb |= (given & 0x00007000u) >> 10; 3598 func (stream, "#%u, #%u", lsb, width); 3599 } 3600 break; 3601 3602 case 'b': 3603 { 3604 unsigned int S = (given & 0x04000000u) >> 26; 3605 unsigned int J1 = (given & 0x00002000u) >> 13; 3606 unsigned int J2 = (given & 0x00000800u) >> 11; 3607 int offset = 0; 3608 3609 offset |= !S << 20; 3610 offset |= J2 << 19; 3611 offset |= J1 << 18; 3612 offset |= (given & 0x003f0000) >> 4; 3613 offset |= (given & 0x000007ff) << 1; 3614 offset -= (1 << 20); 3615 3616 info->print_address_func (pc + 4 + offset, info); 3617 } 3618 break; 3619 3620 case 'B': 3621 { 3622 unsigned int S = (given & 0x04000000u) >> 26; 3623 unsigned int I1 = (given & 0x00002000u) >> 13; 3624 unsigned int I2 = (given & 0x00000800u) >> 11; 3625 int offset = 0; 3626 3627 offset |= !S << 24; 3628 offset |= !(I1 ^ S) << 23; 3629 offset |= !(I2 ^ S) << 22; 3630 offset |= (given & 0x03ff0000u) >> 4; 3631 offset |= (given & 0x000007ffu) << 1; 3632 offset -= (1 << 24); 3633 offset += pc + 4; 3634 3635 /* BLX target addresses are always word aligned. */ 3636 if ((given & 0x00001000u) == 0) 3637 offset &= ~2u; 3638 3639 info->print_address_func (offset, info); 3640 } 3641 break; 3642 3643 case 's': 3644 { 3645 unsigned int shift = 0; 3646 shift |= (given & 0x000000c0u) >> 6; 3647 shift |= (given & 0x00007000u) >> 10; 3648 if (given & 0x00200000u) 3649 func (stream, ", asr #%u", shift); 3650 else if (shift) 3651 func (stream, ", lsl #%u", shift); 3652 /* else print nothing - lsl #0 */ 3653 } 3654 break; 3655 3656 case 'R': 3657 { 3658 unsigned int rot = (given & 0x00000030) >> 4; 3659 if (rot) 3660 func (stream, ", ror #%u", rot * 8); 3661 } 3662 break; 3663 3664 case 'U': 3665 switch (given & 0xf) 3666 { 3667 case 0xf: func(stream, "sy"); break; 3668 case 0x7: func(stream, "un"); break; 3669 case 0xe: func(stream, "st"); break; 3670 case 0x6: func(stream, "unst"); break; 3671 default: 3672 func(stream, "#%d", (int)given & 0xf); 3673 break; 3674 } 3675 break; 3676 3677 case 'C': 3678 if ((given & 0xff) == 0) 3679 { 3680 func (stream, "%cPSR_", (given & 0x100000) ? 'S' : 'C'); 3681 if (given & 0x800) 3682 func (stream, "f"); 3683 if (given & 0x400) 3684 func (stream, "s"); 3685 if (given & 0x200) 3686 func (stream, "x"); 3687 if (given & 0x100) 3688 func (stream, "c"); 3689 } 3690 else 3691 { 3692 func (stream, psr_name (given & 0xff)); 3693 } 3694 break; 3695 3696 case 'D': 3697 if ((given & 0xff) == 0) 3698 func (stream, "%cPSR", (given & 0x100000) ? 'S' : 'C'); 3699 else 3700 func (stream, psr_name (given & 0xff)); 3701 break; 3702 3703 case '0': case '1': case '2': case '3': case '4': 3704 case '5': case '6': case '7': case '8': case '9': 3705 { 3706 int width; 3707 unsigned long val; 3708 3709 c = arm_decode_bitfield (c, given, &val, &width); 3710 3711 switch (*c) 3712 { 3713 case 'd': func (stream, "%lu", val); break; 3714 case 'W': func (stream, "%lu", val * 4); break; 3715 case 'r': func (stream, "%s", arm_regnames[val]); break; 3716 3717 case 'c': 3718 func (stream, "%s", arm_conditional[val]); 3719 break; 3720 3721 case '\'': 3722 c++; 3723 if (val == ((1ul << width) - 1)) 3724 func (stream, "%c", *c); 3725 break; 3726 3727 case '`': 3728 c++; 3729 if (val == 0) 3730 func (stream, "%c", *c); 3731 break; 3732 3733 case '?': 3734 func (stream, "%c", c[(1 << width) - (int)val]); 3735 c += 1 << width; 3736 break; 3737 3738 default: 3739 abort (); 3740 } 3741 } 3742 break; 3743 3744 default: 3745 abort (); 3746 } 3747 } 3748 return; 3749 } 3750 3751 /* No match. */ 3752 abort (); 3753} 3754 3755/* Print data bytes on INFO->STREAM. */ 3756 3757static void 3758print_insn_data (bfd_vma pc ATTRIBUTE_UNUSED, struct disassemble_info *info, 3759 long given) 3760{ 3761 switch (info->bytes_per_chunk) 3762 { 3763 case 1: 3764 info->fprintf_func (info->stream, ".byte\t0x%02lx", given); 3765 break; 3766 case 2: 3767 info->fprintf_func (info->stream, ".short\t0x%04lx", given); 3768 break; 3769 case 4: 3770 info->fprintf_func (info->stream, ".word\t0x%08lx", given); 3771 break; 3772 default: 3773 abort (); 3774 } 3775} 3776 3777/* Disallow mapping symbols ($a, $b, $d, $t etc) from 3778 being displayed in symbol relative addresses. */ 3779 3780bfd_boolean 3781arm_symbol_is_valid (asymbol * sym, 3782 struct disassemble_info * info ATTRIBUTE_UNUSED) 3783{ 3784 const char * name; 3785 3786 if (sym == NULL) 3787 return FALSE; 3788 3789 name = bfd_asymbol_name (sym); 3790 3791 return (name && *name != '$'); 3792} 3793 3794/* Parse an individual disassembler option. */ 3795 3796void 3797parse_arm_disassembler_option (char *option) 3798{ 3799 if (option == NULL) 3800 return; 3801 3802 if (CONST_STRNEQ (option, "reg-names-")) 3803 { 3804 int i; 3805 3806 option += 10; 3807 3808 for (i = NUM_ARM_REGNAMES; i--;) 3809 if (strneq (option, regnames[i].name, strlen (regnames[i].name))) 3810 { 3811 regname_selected = i; 3812 break; 3813 } 3814 3815 if (i < 0) 3816 /* XXX - should break 'option' at following delimiter. */ 3817 fprintf (stderr, _("Unrecognised register name set: %s\n"), option); 3818 } 3819 else if (CONST_STRNEQ (option, "force-thumb")) 3820 force_thumb = 1; 3821 else if (CONST_STRNEQ (option, "no-force-thumb")) 3822 force_thumb = 0; 3823 else 3824 /* XXX - should break 'option' at following delimiter. */ 3825 fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option); 3826 3827 return; 3828} 3829 3830/* Parse the string of disassembler options, spliting it at whitespaces 3831 or commas. (Whitespace separators supported for backwards compatibility). */ 3832 3833static void 3834parse_disassembler_options (char *options) 3835{ 3836 if (options == NULL) 3837 return; 3838 3839 while (*options) 3840 { 3841 parse_arm_disassembler_option (options); 3842 3843 /* Skip forward to next seperator. */ 3844 while ((*options) && (! ISSPACE (*options)) && (*options != ',')) 3845 ++ options; 3846 /* Skip forward past seperators. */ 3847 while (ISSPACE (*options) || (*options == ',')) 3848 ++ options; 3849 } 3850} 3851 3852/* Search back through the insn stream to determine if this instruction is 3853 conditionally executed. */ 3854static void 3855find_ifthen_state (bfd_vma pc, struct disassemble_info *info, 3856 bfd_boolean little) 3857{ 3858 unsigned char b[2]; 3859 unsigned int insn; 3860 int status; 3861 /* COUNT is twice the number of instructions seen. It will be odd if we 3862 just crossed an instruction boundary. */ 3863 int count; 3864 int it_count; 3865 unsigned int seen_it; 3866 bfd_vma addr; 3867 3868 ifthen_address = pc; 3869 ifthen_state = 0; 3870 3871 addr = pc; 3872 count = 1; 3873 it_count = 0; 3874 seen_it = 0; 3875 /* Scan backwards looking for IT instructions, keeping track of where 3876 instruction boundaries are. We don't know if something is actually an 3877 IT instruction until we find a definite instruction boundary. */ 3878 for (;;) 3879 { 3880 if (addr == 0 || info->symbol_at_address_func(addr, info)) 3881 { 3882 /* A symbol must be on an instruction boundary, and will not 3883 be within an IT block. */ 3884 if (seen_it && (count & 1)) 3885 break; 3886 3887 return; 3888 } 3889 addr -= 2; 3890 status = info->read_memory_func (addr, (bfd_byte *)b, 2, info); 3891 if (status) 3892 return; 3893 3894 if (little) 3895 insn = (b[0]) | (b[1] << 8); 3896 else 3897 insn = (b[1]) | (b[0] << 8); 3898 if (seen_it) 3899 { 3900 if ((insn & 0xf800) < 0xe800) 3901 { 3902 /* Addr + 2 is an instruction boundary. See if this matches 3903 the expected boundary based on the position of the last 3904 IT candidate. */ 3905 if (count & 1) 3906 break; 3907 seen_it = 0; 3908 } 3909 } 3910 if ((insn & 0xff00) == 0xbf00 && (insn & 0xf) != 0) 3911 { 3912 /* This could be an IT instruction. */ 3913 seen_it = insn; 3914 it_count = count >> 1; 3915 } 3916 if ((insn & 0xf800) >= 0xe800) 3917 count++; 3918 else 3919 count = (count + 2) | 1; 3920 /* IT blocks contain at most 4 instructions. */ 3921 if (count >= 8 && !seen_it) 3922 return; 3923 } 3924 /* We found an IT instruction. */ 3925 ifthen_state = (seen_it & 0xe0) | ((seen_it << it_count) & 0x1f); 3926 if ((ifthen_state & 0xf) == 0) 3927 ifthen_state = 0; 3928} 3929 3930/* Try to infer the code type (Arm or Thumb) from a symbol. 3931 Returns nonzero if *MAP_TYPE was set. */ 3932 3933static int 3934get_sym_code_type (struct disassemble_info *info, int n, 3935 enum map_type *map_type) 3936{ 3937 elf_symbol_type *es; 3938 unsigned int type; 3939 const char *name; 3940 3941 es = *(elf_symbol_type **)(info->symtab + n); 3942 type = ELF_ST_TYPE (es->internal_elf_sym.st_info); 3943 3944 /* If the symbol has function type then use that. */ 3945 if (type == STT_FUNC || type == STT_ARM_TFUNC) 3946 { 3947 *map_type = (type == STT_ARM_TFUNC) ? MAP_THUMB : MAP_ARM; 3948 return TRUE; 3949 } 3950 3951 /* Check for mapping symbols. */ 3952 name = bfd_asymbol_name(info->symtab[n]); 3953 if (name[0] == '$' && (name[1] == 'a' || name[1] == 't' || name[1] == 'd') 3954 && (name[2] == 0 || name[2] == '.')) 3955 { 3956 *map_type = ((name[1] == 'a') ? MAP_ARM 3957 : (name[1] == 't') ? MAP_THUMB 3958 : MAP_DATA); 3959 return TRUE; 3960 } 3961 3962 return FALSE; 3963} 3964 3965/* NOTE: There are no checks in these routines that 3966 the relevant number of data bytes exist. */ 3967 3968static int 3969print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little) 3970{ 3971 unsigned char b[4]; 3972 long given; 3973 int status; 3974 int is_thumb = FALSE; 3975 int is_data = FALSE; 3976 unsigned int size = 4; 3977 void (*printer) (bfd_vma, struct disassemble_info *, long); 3978 bfd_boolean found = FALSE; 3979 3980 if (info->disassembler_options) 3981 { 3982 parse_disassembler_options (info->disassembler_options); 3983 3984 /* To avoid repeated parsing of these options, we remove them here. */ 3985 info->disassembler_options = NULL; 3986 } 3987 3988 /* First check the full symtab for a mapping symbol, even if there 3989 are no usable non-mapping symbols for this address. */ 3990 if (info->symtab != NULL 3991 && bfd_asymbol_flavour (*info->symtab) == bfd_target_elf_flavour) 3992 { 3993 bfd_vma addr; 3994 int n; 3995 int last_sym = -1; 3996 enum map_type type = MAP_ARM; 3997 3998 if (pc <= last_mapping_addr) 3999 last_mapping_sym = -1; 4000 is_thumb = (last_type == MAP_THUMB); 4001 found = FALSE; 4002 /* Start scanning at the start of the function, or wherever 4003 we finished last time. */ 4004 n = info->symtab_pos + 1; 4005 if (n < last_mapping_sym) 4006 n = last_mapping_sym; 4007 4008 /* Scan up to the location being disassembled. */ 4009 for (; n < info->symtab_size; n++) 4010 { 4011 addr = bfd_asymbol_value (info->symtab[n]); 4012 if (addr > pc) 4013 break; 4014 if ((info->section == NULL 4015 || info->section == info->symtab[n]->section) 4016 && get_sym_code_type (info, n, &type)) 4017 { 4018 last_sym = n; 4019 found = TRUE; 4020 } 4021 } 4022 4023 if (!found) 4024 { 4025 n = info->symtab_pos; 4026 if (n < last_mapping_sym - 1) 4027 n = last_mapping_sym - 1; 4028 4029 /* No mapping symbol found at this address. Look backwards 4030 for a preceeding one. */ 4031 for (; n >= 0; n--) 4032 { 4033 if (get_sym_code_type (info, n, &type)) 4034 { 4035 last_sym = n; 4036 found = TRUE; 4037 break; 4038 } 4039 } 4040 } 4041 4042 last_mapping_sym = last_sym; 4043 last_type = type; 4044 is_thumb = (last_type == MAP_THUMB); 4045 is_data = (last_type == MAP_DATA); 4046 4047 /* Look a little bit ahead to see if we should print out 4048 two or four bytes of data. If there's a symbol, 4049 mapping or otherwise, after two bytes then don't 4050 print more. */ 4051 if (is_data) 4052 { 4053 size = 4 - (pc & 3); 4054 for (n = last_sym + 1; n < info->symtab_size; n++) 4055 { 4056 addr = bfd_asymbol_value (info->symtab[n]); 4057 if (addr > pc) 4058 { 4059 if (addr - pc < size) 4060 size = addr - pc; 4061 break; 4062 } 4063 } 4064 /* If the next symbol is after three bytes, we need to 4065 print only part of the data, so that we can use either 4066 .byte or .short. */ 4067 if (size == 3) 4068 size = (pc & 1) ? 1 : 2; 4069 } 4070 } 4071 4072 if (info->symbols != NULL) 4073 { 4074 if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour) 4075 { 4076 coff_symbol_type * cs; 4077 4078 cs = coffsymbol (*info->symbols); 4079 is_thumb = ( cs->native->u.syment.n_sclass == C_THUMBEXT 4080 || cs->native->u.syment.n_sclass == C_THUMBSTAT 4081 || cs->native->u.syment.n_sclass == C_THUMBLABEL 4082 || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC 4083 || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC); 4084 } 4085 else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour 4086 && !found) 4087 { 4088 /* If no mapping symbol has been found then fall back to the type 4089 of the function symbol. */ 4090 elf_symbol_type * es; 4091 unsigned int type; 4092 4093 es = *(elf_symbol_type **)(info->symbols); 4094 type = ELF_ST_TYPE (es->internal_elf_sym.st_info); 4095 4096 is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT); 4097 } 4098 } 4099 4100 if (force_thumb) 4101 is_thumb = TRUE; 4102 4103 info->display_endian = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG; 4104 info->bytes_per_line = 4; 4105 4106 if (is_data) 4107 { 4108 int i; 4109 4110 /* size was already set above. */ 4111 info->bytes_per_chunk = size; 4112 printer = print_insn_data; 4113 4114 status = info->read_memory_func (pc, (bfd_byte *)b, size, info); 4115 given = 0; 4116 if (little) 4117 for (i = size - 1; i >= 0; i--) 4118 given = b[i] | (given << 8); 4119 else 4120 for (i = 0; i < (int) size; i++) 4121 given = b[i] | (given << 8); 4122 } 4123 else if (!is_thumb) 4124 { 4125 /* In ARM mode endianness is a straightforward issue: the instruction 4126 is four bytes long and is either ordered 0123 or 3210. */ 4127 printer = print_insn_arm; 4128 info->bytes_per_chunk = 4; 4129 size = 4; 4130 4131 status = info->read_memory_func (pc, (bfd_byte *)b, 4, info); 4132 if (little) 4133 given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24); 4134 else 4135 given = (b[3]) | (b[2] << 8) | (b[1] << 16) | (b[0] << 24); 4136 } 4137 else 4138 { 4139 /* In Thumb mode we have the additional wrinkle of two 4140 instruction lengths. Fortunately, the bits that determine 4141 the length of the current instruction are always to be found 4142 in the first two bytes. */ 4143 printer = print_insn_thumb16; 4144 info->bytes_per_chunk = 2; 4145 size = 2; 4146 4147 status = info->read_memory_func (pc, (bfd_byte *)b, 2, info); 4148 if (little) 4149 given = (b[0]) | (b[1] << 8); 4150 else 4151 given = (b[1]) | (b[0] << 8); 4152 4153 if (!status) 4154 { 4155 /* These bit patterns signal a four-byte Thumb 4156 instruction. */ 4157 if ((given & 0xF800) == 0xF800 4158 || (given & 0xF800) == 0xF000 4159 || (given & 0xF800) == 0xE800) 4160 { 4161 status = info->read_memory_func (pc + 2, (bfd_byte *)b, 2, info); 4162 if (little) 4163 given = (b[0]) | (b[1] << 8) | (given << 16); 4164 else 4165 given = (b[1]) | (b[0] << 8) | (given << 16); 4166 4167 printer = print_insn_thumb32; 4168 size = 4; 4169 } 4170 } 4171 4172 if (ifthen_address != pc) 4173 find_ifthen_state(pc, info, little); 4174 4175 if (ifthen_state) 4176 { 4177 if ((ifthen_state & 0xf) == 0x8) 4178 ifthen_next_state = 0; 4179 else 4180 ifthen_next_state = (ifthen_state & 0xe0) 4181 | ((ifthen_state & 0xf) << 1); 4182 } 4183 } 4184 4185 if (status) 4186 { 4187 info->memory_error_func (status, pc, info); 4188 return -1; 4189 } 4190 if (info->flags & INSN_HAS_RELOC) 4191 /* If the instruction has a reloc associated with it, then 4192 the offset field in the instruction will actually be the 4193 addend for the reloc. (We are using REL type relocs). 4194 In such cases, we can ignore the pc when computing 4195 addresses, since the addend is not currently pc-relative. */ 4196 pc = 0; 4197 4198 printer (pc, info, given); 4199 4200 if (is_thumb) 4201 { 4202 ifthen_state = ifthen_next_state; 4203 ifthen_address += size; 4204 } 4205 return size; 4206} 4207 4208int 4209print_insn_big_arm (bfd_vma pc, struct disassemble_info *info) 4210{ 4211 return print_insn (pc, info, FALSE); 4212} 4213 4214int 4215print_insn_little_arm (bfd_vma pc, struct disassemble_info *info) 4216{ 4217 return print_insn (pc, info, TRUE); 4218} 4219 4220void 4221print_arm_disassembler_options (FILE *stream) 4222{ 4223 int i; 4224 4225 fprintf (stream, _("\n\ 4226The following ARM specific disassembler options are supported for use with\n\ 4227the -M switch:\n")); 4228 4229 for (i = NUM_ARM_REGNAMES; i--;) 4230 fprintf (stream, " reg-names-%s %*c%s\n", 4231 regnames[i].name, 4232 (int)(14 - strlen (regnames[i].name)), ' ', 4233 regnames[i].description); 4234 4235 fprintf (stream, " force-thumb Assume all insns are Thumb insns\n"); 4236 fprintf (stream, " no-force-thumb Examine preceeding label to determine an insn's type\n\n"); 4237} 4238