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