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