1 /* Instruction printing code for the ARM 2 Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 3 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, write to the Free Software 21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 22 23 #include "sysdep.h" 24 25 #include "dis-asm.h" 26 #include "opcode/arm.h" 27 #include "opintl.h" 28 #include "safe-ctype.h" 29 30 /* FIXME: This shouldn't be done here. */ 31 #include "coff/internal.h" 32 #include "libcoff.h" 33 #include "elf-bfd.h" 34 #include "elf/internal.h" 35 #include "elf/arm.h" 36 37 /* FIXME: Belongs in global header. */ 38 #ifndef strneq 39 #define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0) 40 #endif 41 42 #ifndef NUM_ELEM 43 #define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0]) 44 #endif 45 46 struct opcode32 47 { 48 unsigned long arch; /* Architecture defining this insn. */ 49 unsigned long value, mask; /* Recognise insn if (op&mask)==value. */ 50 const char *assembler; /* How to disassemble this insn. */ 51 }; 52 53 struct opcode16 54 { 55 unsigned long arch; /* Architecture defining this insn. */ 56 unsigned short value, mask; /* Recognise insn if (op&mask)==value. */ 57 const char *assembler; /* How to disassemble this insn. */ 58 }; 59 60 /* print_insn_coprocessor recognizes the following format control codes: 61 62 %% % 63 64 %c print condition code (always bits 28-31) 65 %A print address for ldc/stc/ldf/stf instruction 66 %I print cirrus signed shift immediate: bits 0..3|4..6 67 %F print the COUNT field of a LFM/SFM instruction. 68 %P print floating point precision in arithmetic insn 69 %Q print floating point precision in ldf/stf insn 70 %R print floating point rounding mode 71 72 %<bitfield>r print as an ARM register 73 %<bitfield>d print the bitfield in decimal 74 %<bitfield>x print the bitfield in hex 75 %<bitfield>X print the bitfield as 1 hex digit without leading "0x" 76 %<bitfield>f print a floating point constant if >7 else a 77 floating point register 78 %<bitfield>w print as an iWMMXt width field - [bhwd]ss/us 79 %<bitfield>g print as an iWMMXt 64-bit register 80 %<bitfield>G print as an iWMMXt general purpose or control register 81 82 %<code>y print a single precision VFP reg. 83 Codes: 0=>Sm, 1=>Sd, 2=>Sn, 3=>multi-list, 4=>Sm pair 84 %<code>z print a double precision VFP reg 85 Codes: 0=>Dm, 1=>Dd, 2=>Dn, 3=>multi-list 86 %<bitnum>'c print specified char iff bit is one 87 %<bitnum>`c print specified char iff bit is zero 88 %<bitnum>?ab print a if bit is one else print b 89 90 %L print as an iWMMXt N/M width field. 91 %Z print the Immediate of a WSHUFH instruction. 92 %l like 'A' except use byte offsets for 'B' & 'H' 93 versions. */ 94 95 /* Common coprocessor opcodes shared between Arm and Thumb-2. */ 96 97 static const struct opcode32 coprocessor_opcodes[] = 98 { 99 /* XScale instructions. */ 100 {ARM_CEXT_XSCALE, 0x0e200010, 0x0fff0ff0, "mia%c\tacc0, %0-3r, %12-15r"}, 101 {ARM_CEXT_XSCALE, 0x0e280010, 0x0fff0ff0, "miaph%c\tacc0, %0-3r, %12-15r"}, 102 {ARM_CEXT_XSCALE, 0x0e2c0010, 0x0ffc0ff0, "mia%17'T%17`B%16'T%16`B%c\tacc0, %0-3r, %12-15r"}, 103 {ARM_CEXT_XSCALE, 0x0c400000, 0x0ff00fff, "mar%c\tacc0, %12-15r, %16-19r"}, 104 {ARM_CEXT_XSCALE, 0x0c500000, 0x0ff00fff, "mra%c\t%12-15r, %16-19r, acc0"}, 105 106 /* Intel Wireless MMX technology instructions. */ 107 #define FIRST_IWMMXT_INSN 0x0e130130 108 #define IWMMXT_INSN_COUNT 47 109 {ARM_CEXT_IWMMXT, 0x0e130130, 0x0f3f0fff, "tandc%22-23w%c\t%12-15r"}, 110 {ARM_CEXT_XSCALE, 0x0e400010, 0x0ff00f3f, "tbcst%6-7w%c\t%16-19g, %12-15r"}, 111 {ARM_CEXT_XSCALE, 0x0e130170, 0x0f3f0ff8, "textrc%22-23w%c\t%12-15r, #%0-2d"}, 112 {ARM_CEXT_XSCALE, 0x0e100070, 0x0f300ff0, "textrm%3?su%22-23w%c\t%12-15r, %16-19g, #%0-2d"}, 113 {ARM_CEXT_XSCALE, 0x0e600010, 0x0ff00f38, "tinsr%6-7w%c\t%16-19g, %12-15r, #%0-2d"}, 114 {ARM_CEXT_XSCALE, 0x0e000110, 0x0ff00fff, "tmcr%c\t%16-19G, %12-15r"}, 115 {ARM_CEXT_XSCALE, 0x0c400000, 0x0ff00ff0, "tmcrr%c\t%0-3g, %12-15r, %16-19r"}, 116 {ARM_CEXT_XSCALE, 0x0e2c0010, 0x0ffc0e10, "tmia%17?tb%16?tb%c\t%5-8g, %0-3r, %12-15r"}, 117 {ARM_CEXT_XSCALE, 0x0e200010, 0x0fff0e10, "tmia%c\t%5-8g, %0-3r, %12-15r"}, 118 {ARM_CEXT_XSCALE, 0x0e280010, 0x0fff0e10, "tmiaph%c\t%5-8g, %0-3r, %12-15r"}, 119 {ARM_CEXT_XSCALE, 0x0e100030, 0x0f300fff, "tmovmsk%22-23w%c\t%12-15r, %16-19g"}, 120 {ARM_CEXT_XSCALE, 0x0e100110, 0x0ff00ff0, "tmrc%c\t%12-15r, %16-19G"}, 121 {ARM_CEXT_XSCALE, 0x0c500000, 0x0ff00ff0, "tmrrc%c\t%12-15r, %16-19r, %0-3g"}, 122 {ARM_CEXT_XSCALE, 0x0e130150, 0x0f3f0fff, "torc%22-23w%c\t%12-15r"}, 123 {ARM_CEXT_XSCALE, 0x0e0001c0, 0x0f300fff, "wacc%22-23w%c\t%12-15g, %16-19g"}, 124 {ARM_CEXT_XSCALE, 0x0e000180, 0x0f000ff0, "wadd%20-23w%c\t%12-15g, %16-19g, %0-3g"}, 125 {ARM_CEXT_XSCALE, 0x0e000020, 0x0f800ff0, "waligni%c\t%12-15g, %16-19g, %0-3g, #%20-22d"}, 126 {ARM_CEXT_XSCALE, 0x0e800020, 0x0fc00ff0, "walignr%20-21d%c\t%12-15g, %16-19g, %0-3g"}, 127 {ARM_CEXT_XSCALE, 0x0e200000, 0x0fe00ff0, "wand%20'n%c\t%12-15g, %16-19g, %0-3g"}, 128 {ARM_CEXT_XSCALE, 0x0e800000, 0x0fa00ff0, "wavg2%22?hb%20'r%c\t%12-15g, %16-19g, %0-3g"}, 129 {ARM_CEXT_XSCALE, 0x0e000060, 0x0f300ff0, "wcmpeq%22-23w%c\t%12-15g, %16-19g, %0-3g"}, 130 {ARM_CEXT_XSCALE, 0x0e100060, 0x0f100ff0, "wcmpgt%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"}, 131 {ARM_CEXT_XSCALE, 0xfc100100, 0xfe500f00, "wldrw\t%12-15G, %A"}, 132 {ARM_CEXT_XSCALE, 0x0c100000, 0x0e100e00, "wldr%L%c\t%12-15g, %l"}, 133 {ARM_CEXT_XSCALE, 0x0e400100, 0x0fc00ff0, "wmac%21?su%20'z%c\t%12-15g, %16-19g, %0-3g"}, 134 {ARM_CEXT_XSCALE, 0x0e800100, 0x0fd00ff0, "wmadd%21?su%c\t%12-15g, %16-19g, %0-3g"}, 135 {ARM_CEXT_XSCALE, 0x0e000160, 0x0f100ff0, "wmax%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"}, 136 {ARM_CEXT_XSCALE, 0x0e100160, 0x0f100ff0, "wmin%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"}, 137 {ARM_CEXT_XSCALE, 0x0e000100, 0x0fc00ff0, "wmul%21?su%20?ml%c\t%12-15g, %16-19g, %0-3g"}, 138 {ARM_CEXT_XSCALE, 0x0e000000, 0x0ff00ff0, "wor%c\t%12-15g, %16-19g, %0-3g"}, 139 {ARM_CEXT_XSCALE, 0x0e000080, 0x0f000ff0, "wpack%20-23w%c\t%12-15g, %16-19g, %0-3g"}, 140 {ARM_CEXT_XSCALE, 0x0e300040, 0x0f300ff0, "wror%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"}, 141 {ARM_CEXT_XSCALE, 0x0e300148, 0x0f300ffc, "wror%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"}, 142 {ARM_CEXT_XSCALE, 0x0e000120, 0x0fa00ff0, "wsad%22?hb%20'z%c\t%12-15g, %16-19g, %0-3g"}, 143 {ARM_CEXT_XSCALE, 0x0e0001e0, 0x0f000ff0, "wshufh%c\t%12-15g, %16-19g, #%Z"}, 144 {ARM_CEXT_XSCALE, 0x0e100040, 0x0f300ff0, "wsll%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"}, 145 {ARM_CEXT_XSCALE, 0x0e100148, 0x0f300ffc, "wsll%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"}, 146 {ARM_CEXT_XSCALE, 0x0e000040, 0x0f300ff0, "wsra%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"}, 147 {ARM_CEXT_XSCALE, 0x0e000148, 0x0f300ffc, "wsra%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"}, 148 {ARM_CEXT_XSCALE, 0x0e200040, 0x0f300ff0, "wsrl%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"}, 149 {ARM_CEXT_XSCALE, 0x0e200148, 0x0f300ffc, "wsrl%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"}, 150 {ARM_CEXT_XSCALE, 0xfc000100, 0xfe500f00, "wstrw\t%12-15G, %A"}, 151 {ARM_CEXT_XSCALE, 0x0c000000, 0x0e100e00, "wstr%L%c\t%12-15g, %l"}, 152 {ARM_CEXT_XSCALE, 0x0e0001a0, 0x0f000ff0, "wsub%20-23w%c\t%12-15g, %16-19g, %0-3g"}, 153 {ARM_CEXT_XSCALE, 0x0e0000c0, 0x0f100fff, "wunpckeh%21?su%22-23w%c\t%12-15g, %16-19g"}, 154 {ARM_CEXT_XSCALE, 0x0e0000e0, 0x0f100fff, "wunpckel%21?su%22-23w%c\t%12-15g, %16-19g"}, 155 {ARM_CEXT_XSCALE, 0x0e1000c0, 0x0f300ff0, "wunpckih%22-23w%c\t%12-15g, %16-19g, %0-3g"}, 156 {ARM_CEXT_XSCALE, 0x0e1000e0, 0x0f300ff0, "wunpckil%22-23w%c\t%12-15g, %16-19g, %0-3g"}, 157 {ARM_CEXT_XSCALE, 0x0e100000, 0x0ff00ff0, "wxor%c\t%12-15g, %16-19g, %0-3g"}, 158 159 /* Floating point coprocessor (FPA) instructions */ 160 {FPU_FPA_EXT_V1, 0x0e000100, 0x0ff08f10, "adf%c%P%R\t%12-14f, %16-18f, %0-3f"}, 161 {FPU_FPA_EXT_V1, 0x0e100100, 0x0ff08f10, "muf%c%P%R\t%12-14f, %16-18f, %0-3f"}, 162 {FPU_FPA_EXT_V1, 0x0e200100, 0x0ff08f10, "suf%c%P%R\t%12-14f, %16-18f, %0-3f"}, 163 {FPU_FPA_EXT_V1, 0x0e300100, 0x0ff08f10, "rsf%c%P%R\t%12-14f, %16-18f, %0-3f"}, 164 {FPU_FPA_EXT_V1, 0x0e400100, 0x0ff08f10, "dvf%c%P%R\t%12-14f, %16-18f, %0-3f"}, 165 {FPU_FPA_EXT_V1, 0x0e500100, 0x0ff08f10, "rdf%c%P%R\t%12-14f, %16-18f, %0-3f"}, 166 {FPU_FPA_EXT_V1, 0x0e600100, 0x0ff08f10, "pow%c%P%R\t%12-14f, %16-18f, %0-3f"}, 167 {FPU_FPA_EXT_V1, 0x0e700100, 0x0ff08f10, "rpw%c%P%R\t%12-14f, %16-18f, %0-3f"}, 168 {FPU_FPA_EXT_V1, 0x0e800100, 0x0ff08f10, "rmf%c%P%R\t%12-14f, %16-18f, %0-3f"}, 169 {FPU_FPA_EXT_V1, 0x0e900100, 0x0ff08f10, "fml%c%P%R\t%12-14f, %16-18f, %0-3f"}, 170 {FPU_FPA_EXT_V1, 0x0ea00100, 0x0ff08f10, "fdv%c%P%R\t%12-14f, %16-18f, %0-3f"}, 171 {FPU_FPA_EXT_V1, 0x0eb00100, 0x0ff08f10, "frd%c%P%R\t%12-14f, %16-18f, %0-3f"}, 172 {FPU_FPA_EXT_V1, 0x0ec00100, 0x0ff08f10, "pol%c%P%R\t%12-14f, %16-18f, %0-3f"}, 173 {FPU_FPA_EXT_V1, 0x0e008100, 0x0ff08f10, "mvf%c%P%R\t%12-14f, %0-3f"}, 174 {FPU_FPA_EXT_V1, 0x0e108100, 0x0ff08f10, "mnf%c%P%R\t%12-14f, %0-3f"}, 175 {FPU_FPA_EXT_V1, 0x0e208100, 0x0ff08f10, "abs%c%P%R\t%12-14f, %0-3f"}, 176 {FPU_FPA_EXT_V1, 0x0e308100, 0x0ff08f10, "rnd%c%P%R\t%12-14f, %0-3f"}, 177 {FPU_FPA_EXT_V1, 0x0e408100, 0x0ff08f10, "sqt%c%P%R\t%12-14f, %0-3f"}, 178 {FPU_FPA_EXT_V1, 0x0e508100, 0x0ff08f10, "log%c%P%R\t%12-14f, %0-3f"}, 179 {FPU_FPA_EXT_V1, 0x0e608100, 0x0ff08f10, "lgn%c%P%R\t%12-14f, %0-3f"}, 180 {FPU_FPA_EXT_V1, 0x0e708100, 0x0ff08f10, "exp%c%P%R\t%12-14f, %0-3f"}, 181 {FPU_FPA_EXT_V1, 0x0e808100, 0x0ff08f10, "sin%c%P%R\t%12-14f, %0-3f"}, 182 {FPU_FPA_EXT_V1, 0x0e908100, 0x0ff08f10, "cos%c%P%R\t%12-14f, %0-3f"}, 183 {FPU_FPA_EXT_V1, 0x0ea08100, 0x0ff08f10, "tan%c%P%R\t%12-14f, %0-3f"}, 184 {FPU_FPA_EXT_V1, 0x0eb08100, 0x0ff08f10, "asn%c%P%R\t%12-14f, %0-3f"}, 185 {FPU_FPA_EXT_V1, 0x0ec08100, 0x0ff08f10, "acs%c%P%R\t%12-14f, %0-3f"}, 186 {FPU_FPA_EXT_V1, 0x0ed08100, 0x0ff08f10, "atn%c%P%R\t%12-14f, %0-3f"}, 187 {FPU_FPA_EXT_V1, 0x0ee08100, 0x0ff08f10, "urd%c%P%R\t%12-14f, %0-3f"}, 188 {FPU_FPA_EXT_V1, 0x0ef08100, 0x0ff08f10, "nrm%c%P%R\t%12-14f, %0-3f"}, 189 {FPU_FPA_EXT_V1, 0x0e000110, 0x0ff00f1f, "flt%c%P%R\t%16-18f, %12-15r"}, 190 {FPU_FPA_EXT_V1, 0x0e100110, 0x0fff0f98, "fix%c%R\t%12-15r, %0-2f"}, 191 {FPU_FPA_EXT_V1, 0x0e200110, 0x0fff0fff, "wfs%c\t%12-15r"}, 192 {FPU_FPA_EXT_V1, 0x0e300110, 0x0fff0fff, "rfs%c\t%12-15r"}, 193 {FPU_FPA_EXT_V1, 0x0e400110, 0x0fff0fff, "wfc%c\t%12-15r"}, 194 {FPU_FPA_EXT_V1, 0x0e500110, 0x0fff0fff, "rfc%c\t%12-15r"}, 195 {FPU_FPA_EXT_V1, 0x0e90f110, 0x0ff8fff0, "cmf%c\t%16-18f, %0-3f"}, 196 {FPU_FPA_EXT_V1, 0x0eb0f110, 0x0ff8fff0, "cnf%c\t%16-18f, %0-3f"}, 197 {FPU_FPA_EXT_V1, 0x0ed0f110, 0x0ff8fff0, "cmfe%c\t%16-18f, %0-3f"}, 198 {FPU_FPA_EXT_V1, 0x0ef0f110, 0x0ff8fff0, "cnfe%c\t%16-18f, %0-3f"}, 199 {FPU_FPA_EXT_V1, 0x0c000100, 0x0e100f00, "stf%c%Q\t%12-14f, %A"}, 200 {FPU_FPA_EXT_V1, 0x0c100100, 0x0e100f00, "ldf%c%Q\t%12-14f, %A"}, 201 {FPU_FPA_EXT_V2, 0x0c000200, 0x0e100f00, "sfm%c\t%12-14f, %F, %A"}, 202 {FPU_FPA_EXT_V2, 0x0c100200, 0x0e100f00, "lfm%c\t%12-14f, %F, %A"}, 203 204 /* Floating point coprocessor (VFP) instructions */ 205 {FPU_VFP_EXT_V1, 0x0eb00bc0, 0x0fff0ff0, "fabsd%c\t%1z, %0z"}, 206 {FPU_VFP_EXT_V1xD, 0x0eb00ac0, 0x0fbf0fd0, "fabss%c\t%1y, %0y"}, 207 {FPU_VFP_EXT_V1, 0x0e300b00, 0x0ff00ff0, "faddd%c\t%1z, %2z, %0z"}, 208 {FPU_VFP_EXT_V1xD, 0x0e300a00, 0x0fb00f50, "fadds%c\t%1y, %2y, %0y"}, 209 {FPU_VFP_EXT_V1, 0x0eb40b40, 0x0fff0f70, "fcmp%7'ed%c\t%1z, %0z"}, 210 {FPU_VFP_EXT_V1xD, 0x0eb40a40, 0x0fbf0f50, "fcmp%7'es%c\t%1y, %0y"}, 211 {FPU_VFP_EXT_V1, 0x0eb50b40, 0x0fff0f70, "fcmp%7'ezd%c\t%1z"}, 212 {FPU_VFP_EXT_V1xD, 0x0eb50a40, 0x0fbf0f70, "fcmp%7'ezs%c\t%1y"}, 213 {FPU_VFP_EXT_V1, 0x0eb00b40, 0x0fff0ff0, "fcpyd%c\t%1z, %0z"}, 214 {FPU_VFP_EXT_V1xD, 0x0eb00a40, 0x0fbf0fd0, "fcpys%c\t%1y, %0y"}, 215 {FPU_VFP_EXT_V1, 0x0eb70ac0, 0x0fff0fd0, "fcvtds%c\t%1z, %0y"}, 216 {FPU_VFP_EXT_V1, 0x0eb70bc0, 0x0fbf0ff0, "fcvtsd%c\t%1y, %0z"}, 217 {FPU_VFP_EXT_V1, 0x0e800b00, 0x0ff00ff0, "fdivd%c\t%1z, %2z, %0z"}, 218 {FPU_VFP_EXT_V1xD, 0x0e800a00, 0x0fb00f50, "fdivs%c\t%1y, %2y, %0y"}, 219 {FPU_VFP_EXT_V1, 0x0d100b00, 0x0f700f00, "fldd%c\t%1z, %A"}, 220 {FPU_VFP_EXT_V1xD, 0x0c900b00, 0x0fd00f00, "fldmia%0?xd%c\t%16-19r%21'!, %3z"}, 221 {FPU_VFP_EXT_V1xD, 0x0d300b00, 0x0ff00f00, "fldmdb%0?xd%c\t%16-19r!, %3z"}, 222 {FPU_VFP_EXT_V1xD, 0x0d100a00, 0x0f300f00, "flds%c\t%1y, %A"}, 223 {FPU_VFP_EXT_V1xD, 0x0c900a00, 0x0f900f00, "fldmias%c\t%16-19r%21'!, %3y"}, 224 {FPU_VFP_EXT_V1xD, 0x0d300a00, 0x0fb00f00, "fldmdbs%c\t%16-19r!, %3y"}, 225 {FPU_VFP_EXT_V1, 0x0e000b00, 0x0ff00ff0, "fmacd%c\t%1z, %2z, %0z"}, 226 {FPU_VFP_EXT_V1xD, 0x0e000a00, 0x0fb00f50, "fmacs%c\t%1y, %2y, %0y"}, 227 {FPU_VFP_EXT_V1, 0x0e200b10, 0x0ff00fff, "fmdhr%c\t%2z, %12-15r"}, 228 {FPU_VFP_EXT_V1, 0x0e000b10, 0x0ff00fff, "fmdlr%c\t%2z, %12-15r"}, 229 {FPU_VFP_EXT_V2, 0x0c400b10, 0x0ff00ff0, "fmdrr%c\t%0z, %12-15r, %16-19r"}, 230 {FPU_VFP_EXT_V1, 0x0e300b10, 0x0ff00fff, "fmrdh%c\t%12-15r, %2z"}, 231 {FPU_VFP_EXT_V1, 0x0e100b10, 0x0ff00fff, "fmrdl%c\t%12-15r, %2z"}, 232 {FPU_VFP_EXT_V1, 0x0c500b10, 0x0ff00ff0, "fmrrd%c\t%12-15r, %16-19r, %0z"}, 233 {FPU_VFP_EXT_V2, 0x0c500a10, 0x0ff00fd0, "fmrrs%c\t%12-15r, %16-19r, %4y"}, 234 {FPU_VFP_EXT_V1xD, 0x0e100a10, 0x0ff00f7f, "fmrs%c\t%12-15r, %2y"}, 235 {FPU_VFP_EXT_V1xD, 0x0ef1fa10, 0x0fffffff, "fmstat%c"}, 236 {FPU_VFP_EXT_V1xD, 0x0ef00a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpsid"}, 237 {FPU_VFP_EXT_V1xD, 0x0ef10a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpscr"}, 238 {FPU_VFP_EXT_V1xD, 0x0ef80a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpexc"}, 239 {FPU_VFP_EXT_V1xD, 0x0ef90a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpinst\t@ Impl def"}, 240 {FPU_VFP_EXT_V1xD, 0x0efa0a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpinst2\t@ Impl def"}, 241 {FPU_VFP_EXT_V1xD, 0x0ef00a10, 0x0ff00fff, "fmrx%c\t%12-15r, <impl def 0x%16-19x>"}, 242 {FPU_VFP_EXT_V1, 0x0e100b00, 0x0ff00ff0, "fmscd%c\t%1z, %2z, %0z"}, 243 {FPU_VFP_EXT_V1xD, 0x0e100a00, 0x0fb00f50, "fmscs%c\t%1y, %2y, %0y"}, 244 {FPU_VFP_EXT_V1xD, 0x0e000a10, 0x0ff00f7f, "fmsr%c\t%2y, %12-15r"}, 245 {FPU_VFP_EXT_V2, 0x0c400a10, 0x0ff00fd0, "fmsrr%c\t%12-15r, %16-19r, %4y"}, 246 {FPU_VFP_EXT_V1, 0x0e200b00, 0x0ff00ff0, "fmuld%c\t%1z, %2z, %0z"}, 247 {FPU_VFP_EXT_V1xD, 0x0e200a00, 0x0fb00f50, "fmuls%c\t%1y, %2y, %0y"}, 248 {FPU_VFP_EXT_V1xD, 0x0ee00a10, 0x0fff0fff, "fmxr%c\tfpsid, %12-15r"}, 249 {FPU_VFP_EXT_V1xD, 0x0ee10a10, 0x0fff0fff, "fmxr%c\tfpscr, %12-15r"}, 250 {FPU_VFP_EXT_V1xD, 0x0ee80a10, 0x0fff0fff, "fmxr%c\tfpexc, %12-15r"}, 251 {FPU_VFP_EXT_V1xD, 0x0ee90a10, 0x0fff0fff, "fmxr%c\tfpinst, %12-15r\t@ Impl def"}, 252 {FPU_VFP_EXT_V1xD, 0x0eea0a10, 0x0fff0fff, "fmxr%c\tfpinst2, %12-15r\t@ Impl def"}, 253 {FPU_VFP_EXT_V1xD, 0x0ee00a10, 0x0ff00fff, "fmxr%c\t<impl def 0x%16-19x>, %12-15r"}, 254 {FPU_VFP_EXT_V1, 0x0eb10b40, 0x0fff0ff0, "fnegd%c\t%1z, %0z"}, 255 {FPU_VFP_EXT_V1xD, 0x0eb10a40, 0x0fbf0fd0, "fnegs%c\t%1y, %0y"}, 256 {FPU_VFP_EXT_V1, 0x0e000b40, 0x0ff00ff0, "fnmacd%c\t%1z, %2z, %0z"}, 257 {FPU_VFP_EXT_V1xD, 0x0e000a40, 0x0fb00f50, "fnmacs%c\t%1y, %2y, %0y"}, 258 {FPU_VFP_EXT_V1, 0x0e100b40, 0x0ff00ff0, "fnmscd%c\t%1z, %2z, %0z"}, 259 {FPU_VFP_EXT_V1xD, 0x0e100a40, 0x0fb00f50, "fnmscs%c\t%1y, %2y, %0y"}, 260 {FPU_VFP_EXT_V1, 0x0e200b40, 0x0ff00ff0, "fnmuld%c\t%1z, %2z, %0z"}, 261 {FPU_VFP_EXT_V1xD, 0x0e200a40, 0x0fb00f50, "fnmuls%c\t%1y, %2y, %0y"}, 262 {FPU_VFP_EXT_V1, 0x0eb80bc0, 0x0fff0fd0, "fsitod%c\t%1z, %0y"}, 263 {FPU_VFP_EXT_V1xD, 0x0eb80ac0, 0x0fbf0fd0, "fsitos%c\t%1y, %0y"}, 264 {FPU_VFP_EXT_V1, 0x0eb10bc0, 0x0fff0ff0, "fsqrtd%c\t%1z, %0z"}, 265 {FPU_VFP_EXT_V1xD, 0x0eb10ac0, 0x0fbf0fd0, "fsqrts%c\t%1y, %0y"}, 266 {FPU_VFP_EXT_V1, 0x0d000b00, 0x0f700f00, "fstd%c\t%1z, %A"}, 267 {FPU_VFP_EXT_V1xD, 0x0c800b00, 0x0fd00f00, "fstmia%0?xd%c\t%16-19r%21'!, %3z"}, 268 {FPU_VFP_EXT_V1xD, 0x0d200b00, 0x0ff00f00, "fstmdb%0?xd%c\t%16-19r!, %3z"}, 269 {FPU_VFP_EXT_V1xD, 0x0d000a00, 0x0f300f00, "fsts%c\t%1y, %A"}, 270 {FPU_VFP_EXT_V1xD, 0x0c800a00, 0x0f900f00, "fstmias%c\t%16-19r%21'!, %3y"}, 271 {FPU_VFP_EXT_V1xD, 0x0d200a00, 0x0fb00f00, "fstmdbs%c\t%16-19r!, %3y"}, 272 {FPU_VFP_EXT_V1, 0x0e300b40, 0x0ff00ff0, "fsubd%c\t%1z, %2z, %0z"}, 273 {FPU_VFP_EXT_V1xD, 0x0e300a40, 0x0fb00f50, "fsubs%c\t%1y, %2y, %0y"}, 274 {FPU_VFP_EXT_V1, 0x0ebc0b40, 0x0fbe0f70, "fto%16?sui%7'zd%c\t%1y, %0z"}, 275 {FPU_VFP_EXT_V1xD, 0x0ebc0a40, 0x0fbe0f50, "fto%16?sui%7'zs%c\t%1y, %0y"}, 276 {FPU_VFP_EXT_V1, 0x0eb80b40, 0x0fff0fd0, "fuitod%c\t%1z, %0y"}, 277 {FPU_VFP_EXT_V1xD, 0x0eb80a40, 0x0fbf0fd0, "fuitos%c\t%1y, %0y"}, 278 279 /* Cirrus coprocessor instructions. */ 280 {ARM_CEXT_MAVERICK, 0x0d100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"}, 281 {ARM_CEXT_MAVERICK, 0x0c100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"}, 282 {ARM_CEXT_MAVERICK, 0x0d500400, 0x0f500f00, "cfldrd%c\tmvd%12-15d, %A"}, 283 {ARM_CEXT_MAVERICK, 0x0c500400, 0x0f500f00, "cfldrd%c\tmvd%12-15d, %A"}, 284 {ARM_CEXT_MAVERICK, 0x0d100500, 0x0f500f00, "cfldr32%c\tmvfx%12-15d, %A"}, 285 {ARM_CEXT_MAVERICK, 0x0c100500, 0x0f500f00, "cfldr32%c\tmvfx%12-15d, %A"}, 286 {ARM_CEXT_MAVERICK, 0x0d500500, 0x0f500f00, "cfldr64%c\tmvdx%12-15d, %A"}, 287 {ARM_CEXT_MAVERICK, 0x0c500500, 0x0f500f00, "cfldr64%c\tmvdx%12-15d, %A"}, 288 {ARM_CEXT_MAVERICK, 0x0d000400, 0x0f500f00, "cfstrs%c\tmvf%12-15d, %A"}, 289 {ARM_CEXT_MAVERICK, 0x0c000400, 0x0f500f00, "cfstrs%c\tmvf%12-15d, %A"}, 290 {ARM_CEXT_MAVERICK, 0x0d400400, 0x0f500f00, "cfstrd%c\tmvd%12-15d, %A"}, 291 {ARM_CEXT_MAVERICK, 0x0c400400, 0x0f500f00, "cfstrd%c\tmvd%12-15d, %A"}, 292 {ARM_CEXT_MAVERICK, 0x0d000500, 0x0f500f00, "cfstr32%c\tmvfx%12-15d, %A"}, 293 {ARM_CEXT_MAVERICK, 0x0c000500, 0x0f500f00, "cfstr32%c\tmvfx%12-15d, %A"}, 294 {ARM_CEXT_MAVERICK, 0x0d400500, 0x0f500f00, "cfstr64%c\tmvdx%12-15d, %A"}, 295 {ARM_CEXT_MAVERICK, 0x0c400500, 0x0f500f00, "cfstr64%c\tmvdx%12-15d, %A"}, 296 {ARM_CEXT_MAVERICK, 0x0e000450, 0x0ff00ff0, "cfmvsr%c\tmvf%16-19d, %12-15r"}, 297 {ARM_CEXT_MAVERICK, 0x0e100450, 0x0ff00ff0, "cfmvrs%c\t%12-15r, mvf%16-19d"}, 298 {ARM_CEXT_MAVERICK, 0x0e000410, 0x0ff00ff0, "cfmvdlr%c\tmvd%16-19d, %12-15r"}, 299 {ARM_CEXT_MAVERICK, 0x0e100410, 0x0ff00ff0, "cfmvrdl%c\t%12-15r, mvd%16-19d"}, 300 {ARM_CEXT_MAVERICK, 0x0e000430, 0x0ff00ff0, "cfmvdhr%c\tmvd%16-19d, %12-15r"}, 301 {ARM_CEXT_MAVERICK, 0x0e100430, 0x0ff00fff, "cfmvrdh%c\t%12-15r, mvd%16-19d"}, 302 {ARM_CEXT_MAVERICK, 0x0e000510, 0x0ff00fff, "cfmv64lr%c\tmvdx%16-19d, %12-15r"}, 303 {ARM_CEXT_MAVERICK, 0x0e100510, 0x0ff00fff, "cfmvr64l%c\t%12-15r, mvdx%16-19d"}, 304 {ARM_CEXT_MAVERICK, 0x0e000530, 0x0ff00fff, "cfmv64hr%c\tmvdx%16-19d, %12-15r"}, 305 {ARM_CEXT_MAVERICK, 0x0e100530, 0x0ff00fff, "cfmvr64h%c\t%12-15r, mvdx%16-19d"}, 306 {ARM_CEXT_MAVERICK, 0x0e200440, 0x0ff00fff, "cfmval32%c\tmvax%12-15d, mvfx%16-19d"}, 307 {ARM_CEXT_MAVERICK, 0x0e100440, 0x0ff00fff, "cfmv32al%c\tmvfx%12-15d, mvax%16-19d"}, 308 {ARM_CEXT_MAVERICK, 0x0e200460, 0x0ff00fff, "cfmvam32%c\tmvax%12-15d, mvfx%16-19d"}, 309 {ARM_CEXT_MAVERICK, 0x0e100460, 0x0ff00fff, "cfmv32am%c\tmvfx%12-15d, mvax%16-19d"}, 310 {ARM_CEXT_MAVERICK, 0x0e200480, 0x0ff00fff, "cfmvah32%c\tmvax%12-15d, mvfx%16-19d"}, 311 {ARM_CEXT_MAVERICK, 0x0e100480, 0x0ff00fff, "cfmv32ah%c\tmvfx%12-15d, mvax%16-19d"}, 312 {ARM_CEXT_MAVERICK, 0x0e2004a0, 0x0ff00fff, "cfmva32%c\tmvax%12-15d, mvfx%16-19d"}, 313 {ARM_CEXT_MAVERICK, 0x0e1004a0, 0x0ff00fff, "cfmv32a%c\tmvfx%12-15d, mvax%16-19d"}, 314 {ARM_CEXT_MAVERICK, 0x0e2004c0, 0x0ff00fff, "cfmva64%c\tmvax%12-15d, mvdx%16-19d"}, 315 {ARM_CEXT_MAVERICK, 0x0e1004c0, 0x0ff00fff, "cfmv64a%c\tmvdx%12-15d, mvax%16-19d"}, 316 {ARM_CEXT_MAVERICK, 0x0e2004e0, 0x0fff0fff, "cfmvsc32%c\tdspsc, mvdx%12-15d"}, 317 {ARM_CEXT_MAVERICK, 0x0e1004e0, 0x0fff0fff, "cfmv32sc%c\tmvdx%12-15d, dspsc"}, 318 {ARM_CEXT_MAVERICK, 0x0e000400, 0x0ff00fff, "cfcpys%c\tmvf%12-15d, mvf%16-19d"}, 319 {ARM_CEXT_MAVERICK, 0x0e000420, 0x0ff00fff, "cfcpyd%c\tmvd%12-15d, mvd%16-19d"}, 320 {ARM_CEXT_MAVERICK, 0x0e000460, 0x0ff00fff, "cfcvtsd%c\tmvd%12-15d, mvf%16-19d"}, 321 {ARM_CEXT_MAVERICK, 0x0e000440, 0x0ff00fff, "cfcvtds%c\tmvf%12-15d, mvd%16-19d"}, 322 {ARM_CEXT_MAVERICK, 0x0e000480, 0x0ff00fff, "cfcvt32s%c\tmvf%12-15d, mvfx%16-19d"}, 323 {ARM_CEXT_MAVERICK, 0x0e0004a0, 0x0ff00fff, "cfcvt32d%c\tmvd%12-15d, mvfx%16-19d"}, 324 {ARM_CEXT_MAVERICK, 0x0e0004c0, 0x0ff00fff, "cfcvt64s%c\tmvf%12-15d, mvdx%16-19d"}, 325 {ARM_CEXT_MAVERICK, 0x0e0004e0, 0x0ff00fff, "cfcvt64d%c\tmvd%12-15d, mvdx%16-19d"}, 326 {ARM_CEXT_MAVERICK, 0x0e100580, 0x0ff00fff, "cfcvts32%c\tmvfx%12-15d, mvf%16-19d"}, 327 {ARM_CEXT_MAVERICK, 0x0e1005a0, 0x0ff00fff, "cfcvtd32%c\tmvfx%12-15d, mvd%16-19d"}, 328 {ARM_CEXT_MAVERICK, 0x0e1005c0, 0x0ff00fff, "cftruncs32%c\tmvfx%12-15d, mvf%16-19d"}, 329 {ARM_CEXT_MAVERICK, 0x0e1005e0, 0x0ff00fff, "cftruncd32%c\tmvfx%12-15d, mvd%16-19d"}, 330 {ARM_CEXT_MAVERICK, 0x0e000550, 0x0ff00ff0, "cfrshl32%c\tmvfx%16-19d, mvfx%0-3d, %12-15r"}, 331 {ARM_CEXT_MAVERICK, 0x0e000570, 0x0ff00ff0, "cfrshl64%c\tmvdx%16-19d, mvdx%0-3d, %12-15r"}, 332 {ARM_CEXT_MAVERICK, 0x0e000500, 0x0ff00f10, "cfsh32%c\tmvfx%12-15d, mvfx%16-19d, #%I"}, 333 {ARM_CEXT_MAVERICK, 0x0e200500, 0x0ff00f10, "cfsh64%c\tmvdx%12-15d, mvdx%16-19d, #%I"}, 334 {ARM_CEXT_MAVERICK, 0x0e100490, 0x0ff00ff0, "cfcmps%c\t%12-15r, mvf%16-19d, mvf%0-3d"}, 335 {ARM_CEXT_MAVERICK, 0x0e1004b0, 0x0ff00ff0, "cfcmpd%c\t%12-15r, mvd%16-19d, mvd%0-3d"}, 336 {ARM_CEXT_MAVERICK, 0x0e100590, 0x0ff00ff0, "cfcmp32%c\t%12-15r, mvfx%16-19d, mvfx%0-3d"}, 337 {ARM_CEXT_MAVERICK, 0x0e1005b0, 0x0ff00ff0, "cfcmp64%c\t%12-15r, mvdx%16-19d, mvdx%0-3d"}, 338 {ARM_CEXT_MAVERICK, 0x0e300400, 0x0ff00fff, "cfabss%c\tmvf%12-15d, mvf%16-19d"}, 339 {ARM_CEXT_MAVERICK, 0x0e300420, 0x0ff00fff, "cfabsd%c\tmvd%12-15d, mvd%16-19d"}, 340 {ARM_CEXT_MAVERICK, 0x0e300440, 0x0ff00fff, "cfnegs%c\tmvf%12-15d, mvf%16-19d"}, 341 {ARM_CEXT_MAVERICK, 0x0e300460, 0x0ff00fff, "cfnegd%c\tmvd%12-15d, mvd%16-19d"}, 342 {ARM_CEXT_MAVERICK, 0x0e300480, 0x0ff00ff0, "cfadds%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"}, 343 {ARM_CEXT_MAVERICK, 0x0e3004a0, 0x0ff00ff0, "cfaddd%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"}, 344 {ARM_CEXT_MAVERICK, 0x0e3004c0, 0x0ff00ff0, "cfsubs%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"}, 345 {ARM_CEXT_MAVERICK, 0x0e3004e0, 0x0ff00ff0, "cfsubd%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"}, 346 {ARM_CEXT_MAVERICK, 0x0e100400, 0x0ff00ff0, "cfmuls%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"}, 347 {ARM_CEXT_MAVERICK, 0x0e100420, 0x0ff00ff0, "cfmuld%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"}, 348 {ARM_CEXT_MAVERICK, 0x0e300500, 0x0ff00fff, "cfabs32%c\tmvfx%12-15d, mvfx%16-19d"}, 349 {ARM_CEXT_MAVERICK, 0x0e300520, 0x0ff00fff, "cfabs64%c\tmvdx%12-15d, mvdx%16-19d"}, 350 {ARM_CEXT_MAVERICK, 0x0e300540, 0x0ff00fff, "cfneg32%c\tmvfx%12-15d, mvfx%16-19d"}, 351 {ARM_CEXT_MAVERICK, 0x0e300560, 0x0ff00fff, "cfneg64%c\tmvdx%12-15d, mvdx%16-19d"}, 352 {ARM_CEXT_MAVERICK, 0x0e300580, 0x0ff00ff0, "cfadd32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"}, 353 {ARM_CEXT_MAVERICK, 0x0e3005a0, 0x0ff00ff0, "cfadd64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"}, 354 {ARM_CEXT_MAVERICK, 0x0e3005c0, 0x0ff00ff0, "cfsub32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"}, 355 {ARM_CEXT_MAVERICK, 0x0e3005e0, 0x0ff00ff0, "cfsub64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"}, 356 {ARM_CEXT_MAVERICK, 0x0e100500, 0x0ff00ff0, "cfmul32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"}, 357 {ARM_CEXT_MAVERICK, 0x0e100520, 0x0ff00ff0, "cfmul64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"}, 358 {ARM_CEXT_MAVERICK, 0x0e100540, 0x0ff00ff0, "cfmac32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"}, 359 {ARM_CEXT_MAVERICK, 0x0e100560, 0x0ff00ff0, "cfmsc32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"}, 360 {ARM_CEXT_MAVERICK, 0x0e000600, 0x0ff00f10, "cfmadd32%c\tmvax%5-7d, mvfx%12-15d, mvfx%16-19d, mvfx%0-3d"}, 361 {ARM_CEXT_MAVERICK, 0x0e100600, 0x0ff00f10, "cfmsub32%c\tmvax%5-7d, mvfx%12-15d, mvfx%16-19d, mvfx%0-3d"}, 362 {ARM_CEXT_MAVERICK, 0x0e200600, 0x0ff00f10, "cfmadda32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"}, 363 {ARM_CEXT_MAVERICK, 0x0e300600, 0x0ff00f10, "cfmsuba32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"}, 364 365 /* Generic coprocessor instructions */ 366 {ARM_EXT_V2, 0x0c400000, 0x0ff00000, "mcrr%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"}, 367 {ARM_EXT_V2, 0x0c500000, 0x0ff00000, "mrrc%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"}, 368 {ARM_EXT_V2, 0x0e000000, 0x0f000010, "cdp%c\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"}, 369 {ARM_EXT_V2, 0x0e100010, 0x0f100010, "mrc%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"}, 370 {ARM_EXT_V2, 0x0e000010, 0x0f100010, "mcr%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"}, 371 {ARM_EXT_V2, 0x0c000000, 0x0e100000, "stc%c%22'l\t%8-11d, cr%12-15d, %A"}, 372 {ARM_EXT_V2, 0x0c100000, 0x0e100000, "ldc%c%22'l\t%8-11d, cr%12-15d, %A"}, 373 374 /* V6 coprocessor instructions */ 375 {ARM_EXT_V6, 0xfc500000, 0xfff00000, "mrrc2\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"}, 376 {ARM_EXT_V6, 0xfc400000, 0xfff00000, "mcrr2\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"}, 377 378 /* V5 coprocessor instructions */ 379 {ARM_EXT_V5, 0xfc100000, 0xfe100000, "ldc2%22'l\t%8-11d, cr%12-15d, %A"}, 380 {ARM_EXT_V5, 0xfc000000, 0xfe100000, "stc2%22'l\t%8-11d, cr%12-15d, %A"}, 381 {ARM_EXT_V5, 0xfe000000, 0xff000010, "cdp2\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"}, 382 {ARM_EXT_V5, 0xfe000010, 0xff100010, "mcr2\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"}, 383 {ARM_EXT_V5, 0xfe100010, 0xff100010, "mrc2\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"}, 384 {0, 0, 0, 0} 385 }; 386 387 /* Opcode tables: ARM, 16-bit Thumb, 32-bit Thumb. All three are partially 388 ordered: they must be searched linearly from the top to obtain a correct 389 match. */ 390 391 /* print_insn_arm recognizes the following format control codes: 392 393 %% % 394 395 %a print address for ldr/str instruction 396 %s print address for ldr/str halfword/signextend instruction 397 %b print branch destination 398 %c print condition code (always bits 28-31) 399 %m print register mask for ldm/stm instruction 400 %o print operand2 (immediate or register + shift) 401 %p print 'p' iff bits 12-15 are 15 402 %t print 't' iff bit 21 set and bit 24 clear 403 %B print arm BLX(1) destination 404 %C print the PSR sub type. 405 %U print barrier type. 406 %P print address for pli instruction. 407 408 %<bitfield>r print as an ARM register 409 %<bitfield>d print the bitfield in decimal 410 %<bitfield>W print the bitfield plus one in decimal 411 %<bitfield>x print the bitfield in hex 412 %<bitfield>X print the bitfield as 1 hex digit without leading "0x" 413 414 %<bitnum>'c print specified char iff bit is one 415 %<bitnum>`c print specified char iff bit is zero 416 %<bitnum>?ab print a if bit is one else print b 417 418 %e print arm SMI operand (bits 0..7,8..19). 419 %E print the LSB and WIDTH fields of a BFI or BFC instruction. 420 %V print the 16-bit immediate field of a MOVT or MOVW instruction. */ 421 422 static const struct opcode32 arm_opcodes[] = 423 { 424 /* ARM instructions. */ 425 {ARM_EXT_V1, 0xe1a00000, 0xffffffff, "nop\t\t\t(mov r0,r0)"}, 426 {ARM_EXT_V4T | ARM_EXT_V5, 0x012FFF10, 0x0ffffff0, "bx%c\t%0-3r"}, 427 {ARM_EXT_V2, 0x00000090, 0x0fe000f0, "mul%c%20's\t%16-19r, %0-3r, %8-11r"}, 428 {ARM_EXT_V2, 0x00200090, 0x0fe000f0, "mla%c%20's\t%16-19r, %0-3r, %8-11r, %12-15r"}, 429 {ARM_EXT_V2S, 0x01000090, 0x0fb00ff0, "swp%c%22'b\t%12-15r, %0-3r, [%16-19r]"}, 430 {ARM_EXT_V3M, 0x00800090, 0x0fa000f0, "%22?sumull%c%20's\t%12-15r, %16-19r, %0-3r, %8-11r"}, 431 {ARM_EXT_V3M, 0x00a00090, 0x0fa000f0, "%22?sumlal%c%20's\t%12-15r, %16-19r, %0-3r, %8-11r"}, 432 433 /* V7 instructions. */ 434 {ARM_EXT_V7, 0xf450f000, 0xfd70f000, "pli\t%P"}, 435 {ARM_EXT_V7, 0x0320f0f0, 0x0ffffff0, "dbg%c\t#%0-3d"}, 436 {ARM_EXT_V7, 0xf57ff050, 0xfffffff0, "dmb\t%U"}, 437 {ARM_EXT_V7, 0xf57ff040, 0xfffffff0, "dsb\t%U"}, 438 {ARM_EXT_V7, 0xf57ff060, 0xfffffff0, "isb\t%U"}, 439 440 /* ARM V6T2 instructions. */ 441 {ARM_EXT_V6T2, 0x07c0001f, 0x0fe0007f, "bfc%c\t%12-15r, %E"}, 442 {ARM_EXT_V6T2, 0x07c00010, 0x0fe00070, "bfi%c\t%12-15r, %0-3r, %E"}, 443 {ARM_EXT_V6T2, 0x00600090, 0x0ff000f0, "mls%c\t%16-19r, %0-3r, %8-11r, %12-15r"}, 444 {ARM_EXT_V6T2, 0x006000b0, 0x0f7000f0, "str%cht\t%12-15r, %s"}, 445 {ARM_EXT_V6T2, 0x00300090, 0x0f300090, "ldr%c%6's%5?hbt\t%12-15r, %s"}, 446 {ARM_EXT_V6T2, 0x03000000, 0x0ff00000, "movw%c\t%12-15r, %V"}, 447 {ARM_EXT_V6T2, 0x03400000, 0x0ff00000, "movt%c\t%12-15r, %V"}, 448 {ARM_EXT_V6T2, 0x03ff0f30, 0x0fff0ff0, "rbit%c\t%12-15r, %0-3r"}, 449 {ARM_EXT_V6T2, 0x07a00050, 0x0fa00070, "%22?usbfx%c\t%12-15r, %0-3r, #%7-11d, #%16-20W"}, 450 451 /* ARM V6Z instructions. */ 452 {ARM_EXT_V6Z, 0x01600070, 0x0ff000f0, "smc%c\t%e"}, 453 454 /* ARM V6K instructions. */ 455 {ARM_EXT_V6K, 0xf57ff01f, 0xffffffff, "clrex"}, 456 {ARM_EXT_V6K, 0x01d00f9f, 0x0ff00fff, "ldrexb%c\t%12-15r, [%16-19r]"}, 457 {ARM_EXT_V6K, 0x01b00f9f, 0x0ff00fff, "ldrexd%c\t%12-15r, [%16-19r]"}, 458 {ARM_EXT_V6K, 0x01f00f9f, 0x0ff00fff, "ldrexh%c\t%12-15r, [%16-19r]"}, 459 {ARM_EXT_V6K, 0x01c00f90, 0x0ff00ff0, "strexb%c\t%12-15r, %0-3r, [%16-19r]"}, 460 {ARM_EXT_V6K, 0x01a00f90, 0x0ff00ff0, "strexd%c\t%12-15r, %0-3r, [%16-19r]"}, 461 {ARM_EXT_V6K, 0x01e00f90, 0x0ff00ff0, "strexh%c\t%12-15r, %0-3r, [%16-19r]"}, 462 463 /* ARM V6K NOP hints. */ 464 {ARM_EXT_V6K, 0x0320f001, 0x0fffffff, "yield%c"}, 465 {ARM_EXT_V6K, 0x0320f002, 0x0fffffff, "wfe%c"}, 466 {ARM_EXT_V6K, 0x0320f003, 0x0fffffff, "wfi%c"}, 467 {ARM_EXT_V6K, 0x0320f004, 0x0fffffff, "sev%c"}, 468 {ARM_EXT_V6K, 0x0320f000, 0x0fffff00, "nop%c\t{%0-7d}"}, 469 470 /* ARM V6 instructions. */ 471 {ARM_EXT_V6, 0xf1080000, 0xfffdfe3f, "cpsie\t%8'a%7'i%6'f"}, 472 {ARM_EXT_V6, 0xf1080000, 0xfffdfe20, "cpsie\t%8'a%7'i%6'f,#%0-4d"}, 473 {ARM_EXT_V6, 0xf10C0000, 0xfffdfe3f, "cpsid\t%8'a%7'i%6'f"}, 474 {ARM_EXT_V6, 0xf10C0000, 0xfffdfe20, "cpsid\t%8'a%7'i%6'f,#%0-4d"}, 475 {ARM_EXT_V6, 0xf1000000, 0xfff1fe20, "cps\t#%0-4d"}, 476 {ARM_EXT_V6, 0x06800010, 0x0ff00ff0, "pkhbt%c\t%12-15r, %16-19r, %0-3r"}, 477 {ARM_EXT_V6, 0x06800010, 0x0ff00070, "pkhbt%c\t%12-15r, %16-19r, %0-3r, LSL #%7-11d"}, 478 {ARM_EXT_V6, 0x06800050, 0x0ff00ff0, "pkhtb%c\t%12-15r, %16-19r, %0-3r, ASR #32"}, 479 {ARM_EXT_V6, 0x06800050, 0x0ff00070, "pkhtb%c\t%12-15r, %16-19r, %0-3r, ASR #%7-11d"}, 480 {ARM_EXT_V6, 0x01900f9f, 0x0ff00fff, "ldrex%c\tr%12-15d, [%16-19r]"}, 481 {ARM_EXT_V6, 0x06200f10, 0x0ff00ff0, "qadd16%c\t%12-15r, %16-19r, %0-3r"}, 482 {ARM_EXT_V6, 0x06200f90, 0x0ff00ff0, "qadd8%c\t%12-15r, %16-19r, %0-3r"}, 483 {ARM_EXT_V6, 0x06200f30, 0x0ff00ff0, "qaddsubx%c\t%12-15r, %16-19r, %0-3r"}, 484 {ARM_EXT_V6, 0x06200f70, 0x0ff00ff0, "qsub16%c\t%12-15r, %16-19r, %0-3r"}, 485 {ARM_EXT_V6, 0x06200ff0, 0x0ff00ff0, "qsub8%c\t%12-15r, %16-19r, %0-3r"}, 486 {ARM_EXT_V6, 0x06200f50, 0x0ff00ff0, "qsubaddx%c\t%12-15r, %16-19r, %0-3r"}, 487 {ARM_EXT_V6, 0x06100f10, 0x0ff00ff0, "sadd16%c\t%12-15r, %16-19r, %0-3r"}, 488 {ARM_EXT_V6, 0x06100f90, 0x0ff00ff0, "sadd8%c\t%12-15r, %16-19r, %0-3r"}, 489 {ARM_EXT_V6, 0x06100f30, 0x0ff00ff0, "saddaddx%c\t%12-15r, %16-19r, %0-3r"}, 490 {ARM_EXT_V6, 0x06300f10, 0x0ff00ff0, "shadd16%c\t%12-15r, %16-19r, %0-3r"}, 491 {ARM_EXT_V6, 0x06300f90, 0x0ff00ff0, "shadd8%c\t%12-15r, %16-19r, %0-3r"}, 492 {ARM_EXT_V6, 0x06300f30, 0x0ff00ff0, "shaddsubx%c\t%12-15r, %16-19r, %0-3r"}, 493 {ARM_EXT_V6, 0x06300f70, 0x0ff00ff0, "shsub16%c\t%12-15r, %16-19r, %0-3r"}, 494 {ARM_EXT_V6, 0x06300ff0, 0x0ff00ff0, "shsub8%c\t%12-15r, %16-19r, %0-3r"}, 495 {ARM_EXT_V6, 0x06300f50, 0x0ff00ff0, "shsubaddx%c\t%12-15r, %16-19r, %0-3r"}, 496 {ARM_EXT_V6, 0x06100f70, 0x0ff00ff0, "ssub16%c\t%12-15r, %16-19r, %0-3r"}, 497 {ARM_EXT_V6, 0x06100ff0, 0x0ff00ff0, "ssub8%c\t%12-15r, %16-19r, %0-3r"}, 498 {ARM_EXT_V6, 0x06100f50, 0x0ff00ff0, "ssubaddx%c\t%12-15r, %16-19r, %0-3r"}, 499 {ARM_EXT_V6, 0x06500f10, 0x0ff00ff0, "uadd16%c\t%12-15r, %16-19r, %0-3r"}, 500 {ARM_EXT_V6, 0x06500f90, 0x0ff00ff0, "uadd8%c\t%12-15r, %16-19r, %0-3r"}, 501 {ARM_EXT_V6, 0x06500f30, 0x0ff00ff0, "uaddsubx%c\t%12-15r, %16-19r, %0-3r"}, 502 {ARM_EXT_V6, 0x06700f10, 0x0ff00ff0, "uhadd16%c\t%12-15r, %16-19r, %0-3r"}, 503 {ARM_EXT_V6, 0x06700f90, 0x0ff00ff0, "uhadd8%c\t%12-15r, %16-19r, %0-3r"}, 504 {ARM_EXT_V6, 0x06700f30, 0x0ff00ff0, "uhaddsubx%c\t%12-15r, %16-19r, %0-3r"}, 505 {ARM_EXT_V6, 0x06700f70, 0x0ff00ff0, "uhsub16%c\t%12-15r, %16-19r, %0-3r"}, 506 {ARM_EXT_V6, 0x06700ff0, 0x0ff00ff0, "uhsub8%c\t%12-15r, %16-19r, %0-3r"}, 507 {ARM_EXT_V6, 0x06700f50, 0x0ff00ff0, "uhsubaddx%c\t%12-15r, %16-19r, %0-3r"}, 508 {ARM_EXT_V6, 0x06600f10, 0x0ff00ff0, "uqadd16%c\t%12-15r, %16-19r, %0-3r"}, 509 {ARM_EXT_V6, 0x06600f90, 0x0ff00ff0, "uqadd8%c\t%12-15r, %16-19r, %0-3r"}, 510 {ARM_EXT_V6, 0x06600f30, 0x0ff00ff0, "uqaddsubx%c\t%12-15r, %16-19r, %0-3r"}, 511 {ARM_EXT_V6, 0x06600f70, 0x0ff00ff0, "uqsub16%c\t%12-15r, %16-19r, %0-3r"}, 512 {ARM_EXT_V6, 0x06600ff0, 0x0ff00ff0, "uqsub8%c\t%12-15r, %16-19r, %0-3r"}, 513 {ARM_EXT_V6, 0x06600f50, 0x0ff00ff0, "uqsubaddx%c\t%12-15r, %16-19r, %0-3r"}, 514 {ARM_EXT_V6, 0x06500f70, 0x0ff00ff0, "usub16%c\t%12-15r, %16-19r, %0-3r"}, 515 {ARM_EXT_V6, 0x06500ff0, 0x0ff00ff0, "usub8%c\t%12-15r, %16-19r, %0-3r"}, 516 {ARM_EXT_V6, 0x06500f50, 0x0ff00ff0, "usubaddx%c\t%12-15r, %16-19r, %0-3r"}, 517 {ARM_EXT_V6, 0x06bf0f30, 0x0fff0ff0, "rev%c\t\%12-15r, %0-3r"}, 518 {ARM_EXT_V6, 0x06bf0fb0, 0x0fff0ff0, "rev16%c\t\%12-15r, %0-3r"}, 519 {ARM_EXT_V6, 0x06ff0fb0, 0x0fff0ff0, "revsh%c\t\%12-15r, %0-3r"}, 520 {ARM_EXT_V6, 0xf8100a00, 0xfe50ffff, "rfe%23?id%24?ba\t\%16-19r%21'!"}, 521 {ARM_EXT_V6, 0x06bf0070, 0x0fff0ff0, "sxth%c %12-15r,%0-3r"}, 522 {ARM_EXT_V6, 0x06bf0470, 0x0fff0ff0, "sxth%c %12-15r,%0-3r, ROR #8"}, 523 {ARM_EXT_V6, 0x06bf0870, 0x0fff0ff0, "sxth%c %12-15r,%0-3r, ROR #16"}, 524 {ARM_EXT_V6, 0x06bf0c70, 0x0fff0ff0, "sxth%c %12-15r,%0-3r, ROR #24"}, 525 {ARM_EXT_V6, 0x068f0070, 0x0fff0ff0, "sxtb16%c %12-15r,%0-3r"}, 526 {ARM_EXT_V6, 0x068f0470, 0x0fff0ff0, "sxtb16%c %12-15r,%0-3r, ROR #8"}, 527 {ARM_EXT_V6, 0x068f0870, 0x0fff0ff0, "sxtb16%c %12-15r,%0-3r, ROR #16"}, 528 {ARM_EXT_V6, 0x068f0c70, 0x0fff0ff0, "sxtb16%c %12-15r,%0-3r, ROR #24"}, 529 {ARM_EXT_V6, 0x06af0070, 0x0fff0ff0, "sxtb%c %12-15r,%0-3r"}, 530 {ARM_EXT_V6, 0x06af0470, 0x0fff0ff0, "sxtb%c %12-15r,%0-3r, ROR #8"}, 531 {ARM_EXT_V6, 0x06af0870, 0x0fff0ff0, "sxtb%c %12-15r,%0-3r, ROR #16"}, 532 {ARM_EXT_V6, 0x06af0c70, 0x0fff0ff0, "sxtb%c %12-15r,%0-3r, ROR #24"}, 533 {ARM_EXT_V6, 0x06ff0070, 0x0fff0ff0, "uxth%c %12-15r,%0-3r"}, 534 {ARM_EXT_V6, 0x06ff0470, 0x0fff0ff0, "uxth%c %12-15r,%0-3r, ROR #8"}, 535 {ARM_EXT_V6, 0x06ff0870, 0x0fff0ff0, "uxth%c %12-15r,%0-3r, ROR #16"}, 536 {ARM_EXT_V6, 0x06ff0c70, 0x0fff0ff0, "uxth%c %12-15r,%0-3r, ROR #24"}, 537 {ARM_EXT_V6, 0x06cf0070, 0x0fff0ff0, "uxtb16%c %12-15r,%0-3r"}, 538 {ARM_EXT_V6, 0x06cf0470, 0x0fff0ff0, "uxtb16%c %12-15r,%0-3r, ROR #8"}, 539 {ARM_EXT_V6, 0x06cf0870, 0x0fff0ff0, "uxtb16%c %12-15r,%0-3r, ROR #16"}, 540 {ARM_EXT_V6, 0x06cf0c70, 0x0fff0ff0, "uxtb16%c %12-15r,%0-3r, ROR #24"}, 541 {ARM_EXT_V6, 0x06ef0070, 0x0fff0ff0, "uxtb%c %12-15r,%0-3r"}, 542 {ARM_EXT_V6, 0x06ef0470, 0x0fff0ff0, "uxtb%c %12-15r,%0-3r, ROR #8"}, 543 {ARM_EXT_V6, 0x06ef0870, 0x0fff0ff0, "uxtb%c %12-15r,%0-3r, ROR #16"}, 544 {ARM_EXT_V6, 0x06ef0c70, 0x0fff0ff0, "uxtb%c %12-15r,%0-3r, ROR #24"}, 545 {ARM_EXT_V6, 0x06b00070, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r"}, 546 {ARM_EXT_V6, 0x06b00470, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ROR #8"}, 547 {ARM_EXT_V6, 0x06b00870, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ROR #16"}, 548 {ARM_EXT_V6, 0x06b00c70, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ROR #24"}, 549 {ARM_EXT_V6, 0x06800070, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r"}, 550 {ARM_EXT_V6, 0x06800470, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #8"}, 551 {ARM_EXT_V6, 0x06800870, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #16"}, 552 {ARM_EXT_V6, 0x06800c70, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #24"}, 553 {ARM_EXT_V6, 0x06a00070, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r"}, 554 {ARM_EXT_V6, 0x06a00470, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ROR #8"}, 555 {ARM_EXT_V6, 0x06a00870, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ROR #16"}, 556 {ARM_EXT_V6, 0x06a00c70, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ROR #24"}, 557 {ARM_EXT_V6, 0x06f00070, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r"}, 558 {ARM_EXT_V6, 0x06f00470, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ROR #8"}, 559 {ARM_EXT_V6, 0x06f00870, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ROR #16"}, 560 {ARM_EXT_V6, 0x06f00c70, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ROR #24"}, 561 {ARM_EXT_V6, 0x06c00070, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r"}, 562 {ARM_EXT_V6, 0x06c00470, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #8"}, 563 {ARM_EXT_V6, 0x06c00870, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #16"}, 564 {ARM_EXT_V6, 0x06c00c70, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #24"}, 565 {ARM_EXT_V6, 0x06e00070, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r"}, 566 {ARM_EXT_V6, 0x06e00470, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ROR #8"}, 567 {ARM_EXT_V6, 0x06e00870, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ROR #16"}, 568 {ARM_EXT_V6, 0x06e00c70, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ROR #24"}, 569 {ARM_EXT_V6, 0x06800fb0, 0x0ff00ff0, "sel%c\t%12-15r, %16-19r, %0-3r"}, 570 {ARM_EXT_V6, 0xf1010000, 0xfffffc00, "setend\t%9?ble"}, 571 {ARM_EXT_V6, 0x0700f010, 0x0ff0f0d0, "smuad%5'x%c\t%16-19r, %0-3r, %8-11r"}, 572 {ARM_EXT_V6, 0x0700f050, 0x0ff0f0d0, "smusd%5'x%c\t%16-19r, %0-3r, %8-11r"}, 573 {ARM_EXT_V6, 0x07000010, 0x0ff000d0, "smlad%5'x%c\t%16-19r, %0-3r, %8-11r, %12-15r"}, 574 {ARM_EXT_V6, 0x07400010, 0x0ff000d0, "smlald%5'x%c\t%12-15r, %16-19r, %0-3r, %8-11r"}, 575 {ARM_EXT_V6, 0x07000050, 0x0ff000d0, "smlsd%5'x%c\t%16-19r, %0-3r, %8-11r, %12-15r"}, 576 {ARM_EXT_V6, 0x07400050, 0x0ff000d0, "smlsld%5'x%c\t%12-15r, %16-19r, %0-3r, %8-11r"}, 577 {ARM_EXT_V6, 0x0750f010, 0x0ff0f0d0, "smmul%5'r%c\t%16-19r, %0-3r, %8-11r"}, 578 {ARM_EXT_V6, 0x07500010, 0x0ff000d0, "smmla%5'r%c\t%16-19r, %0-3r, %8-11r, %12-15r"}, 579 {ARM_EXT_V6, 0x075000d0, 0x0ff000d0, "smmls%5'r%c\t%16-19r, %0-3r, %8-11r, %12-15r"}, 580 {ARM_EXT_V6, 0xf84d0500, 0xfe5fffe0, "srs%23?id%24?ba\t#%0-4d%21'!"}, 581 {ARM_EXT_V6, 0x06a00010, 0x0fe00ff0, "ssat%c\t%12-15r, #%16-20W, %0-3r"}, 582 {ARM_EXT_V6, 0x06a00010, 0x0fe00070, "ssat%c\t%12-15r, #%16-20W, %0-3r, LSL #%7-11d"}, 583 {ARM_EXT_V6, 0x06a00050, 0x0fe00070, "ssat%c\t%12-15r, #%16-20W, %0-3r, ASR #%7-11d"}, 584 {ARM_EXT_V6, 0x06a00f30, 0x0ff00ff0, "ssat16%c\t%12-15r, #%16-19W, %0-3r"}, 585 {ARM_EXT_V6, 0x01800f90, 0x0ff00ff0, "strex%c\t%12-15r, %0-3r, [%16-19r]"}, 586 {ARM_EXT_V6, 0x00400090, 0x0ff000f0, "umaal%c\t%12-15r, %16-19r, %0-3r, %8-11r"}, 587 {ARM_EXT_V6, 0x0780f010, 0x0ff0f0f0, "usad8%c\t%16-19r, %0-3r, %8-11r"}, 588 {ARM_EXT_V6, 0x07800010, 0x0ff000f0, "usada8%c\t%16-19r, %0-3r, %8-11r, %12-15r"}, 589 {ARM_EXT_V6, 0x06e00010, 0x0fe00ff0, "usat%c\t%12-15r, #%16-20d, %0-3r"}, 590 {ARM_EXT_V6, 0x06e00010, 0x0fe00070, "usat%c\t%12-15r, #%16-20d, %0-3r, LSL #%7-11d"}, 591 {ARM_EXT_V6, 0x06e00050, 0x0fe00070, "usat%c\t%12-15r, #%16-20d, %0-3r, ASR #%7-11d"}, 592 {ARM_EXT_V6, 0x06e00f30, 0x0ff00ff0, "usat16%c\t%12-15r, #%16-19d, %0-3r"}, 593 594 /* V5J instruction. */ 595 {ARM_EXT_V5J, 0x012fff20, 0x0ffffff0, "bxj%c\t%0-3r"}, 596 597 /* V5 Instructions. */ 598 {ARM_EXT_V5, 0xe1200070, 0xfff000f0, "bkpt\t0x%16-19X%12-15X%8-11X%0-3X"}, 599 {ARM_EXT_V5, 0xfa000000, 0xfe000000, "blx\t%B"}, 600 {ARM_EXT_V5, 0x012fff30, 0x0ffffff0, "blx%c\t%0-3r"}, 601 {ARM_EXT_V5, 0x016f0f10, 0x0fff0ff0, "clz%c\t%12-15r, %0-3r"}, 602 603 /* V5E "El Segundo" Instructions. */ 604 {ARM_EXT_V5E, 0x000000d0, 0x0e1000f0, "ldr%cd\t%12-15r, %s"}, 605 {ARM_EXT_V5E, 0x000000f0, 0x0e1000f0, "str%cd\t%12-15r, %s"}, 606 {ARM_EXT_V5E, 0xf450f000, 0xfc70f000, "pld\t%a"}, 607 {ARM_EXT_V5ExP, 0x01000080, 0x0ff000f0, "smlabb%c\t%16-19r, %0-3r, %8-11r, %12-15r"}, 608 {ARM_EXT_V5ExP, 0x010000a0, 0x0ff000f0, "smlatb%c\t%16-19r, %0-3r, %8-11r, %12-15r"}, 609 {ARM_EXT_V5ExP, 0x010000c0, 0x0ff000f0, "smlabt%c\t%16-19r, %0-3r, %8-11r, %12-15r"}, 610 {ARM_EXT_V5ExP, 0x010000e0, 0x0ff000f0, "smlatt%c\t%16-19r, %0-3r, %8-11r, %12-15r"}, 611 612 {ARM_EXT_V5ExP, 0x01200080, 0x0ff000f0, "smlawb%c\t%16-19r, %0-3r, %8-11r, %12-15r"}, 613 {ARM_EXT_V5ExP, 0x012000c0, 0x0ff000f0, "smlawt%c\t%16-19r, %0-3r, %8-11r, %12-15r"}, 614 615 {ARM_EXT_V5ExP, 0x01400080, 0x0ff000f0, "smlalbb%c\t%12-15r, %16-19r, %0-3r, %8-11r"}, 616 {ARM_EXT_V5ExP, 0x014000a0, 0x0ff000f0, "smlaltb%c\t%12-15r, %16-19r, %0-3r, %8-11r"}, 617 {ARM_EXT_V5ExP, 0x014000c0, 0x0ff000f0, "smlalbt%c\t%12-15r, %16-19r, %0-3r, %8-11r"}, 618 {ARM_EXT_V5ExP, 0x014000e0, 0x0ff000f0, "smlaltt%c\t%12-15r, %16-19r, %0-3r, %8-11r"}, 619 620 {ARM_EXT_V5ExP, 0x01600080, 0x0ff0f0f0, "smulbb%c\t%16-19r, %0-3r, %8-11r"}, 621 {ARM_EXT_V5ExP, 0x016000a0, 0x0ff0f0f0, "smultb%c\t%16-19r, %0-3r, %8-11r"}, 622 {ARM_EXT_V5ExP, 0x016000c0, 0x0ff0f0f0, "smulbt%c\t%16-19r, %0-3r, %8-11r"}, 623 {ARM_EXT_V5ExP, 0x016000e0, 0x0ff0f0f0, "smultt%c\t%16-19r, %0-3r, %8-11r"}, 624 625 {ARM_EXT_V5ExP, 0x012000a0, 0x0ff0f0f0, "smulwb%c\t%16-19r, %0-3r, %8-11r"}, 626 {ARM_EXT_V5ExP, 0x012000e0, 0x0ff0f0f0, "smulwt%c\t%16-19r, %0-3r, %8-11r"}, 627 628 {ARM_EXT_V5ExP, 0x01000050, 0x0ff00ff0, "qadd%c\t%12-15r, %0-3r, %16-19r"}, 629 {ARM_EXT_V5ExP, 0x01400050, 0x0ff00ff0, "qdadd%c\t%12-15r, %0-3r, %16-19r"}, 630 {ARM_EXT_V5ExP, 0x01200050, 0x0ff00ff0, "qsub%c\t%12-15r, %0-3r, %16-19r"}, 631 {ARM_EXT_V5ExP, 0x01600050, 0x0ff00ff0, "qdsub%c\t%12-15r, %0-3r, %16-19r"}, 632 633 /* ARM Instructions. */ 634 {ARM_EXT_V1, 0x00000090, 0x0e100090, "str%c%6's%5?hb\t%12-15r, %s"}, 635 {ARM_EXT_V1, 0x00100090, 0x0e100090, "ldr%c%6's%5?hb\t%12-15r, %s"}, 636 {ARM_EXT_V1, 0x00000000, 0x0de00000, "and%c%20's\t%12-15r, %16-19r, %o"}, 637 {ARM_EXT_V1, 0x00200000, 0x0de00000, "eor%c%20's\t%12-15r, %16-19r, %o"}, 638 {ARM_EXT_V1, 0x00400000, 0x0de00000, "sub%c%20's\t%12-15r, %16-19r, %o"}, 639 {ARM_EXT_V1, 0x00600000, 0x0de00000, "rsb%c%20's\t%12-15r, %16-19r, %o"}, 640 {ARM_EXT_V1, 0x00800000, 0x0de00000, "add%c%20's\t%12-15r, %16-19r, %o"}, 641 {ARM_EXT_V1, 0x00a00000, 0x0de00000, "adc%c%20's\t%12-15r, %16-19r, %o"}, 642 {ARM_EXT_V1, 0x00c00000, 0x0de00000, "sbc%c%20's\t%12-15r, %16-19r, %o"}, 643 {ARM_EXT_V1, 0x00e00000, 0x0de00000, "rsc%c%20's\t%12-15r, %16-19r, %o"}, 644 {ARM_EXT_V3, 0x0120f000, 0x0db0f000, "msr%c\t%22?SCPSR%C, %o"}, 645 {ARM_EXT_V3, 0x010f0000, 0x0fbf0fff, "mrs%c\t%12-15r, %22?SCPSR"}, 646 {ARM_EXT_V1, 0x01000000, 0x0de00000, "tst%c%p\t%16-19r, %o"}, 647 {ARM_EXT_V1, 0x01200000, 0x0de00000, "teq%c%p\t%16-19r, %o"}, 648 {ARM_EXT_V1, 0x01400000, 0x0de00000, "cmp%c%p\t%16-19r, %o"}, 649 {ARM_EXT_V1, 0x01600000, 0x0de00000, "cmn%c%p\t%16-19r, %o"}, 650 {ARM_EXT_V1, 0x01800000, 0x0de00000, "orr%c%20's\t%12-15r, %16-19r, %o"}, 651 {ARM_EXT_V1, 0x01a00000, 0x0de00000, "mov%c%20's\t%12-15r, %o"}, 652 {ARM_EXT_V1, 0x01c00000, 0x0de00000, "bic%c%20's\t%12-15r, %16-19r, %o"}, 653 {ARM_EXT_V1, 0x01e00000, 0x0de00000, "mvn%c%20's\t%12-15r, %o"}, 654 {ARM_EXT_V1, 0x04000000, 0x0e100000, "str%c%22'b%t\t%12-15r, %a"}, 655 {ARM_EXT_V1, 0x06000000, 0x0e100ff0, "str%c%22'b%t\t%12-15r, %a"}, 656 {ARM_EXT_V1, 0x04000000, 0x0c100010, "str%c%22'b%t\t%12-15r, %a"}, 657 {ARM_EXT_V1, 0x06000010, 0x0e000010, "undefined"}, 658 {ARM_EXT_V1, 0x04100000, 0x0c100000, "ldr%c%22'b%t\t%12-15r, %a"}, 659 {ARM_EXT_V1, 0x08000000, 0x0e100000, "stm%c%23?id%24?ba\t%16-19r%21'!, %m%22'^"}, 660 {ARM_EXT_V1, 0x08100000, 0x0e100000, "ldm%c%23?id%24?ba\t%16-19r%21'!, %m%22'^"}, 661 {ARM_EXT_V1, 0x0a000000, 0x0e000000, "b%24'l%c\t%b"}, 662 {ARM_EXT_V1, 0x0f000000, 0x0f000000, "svc%c\t%0-23x"}, 663 664 /* The rest. */ 665 {ARM_EXT_V1, 0x00000000, 0x00000000, "undefined instruction %0-31x"}, 666 {0, 0x00000000, 0x00000000, 0} 667 }; 668 669 /* print_insn_thumb16 recognizes the following format control codes: 670 671 %S print Thumb register (bits 3..5 as high number if bit 6 set) 672 %D print Thumb register (bits 0..2 as high number if bit 7 set) 673 %<bitfield>I print bitfield as a signed decimal 674 (top bit of range being the sign bit) 675 %N print Thumb register mask (with LR) 676 %O print Thumb register mask (with PC) 677 %M print Thumb register mask 678 %b print CZB's 6-bit unsigned branch destination 679 %s print Thumb right-shift immediate (6..10; 0 == 32). 680 %<bitfield>r print bitfield as an ARM register 681 %<bitfield>d print bitfield as a decimal 682 %<bitfield>H print (bitfield * 2) as a decimal 683 %<bitfield>W print (bitfield * 4) as a decimal 684 %<bitfield>a print (bitfield * 4) as a pc-rel offset + decoded symbol 685 %<bitfield>B print Thumb branch destination (signed displacement) 686 %<bitfield>c print bitfield as a condition code 687 %<bitnum>'c print specified char iff bit is one 688 %<bitnum>?ab print a if bit is one else print b. */ 689 690 static const struct opcode16 thumb_opcodes[] = 691 { 692 /* Thumb instructions. */ 693 694 /* ARM V6K no-argument instructions. */ 695 {ARM_EXT_V6K, 0xbf00, 0xffff, "nop"}, 696 {ARM_EXT_V6K, 0xbf10, 0xffff, "yield"}, 697 {ARM_EXT_V6K, 0xbf20, 0xffff, "wfe"}, 698 {ARM_EXT_V6K, 0xbf30, 0xffff, "wfi"}, 699 {ARM_EXT_V6K, 0xbf40, 0xffff, "sev"}, 700 {ARM_EXT_V6K, 0xbf00, 0xff0f, "nop\t{%4-7d}"}, 701 702 /* ARM V6T2 instructions. */ 703 {ARM_EXT_V6T2, 0xb900, 0xfd00, "cbnz\t%0-2r, %b"}, 704 {ARM_EXT_V6T2, 0xb100, 0xfd00, "cbz\t%0-2r, %b"}, 705 {ARM_EXT_V6T2, 0xbf08, 0xff0f, "it\t%4-7c"}, 706 {ARM_EXT_V6T2, 0xbf14, 0xff17, "it%3?te\t%4-7c"}, 707 {ARM_EXT_V6T2, 0xbf04, 0xff17, "it%3?et\t%4-7c"}, 708 {ARM_EXT_V6T2, 0xbf12, 0xff13, "it%3?te%2?te\t%4-7c"}, 709 {ARM_EXT_V6T2, 0xbf02, 0xff13, "it%3?et%2?et\t%4-7c"}, 710 {ARM_EXT_V6T2, 0xbf11, 0xff11, "it%3?te%2?te%1?te\t%4-7c"}, 711 {ARM_EXT_V6T2, 0xbf01, 0xff11, "it%3?et%2?et%1?et\t%4-7c"}, 712 713 /* ARM V6. */ 714 {ARM_EXT_V6, 0xb660, 0xfff8, "cpsie\t%2'a%1'i%0'f"}, 715 {ARM_EXT_V6, 0xb670, 0xfff8, "cpsid\t%2'a%1'i%0'f"}, 716 {ARM_EXT_V6, 0x4600, 0xffc0, "mov\t%0-2r, %3-5r"}, 717 {ARM_EXT_V6, 0xba00, 0xffc0, "rev\t%0-2r, %3-5r"}, 718 {ARM_EXT_V6, 0xba40, 0xffc0, "rev16\t%0-2r, %3-5r"}, 719 {ARM_EXT_V6, 0xbac0, 0xffc0, "revsh\t%0-2r, %3-5r"}, 720 {ARM_EXT_V6, 0xb650, 0xfff7, "setend\t%3?ble"}, 721 {ARM_EXT_V6, 0xb200, 0xffc0, "sxth\t%0-2r, %3-5r"}, 722 {ARM_EXT_V6, 0xb240, 0xffc0, "sxtb\t%0-2r, %3-5r"}, 723 {ARM_EXT_V6, 0xb280, 0xffc0, "uxth\t%0-2r, %3-5r"}, 724 {ARM_EXT_V6, 0xb2c0, 0xffc0, "uxtb\t%0-2r, %3-5r"}, 725 726 /* ARM V5 ISA extends Thumb. */ 727 {ARM_EXT_V5T, 0xbe00, 0xff00, "bkpt\t%0-7x"}, 728 /* This is BLX(2). BLX(1) is a 32-bit instruction. */ 729 {ARM_EXT_V5T, 0x4780, 0xff87, "blx\t%3-6r"}, /* note: 4 bit register number. */ 730 /* ARM V4T ISA (Thumb v1). */ 731 {ARM_EXT_V4T, 0x46C0, 0xFFFF, "nop\t\t\t(mov r8, r8)"}, 732 /* Format 4. */ 733 {ARM_EXT_V4T, 0x4000, 0xFFC0, "ands\t%0-2r, %3-5r"}, 734 {ARM_EXT_V4T, 0x4040, 0xFFC0, "eors\t%0-2r, %3-5r"}, 735 {ARM_EXT_V4T, 0x4080, 0xFFC0, "lsls\t%0-2r, %3-5r"}, 736 {ARM_EXT_V4T, 0x40C0, 0xFFC0, "lsrs\t%0-2r, %3-5r"}, 737 {ARM_EXT_V4T, 0x4100, 0xFFC0, "asrs\t%0-2r, %3-5r"}, 738 {ARM_EXT_V4T, 0x4140, 0xFFC0, "adcs\t%0-2r, %3-5r"}, 739 {ARM_EXT_V4T, 0x4180, 0xFFC0, "sbcs\t%0-2r, %3-5r"}, 740 {ARM_EXT_V4T, 0x41C0, 0xFFC0, "rors\t%0-2r, %3-5r"}, 741 {ARM_EXT_V4T, 0x4200, 0xFFC0, "tst\t%0-2r, %3-5r"}, 742 {ARM_EXT_V4T, 0x4240, 0xFFC0, "negs\t%0-2r, %3-5r"}, 743 {ARM_EXT_V4T, 0x4280, 0xFFC0, "cmp\t%0-2r, %3-5r"}, 744 {ARM_EXT_V4T, 0x42C0, 0xFFC0, "cmn\t%0-2r, %3-5r"}, 745 {ARM_EXT_V4T, 0x4300, 0xFFC0, "orrs\t%0-2r, %3-5r"}, 746 {ARM_EXT_V4T, 0x4340, 0xFFC0, "muls\t%0-2r, %3-5r"}, 747 {ARM_EXT_V4T, 0x4380, 0xFFC0, "bics\t%0-2r, %3-5r"}, 748 {ARM_EXT_V4T, 0x43C0, 0xFFC0, "mvns\t%0-2r, %3-5r"}, 749 /* format 13 */ 750 {ARM_EXT_V4T, 0xB000, 0xFF80, "add\tsp, #%0-6W"}, 751 {ARM_EXT_V4T, 0xB080, 0xFF80, "sub\tsp, #%0-6W"}, 752 /* format 5 */ 753 {ARM_EXT_V4T, 0x4700, 0xFF80, "bx\t%S"}, 754 {ARM_EXT_V4T, 0x4400, 0xFF00, "add\t%D, %S"}, 755 {ARM_EXT_V4T, 0x4500, 0xFF00, "cmp\t%D, %S"}, 756 {ARM_EXT_V4T, 0x4600, 0xFF00, "mov\t%D, %S"}, 757 /* format 14 */ 758 {ARM_EXT_V4T, 0xB400, 0xFE00, "push\t%N"}, 759 {ARM_EXT_V4T, 0xBC00, 0xFE00, "pop\t%O"}, 760 /* format 2 */ 761 {ARM_EXT_V4T, 0x1800, 0xFE00, "adds\t%0-2r, %3-5r, %6-8r"}, 762 {ARM_EXT_V4T, 0x1A00, 0xFE00, "subs\t%0-2r, %3-5r, %6-8r"}, 763 {ARM_EXT_V4T, 0x1C00, 0xFE00, "adds\t%0-2r, %3-5r, #%6-8d"}, 764 {ARM_EXT_V4T, 0x1E00, 0xFE00, "subs\t%0-2r, %3-5r, #%6-8d"}, 765 /* format 8 */ 766 {ARM_EXT_V4T, 0x5200, 0xFE00, "strh\t%0-2r, [%3-5r, %6-8r]"}, 767 {ARM_EXT_V4T, 0x5A00, 0xFE00, "ldrh\t%0-2r, [%3-5r, %6-8r]"}, 768 {ARM_EXT_V4T, 0x5600, 0xF600, "ldrs%11?hb\t%0-2r, [%3-5r, %6-8r]"}, 769 /* format 7 */ 770 {ARM_EXT_V4T, 0x5000, 0xFA00, "str%10'b\t%0-2r, [%3-5r, %6-8r]"}, 771 {ARM_EXT_V4T, 0x5800, 0xFA00, "ldr%10'b\t%0-2r, [%3-5r, %6-8r]"}, 772 /* format 1 */ 773 {ARM_EXT_V4T, 0x0000, 0xF800, "lsls\t%0-2r, %3-5r, #%6-10d"}, 774 {ARM_EXT_V4T, 0x0800, 0xF800, "lsrs\t%0-2r, %3-5r, %s"}, 775 {ARM_EXT_V4T, 0x1000, 0xF800, "asrs\t%0-2r, %3-5r, %s"}, 776 /* format 3 */ 777 {ARM_EXT_V4T, 0x2000, 0xF800, "movs\t%8-10r, #%0-7d"}, 778 {ARM_EXT_V4T, 0x2800, 0xF800, "cmp\t%8-10r, #%0-7d"}, 779 {ARM_EXT_V4T, 0x3000, 0xF800, "adds\t%8-10r, #%0-7d"}, 780 {ARM_EXT_V4T, 0x3800, 0xF800, "subs\t%8-10r, #%0-7d"}, 781 /* format 6 */ 782 {ARM_EXT_V4T, 0x4800, 0xF800, "ldr\t%8-10r, [pc, #%0-7W]\t(%0-7a)"}, /* TODO: Disassemble PC relative "LDR rD,=<symbolic>" */ 783 /* format 9 */ 784 {ARM_EXT_V4T, 0x6000, 0xF800, "str\t%0-2r, [%3-5r, #%6-10W]"}, 785 {ARM_EXT_V4T, 0x6800, 0xF800, "ldr\t%0-2r, [%3-5r, #%6-10W]"}, 786 {ARM_EXT_V4T, 0x7000, 0xF800, "strb\t%0-2r, [%3-5r, #%6-10d]"}, 787 {ARM_EXT_V4T, 0x7800, 0xF800, "ldrb\t%0-2r, [%3-5r, #%6-10d]"}, 788 /* format 10 */ 789 {ARM_EXT_V4T, 0x8000, 0xF800, "strh\t%0-2r, [%3-5r, #%6-10H]"}, 790 {ARM_EXT_V4T, 0x8800, 0xF800, "ldrh\t%0-2r, [%3-5r, #%6-10H]"}, 791 /* format 11 */ 792 {ARM_EXT_V4T, 0x9000, 0xF800, "str\t%8-10r, [sp, #%0-7W]"}, 793 {ARM_EXT_V4T, 0x9800, 0xF800, "ldr\t%8-10r, [sp, #%0-7W]"}, 794 /* format 12 */ 795 {ARM_EXT_V4T, 0xA000, 0xF800, "add\t%8-10r, pc, #%0-7W\t(adr %8-10r,%0-7a)"}, 796 {ARM_EXT_V4T, 0xA800, 0xF800, "add\t%8-10r, sp, #%0-7W"}, 797 /* format 15 */ 798 {ARM_EXT_V4T, 0xC000, 0xF800, "stmia\t%8-10r!, %M"}, 799 {ARM_EXT_V4T, 0xC800, 0xF800, "ldmia\t%8-10r!, %M"}, 800 /* format 17 */ 801 {ARM_EXT_V4T, 0xDF00, 0xFF00, "svc\t%0-7d"}, 802 /* format 16 */ 803 {ARM_EXT_V4T, 0xD000, 0xF000, "b%8-11c.n\t%0-7B"}, 804 /* format 18 */ 805 {ARM_EXT_V4T, 0xE000, 0xF800, "b.n\t%0-10B"}, 806 807 /* The E800 .. FFFF range is unconditionally redirected to the 808 32-bit table, because even in pre-V6T2 ISAs, BL and BLX(1) pairs 809 are processed via that table. Thus, we can never encounter a 810 bare "second half of BL/BLX(1)" instruction here. */ 811 {ARM_EXT_V1, 0x0000, 0x0000, "undefined"}, 812 {0, 0, 0, 0} 813 }; 814 815 /* Thumb32 opcodes use the same table structure as the ARM opcodes. 816 We adopt the convention that hw1 is the high 16 bits of .value and 817 .mask, hw2 the low 16 bits. 818 819 print_insn_thumb32 recognizes the following format control codes: 820 821 %% % 822 823 %I print a 12-bit immediate from hw1[10],hw2[14:12,7:0] 824 %M print a modified 12-bit immediate (same location) 825 %J print a 16-bit immediate from hw1[3:0,10],hw2[14:12,7:0] 826 %K print a 16-bit immediate from hw2[3:0],hw1[3:0],hw2[11:4] 827 %S print a possibly-shifted Rm 828 829 %a print the address of a plain load/store 830 %w print the width and signedness of a core load/store 831 %m print register mask for ldm/stm 832 833 %E print the lsb and width fields of a bfc/bfi instruction 834 %F print the lsb and width fields of a sbfx/ubfx instruction 835 %b print a conditional branch offset 836 %B print an unconditional branch offset 837 %s print the shift field of an SSAT instruction 838 %R print the rotation field of an SXT instruction 839 %U print barrier type. 840 %P print address for pli instruction. 841 842 %<bitfield>d print bitfield in decimal 843 %<bitfield>W print bitfield*4 in decimal 844 %<bitfield>r print bitfield as an ARM register 845 %<bitfield>c print bitfield as a condition code 846 847 %<bitnum>'c print "c" iff bit is one 848 %<bitnum>`c print "c" iff bit is zero 849 %<bitnum>?ab print "a" if bit is one, else "b" 850 851 With one exception at the bottom (done because BL and BLX(1) need 852 to come dead last), this table was machine-sorted first in 853 decreasing order of number of bits set in the mask, then in 854 increasing numeric order of mask, then in increasing numeric order 855 of opcode. This order is not the clearest for a human reader, but 856 is guaranteed never to catch a special-case bit pattern with a more 857 general mask, which is important, because this instruction encoding 858 makes heavy use of special-case bit patterns. */ 859 static const struct opcode32 thumb32_opcodes[] = 860 { 861 /* V7 instructions. */ 862 {ARM_EXT_V7, 0xf910f000, 0xff70f000, "pli\t%a"}, 863 {ARM_EXT_V7, 0xf3af80f0, 0xfffffff0, "dbg\t#%0-3d"}, 864 {ARM_EXT_V7, 0xf3bf8f50, 0xfffffff0, "dmb\t%U"}, 865 {ARM_EXT_V7, 0xf3bf8f40, 0xfffffff0, "dsb\t%U"}, 866 {ARM_EXT_V7, 0xf3bf8f60, 0xfffffff0, "isb\t%U"}, 867 {ARM_EXT_DIV, 0xfb90f0f0, 0xfff0f0f0, "sdiv\t%8-11r, %16-19r, %0-3r"}, 868 {ARM_EXT_DIV, 0xfbb0f0f0, 0xfff0f0f0, "udiv\t%8-11r, %16-19r, %0-3r"}, 869 870 /* Instructions defined in the basic V6T2 set. */ 871 {ARM_EXT_V6T2, 0xf3af8000, 0xffffffff, "nop.w"}, 872 {ARM_EXT_V6T2, 0xf3af8001, 0xffffffff, "yield.w"}, 873 {ARM_EXT_V6T2, 0xf3af8002, 0xffffffff, "wfe.w"}, 874 {ARM_EXT_V6T2, 0xf3af8003, 0xffffffff, "wfi.w"}, 875 {ARM_EXT_V6T2, 0xf3af9004, 0xffffffff, "sev.w"}, 876 {ARM_EXT_V6T2, 0xf3af8000, 0xffffff00, "nop.w\t{%0-7d}"}, 877 878 {ARM_EXT_V6T2, 0xf3bf8f2f, 0xffffffff, "clrex"}, 879 {ARM_EXT_V6T2, 0xf3af8400, 0xffffff1f, "cpsie.w\t%7'a%6'i%5'f"}, 880 {ARM_EXT_V6T2, 0xf3af8600, 0xffffff1f, "cpsid.w\t%7'a%6'i%5'f"}, 881 {ARM_EXT_V6T2, 0xf3c08f00, 0xfff0ffff, "bxj\t%16-19r"}, 882 {ARM_EXT_V6T2, 0xe810c000, 0xffd0ffff, "rfedb\t%16-19r%21'!"}, 883 {ARM_EXT_V6T2, 0xe990c000, 0xffd0ffff, "rfeia\t%16-19r%21'!"}, 884 {ARM_EXT_V6T2, 0xf3ef8000, 0xffeff000, "mrs\t%8-11r, %D"}, 885 {ARM_EXT_V6T2, 0xf3af8100, 0xffffffe0, "cps\t#%0-4d"}, 886 {ARM_EXT_V6T2, 0xe8d0f000, 0xfff0fff0, "tbb\t[%16-19r, %0-3r]"}, 887 {ARM_EXT_V6T2, 0xe8d0f010, 0xfff0fff0, "tbh\t[%16-19r, %0-3r, lsl #1]"}, 888 {ARM_EXT_V6T2, 0xf3af8500, 0xffffff00, "cpsie\t%7'a%6'i%5'f, #%0-4d"}, 889 {ARM_EXT_V6T2, 0xf3af8700, 0xffffff00, "cpsid\t%7'a%6'i%5'f, #%0-4d"}, 890 {ARM_EXT_V6T2, 0xf3de8f00, 0xffffff00, "subs\tpc, lr, #%0-7d"}, 891 {ARM_EXT_V6T2, 0xf3808000, 0xffe0f000, "msr\t%C, %16-19r"}, 892 {ARM_EXT_V6T2, 0xe8500f00, 0xfff00fff, "ldrex\t%12-15r, [%16-19r]"}, 893 {ARM_EXT_V6T2, 0xe8d00f4f, 0xfff00fef, "ldrex%4?hb\t%12-15r, [%16-19r]"}, 894 {ARM_EXT_V6T2, 0xe800c000, 0xffd0ffe0, "srsdb\t#%0-4d%21'!"}, 895 {ARM_EXT_V6T2, 0xe980c000, 0xffd0ffe0, "srsia\t#%0-4d%21'!"}, 896 {ARM_EXT_V6T2, 0xfa0ff080, 0xfffff0c0, "sxth.w\t%8-11r, %0-3r%R"}, 897 {ARM_EXT_V6T2, 0xfa1ff080, 0xfffff0c0, "uxth.w\t%8-11r, %0-3r%R"}, 898 {ARM_EXT_V6T2, 0xfa2ff080, 0xfffff0c0, "sxtb16\t%8-11r, %0-3r%R"}, 899 {ARM_EXT_V6T2, 0xfa3ff080, 0xfffff0c0, "uxtb16\t%8-11r, %0-3r%R"}, 900 {ARM_EXT_V6T2, 0xfa4ff080, 0xfffff0c0, "sxtb.w\t%8-11r, %0-3r%R"}, 901 {ARM_EXT_V6T2, 0xfa5ff080, 0xfffff0c0, "uxtb.w\t%8-11r, %0-3r%R"}, 902 {ARM_EXT_V6T2, 0xe8400000, 0xfff000ff, "strex\t%8-11r, %12-15r, [%16-19r]"}, 903 {ARM_EXT_V6T2, 0xe8d0007f, 0xfff000ff, "ldrexd\t%12-15r, %8-11r, [%16-19r]"}, 904 {ARM_EXT_V6T2, 0xfa80f000, 0xfff0f0f0, "sadd8\t%8-11r, %16-19r, %0-3r"}, 905 {ARM_EXT_V6T2, 0xfa80f010, 0xfff0f0f0, "qadd8\t%8-11r, %16-19r, %0-3r"}, 906 {ARM_EXT_V6T2, 0xfa80f020, 0xfff0f0f0, "shadd8\t%8-11r, %16-19r, %0-3r"}, 907 {ARM_EXT_V6T2, 0xfa80f040, 0xfff0f0f0, "uadd8\t%8-11r, %16-19r, %0-3r"}, 908 {ARM_EXT_V6T2, 0xfa80f050, 0xfff0f0f0, "uqadd8\t%8-11r, %16-19r, %0-3r"}, 909 {ARM_EXT_V6T2, 0xfa80f060, 0xfff0f0f0, "uhadd8\t%8-11r, %16-19r, %0-3r"}, 910 {ARM_EXT_V6T2, 0xfa80f080, 0xfff0f0f0, "qadd\t%8-11r, %0-3r, %16-19r"}, 911 {ARM_EXT_V6T2, 0xfa80f090, 0xfff0f0f0, "qdadd\t%8-11r, %0-3r, %16-19r"}, 912 {ARM_EXT_V6T2, 0xfa80f0a0, 0xfff0f0f0, "qsub\t%8-11r, %0-3r, %16-19r"}, 913 {ARM_EXT_V6T2, 0xfa80f0b0, 0xfff0f0f0, "qdsub\t%8-11r, %0-3r, %16-19r"}, 914 {ARM_EXT_V6T2, 0xfa90f000, 0xfff0f0f0, "sadd16\t%8-11r, %16-19r, %0-3r"}, 915 {ARM_EXT_V6T2, 0xfa90f010, 0xfff0f0f0, "qadd16\t%8-11r, %16-19r, %0-3r"}, 916 {ARM_EXT_V6T2, 0xfa90f020, 0xfff0f0f0, "shadd16\t%8-11r, %16-19r, %0-3r"}, 917 {ARM_EXT_V6T2, 0xfa90f040, 0xfff0f0f0, "uadd16\t%8-11r, %16-19r, %0-3r"}, 918 {ARM_EXT_V6T2, 0xfa90f050, 0xfff0f0f0, "uqadd16\t%8-11r, %16-19r, %0-3r"}, 919 {ARM_EXT_V6T2, 0xfa90f060, 0xfff0f0f0, "uhadd16\t%8-11r, %16-19r, %0-3r"}, 920 {ARM_EXT_V6T2, 0xfa90f080, 0xfff0f0f0, "rev.w\t%8-11r, %16-19r"}, 921 {ARM_EXT_V6T2, 0xfa90f090, 0xfff0f0f0, "rev16.w\t%8-11r, %16-19r"}, 922 {ARM_EXT_V6T2, 0xfa90f0a0, 0xfff0f0f0, "rbit\t%8-11r, %16-19r"}, 923 {ARM_EXT_V6T2, 0xfa90f0b0, 0xfff0f0f0, "revsh.w\t%8-11r, %16-19r"}, 924 {ARM_EXT_V6T2, 0xfaa0f000, 0xfff0f0f0, "saddsubx\t%8-11r, %16-19r, %0-3r"}, 925 {ARM_EXT_V6T2, 0xfaa0f010, 0xfff0f0f0, "qaddsubx\t%8-11r, %16-19r, %0-3r"}, 926 {ARM_EXT_V6T2, 0xfaa0f020, 0xfff0f0f0, "shaddsubx\t%8-11r, %16-19r, %0-3r"}, 927 {ARM_EXT_V6T2, 0xfaa0f040, 0xfff0f0f0, "uaddsubx\t%8-11r, %16-19r, %0-3r"}, 928 {ARM_EXT_V6T2, 0xfaa0f050, 0xfff0f0f0, "uqaddsubx\t%8-11r, %16-19r, %0-3r"}, 929 {ARM_EXT_V6T2, 0xfaa0f060, 0xfff0f0f0, "uhaddsubx\t%8-11r, %16-19r, %0-3r"}, 930 {ARM_EXT_V6T2, 0xfaa0f080, 0xfff0f0f0, "sel\t%8-11r, %16-19r, %0-3r"}, 931 {ARM_EXT_V6T2, 0xfab0f080, 0xfff0f0f0, "clz\t%8-11r, %16-19r"}, 932 {ARM_EXT_V6T2, 0xfac0f000, 0xfff0f0f0, "ssub8\t%8-11r, %16-19r, %0-3r"}, 933 {ARM_EXT_V6T2, 0xfac0f010, 0xfff0f0f0, "qsub8\t%8-11r, %16-19r, %0-3r"}, 934 {ARM_EXT_V6T2, 0xfac0f020, 0xfff0f0f0, "shsub8\t%8-11r, %16-19r, %0-3r"}, 935 {ARM_EXT_V6T2, 0xfac0f040, 0xfff0f0f0, "usub8\t%8-11r, %16-19r, %0-3r"}, 936 {ARM_EXT_V6T2, 0xfac0f050, 0xfff0f0f0, "uqsub8\t%8-11r, %16-19r, %0-3r"}, 937 {ARM_EXT_V6T2, 0xfac0f060, 0xfff0f0f0, "uhsub8\t%8-11r, %16-19r, %0-3r"}, 938 {ARM_EXT_V6T2, 0xfad0f000, 0xfff0f0f0, "ssub16\t%8-11r, %16-19r, %0-3r"}, 939 {ARM_EXT_V6T2, 0xfad0f010, 0xfff0f0f0, "qsub16\t%8-11r, %16-19r, %0-3r"}, 940 {ARM_EXT_V6T2, 0xfad0f020, 0xfff0f0f0, "shsub16\t%8-11r, %16-19r, %0-3r"}, 941 {ARM_EXT_V6T2, 0xfad0f040, 0xfff0f0f0, "usub16\t%8-11r, %16-19r, %0-3r"}, 942 {ARM_EXT_V6T2, 0xfad0f050, 0xfff0f0f0, "uqsub16\t%8-11r, %16-19r, %0-3r"}, 943 {ARM_EXT_V6T2, 0xfad0f060, 0xfff0f0f0, "uhsub16\t%8-11r, %16-19r, %0-3r"}, 944 {ARM_EXT_V6T2, 0xfae0f000, 0xfff0f0f0, "ssubaddx\t%8-11r, %16-19r, %0-3r"}, 945 {ARM_EXT_V6T2, 0xfae0f010, 0xfff0f0f0, "qsubaddx\t%8-11r, %16-19r, %0-3r"}, 946 {ARM_EXT_V6T2, 0xfae0f020, 0xfff0f0f0, "shsubaddx\t%8-11r, %16-19r, %0-3r"}, 947 {ARM_EXT_V6T2, 0xfae0f040, 0xfff0f0f0, "usubaddx\t%8-11r, %16-19r, %0-3r"}, 948 {ARM_EXT_V6T2, 0xfae0f050, 0xfff0f0f0, "uqsubaddx\t%8-11r, %16-19r, %0-3r"}, 949 {ARM_EXT_V6T2, 0xfae0f060, 0xfff0f0f0, "uhsubaddx\t%8-11r, %16-19r, %0-3r"}, 950 {ARM_EXT_V6T2, 0xfb00f000, 0xfff0f0f0, "mul.w\t%8-11r, %16-19r, %0-3r"}, 951 {ARM_EXT_V6T2, 0xfb70f000, 0xfff0f0f0, "usad8\t%8-11r, %16-19r, %0-3r"}, 952 {ARM_EXT_V6T2, 0xfa00f000, 0xffe0f0f0, "lsl%20's.w\t%8-11r, %16-19r, %0-3r"}, 953 {ARM_EXT_V6T2, 0xfa20f000, 0xffe0f0f0, "lsr%20's.w\t%8-11r, %16-19r, %0-3r"}, 954 {ARM_EXT_V6T2, 0xfa40f000, 0xffe0f0f0, "asr%20's.w\t%8-11r, %16-19r, %0-3r"}, 955 {ARM_EXT_V6T2, 0xfa60f000, 0xffe0f0f0, "ror%20's.w\t%8-11r, %16-19r, %0-3r"}, 956 {ARM_EXT_V6T2, 0xe8c00f40, 0xfff00fe0, "strex%4?hb\t%0-3r, %12-15r, [%16-19r]"}, 957 {ARM_EXT_V6T2, 0xf3200000, 0xfff0f0e0, "ssat16\t%8-11r, #%0-4d, %16-19r"}, 958 {ARM_EXT_V6T2, 0xf3a00000, 0xfff0f0e0, "usat16\t%8-11r, #%0-4d, %16-19r"}, 959 {ARM_EXT_V6T2, 0xfb20f000, 0xfff0f0e0, "smuad%4'x\t%8-11r, %16-19r, %0-3r"}, 960 {ARM_EXT_V6T2, 0xfb30f000, 0xfff0f0e0, "smulw%4?tb\t%8-11r, %16-19r, %0-3r"}, 961 {ARM_EXT_V6T2, 0xfb40f000, 0xfff0f0e0, "smusd%4'x\t%8-11r, %16-19r, %0-3r"}, 962 {ARM_EXT_V6T2, 0xfb50f000, 0xfff0f0e0, "smmul%4'r\t%8-11r, %16-19r, %0-3r"}, 963 {ARM_EXT_V6T2, 0xfa00f080, 0xfff0f0c0, "sxtah\t%8-11r, %16-19r, %0-3r%R"}, 964 {ARM_EXT_V6T2, 0xfa10f080, 0xfff0f0c0, "uxtah\t%8-11r, %16-19r, %0-3r%R"}, 965 {ARM_EXT_V6T2, 0xfa20f080, 0xfff0f0c0, "sxtab16\t%8-11r, %16-19r, %0-3r%R"}, 966 {ARM_EXT_V6T2, 0xfa30f080, 0xfff0f0c0, "uxtab16\t%8-11r, %16-19r, %0-3r%R"}, 967 {ARM_EXT_V6T2, 0xfa40f080, 0xfff0f0c0, "sxtab\t%8-11r, %16-19r, %0-3r%R"}, 968 {ARM_EXT_V6T2, 0xfa50f080, 0xfff0f0c0, "uxtab\t%8-11r, %16-19r, %0-3r%R"}, 969 {ARM_EXT_V6T2, 0xfb10f000, 0xfff0f0c0, "smul%5?tb%4?tb\t%8-11r, %16-19r, %0-3r"}, 970 {ARM_EXT_V6T2, 0xf36f0000, 0xffff8020, "bfc\t%8-11r, %E"}, 971 {ARM_EXT_V6T2, 0xea100f00, 0xfff08f00, "tst.w\t%16-19r, %S"}, 972 {ARM_EXT_V6T2, 0xea900f00, 0xfff08f00, "teq\t%16-19r, %S"}, 973 {ARM_EXT_V6T2, 0xeb100f00, 0xfff08f00, "cmn.w\t%16-19r, %S"}, 974 {ARM_EXT_V6T2, 0xebb00f00, 0xfff08f00, "cmp.w\t%16-19r, %S"}, 975 {ARM_EXT_V6T2, 0xf0100f00, 0xfbf08f00, "tst.w\t%16-19r, %M"}, 976 {ARM_EXT_V6T2, 0xf0900f00, 0xfbf08f00, "teq\t%16-19r, %M"}, 977 {ARM_EXT_V6T2, 0xf1100f00, 0xfbf08f00, "cmn.w\t%16-19r, %M"}, 978 {ARM_EXT_V6T2, 0xf1b00f00, 0xfbf08f00, "cmp.w\t%16-19r, %M"}, 979 {ARM_EXT_V6T2, 0xea4f0000, 0xffef8000, "mov%20's.w\t%8-11r, %S"}, 980 {ARM_EXT_V6T2, 0xea6f0000, 0xffef8000, "mvn%20's.w\t%8-11r, %S"}, 981 {ARM_EXT_V6T2, 0xe8c00070, 0xfff000f0, "strexd\t%0-3r, %12-15r, %8-11r, [%16-19r]"}, 982 {ARM_EXT_V6T2, 0xfb000000, 0xfff000f0, "mla\t%8-11r, %16-19r, %0-3r, %12-15r"}, 983 {ARM_EXT_V6T2, 0xfb000010, 0xfff000f0, "mls\t%8-11r, %16-19r, %0-3r, %12-15r"}, 984 {ARM_EXT_V6T2, 0xfb700000, 0xfff000f0, "usada8\t%8-11r, %16-19r, %0-3r, %12-15r"}, 985 {ARM_EXT_V6T2, 0xfb800000, 0xfff000f0, "smull\t%12-15r, %8-11r, %16-19r, %0-3r"}, 986 {ARM_EXT_V6T2, 0xfba00000, 0xfff000f0, "umull\t%12-15r, %8-11r, %16-19r, %0-3r"}, 987 {ARM_EXT_V6T2, 0xfbc00000, 0xfff000f0, "smlal\t%12-15r, %8-11r, %16-19r, %0-3r"}, 988 {ARM_EXT_V6T2, 0xfbe00000, 0xfff000f0, "umlal\t%12-15r, %8-11r, %16-19r, %0-3r"}, 989 {ARM_EXT_V6T2, 0xfbe00060, 0xfff000f0, "umaal\t%12-15r, %8-11r, %16-19r, %0-3r"}, 990 {ARM_EXT_V6T2, 0xe8500f00, 0xfff00f00, "ldrex\t%12-15r, [%16-19r, #%0-7W]"}, 991 {ARM_EXT_V6T2, 0xf7f08000, 0xfff0f000, "smc\t%K"}, 992 {ARM_EXT_V6T2, 0xf04f0000, 0xfbef8000, "mov%20's.w\t%8-11r, %M"}, 993 {ARM_EXT_V6T2, 0xf06f0000, 0xfbef8000, "mvn%20's.w\t%8-11r, %M"}, 994 {ARM_EXT_V6T2, 0xf810f000, 0xff70f000, "pld\t%a"}, 995 {ARM_EXT_V6T2, 0xfb200000, 0xfff000e0, "smlad%4'x\t%8-11r, %16-19r, %0-3r, %12-15r"}, 996 {ARM_EXT_V6T2, 0xfb300000, 0xfff000e0, "smlaw%4?tb\t%8-11r, %16-19r, %0-3r, %12-15r"}, 997 {ARM_EXT_V6T2, 0xfb400000, 0xfff000e0, "smlsd%4'x\t%8-11r, %16-19r, %0-3r, %12-15r"}, 998 {ARM_EXT_V6T2, 0xfb500000, 0xfff000e0, "smmla%4'r\t%8-11r, %16-19r, %0-3r, %12-15r"}, 999 {ARM_EXT_V6T2, 0xfb600000, 0xfff000e0, "smmls%4'r\t%8-11r, %16-19r, %0-3r, %12-15r"}, 1000 {ARM_EXT_V6T2, 0xfbc000c0, 0xfff000e0, "smlald%4'x\t%12-15r, %8-11r, %16-19r, %0-3r"}, 1001 {ARM_EXT_V6T2, 0xfbd000c0, 0xfff000e0, "smlsld%4'x\t%12-15r, %8-11r, %16-19r, %0-3r"}, 1002 {ARM_EXT_V6T2, 0xeac00000, 0xfff08030, "pkhbt\t%8-11r, %16-19r, %S"}, 1003 {ARM_EXT_V6T2, 0xeac00020, 0xfff08030, "pkhtb\t%8-11r, %16-19r, %S"}, 1004 {ARM_EXT_V6T2, 0xf3400000, 0xfff08020, "sbfx\t%8-11r, %16-19r, %F"}, 1005 {ARM_EXT_V6T2, 0xf3c00000, 0xfff08020, "ubfx\t%8-11r, %16-19r, %F"}, 1006 {ARM_EXT_V6T2, 0xf8000e00, 0xff900f00, "str%wt\t%12-15r, %a"}, 1007 {ARM_EXT_V6T2, 0xfb100000, 0xfff000c0, "smla%5?tb%4?tb\t%8-11r, %16-19r, %0-3r, %12-15r"}, 1008 {ARM_EXT_V6T2, 0xfbc00080, 0xfff000c0, "smlal%5?tb%4?tb\t%12-15r, %8-11r, %16-19r, %0-3r"}, 1009 {ARM_EXT_V6T2, 0xf3600000, 0xfff08020, "bfi\t%8-11r, %16-19r, %E"}, 1010 {ARM_EXT_V6T2, 0xf8100e00, 0xfe900f00, "ldr%wt\t%12-15r, %a"}, 1011 {ARM_EXT_V6T2, 0xf3000000, 0xffd08020, "ssat\t%8-11r, #%0-4d, %16-19r%s"}, 1012 {ARM_EXT_V6T2, 0xf3800000, 0xffd08020, "usat\t%8-11r, #%0-4d, %16-19r%s"}, 1013 {ARM_EXT_V6T2, 0xf2000000, 0xfbf08000, "addw\t%8-11r, %16-19r, %I"}, 1014 {ARM_EXT_V6T2, 0xf2400000, 0xfbf08000, "movw\t%8-11r, %J"}, 1015 {ARM_EXT_V6T2, 0xf2a00000, 0xfbf08000, "subw\t%8-11r, %16-19r, %I"}, 1016 {ARM_EXT_V6T2, 0xf2c00000, 0xfbf08000, "movt\t%8-11r, %J"}, 1017 {ARM_EXT_V6T2, 0xea000000, 0xffe08000, "and%20's.w\t%8-11r, %16-19r, %S"}, 1018 {ARM_EXT_V6T2, 0xea200000, 0xffe08000, "bic%20's.w\t%8-11r, %16-19r, %S"}, 1019 {ARM_EXT_V6T2, 0xea400000, 0xffe08000, "orr%20's.w\t%8-11r, %16-19r, %S"}, 1020 {ARM_EXT_V6T2, 0xea600000, 0xffe08000, "orn%20's\t%8-11r, %16-19r, %S"}, 1021 {ARM_EXT_V6T2, 0xea800000, 0xffe08000, "eor%20's.w\t%8-11r, %16-19r, %S"}, 1022 {ARM_EXT_V6T2, 0xeb000000, 0xffe08000, "add%20's.w\t%8-11r, %16-19r, %S"}, 1023 {ARM_EXT_V6T2, 0xeb400000, 0xffe08000, "adc%20's.w\t%8-11r, %16-19r, %S"}, 1024 {ARM_EXT_V6T2, 0xeb600000, 0xffe08000, "sbc%20's.w\t%8-11r, %16-19r, %S"}, 1025 {ARM_EXT_V6T2, 0xeba00000, 0xffe08000, "sub%20's.w\t%8-11r, %16-19r, %S"}, 1026 {ARM_EXT_V6T2, 0xebc00000, 0xffe08000, "rsb%20's\t%8-11r, %16-19r, %S"}, 1027 {ARM_EXT_V6T2, 0xe8400000, 0xfff00000, "strex\t%8-11r, %12-15r, [%16-19r, #%0-7W]"}, 1028 {ARM_EXT_V6T2, 0xf0000000, 0xfbe08000, "and%20's.w\t%8-11r, %16-19r, %M"}, 1029 {ARM_EXT_V6T2, 0xf0200000, 0xfbe08000, "bic%20's.w\t%8-11r, %16-19r, %M"}, 1030 {ARM_EXT_V6T2, 0xf0400000, 0xfbe08000, "orr%20's.w\t%8-11r, %16-19r, %M"}, 1031 {ARM_EXT_V6T2, 0xf0600000, 0xfbe08000, "orn%20's\t%8-11r, %16-19r, %M"}, 1032 {ARM_EXT_V6T2, 0xf0800000, 0xfbe08000, "eor%20's.w\t%8-11r, %16-19r, %M"}, 1033 {ARM_EXT_V6T2, 0xf1000000, 0xfbe08000, "add%20's.w\t%8-11r, %16-19r, %M"}, 1034 {ARM_EXT_V6T2, 0xf1400000, 0xfbe08000, "adc%20's.w\t%8-11r, %16-19r, %M"}, 1035 {ARM_EXT_V6T2, 0xf1600000, 0xfbe08000, "sbc%20's.w\t%8-11r, %16-19r, %M"}, 1036 {ARM_EXT_V6T2, 0xf1a00000, 0xfbe08000, "sub%20's.w\t%8-11r, %16-19r, %M"}, 1037 {ARM_EXT_V6T2, 0xf1c00000, 0xfbe08000, "rsb%20's\t%8-11r, %16-19r, %M"}, 1038 {ARM_EXT_V6T2, 0xe8800000, 0xffd00000, "stmia.w\t%16-19r%21'!, %m"}, 1039 {ARM_EXT_V6T2, 0xe8900000, 0xffd00000, "ldmia.w\t%16-19r%21'!, %m"}, 1040 {ARM_EXT_V6T2, 0xe9000000, 0xffd00000, "stmdb\t%16-19r%21'!, %m"}, 1041 {ARM_EXT_V6T2, 0xe9100000, 0xffd00000, "ldmdb\t%16-19r%21'!, %m"}, 1042 {ARM_EXT_V6T2, 0xe9c00000, 0xffd000ff, "strd\t%12-15r, %8-11r, [%16-19r]"}, 1043 {ARM_EXT_V6T2, 0xe9d00000, 0xffd000ff, "ldrd\t%12-15r, %8-11r, [%16-19r]"}, 1044 {ARM_EXT_V6T2, 0xe9400000, 0xff500000, "strd\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]"}, 1045 {ARM_EXT_V6T2, 0xe9500000, 0xff500000, "ldrd\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]"}, 1046 {ARM_EXT_V6T2, 0xf8000000, 0xff100000, "str%w.w\t%12-15r, %a"}, 1047 {ARM_EXT_V6T2, 0xf8100000, 0xfe100000, "ldr%w.w\t%12-15r, %a"}, 1048 1049 /* Filter out Bcc with cond=E or F, which are used for other instructions. */ 1050 {ARM_EXT_V6T2, 0xf3c08000, 0xfbc0d000, "undefined (bcc, cond=0xF)"}, 1051 {ARM_EXT_V6T2, 0xf3808000, 0xfbc0d000, "undefined (bcc, cond=0xE)"}, 1052 {ARM_EXT_V6T2, 0xf0008000, 0xf800d000, "b%22-25c.w\t%b"}, 1053 {ARM_EXT_V6T2, 0xf0009000, 0xf800d000, "b.w\t%B"}, 1054 1055 /* These have been 32-bit since the invention of Thumb. */ 1056 {ARM_EXT_V4T, 0xf000c000, 0xf800d000, "blx\t%B"}, 1057 {ARM_EXT_V4T, 0xf000d000, 0xf800d000, "bl\t%B"}, 1058 1059 /* Fallback. */ 1060 {ARM_EXT_V1, 0x00000000, 0x00000000, "undefined"}, 1061 {0, 0, 0, 0} 1062 }; 1063 1064 static const char *const arm_conditional[] = 1065 {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc", 1066 "hi", "ls", "ge", "lt", "gt", "le", "", "<und>"}; 1067 1068 static const char *const arm_fp_const[] = 1069 {"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"}; 1070 1071 static const char *const arm_shift[] = 1072 {"lsl", "lsr", "asr", "ror"}; 1073 1074 typedef struct 1075 { 1076 const char *name; 1077 const char *description; 1078 const char *reg_names[16]; 1079 } 1080 arm_regname; 1081 1082 static const arm_regname regnames[] = 1083 { 1084 { "raw" , "Select raw register names", 1085 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}}, 1086 { "gcc", "Select register names used by GCC", 1087 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc" }}, 1088 { "std", "Select register names used in ARM's ISA documentation", 1089 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc" }}, 1090 { "apcs", "Select register names used in the APCS", 1091 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "sl", "fp", "ip", "sp", "lr", "pc" }}, 1092 { "atpcs", "Select register names used in the ATPCS", 1093 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "IP", "SP", "LR", "PC" }}, 1094 { "special-atpcs", "Select special register names used in the ATPCS", 1095 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL", "FP", "IP", "SP", "LR", "PC" }}, 1096 }; 1097 1098 static const char *const iwmmxt_wwnames[] = 1099 {"b", "h", "w", "d"}; 1100 1101 static const char *const iwmmxt_wwssnames[] = 1102 {"b", "bus", "b", "bss", 1103 "h", "hus", "h", "hss", 1104 "w", "wus", "w", "wss", 1105 "d", "dus", "d", "dss" 1106 }; 1107 1108 static const char *const iwmmxt_regnames[] = 1109 { "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6", "wr7", 1110 "wr8", "wr9", "wr10", "wr11", "wr12", "wr13", "wr14", "wr15" 1111 }; 1112 1113 static const char *const iwmmxt_cregnames[] = 1114 { "wcid", "wcon", "wcssf", "wcasf", "reserved", "reserved", "reserved", "reserved", 1115 "wcgr0", "wcgr1", "wcgr2", "wcgr3", "reserved", "reserved", "reserved", "reserved" 1116 }; 1117 1118 /* Default to GCC register name set. */ 1119 static unsigned int regname_selected = 1; 1120 1121 #define NUM_ARM_REGNAMES NUM_ELEM (regnames) 1122 #define arm_regnames regnames[regname_selected].reg_names 1123 1124 static bfd_boolean force_thumb = FALSE; 1125 1126 1127 /* Functions. */ 1128 int 1129 get_arm_regname_num_options (void) 1130 { 1131 return NUM_ARM_REGNAMES; 1132 } 1133 1134 int 1135 set_arm_regname_option (int option) 1136 { 1137 int old = regname_selected; 1138 regname_selected = option; 1139 return old; 1140 } 1141 1142 int 1143 get_arm_regnames (int option, const char **setname, const char **setdescription, 1144 const char *const **register_names) 1145 { 1146 *setname = regnames[option].name; 1147 *setdescription = regnames[option].description; 1148 *register_names = regnames[option].reg_names; 1149 return 16; 1150 } 1151 1152 static void 1153 arm_decode_shift (long given, fprintf_ftype func, void *stream) 1154 { 1155 func (stream, "%s", arm_regnames[given & 0xf]); 1156 1157 if ((given & 0xff0) != 0) 1158 { 1159 if ((given & 0x10) == 0) 1160 { 1161 int amount = (given & 0xf80) >> 7; 1162 int shift = (given & 0x60) >> 5; 1163 1164 if (amount == 0) 1165 { 1166 if (shift == 3) 1167 { 1168 func (stream, ", rrx"); 1169 return; 1170 } 1171 1172 amount = 32; 1173 } 1174 1175 func (stream, ", %s #%d", arm_shift[shift], amount); 1176 } 1177 else 1178 func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5], 1179 arm_regnames[(given & 0xf00) >> 8]); 1180 } 1181 } 1182 1183 /* Print one coprocessor instruction on INFO->STREAM. 1184 Return TRUE if the instuction matched, FALSE if this is not a 1185 recognised coprocessor instruction. */ 1186 1187 static bfd_boolean 1188 print_insn_coprocessor (struct disassemble_info *info, long given, 1189 bfd_boolean thumb) 1190 { 1191 const struct opcode32 *insn; 1192 void *stream = info->stream; 1193 fprintf_ftype func = info->fprintf_func; 1194 unsigned long mask; 1195 unsigned long value; 1196 1197 for (insn = coprocessor_opcodes; insn->assembler; insn++) 1198 { 1199 if (insn->value == FIRST_IWMMXT_INSN 1200 && info->mach != bfd_mach_arm_XScale 1201 && info->mach != bfd_mach_arm_iWMMXt) 1202 insn = insn + IWMMXT_INSN_COUNT; 1203 1204 mask = insn->mask; 1205 value = insn->value; 1206 if (thumb) 1207 { 1208 /* The high 4 bits are 0xe for Arm conditional instructions, and 1209 0xe for arm unconditional instructions. The rest of the 1210 encoding is the same. */ 1211 mask |= 0xf0000000; 1212 value |= 0xe0000000; 1213 } 1214 else 1215 { 1216 /* Only match unconditional instuctions against unconditional 1217 patterns. */ 1218 if ((given & 0xf0000000) == 0xf0000000) 1219 mask |= 0xf0000000; 1220 } 1221 if ((given & mask) == value) 1222 { 1223 const char *c; 1224 1225 for (c = insn->assembler; *c; c++) 1226 { 1227 if (*c == '%') 1228 { 1229 switch (*++c) 1230 { 1231 case '%': 1232 func (stream, "%%"); 1233 break; 1234 1235 case 'A': 1236 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]); 1237 1238 if ((given & (1 << 24)) != 0) 1239 { 1240 int offset = given & 0xff; 1241 1242 if (offset) 1243 func (stream, ", #%s%d]%s", 1244 ((given & 0x00800000) == 0 ? "-" : ""), 1245 offset * 4, 1246 ((given & 0x00200000) != 0 ? "!" : "")); 1247 else 1248 func (stream, "]"); 1249 } 1250 else 1251 { 1252 int offset = given & 0xff; 1253 1254 func (stream, "]"); 1255 1256 if (given & (1 << 21)) 1257 { 1258 if (offset) 1259 func (stream, ", #%s%d", 1260 ((given & 0x00800000) == 0 ? "-" : ""), 1261 offset * 4); 1262 } 1263 else 1264 func (stream, ", {%d}", offset); 1265 } 1266 break; 1267 1268 case 'c': 1269 func (stream, "%s", 1270 arm_conditional [(given >> 28) & 0xf]); 1271 break; 1272 1273 case 'I': 1274 /* Print a Cirrus/DSP shift immediate. */ 1275 /* Immediates are 7bit signed ints with bits 0..3 in 1276 bits 0..3 of opcode and bits 4..6 in bits 5..7 1277 of opcode. */ 1278 { 1279 int imm; 1280 1281 imm = (given & 0xf) | ((given & 0xe0) >> 1); 1282 1283 /* Is ``imm'' a negative number? */ 1284 if (imm & 0x40) 1285 imm |= (-1 << 7); 1286 1287 func (stream, "%d", imm); 1288 } 1289 1290 break; 1291 1292 case 'F': 1293 switch (given & 0x00408000) 1294 { 1295 case 0: 1296 func (stream, "4"); 1297 break; 1298 case 0x8000: 1299 func (stream, "1"); 1300 break; 1301 case 0x00400000: 1302 func (stream, "2"); 1303 break; 1304 default: 1305 func (stream, "3"); 1306 } 1307 break; 1308 1309 case 'P': 1310 switch (given & 0x00080080) 1311 { 1312 case 0: 1313 func (stream, "s"); 1314 break; 1315 case 0x80: 1316 func (stream, "d"); 1317 break; 1318 case 0x00080000: 1319 func (stream, "e"); 1320 break; 1321 default: 1322 func (stream, _("<illegal precision>")); 1323 break; 1324 } 1325 break; 1326 case 'Q': 1327 switch (given & 0x00408000) 1328 { 1329 case 0: 1330 func (stream, "s"); 1331 break; 1332 case 0x8000: 1333 func (stream, "d"); 1334 break; 1335 case 0x00400000: 1336 func (stream, "e"); 1337 break; 1338 default: 1339 func (stream, "p"); 1340 break; 1341 } 1342 break; 1343 case 'R': 1344 switch (given & 0x60) 1345 { 1346 case 0: 1347 break; 1348 case 0x20: 1349 func (stream, "p"); 1350 break; 1351 case 0x40: 1352 func (stream, "m"); 1353 break; 1354 default: 1355 func (stream, "z"); 1356 break; 1357 } 1358 break; 1359 1360 case '0': case '1': case '2': case '3': case '4': 1361 case '5': case '6': case '7': case '8': case '9': 1362 { 1363 int bitstart = *c++ - '0'; 1364 int bitend = 0; 1365 while (*c >= '0' && *c <= '9') 1366 bitstart = (bitstart * 10) + *c++ - '0'; 1367 1368 switch (*c) 1369 { 1370 case '-': 1371 c++; 1372 1373 while (*c >= '0' && *c <= '9') 1374 bitend = (bitend * 10) + *c++ - '0'; 1375 1376 if (!bitend) 1377 abort (); 1378 1379 switch (*c) 1380 { 1381 case 'r': 1382 { 1383 long reg; 1384 1385 reg = given >> bitstart; 1386 reg &= (2 << (bitend - bitstart)) - 1; 1387 1388 func (stream, "%s", arm_regnames[reg]); 1389 } 1390 break; 1391 case 'd': 1392 { 1393 long reg; 1394 1395 reg = given >> bitstart; 1396 reg &= (2 << (bitend - bitstart)) - 1; 1397 1398 func (stream, "%ld", reg); 1399 } 1400 break; 1401 case 'f': 1402 { 1403 long reg; 1404 1405 reg = given >> bitstart; 1406 reg &= (2 << (bitend - bitstart)) - 1; 1407 1408 if (reg > 7) 1409 func (stream, "#%s", 1410 arm_fp_const[reg & 7]); 1411 else 1412 func (stream, "f%ld", reg); 1413 } 1414 break; 1415 1416 case 'w': 1417 { 1418 long reg; 1419 1420 if (bitstart != bitend) 1421 { 1422 reg = given >> bitstart; 1423 reg &= (2 << (bitend - bitstart)) - 1; 1424 if (bitend - bitstart == 1) 1425 func (stream, "%s", iwmmxt_wwnames[reg]); 1426 else 1427 func (stream, "%s", iwmmxt_wwssnames[reg]); 1428 } 1429 else 1430 { 1431 reg = (((given >> 8) & 0x1) | 1432 ((given >> 22) & 0x1)); 1433 func (stream, "%s", iwmmxt_wwnames[reg]); 1434 } 1435 } 1436 break; 1437 1438 case 'g': 1439 { 1440 long reg; 1441 reg = given >> bitstart; 1442 reg &= (2 << (bitend - bitstart)) - 1; 1443 func (stream, "%s", iwmmxt_regnames[reg]); 1444 } 1445 break; 1446 1447 case 'G': 1448 { 1449 long reg; 1450 reg = given >> bitstart; 1451 reg &= (2 << (bitend - bitstart)) - 1; 1452 func (stream, "%s", iwmmxt_cregnames[reg]); 1453 } 1454 break; 1455 1456 default: 1457 abort (); 1458 } 1459 break; 1460 1461 case 'y': 1462 case 'z': 1463 { 1464 int single = *c == 'y'; 1465 int regno; 1466 1467 switch (bitstart) 1468 { 1469 case 4: /* Sm pair */ 1470 func (stream, "{"); 1471 /* Fall through. */ 1472 case 0: /* Sm, Dm */ 1473 regno = given & 0x0000000f; 1474 if (single) 1475 { 1476 regno <<= 1; 1477 regno += (given >> 5) & 1; 1478 } 1479 break; 1480 1481 case 1: /* Sd, Dd */ 1482 regno = (given >> 12) & 0x0000000f; 1483 if (single) 1484 { 1485 regno <<= 1; 1486 regno += (given >> 22) & 1; 1487 } 1488 break; 1489 1490 case 2: /* Sn, Dn */ 1491 regno = (given >> 16) & 0x0000000f; 1492 if (single) 1493 { 1494 regno <<= 1; 1495 regno += (given >> 7) & 1; 1496 } 1497 break; 1498 1499 case 3: /* List */ 1500 func (stream, "{"); 1501 regno = (given >> 12) & 0x0000000f; 1502 if (single) 1503 { 1504 regno <<= 1; 1505 regno += (given >> 22) & 1; 1506 } 1507 break; 1508 1509 1510 default: 1511 abort (); 1512 } 1513 1514 func (stream, "%c%d", single ? 's' : 'd', regno); 1515 1516 if (bitstart == 3) 1517 { 1518 int count = given & 0xff; 1519 1520 if (single == 0) 1521 count >>= 1; 1522 1523 if (--count) 1524 { 1525 func (stream, "-%c%d", 1526 single ? 's' : 'd', 1527 regno + count); 1528 } 1529 1530 func (stream, "}"); 1531 } 1532 else if (bitstart == 4) 1533 func (stream, ", %c%d}", single ? 's' : 'd', 1534 regno + 1); 1535 1536 break; 1537 } 1538 1539 break; 1540 1541 case '`': 1542 c++; 1543 if ((given & (1 << bitstart)) == 0) 1544 func (stream, "%c", *c); 1545 break; 1546 case '\'': 1547 c++; 1548 if ((given & (1 << bitstart)) != 0) 1549 func (stream, "%c", *c); 1550 break; 1551 case '?': 1552 ++c; 1553 if ((given & (1 << bitstart)) != 0) 1554 func (stream, "%c", *c++); 1555 else 1556 func (stream, "%c", *++c); 1557 break; 1558 default: 1559 abort (); 1560 } 1561 break; 1562 1563 case 'L': 1564 switch (given & 0x00400100) 1565 { 1566 case 0x00000000: func (stream, "b"); break; 1567 case 0x00400000: func (stream, "h"); break; 1568 case 0x00000100: func (stream, "w"); break; 1569 case 0x00400100: func (stream, "d"); break; 1570 default: 1571 break; 1572 } 1573 break; 1574 1575 case 'Z': 1576 { 1577 int value; 1578 /* given (20, 23) | given (0, 3) */ 1579 value = ((given >> 16) & 0xf0) | (given & 0xf); 1580 func (stream, "%d", value); 1581 } 1582 break; 1583 1584 case 'l': 1585 /* This is like the 'A' operator, except that if 1586 the width field "M" is zero, then the offset is 1587 *not* multiplied by four. */ 1588 { 1589 int offset = given & 0xff; 1590 int multiplier = (given & 0x00000100) ? 4 : 1; 1591 1592 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]); 1593 1594 if (offset) 1595 { 1596 if ((given & 0x01000000) != 0) 1597 func (stream, ", #%s%d]%s", 1598 ((given & 0x00800000) == 0 ? "-" : ""), 1599 offset * multiplier, 1600 ((given & 0x00200000) != 0 ? "!" : "")); 1601 else 1602 func (stream, "], #%s%d", 1603 ((given & 0x00800000) == 0 ? "-" : ""), 1604 offset * multiplier); 1605 } 1606 else 1607 func (stream, "]"); 1608 } 1609 break; 1610 1611 default: 1612 abort (); 1613 } 1614 } 1615 } 1616 else 1617 func (stream, "%c", *c); 1618 } 1619 return TRUE; 1620 } 1621 } 1622 return FALSE; 1623 } 1624 1625 static void 1626 print_arm_address (bfd_vma pc, struct disassemble_info *info, long given) 1627 { 1628 void *stream = info->stream; 1629 fprintf_ftype func = info->fprintf_func; 1630 1631 if (((given & 0x000f0000) == 0x000f0000) 1632 && ((given & 0x02000000) == 0)) 1633 { 1634 int offset = given & 0xfff; 1635 1636 func (stream, "[pc"); 1637 1638 if (given & 0x01000000) 1639 { 1640 if ((given & 0x00800000) == 0) 1641 offset = - offset; 1642 1643 /* Pre-indexed. */ 1644 func (stream, ", #%d]", offset); 1645 1646 offset += pc + 8; 1647 1648 /* Cope with the possibility of write-back 1649 being used. Probably a very dangerous thing 1650 for the programmer to do, but who are we to 1651 argue ? */ 1652 if (given & 0x00200000) 1653 func (stream, "!"); 1654 } 1655 else 1656 { 1657 /* Post indexed. */ 1658 func (stream, "], #%d", offset); 1659 1660 /* ie ignore the offset. */ 1661 offset = pc + 8; 1662 } 1663 1664 func (stream, "\t; "); 1665 info->print_address_func (offset, info); 1666 } 1667 else 1668 { 1669 func (stream, "[%s", 1670 arm_regnames[(given >> 16) & 0xf]); 1671 if ((given & 0x01000000) != 0) 1672 { 1673 if ((given & 0x02000000) == 0) 1674 { 1675 int offset = given & 0xfff; 1676 if (offset) 1677 func (stream, ", #%s%d", 1678 (((given & 0x00800000) == 0) 1679 ? "-" : ""), offset); 1680 } 1681 else 1682 { 1683 func (stream, ", %s", 1684 (((given & 0x00800000) == 0) 1685 ? "-" : "")); 1686 arm_decode_shift (given, func, stream); 1687 } 1688 1689 func (stream, "]%s", 1690 ((given & 0x00200000) != 0) ? "!" : ""); 1691 } 1692 else 1693 { 1694 if ((given & 0x02000000) == 0) 1695 { 1696 int offset = given & 0xfff; 1697 if (offset) 1698 func (stream, "], #%s%d", 1699 (((given & 0x00800000) == 0) 1700 ? "-" : ""), offset); 1701 else 1702 func (stream, "]"); 1703 } 1704 else 1705 { 1706 func (stream, "], %s", 1707 (((given & 0x00800000) == 0) 1708 ? "-" : "")); 1709 arm_decode_shift (given, func, stream); 1710 } 1711 } 1712 } 1713 } 1714 1715 /* Print one ARM instruction from PC on INFO->STREAM. */ 1716 1717 static void 1718 print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given) 1719 { 1720 const struct opcode32 *insn; 1721 void *stream = info->stream; 1722 fprintf_ftype func = info->fprintf_func; 1723 1724 if (print_insn_coprocessor (info, given, FALSE)) 1725 return; 1726 1727 for (insn = arm_opcodes; insn->assembler; insn++) 1728 { 1729 if (insn->value == FIRST_IWMMXT_INSN 1730 && info->mach != bfd_mach_arm_XScale 1731 && info->mach != bfd_mach_arm_iWMMXt) 1732 insn = insn + IWMMXT_INSN_COUNT; 1733 1734 if ((given & insn->mask) == insn->value 1735 /* Special case: an instruction with all bits set in the condition field 1736 (0xFnnn_nnnn) is only matched if all those bits are set in insn->mask, 1737 or by the catchall at the end of the table. */ 1738 && ((given & 0xF0000000) != 0xF0000000 1739 || (insn->mask & 0xF0000000) == 0xF0000000 1740 || (insn->mask == 0 && insn->value == 0))) 1741 { 1742 const char *c; 1743 1744 for (c = insn->assembler; *c; c++) 1745 { 1746 if (*c == '%') 1747 { 1748 switch (*++c) 1749 { 1750 case '%': 1751 func (stream, "%%"); 1752 break; 1753 1754 case 'a': 1755 print_arm_address (pc, info, given); 1756 break; 1757 1758 case 'P': 1759 /* Set P address bit and use normal address 1760 printing routine. */ 1761 print_arm_address (pc, info, given | (1 << 24)); 1762 break; 1763 1764 case 's': 1765 if ((given & 0x004f0000) == 0x004f0000) 1766 { 1767 /* PC relative with immediate offset. */ 1768 int offset = ((given & 0xf00) >> 4) | (given & 0xf); 1769 1770 if ((given & 0x00800000) == 0) 1771 offset = -offset; 1772 1773 func (stream, "[pc, #%d]\t; ", offset); 1774 info->print_address_func (offset + pc + 8, info); 1775 } 1776 else 1777 { 1778 func (stream, "[%s", 1779 arm_regnames[(given >> 16) & 0xf]); 1780 if ((given & 0x01000000) != 0) 1781 { 1782 /* Pre-indexed. */ 1783 if ((given & 0x00400000) == 0x00400000) 1784 { 1785 /* Immediate. */ 1786 int offset = ((given & 0xf00) >> 4) | (given & 0xf); 1787 if (offset) 1788 func (stream, ", #%s%d", 1789 (((given & 0x00800000) == 0) 1790 ? "-" : ""), offset); 1791 } 1792 else 1793 { 1794 /* Register. */ 1795 func (stream, ", %s%s", 1796 (((given & 0x00800000) == 0) 1797 ? "-" : ""), 1798 arm_regnames[given & 0xf]); 1799 } 1800 1801 func (stream, "]%s", 1802 ((given & 0x00200000) != 0) ? "!" : ""); 1803 } 1804 else 1805 { 1806 /* Post-indexed. */ 1807 if ((given & 0x00400000) == 0x00400000) 1808 { 1809 /* Immediate. */ 1810 int offset = ((given & 0xf00) >> 4) | (given & 0xf); 1811 if (offset) 1812 func (stream, "], #%s%d", 1813 (((given & 0x00800000) == 0) 1814 ? "-" : ""), offset); 1815 else 1816 func (stream, "]"); 1817 } 1818 else 1819 { 1820 /* Register. */ 1821 func (stream, "], %s%s", 1822 (((given & 0x00800000) == 0) 1823 ? "-" : ""), 1824 arm_regnames[given & 0xf]); 1825 } 1826 } 1827 } 1828 break; 1829 1830 case 'b': 1831 { 1832 int disp = (((given & 0xffffff) ^ 0x800000) - 0x800000); 1833 info->print_address_func (disp*4 + pc + 8, info); 1834 } 1835 break; 1836 1837 case 'c': 1838 func (stream, "%s", 1839 arm_conditional [(given >> 28) & 0xf]); 1840 break; 1841 1842 case 'm': 1843 { 1844 int started = 0; 1845 int reg; 1846 1847 func (stream, "{"); 1848 for (reg = 0; reg < 16; reg++) 1849 if ((given & (1 << reg)) != 0) 1850 { 1851 if (started) 1852 func (stream, ", "); 1853 started = 1; 1854 func (stream, "%s", arm_regnames[reg]); 1855 } 1856 func (stream, "}"); 1857 } 1858 break; 1859 1860 case 'o': 1861 if ((given & 0x02000000) != 0) 1862 { 1863 int rotate = (given & 0xf00) >> 7; 1864 int immed = (given & 0xff); 1865 immed = (((immed << (32 - rotate)) 1866 | (immed >> rotate)) & 0xffffffff); 1867 func (stream, "#%d\t; 0x%x", immed, immed); 1868 } 1869 else 1870 arm_decode_shift (given, func, stream); 1871 break; 1872 1873 case 'p': 1874 if ((given & 0x0000f000) == 0x0000f000) 1875 func (stream, "p"); 1876 break; 1877 1878 case 't': 1879 if ((given & 0x01200000) == 0x00200000) 1880 func (stream, "t"); 1881 break; 1882 1883 case 'A': 1884 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]); 1885 1886 if ((given & (1 << 24)) != 0) 1887 { 1888 int offset = given & 0xff; 1889 1890 if (offset) 1891 func (stream, ", #%s%d]%s", 1892 ((given & 0x00800000) == 0 ? "-" : ""), 1893 offset * 4, 1894 ((given & 0x00200000) != 0 ? "!" : "")); 1895 else 1896 func (stream, "]"); 1897 } 1898 else 1899 { 1900 int offset = given & 0xff; 1901 1902 func (stream, "]"); 1903 1904 if (given & (1 << 21)) 1905 { 1906 if (offset) 1907 func (stream, ", #%s%d", 1908 ((given & 0x00800000) == 0 ? "-" : ""), 1909 offset * 4); 1910 } 1911 else 1912 func (stream, ", {%d}", offset); 1913 } 1914 break; 1915 1916 case 'B': 1917 /* Print ARM V5 BLX(1) address: pc+25 bits. */ 1918 { 1919 bfd_vma address; 1920 bfd_vma offset = 0; 1921 1922 if (given & 0x00800000) 1923 /* Is signed, hi bits should be ones. */ 1924 offset = (-1) ^ 0x00ffffff; 1925 1926 /* Offset is (SignExtend(offset field)<<2). */ 1927 offset += given & 0x00ffffff; 1928 offset <<= 2; 1929 address = offset + pc + 8; 1930 1931 if (given & 0x01000000) 1932 /* H bit allows addressing to 2-byte boundaries. */ 1933 address += 2; 1934 1935 info->print_address_func (address, info); 1936 } 1937 break; 1938 1939 case 'C': 1940 func (stream, "_"); 1941 if (given & 0x80000) 1942 func (stream, "f"); 1943 if (given & 0x40000) 1944 func (stream, "s"); 1945 if (given & 0x20000) 1946 func (stream, "x"); 1947 if (given & 0x10000) 1948 func (stream, "c"); 1949 break; 1950 1951 case 'U': 1952 switch (given & 0xf) 1953 { 1954 case 0xf: func(stream, "sy"); break; 1955 case 0x7: func(stream, "un"); break; 1956 case 0xe: func(stream, "st"); break; 1957 case 0x6: func(stream, "unst"); break; 1958 default: 1959 func(stream, "#%d", (int)given & 0xf); 1960 break; 1961 } 1962 break; 1963 1964 case '0': case '1': case '2': case '3': case '4': 1965 case '5': case '6': case '7': case '8': case '9': 1966 { 1967 int bitstart = *c++ - '0'; 1968 int bitend = 0; 1969 while (*c >= '0' && *c <= '9') 1970 bitstart = (bitstart * 10) + *c++ - '0'; 1971 1972 switch (*c) 1973 { 1974 case '-': 1975 c++; 1976 1977 while (*c >= '0' && *c <= '9') 1978 bitend = (bitend * 10) + *c++ - '0'; 1979 1980 if (!bitend) 1981 abort (); 1982 1983 switch (*c) 1984 { 1985 case 'r': 1986 { 1987 long reg; 1988 1989 reg = given >> bitstart; 1990 reg &= (2 << (bitend - bitstart)) - 1; 1991 1992 func (stream, "%s", arm_regnames[reg]); 1993 } 1994 break; 1995 case 'd': 1996 { 1997 long reg; 1998 1999 reg = given >> bitstart; 2000 reg &= (2 << (bitend - bitstart)) - 1; 2001 2002 func (stream, "%ld", reg); 2003 } 2004 break; 2005 case 'W': 2006 { 2007 long reg; 2008 2009 reg = given >> bitstart; 2010 reg &= (2 << (bitend - bitstart)) - 1; 2011 2012 func (stream, "%ld", reg + 1); 2013 } 2014 break; 2015 case 'x': 2016 { 2017 long reg; 2018 2019 reg = given >> bitstart; 2020 reg &= (2 << (bitend - bitstart)) - 1; 2021 2022 func (stream, "0x%08lx", reg); 2023 2024 /* Some SWI instructions have special 2025 meanings. */ 2026 if ((given & 0x0fffffff) == 0x0FF00000) 2027 func (stream, "\t; IMB"); 2028 else if ((given & 0x0fffffff) == 0x0FF00001) 2029 func (stream, "\t; IMBRange"); 2030 } 2031 break; 2032 case 'X': 2033 { 2034 long reg; 2035 2036 reg = given >> bitstart; 2037 reg &= (2 << (bitend - bitstart)) - 1; 2038 2039 func (stream, "%01lx", reg & 0xf); 2040 } 2041 break; 2042 default: 2043 abort (); 2044 } 2045 break; 2046 2047 case '`': 2048 c++; 2049 if ((given & (1 << bitstart)) == 0) 2050 func (stream, "%c", *c); 2051 break; 2052 case '\'': 2053 c++; 2054 if ((given & (1 << bitstart)) != 0) 2055 func (stream, "%c", *c); 2056 break; 2057 case '?': 2058 ++c; 2059 if ((given & (1 << bitstart)) != 0) 2060 func (stream, "%c", *c++); 2061 else 2062 func (stream, "%c", *++c); 2063 break; 2064 default: 2065 abort (); 2066 } 2067 break; 2068 2069 case 'e': 2070 { 2071 int imm; 2072 2073 imm = (given & 0xf) | ((given & 0xfff00) >> 4); 2074 func (stream, "%d", imm); 2075 } 2076 break; 2077 2078 case 'E': 2079 /* LSB and WIDTH fields of BFI or BFC. The machine- 2080 language instruction encodes LSB and MSB. */ 2081 { 2082 long msb = (given & 0x001f0000) >> 16; 2083 long lsb = (given & 0x00000f80) >> 7; 2084 2085 long width = msb - lsb + 1; 2086 if (width > 0) 2087 func (stream, "#%lu, #%lu", lsb, width); 2088 else 2089 func (stream, "(invalid: %lu:%lu)", lsb, msb); 2090 } 2091 break; 2092 2093 case 'V': 2094 /* 16-bit unsigned immediate from a MOVT or MOVW 2095 instruction, encoded in bits 0:11 and 15:19. */ 2096 { 2097 long hi = (given & 0x000f0000) >> 4; 2098 long lo = (given & 0x00000fff); 2099 long imm16 = hi | lo; 2100 func (stream, "#%lu\t; 0x%lx", imm16, imm16); 2101 } 2102 break; 2103 2104 default: 2105 abort (); 2106 } 2107 } 2108 } 2109 else 2110 func (stream, "%c", *c); 2111 } 2112 return; 2113 } 2114 } 2115 abort (); 2116 } 2117 2118 /* Print one 16-bit Thumb instruction from PC on INFO->STREAM. */ 2119 2120 static void 2121 print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given) 2122 { 2123 const struct opcode16 *insn; 2124 void *stream = info->stream; 2125 fprintf_ftype func = info->fprintf_func; 2126 2127 for (insn = thumb_opcodes; insn->assembler; insn++) 2128 if ((given & insn->mask) == insn->value) 2129 { 2130 const char *c = insn->assembler; 2131 for (; *c; c++) 2132 { 2133 int domaskpc = 0; 2134 int domasklr = 0; 2135 2136 if (*c != '%') 2137 { 2138 func (stream, "%c", *c); 2139 continue; 2140 } 2141 2142 switch (*++c) 2143 { 2144 case '%': 2145 func (stream, "%%"); 2146 break; 2147 2148 case 'S': 2149 { 2150 long reg; 2151 2152 reg = (given >> 3) & 0x7; 2153 if (given & (1 << 6)) 2154 reg += 8; 2155 2156 func (stream, "%s", arm_regnames[reg]); 2157 } 2158 break; 2159 2160 case 'D': 2161 { 2162 long reg; 2163 2164 reg = given & 0x7; 2165 if (given & (1 << 7)) 2166 reg += 8; 2167 2168 func (stream, "%s", arm_regnames[reg]); 2169 } 2170 break; 2171 2172 case 'N': 2173 if (given & (1 << 8)) 2174 domasklr = 1; 2175 /* Fall through. */ 2176 case 'O': 2177 if (*c == 'O' && (given & (1 << 8))) 2178 domaskpc = 1; 2179 /* Fall through. */ 2180 case 'M': 2181 { 2182 int started = 0; 2183 int reg; 2184 2185 func (stream, "{"); 2186 2187 /* It would be nice if we could spot 2188 ranges, and generate the rS-rE format: */ 2189 for (reg = 0; (reg < 8); reg++) 2190 if ((given & (1 << reg)) != 0) 2191 { 2192 if (started) 2193 func (stream, ", "); 2194 started = 1; 2195 func (stream, "%s", arm_regnames[reg]); 2196 } 2197 2198 if (domasklr) 2199 { 2200 if (started) 2201 func (stream, ", "); 2202 started = 1; 2203 func (stream, arm_regnames[14] /* "lr" */); 2204 } 2205 2206 if (domaskpc) 2207 { 2208 if (started) 2209 func (stream, ", "); 2210 func (stream, arm_regnames[15] /* "pc" */); 2211 } 2212 2213 func (stream, "}"); 2214 } 2215 break; 2216 2217 case 'b': 2218 /* Print ARM V6T2 CZB address: pc+4+6 bits. */ 2219 { 2220 bfd_vma address = (pc + 4 2221 + ((given & 0x00f8) >> 2) 2222 + ((given & 0x0200) >> 3)); 2223 info->print_address_func (address, info); 2224 } 2225 break; 2226 2227 case 's': 2228 /* Right shift immediate -- bits 6..10; 1-31 print 2229 as themselves, 0 prints as 32. */ 2230 { 2231 long imm = (given & 0x07c0) >> 6; 2232 if (imm == 0) 2233 imm = 32; 2234 func (stream, "#%ld", imm); 2235 } 2236 break; 2237 2238 case '0': case '1': case '2': case '3': case '4': 2239 case '5': case '6': case '7': case '8': case '9': 2240 { 2241 int bitstart = *c++ - '0'; 2242 int bitend = 0; 2243 2244 while (*c >= '0' && *c <= '9') 2245 bitstart = (bitstart * 10) + *c++ - '0'; 2246 2247 switch (*c) 2248 { 2249 case '-': 2250 { 2251 long reg; 2252 2253 c++; 2254 while (*c >= '0' && *c <= '9') 2255 bitend = (bitend * 10) + *c++ - '0'; 2256 if (!bitend) 2257 abort (); 2258 reg = given >> bitstart; 2259 reg &= (2 << (bitend - bitstart)) - 1; 2260 switch (*c) 2261 { 2262 case 'r': 2263 func (stream, "%s", arm_regnames[reg]); 2264 break; 2265 2266 case 'd': 2267 func (stream, "%ld", reg); 2268 break; 2269 2270 case 'H': 2271 func (stream, "%ld", reg << 1); 2272 break; 2273 2274 case 'W': 2275 func (stream, "%ld", reg << 2); 2276 break; 2277 2278 case 'a': 2279 /* PC-relative address -- the bottom two 2280 bits of the address are dropped 2281 before the calculation. */ 2282 info->print_address_func 2283 (((pc + 4) & ~3) + (reg << 2), info); 2284 break; 2285 2286 case 'x': 2287 func (stream, "0x%04lx", reg); 2288 break; 2289 2290 case 'B': 2291 reg = ((reg ^ (1 << bitend)) - (1 << bitend)); 2292 info->print_address_func (reg * 2 + pc + 4, info); 2293 break; 2294 2295 case 'c': 2296 { 2297 /* Must print 0xE as 'al' to distinguish 2298 unconditional B from conditional BAL. */ 2299 if (reg == 0xE) 2300 func (stream, "al"); 2301 else 2302 func (stream, "%s", arm_conditional [reg]); 2303 } 2304 break; 2305 2306 default: 2307 abort (); 2308 } 2309 } 2310 break; 2311 2312 case '\'': 2313 c++; 2314 if ((given & (1 << bitstart)) != 0) 2315 func (stream, "%c", *c); 2316 break; 2317 2318 case '?': 2319 ++c; 2320 if ((given & (1 << bitstart)) != 0) 2321 func (stream, "%c", *c++); 2322 else 2323 func (stream, "%c", *++c); 2324 break; 2325 2326 default: 2327 abort (); 2328 } 2329 } 2330 break; 2331 2332 default: 2333 abort (); 2334 } 2335 } 2336 return; 2337 } 2338 2339 /* No match. */ 2340 abort (); 2341 } 2342 2343 /* Return the name of an V7M special register. */ 2344 static const char * 2345 psr_name (int regno) 2346 { 2347 switch (regno) 2348 { 2349 case 0: return "APSR"; 2350 case 1: return "IAPSR"; 2351 case 2: return "EAPSR"; 2352 case 3: return "PSR"; 2353 case 5: return "IPSR"; 2354 case 6: return "EPSR"; 2355 case 7: return "IEPSR"; 2356 case 8: return "MSP"; 2357 case 9: return "PSP"; 2358 case 16: return "PRIMASK"; 2359 case 17: return "BASEPRI"; 2360 case 18: return "BASEPRI_MASK"; 2361 case 19: return "FAULTMASK"; 2362 case 20: return "CONTROL"; 2363 default: return "<unknown>"; 2364 } 2365 } 2366 2367 /* Print one 32-bit Thumb instruction from PC on INFO->STREAM. */ 2368 2369 static void 2370 print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given) 2371 { 2372 const struct opcode32 *insn; 2373 void *stream = info->stream; 2374 fprintf_ftype func = info->fprintf_func; 2375 2376 if (print_insn_coprocessor (info, given, TRUE)) 2377 return; 2378 2379 for (insn = thumb32_opcodes; insn->assembler; insn++) 2380 if ((given & insn->mask) == insn->value) 2381 { 2382 const char *c = insn->assembler; 2383 for (; *c; c++) 2384 { 2385 if (*c != '%') 2386 { 2387 func (stream, "%c", *c); 2388 continue; 2389 } 2390 2391 switch (*++c) 2392 { 2393 case '%': 2394 func (stream, "%%"); 2395 break; 2396 2397 case 'I': 2398 { 2399 unsigned int imm12 = 0; 2400 imm12 |= (given & 0x000000ffu); 2401 imm12 |= (given & 0x00007000u) >> 4; 2402 imm12 |= (given & 0x04000000u) >> 15; 2403 func (stream, "#%u\t; 0x%x", imm12, imm12); 2404 } 2405 break; 2406 2407 case 'M': 2408 { 2409 unsigned int bits = 0, imm, imm8, mod; 2410 bits |= (given & 0x000000ffu); 2411 bits |= (given & 0x00007000u) >> 4; 2412 bits |= (given & 0x04000000u) >> 15; 2413 imm8 = (bits & 0x0ff); 2414 mod = (bits & 0xf00) >> 8; 2415 switch (mod) 2416 { 2417 case 0: imm = imm8; break; 2418 case 1: imm = ((imm8<<16) | imm8); break; 2419 case 2: imm = ((imm8<<24) | (imm8 << 8)); break; 2420 case 3: imm = ((imm8<<24) | (imm8 << 16) | (imm8 << 8) | imm8); break; 2421 default: 2422 mod = (bits & 0xf80) >> 7; 2423 imm8 = (bits & 0x07f) | 0x80; 2424 imm = (((imm8 << (32 - mod)) | (imm8 >> mod)) & 0xffffffff); 2425 } 2426 func (stream, "#%u\t; 0x%x", imm, imm); 2427 } 2428 break; 2429 2430 case 'J': 2431 { 2432 unsigned int imm = 0; 2433 imm |= (given & 0x000000ffu); 2434 imm |= (given & 0x00007000u) >> 4; 2435 imm |= (given & 0x04000000u) >> 15; 2436 imm |= (given & 0x000f0000u) >> 4; 2437 func (stream, "#%u\t; 0x%x", imm, imm); 2438 } 2439 break; 2440 2441 case 'K': 2442 { 2443 unsigned int imm = 0; 2444 imm |= (given & 0x000f0000u) >> 16; 2445 imm |= (given & 0x00000ff0u) >> 0; 2446 imm |= (given & 0x0000000fu) << 12; 2447 func (stream, "#%u\t; 0x%x", imm, imm); 2448 } 2449 break; 2450 2451 case 'S': 2452 { 2453 unsigned int reg = (given & 0x0000000fu); 2454 unsigned int stp = (given & 0x00000030u) >> 4; 2455 unsigned int imm = 0; 2456 imm |= (given & 0x000000c0u) >> 6; 2457 imm |= (given & 0x00007000u) >> 10; 2458 2459 func (stream, "%s", arm_regnames[reg]); 2460 switch (stp) 2461 { 2462 case 0: 2463 if (imm > 0) 2464 func (stream, ", lsl #%u", imm); 2465 break; 2466 2467 case 1: 2468 if (imm == 0) 2469 imm = 32; 2470 func (stream, ", lsr #%u", imm); 2471 break; 2472 2473 case 2: 2474 if (imm == 0) 2475 imm = 32; 2476 func (stream, ", asr #%u", imm); 2477 break; 2478 2479 case 3: 2480 if (imm == 0) 2481 func (stream, ", rrx"); 2482 else 2483 func (stream, ", ror #%u", imm); 2484 } 2485 } 2486 break; 2487 2488 case 'a': 2489 { 2490 unsigned int Rn = (given & 0x000f0000) >> 16; 2491 unsigned int U = (given & 0x00800000) >> 23; 2492 unsigned int op = (given & 0x00000f00) >> 8; 2493 unsigned int i12 = (given & 0x00000fff); 2494 unsigned int i8 = (given & 0x000000ff); 2495 bfd_boolean writeback = FALSE, postind = FALSE; 2496 int offset = 0; 2497 2498 func (stream, "[%s", arm_regnames[Rn]); 2499 if (U) /* 12-bit positive immediate offset */ 2500 offset = i12; 2501 else if (Rn == 15) /* 12-bit negative immediate offset */ 2502 offset = -(int)i12; 2503 else if (op == 0x0) /* shifted register offset */ 2504 { 2505 unsigned int Rm = (i8 & 0x0f); 2506 unsigned int sh = (i8 & 0x30) >> 4; 2507 func (stream, ", %s", arm_regnames[Rm]); 2508 if (sh) 2509 func (stream, ", lsl #%u", sh); 2510 func (stream, "]"); 2511 break; 2512 } 2513 else switch (op) 2514 { 2515 case 0xE: /* 8-bit positive immediate offset */ 2516 offset = i8; 2517 break; 2518 2519 case 0xC: /* 8-bit negative immediate offset */ 2520 offset = -i8; 2521 break; 2522 2523 case 0xF: /* 8-bit + preindex with wb */ 2524 offset = i8; 2525 writeback = TRUE; 2526 break; 2527 2528 case 0xD: /* 8-bit - preindex with wb */ 2529 offset = -i8; 2530 writeback = TRUE; 2531 break; 2532 2533 case 0xB: /* 8-bit + postindex */ 2534 offset = i8; 2535 postind = TRUE; 2536 break; 2537 2538 case 0x9: /* 8-bit - postindex */ 2539 offset = -i8; 2540 postind = TRUE; 2541 break; 2542 2543 default: 2544 func (stream, ", <undefined>]"); 2545 goto skip; 2546 } 2547 2548 if (postind) 2549 func (stream, "], #%d", offset); 2550 else 2551 { 2552 if (offset) 2553 func (stream, ", #%d", offset); 2554 func (stream, writeback ? "]!" : "]"); 2555 } 2556 2557 if (Rn == 15) 2558 { 2559 func (stream, "\t; "); 2560 info->print_address_func (((pc + 4) & ~3) + offset, info); 2561 } 2562 } 2563 skip: 2564 break; 2565 2566 case 'A': 2567 { 2568 unsigned int P = (given & 0x01000000) >> 24; 2569 unsigned int U = (given & 0x00800000) >> 23; 2570 unsigned int W = (given & 0x00400000) >> 21; 2571 unsigned int Rn = (given & 0x000f0000) >> 16; 2572 unsigned int off = (given & 0x000000ff); 2573 2574 func (stream, "[%s", arm_regnames[Rn]); 2575 if (P) 2576 { 2577 if (off || !U) 2578 func (stream, ", #%c%u", U ? '+' : '-', off * 4); 2579 func (stream, "]"); 2580 if (W) 2581 func (stream, "!"); 2582 } 2583 else 2584 { 2585 func (stream, "], "); 2586 if (W) 2587 func (stream, "#%c%u", U ? '+' : '-', off * 4); 2588 else 2589 func (stream, "{%u}", off); 2590 } 2591 } 2592 break; 2593 2594 case 'w': 2595 { 2596 unsigned int Sbit = (given & 0x01000000) >> 24; 2597 unsigned int type = (given & 0x00600000) >> 21; 2598 switch (type) 2599 { 2600 case 0: func (stream, Sbit ? "sb" : "b"); break; 2601 case 1: func (stream, Sbit ? "sh" : "h"); break; 2602 case 2: 2603 if (Sbit) 2604 func (stream, "??"); 2605 break; 2606 case 3: 2607 func (stream, "??"); 2608 break; 2609 } 2610 } 2611 break; 2612 2613 case 'm': 2614 { 2615 int started = 0; 2616 int reg; 2617 2618 func (stream, "{"); 2619 for (reg = 0; reg < 16; reg++) 2620 if ((given & (1 << reg)) != 0) 2621 { 2622 if (started) 2623 func (stream, ", "); 2624 started = 1; 2625 func (stream, "%s", arm_regnames[reg]); 2626 } 2627 func (stream, "}"); 2628 } 2629 break; 2630 2631 case 'E': 2632 { 2633 unsigned int msb = (given & 0x0000001f); 2634 unsigned int lsb = 0; 2635 lsb |= (given & 0x000000c0u) >> 6; 2636 lsb |= (given & 0x00007000u) >> 10; 2637 func (stream, "#%u, #%u", lsb, msb - lsb + 1); 2638 } 2639 break; 2640 2641 case 'F': 2642 { 2643 unsigned int width = (given & 0x0000001f) + 1; 2644 unsigned int lsb = 0; 2645 lsb |= (given & 0x000000c0u) >> 6; 2646 lsb |= (given & 0x00007000u) >> 10; 2647 func (stream, "#%u, #%u", lsb, width); 2648 } 2649 break; 2650 2651 case 'b': 2652 { 2653 unsigned int S = (given & 0x04000000u) >> 26; 2654 unsigned int J1 = (given & 0x00002000u) >> 13; 2655 unsigned int J2 = (given & 0x00000800u) >> 11; 2656 int offset = 0; 2657 2658 offset |= !S << 20; 2659 offset |= J2 << 19; 2660 offset |= J1 << 18; 2661 offset |= (given & 0x003f0000) >> 4; 2662 offset |= (given & 0x000007ff) << 1; 2663 offset -= (1 << 20); 2664 2665 info->print_address_func (pc + 4 + offset, info); 2666 } 2667 break; 2668 2669 case 'B': 2670 { 2671 unsigned int S = (given & 0x04000000u) >> 26; 2672 unsigned int I1 = (given & 0x00002000u) >> 13; 2673 unsigned int I2 = (given & 0x00000800u) >> 11; 2674 int offset = 0; 2675 2676 offset |= !S << 24; 2677 offset |= !(I1 ^ S) << 23; 2678 offset |= !(I2 ^ S) << 22; 2679 offset |= (given & 0x03ff0000u) >> 4; 2680 offset |= (given & 0x000007ffu) << 1; 2681 offset -= (1 << 24); 2682 offset += pc + 4; 2683 2684 /* BLX target addresses are always word aligned. */ 2685 if ((given & 0x00001000u) == 0) 2686 offset &= ~2u; 2687 2688 info->print_address_func (offset, info); 2689 } 2690 break; 2691 2692 case 's': 2693 { 2694 unsigned int shift = 0; 2695 shift |= (given & 0x000000c0u) >> 6; 2696 shift |= (given & 0x00007000u) >> 10; 2697 if (given & 0x00200000u) 2698 func (stream, ", asr #%u", shift); 2699 else if (shift) 2700 func (stream, ", lsl #%u", shift); 2701 /* else print nothing - lsl #0 */ 2702 } 2703 break; 2704 2705 case 'R': 2706 { 2707 unsigned int rot = (given & 0x00000030) >> 4; 2708 if (rot) 2709 func (stream, ", ror #%u", rot * 8); 2710 } 2711 break; 2712 2713 case 'U': 2714 switch (given & 0xf) 2715 { 2716 case 0xf: func(stream, "sy"); break; 2717 case 0x7: func(stream, "un"); break; 2718 case 0xe: func(stream, "st"); break; 2719 case 0x6: func(stream, "unst"); break; 2720 default: 2721 func(stream, "#%d", (int)given & 0xf); 2722 break; 2723 } 2724 break; 2725 2726 case 'C': 2727 if ((given & 0xff) == 0) 2728 { 2729 func (stream, "%cPSR_", (given & 0x100000) ? 'S' : 'C'); 2730 if (given & 0x800) 2731 func (stream, "f"); 2732 if (given & 0x400) 2733 func (stream, "s"); 2734 if (given & 0x200) 2735 func (stream, "x"); 2736 if (given & 0x100) 2737 func (stream, "c"); 2738 } 2739 else 2740 { 2741 func (stream, psr_name (given & 0xff)); 2742 } 2743 break; 2744 2745 case 'D': 2746 if ((given & 0xff) == 0) 2747 func (stream, "%cPSR", (given & 0x100000) ? 'S' : 'C'); 2748 else 2749 func (stream, psr_name (given & 0xff)); 2750 break; 2751 2752 case '0': case '1': case '2': case '3': case '4': 2753 case '5': case '6': case '7': case '8': case '9': 2754 { 2755 int bitstart = *c++ - '0'; 2756 int bitend = 0; 2757 unsigned int val; 2758 while (*c >= '0' && *c <= '9') 2759 bitstart = (bitstart * 10) + *c++ - '0'; 2760 2761 if (*c == '-') 2762 { 2763 c++; 2764 while (*c >= '0' && *c <= '9') 2765 bitend = (bitend * 10) + *c++ - '0'; 2766 if (!bitend) 2767 abort (); 2768 2769 val = given >> bitstart; 2770 val &= (2 << (bitend - bitstart)) - 1; 2771 } 2772 else 2773 val = (given >> bitstart) & 1; 2774 2775 switch (*c) 2776 { 2777 case 'd': func (stream, "%u", val); break; 2778 case 'W': func (stream, "%u", val * 4); break; 2779 case 'r': func (stream, "%s", arm_regnames[val]); break; 2780 2781 case 'c': 2782 if (val == 0xE) 2783 func (stream, "al"); 2784 else 2785 func (stream, "%s", arm_conditional[val]); 2786 break; 2787 2788 case '\'': 2789 if (val) 2790 func (stream, "%c", c[1]); 2791 c++; 2792 break; 2793 2794 case '`': 2795 if (!val) 2796 func (stream, "%c", c[1]); 2797 c++; 2798 break; 2799 2800 case '?': 2801 func (stream, "%c", val ? c[1] : c[2]); 2802 c += 2; 2803 break; 2804 2805 default: 2806 abort (); 2807 } 2808 } 2809 break; 2810 2811 default: 2812 abort (); 2813 } 2814 } 2815 return; 2816 } 2817 2818 /* No match. */ 2819 abort (); 2820 } 2821 2822 /* Disallow mapping symbols ($a, $b, $d, $t etc) from 2823 being displayed in symbol relative addresses. */ 2824 2825 bfd_boolean 2826 arm_symbol_is_valid (asymbol * sym, 2827 struct disassemble_info * info ATTRIBUTE_UNUSED) 2828 { 2829 const char * name; 2830 2831 if (sym == NULL) 2832 return FALSE; 2833 2834 name = bfd_asymbol_name (sym); 2835 2836 return (name && *name != '$'); 2837 } 2838 2839 /* Parse an individual disassembler option. */ 2840 2841 void 2842 parse_arm_disassembler_option (char *option) 2843 { 2844 if (option == NULL) 2845 return; 2846 2847 if (strneq (option, "reg-names-", 10)) 2848 { 2849 int i; 2850 2851 option += 10; 2852 2853 for (i = NUM_ARM_REGNAMES; i--;) 2854 if (strneq (option, regnames[i].name, strlen (regnames[i].name))) 2855 { 2856 regname_selected = i; 2857 break; 2858 } 2859 2860 if (i < 0) 2861 /* XXX - should break 'option' at following delimiter. */ 2862 fprintf (stderr, _("Unrecognised register name set: %s\n"), option); 2863 } 2864 else if (strneq (option, "force-thumb", 11)) 2865 force_thumb = 1; 2866 else if (strneq (option, "no-force-thumb", 14)) 2867 force_thumb = 0; 2868 else 2869 /* XXX - should break 'option' at following delimiter. */ 2870 fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option); 2871 2872 return; 2873 } 2874 2875 /* Parse the string of disassembler options, spliting it at whitespaces 2876 or commas. (Whitespace separators supported for backwards compatibility). */ 2877 2878 static void 2879 parse_disassembler_options (char *options) 2880 { 2881 if (options == NULL) 2882 return; 2883 2884 while (*options) 2885 { 2886 parse_arm_disassembler_option (options); 2887 2888 /* Skip forward to next seperator. */ 2889 while ((*options) && (! ISSPACE (*options)) && (*options != ',')) 2890 ++ options; 2891 /* Skip forward past seperators. */ 2892 while (ISSPACE (*options) || (*options == ',')) 2893 ++ options; 2894 } 2895 } 2896 2897 /* NOTE: There are no checks in these routines that 2898 the relevant number of data bytes exist. */ 2899 2900 static int 2901 print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little) 2902 { 2903 unsigned char b[4]; 2904 long given; 2905 int status; 2906 int is_thumb; 2907 int size; 2908 void (*printer) (bfd_vma, struct disassemble_info *, long); 2909 2910 if (info->disassembler_options) 2911 { 2912 parse_disassembler_options (info->disassembler_options); 2913 2914 /* To avoid repeated parsing of these options, we remove them here. */ 2915 info->disassembler_options = NULL; 2916 } 2917 2918 is_thumb = force_thumb; 2919 2920 if (!is_thumb && info->symbols != NULL) 2921 { 2922 if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour) 2923 { 2924 coff_symbol_type * cs; 2925 2926 cs = coffsymbol (*info->symbols); 2927 is_thumb = ( cs->native->u.syment.n_sclass == C_THUMBEXT 2928 || cs->native->u.syment.n_sclass == C_THUMBSTAT 2929 || cs->native->u.syment.n_sclass == C_THUMBLABEL 2930 || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC 2931 || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC); 2932 } 2933 else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour) 2934 { 2935 elf_symbol_type * es; 2936 unsigned int type; 2937 2938 es = *(elf_symbol_type **)(info->symbols); 2939 type = ELF_ST_TYPE (es->internal_elf_sym.st_info); 2940 2941 is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT); 2942 } 2943 } 2944 2945 info->display_endian = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG; 2946 info->bytes_per_line = 4; 2947 2948 if (!is_thumb) 2949 { 2950 /* In ARM mode endianness is a straightforward issue: the instruction 2951 is four bytes long and is either ordered 0123 or 3210. */ 2952 printer = print_insn_arm; 2953 info->bytes_per_chunk = 4; 2954 size = 4; 2955 2956 status = info->read_memory_func (pc, (bfd_byte *)b, 4, info); 2957 if (little) 2958 given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24); 2959 else 2960 given = (b[3]) | (b[2] << 8) | (b[1] << 16) | (b[0] << 24); 2961 } 2962 else 2963 { 2964 /* In Thumb mode we have the additional wrinkle of two 2965 instruction lengths. Fortunately, the bits that determine 2966 the length of the current instruction are always to be found 2967 in the first two bytes. */ 2968 printer = print_insn_thumb16; 2969 info->bytes_per_chunk = 2; 2970 size = 2; 2971 2972 status = info->read_memory_func (pc, (bfd_byte *)b, 2, info); 2973 if (little) 2974 given = (b[0]) | (b[1] << 8); 2975 else 2976 given = (b[1]) | (b[0] << 8); 2977 2978 if (!status) 2979 { 2980 /* These bit patterns signal a four-byte Thumb 2981 instruction. */ 2982 if ((given & 0xF800) == 0xF800 2983 || (given & 0xF800) == 0xF000 2984 || (given & 0xF800) == 0xE800) 2985 { 2986 status = info->read_memory_func (pc + 2, (bfd_byte *)b, 2, info); 2987 if (little) 2988 given = (b[0]) | (b[1] << 8) | (given << 16); 2989 else 2990 given = (b[1]) | (b[0] << 8) | (given << 16); 2991 2992 printer = print_insn_thumb32; 2993 size = 4; 2994 } 2995 } 2996 } 2997 2998 if (status) 2999 { 3000 info->memory_error_func (status, pc, info); 3001 return -1; 3002 } 3003 if (info->flags & INSN_HAS_RELOC) 3004 /* If the instruction has a reloc associated with it, then 3005 the offset field in the instruction will actually be the 3006 addend for the reloc. (We are using REL type relocs). 3007 In such cases, we can ignore the pc when computing 3008 addresses, since the addend is not currently pc-relative. */ 3009 pc = 0; 3010 3011 printer (pc, info, given); 3012 return size; 3013 } 3014 3015 int 3016 print_insn_big_arm (bfd_vma pc, struct disassemble_info *info) 3017 { 3018 return print_insn (pc, info, FALSE); 3019 } 3020 3021 int 3022 print_insn_little_arm (bfd_vma pc, struct disassemble_info *info) 3023 { 3024 return print_insn (pc, info, TRUE); 3025 } 3026 3027 void 3028 print_arm_disassembler_options (FILE *stream) 3029 { 3030 int i; 3031 3032 fprintf (stream, _("\n\ 3033 The following ARM specific disassembler options are supported for use with\n\ 3034 the -M switch:\n")); 3035 3036 for (i = NUM_ARM_REGNAMES; i--;) 3037 fprintf (stream, " reg-names-%s %*c%s\n", 3038 regnames[i].name, 3039 (int)(14 - strlen (regnames[i].name)), ' ', 3040 regnames[i].description); 3041 3042 fprintf (stream, " force-thumb Assume all insns are Thumb insns\n"); 3043 fprintf (stream, " no-force-thumb Examine preceeding label to determine an insn's type\n\n"); 3044 } 3045