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