Annotation of qemu/arm-dis.c, revision 1.1.1.1

1.1       root        1: /* Instruction printing code for the ARM
                      2:    Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
                      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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
                     22: 
                     23: #include "dis-asm.h"
                     24: 
                     25: struct arm_opcode {
                     26:     unsigned long value, mask; /* recognise instruction if (op&mask)==value */
                     27:     char *assembler;           /* how to disassemble this instruction */
                     28: };
                     29: 
                     30: struct thumb_opcode
                     31: {
                     32:     unsigned short value, mask;        /* recognise instruction if (op&mask)==value */
                     33:     char * assembler;          /* how to disassemble this instruction */
                     34: };
                     35: 
                     36: /* format of the assembler string :
                     37:    
                     38:    %%                  %
                     39:    %<bitfield>d                print the bitfield in decimal
                     40:    %<bitfield>x                print the bitfield in hex
                     41:    %<bitfield>X                print the bitfield as 1 hex digit without leading "0x"
                     42:    %<bitfield>r                print as an ARM register
                     43:    %<bitfield>f                print a floating point constant if >7 else a
                     44:                        floating point register
                     45:    %<code>y            print a single precision VFP reg.
                     46:                          Codes: 0=>Sm, 1=>Sd, 2=>Sn, 3=>multi-list, 4=>Sm pair
                     47:    %<code>z            print a double precision VFP reg
                     48:                          Codes: 0=>Dm, 1=>Dd, 2=>Dn, 3=>multi-list
                     49:    %c                  print condition code (always bits 28-31)
                     50:    %P                  print floating point precision in arithmetic insn
                     51:    %Q                  print floating point precision in ldf/stf insn
                     52:    %R                  print floating point rounding mode
                     53:    %<bitnum>'c         print specified char iff bit is one
                     54:    %<bitnum>`c         print specified char iff bit is zero
                     55:    %<bitnum>?ab                print a if bit is one else print b
                     56:    %p                  print 'p' iff bits 12-15 are 15
                     57:    %t                  print 't' iff bit 21 set and bit 24 clear
                     58:    %o                  print operand2 (immediate or register + shift)
                     59:    %a                  print address for ldr/str instruction
                     60:    %s                   print address for ldr/str halfword/signextend instruction
                     61:    %b                  print branch destination
                     62:    %B                  print arm BLX(1) destination
                     63:    %A                  print address for ldc/stc/ldf/stf instruction
                     64:    %m                  print register mask for ldm/stm instruction
                     65:    %C                  print the PSR sub type.
                     66:    %F                  print the COUNT field of a LFM/SFM instruction.
                     67: Thumb specific format options:
                     68:    %D                   print Thumb register (bits 0..2 as high number if bit 7 set)
                     69:    %S                   print Thumb register (bits 3..5 as high number if bit 6 set)
                     70:    %<bitfield>I         print bitfield as a signed decimal
                     71:                                (top bit of range being the sign bit)
                     72:    %M                   print Thumb register mask
                     73:    %N                   print Thumb register mask (with LR)
                     74:    %O                   print Thumb register mask (with PC)
                     75:    %T                   print Thumb condition code (always bits 8-11)
                     76:    %I                   print cirrus signed shift immediate: bits 0..3|4..6
                     77:    %<bitfield>B         print Thumb branch destination (signed displacement)
                     78:    %<bitfield>W         print (bitfield * 4) as a decimal
                     79:    %<bitfield>H         print (bitfield * 2) as a decimal
                     80:    %<bitfield>a         print (bitfield * 4) as a pc-rel offset + decoded symbol
                     81: */
                     82: 
                     83: /* Note: There is a partial ordering in this table - it must be searched from
                     84:    the top to obtain a correct match. */
                     85: 
                     86: static struct arm_opcode arm_opcodes[] =
                     87: {
                     88:     /* ARM instructions.  */
                     89:     {0xe1a00000, 0xffffffff, "nop\t\t\t(mov r0,r0)"},
                     90:     {0x012FFF10, 0x0ffffff0, "bx%c\t%0-3r"},
                     91:     {0x00000090, 0x0fe000f0, "mul%c%20's\t%16-19r, %0-3r, %8-11r"},
                     92:     {0x00200090, 0x0fe000f0, "mla%c%20's\t%16-19r, %0-3r, %8-11r, %12-15r"},
                     93:     {0x01000090, 0x0fb00ff0, "swp%c%22'b\t%12-15r, %0-3r, [%16-19r]"},
                     94:     {0x00800090, 0x0fa000f0, "%22?sumull%c%20's\t%12-15r, %16-19r, %0-3r, %8-11r"},
                     95:     {0x00a00090, 0x0fa000f0, "%22?sumlal%c%20's\t%12-15r, %16-19r, %0-3r, %8-11r"},
                     96: 
                     97:     /* V5J instruction.  */
                     98:     {0x012fff20, 0x0ffffff0, "bxj%c\t%0-3r"},
                     99: 
                    100:     /* XScale instructions.  */
                    101:     {0x0e200010, 0x0fff0ff0, "mia%c\tacc0, %0-3r, %12-15r"},
                    102:     {0x0e280010, 0x0fff0ff0, "miaph%c\tacc0, %0-3r, %12-15r"},
                    103:     {0x0e2c0010, 0x0ffc0ff0, "mia%17'T%17`B%16'T%16`B%c\tacc0, %0-3r, %12-15r"},
                    104:     {0x0c400000, 0x0ff00fff, "mar%c\tacc0, %12-15r, %16-19r"},
                    105:     {0x0c500000, 0x0ff00fff, "mra%c\t%12-15r, %16-19r, acc0"},
                    106:     {0xf450f000, 0xfc70f000, "pld\t%a"},
                    107:     
                    108:     /* V5 Instructions.  */
                    109:     {0xe1200070, 0xfff000f0, "bkpt\t0x%16-19X%12-15X%8-11X%0-3X"},
                    110:     {0xfa000000, 0xfe000000, "blx\t%B"},
                    111:     {0x012fff30, 0x0ffffff0, "blx%c\t%0-3r"},
                    112:     {0x016f0f10, 0x0fff0ff0, "clz%c\t%12-15r, %0-3r"},
                    113:     {0xfc100000, 0xfe100000, "ldc2%22'l\t%8-11d, cr%12-15d, %A"},
                    114:     {0xfc000000, 0xfe100000, "stc2%22'l\t%8-11d, cr%12-15d, %A"},
                    115:     {0xfe000000, 0xff000010, "cdp2\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"},
                    116:     {0xfe000010, 0xff100010, "mcr2\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
                    117:     {0xfe100010, 0xff100010, "mrc2\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
                    118: 
                    119:     /* V5E "El Segundo" Instructions.  */    
                    120:     {0x000000d0, 0x0e1000f0, "ldr%cd\t%12-15r, %s"},
                    121:     {0x000000f0, 0x0e1000f0, "str%cd\t%12-15r, %s"},
                    122:     {0x01000080, 0x0ff000f0, "smlabb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
                    123:     {0x010000a0, 0x0ff000f0, "smlatb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
                    124:     {0x010000c0, 0x0ff000f0, "smlabt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
                    125:     {0x010000e0, 0x0ff000f0, "smlatt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
                    126: 
                    127:     {0x01200080, 0x0ff000f0, "smlawb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
                    128:     {0x012000c0, 0x0ff000f0, "smlawt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
                    129: 
                    130:     {0x01400080, 0x0ff000f0, "smlalbb%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
                    131:     {0x014000a0, 0x0ff000f0, "smlaltb%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
                    132:     {0x014000c0, 0x0ff000f0, "smlalbt%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
                    133:     {0x014000e0, 0x0ff000f0, "smlaltt%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
                    134: 
                    135:     {0x01600080, 0x0ff0f0f0, "smulbb%c\t%16-19r, %0-3r, %8-11r"},
                    136:     {0x016000a0, 0x0ff0f0f0, "smultb%c\t%16-19r, %0-3r, %8-11r"},
                    137:     {0x016000c0, 0x0ff0f0f0, "smulbt%c\t%16-19r, %0-3r, %8-11r"},
                    138:     {0x016000e0, 0x0ff0f0f0, "smultt%c\t%16-19r, %0-3r, %8-11r"},
                    139: 
                    140:     {0x012000a0, 0x0ff0f0f0, "smulwb%c\t%16-19r, %0-3r, %8-11r"},
                    141:     {0x012000e0, 0x0ff0f0f0, "smulwt%c\t%16-19r, %0-3r, %8-11r"},
                    142: 
                    143:     {0x01000050, 0x0ff00ff0,  "qadd%c\t%12-15r, %0-3r, %16-19r"},
                    144:     {0x01400050, 0x0ff00ff0, "qdadd%c\t%12-15r, %0-3r, %16-19r"},
                    145:     {0x01200050, 0x0ff00ff0,  "qsub%c\t%12-15r, %0-3r, %16-19r"},
                    146:     {0x01600050, 0x0ff00ff0, "qdsub%c\t%12-15r, %0-3r, %16-19r"},
                    147: 
                    148:     {0x0c400000, 0x0ff00000, "mcrr%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
                    149:     {0x0c500000, 0x0ff00000, "mrrc%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
                    150: 
                    151:     /* ARM Instructions.  */
                    152:     {0x00000090, 0x0e100090, "str%c%6's%5?hb\t%12-15r, %s"},
                    153:     {0x00100090, 0x0e100090, "ldr%c%6's%5?hb\t%12-15r, %s"},
                    154:     {0x00000000, 0x0de00000, "and%c%20's\t%12-15r, %16-19r, %o"},
                    155:     {0x00200000, 0x0de00000, "eor%c%20's\t%12-15r, %16-19r, %o"},
                    156:     {0x00400000, 0x0de00000, "sub%c%20's\t%12-15r, %16-19r, %o"},
                    157:     {0x00600000, 0x0de00000, "rsb%c%20's\t%12-15r, %16-19r, %o"},
                    158:     {0x00800000, 0x0de00000, "add%c%20's\t%12-15r, %16-19r, %o"},
                    159:     {0x00a00000, 0x0de00000, "adc%c%20's\t%12-15r, %16-19r, %o"},
                    160:     {0x00c00000, 0x0de00000, "sbc%c%20's\t%12-15r, %16-19r, %o"},
                    161:     {0x00e00000, 0x0de00000, "rsc%c%20's\t%12-15r, %16-19r, %o"},
                    162:     {0x0120f000, 0x0db0f000, "msr%c\t%22?SCPSR%C, %o"},
                    163:     {0x010f0000, 0x0fbf0fff, "mrs%c\t%12-15r, %22?SCPSR"},
                    164:     {0x01000000, 0x0de00000, "tst%c%p\t%16-19r, %o"},
                    165:     {0x01200000, 0x0de00000, "teq%c%p\t%16-19r, %o"},
                    166:     {0x01400000, 0x0de00000, "cmp%c%p\t%16-19r, %o"},
                    167:     {0x01600000, 0x0de00000, "cmn%c%p\t%16-19r, %o"},
                    168:     {0x01800000, 0x0de00000, "orr%c%20's\t%12-15r, %16-19r, %o"},
                    169:     {0x01a00000, 0x0de00000, "mov%c%20's\t%12-15r, %o"},
                    170:     {0x01c00000, 0x0de00000, "bic%c%20's\t%12-15r, %16-19r, %o"},
                    171:     {0x01e00000, 0x0de00000, "mvn%c%20's\t%12-15r, %o"},
                    172:     {0x04000000, 0x0e100000, "str%c%22'b%t\t%12-15r, %a"},
                    173:     {0x06000000, 0x0e100ff0, "str%c%22'b%t\t%12-15r, %a"},
                    174:     {0x04000000, 0x0c100010, "str%c%22'b%t\t%12-15r, %a"},
                    175:     {0x06000010, 0x0e000010, "undefined"},
                    176:     {0x04100000, 0x0c100000, "ldr%c%22'b%t\t%12-15r, %a"},
                    177:     {0x08000000, 0x0e100000, "stm%c%23?id%24?ba\t%16-19r%21'!, %m%22'^"},
                    178:     {0x08100000, 0x0e100000, "ldm%c%23?id%24?ba\t%16-19r%21'!, %m%22'^"},
                    179:     {0x0a000000, 0x0e000000, "b%24'l%c\t%b"},
                    180:     {0x0f000000, 0x0f000000, "swi%c\t%0-23x"},
                    181: 
                    182:     /* Floating point coprocessor (FPA) instructions */
                    183:     {0x0e000100, 0x0ff08f10, "adf%c%P%R\t%12-14f, %16-18f, %0-3f"},
                    184:     {0x0e100100, 0x0ff08f10, "muf%c%P%R\t%12-14f, %16-18f, %0-3f"},
                    185:     {0x0e200100, 0x0ff08f10, "suf%c%P%R\t%12-14f, %16-18f, %0-3f"},
                    186:     {0x0e300100, 0x0ff08f10, "rsf%c%P%R\t%12-14f, %16-18f, %0-3f"},
                    187:     {0x0e400100, 0x0ff08f10, "dvf%c%P%R\t%12-14f, %16-18f, %0-3f"},
                    188:     {0x0e500100, 0x0ff08f10, "rdf%c%P%R\t%12-14f, %16-18f, %0-3f"},
                    189:     {0x0e600100, 0x0ff08f10, "pow%c%P%R\t%12-14f, %16-18f, %0-3f"},
                    190:     {0x0e700100, 0x0ff08f10, "rpw%c%P%R\t%12-14f, %16-18f, %0-3f"},
                    191:     {0x0e800100, 0x0ff08f10, "rmf%c%P%R\t%12-14f, %16-18f, %0-3f"},
                    192:     {0x0e900100, 0x0ff08f10, "fml%c%P%R\t%12-14f, %16-18f, %0-3f"},
                    193:     {0x0ea00100, 0x0ff08f10, "fdv%c%P%R\t%12-14f, %16-18f, %0-3f"},
                    194:     {0x0eb00100, 0x0ff08f10, "frd%c%P%R\t%12-14f, %16-18f, %0-3f"},
                    195:     {0x0ec00100, 0x0ff08f10, "pol%c%P%R\t%12-14f, %16-18f, %0-3f"},
                    196:     {0x0e008100, 0x0ff08f10, "mvf%c%P%R\t%12-14f, %0-3f"},
                    197:     {0x0e108100, 0x0ff08f10, "mnf%c%P%R\t%12-14f, %0-3f"},
                    198:     {0x0e208100, 0x0ff08f10, "abs%c%P%R\t%12-14f, %0-3f"},
                    199:     {0x0e308100, 0x0ff08f10, "rnd%c%P%R\t%12-14f, %0-3f"},
                    200:     {0x0e408100, 0x0ff08f10, "sqt%c%P%R\t%12-14f, %0-3f"},
                    201:     {0x0e508100, 0x0ff08f10, "log%c%P%R\t%12-14f, %0-3f"},
                    202:     {0x0e608100, 0x0ff08f10, "lgn%c%P%R\t%12-14f, %0-3f"},
                    203:     {0x0e708100, 0x0ff08f10, "exp%c%P%R\t%12-14f, %0-3f"},
                    204:     {0x0e808100, 0x0ff08f10, "sin%c%P%R\t%12-14f, %0-3f"},
                    205:     {0x0e908100, 0x0ff08f10, "cos%c%P%R\t%12-14f, %0-3f"},
                    206:     {0x0ea08100, 0x0ff08f10, "tan%c%P%R\t%12-14f, %0-3f"},
                    207:     {0x0eb08100, 0x0ff08f10, "asn%c%P%R\t%12-14f, %0-3f"},
                    208:     {0x0ec08100, 0x0ff08f10, "acs%c%P%R\t%12-14f, %0-3f"},
                    209:     {0x0ed08100, 0x0ff08f10, "atn%c%P%R\t%12-14f, %0-3f"},
                    210:     {0x0ee08100, 0x0ff08f10, "urd%c%P%R\t%12-14f, %0-3f"},
                    211:     {0x0ef08100, 0x0ff08f10, "nrm%c%P%R\t%12-14f, %0-3f"},
                    212:     {0x0e000110, 0x0ff00f1f, "flt%c%P%R\t%16-18f, %12-15r"},
                    213:     {0x0e100110, 0x0fff0f98, "fix%c%R\t%12-15r, %0-2f"},
                    214:     {0x0e200110, 0x0fff0fff, "wfs%c\t%12-15r"},
                    215:     {0x0e300110, 0x0fff0fff, "rfs%c\t%12-15r"},
                    216:     {0x0e400110, 0x0fff0fff, "wfc%c\t%12-15r"},
                    217:     {0x0e500110, 0x0fff0fff, "rfc%c\t%12-15r"},
                    218:     {0x0e90f110, 0x0ff8fff0, "cmf%c\t%16-18f, %0-3f"},
                    219:     {0x0eb0f110, 0x0ff8fff0, "cnf%c\t%16-18f, %0-3f"},
                    220:     {0x0ed0f110, 0x0ff8fff0, "cmfe%c\t%16-18f, %0-3f"},
                    221:     {0x0ef0f110, 0x0ff8fff0, "cnfe%c\t%16-18f, %0-3f"},
                    222:     {0x0c000100, 0x0e100f00, "stf%c%Q\t%12-14f, %A"},
                    223:     {0x0c100100, 0x0e100f00, "ldf%c%Q\t%12-14f, %A"},
                    224:     {0x0c000200, 0x0e100f00, "sfm%c\t%12-14f, %F, %A"},
                    225:     {0x0c100200, 0x0e100f00, "lfm%c\t%12-14f, %F, %A"},
                    226: 
                    227:     /* Floating point coprocessor (VFP) instructions */
                    228:     {0x0eb00bc0, 0x0fff0ff0, "fabsd%c\t%1z, %0z"},
                    229:     {0x0eb00ac0, 0x0fbf0fd0, "fabss%c\t%1y, %0y"},
                    230:     {0x0e300b00, 0x0ff00ff0, "faddd%c\t%1z, %2z, %0z"},
                    231:     {0x0e300a00, 0x0fb00f50, "fadds%c\t%1y, %2y, %1y"},
                    232:     {0x0eb40b40, 0x0fff0f70, "fcmp%7'ed%c\t%1z, %0z"},
                    233:     {0x0eb40a40, 0x0fbf0f50, "fcmp%7'es%c\t%1y, %0y"},
                    234:     {0x0eb50b40, 0x0fff0f70, "fcmp%7'ezd%c\t%1z"},
                    235:     {0x0eb50a40, 0x0fbf0f70, "fcmp%7'ezs%c\t%1y"},
                    236:     {0x0eb00b40, 0x0fff0ff0, "fcpyd%c\t%1z, %0z"},
                    237:     {0x0eb00a40, 0x0fbf0fd0, "fcpys%c\t%1y, %0y"},
                    238:     {0x0eb70ac0, 0x0fff0fd0, "fcvtds%c\t%1z, %0y"},
                    239:     {0x0eb70bc0, 0x0fbf0ff0, "fcvtsd%c\t%1y, %0z"},
                    240:     {0x0e800b00, 0x0ff00ff0, "fdivd%c\t%1z, %2z, %0z"},
                    241:     {0x0e800a00, 0x0fb00f50, "fdivs%c\t%1y, %2y, %0y"},
                    242:     {0x0d100b00, 0x0f700f00, "fldd%c\t%1z, %A"},
                    243:     {0x0c900b00, 0x0fd00f00, "fldmia%0?xd%c\t%16-19r%21'!, %3z"},
                    244:     {0x0d300b00, 0x0ff00f00, "fldmdb%0?xd%c\t%16-19r!, %3z"},
                    245:     {0x0d100a00, 0x0f300f00, "flds%c\t%1y, %A"},
                    246:     {0x0c900a00, 0x0f900f00, "fldmias%c\t%16-19r%21'!, %3y"},
                    247:     {0x0d300a00, 0x0fb00f00, "fldmdbs%c\t%16-19r!, %3y"},
                    248:     {0x0e000b00, 0x0ff00ff0, "fmacd%c\t%1z, %2z, %0z"},
                    249:     {0x0e000a00, 0x0fb00f50, "fmacs%c\t%1y, %2y, %0y"},
                    250:     {0x0e200b10, 0x0ff00fff, "fmdhr%c\t%2z, %12-15r"},
                    251:     {0x0e000b10, 0x0ff00fff, "fmdlr%c\t%2z, %12-15r"},
                    252:     {0x0c400b10, 0x0ff00ff0, "fmdrr%c\t%0z, %12-15r, %16-19r"},
                    253:     {0x0e300b10, 0x0ff00fff, "fmrdh%c\t%12-15r, %2z"},
                    254:     {0x0e100b10, 0x0ff00fff, "fmrdl%c\t%12-15r, %2z"},
                    255:     {0x0c500b10, 0x0ff00ff0, "fmrrd%c\t%12-15r, %16-19r, %0z"},
                    256:     {0x0c500a10, 0x0ff00fd0, "fmrrs%c\t%12-15r, %16-19r, %4y"},
                    257:     {0x0e100a10, 0x0ff00f7f, "fmrs%c\t%12-15r, %2y"},
                    258:     {0x0ef1fa10, 0x0fffffff, "fmstat%c"},
                    259:     {0x0ef00a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpsid"},
                    260:     {0x0ef10a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpscr"},
                    261:     {0x0ef80a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpexc"},
                    262:     {0x0ef90a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpinst\t@ Impl def"},
                    263:     {0x0efa0a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpinst2\t@ Impl def"},
                    264:     {0x0ef00a10, 0x0ff00fff, "fmrx%c\t%12-15r, <impl def 0x%16-19x>"},
                    265:     {0x0e100b00, 0x0ff00ff0, "fmscd%c\t%1z, %2z, %0z"},
                    266:     {0x0e100a00, 0x0fb00f50, "fmscs%c\t%1y, %2y, %0y"},
                    267:     {0x0e000a10, 0x0ff00f7f, "fmsr%c\t%2y, %12-15r"},
                    268:     {0x0c400a10, 0x0ff00fd0, "fmsrr%c\t%12-15r, %16-19r, %4y"},
                    269:     {0x0e200b00, 0x0ff00ff0, "fmuld%c\t%1z, %2z, %0z"},
                    270:     {0x0e200a00, 0x0fb00f50, "fmuls%c\t%1y, %2y, %0y"},
                    271:     {0x0ee00a10, 0x0fff0fff, "fmxr%c\tfpsid, %12-15r"},
                    272:     {0x0ee10a10, 0x0fff0fff, "fmxr%c\tfpscr, %12-15r"},
                    273:     {0x0ee80a10, 0x0fff0fff, "fmxr%c\tfpexc, %12-15r"},
                    274:     {0x0ee90a10, 0x0fff0fff, "fmxr%c\tfpinst, %12-15r\t@ Impl def"},
                    275:     {0x0eea0a10, 0x0fff0fff, "fmxr%c\tfpinst2, %12-15r\t@ Impl def"},
                    276:     {0x0ee00a10, 0x0ff00fff, "fmxr%c\t<impl def 0x%16-19x>, %12-15r"},
                    277:     {0x0eb10b40, 0x0fff0ff0, "fnegd%c\t%1z, %0z"},
                    278:     {0x0eb10a40, 0x0fbf0fd0, "fnegs%c\t%1y, %0y"},
                    279:     {0x0e000b40, 0x0ff00ff0, "fnmacd%c\t%1z, %2z, %0z"},
                    280:     {0x0e000a40, 0x0fb00f50, "fnmacs%c\t%1y, %2y, %0y"},
                    281:     {0x0e100b40, 0x0ff00ff0, "fnmscd%c\t%1z, %2z, %0z"},
                    282:     {0x0e100a40, 0x0fb00f50, "fnmscs%c\t%1y, %2y, %0y"},
                    283:     {0x0e200b40, 0x0ff00ff0, "fnmuld%c\t%1z, %2z, %0z"},
                    284:     {0x0e200a40, 0x0fb00f50, "fnmuls%c\t%1y, %2y, %0y"},
                    285:     {0x0eb80bc0, 0x0fff0fd0, "fsitod%c\t%1z, %0y"},
                    286:     {0x0eb80ac0, 0x0fbf0fd0, "fsitos%c\t%1y, %0y"},
                    287:     {0x0eb10bc0, 0x0fff0ff0, "fsqrtd%c\t%1z, %0z"},
                    288:     {0x0eb10ac0, 0x0fbf0fd0, "fsqrts%c\t%1y, %0y"},
                    289:     {0x0d000b00, 0x0f700f00, "fstd%c\t%1z, %A"},
                    290:     {0x0c800b00, 0x0fd00f00, "fstmia%0?xd%c\t%16-19r%21'!, %3z"},
                    291:     {0x0d200b00, 0x0ff00f00, "fstmdb%0?xd%c\t%16-19r!, %3z"},
                    292:     {0x0d000a00, 0x0f300f00, "fsts%c\t%1y, %A"},
                    293:     {0x0c800a00, 0x0f900f00, "fstmias%c\t%16-19r%21'!, %3y"},
                    294:     {0x0d200a00, 0x0fb00f00, "fstmdbs%c\t%16-19r!, %3y"},
                    295:     {0x0e300b40, 0x0ff00ff0, "fsubd%c\t%1z, %2z, %0z"},
                    296:     {0x0e300a40, 0x0fb00f50, "fsubs%c\t%1y, %2y, %0y"},
                    297:     {0x0ebc0b40, 0x0fbe0f70, "fto%16?sui%7'zd%c\t%1y, %0z"},
                    298:     {0x0ebc0a40, 0x0fbe0f50, "fto%16?sui%7'zs%c\t%1y, %0y"},
                    299:     {0x0eb80b40, 0x0fff0fd0, "fuitod%c\t%1z, %0y"},
                    300:     {0x0eb80a40, 0x0fbf0fd0, "fuitos%c\t%1y, %0y"},
                    301: 
                    302:     /* Cirrus coprocessor instructions.  */
                    303:     {0x0d100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"},
                    304:     {0x0c100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"},
                    305:     {0x0d500400, 0x0f500f00, "cfldrd%c\tmvd%12-15d, %A"},
                    306:     {0x0c500400, 0x0f500f00, "cfldrd%c\tmvd%12-15d, %A"}, 
                    307:     {0x0d100500, 0x0f500f00, "cfldr32%c\tmvfx%12-15d, %A"},
                    308:     {0x0c100500, 0x0f500f00, "cfldr32%c\tmvfx%12-15d, %A"},
                    309:     {0x0d500500, 0x0f500f00, "cfldr64%c\tmvdx%12-15d, %A"},
                    310:     {0x0c500500, 0x0f500f00, "cfldr64%c\tmvdx%12-15d, %A"},
                    311:     {0x0d000400, 0x0f500f00, "cfstrs%c\tmvf%12-15d, %A"},
                    312:     {0x0c000400, 0x0f500f00, "cfstrs%c\tmvf%12-15d, %A"},
                    313:     {0x0d400400, 0x0f500f00, "cfstrd%c\tmvd%12-15d, %A"},
                    314:     {0x0c400400, 0x0f500f00, "cfstrd%c\tmvd%12-15d, %A"},
                    315:     {0x0d000500, 0x0f500f00, "cfstr32%c\tmvfx%12-15d, %A"},
                    316:     {0x0c000500, 0x0f500f00, "cfstr32%c\tmvfx%12-15d, %A"},
                    317:     {0x0d400500, 0x0f500f00, "cfstr64%c\tmvdx%12-15d, %A"},
                    318:     {0x0c400500, 0x0f500f00, "cfstr64%c\tmvdx%12-15d, %A"},
                    319:     {0x0e000450, 0x0ff00ff0, "cfmvsr%c\tmvf%16-19d, %12-15r"},
                    320:     {0x0e100450, 0x0ff00ff0, "cfmvrs%c\t%12-15r, mvf%16-19d"},
                    321:     {0x0e000410, 0x0ff00ff0, "cfmvdlr%c\tmvd%16-19d, %12-15r"},
                    322:     {0x0e100410, 0x0ff00ff0, "cfmvrdl%c\t%12-15r, mvd%16-19d"},
                    323:     {0x0e000430, 0x0ff00ff0, "cfmvdhr%c\tmvd%16-19d, %12-15r"},
                    324:     {0x0e100430, 0x0ff00fff, "cfmvrdh%c\t%12-15r, mvd%16-19d"},
                    325:     {0x0e000510, 0x0ff00fff, "cfmv64lr%c\tmvdx%16-19d, %12-15r"},
                    326:     {0x0e100510, 0x0ff00fff, "cfmvr64l%c\t%12-15r, mvdx%16-19d"},
                    327:     {0x0e000530, 0x0ff00fff, "cfmv64hr%c\tmvdx%16-19d, %12-15r"},
                    328:     {0x0e100530, 0x0ff00fff, "cfmvr64h%c\t%12-15r, mvdx%16-19d"},
                    329:     {0x0e100610, 0x0ff0fff0, "cfmval32%c\tmvax%0-3d, mvfx%16-19d"},
                    330:     {0x0e000610, 0x0ff0fff0, "cfmv32al%c\tmvfx%0-3d, mvax%16-19d"},
                    331:     {0x0e100630, 0x0ff0fff0, "cfmvam32%c\tmvax%0-3d, mvfx%16-19d"},
                    332:     {0x0e000630, 0x0ff0fff0, "cfmv32am%c\tmvfx%0-3d, mvax%16-19d"},
                    333:     {0x0e100650, 0x0ff0fff0, "cfmvah32%c\tmvax%0-3d, mvfx%16-19d"},
                    334:     {0x0e000650, 0x0ff0fff0, "cfmv32ah%c\tmvfx%0-3d, mvax%16-19d"},
                    335:     {0x0e000670, 0x0ff0fff0, "cfmv32a%c\tmvfx%0-3d, mvax%16-19d"},
                    336:     {0x0e100670, 0x0ff0fff0, "cfmva32%c\tmvax%0-3d, mvfx%16-19d"},
                    337:     {0x0e000690, 0x0ff0fff0, "cfmv64a%c\tmvdx%0-3d, mvax%16-19d"},
                    338:     {0x0e100690, 0x0ff0fff0, "cfmva64%c\tmvax%0-3d, mvdx%16-19d"},
                    339:     {0x0e1006b0, 0x0ff0fff0, "cfmvsc32%c\tdspsc, mvfx%16-19d"},
                    340:     {0x0e0006b0, 0x0ff0fff0, "cfmv32sc%c\tmvfx%0-3d, dspsc"},
                    341:     {0x0e000400, 0x0ff00fff, "cfcpys%c\tmvf%12-15d, mvf%16-19d"},
                    342:     {0x0e000420, 0x0ff00fff, "cfcpyd%c\tmvd%12-15d, mvd%16-19d"},
                    343:     {0x0e000460, 0x0ff00fff, "cfcvtsd%c\tmvd%12-15d, mvf%16-19d"},
                    344:     {0x0e000440, 0x0ff00fff, "cfcvtds%c\tmvf%12-15d, mvd%16-19d"},
                    345:     {0x0e000480, 0x0ff00fff, "cfcvt32s%c\tmvf%12-15d, mvfx%16-19d"},
                    346:     {0x0e0004a0, 0x0ff00fff, "cfcvt32d%c\tmvd%12-15d, mvfx%16-19d"},
                    347:     {0x0e0004c0, 0x0ff00fff, "cfcvt64s%c\tmvf%12-15d, mvdx%16-19d"},
                    348:     {0x0e0004e0, 0x0ff00fff, "cfcvt64d%c\tmvd%12-15d, mvdx%16-19d"},
                    349:     {0x0e100580, 0x0ff00fff, "cfcvts32%c\tmvfx%12-15d, mvf%16-19d"},
                    350:     {0x0e1005a0, 0x0ff00fff, "cfcvtd32%c\tmvfx%12-15d, mvd%16-19d"},
                    351:     {0x0e1005c0, 0x0ff00fff, "cftruncs32%c\tmvfx%12-15d, mvf%16-19d"},
                    352:     {0x0e1005e0, 0x0ff00fff, "cftruncd32%c\tmvfx%12-15d, mvd%16-19d"},
                    353:     {0x0e000550, 0x0ff00ff0, "cfrshl32%c\tmvfx%16-19d, mvfx%0-3d, %12-15r"},
                    354:     {0x0e000570, 0x0ff00ff0, "cfrshl64%c\tmvdx%16-19d, mvdx%0-3d, %12-15r"},
                    355:     {0x0e000500, 0x0ff00f00, "cfsh32%c\tmvfx%12-15d, mvfx%16-19d, #%I"},
                    356:     {0x0e200500, 0x0ff00f00, "cfsh64%c\tmvdx%12-15d, mvdx%16-19d, #%I"},
                    357:     {0x0e100490, 0x0ff00ff0, "cfcmps%c\t%12-15r, mvf%16-19d, mvf%0-3d"},
                    358:     {0x0e1004b0, 0x0ff00ff0, "cfcmpd%c\t%12-15r, mvd%16-19d, mvd%0-3d"},
                    359:     {0x0e100590, 0x0ff00ff0, "cfcmp32%c\t%12-15r, mvfx%16-19d, mvfx%0-3d"},
                    360:     {0x0e1005b0, 0x0ff00ff0, "cfcmp64%c\t%12-15r, mvdx%16-19d, mvdx%0-3d"},
                    361:     {0x0e300400, 0x0ff00fff, "cfabss%c\tmvf%12-15d, mvf%16-19d"},
                    362:     {0x0e300420, 0x0ff00fff, "cfabsd%c\tmvd%12-15d, mvd%16-19d"},
                    363:     {0x0e300440, 0x0ff00fff, "cfnegs%c\tmvf%12-15d, mvf%16-19d"},
                    364:     {0x0e300460, 0x0ff00fff, "cfnegd%c\tmvd%12-15d, mvd%16-19d"},
                    365:     {0x0e300480, 0x0ff00ff0, "cfadds%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
                    366:     {0x0e3004a0, 0x0ff00ff0, "cfaddd%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
                    367:     {0x0e3004c0, 0x0ff00ff0, "cfsubs%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
                    368:     {0x0e3004e0, 0x0ff00ff0, "cfsubd%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
                    369:     {0x0e100400, 0x0ff00ff0, "cfmuls%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
                    370:     {0x0e100420, 0x0ff00ff0, "cfmuld%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
                    371:     {0x0e300500, 0x0ff00fff, "cfabs32%c\tmvfx%12-15d, mvfx%16-19d"},
                    372:     {0x0e300520, 0x0ff00fff, "cfabs64%c\tmvdx%12-15d, mvdx%16-19d"},
                    373:     {0x0e300540, 0x0ff00fff, "cfneg32%c\tmvfx%12-15d, mvfx%16-19d"},
                    374:     {0x0e300560, 0x0ff00fff, "cfneg64%c\tmvdx%12-15d, mvdx%16-19d"},
                    375:     {0x0e300580, 0x0ff00ff0, "cfadd32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
                    376:     {0x0e3005a0, 0x0ff00ff0, "cfadd64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
                    377:     {0x0e3005c0, 0x0ff00ff0, "cfsub32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
                    378:     {0x0e3005e0, 0x0ff00ff0, "cfsub64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
                    379:     {0x0e100500, 0x0ff00ff0, "cfmul32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
                    380:     {0x0e100520, 0x0ff00ff0, "cfmul64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
                    381:     {0x0e100540, 0x0ff00ff0, "cfmac32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
                    382:     {0x0e100560, 0x0ff00ff0, "cfmsc32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
                    383:     {0x0e000600, 0x0ff00f00, "cfmadd32%c\tmvax%5-7d, mvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
                    384:     {0x0e100600, 0x0ff00f00, "cfmsub32%c\tmvax%5-7d, mvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
                    385:     {0x0e200600, 0x0ff00f00, "cfmadda32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"},
                    386:     {0x0e300600, 0x0ff00f00, "cfmsuba32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"},
                    387: 
                    388:     /* Generic coprocessor instructions */
                    389:     {0x0e000000, 0x0f000010, "cdp%c\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"},
                    390:     {0x0e100010, 0x0f100010, "mrc%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
                    391:     {0x0e000010, 0x0f100010, "mcr%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
                    392:     {0x0c000000, 0x0e100000, "stc%c%22'l\t%8-11d, cr%12-15d, %A"},
                    393:     {0x0c100000, 0x0e100000, "ldc%c%22'l\t%8-11d, cr%12-15d, %A"},
                    394: 
                    395:     /* The rest.  */
                    396:     {0x00000000, 0x00000000, "undefined instruction %0-31x"},
                    397:     {0x00000000, 0x00000000, 0}
                    398: };
                    399: 
                    400: #define BDISP(x) ((((x) & 0xffffff) ^ 0x800000) - 0x800000) /* 26 bit */
                    401: 
                    402: static struct thumb_opcode thumb_opcodes[] =
                    403: {
                    404:   /* Thumb instructions.  */
                    405: 
                    406:   /* ARM V5 ISA extends Thumb.  */
                    407:   {0xbe00, 0xff00, "bkpt\t%0-7x"},
                    408:   {0x4780, 0xff87, "blx\t%3-6r"},      /* note: 4 bit register number.  */
                    409:   /* Note: this is BLX(2).  BLX(1) is done in arm-dis.c/print_insn_thumb()
                    410:      as an extension of the special processing there for Thumb BL.
                    411:      BL and BLX(1) involve 2 successive 16-bit instructions, which must
                    412:      always appear together in the correct order.  So, the empty
                    413:      string is put in this table, and the string interpreter takes <empty>
                    414:      to mean it has a pair of BL-ish instructions.  */
                    415:   {0x46C0, 0xFFFF, "nop\t\t\t(mov r8, r8)"},
                    416:   /* Format 5 instructions do not update the PSR.  */
                    417:   {0x1C00, 0xFFC0, "mov\t%0-2r, %3-5r\t\t(add %0-2r, %3-5r, #%6-8d)"},
                    418:   /* Format 4.  */
                    419:   {0x4000, 0xFFC0, "and\t%0-2r, %3-5r"},
                    420:   {0x4040, 0xFFC0, "eor\t%0-2r, %3-5r"},
                    421:   {0x4080, 0xFFC0, "lsl\t%0-2r, %3-5r"},
                    422:   {0x40C0, 0xFFC0, "lsr\t%0-2r, %3-5r"},
                    423:   {0x4100, 0xFFC0, "asr\t%0-2r, %3-5r"},
                    424:   {0x4140, 0xFFC0, "adc\t%0-2r, %3-5r"},
                    425:   {0x4180, 0xFFC0, "sbc\t%0-2r, %3-5r"},
                    426:   {0x41C0, 0xFFC0, "ror\t%0-2r, %3-5r"},
                    427:   {0x4200, 0xFFC0, "tst\t%0-2r, %3-5r"},
                    428:   {0x4240, 0xFFC0, "neg\t%0-2r, %3-5r"},
                    429:   {0x4280, 0xFFC0, "cmp\t%0-2r, %3-5r"},
                    430:   {0x42C0, 0xFFC0, "cmn\t%0-2r, %3-5r"},
                    431:   {0x4300, 0xFFC0, "orr\t%0-2r, %3-5r"},
                    432:   {0x4340, 0xFFC0, "mul\t%0-2r, %3-5r"},
                    433:   {0x4380, 0xFFC0, "bic\t%0-2r, %3-5r"},
                    434:   {0x43C0, 0xFFC0, "mvn\t%0-2r, %3-5r"},
                    435:   /* format 13 */
                    436:   {0xB000, 0xFF80, "add\tsp, #%0-6W"},
                    437:   {0xB080, 0xFF80, "sub\tsp, #%0-6W"},
                    438:   /* format 5 */
                    439:   {0x4700, 0xFF80, "bx\t%S"},
                    440:   {0x4400, 0xFF00, "add\t%D, %S"},
                    441:   {0x4500, 0xFF00, "cmp\t%D, %S"},
                    442:   {0x4600, 0xFF00, "mov\t%D, %S"},
                    443:   /* format 14 */
                    444:   {0xB400, 0xFE00, "push\t%N"},
                    445:   {0xBC00, 0xFE00, "pop\t%O"},
                    446:   /* format 2 */
                    447:   {0x1800, 0xFE00, "add\t%0-2r, %3-5r, %6-8r"},
                    448:   {0x1A00, 0xFE00, "sub\t%0-2r, %3-5r, %6-8r"},
                    449:   {0x1C00, 0xFE00, "add\t%0-2r, %3-5r, #%6-8d"},
                    450:   {0x1E00, 0xFE00, "sub\t%0-2r, %3-5r, #%6-8d"},
                    451:   /* format 8 */
                    452:   {0x5200, 0xFE00, "strh\t%0-2r, [%3-5r, %6-8r]"},
                    453:   {0x5A00, 0xFE00, "ldrh\t%0-2r, [%3-5r, %6-8r]"},
                    454:   {0x5600, 0xF600, "ldrs%11?hb\t%0-2r, [%3-5r, %6-8r]"},
                    455:   /* format 7 */
                    456:   {0x5000, 0xFA00, "str%10'b\t%0-2r, [%3-5r, %6-8r]"},
                    457:   {0x5800, 0xFA00, "ldr%10'b\t%0-2r, [%3-5r, %6-8r]"},
                    458:   /* format 1 */
                    459:   {0x0000, 0xF800, "lsl\t%0-2r, %3-5r, #%6-10d"},
                    460:   {0x0800, 0xF800, "lsr\t%0-2r, %3-5r, #%6-10d"},
                    461:   {0x1000, 0xF800, "asr\t%0-2r, %3-5r, #%6-10d"},
                    462:   /* format 3 */
                    463:   {0x2000, 0xF800, "mov\t%8-10r, #%0-7d"},
                    464:   {0x2800, 0xF800, "cmp\t%8-10r, #%0-7d"},
                    465:   {0x3000, 0xF800, "add\t%8-10r, #%0-7d"},
                    466:   {0x3800, 0xF800, "sub\t%8-10r, #%0-7d"},
                    467:   /* format 6 */
                    468:   {0x4800, 0xF800, "ldr\t%8-10r, [pc, #%0-7W]\t(%0-7a)"},  /* TODO: Disassemble PC relative "LDR rD,=<symbolic>" */
                    469:   /* format 9 */
                    470:   {0x6000, 0xF800, "str\t%0-2r, [%3-5r, #%6-10W]"},
                    471:   {0x6800, 0xF800, "ldr\t%0-2r, [%3-5r, #%6-10W]"},
                    472:   {0x7000, 0xF800, "strb\t%0-2r, [%3-5r, #%6-10d]"},
                    473:   {0x7800, 0xF800, "ldrb\t%0-2r, [%3-5r, #%6-10d]"},
                    474:   /* format 10 */
                    475:   {0x8000, 0xF800, "strh\t%0-2r, [%3-5r, #%6-10H]"},
                    476:   {0x8800, 0xF800, "ldrh\t%0-2r, [%3-5r, #%6-10H]"},
                    477:   /* format 11 */
                    478:   {0x9000, 0xF800, "str\t%8-10r, [sp, #%0-7W]"},
                    479:   {0x9800, 0xF800, "ldr\t%8-10r, [sp, #%0-7W]"},
                    480:   /* format 12 */
                    481:   {0xA000, 0xF800, "add\t%8-10r, pc, #%0-7W\t(adr %8-10r,%0-7a)"},
                    482:   {0xA800, 0xF800, "add\t%8-10r, sp, #%0-7W"},
                    483:   /* format 15 */
                    484:   {0xC000, 0xF800, "stmia\t%8-10r!,%M"},
                    485:   {0xC800, 0xF800, "ldmia\t%8-10r!,%M"},
                    486:   /* format 18 */
                    487:   {0xE000, 0xF800, "b\t%0-10B"},
                    488:   {0xE800, 0xF800, "undefined"},
                    489:   /* format 19 */
                    490:   {0xF000, 0xF800, ""}, /* special processing required in disassembler */
                    491:   {0xF800, 0xF800, "second half of BL instruction %0-15x"},
                    492:   /* format 16 */
                    493:   {0xD000, 0xFF00, "beq\t%0-7B"},
                    494:   {0xD100, 0xFF00, "bne\t%0-7B"},
                    495:   {0xD200, 0xFF00, "bcs\t%0-7B"},
                    496:   {0xD300, 0xFF00, "bcc\t%0-7B"},
                    497:   {0xD400, 0xFF00, "bmi\t%0-7B"},
                    498:   {0xD500, 0xFF00, "bpl\t%0-7B"},
                    499:   {0xD600, 0xFF00, "bvs\t%0-7B"},
                    500:   {0xD700, 0xFF00, "bvc\t%0-7B"},
                    501:   {0xD800, 0xFF00, "bhi\t%0-7B"},
                    502:   {0xD900, 0xFF00, "bls\t%0-7B"},
                    503:   {0xDA00, 0xFF00, "bge\t%0-7B"},
                    504:   {0xDB00, 0xFF00, "blt\t%0-7B"},
                    505:   {0xDC00, 0xFF00, "bgt\t%0-7B"},
                    506:   {0xDD00, 0xFF00, "ble\t%0-7B"},
                    507:   /* format 17 */
                    508:   {0xDE00, 0xFF00, "bal\t%0-7B"},
                    509:   {0xDF00, 0xFF00, "swi\t%0-7d"},
                    510:   /* format 9 */
                    511:   {0x6000, 0xF800, "str\t%0-2r, [%3-5r, #%6-10W]"},
                    512:   {0x6800, 0xF800, "ldr\t%0-2r, [%3-5r, #%6-10W]"},
                    513:   {0x7000, 0xF800, "strb\t%0-2r, [%3-5r, #%6-10d]"},
                    514:   {0x7800, 0xF800, "ldrb\t%0-2r, [%3-5r, #%6-10d]"},
                    515:   /* the rest */
                    516:   {0x0000, 0x0000, "undefined instruction %0-15x"},
                    517:   {0x0000, 0x0000, 0}
                    518: };
                    519: 
                    520: #define BDISP23(x) ((((((x) & 0x07ff) << 11) | (((x) & 0x07ff0000) >> 16)) \
                    521:                      ^ 0x200000) - 0x200000) /* 23bit */
                    522: 
                    523: #ifndef streq
                    524: #define streq(a,b)     (strcmp ((a), (b)) == 0)
                    525: #endif
                    526: 
                    527: #ifndef strneq
                    528: #define strneq(a,b,n)  (strncmp ((a), (b), (n)) == 0)
                    529: #endif
                    530: 
                    531: #ifndef NUM_ELEM
                    532: #define NUM_ELEM(a)     (sizeof (a) / sizeof (a)[0])
                    533: #endif
                    534: 
                    535: static char * arm_conditional[] =
                    536: {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
                    537:  "hi", "ls", "ge", "lt", "gt", "le", "", "nv"};
                    538: 
                    539: typedef struct
                    540: {
                    541:   const char * name;
                    542:   const char * description;
                    543:   const char * reg_names[16];
                    544: }
                    545: arm_regname;
                    546: 
                    547: static arm_regname regnames[] =
                    548: {
                    549:   { "raw" , "Select raw register names",
                    550:     { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}},
                    551:   { "gcc",  "Select register names used by GCC",
                    552:     { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "sl",  "fp",  "ip",  "sp",  "lr",  "pc" }},
                    553:   { "std",  "Select register names used in ARM's ISA documentation",
                    554:     { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp",  "lr",  "pc" }},
                    555:   { "apcs", "Select register names used in the APCS",
                    556:     { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "sl",  "fp",  "ip",  "sp",  "lr",  "pc" }},
                    557:   { "atpcs", "Select register names used in the ATPCS",
                    558:     { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7",  "v8",  "IP",  "SP",  "LR",  "PC" }},
                    559:   { "special-atpcs", "Select special register names used in the ATPCS",
                    560:     { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL",  "FP",  "IP",  "SP",  "LR",  "PC" }}
                    561: };
                    562: 
                    563: /* Default to STD register name set.  */
                    564: static unsigned int regname_selected = 2;
                    565: 
                    566: #define NUM_ARM_REGNAMES  NUM_ELEM (regnames)
                    567: #define arm_regnames      regnames[regname_selected].reg_names
                    568: 
                    569: static boolean force_thumb = false;
                    570: 
                    571: static char * arm_fp_const[] =
                    572: {"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
                    573: 
                    574: static char * arm_shift[] = 
                    575: {"lsl", "lsr", "asr", "ror"};
                    576: 
                    577: /* Forward declarations.  */
                    578: static void arm_decode_shift PARAMS ((long, fprintf_ftype, void *));
                    579: static int  print_insn_arm1 PARAMS ((bfd_vma, struct disassemble_info *, long));
                    580: static int  print_insn_thumb PARAMS ((bfd_vma, struct disassemble_info *, long));
                    581: static void parse_disassembler_options PARAMS ((char *));
                    582: int get_arm_regname_num_options (void);
                    583: int set_arm_regname_option (int option);
                    584: int get_arm_regnames (int option, const char **setname,
                    585:                      const char **setdescription,
                    586:                      const char ***register_names);
                    587: 
                    588: /* Functions.  */
                    589: int
                    590: get_arm_regname_num_options ()
                    591: {
                    592:   return NUM_ARM_REGNAMES;
                    593: }
                    594: 
                    595: int
                    596: set_arm_regname_option (option)
                    597:      int option;
                    598: {
                    599:   int old = regname_selected;
                    600:   regname_selected = option;
                    601:   return old;
                    602: }
                    603: 
                    604: int
                    605: get_arm_regnames (option, setname, setdescription, register_names)
                    606:      int option;
                    607:      const char **setname;
                    608:      const char **setdescription;
                    609:      const char ***register_names;
                    610: {
                    611:   *setname = regnames[option].name;
                    612:   *setdescription = regnames[option].description;
                    613:   *register_names = regnames[option].reg_names;
                    614:   return 16;
                    615: }
                    616: 
                    617: static void
                    618: arm_decode_shift (given, func, stream)
                    619:      long given;
                    620:      fprintf_ftype func;
                    621:      void * stream;
                    622: {
                    623:   func (stream, "%s", arm_regnames[given & 0xf]);
                    624:   
                    625:   if ((given & 0xff0) != 0)
                    626:     {
                    627:       if ((given & 0x10) == 0)
                    628:        {
                    629:          int amount = (given & 0xf80) >> 7;
                    630:          int shift = (given & 0x60) >> 5;
                    631:          
                    632:          if (amount == 0)
                    633:            {
                    634:              if (shift == 3)
                    635:                {
                    636:                  func (stream, ", rrx");
                    637:                  return;
                    638:                }
                    639:              
                    640:              amount = 32;
                    641:            }
                    642:          
                    643:          func (stream, ", %s #%d", arm_shift[shift], amount);
                    644:        }
                    645:       else
                    646:        func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
                    647:              arm_regnames[(given & 0xf00) >> 8]);
                    648:     }
                    649: }
                    650: 
                    651: /* Print one instruction from PC on INFO->STREAM.
                    652:    Return the size of the instruction (always 4 on ARM). */
                    653: 
                    654: static int
                    655: print_insn_arm1 (pc, info, given)
                    656:      bfd_vma                   pc;
                    657:      struct disassemble_info * info;
                    658:      long                      given;
                    659: {
                    660:   struct arm_opcode *  insn;
                    661:   void *               stream = info->stream;
                    662:   fprintf_ftype        func   = info->fprintf_func;
                    663: 
                    664:   for (insn = arm_opcodes; insn->assembler; insn++)
                    665:     {
                    666:       if ((given & insn->mask) == insn->value)
                    667:        {
                    668:          char * c;
                    669:          
                    670:          for (c = insn->assembler; *c; c++)
                    671:            {
                    672:              if (*c == '%')
                    673:                {
                    674:                  switch (*++c)
                    675:                    {
                    676:                    case '%':
                    677:                      func (stream, "%%");
                    678:                      break;
                    679: 
                    680:                    case 'a':
                    681:                      if (((given & 0x000f0000) == 0x000f0000)
                    682:                          && ((given & 0x02000000) == 0))
                    683:                        {
                    684:                          int offset = given & 0xfff;
                    685:                          
                    686:                          func (stream, "[pc");
                    687:  
                    688:                          if (given & 0x01000000)
                    689:                            {
                    690:                              if ((given & 0x00800000) == 0)
                    691:                                offset = - offset;
                    692:                          
                    693:                              /* Pre-indexed.  */
                    694:                              func (stream, ", #%d]", offset);
                    695: 
                    696:                              offset += pc + 8;
                    697: 
                    698:                              /* Cope with the possibility of write-back
                    699:                                 being used.  Probably a very dangerous thing
                    700:                                 for the programmer to do, but who are we to
                    701:                                 argue ?  */
                    702:                              if (given & 0x00200000)
                    703:                                func (stream, "!");
                    704:                            }
                    705:                          else
                    706:                            {
                    707:                              /* Post indexed.  */
                    708:                              func (stream, "], #%d", offset);
                    709: 
                    710:                              /* ie ignore the offset.  */
                    711:                              offset = pc + 8;
                    712:                            }
                    713:                          
                    714:                          func (stream, "\t; ");
                    715:                          info->print_address_func (offset, info);
                    716:                        }
                    717:                      else
                    718:                        {
                    719:                          func (stream, "[%s", 
                    720:                                arm_regnames[(given >> 16) & 0xf]);
                    721:                          if ((given & 0x01000000) != 0)
                    722:                            {
                    723:                              if ((given & 0x02000000) == 0)
                    724:                                {
                    725:                                  int offset = given & 0xfff;
                    726:                                  if (offset)
                    727:                                    func (stream, ", %s#%d",
                    728:                                          (((given & 0x00800000) == 0)
                    729:                                           ? "-" : ""), offset);
                    730:                                }
                    731:                              else
                    732:                                {
                    733:                                  func (stream, ", %s",
                    734:                                        (((given & 0x00800000) == 0)
                    735:                                         ? "-" : ""));
                    736:                                  arm_decode_shift (given, func, stream);
                    737:                                }
                    738: 
                    739:                              func (stream, "]%s", 
                    740:                                    ((given & 0x00200000) != 0) ? "!" : "");
                    741:                            }
                    742:                          else
                    743:                            {
                    744:                              if ((given & 0x02000000) == 0)
                    745:                                {
                    746:                                  int offset = given & 0xfff;
                    747:                                  if (offset)
                    748:                                    func (stream, "], %s#%d",
                    749:                                          (((given & 0x00800000) == 0)
                    750:                                           ? "-" : ""), offset);
                    751:                                  else 
                    752:                                    func (stream, "]");
                    753:                                }
                    754:                              else
                    755:                                {
                    756:                                  func (stream, "], %s",
                    757:                                        (((given & 0x00800000) == 0) 
                    758:                                         ? "-" : ""));
                    759:                                  arm_decode_shift (given, func, stream);
                    760:                                }
                    761:                            }
                    762:                        }
                    763:                      break;
                    764: 
                    765:                    case 's':
                    766:                       if ((given & 0x004f0000) == 0x004f0000)
                    767:                        {
                    768:                           /* PC relative with immediate offset.  */
                    769:                          int offset = ((given & 0xf00) >> 4) | (given & 0xf);
                    770:                          
                    771:                          if ((given & 0x00800000) == 0)
                    772:                            offset = -offset;
                    773:                          
                    774:                          func (stream, "[pc, #%d]\t; ", offset);
                    775:                          
                    776:                          (*info->print_address_func)
                    777:                            (offset + pc + 8, info);
                    778:                        }
                    779:                      else
                    780:                        {
                    781:                          func (stream, "[%s", 
                    782:                                arm_regnames[(given >> 16) & 0xf]);
                    783:                          if ((given & 0x01000000) != 0)
                    784:                            {
                    785:                               /* Pre-indexed.  */
                    786:                              if ((given & 0x00400000) == 0x00400000)
                    787:                                {
                    788:                                   /* Immediate.  */
                    789:                                   int offset = ((given & 0xf00) >> 4) | (given & 0xf);
                    790:                                  if (offset)
                    791:                                    func (stream, ", %s#%d",
                    792:                                          (((given & 0x00800000) == 0)
                    793:                                           ? "-" : ""), offset);
                    794:                                }
                    795:                              else
                    796:                                {
                    797:                                   /* Register.  */
                    798:                                  func (stream, ", %s%s",
                    799:                                        (((given & 0x00800000) == 0)
                    800:                                         ? "-" : ""),
                    801:                                         arm_regnames[given & 0xf]);
                    802:                                }
                    803: 
                    804:                              func (stream, "]%s", 
                    805:                                    ((given & 0x00200000) != 0) ? "!" : "");
                    806:                            }
                    807:                          else
                    808:                            {
                    809:                               /* Post-indexed.  */
                    810:                              if ((given & 0x00400000) == 0x00400000)
                    811:                                {
                    812:                                   /* Immediate.  */
                    813:                                   int offset = ((given & 0xf00) >> 4) | (given & 0xf);
                    814:                                  if (offset)
                    815:                                    func (stream, "], %s#%d",
                    816:                                          (((given & 0x00800000) == 0)
                    817:                                           ? "-" : ""), offset);
                    818:                                  else 
                    819:                                    func (stream, "]");
                    820:                                }
                    821:                              else
                    822:                                {
                    823:                                   /* Register.  */
                    824:                                  func (stream, "], %s%s",
                    825:                                        (((given & 0x00800000) == 0)
                    826:                                         ? "-" : ""),
                    827:                                         arm_regnames[given & 0xf]);
                    828:                                }
                    829:                            }
                    830:                        }
                    831:                      break;
                    832:                          
                    833:                    case 'b':
                    834:                      (*info->print_address_func)
                    835:                        (BDISP (given) * 4 + pc + 8, info);
                    836:                      break;
                    837: 
                    838:                    case 'c':
                    839:                      func (stream, "%s",
                    840:                            arm_conditional [(given >> 28) & 0xf]);
                    841:                      break;
                    842: 
                    843:                    case 'm':
                    844:                      {
                    845:                        int started = 0;
                    846:                        int reg;
                    847: 
                    848:                        func (stream, "{");
                    849:                        for (reg = 0; reg < 16; reg++)
                    850:                          if ((given & (1 << reg)) != 0)
                    851:                            {
                    852:                              if (started)
                    853:                                func (stream, ", ");
                    854:                              started = 1;
                    855:                              func (stream, "%s", arm_regnames[reg]);
                    856:                            }
                    857:                        func (stream, "}");
                    858:                      }
                    859:                      break;
                    860: 
                    861:                    case 'o':
                    862:                      if ((given & 0x02000000) != 0)
                    863:                        {
                    864:                          int rotate = (given & 0xf00) >> 7;
                    865:                          int immed = (given & 0xff);
                    866:                          immed = (((immed << (32 - rotate))
                    867:                                    | (immed >> rotate)) & 0xffffffff);
                    868:                          func (stream, "#%d\t; 0x%x", immed, immed);
                    869:                        }
                    870:                      else
                    871:                        arm_decode_shift (given, func, stream);
                    872:                      break;
                    873: 
                    874:                    case 'p':
                    875:                      if ((given & 0x0000f000) == 0x0000f000)
                    876:                        func (stream, "p");
                    877:                      break;
                    878: 
                    879:                    case 't':
                    880:                      if ((given & 0x01200000) == 0x00200000)
                    881:                        func (stream, "t");
                    882:                      break;
                    883: 
                    884:                    case 'A':
                    885:                      func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
                    886:                      if ((given & 0x01000000) != 0)
                    887:                        {
                    888:                          int offset = given & 0xff;
                    889:                          if (offset)
                    890:                            func (stream, ", %s#%d]%s",
                    891:                                  ((given & 0x00800000) == 0 ? "-" : ""),
                    892:                                  offset * 4,
                    893:                                  ((given & 0x00200000) != 0 ? "!" : ""));
                    894:                          else
                    895:                            func (stream, "]");
                    896:                        }
                    897:                      else
                    898:                        {
                    899:                          int offset = given & 0xff;
                    900:                          if (offset)
                    901:                            func (stream, "], %s#%d",
                    902:                                  ((given & 0x00800000) == 0 ? "-" : ""),
                    903:                                  offset * 4);
                    904:                          else
                    905:                            func (stream, "]");
                    906:                        }
                    907:                      break;
                    908: 
                    909:                    case 'B':
                    910:                      /* Print ARM V5 BLX(1) address: pc+25 bits.  */
                    911:                      {
                    912:                        bfd_vma address;
                    913:                        bfd_vma offset = 0;
                    914:                        
                    915:                        if (given & 0x00800000)
                    916:                          /* Is signed, hi bits should be ones.  */
                    917:                          offset = (-1) ^ 0x00ffffff;
                    918: 
                    919:                        /* Offset is (SignExtend(offset field)<<2).  */
                    920:                        offset += given & 0x00ffffff;
                    921:                        offset <<= 2;
                    922:                        address = offset + pc + 8;
                    923:                        
                    924:                        if (given & 0x01000000)
                    925:                          /* H bit allows addressing to 2-byte boundaries.  */
                    926:                          address += 2;
                    927: 
                    928:                        info->print_address_func (address, info);
                    929:                      }
                    930:                      break;
                    931: 
                    932:                    case 'I':
                    933:                      /* Print a Cirrus/DSP shift immediate.  */
                    934:                      /* Immediates are 7bit signed ints with bits 0..3 in
                    935:                         bits 0..3 of opcode and bits 4..6 in bits 5..7
                    936:                         of opcode.  */
                    937:                      {
                    938:                        int imm;
                    939: 
                    940:                        imm = (given & 0xf) | ((given & 0xe0) >> 1);
                    941: 
                    942:                        /* Is ``imm'' a negative number?  */
                    943:                        if (imm & 0x40)
                    944:                          imm |= (-1 << 7);
                    945: 
                    946:                        func (stream, "%d", imm);
                    947:                      }
                    948: 
                    949:                      break;
                    950: 
                    951:                    case 'C':
                    952:                      func (stream, "_");
                    953:                      if (given & 0x80000)
                    954:                        func (stream, "f");
                    955:                      if (given & 0x40000)
                    956:                        func (stream, "s");
                    957:                      if (given & 0x20000)
                    958:                        func (stream, "x");
                    959:                      if (given & 0x10000)
                    960:                        func (stream, "c");
                    961:                      break;
                    962: 
                    963:                    case 'F':
                    964:                      switch (given & 0x00408000)
                    965:                        {
                    966:                        case 0:
                    967:                          func (stream, "4");
                    968:                          break;
                    969:                        case 0x8000:
                    970:                          func (stream, "1");
                    971:                          break;
                    972:                        case 0x00400000:
                    973:                          func (stream, "2");
                    974:                          break;
                    975:                        default:
                    976:                          func (stream, "3");
                    977:                        }
                    978:                      break;
                    979:                        
                    980:                    case 'P':
                    981:                      switch (given & 0x00080080)
                    982:                        {
                    983:                        case 0:
                    984:                          func (stream, "s");
                    985:                          break;
                    986:                        case 0x80:
                    987:                          func (stream, "d");
                    988:                          break;
                    989:                        case 0x00080000:
                    990:                          func (stream, "e");
                    991:                          break;
                    992:                        default:
                    993:                          func (stream, _("<illegal precision>"));
                    994:                          break;
                    995:                        }
                    996:                      break;
                    997:                    case 'Q':
                    998:                      switch (given & 0x00408000)
                    999:                        {
                   1000:                        case 0:
                   1001:                          func (stream, "s");
                   1002:                          break;
                   1003:                        case 0x8000:
                   1004:                          func (stream, "d");
                   1005:                          break;
                   1006:                        case 0x00400000:
                   1007:                          func (stream, "e");
                   1008:                          break;
                   1009:                        default:
                   1010:                          func (stream, "p");
                   1011:                          break;
                   1012:                        }
                   1013:                      break;
                   1014:                    case 'R':
                   1015:                      switch (given & 0x60)
                   1016:                        {
                   1017:                        case 0:
                   1018:                          break;
                   1019:                        case 0x20:
                   1020:                          func (stream, "p");
                   1021:                          break;
                   1022:                        case 0x40:
                   1023:                          func (stream, "m");
                   1024:                          break;
                   1025:                        default:
                   1026:                          func (stream, "z");
                   1027:                          break;
                   1028:                        }
                   1029:                      break;
                   1030: 
                   1031:                    case '0': case '1': case '2': case '3': case '4': 
                   1032:                    case '5': case '6': case '7': case '8': case '9':
                   1033:                      {
                   1034:                        int bitstart = *c++ - '0';
                   1035:                        int bitend = 0;
                   1036:                        while (*c >= '0' && *c <= '9')
                   1037:                          bitstart = (bitstart * 10) + *c++ - '0';
                   1038: 
                   1039:                        switch (*c)
                   1040:                          {
                   1041:                          case '-':
                   1042:                            c++;
                   1043:                            
                   1044:                            while (*c >= '0' && *c <= '9')
                   1045:                              bitend = (bitend * 10) + *c++ - '0';
                   1046:                            
                   1047:                            if (!bitend)
                   1048:                              abort ();
                   1049:                            
                   1050:                            switch (*c)
                   1051:                              {
                   1052:                              case 'r':
                   1053:                                {
                   1054:                                  long reg;
                   1055:                                  
                   1056:                                  reg = given >> bitstart;
                   1057:                                  reg &= (2 << (bitend - bitstart)) - 1;
                   1058:                                  
                   1059:                                  func (stream, "%s", arm_regnames[reg]);
                   1060:                                }
                   1061:                                break;
                   1062:                              case 'd':
                   1063:                                {
                   1064:                                  long reg;
                   1065:                                  
                   1066:                                  reg = given >> bitstart;
                   1067:                                  reg &= (2 << (bitend - bitstart)) - 1;
                   1068:                                  
                   1069:                                  func (stream, "%d", reg);
                   1070:                                }
                   1071:                                break;
                   1072:                              case 'x':
                   1073:                                {
                   1074:                                  long reg;
                   1075:                                  
                   1076:                                  reg = given >> bitstart;
                   1077:                                  reg &= (2 << (bitend - bitstart)) - 1;
                   1078:                                  
                   1079:                                  func (stream, "0x%08x", reg);
                   1080:                                  
                   1081:                                  /* Some SWI instructions have special
                   1082:                                     meanings.  */
                   1083:                                  if ((given & 0x0fffffff) == 0x0FF00000)
                   1084:                                    func (stream, "\t; IMB");
                   1085:                                  else if ((given & 0x0fffffff) == 0x0FF00001)
                   1086:                                    func (stream, "\t; IMBRange");
                   1087:                                }
                   1088:                                break;
                   1089:                              case 'X':
                   1090:                                {
                   1091:                                  long reg;
                   1092:                                  
                   1093:                                  reg = given >> bitstart;
                   1094:                                  reg &= (2 << (bitend - bitstart)) - 1;
                   1095:                                  
                   1096:                                  func (stream, "%01x", reg & 0xf);
                   1097:                                }
                   1098:                                break;
                   1099:                              case 'f':
                   1100:                                {
                   1101:                                  long reg;
                   1102:                                  
                   1103:                                  reg = given >> bitstart;
                   1104:                                  reg &= (2 << (bitend - bitstart)) - 1;
                   1105:                                  
                   1106:                                  if (reg > 7)
                   1107:                                    func (stream, "#%s",
                   1108:                                          arm_fp_const[reg & 7]);
                   1109:                                  else
                   1110:                                    func (stream, "f%d", reg);
                   1111:                                }
                   1112:                                break;
                   1113:                              default:
                   1114:                                abort ();
                   1115:                              }
                   1116:                            break;
                   1117: 
                   1118:                          case 'y':
                   1119:                          case 'z':
                   1120:                            {
                   1121:                              int single = *c == 'y';
                   1122:                              int regno;
                   1123: 
                   1124:                              switch (bitstart)
                   1125:                                {
                   1126:                                case 4: /* Sm pair */
                   1127:                                  func (stream, "{");
                   1128:                                  /* Fall through.  */
                   1129:                                case 0: /* Sm, Dm */
                   1130:                                  regno = given & 0x0000000f;
                   1131:                                  if (single)
                   1132:                                    {
                   1133:                                      regno <<= 1;
                   1134:                                      regno += (given >> 5) & 1;
                   1135:                                    }
                   1136:                                  break;
                   1137: 
                   1138:                                case 1: /* Sd, Dd */
                   1139:                                  regno = (given >> 12) & 0x0000000f;
                   1140:                                  if (single)
                   1141:                                    {
                   1142:                                      regno <<= 1;
                   1143:                                      regno += (given >> 22) & 1;
                   1144:                                    }
                   1145:                                  break;
                   1146: 
                   1147:                                case 2: /* Sn, Dn */
                   1148:                                  regno = (given >> 16) & 0x0000000f;
                   1149:                                  if (single)
                   1150:                                    {
                   1151:                                      regno <<= 1;
                   1152:                                      regno += (given >> 7) & 1;
                   1153:                                    }
                   1154:                                  break;
                   1155: 
                   1156:                                case 3: /* List */
                   1157:                                  func (stream, "{");
                   1158:                                  regno = (given >> 12) & 0x0000000f;
                   1159:                                  if (single)
                   1160:                                    {
                   1161:                                      regno <<= 1;
                   1162:                                      regno += (given >> 22) & 1;
                   1163:                                    }
                   1164:                                  break;
                   1165: 
                   1166:                                  
                   1167:                                default:
                   1168:                                  abort ();
                   1169:                                }
                   1170: 
                   1171:                              func (stream, "%c%d", single ? 's' : 'd', regno);
                   1172: 
                   1173:                              if (bitstart == 3)
                   1174:                                {
                   1175:                                  int count = given & 0xff;
                   1176: 
                   1177:                                  if (single == 0)
                   1178:                                    count >>= 1;
                   1179: 
                   1180:                                  if (--count)
                   1181:                                    {
                   1182:                                      func (stream, "-%c%d",
                   1183:                                            single ? 's' : 'd',
                   1184:                                            regno + count);
                   1185:                                    }
                   1186: 
                   1187:                                  func (stream, "}");
                   1188:                                }
                   1189:                              else if (bitstart == 4)
                   1190:                                func (stream, ", %c%d}", single ? 's' : 'd',
                   1191:                                      regno + 1);
                   1192: 
                   1193:                              break;
                   1194:                            }
                   1195: 
                   1196:                          case '`':
                   1197:                            c++;
                   1198:                            if ((given & (1 << bitstart)) == 0)
                   1199:                              func (stream, "%c", *c);
                   1200:                            break;
                   1201:                          case '\'':
                   1202:                            c++;
                   1203:                            if ((given & (1 << bitstart)) != 0)
                   1204:                              func (stream, "%c", *c);
                   1205:                            break;
                   1206:                          case '?':
                   1207:                            ++c;
                   1208:                            if ((given & (1 << bitstart)) != 0)
                   1209:                              func (stream, "%c", *c++);
                   1210:                            else
                   1211:                              func (stream, "%c", *++c);
                   1212:                            break;
                   1213:                          default:
                   1214:                            abort ();
                   1215:                          }
                   1216:                        break;
                   1217: 
                   1218:                      default:
                   1219:                        abort ();
                   1220:                      }
                   1221:                    }
                   1222:                }
                   1223:              else
                   1224:                func (stream, "%c", *c);
                   1225:            }
                   1226:          return 4;
                   1227:        }
                   1228:     }
                   1229:   abort ();
                   1230: }
                   1231: 
                   1232: /* Print one instruction from PC on INFO->STREAM.
                   1233:    Return the size of the instruction. */
                   1234: 
                   1235: static int
                   1236: print_insn_thumb (pc, info, given)
                   1237:      bfd_vma                   pc;
                   1238:      struct disassemble_info * info;
                   1239:      long                      given;
                   1240: {
                   1241:   struct thumb_opcode * insn;
                   1242:   void *                stream = info->stream;
                   1243:   fprintf_ftype         func = info->fprintf_func;
                   1244: 
                   1245:   for (insn = thumb_opcodes; insn->assembler; insn++)
                   1246:     {
                   1247:       if ((given & insn->mask) == insn->value)
                   1248:         {
                   1249:           char * c = insn->assembler;
                   1250: 
                   1251:           /* Special processing for Thumb 2 instruction BL sequence:  */
                   1252:           if (!*c) /* Check for empty (not NULL) assembler string.  */
                   1253:             {
                   1254:              long offset;
                   1255:              
                   1256:              info->bytes_per_chunk = 4;
                   1257:              info->bytes_per_line  = 4;
                   1258: 
                   1259:              offset = BDISP23 (given);
                   1260:              offset = offset * 2 + pc + 4;
                   1261: 
                   1262:              if ((given & 0x10000000) == 0)
                   1263:                {
                   1264:                  func (stream, "blx\t");
                   1265:                  offset &= 0xfffffffc;
                   1266:                }
                   1267:              else
                   1268:                func (stream, "bl\t");
                   1269: 
                   1270:              info->print_address_func (offset, info);
                   1271:               return 4;
                   1272:             }
                   1273:           else
                   1274:             {
                   1275:              info->bytes_per_chunk = 2;
                   1276:              info->bytes_per_line  = 4;
                   1277:                      
                   1278:               given &= 0xffff;
                   1279:              
                   1280:               for (; *c; c++)
                   1281:                 {
                   1282:                   if (*c == '%')
                   1283:                     {
                   1284:                       int domaskpc = 0;
                   1285:                       int domasklr = 0;
                   1286:                      
                   1287:                       switch (*++c)
                   1288:                         {
                   1289:                         case '%':
                   1290:                           func (stream, "%%");
                   1291:                           break;
                   1292: 
                   1293:                         case 'S':
                   1294:                           {
                   1295:                             long reg;
                   1296:                            
                   1297:                             reg = (given >> 3) & 0x7;
                   1298:                             if (given & (1 << 6))
                   1299:                               reg += 8;
                   1300:                            
                   1301:                             func (stream, "%s", arm_regnames[reg]);
                   1302:                           }
                   1303:                           break;
                   1304: 
                   1305:                         case 'D':
                   1306:                           {
                   1307:                             long reg;
                   1308:                            
                   1309:                             reg = given & 0x7;
                   1310:                             if (given & (1 << 7))
                   1311:                              reg += 8;
                   1312:                            
                   1313:                             func (stream, "%s", arm_regnames[reg]);
                   1314:                           }
                   1315:                           break;
                   1316: 
                   1317:                         case 'T':
                   1318:                           func (stream, "%s",
                   1319:                                 arm_conditional [(given >> 8) & 0xf]);
                   1320:                           break;
                   1321: 
                   1322:                         case 'N':
                   1323:                           if (given & (1 << 8))
                   1324:                             domasklr = 1;
                   1325:                           /* Fall through.  */
                   1326:                         case 'O':
                   1327:                           if (*c == 'O' && (given & (1 << 8)))
                   1328:                             domaskpc = 1;
                   1329:                           /* Fall through.  */
                   1330:                         case 'M':
                   1331:                           {
                   1332:                             int started = 0;
                   1333:                             int reg;
                   1334:                            
                   1335:                             func (stream, "{");
                   1336:                            
                   1337:                             /* It would be nice if we could spot
                   1338:                                ranges, and generate the rS-rE format: */
                   1339:                             for (reg = 0; (reg < 8); reg++)
                   1340:                               if ((given & (1 << reg)) != 0)
                   1341:                                 {
                   1342:                                   if (started)
                   1343:                                     func (stream, ", ");
                   1344:                                   started = 1;
                   1345:                                   func (stream, "%s", arm_regnames[reg]);
                   1346:                                 }
                   1347: 
                   1348:                             if (domasklr)
                   1349:                               {
                   1350:                                 if (started)
                   1351:                                   func (stream, ", ");
                   1352:                                 started = 1;
                   1353:                                 func (stream, arm_regnames[14] /* "lr" */);
                   1354:                               }
                   1355: 
                   1356:                             if (domaskpc)
                   1357:                               {
                   1358:                                 if (started)
                   1359:                                   func (stream, ", ");
                   1360:                                 func (stream, arm_regnames[15] /* "pc" */);
                   1361:                               }
                   1362: 
                   1363:                             func (stream, "}");
                   1364:                           }
                   1365:                           break;
                   1366: 
                   1367: 
                   1368:                         case '0': case '1': case '2': case '3': case '4': 
                   1369:                         case '5': case '6': case '7': case '8': case '9':
                   1370:                           {
                   1371:                             int bitstart = *c++ - '0';
                   1372:                             int bitend = 0;
                   1373:                            
                   1374:                             while (*c >= '0' && *c <= '9')
                   1375:                               bitstart = (bitstart * 10) + *c++ - '0';
                   1376: 
                   1377:                             switch (*c)
                   1378:                               {
                   1379:                               case '-':
                   1380:                                 {
                   1381:                                   long reg;
                   1382:                                  
                   1383:                                   c++;
                   1384:                                   while (*c >= '0' && *c <= '9')
                   1385:                                     bitend = (bitend * 10) + *c++ - '0';
                   1386:                                   if (!bitend)
                   1387:                                     abort ();
                   1388:                                   reg = given >> bitstart;
                   1389:                                   reg &= (2 << (bitend - bitstart)) - 1;
                   1390:                                   switch (*c)
                   1391:                                     {
                   1392:                                     case 'r':
                   1393:                                       func (stream, "%s", arm_regnames[reg]);
                   1394:                                       break;
                   1395: 
                   1396:                                     case 'd':
                   1397:                                       func (stream, "%d", reg);
                   1398:                                       break;
                   1399: 
                   1400:                                     case 'H':
                   1401:                                       func (stream, "%d", reg << 1);
                   1402:                                       break;
                   1403: 
                   1404:                                     case 'W':
                   1405:                                       func (stream, "%d", reg << 2);
                   1406:                                       break;
                   1407: 
                   1408:                                     case 'a':
                   1409:                                      /* PC-relative address -- the bottom two
                   1410:                                         bits of the address are dropped
                   1411:                                         before the calculation.  */
                   1412:                                       info->print_address_func
                   1413:                                        (((pc + 4) & ~3) + (reg << 2), info);
                   1414:                                       break;
                   1415: 
                   1416:                                     case 'x':
                   1417:                                       func (stream, "0x%04x", reg);
                   1418:                                       break;
                   1419: 
                   1420:                                     case 'I':
                   1421:                                       reg = ((reg ^ (1 << bitend)) - (1 << bitend));
                   1422:                                       func (stream, "%d", reg);
                   1423:                                       break;
                   1424: 
                   1425:                                     case 'B':
                   1426:                                       reg = ((reg ^ (1 << bitend)) - (1 << bitend));
                   1427:                                       (*info->print_address_func)
                   1428:                                         (reg * 2 + pc + 4, info);
                   1429:                                       break;
                   1430: 
                   1431:                                     default:
                   1432:                                       abort ();
                   1433:                                     }
                   1434:                                 }
                   1435:                                 break;
                   1436: 
                   1437:                               case '\'':
                   1438:                                 c++;
                   1439:                                 if ((given & (1 << bitstart)) != 0)
                   1440:                                   func (stream, "%c", *c);
                   1441:                                 break;
                   1442: 
                   1443:                               case '?':
                   1444:                                 ++c;
                   1445:                                 if ((given & (1 << bitstart)) != 0)
                   1446:                                   func (stream, "%c", *c++);
                   1447:                                 else
                   1448:                                   func (stream, "%c", *++c);
                   1449:                                 break;
                   1450: 
                   1451:                               default:
                   1452:                                  abort ();
                   1453:                               }
                   1454:                           }
                   1455:                           break;
                   1456: 
                   1457:                         default:
                   1458:                           abort ();
                   1459:                         }
                   1460:                     }
                   1461:                   else
                   1462:                     func (stream, "%c", *c);
                   1463:                 }
                   1464:              }
                   1465:           return 2;
                   1466:        }
                   1467:     }
                   1468: 
                   1469:   /* No match.  */
                   1470:   abort ();
                   1471: }
                   1472: 
                   1473: /* Parse an individual disassembler option.  */
                   1474: 
                   1475: void
                   1476: parse_arm_disassembler_option (option)
                   1477:      char * option;
                   1478: {
                   1479:   if (option == NULL)
                   1480:     return;
                   1481:       
                   1482:   if (strneq (option, "reg-names-", 10))
                   1483:     {
                   1484:       int i;
                   1485:        
                   1486:       option += 10;
                   1487: 
                   1488:       for (i = NUM_ARM_REGNAMES; i--;)
                   1489:        if (streq (option, regnames[i].name))
                   1490:          {
                   1491:            regname_selected = i;
                   1492:            break;
                   1493:          }
                   1494:       
                   1495:       if (i < 0)
                   1496:        fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
                   1497:     }
                   1498:   else if (streq (option, "force-thumb"))
                   1499:     force_thumb = 1;
                   1500:   else if (streq (option, "no-force-thumb"))
                   1501:     force_thumb = 0;
                   1502:   else
                   1503:     fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
                   1504:   
                   1505:   return;
                   1506: }
                   1507: 
                   1508: /* Parse the string of disassembler options, spliting it at whitespaces.  */
                   1509: 
                   1510: static void
                   1511: parse_disassembler_options (options)
                   1512:      char * options;
                   1513: {
                   1514:   char * space;
                   1515:   
                   1516:   if (options == NULL)
                   1517:     return;
                   1518: 
                   1519:   do
                   1520:     {
                   1521:       space = strchr (options, ' ');
                   1522: 
                   1523:       if (space)
                   1524:        {
                   1525:          * space = '\0';
                   1526:          parse_arm_disassembler_option (options);
                   1527:          * space = ' ';
                   1528:          options = space + 1;
                   1529:        }
                   1530:       else
                   1531:        parse_arm_disassembler_option (options);
                   1532:     }
                   1533:   while (space);
                   1534: }
                   1535: 
                   1536: /* NOTE: There are no checks in these routines that
                   1537:    the relevant number of data bytes exist.  */
                   1538: 
                   1539: int
                   1540: print_insn_arm (pc, info)
                   1541:      bfd_vma pc;
                   1542:      struct disassemble_info * info;
                   1543: {
                   1544:   unsigned char      b[4];
                   1545:   long               given;
                   1546:   int                status;
                   1547:   int                is_thumb;
                   1548:   int little;
                   1549: 
                   1550:   if (info->disassembler_options)
                   1551:     {
                   1552:       parse_disassembler_options (info->disassembler_options);
                   1553:       
                   1554:       /* To avoid repeated parsing of these options, we remove them here.  */
                   1555:       info->disassembler_options = NULL;
                   1556:     }
                   1557:   
                   1558:   is_thumb = force_thumb;
                   1559:   if (pc & 1)
                   1560:     {
                   1561:       is_thumb = 1;
                   1562:       pc &= ~(bfd_vma) 1;
                   1563:     }
                   1564:   
                   1565: #if 0
                   1566:   if (!is_thumb && info->symbols != NULL)
                   1567:     {
                   1568:       if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
                   1569:        {
                   1570:          coff_symbol_type * cs;
                   1571:          
                   1572:          cs = coffsymbol (*info->symbols);
                   1573:          is_thumb = (   cs->native->u.syment.n_sclass == C_THUMBEXT
                   1574:                      || cs->native->u.syment.n_sclass == C_THUMBSTAT
                   1575:                      || cs->native->u.syment.n_sclass == C_THUMBLABEL
                   1576:                      || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
                   1577:                      || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
                   1578:        }
                   1579:       else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour)
                   1580:        {
                   1581:          elf_symbol_type *  es;
                   1582:          unsigned int       type;
                   1583:          
                   1584:          es = *(elf_symbol_type **)(info->symbols);
                   1585:          type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
                   1586:          
                   1587:          is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
                   1588:        }
                   1589:     }
                   1590: #endif
                   1591:   
                   1592:   little = (info->endian == BFD_ENDIAN_LITTLE);
                   1593:   info->bytes_per_chunk = 4;
                   1594:   info->display_endian  = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
                   1595: 
                   1596:   if (little)
                   1597:     {
                   1598:       status = info->read_memory_func (pc, (bfd_byte *) &b[0], 4, info);
                   1599:       if (status != 0 && is_thumb)
                   1600:        {
                   1601:          info->bytes_per_chunk = 2;
                   1602:          
                   1603:          status = info->read_memory_func (pc, (bfd_byte *) b, 2, info);
                   1604:          b[3] = b[2] = 0;
                   1605:        }
                   1606:       
                   1607:       if (status != 0)
                   1608:        {
                   1609:          info->memory_error_func (status, pc, info);
                   1610:          return -1;
                   1611:        }
                   1612:       
                   1613:       given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
                   1614:     }
                   1615:   else
                   1616:     {
                   1617:       status = info->read_memory_func
                   1618:        (pc & ~ 0x3, (bfd_byte *) &b[0], 4, info);
                   1619:       if (status != 0)
                   1620:        {
                   1621:          info->memory_error_func (status, pc, info);
                   1622:          return -1;
                   1623:        }
                   1624:       
                   1625:       if (is_thumb)
                   1626:        {
                   1627:          if (pc & 0x2)
                   1628:            {
                   1629:              given = (b[2] << 8) | b[3];
                   1630:              
                   1631:              status = info->read_memory_func
                   1632:                ((pc + 4) & ~ 0x3, (bfd_byte *) b, 4, info);
                   1633:              if (status != 0)
                   1634:                {
                   1635:                  info->memory_error_func (status, pc + 4, info);
                   1636:                  return -1;
                   1637:                }
                   1638:              
                   1639:              given |= (b[0] << 24) | (b[1] << 16);
                   1640:            }
                   1641:          else
                   1642:            given = (b[0] << 8) | b[1] | (b[2] << 24) | (b[3] << 16);
                   1643:        }
                   1644:       else
                   1645:        given = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3]);
                   1646:     }
                   1647:   
                   1648:   if (info->flags & INSN_HAS_RELOC)
                   1649:     /* If the instruction has a reloc associated with it, then
                   1650:        the offset field in the instruction will actually be the
                   1651:        addend for the reloc.  (We are using REL type relocs).
                   1652:        In such cases, we can ignore the pc when computing
                   1653:        addresses, since the addend is not currently pc-relative.  */
                   1654:     pc = 0;
                   1655:   if (is_thumb)
                   1656:     status = print_insn_thumb (pc, info, given);
                   1657:   else
                   1658:     status = print_insn_arm1 (pc, info, given);
                   1659: 
                   1660:   return status;
                   1661: }
                   1662: 
                   1663: void
                   1664: print_arm_disassembler_options (FILE * stream)
                   1665: {
                   1666:   int i;
                   1667: 
                   1668:   fprintf (stream, _("\n\
                   1669: The following ARM specific disassembler options are supported for use with\n\
                   1670: the -M switch:\n"));
                   1671:   
                   1672:   for (i = NUM_ARM_REGNAMES; i--;)
                   1673:     fprintf (stream, "  reg-names-%s %*c%s\n",
                   1674:             regnames[i].name,
                   1675:             (int)(14 - strlen (regnames[i].name)), ' ',
                   1676:             regnames[i].description);
                   1677: 
                   1678:   fprintf (stream, "  force-thumb              Assume all insns are Thumb insns\n");
                   1679:   fprintf (stream, "  no-force-thumb           Examine preceeding label to determine an insn's type\n\n");
                   1680: }

unix.superglobalmegacorp.com