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