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