This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Convert tc-arm.c to ISO C.


Hi Guys,

  I am applying the attached patch to update tc-arm.c to ISO C90.

Cheers
  Nick

PS. Apologies to Paul Brook - since this patch is going to interfere
with his recently posted patch.  I will take care of this issue.

2004-09-30  Nick Clifton  <nickc@redhat.com>

	* config/tc-arm.c: Use ISO C90 formatting.

Index: gas/config/tc-arm.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-arm.c,v
retrieving revision 1.178
diff -c -3 -p -r1.178 tc-arm.c
*** gas/config/tc-arm.c	30 Sep 2004 13:18:53 -0000	1.178
--- gas/config/tc-arm.c	30 Sep 2004 15:38:20 -0000
*************** static const struct reg_entry mav_dspsc_
*** 709,718 ****
  
  struct reg_map
  {
!   const struct reg_entry *names;
!   int max_regno;
!   struct hash_control *htab;
!   const char *expected;
  };
  
  struct reg_map all_reg_maps[] =
--- 709,718 ----
  
  struct reg_map
  {
!   const struct reg_entry * names;
!   int                      max_regno;
!   struct hash_control *    htab;
!   const char *             expected;
  };
  
  struct reg_map all_reg_maps[] =
*************** enum arm_reg_type
*** 753,1040 ****
    REG_TYPE_MAX = 13
  };
  
- /* Functions called by parser.  */
- /* ARM instructions.  */
- static void do_arit		PARAMS ((char *));
- static void do_cmp		PARAMS ((char *));
- static void do_mov		PARAMS ((char *));
- static void do_ldst		PARAMS ((char *));
- static void do_ldstt		PARAMS ((char *));
- static void do_ldmstm		PARAMS ((char *));
- static void do_branch		PARAMS ((char *));
- static void do_swi		PARAMS ((char *));
- 
- /* Pseudo Op codes.  */
- static void do_adr		PARAMS ((char *));
- static void do_adrl		PARAMS ((char *));
- static void do_empty		PARAMS ((char *));
- 
- /* ARM v2.  */
- static void do_mul		PARAMS ((char *));
- static void do_mla		PARAMS ((char *));
- 
- /* ARM v2S.  */
- static void do_swap		PARAMS ((char *));
- 
- /* ARM v3.  */
- static void do_msr		PARAMS ((char *));
- static void do_mrs		PARAMS ((char *));
- 
- /* ARM v3M.  */
- static void do_mull		PARAMS ((char *));
- 
- /* ARM v4.  */
- static void do_ldstv4		PARAMS ((char *));
- 
- /* ARM v4T.  */
- static void do_bx               PARAMS ((char *));
- 
- /* ARM v5T.  */
- static void do_blx		PARAMS ((char *));
- static void do_bkpt		PARAMS ((char *));
- static void do_clz		PARAMS ((char *));
- static void do_lstc2		PARAMS ((char *));
- static void do_cdp2		PARAMS ((char *));
- static void do_co_reg2		PARAMS ((char *));
- 
- /* ARM v5TExP.  */
- static void do_smla		PARAMS ((char *));
- static void do_smlal		PARAMS ((char *));
- static void do_smul		PARAMS ((char *));
- static void do_qadd		PARAMS ((char *));
- 
- /* ARM v5TE.  */
- static void do_pld		PARAMS ((char *));
- static void do_ldrd		PARAMS ((char *));
- static void do_co_reg2c		PARAMS ((char *));
- 
- /* ARM v5TEJ.  */
- static void do_bxj		PARAMS ((char *));
- 
- /* ARM V6. */
- static void do_cps              PARAMS ((char *));
- static void do_cpsi             PARAMS ((char *));
- static void do_ldrex            PARAMS ((char *));
- static void do_pkhbt            PARAMS ((char *));
- static void do_pkhtb            PARAMS ((char *));
- static void do_qadd16           PARAMS ((char *));
- static void do_rev              PARAMS ((char *));
- static void do_rfe              PARAMS ((char *));
- static void do_sxtah            PARAMS ((char *));
- static void do_sxth             PARAMS ((char *));
- static void do_setend           PARAMS ((char *));
- static void do_smlad            PARAMS ((char *));
- static void do_smlald           PARAMS ((char *));
- static void do_smmul            PARAMS ((char *));
- static void do_ssat             PARAMS ((char *));
- static void do_usat             PARAMS ((char *));
- static void do_srs              PARAMS ((char *));
- static void do_ssat16           PARAMS ((char *));
- static void do_usat16           PARAMS ((char *));
- static void do_strex            PARAMS ((char *));
- static void do_umaal            PARAMS ((char *));
- 
- static void do_cps_mode         PARAMS ((char **));
- static void do_cps_flags        PARAMS ((char **, int));
- static int do_endian_specifier  PARAMS ((char *));
- static void do_pkh_core         PARAMS ((char *, int));
- static void do_sat              PARAMS ((char **, int));
- static void do_sat16            PARAMS ((char **, int));
- 
- /* Coprocessor Instructions.  */
- static void do_cdp		PARAMS ((char *));
- static void do_lstc		PARAMS ((char *));
- static void do_co_reg		PARAMS ((char *));
- 
- /* FPA instructions.  */
- static void do_fpa_ctrl		PARAMS ((char *));
- static void do_fpa_ldst		PARAMS ((char *));
- static void do_fpa_ldmstm	PARAMS ((char *));
- static void do_fpa_dyadic	PARAMS ((char *));
- static void do_fpa_monadic	PARAMS ((char *));
- static void do_fpa_cmp		PARAMS ((char *));
- static void do_fpa_from_reg	PARAMS ((char *));
- static void do_fpa_to_reg	PARAMS ((char *));
- 
- /* VFP instructions.  */
- static void do_vfp_sp_monadic	PARAMS ((char *));
- static void do_vfp_dp_monadic	PARAMS ((char *));
- static void do_vfp_sp_dyadic	PARAMS ((char *));
- static void do_vfp_dp_dyadic	PARAMS ((char *));
- static void do_vfp_reg_from_sp  PARAMS ((char *));
- static void do_vfp_sp_from_reg  PARAMS ((char *));
- static void do_vfp_reg2_from_sp2 PARAMS ((char *));
- static void do_vfp_sp2_from_reg2 PARAMS ((char *));
- static void do_vfp_reg_from_dp  PARAMS ((char *));
- static void do_vfp_reg2_from_dp PARAMS ((char *));
- static void do_vfp_dp_from_reg  PARAMS ((char *));
- static void do_vfp_dp_from_reg2 PARAMS ((char *));
- static void do_vfp_reg_from_ctrl PARAMS ((char *));
- static void do_vfp_ctrl_from_reg PARAMS ((char *));
- static void do_vfp_sp_ldst	PARAMS ((char *));
- static void do_vfp_dp_ldst	PARAMS ((char *));
- static void do_vfp_sp_ldstmia	PARAMS ((char *));
- static void do_vfp_sp_ldstmdb	PARAMS ((char *));
- static void do_vfp_dp_ldstmia	PARAMS ((char *));
- static void do_vfp_dp_ldstmdb	PARAMS ((char *));
- static void do_vfp_xp_ldstmia	PARAMS ((char *));
- static void do_vfp_xp_ldstmdb	PARAMS ((char *));
- static void do_vfp_sp_compare_z	PARAMS ((char *));
- static void do_vfp_dp_compare_z	PARAMS ((char *));
- static void do_vfp_dp_sp_cvt	PARAMS ((char *));
- static void do_vfp_sp_dp_cvt	PARAMS ((char *));
- 
- /* XScale.  */
- static void do_xsc_mia		PARAMS ((char *));
- static void do_xsc_mar		PARAMS ((char *));
- static void do_xsc_mra		PARAMS ((char *));
- 
- /* Maverick.  */
- static void do_mav_binops	PARAMS ((char *, int, enum arm_reg_type,
- 					 enum arm_reg_type));
- static void do_mav_binops_1a	PARAMS ((char *));
- static void do_mav_binops_1b	PARAMS ((char *));
- static void do_mav_binops_1c	PARAMS ((char *));
- static void do_mav_binops_1d	PARAMS ((char *));
- static void do_mav_binops_1e	PARAMS ((char *));
- static void do_mav_binops_1f	PARAMS ((char *));
- static void do_mav_binops_1g	PARAMS ((char *));
- static void do_mav_binops_1h	PARAMS ((char *));
- static void do_mav_binops_1i	PARAMS ((char *));
- static void do_mav_binops_1j	PARAMS ((char *));
- static void do_mav_binops_1k	PARAMS ((char *));
- static void do_mav_binops_1l	PARAMS ((char *));
- static void do_mav_binops_1m	PARAMS ((char *));
- static void do_mav_binops_1n	PARAMS ((char *));
- static void do_mav_binops_1o	PARAMS ((char *));
- static void do_mav_binops_2a	PARAMS ((char *));
- static void do_mav_binops_2b	PARAMS ((char *));
- static void do_mav_binops_2c	PARAMS ((char *));
- static void do_mav_binops_3a	PARAMS ((char *));
- static void do_mav_binops_3b	PARAMS ((char *));
- static void do_mav_binops_3c	PARAMS ((char *));
- static void do_mav_binops_3d	PARAMS ((char *));
- static void do_mav_triple	PARAMS ((char *, int, enum arm_reg_type,
- 					 enum arm_reg_type,
- 					 enum arm_reg_type));
- static void do_mav_triple_4a	PARAMS ((char *));
- static void do_mav_triple_4b	PARAMS ((char *));
- static void do_mav_triple_5a	PARAMS ((char *));
- static void do_mav_triple_5b	PARAMS ((char *));
- static void do_mav_triple_5c	PARAMS ((char *));
- static void do_mav_triple_5d	PARAMS ((char *));
- static void do_mav_triple_5e	PARAMS ((char *));
- static void do_mav_triple_5f	PARAMS ((char *));
- static void do_mav_triple_5g	PARAMS ((char *));
- static void do_mav_triple_5h	PARAMS ((char *));
- static void do_mav_quad		PARAMS ((char *, int, enum arm_reg_type,
- 					 enum arm_reg_type,
- 					 enum arm_reg_type,
- 					 enum arm_reg_type));
- static void do_mav_quad_6a	PARAMS ((char *));
- static void do_mav_quad_6b	PARAMS ((char *));
- static void do_mav_dspsc_1	PARAMS ((char *));
- static void do_mav_dspsc_2	PARAMS ((char *));
- static void do_mav_shift	PARAMS ((char *, enum arm_reg_type,
- 					 enum arm_reg_type));
- static void do_mav_shift_1	PARAMS ((char *));
- static void do_mav_shift_2	PARAMS ((char *));
- static void do_mav_ldst		PARAMS ((char *, enum arm_reg_type));
- static void do_mav_ldst_1	PARAMS ((char *));
- static void do_mav_ldst_2	PARAMS ((char *));
- static void do_mav_ldst_3	PARAMS ((char *));
- static void do_mav_ldst_4	PARAMS ((char *));
- 
- static int mav_reg_required_here	PARAMS ((char **, int,
- 						 enum arm_reg_type));
- static int mav_parse_offset	PARAMS ((char **, int *));
- 
- static void fix_new_arm		PARAMS ((fragS *, int, short, expressionS *,
- 					 int, int));
- static int arm_reg_parse	PARAMS ((char **, struct hash_control *));
- static enum arm_reg_type arm_reg_parse_any PARAMS ((char *));
- static const struct asm_psr * arm_psr_parse PARAMS ((char **));
- static void symbol_locate	PARAMS ((symbolS *, const char *, segT, valueT,
- 					 fragS *));
- static int add_to_lit_pool	PARAMS ((void));
- static unsigned validate_immediate PARAMS ((unsigned));
- static unsigned validate_immediate_twopart PARAMS ((unsigned int,
- 						    unsigned int *));
- static int validate_offset_imm	PARAMS ((unsigned int, int));
- static void opcode_select	PARAMS ((int));
- static void end_of_line		PARAMS ((char *));
- static int reg_required_here	PARAMS ((char **, int));
- static int psr_required_here	PARAMS ((char **));
- static int co_proc_number	PARAMS ((char **));
- static int cp_opc_expr		PARAMS ((char **, int, int));
- static int cp_reg_required_here	PARAMS ((char **, int));
- static int fp_reg_required_here	PARAMS ((char **, int));
- static int vfp_sp_reg_required_here PARAMS ((char **, enum vfp_sp_reg_pos));
- static int vfp_dp_reg_required_here PARAMS ((char **, enum vfp_dp_reg_pos));
- static void vfp_sp_ldstm	PARAMS ((char *, enum vfp_ldstm_type));
- static void vfp_dp_ldstm	PARAMS ((char *, enum vfp_ldstm_type));
- static long vfp_sp_reg_list	PARAMS ((char **, enum vfp_sp_reg_pos));
- static long vfp_dp_reg_list	PARAMS ((char **));
- static int vfp_psr_required_here PARAMS ((char **str));
- static const struct vfp_reg *vfp_psr_parse PARAMS ((char **str));
- static int cp_address_offset	PARAMS ((char **));
- static int cp_address_required_here	PARAMS ((char **, int));
- static int my_get_float_expression	PARAMS ((char **));
- static int skip_past_comma	PARAMS ((char **));
- static int walk_no_bignums	PARAMS ((symbolS *));
- static int negate_data_op	PARAMS ((unsigned long *, unsigned long));
- static int data_op2		PARAMS ((char **));
- static int fp_op2		PARAMS ((char **));
- static long reg_list		PARAMS ((char **));
- static void thumb_load_store	PARAMS ((char *, int, int));
- static int decode_shift		PARAMS ((char **, int));
- static int ldst_extend		PARAMS ((char **));
- static int ldst_extend_v4		PARAMS ((char **));
- static void thumb_add_sub	PARAMS ((char *, int));
- static void insert_reg		PARAMS ((const struct reg_entry *,
- 					 struct hash_control *));
- static void thumb_shift		PARAMS ((char *, int));
- static void thumb_mov_compare	PARAMS ((char *, int));
- static void build_arm_ops_hsh	PARAMS ((void));
- static void set_constant_flonums	PARAMS ((void));
- static valueT md_chars_to_number	PARAMS ((char *, int));
- static void build_reg_hsh	PARAMS ((struct reg_map *));
- static void insert_reg_alias	PARAMS ((char *, int, struct hash_control *));
- static int create_register_alias	PARAMS ((char *, char *));
- static void output_inst		PARAMS ((const char *));
- static int accum0_required_here PARAMS ((char **));
- static int ld_mode_required_here PARAMS ((char **));
- static void do_branch25         PARAMS ((char *));
- static symbolS * find_real_start PARAMS ((symbolS *));
- #ifdef OBJ_ELF
- static bfd_reloc_code_real_type	arm_parse_reloc PARAMS ((void));
- #endif
- 
- static int wreg_required_here   PARAMS ((char **, int, enum wreg_type));
- static void do_iwmmxt_byte_addr PARAMS ((char *));
- static void do_iwmmxt_tandc     PARAMS ((char *));
- static void do_iwmmxt_tbcst     PARAMS ((char *));
- static void do_iwmmxt_textrc    PARAMS ((char *));
- static void do_iwmmxt_textrm    PARAMS ((char *));
- static void do_iwmmxt_tinsr     PARAMS ((char *));
- static void do_iwmmxt_tmcr      PARAMS ((char *));
- static void do_iwmmxt_tmcrr     PARAMS ((char *));
- static void do_iwmmxt_tmia      PARAMS ((char *));
- static void do_iwmmxt_tmovmsk   PARAMS ((char *));
- static void do_iwmmxt_tmrc      PARAMS ((char *));
- static void do_iwmmxt_tmrrc     PARAMS ((char *));
- static void do_iwmmxt_torc      PARAMS ((char *));
- static void do_iwmmxt_waligni   PARAMS ((char *));
- static void do_iwmmxt_wmov      PARAMS ((char *));
- static void do_iwmmxt_word_addr PARAMS ((char *));
- static void do_iwmmxt_wrwr      PARAMS ((char *));
- static void do_iwmmxt_wrwrwcg   PARAMS ((char *));
- static void do_iwmmxt_wrwrwr    PARAMS ((char *));
- static void do_iwmmxt_wshufh    PARAMS ((char *));
- static void do_iwmmxt_wzero     PARAMS ((char *));
- static int cp_byte_address_offset         PARAMS ((char **));
- static int cp_byte_address_required_here  PARAMS ((char **));
- 
  /* ARM instructions take 4bytes in the object file, Thumb instructions
     take 2:  */
  #define INSN_SIZE       4
--- 753,758 ----
*************** struct asm_opcode
*** 1073,2417 ****
    unsigned long variant;
  
    /* Function to call to parse args.  */
!   void (* parms) PARAMS ((char *));
  };
  
! static const struct asm_opcode insns[] =
! {
!   /* Core ARM Instructions.  */
!   {"and",        0xe0000000, 3,  ARM_EXT_V1,       do_arit},
!   {"ands",       0xe0100000, 3,  ARM_EXT_V1,       do_arit},
!   {"eor",        0xe0200000, 3,  ARM_EXT_V1,       do_arit},
!   {"eors",       0xe0300000, 3,  ARM_EXT_V1,       do_arit},
!   {"sub",        0xe0400000, 3,  ARM_EXT_V1,       do_arit},
!   {"subs",       0xe0500000, 3,  ARM_EXT_V1,       do_arit},
!   {"rsb",        0xe0600000, 3,  ARM_EXT_V1,       do_arit},
!   {"rsbs",       0xe0700000, 3,  ARM_EXT_V1,       do_arit},
!   {"add",        0xe0800000, 3,  ARM_EXT_V1,       do_arit},
!   {"adds",       0xe0900000, 3,  ARM_EXT_V1,       do_arit},
!   {"adc",        0xe0a00000, 3,  ARM_EXT_V1,       do_arit},
!   {"adcs",       0xe0b00000, 3,  ARM_EXT_V1,       do_arit},
!   {"sbc",        0xe0c00000, 3,  ARM_EXT_V1,       do_arit},
!   {"sbcs",       0xe0d00000, 3,  ARM_EXT_V1,       do_arit},
!   {"rsc",        0xe0e00000, 3,  ARM_EXT_V1,       do_arit},
!   {"rscs",       0xe0f00000, 3,  ARM_EXT_V1,       do_arit},
!   {"orr",        0xe1800000, 3,  ARM_EXT_V1,       do_arit},
!   {"orrs",       0xe1900000, 3,  ARM_EXT_V1,       do_arit},
!   {"bic",        0xe1c00000, 3,  ARM_EXT_V1,       do_arit},
!   {"bics",       0xe1d00000, 3,  ARM_EXT_V1,       do_arit},
! 
!   {"tst",        0xe1100000, 3,  ARM_EXT_V1,       do_cmp},
!   {"tsts",       0xe1100000, 3,  ARM_EXT_V1,       do_cmp},
!   {"tstp",       0xe110f000, 3,  ARM_EXT_V1,       do_cmp},
!   {"teq",        0xe1300000, 3,  ARM_EXT_V1,       do_cmp},
!   {"teqs",       0xe1300000, 3,  ARM_EXT_V1,       do_cmp},
!   {"teqp",       0xe130f000, 3,  ARM_EXT_V1,       do_cmp},
!   {"cmp",        0xe1500000, 3,  ARM_EXT_V1,       do_cmp},
!   {"cmps",       0xe1500000, 3,  ARM_EXT_V1,       do_cmp},
!   {"cmpp",       0xe150f000, 3,  ARM_EXT_V1,       do_cmp},
!   {"cmn",        0xe1700000, 3,  ARM_EXT_V1,       do_cmp},
!   {"cmns",       0xe1700000, 3,  ARM_EXT_V1,       do_cmp},
!   {"cmnp",       0xe170f000, 3,  ARM_EXT_V1,       do_cmp},
  
!   {"mov",        0xe1a00000, 3,  ARM_EXT_V1,       do_mov},
!   {"movs",       0xe1b00000, 3,  ARM_EXT_V1,       do_mov},
!   {"mvn",        0xe1e00000, 3,  ARM_EXT_V1,       do_mov},
!   {"mvns",       0xe1f00000, 3,  ARM_EXT_V1,       do_mov},
  
!   {"ldr",        0xe4100000, 3,  ARM_EXT_V1,       do_ldst},
!   {"ldrb",       0xe4500000, 3,  ARM_EXT_V1,       do_ldst},
!   {"ldrt",       0xe4300000, 3,  ARM_EXT_V1,       do_ldstt},
!   {"ldrbt",      0xe4700000, 3,  ARM_EXT_V1,       do_ldstt},
!   {"str",        0xe4000000, 3,  ARM_EXT_V1,       do_ldst},
!   {"strb",       0xe4400000, 3,  ARM_EXT_V1,       do_ldst},
!   {"strt",       0xe4200000, 3,  ARM_EXT_V1,       do_ldstt},
!   {"strbt",      0xe4600000, 3,  ARM_EXT_V1,       do_ldstt},
  
!   {"stmia",      0xe8800000, 3,  ARM_EXT_V1,       do_ldmstm},
!   {"stmib",      0xe9800000, 3,  ARM_EXT_V1,       do_ldmstm},
!   {"stmda",      0xe8000000, 3,  ARM_EXT_V1,       do_ldmstm},
!   {"stmdb",      0xe9000000, 3,  ARM_EXT_V1,       do_ldmstm},
!   {"stmfd",      0xe9000000, 3,  ARM_EXT_V1,       do_ldmstm},
!   {"stmfa",      0xe9800000, 3,  ARM_EXT_V1,       do_ldmstm},
!   {"stmea",      0xe8800000, 3,  ARM_EXT_V1,       do_ldmstm},
!   {"stmed",      0xe8000000, 3,  ARM_EXT_V1,       do_ldmstm},
  
!   {"ldmia",      0xe8900000, 3,  ARM_EXT_V1,       do_ldmstm},
!   {"ldmib",      0xe9900000, 3,  ARM_EXT_V1,       do_ldmstm},
!   {"ldmda",      0xe8100000, 3,  ARM_EXT_V1,       do_ldmstm},
!   {"ldmdb",      0xe9100000, 3,  ARM_EXT_V1,       do_ldmstm},
!   {"ldmfd",      0xe8900000, 3,  ARM_EXT_V1,       do_ldmstm},
!   {"ldmfa",      0xe8100000, 3,  ARM_EXT_V1,       do_ldmstm},
!   {"ldmea",      0xe9100000, 3,  ARM_EXT_V1,       do_ldmstm},
!   {"ldmed",      0xe9900000, 3,  ARM_EXT_V1,       do_ldmstm},
  
!   {"swi",        0xef000000, 3,  ARM_EXT_V1,       do_swi},
! #ifdef TE_WINCE
!   /* XXX This is the wrong place to do this.  Think multi-arch.  */
!   {"bl",         0xeb000000, 2,  ARM_EXT_V1,       do_branch},
!   {"b",          0xea000000, 1,  ARM_EXT_V1,       do_branch},
! #else
!   {"bl",         0xebfffffe, 2,  ARM_EXT_V1,       do_branch},
!   {"b",          0xeafffffe, 1,  ARM_EXT_V1,       do_branch},
! #endif
  
!   /* Pseudo ops.  */
!   {"adr",        0xe28f0000, 3,  ARM_EXT_V1,       do_adr},
!   {"adrl",       0xe28f0000, 3,  ARM_EXT_V1,       do_adrl},
!   {"nop",        0xe1a00000, 3,  ARM_EXT_V1,       do_empty},
  
!   /* ARM 2 multiplies.  */
!   {"mul",        0xe0000090, 3,  ARM_EXT_V2,       do_mul},
!   {"muls",       0xe0100090, 3,  ARM_EXT_V2,       do_mul},
!   {"mla",        0xe0200090, 3,  ARM_EXT_V2,       do_mla},
!   {"mlas",       0xe0300090, 3,  ARM_EXT_V2,       do_mla},
  
!   /* Generic coprocessor instructions.  */
!   {"cdp",        0xee000000, 3,  ARM_EXT_V2,       do_cdp},
!   {"ldc",        0xec100000, 3,  ARM_EXT_V2,       do_lstc},
!   {"ldcl",       0xec500000, 3,  ARM_EXT_V2,       do_lstc},
!   {"stc",        0xec000000, 3,  ARM_EXT_V2,       do_lstc},
!   {"stcl",       0xec400000, 3,  ARM_EXT_V2,       do_lstc},
!   {"mcr",        0xee000010, 3,  ARM_EXT_V2,       do_co_reg},
!   {"mrc",        0xee100010, 3,  ARM_EXT_V2,       do_co_reg},
  
!   /* ARM 3 - swp instructions.  */
!   {"swp",        0xe1000090, 3,  ARM_EXT_V2S,      do_swap},
!   {"swpb",       0xe1400090, 3,  ARM_EXT_V2S,      do_swap},
  
!   /* ARM 6 Status register instructions.  */
!   {"mrs",        0xe10f0000, 3,  ARM_EXT_V3,       do_mrs},
!   {"msr",        0xe120f000, 3,  ARM_EXT_V3,       do_msr},
!   /* ScottB: our code uses     0xe128f000 for msr.
!      NickC:  but this is wrong because the bits 16 through 19 are
!              handled by the PSR_xxx defines above.  */
  
!   /* ARM 7M long multiplies.  */
!   {"smull",      0xe0c00090, 5,  ARM_EXT_V3M,      do_mull},
!   {"smulls",     0xe0d00090, 5,  ARM_EXT_V3M,      do_mull},
!   {"umull",      0xe0800090, 5,  ARM_EXT_V3M,      do_mull},
!   {"umulls",     0xe0900090, 5,  ARM_EXT_V3M,      do_mull},
!   {"smlal",      0xe0e00090, 5,  ARM_EXT_V3M,      do_mull},
!   {"smlals",     0xe0f00090, 5,  ARM_EXT_V3M,      do_mull},
!   {"umlal",      0xe0a00090, 5,  ARM_EXT_V3M,      do_mull},
!   {"umlals",     0xe0b00090, 5,  ARM_EXT_V3M,      do_mull},
  
!   /* ARM Architecture 4.  */
!   {"ldrh",       0xe01000b0, 3,  ARM_EXT_V4,       do_ldstv4},
!   {"ldrsh",      0xe01000f0, 3,  ARM_EXT_V4,       do_ldstv4},
!   {"ldrsb",      0xe01000d0, 3,  ARM_EXT_V4,       do_ldstv4},
!   {"strh",       0xe00000b0, 3,  ARM_EXT_V4,       do_ldstv4},
  
!   /* ARM Architecture 4T.  */
!   /* Note: bx (and blx) are required on V5, even if the processor does
!      not support Thumb.  */
!   {"bx",         0xe12fff10, 2,  ARM_EXT_V4T | ARM_EXT_V5, do_bx},
  
!   /*  ARM Architecture 5T.  */
!   /* Note: blx has 2 variants, so the .value is set dynamically.
!      Only one of the variants has conditional execution.  */
!   {"blx",        0xe0000000, 3,  ARM_EXT_V5,       do_blx},
!   {"clz",        0xe16f0f10, 3,  ARM_EXT_V5,       do_clz},
!   {"bkpt",       0xe1200070, 0,  ARM_EXT_V5,       do_bkpt},
!   {"ldc2",       0xfc100000, 0,  ARM_EXT_V5,       do_lstc2},
!   {"ldc2l",      0xfc500000, 0,  ARM_EXT_V5,       do_lstc2},
!   {"stc2",       0xfc000000, 0,  ARM_EXT_V5,       do_lstc2},
!   {"stc2l",      0xfc400000, 0,  ARM_EXT_V5,       do_lstc2},
!   {"cdp2",       0xfe000000, 0,  ARM_EXT_V5,       do_cdp2},
!   {"mcr2",       0xfe000010, 0,  ARM_EXT_V5,       do_co_reg2},
!   {"mrc2",       0xfe100010, 0,  ARM_EXT_V5,       do_co_reg2},
  
!   /*  ARM Architecture 5TExP.  */
!   {"smlabb",     0xe1000080, 6,  ARM_EXT_V5ExP,    do_smla},
!   {"smlatb",     0xe10000a0, 6,  ARM_EXT_V5ExP,    do_smla},
!   {"smlabt",     0xe10000c0, 6,  ARM_EXT_V5ExP,    do_smla},
!   {"smlatt",     0xe10000e0, 6,  ARM_EXT_V5ExP,    do_smla},
  
!   {"smlawb",     0xe1200080, 6,  ARM_EXT_V5ExP,    do_smla},
!   {"smlawt",     0xe12000c0, 6,  ARM_EXT_V5ExP,    do_smla},
  
!   {"smlalbb",    0xe1400080, 7,  ARM_EXT_V5ExP,    do_smlal},
!   {"smlaltb",    0xe14000a0, 7,  ARM_EXT_V5ExP,    do_smlal},
!   {"smlalbt",    0xe14000c0, 7,  ARM_EXT_V5ExP,    do_smlal},
!   {"smlaltt",    0xe14000e0, 7,  ARM_EXT_V5ExP,    do_smlal},
  
!   {"smulbb",     0xe1600080, 6,  ARM_EXT_V5ExP,    do_smul},
!   {"smultb",     0xe16000a0, 6,  ARM_EXT_V5ExP,    do_smul},
!   {"smulbt",     0xe16000c0, 6,  ARM_EXT_V5ExP,    do_smul},
!   {"smultt",     0xe16000e0, 6,  ARM_EXT_V5ExP,    do_smul},
  
!   {"smulwb",     0xe12000a0, 6,  ARM_EXT_V5ExP,    do_smul},
!   {"smulwt",     0xe12000e0, 6,  ARM_EXT_V5ExP,    do_smul},
  
!   {"qadd",       0xe1000050, 4,  ARM_EXT_V5ExP,    do_qadd},
!   {"qdadd",      0xe1400050, 5,  ARM_EXT_V5ExP,    do_qadd},
!   {"qsub",       0xe1200050, 4,  ARM_EXT_V5ExP,    do_qadd},
!   {"qdsub",      0xe1600050, 5,  ARM_EXT_V5ExP,    do_qadd},
! 
!   /*  ARM Architecture 5TE.  */
!   {"pld",        0xf450f000, 0,  ARM_EXT_V5E,      do_pld},
!   {"ldrd",       0xe00000d0, 3,  ARM_EXT_V5E,      do_ldrd},
!   {"strd",       0xe00000f0, 3,  ARM_EXT_V5E,      do_ldrd},
! 
!   {"mcrr",       0xec400000, 4,  ARM_EXT_V5E,      do_co_reg2c},
!   {"mrrc",       0xec500000, 4,  ARM_EXT_V5E,      do_co_reg2c},
! 
!   /*  ARM Architecture 5TEJ.  */
!   {"bxj",	 0xe12fff20, 3,  ARM_EXT_V5J,	   do_bxj},
! 
!   /*  ARM V6.  */
!   { "cps",       0xf1020000, 0,  ARM_EXT_V6,       do_cps},
!   { "cpsie",     0xf1080000, 0,  ARM_EXT_V6,       do_cpsi},
!   { "cpsid",     0xf10C0000, 0,  ARM_EXT_V6,       do_cpsi},
!   { "ldrex",     0xe1900f9f, 5,  ARM_EXT_V6,       do_ldrex},
!   { "mcrr2",     0xfc400000, 0,  ARM_EXT_V6,       do_co_reg2c},
!   { "mrrc2",     0xfc500000, 0,  ARM_EXT_V6,       do_co_reg2c},
!   { "pkhbt",     0xe6800010, 5,  ARM_EXT_V6,       do_pkhbt},
!   { "pkhtb",     0xe6800050, 5,  ARM_EXT_V6,       do_pkhtb},
!   { "qadd16",    0xe6200f10, 6,  ARM_EXT_V6,       do_qadd16},
!   { "qadd8",     0xe6200f90, 5,  ARM_EXT_V6,       do_qadd16},
!   { "qaddsubx",  0xe6200f30, 8,  ARM_EXT_V6,       do_qadd16},
!   { "qsub16",    0xe6200f70, 6,  ARM_EXT_V6,       do_qadd16},
!   { "qsub8",     0xe6200ff0, 5,  ARM_EXT_V6,       do_qadd16},
!   { "qsubaddx",  0xe6200f50, 8,  ARM_EXT_V6,       do_qadd16},
!   { "sadd16",    0xe6100f10, 6,  ARM_EXT_V6,       do_qadd16},
!   { "sadd8",     0xe6100f90, 5,  ARM_EXT_V6,       do_qadd16},
!   { "saddsubx",  0xe6100f30, 8,  ARM_EXT_V6,       do_qadd16},
!   { "shadd16",   0xe6300f10, 7,  ARM_EXT_V6,       do_qadd16},
!   { "shadd8",    0xe6300f90, 6,  ARM_EXT_V6,       do_qadd16},
!   { "shaddsubx", 0xe6300f30, 9,  ARM_EXT_V6,       do_qadd16},
!   { "shsub16",   0xe6300f70, 7,  ARM_EXT_V6,       do_qadd16},
!   { "shsub8",    0xe6300ff0, 6,  ARM_EXT_V6,       do_qadd16},
!   { "shsubaddx", 0xe6300f50, 9,  ARM_EXT_V6,       do_qadd16},
!   { "ssub16",    0xe6100f70, 6,  ARM_EXT_V6,       do_qadd16},
!   { "ssub8",     0xe6100ff0, 5,  ARM_EXT_V6,       do_qadd16},
!   { "ssubaddx",  0xe6100f50, 8,  ARM_EXT_V6,       do_qadd16},
!   { "uadd16",    0xe6500f10, 6,  ARM_EXT_V6,       do_qadd16},
!   { "uadd8",     0xe6500f90, 5,  ARM_EXT_V6,       do_qadd16},
!   { "uaddsubx",  0xe6500f30, 8,  ARM_EXT_V6,       do_qadd16},
!   { "uhadd16",   0xe6700f10, 7,  ARM_EXT_V6,       do_qadd16},
!   { "uhadd8",    0xe6700f90, 6,  ARM_EXT_V6,       do_qadd16},
!   { "uhaddsubx", 0xe6700f30, 9,  ARM_EXT_V6,       do_qadd16},
!   { "uhsub16",   0xe6700f70, 7,  ARM_EXT_V6,       do_qadd16},
!   { "uhsub8",    0xe6700ff0, 6,  ARM_EXT_V6,       do_qadd16},
!   { "uhsubaddx", 0xe6700f50, 9,  ARM_EXT_V6,       do_qadd16},
!   { "uqadd16",   0xe6600f10, 7,  ARM_EXT_V6,       do_qadd16},
!   { "uqadd8",    0xe6600f90, 6,  ARM_EXT_V6,       do_qadd16},
!   { "uqaddsubx", 0xe6600f30, 9,  ARM_EXT_V6,       do_qadd16},
!   { "uqsub16",   0xe6600f70, 7,  ARM_EXT_V6,       do_qadd16},
!   { "uqsub8",    0xe6600ff0, 6,  ARM_EXT_V6,       do_qadd16},
!   { "uqsubaddx", 0xe6600f50, 9,  ARM_EXT_V6,       do_qadd16},
!   { "usub16",    0xe6500f70, 6,  ARM_EXT_V6,       do_qadd16},
!   { "usub8",     0xe6500ff0, 5,  ARM_EXT_V6,       do_qadd16},
!   { "usubaddx",  0xe6500f50, 8,  ARM_EXT_V6,       do_qadd16},
!   { "rev",       0xe6bf0f30, 3,  ARM_EXT_V6,       do_rev},
!   { "rev16",     0xe6bf0fb0, 5,  ARM_EXT_V6,       do_rev},
!   { "revsh",     0xe6ff0fb0, 5,  ARM_EXT_V6,       do_rev},
!   { "rfeia",     0xf8900a00, 0,  ARM_EXT_V6,       do_rfe},
!   { "rfeib",     0xf9900a00, 0,  ARM_EXT_V6,       do_rfe},
!   { "rfeda",     0xf8100a00, 0,  ARM_EXT_V6,       do_rfe},
!   { "rfedb",     0xf9100a00, 0,  ARM_EXT_V6,       do_rfe},
!   { "rfefd",     0xf8900a00, 0,  ARM_EXT_V6,       do_rfe},
!   { "rfefa",     0xf9900a00, 0,  ARM_EXT_V6,       do_rfe},
!   { "rfeea",     0xf8100a00, 0,  ARM_EXT_V6,       do_rfe},
!   { "rfeed",     0xf9100a00, 0,  ARM_EXT_V6,       do_rfe},
!   { "sxtah",     0xe6b00070, 5,  ARM_EXT_V6,       do_sxtah},
!   { "sxtab16",   0xe6800070, 7,  ARM_EXT_V6,       do_sxtah},
!   { "sxtab",     0xe6a00070, 5,  ARM_EXT_V6,       do_sxtah},
!   { "sxth",      0xe6bf0070, 4,  ARM_EXT_V6,       do_sxth},
!   { "sxtb16",    0xe68f0070, 6,  ARM_EXT_V6,       do_sxth},
!   { "sxtb",      0xe6af0070, 4,  ARM_EXT_V6,       do_sxth},
!   { "uxtah",     0xe6f00070, 5,  ARM_EXT_V6,       do_sxtah},
!   { "uxtab16",   0xe6c00070, 7,  ARM_EXT_V6,       do_sxtah},
!   { "uxtab",     0xe6e00070, 5,  ARM_EXT_V6,       do_sxtah},
!   { "uxth",      0xe6ff0070, 4,  ARM_EXT_V6,       do_sxth},
!   { "uxtb16",    0xe6cf0070, 6,  ARM_EXT_V6,       do_sxth},
!   { "uxtb",      0xe6ef0070, 4,  ARM_EXT_V6,       do_sxth},
!   { "sel",       0xe68000b0, 3,  ARM_EXT_V6,       do_qadd16},
!   { "setend",    0xf1010000, 0,  ARM_EXT_V6,       do_setend},
!   { "smlad",     0xe7000010, 5,  ARM_EXT_V6,       do_smlad},
!   { "smladx",    0xe7000030, 6,  ARM_EXT_V6,       do_smlad},
!   { "smlald",    0xe7400010, 6,  ARM_EXT_V6,       do_smlald},
!   { "smlaldx",   0xe7400030, 7,  ARM_EXT_V6,       do_smlald},
!   { "smlsd",     0xe7000050, 5,  ARM_EXT_V6,       do_smlad},
!   { "smlsdx",    0xe7000070, 6,  ARM_EXT_V6,       do_smlad},
!   { "smlsld",    0xe7400050, 6,  ARM_EXT_V6,       do_smlald},
!   { "smlsldx",   0xe7400070, 7,  ARM_EXT_V6,       do_smlald},
!   { "smmla",     0xe7500010, 5,  ARM_EXT_V6,       do_smlad},
!   { "smmlar",    0xe7500030, 6,  ARM_EXT_V6,       do_smlad},
!   { "smmls",     0xe75000d0, 5,  ARM_EXT_V6,       do_smlad},
!   { "smmlsr",    0xe75000f0, 6,  ARM_EXT_V6,       do_smlad},
!   { "smmul",     0xe750f010, 5,  ARM_EXT_V6,       do_smmul},
!   { "smmulr",    0xe750f030, 6,  ARM_EXT_V6,       do_smmul},
!   { "smuad",     0xe700f010, 5,  ARM_EXT_V6,       do_smmul},
!   { "smuadx",    0xe700f030, 6,  ARM_EXT_V6,       do_smmul},
!   { "smusd",     0xe700f050, 5,  ARM_EXT_V6,       do_smmul},
!   { "smusdx",    0xe700f070, 6,  ARM_EXT_V6,       do_smmul},
!   { "srsia",     0xf8cd0500, 0,  ARM_EXT_V6,       do_srs},
!   { "srsib",     0xf9cd0500, 0,  ARM_EXT_V6,       do_srs},
!   { "srsda",     0xf84d0500, 0,  ARM_EXT_V6,       do_srs},
!   { "srsdb",     0xf94d0500, 0,  ARM_EXT_V6,       do_srs},
!   { "ssat",      0xe6a00010, 4,  ARM_EXT_V6,       do_ssat},
!   { "ssat16",    0xe6a00f30, 6,  ARM_EXT_V6,       do_ssat16},
!   { "strex",     0xe1800f90, 5,  ARM_EXT_V6,       do_strex},
!   { "umaal",     0xe0400090, 5,  ARM_EXT_V6,       do_umaal},
!   { "usad8",     0xe780f010, 5,  ARM_EXT_V6,       do_smmul},
!   { "usada8",    0xe7800010, 6,  ARM_EXT_V6,       do_smlad},
!   { "usat",      0xe6e00010, 4,  ARM_EXT_V6,       do_usat},
!   { "usat16",    0xe6e00f30, 6,  ARM_EXT_V6,       do_usat16},
! 
!   /* Core FPA instruction set (V1).  */
!   {"wfs",        0xee200110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
!   {"rfs",        0xee300110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
!   {"wfc",        0xee400110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
!   {"rfc",        0xee500110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
! 
!   {"ldfs",       0xec100100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
!   {"ldfd",       0xec108100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
!   {"ldfe",       0xec500100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
!   {"ldfp",       0xec508100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
! 
!   {"stfs",       0xec000100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
!   {"stfd",       0xec008100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
!   {"stfe",       0xec400100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
!   {"stfp",       0xec408100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
! 
!   {"mvfs",       0xee008100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"mvfsp",      0xee008120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"mvfsm",      0xee008140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"mvfsz",      0xee008160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"mvfd",       0xee008180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"mvfdp",      0xee0081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"mvfdm",      0xee0081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"mvfdz",      0xee0081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"mvfe",       0xee088100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"mvfep",      0xee088120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"mvfem",      0xee088140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"mvfez",      0xee088160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
! 
!   {"mnfs",       0xee108100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"mnfsp",      0xee108120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"mnfsm",      0xee108140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"mnfsz",      0xee108160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"mnfd",       0xee108180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"mnfdp",      0xee1081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"mnfdm",      0xee1081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"mnfdz",      0xee1081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"mnfe",       0xee188100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"mnfep",      0xee188120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"mnfem",      0xee188140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"mnfez",      0xee188160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
! 
!   {"abss",       0xee208100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"abssp",      0xee208120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"abssm",      0xee208140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"abssz",      0xee208160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"absd",       0xee208180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"absdp",      0xee2081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"absdm",      0xee2081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"absdz",      0xee2081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"abse",       0xee288100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"absep",      0xee288120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"absem",      0xee288140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"absez",      0xee288160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
! 
!   {"rnds",       0xee308100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"rndsp",      0xee308120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"rndsm",      0xee308140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"rndsz",      0xee308160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"rndd",       0xee308180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"rnddp",      0xee3081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"rnddm",      0xee3081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"rnddz",      0xee3081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"rnde",       0xee388100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"rndep",      0xee388120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"rndem",      0xee388140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"rndez",      0xee388160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
! 
!   {"sqts",       0xee408100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"sqtsp",      0xee408120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"sqtsm",      0xee408140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"sqtsz",      0xee408160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"sqtd",       0xee408180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"sqtdp",      0xee4081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"sqtdm",      0xee4081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"sqtdz",      0xee4081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"sqte",       0xee488100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"sqtep",      0xee488120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"sqtem",      0xee488140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"sqtez",      0xee488160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
! 
!   {"logs",       0xee508100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"logsp",      0xee508120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"logsm",      0xee508140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"logsz",      0xee508160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"logd",       0xee508180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"logdp",      0xee5081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"logdm",      0xee5081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"logdz",      0xee5081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"loge",       0xee588100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"logep",      0xee588120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"logem",      0xee588140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"logez",      0xee588160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
! 
!   {"lgns",       0xee608100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"lgnsp",      0xee608120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"lgnsm",      0xee608140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"lgnsz",      0xee608160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"lgnd",       0xee608180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"lgndp",      0xee6081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"lgndm",      0xee6081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"lgndz",      0xee6081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"lgne",       0xee688100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"lgnep",      0xee688120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"lgnem",      0xee688140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"lgnez",      0xee688160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
! 
!   {"exps",       0xee708100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"expsp",      0xee708120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"expsm",      0xee708140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"expsz",      0xee708160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"expd",       0xee708180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"expdp",      0xee7081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"expdm",      0xee7081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"expdz",      0xee7081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"expe",       0xee788100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"expep",      0xee788120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"expem",      0xee788140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"expdz",      0xee788160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
! 
!   {"sins",       0xee808100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"sinsp",      0xee808120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"sinsm",      0xee808140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"sinsz",      0xee808160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"sind",       0xee808180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"sindp",      0xee8081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"sindm",      0xee8081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"sindz",      0xee8081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"sine",       0xee888100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"sinep",      0xee888120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"sinem",      0xee888140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"sinez",      0xee888160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
! 
!   {"coss",       0xee908100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"cossp",      0xee908120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"cossm",      0xee908140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"cossz",      0xee908160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"cosd",       0xee908180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"cosdp",      0xee9081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"cosdm",      0xee9081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"cosdz",      0xee9081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"cose",       0xee988100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"cosep",      0xee988120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"cosem",      0xee988140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"cosez",      0xee988160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
! 
!   {"tans",       0xeea08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"tansp",      0xeea08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"tansm",      0xeea08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"tansz",      0xeea08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"tand",       0xeea08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"tandp",      0xeea081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"tandm",      0xeea081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"tandz",      0xeea081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"tane",       0xeea88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"tanep",      0xeea88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"tanem",      0xeea88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"tanez",      0xeea88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
! 
!   {"asns",       0xeeb08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"asnsp",      0xeeb08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"asnsm",      0xeeb08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"asnsz",      0xeeb08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"asnd",       0xeeb08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"asndp",      0xeeb081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"asndm",      0xeeb081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"asndz",      0xeeb081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"asne",       0xeeb88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"asnep",      0xeeb88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"asnem",      0xeeb88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"asnez",      0xeeb88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
! 
!   {"acss",       0xeec08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"acssp",      0xeec08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"acssm",      0xeec08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"acssz",      0xeec08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"acsd",       0xeec08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"acsdp",      0xeec081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"acsdm",      0xeec081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"acsdz",      0xeec081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"acse",       0xeec88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"acsep",      0xeec88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"acsem",      0xeec88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"acsez",      0xeec88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
! 
!   {"atns",       0xeed08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"atnsp",      0xeed08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"atnsm",      0xeed08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"atnsz",      0xeed08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"atnd",       0xeed08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"atndp",      0xeed081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"atndm",      0xeed081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"atndz",      0xeed081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"atne",       0xeed88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"atnep",      0xeed88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"atnem",      0xeed88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"atnez",      0xeed88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
! 
!   {"urds",       0xeee08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"urdsp",      0xeee08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"urdsm",      0xeee08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"urdsz",      0xeee08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"urdd",       0xeee08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"urddp",      0xeee081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"urddm",      0xeee081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"urddz",      0xeee081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"urde",       0xeee88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"urdep",      0xeee88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"urdem",      0xeee88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"urdez",      0xeee88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
! 
!   {"nrms",       0xeef08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"nrmsp",      0xeef08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"nrmsm",      0xeef08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"nrmsz",      0xeef08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"nrmd",       0xeef08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"nrmdp",      0xeef081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"nrmdm",      0xeef081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"nrmdz",      0xeef081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"nrme",       0xeef88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"nrmep",      0xeef88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"nrmem",      0xeef88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"nrmez",      0xeef88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
! 
!   {"adfs",       0xee000100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"adfsp",      0xee000120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"adfsm",      0xee000140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"adfsz",      0xee000160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"adfd",       0xee000180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"adfdp",      0xee0001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"adfdm",      0xee0001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"adfdz",      0xee0001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"adfe",       0xee080100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"adfep",      0xee080120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"adfem",      0xee080140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"adfez",      0xee080160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
! 
!   {"sufs",       0xee200100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"sufsp",      0xee200120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"sufsm",      0xee200140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"sufsz",      0xee200160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"sufd",       0xee200180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"sufdp",      0xee2001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"sufdm",      0xee2001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"sufdz",      0xee2001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"sufe",       0xee280100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"sufep",      0xee280120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"sufem",      0xee280140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"sufez",      0xee280160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
! 
!   {"rsfs",       0xee300100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rsfsp",      0xee300120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rsfsm",      0xee300140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rsfsz",      0xee300160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rsfd",       0xee300180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rsfdp",      0xee3001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rsfdm",      0xee3001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rsfdz",      0xee3001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rsfe",       0xee380100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rsfep",      0xee380120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rsfem",      0xee380140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rsfez",      0xee380160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
! 
!   {"mufs",       0xee100100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"mufsp",      0xee100120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"mufsm",      0xee100140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"mufsz",      0xee100160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"mufd",       0xee100180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"mufdp",      0xee1001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"mufdm",      0xee1001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"mufdz",      0xee1001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"mufe",       0xee180100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"mufep",      0xee180120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"mufem",      0xee180140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"mufez",      0xee180160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
! 
!   {"dvfs",       0xee400100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"dvfsp",      0xee400120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"dvfsm",      0xee400140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"dvfsz",      0xee400160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"dvfd",       0xee400180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"dvfdp",      0xee4001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"dvfdm",      0xee4001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"dvfdz",      0xee4001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"dvfe",       0xee480100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"dvfep",      0xee480120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"dvfem",      0xee480140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"dvfez",      0xee480160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
! 
!   {"rdfs",       0xee500100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rdfsp",      0xee500120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rdfsm",      0xee500140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rdfsz",      0xee500160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rdfd",       0xee500180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rdfdp",      0xee5001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rdfdm",      0xee5001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rdfdz",      0xee5001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rdfe",       0xee580100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rdfep",      0xee580120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rdfem",      0xee580140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rdfez",      0xee580160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
! 
!   {"pows",       0xee600100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"powsp",      0xee600120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"powsm",      0xee600140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"powsz",      0xee600160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"powd",       0xee600180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"powdp",      0xee6001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"powdm",      0xee6001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"powdz",      0xee6001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"powe",       0xee680100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"powep",      0xee680120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"powem",      0xee680140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"powez",      0xee680160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
! 
!   {"rpws",       0xee700100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rpwsp",      0xee700120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rpwsm",      0xee700140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rpwsz",      0xee700160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rpwd",       0xee700180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rpwdp",      0xee7001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rpwdm",      0xee7001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rpwdz",      0xee7001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rpwe",       0xee780100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rpwep",      0xee780120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rpwem",      0xee780140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rpwez",      0xee780160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
! 
!   {"rmfs",       0xee800100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rmfsp",      0xee800120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rmfsm",      0xee800140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rmfsz",      0xee800160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rmfd",       0xee800180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rmfdp",      0xee8001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rmfdm",      0xee8001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rmfdz",      0xee8001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rmfe",       0xee880100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rmfep",      0xee880120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rmfem",      0xee880140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rmfez",      0xee880160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
! 
!   {"fmls",       0xee900100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"fmlsp",      0xee900120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"fmlsm",      0xee900140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"fmlsz",      0xee900160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"fmld",       0xee900180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"fmldp",      0xee9001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"fmldm",      0xee9001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"fmldz",      0xee9001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"fmle",       0xee980100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"fmlep",      0xee980120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"fmlem",      0xee980140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"fmlez",      0xee980160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
! 
!   {"fdvs",       0xeea00100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"fdvsp",      0xeea00120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"fdvsm",      0xeea00140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"fdvsz",      0xeea00160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"fdvd",       0xeea00180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"fdvdp",      0xeea001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"fdvdm",      0xeea001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"fdvdz",      0xeea001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"fdve",       0xeea80100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"fdvep",      0xeea80120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"fdvem",      0xeea80140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"fdvez",      0xeea80160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
! 
!   {"frds",       0xeeb00100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"frdsp",      0xeeb00120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"frdsm",      0xeeb00140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"frdsz",      0xeeb00160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"frdd",       0xeeb00180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"frddp",      0xeeb001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"frddm",      0xeeb001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"frddz",      0xeeb001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"frde",       0xeeb80100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"frdep",      0xeeb80120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"frdem",      0xeeb80140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"frdez",      0xeeb80160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
! 
!   {"pols",       0xeec00100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"polsp",      0xeec00120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"polsm",      0xeec00140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"polsz",      0xeec00160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"pold",       0xeec00180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"poldp",      0xeec001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"poldm",      0xeec001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"poldz",      0xeec001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"pole",       0xeec80100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"polep",      0xeec80120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"polem",      0xeec80140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"polez",      0xeec80160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
! 
!   {"cmf",        0xee90f110, 3,  FPU_FPA_EXT_V1,   do_fpa_cmp},
!   {"cmfe",       0xeed0f110, 3,  FPU_FPA_EXT_V1,   do_fpa_cmp},
!   {"cnf",        0xeeb0f110, 3,  FPU_FPA_EXT_V1,   do_fpa_cmp},
!   {"cnfe",       0xeef0f110, 3,  FPU_FPA_EXT_V1,   do_fpa_cmp},
!   /* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should
!      not be an optional suffix, but part of the instruction.  To be
!      compatible, we accept either.  */
!   {"cmfe",       0xeed0f110, 4,  FPU_FPA_EXT_V1,   do_fpa_cmp},
!   {"cnfe",       0xeef0f110, 4,  FPU_FPA_EXT_V1,   do_fpa_cmp},
! 
!   {"flts",       0xee000110, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
!   {"fltsp",      0xee000130, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
!   {"fltsm",      0xee000150, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
!   {"fltsz",      0xee000170, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
!   {"fltd",       0xee000190, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
!   {"fltdp",      0xee0001b0, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
!   {"fltdm",      0xee0001d0, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
!   {"fltdz",      0xee0001f0, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
!   {"flte",       0xee080110, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
!   {"fltep",      0xee080130, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
!   {"fltem",      0xee080150, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
!   {"fltez",      0xee080170, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
! 
!   /* The implementation of the FIX instruction is broken on some
!      assemblers, in that it accepts a precision specifier as well as a
!      rounding specifier, despite the fact that this is meaningless.
!      To be more compatible, we accept it as well, though of course it
!      does not set any bits.  */
!   {"fix",        0xee100110, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
!   {"fixp",       0xee100130, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
!   {"fixm",       0xee100150, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
!   {"fixz",       0xee100170, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
!   {"fixsp",      0xee100130, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
!   {"fixsm",      0xee100150, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
!   {"fixsz",      0xee100170, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
!   {"fixdp",      0xee100130, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
!   {"fixdm",      0xee100150, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
!   {"fixdz",      0xee100170, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
!   {"fixep",      0xee100130, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
!   {"fixem",      0xee100150, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
!   {"fixez",      0xee100170, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
! 
!   /* Instructions that were new with the real FPA, call them V2.  */
!   {"lfm",        0xec100200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
!   {"lfmfd",      0xec900200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
!   {"lfmea",      0xed100200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
!   {"sfm",        0xec000200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
!   {"sfmfd",      0xed000200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
!   {"sfmea",      0xec800200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
! 
!   /* VFP V1xD (single precision).  */
!   /* Moves and type conversions.  */
!   {"fcpys",   0xeeb00a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
!   {"fmrs",    0xee100a10, 4, FPU_VFP_EXT_V1xD, do_vfp_reg_from_sp},
!   {"fmsr",    0xee000a10, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_from_reg},
!   {"fmstat",  0xeef1fa10, 6, FPU_VFP_EXT_V1xD, do_empty},
!   {"fsitos",  0xeeb80ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
!   {"fuitos",  0xeeb80a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
!   {"ftosis",  0xeebd0a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
!   {"ftosizs", 0xeebd0ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
!   {"ftouis",  0xeebc0a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
!   {"ftouizs", 0xeebc0ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
!   {"fmrx",    0xeef00a10, 4, FPU_VFP_EXT_V1xD, do_vfp_reg_from_ctrl},
!   {"fmxr",    0xeee00a10, 4, FPU_VFP_EXT_V1xD, do_vfp_ctrl_from_reg},
! 
!   /* Memory operations.  */
!   {"flds",    0xed100a00, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_ldst},
!   {"fsts",    0xed000a00, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_ldst},
!   {"fldmias", 0xec900a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
!   {"fldmfds", 0xec900a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
!   {"fldmdbs", 0xed300a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
!   {"fldmeas", 0xed300a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
!   {"fldmiax", 0xec900b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
!   {"fldmfdx", 0xec900b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
!   {"fldmdbx", 0xed300b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
!   {"fldmeax", 0xed300b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
!   {"fstmias", 0xec800a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
!   {"fstmeas", 0xec800a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
!   {"fstmdbs", 0xed200a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
!   {"fstmfds", 0xed200a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
!   {"fstmiax", 0xec800b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
!   {"fstmeax", 0xec800b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
!   {"fstmdbx", 0xed200b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
!   {"fstmfdx", 0xed200b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
! 
!   /* Monadic operations.  */
!   {"fabss",   0xeeb00ac0, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
!   {"fnegs",   0xeeb10a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
!   {"fsqrts",  0xeeb10ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
! 
!   /* Dyadic operations.  */
!   {"fadds",   0xee300a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
!   {"fsubs",   0xee300a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
!   {"fmuls",   0xee200a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
!   {"fdivs",   0xee800a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
!   {"fmacs",   0xee000a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
!   {"fmscs",   0xee100a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
!   {"fnmuls",  0xee200a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
!   {"fnmacs",  0xee000a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
!   {"fnmscs",  0xee100a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
! 
!   /* Comparisons.  */
!   {"fcmps",   0xeeb40a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
!   {"fcmpzs",  0xeeb50a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_compare_z},
!   {"fcmpes",  0xeeb40ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
!   {"fcmpezs", 0xeeb50ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_compare_z},
! 
!   /* VFP V1 (Double precision).  */
!   /* Moves and type conversions.  */
!   {"fcpyd",   0xeeb00b40, 5, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
!   {"fcvtds",  0xeeb70ac0, 6, FPU_VFP_EXT_V1,   do_vfp_dp_sp_cvt},
!   {"fcvtsd",  0xeeb70bc0, 6, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
!   {"fmdhr",   0xee200b10, 5, FPU_VFP_EXT_V1,   do_vfp_dp_from_reg},
!   {"fmdlr",   0xee000b10, 5, FPU_VFP_EXT_V1,   do_vfp_dp_from_reg},
!   {"fmrdh",   0xee300b10, 5, FPU_VFP_EXT_V1,   do_vfp_reg_from_dp},
!   {"fmrdl",   0xee100b10, 5, FPU_VFP_EXT_V1,   do_vfp_reg_from_dp},
!   {"fsitod",  0xeeb80bc0, 6, FPU_VFP_EXT_V1,   do_vfp_dp_sp_cvt},
!   {"fuitod",  0xeeb80b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_sp_cvt},
!   {"ftosid",  0xeebd0b40, 6, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
!   {"ftosizd", 0xeebd0bc0, 7, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
!   {"ftouid",  0xeebc0b40, 6, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
!   {"ftouizd", 0xeebc0bc0, 7, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
! 
!   /* Memory operations.  */
!   {"fldd",    0xed100b00, 4, FPU_VFP_EXT_V1,   do_vfp_dp_ldst},
!   {"fstd",    0xed000b00, 4, FPU_VFP_EXT_V1,   do_vfp_dp_ldst},
!   {"fldmiad", 0xec900b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmia},
!   {"fldmfdd", 0xec900b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmia},
!   {"fldmdbd", 0xed300b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmdb},
!   {"fldmead", 0xed300b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmdb},
!   {"fstmiad", 0xec800b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmia},
!   {"fstmead", 0xec800b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmia},
!   {"fstmdbd", 0xed200b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmdb},
!   {"fstmfdd", 0xed200b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmdb},
! 
!   /* Monadic operations.  */
!   {"fabsd",   0xeeb00bc0, 5, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
!   {"fnegd",   0xeeb10b40, 5, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
!   {"fsqrtd",  0xeeb10bc0, 6, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
! 
!   /* Dyadic operations.  */
!   {"faddd",   0xee300b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
!   {"fsubd",   0xee300b40, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
!   {"fmuld",   0xee200b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
!   {"fdivd",   0xee800b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
!   {"fmacd",   0xee000b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
!   {"fmscd",   0xee100b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
!   {"fnmuld",  0xee200b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
!   {"fnmacd",  0xee000b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
!   {"fnmscd",  0xee100b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
! 
!   /* Comparisons.  */
!   {"fcmpd",   0xeeb40b40, 5, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
!   {"fcmpzd",  0xeeb50b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_compare_z},
!   {"fcmped",  0xeeb40bc0, 6, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
!   {"fcmpezd", 0xeeb50bc0, 7, FPU_VFP_EXT_V1,   do_vfp_dp_compare_z},
! 
!   /* VFP V2.  */
!   {"fmsrr",   0xec400a10, 5, FPU_VFP_EXT_V2,   do_vfp_sp2_from_reg2},
!   {"fmrrs",   0xec500a10, 5, FPU_VFP_EXT_V2,   do_vfp_reg2_from_sp2},
!   {"fmdrr",   0xec400b10, 5, FPU_VFP_EXT_V2,   do_vfp_dp_from_reg2},
!   {"fmrrd",   0xec500b10, 5, FPU_VFP_EXT_V2,   do_vfp_reg2_from_dp},
! 
!   /* Intel XScale extensions to ARM V5 ISA.  (All use CP0).  */
!   {"mia",        0xee200010, 3,  ARM_CEXT_XSCALE,   do_xsc_mia},
!   {"miaph",      0xee280010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
!   {"miabb",      0xee2c0010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
!   {"miabt",      0xee2d0010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
!   {"miatb",      0xee2e0010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
!   {"miatt",      0xee2f0010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
!   {"mar",        0xec400000, 3,  ARM_CEXT_XSCALE,   do_xsc_mar},
!   {"mra",        0xec500000, 3,  ARM_CEXT_XSCALE,   do_xsc_mra},
! 
!   /* Intel Wireless MMX technology instructions.  */
!   {"tandcb",     0xee130130, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tandc},
!   {"tandch",     0xee530130, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tandc},
!   {"tandcw",     0xee930130, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tandc},
!   {"tbcstb",     0xee400010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tbcst},
!   {"tbcsth",     0xee400050, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tbcst},
!   {"tbcstw",     0xee400090, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tbcst},
!   {"textrcb",    0xee130170, 7, ARM_CEXT_IWMMXT, do_iwmmxt_textrc},
!   {"textrch",    0xee530170, 7, ARM_CEXT_IWMMXT, do_iwmmxt_textrc},
!   {"textrcw",    0xee930170, 7, ARM_CEXT_IWMMXT, do_iwmmxt_textrc},
!   {"textrmub",   0xee100070, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
!   {"textrmuh",   0xee500070, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
!   {"textrmuw",   0xee900070, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
!   {"textrmsb",   0xee100078, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
!   {"textrmsh",   0xee500078, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
!   {"textrmsw",   0xee900078, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
!   {"tinsrb",     0xee600010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tinsr},
!   {"tinsrh",     0xee600050, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tinsr},
!   {"tinsrw",     0xee600090, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tinsr},
!   {"tmcr",       0xee000110, 4, ARM_CEXT_IWMMXT, do_iwmmxt_tmcr},
!   {"tmcrr",      0xec400000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_tmcrr},
!   {"tmia",       0xee200010, 4, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
!   {"tmiaph",     0xee280010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
!   {"tmiabb",     0xee2c0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
!   {"tmiabt",     0xee2d0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
!   {"tmiatb",     0xee2e0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
!   {"tmiatt",     0xee2f0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
!   {"tmovmskb",   0xee100030, 8, ARM_CEXT_IWMMXT, do_iwmmxt_tmovmsk},
!   {"tmovmskh",   0xee500030, 8, ARM_CEXT_IWMMXT, do_iwmmxt_tmovmsk},
!   {"tmovmskw",   0xee900030, 8, ARM_CEXT_IWMMXT, do_iwmmxt_tmovmsk},
!   {"tmrc",       0xee100110, 4, ARM_CEXT_IWMMXT, do_iwmmxt_tmrc},
!   {"tmrrc",      0xec500000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_tmrrc},
!   {"torcb",      0xee130150, 5, ARM_CEXT_IWMMXT, do_iwmmxt_torc},
!   {"torch",      0xee530150, 5, ARM_CEXT_IWMMXT, do_iwmmxt_torc},
!   {"torcw",      0xee930150, 5, ARM_CEXT_IWMMXT, do_iwmmxt_torc},
!   {"waccb",      0xee0001c0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
!   {"wacch",      0xee4001c0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
!   {"waccw",      0xee8001c0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
!   {"waddbss",    0xee300180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"waddb",      0xee000180, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"waddbus",    0xee100180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"waddhss",    0xee700180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"waddh",      0xee400180, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"waddhus",    0xee500180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"waddwss",    0xeeb00180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"waddw",      0xee800180, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"waddwus",    0xee900180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"waligni",    0xee000020, 7, ARM_CEXT_IWMMXT, do_iwmmxt_waligni},
!   {"walignr0",   0xee800020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"walignr1",   0xee900020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"walignr2",   0xeea00020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"walignr3",   0xeeb00020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wand",       0xee200000, 4, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wandn",      0xee300000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wavg2b",     0xee800000, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wavg2br",    0xee900000, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wavg2h",     0xeec00000, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wavg2hr",    0xeed00000, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wcmpeqb",    0xee000060, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wcmpeqh",    0xee400060, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wcmpeqw",    0xee800060, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wcmpgtub",   0xee100060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wcmpgtuh",   0xee500060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wcmpgtuw",   0xee900060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wcmpgtsb",   0xee300060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wcmpgtsh",   0xee700060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wcmpgtsw",   0xeeb00060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wldrb",      0xec100000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
!   {"wldrh",      0xec100100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
!   {"wldrw",      0xec100200, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
!   {"wldrd",      0xec100300, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
!   {"wmacs",      0xee600100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wmacsz",     0xee700100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wmacu",      0xee400100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wmacuz",     0xee500100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wmadds",     0xeea00100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wmaddu",     0xee800100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wmaxsb",     0xee200160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wmaxsh",     0xee600160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wmaxsw",     0xeea00160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wmaxub",     0xee000160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wmaxuh",     0xee400160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wmaxuw",     0xee800160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wminsb",     0xee300160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wminsh",     0xee700160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wminsw",     0xeeb00160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wminub",     0xee100160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wminuh",     0xee500160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wminuw",     0xee900160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wmov",       0xee000000, 4, ARM_CEXT_IWMMXT, do_iwmmxt_wmov},
!   {"wmulsm",     0xee300100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wmulsl",     0xee200100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wmulum",     0xee100100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wmulul",     0xee000100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wor",        0xee000000, 3, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wpackhss",   0xee700080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wpackhus",   0xee500080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wpackwss",   0xeeb00080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wpackwus",   0xee900080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wpackdss",   0xeef00080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wpackdus",   0xeed00080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wrorh",      0xee700040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wrorhg",     0xee700148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
!   {"wrorw",      0xeeb00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wrorwg",     0xeeb00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
!   {"wrord",      0xeef00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wrordg",     0xeef00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
!   {"wsadb",      0xee000120, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wsadbz",     0xee100120, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wsadh",      0xee400120, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wsadhz",     0xee500120, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wshufh",     0xee0001e0, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wshufh},
!   {"wsllh",      0xee500040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wsllhg",     0xee500148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
!   {"wsllw",      0xee900040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wsllwg",     0xee900148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
!   {"wslld",      0xeed00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wslldg",     0xeed00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
!   {"wsrah",      0xee400040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wsrahg",     0xee400148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
!   {"wsraw",      0xee800040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wsrawg",     0xee800148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
!   {"wsrad",      0xeec00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wsradg",     0xeec00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
!   {"wsrlh",      0xee600040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wsrlhg",     0xee600148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
!   {"wsrlw",      0xeea00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wsrlwg",     0xeea00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
!   {"wsrld",      0xeee00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wsrldg",     0xeee00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
!   {"wstrb",      0xec000000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
!   {"wstrh",      0xec000100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
!   {"wstrw",      0xec000200, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
!   {"wstrd",      0xec000300, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
!   {"wsubbss",    0xee3001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wsubb",      0xee0001a0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wsubbus",    0xee1001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wsubhss",    0xee7001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wsubh",      0xee4001a0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wsubhus",    0xee5001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wsubwss",    0xeeb001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wsubw",      0xee8001a0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wsubwus",    0xee9001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wunpckehub", 0xee0000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
!   {"wunpckehuh", 0xee4000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
!   {"wunpckehuw", 0xee8000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
!   {"wunpckehsb", 0xee2000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
!   {"wunpckehsh", 0xee6000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
!   {"wunpckehsw", 0xeea000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
!   {"wunpckihb",  0xee1000c0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wunpckihh",  0xee5000c0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wunpckihw",  0xee9000c0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wunpckelub", 0xee0000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
!   {"wunpckeluh", 0xee4000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
!   {"wunpckeluw", 0xee8000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
!   {"wunpckelsb", 0xee2000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
!   {"wunpckelsh", 0xee6000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
!   {"wunpckelsw", 0xeea000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
!   {"wunpckilb",  0xee1000e0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wunpckilh",  0xee5000e0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wunpckilw",  0xee9000e0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wxor",       0xee100000, 4, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wzero",      0xee300000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wzero},
! 
!   /* Cirrus Maverick instructions.  */
!   {"cfldrs",     0xec100400, 6,  ARM_CEXT_MAVERICK, do_mav_ldst_1},
!   {"cfldrd",     0xec500400, 6,  ARM_CEXT_MAVERICK, do_mav_ldst_2},
!   {"cfldr32",    0xec100500, 7,  ARM_CEXT_MAVERICK, do_mav_ldst_3},
!   {"cfldr64",    0xec500500, 7,  ARM_CEXT_MAVERICK, do_mav_ldst_4},
!   {"cfstrs",     0xec000400, 6,  ARM_CEXT_MAVERICK, do_mav_ldst_1},
!   {"cfstrd",     0xec400400, 6,  ARM_CEXT_MAVERICK, do_mav_ldst_2},
!   {"cfstr32",    0xec000500, 7,  ARM_CEXT_MAVERICK, do_mav_ldst_3},
!   {"cfstr64",    0xec400500, 7,  ARM_CEXT_MAVERICK, do_mav_ldst_4},
!   {"cfmvsr",     0xee000450, 6,  ARM_CEXT_MAVERICK, do_mav_binops_2a},
!   {"cfmvrs",     0xee100450, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1a},
!   {"cfmvdlr",    0xee000410, 7,  ARM_CEXT_MAVERICK, do_mav_binops_2b},
!   {"cfmvrdl",    0xee100410, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1b},
!   {"cfmvdhr",    0xee000430, 7,  ARM_CEXT_MAVERICK, do_mav_binops_2b},
!   {"cfmvrdh",    0xee100430, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1b},
!   {"cfmv64lr",   0xee000510, 8,  ARM_CEXT_MAVERICK, do_mav_binops_2c},
!   {"cfmvr64l",   0xee100510, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1c},
!   {"cfmv64hr",   0xee000530, 8,  ARM_CEXT_MAVERICK, do_mav_binops_2c},
!   {"cfmvr64h",   0xee100530, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1c},
!   {"cfmval32",   0xee200440, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3a},
!   {"cfmv32al",   0xee100440, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3b},
!   {"cfmvam32",   0xee200460, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3a},
!   {"cfmv32am",   0xee100460, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3b},
!   {"cfmvah32",   0xee200480, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3a},
!   {"cfmv32ah",   0xee100480, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3b},
!   {"cfmva32",    0xee2004a0, 7,  ARM_CEXT_MAVERICK, do_mav_binops_3a},
!   {"cfmv32a",    0xee1004a0, 7,  ARM_CEXT_MAVERICK, do_mav_binops_3b},
!   {"cfmva64",    0xee2004c0, 7,  ARM_CEXT_MAVERICK, do_mav_binops_3c},
!   {"cfmv64a",    0xee1004c0, 7,  ARM_CEXT_MAVERICK, do_mav_binops_3d},
!   {"cfmvsc32",   0xee2004e0, 8,  ARM_CEXT_MAVERICK, do_mav_dspsc_1},
!   {"cfmv32sc",   0xee1004e0, 8,  ARM_CEXT_MAVERICK, do_mav_dspsc_2},
!   {"cfcpys",     0xee000400, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1d},
!   {"cfcpyd",     0xee000420, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1e},
!   {"cfcvtsd",    0xee000460, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1f},
!   {"cfcvtds",    0xee000440, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1g},
!   {"cfcvt32s",   0xee000480, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1h},
!   {"cfcvt32d",   0xee0004a0, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1i},
!   {"cfcvt64s",   0xee0004c0, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1j},
!   {"cfcvt64d",   0xee0004e0, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1k},
!   {"cfcvts32",   0xee100580, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1l},
!   {"cfcvtd32",   0xee1005a0, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1m},
!   {"cftruncs32", 0xee1005c0, 10, ARM_CEXT_MAVERICK, do_mav_binops_1l},
!   {"cftruncd32", 0xee1005e0, 10, ARM_CEXT_MAVERICK, do_mav_binops_1m},
!   {"cfrshl32",   0xee000550, 8,  ARM_CEXT_MAVERICK, do_mav_triple_4a},
!   {"cfrshl64",   0xee000570, 8,  ARM_CEXT_MAVERICK, do_mav_triple_4b},
!   {"cfsh32",     0xee000500, 6,  ARM_CEXT_MAVERICK, do_mav_shift_1},
!   {"cfsh64",     0xee200500, 6,  ARM_CEXT_MAVERICK, do_mav_shift_2},
!   {"cfcmps",     0xee100490, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5a},
!   {"cfcmpd",     0xee1004b0, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5b},
!   {"cfcmp32",    0xee100590, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5c},
!   {"cfcmp64",    0xee1005b0, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5d},
!   {"cfabss",     0xee300400, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1d},
!   {"cfabsd",     0xee300420, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1e},
!   {"cfnegs",     0xee300440, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1d},
!   {"cfnegd",     0xee300460, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1e},
!   {"cfadds",     0xee300480, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5e},
!   {"cfaddd",     0xee3004a0, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5f},
!   {"cfsubs",     0xee3004c0, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5e},
!   {"cfsubd",     0xee3004e0, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5f},
!   {"cfmuls",     0xee100400, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5e},
!   {"cfmuld",     0xee100420, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5f},
!   {"cfabs32",    0xee300500, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1n},
!   {"cfabs64",    0xee300520, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1o},
!   {"cfneg32",    0xee300540, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1n},
!   {"cfneg64",    0xee300560, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1o},
!   {"cfadd32",    0xee300580, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
!   {"cfadd64",    0xee3005a0, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5h},
!   {"cfsub32",    0xee3005c0, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
!   {"cfsub64",    0xee3005e0, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5h},
!   {"cfmul32",    0xee100500, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
!   {"cfmul64",    0xee100520, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5h},
!   {"cfmac32",    0xee100540, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
!   {"cfmsc32",    0xee100560, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
!   {"cfmadd32",   0xee000600, 8,  ARM_CEXT_MAVERICK, do_mav_quad_6a},
!   {"cfmsub32",   0xee100600, 8,  ARM_CEXT_MAVERICK, do_mav_quad_6a},
!   {"cfmadda32",  0xee200600, 9,  ARM_CEXT_MAVERICK, do_mav_quad_6b},
!   {"cfmsuba32",  0xee300600, 9,  ARM_CEXT_MAVERICK, do_mav_quad_6b},
! };
! 
! /* Defines for various bits that we will want to toggle.  */
! #define INST_IMMEDIATE	0x02000000
! #define OFFSET_REG	0x02000000
! #define HWOFFSET_IMM    0x00400000
! #define SHIFT_BY_REG	0x00000010
! #define PRE_INDEX	0x01000000
! #define INDEX_UP	0x00800000
! #define WRITE_BACK	0x00200000
! #define LDM_TYPE_2_OR_3	0x00400000
! 
! #define LITERAL_MASK	0xf000f000
! #define OPCODE_MASK	0xfe1fffff
! #define V4_STR_BIT	0x00000020
! 
! #define DATA_OP_SHIFT	21
! 
! /* Codes to distinguish the arithmetic instructions.  */
! #define OPCODE_AND	0
! #define OPCODE_EOR	1
! #define OPCODE_SUB	2
! #define OPCODE_RSB	3
! #define OPCODE_ADD	4
! #define OPCODE_ADC	5
! #define OPCODE_SBC	6
! #define OPCODE_RSC	7
! #define OPCODE_TST	8
! #define OPCODE_TEQ	9
! #define OPCODE_CMP	10
! #define OPCODE_CMN	11
! #define OPCODE_ORR	12
! #define OPCODE_MOV	13
! #define OPCODE_BIC	14
! #define OPCODE_MVN	15
! 
! /* Thumb v1 (ARMv4T).  */
! static void do_t_nop		PARAMS ((char *));
! static void do_t_arit		PARAMS ((char *));
! static void do_t_add		PARAMS ((char *));
! static void do_t_asr		PARAMS ((char *));
! static void do_t_branch9	PARAMS ((char *));
! static void do_t_branch12	PARAMS ((char *));
! static void do_t_branch23	PARAMS ((char *));
! static void do_t_bx		PARAMS ((char *));
! static void do_t_compare	PARAMS ((char *));
! static void do_t_ldmstm		PARAMS ((char *));
! static void do_t_ldr		PARAMS ((char *));
! static void do_t_ldrb		PARAMS ((char *));
! static void do_t_ldrh		PARAMS ((char *));
! static void do_t_lds		PARAMS ((char *));
! static void do_t_lsl		PARAMS ((char *));
! static void do_t_lsr		PARAMS ((char *));
! static void do_t_mov		PARAMS ((char *));
! static void do_t_push_pop	PARAMS ((char *));
! static void do_t_str		PARAMS ((char *));
! static void do_t_strb		PARAMS ((char *));
! static void do_t_strh		PARAMS ((char *));
! static void do_t_sub		PARAMS ((char *));
! static void do_t_swi		PARAMS ((char *));
! static void do_t_adr		PARAMS ((char *));
! 
! /* Thumb v2 (ARMv5T).  */
! static void do_t_blx		PARAMS ((char *));
! static void do_t_bkpt		PARAMS ((char *));
! 
! /* ARM V6.  */
! static void do_t_cps            PARAMS ((char *));
! static void do_t_cpy            PARAMS ((char *));
! static void do_t_setend         PARAMS ((char *));;
! 
! #define T_OPCODE_MUL 0x4340
! #define T_OPCODE_TST 0x4200
! #define T_OPCODE_CMN 0x42c0
! #define T_OPCODE_NEG 0x4240
! #define T_OPCODE_MVN 0x43c0
! 
! #define T_OPCODE_ADD_R3	0x1800
! #define T_OPCODE_SUB_R3 0x1a00
! #define T_OPCODE_ADD_HI 0x4400
! #define T_OPCODE_ADD_ST 0xb000
! #define T_OPCODE_SUB_ST 0xb080
! #define T_OPCODE_ADD_SP 0xa800
! #define T_OPCODE_ADD_PC 0xa000
! #define T_OPCODE_ADD_I8 0x3000
! #define T_OPCODE_SUB_I8 0x3800
! #define T_OPCODE_ADD_I3 0x1c00
! #define T_OPCODE_SUB_I3 0x1e00
! 
! #define T_OPCODE_ASR_R	0x4100
! #define T_OPCODE_LSL_R	0x4080
! #define T_OPCODE_LSR_R  0x40c0
! #define T_OPCODE_ASR_I	0x1000
! #define T_OPCODE_LSL_I	0x0000
! #define T_OPCODE_LSR_I	0x0800
! 
! #define T_OPCODE_MOV_I8	0x2000
! #define T_OPCODE_CMP_I8 0x2800
! #define T_OPCODE_CMP_LR 0x4280
! #define T_OPCODE_MOV_HR 0x4600
! #define T_OPCODE_CMP_HR 0x4500
! 
! #define T_OPCODE_LDR_PC 0x4800
! #define T_OPCODE_LDR_SP 0x9800
! #define T_OPCODE_STR_SP 0x9000
! #define T_OPCODE_LDR_IW 0x6800
! #define T_OPCODE_STR_IW 0x6000
! #define T_OPCODE_LDR_IH 0x8800
! #define T_OPCODE_STR_IH 0x8000
! #define T_OPCODE_LDR_IB 0x7800
! #define T_OPCODE_STR_IB 0x7000
! #define T_OPCODE_LDR_RW 0x5800
! #define T_OPCODE_STR_RW 0x5000
! #define T_OPCODE_LDR_RH 0x5a00
! #define T_OPCODE_STR_RH 0x5200
! #define T_OPCODE_LDR_RB 0x5c00
! #define T_OPCODE_STR_RB 0x5400
! 
! #define T_OPCODE_PUSH	0xb400
! #define T_OPCODE_POP	0xbc00
! 
! #define T_OPCODE_BRANCH 0xe7fe
! 
! static int thumb_reg		PARAMS ((char ** str, int hi_lo));
! 
! #define THUMB_SIZE	2	/* Size of thumb instruction.  */
! #define THUMB_REG_LO	0x1
! #define THUMB_REG_HI	0x2
! #define THUMB_REG_ANY	0x3
! 
! #define THUMB_H1	0x0080
! #define THUMB_H2	0x0040
! 
! #define THUMB_ASR 0
! #define THUMB_LSL 1
! #define THUMB_LSR 2
! 
! #define THUMB_MOVE 0
! #define THUMB_COMPARE 1
! #define THUMB_CPY 2
! 
! #define THUMB_LOAD 0
! #define THUMB_STORE 1
! 
! #define THUMB_PP_PC_LR 0x0100
! 
! /* These three are used for immediate shifts, do not alter.  */
! #define THUMB_WORD 2
! #define THUMB_HALFWORD 1
! #define THUMB_BYTE 0
! 
! struct thumb_opcode
! {
!   /* Basic string to match.  */
!   const char * template;
! 
!   /* Basic instruction code.  */
!   unsigned long value;
! 
!   int size;
  
    /* Which CPU variants this exists for.  */
    unsigned long variant;
  
    /* Function to call to parse args.  */
!   void (* parms) PARAMS ((char *));
! };
! 
! static const struct thumb_opcode tinsns[] =
! {
!   /* Thumb v1 (ARMv4T).  */
!   {"adc",	0x4140,		2,	ARM_EXT_V4T, do_t_arit},
!   {"add",	0x0000,		2,	ARM_EXT_V4T, do_t_add},
!   {"and",	0x4000,		2,	ARM_EXT_V4T, do_t_arit},
!   {"asr",	0x0000,		2,	ARM_EXT_V4T, do_t_asr},
!   {"b",		T_OPCODE_BRANCH, 2,	ARM_EXT_V4T, do_t_branch12},
!   {"beq",	0xd0fe,		2,	ARM_EXT_V4T, do_t_branch9},
!   {"bne",	0xd1fe,		2,	ARM_EXT_V4T, do_t_branch9},
!   {"bcs",	0xd2fe,		2,	ARM_EXT_V4T, do_t_branch9},
!   {"bhs",	0xd2fe,		2,	ARM_EXT_V4T, do_t_branch9},
!   {"bcc",	0xd3fe,		2,	ARM_EXT_V4T, do_t_branch9},
!   {"bul",	0xd3fe,		2,	ARM_EXT_V4T, do_t_branch9},
!   {"blo",	0xd3fe,		2,	ARM_EXT_V4T, do_t_branch9},
!   {"bmi",	0xd4fe,		2,	ARM_EXT_V4T, do_t_branch9},
!   {"bpl",	0xd5fe,		2,	ARM_EXT_V4T, do_t_branch9},
!   {"bvs",	0xd6fe,		2,	ARM_EXT_V4T, do_t_branch9},
!   {"bvc",	0xd7fe,		2,	ARM_EXT_V4T, do_t_branch9},
!   {"bhi",	0xd8fe,		2,	ARM_EXT_V4T, do_t_branch9},
!   {"bls",	0xd9fe,		2,	ARM_EXT_V4T, do_t_branch9},
!   {"bge",	0xdafe,		2,	ARM_EXT_V4T, do_t_branch9},
!   {"blt",	0xdbfe,		2,	ARM_EXT_V4T, do_t_branch9},
!   {"bgt",	0xdcfe,		2,	ARM_EXT_V4T, do_t_branch9},
!   {"ble",	0xddfe,		2,	ARM_EXT_V4T, do_t_branch9},
!   {"bal",	0xdefe,		2,	ARM_EXT_V4T, do_t_branch9},
!   {"bic",	0x4380,		2,	ARM_EXT_V4T, do_t_arit},
!   {"bl",	0xf7fffffe,	4,	ARM_EXT_V4T, do_t_branch23},
!   {"bx",	0x4700,		2,	ARM_EXT_V4T, do_t_bx},
!   {"cmn",	T_OPCODE_CMN,	2,	ARM_EXT_V4T, do_t_arit},
!   {"cmp",	0x0000,		2,	ARM_EXT_V4T, do_t_compare},
!   {"eor",	0x4040,		2,	ARM_EXT_V4T, do_t_arit},
!   {"ldmia",	0xc800,		2,	ARM_EXT_V4T, do_t_ldmstm},
!   {"ldr",	0x0000,		2,	ARM_EXT_V4T, do_t_ldr},
!   {"ldrb",	0x0000,		2,	ARM_EXT_V4T, do_t_ldrb},
!   {"ldrh",	0x0000,		2,	ARM_EXT_V4T, do_t_ldrh},
!   {"ldrsb",	0x5600,		2,	ARM_EXT_V4T, do_t_lds},
!   {"ldrsh",	0x5e00,		2,	ARM_EXT_V4T, do_t_lds},
!   {"ldsb",	0x5600,		2,	ARM_EXT_V4T, do_t_lds},
!   {"ldsh",	0x5e00,		2,	ARM_EXT_V4T, do_t_lds},
!   {"lsl",	0x0000,		2,	ARM_EXT_V4T, do_t_lsl},
!   {"lsr",	0x0000,		2,	ARM_EXT_V4T, do_t_lsr},
!   {"mov",	0x0000,		2,	ARM_EXT_V4T, do_t_mov},
!   {"mul",	T_OPCODE_MUL,	2,	ARM_EXT_V4T, do_t_arit},
!   {"mvn",	T_OPCODE_MVN,	2,	ARM_EXT_V4T, do_t_arit},
!   {"neg",	T_OPCODE_NEG,	2,	ARM_EXT_V4T, do_t_arit},
!   {"orr",	0x4300,		2,	ARM_EXT_V4T, do_t_arit},
!   {"pop",	0xbc00,		2,	ARM_EXT_V4T, do_t_push_pop},
!   {"push",	0xb400,		2,	ARM_EXT_V4T, do_t_push_pop},
!   {"ror",	0x41c0,		2,	ARM_EXT_V4T, do_t_arit},
!   {"sbc",	0x4180,		2,	ARM_EXT_V4T, do_t_arit},
!   {"stmia",	0xc000,		2,	ARM_EXT_V4T, do_t_ldmstm},
!   {"str",	0x0000,		2,	ARM_EXT_V4T, do_t_str},
!   {"strb",	0x0000,		2,	ARM_EXT_V4T, do_t_strb},
!   {"strh",	0x0000,		2,	ARM_EXT_V4T, do_t_strh},
!   {"swi",	0xdf00,		2,	ARM_EXT_V4T, do_t_swi},
!   {"sub",	0x0000,		2,	ARM_EXT_V4T, do_t_sub},
!   {"tst",	T_OPCODE_TST,	2,	ARM_EXT_V4T, do_t_arit},
!   /* Pseudo ops:  */
!   {"adr",       0x0000,         2,      ARM_EXT_V4T, do_t_adr},
!   {"nop",       0x46C0,         2,      ARM_EXT_V4T, do_t_nop},      /* mov r8,r8  */
!   /* Thumb v2 (ARMv5T).  */
!   {"blx",	0,		0,	ARM_EXT_V5T, do_t_blx},
!   {"bkpt",	0xbe00,		2,	ARM_EXT_V5T, do_t_bkpt},
! 
!   /* ARM V6.  */
!   {"cpsie",	0xb660,		2,	ARM_EXT_V6,  do_t_cps},
!   {"cpsid",     0xb670,		2,	ARM_EXT_V6,  do_t_cps},
!   {"cpy",	0x4600,		2,	ARM_EXT_V6,  do_t_cpy},
!   {"rev",	0xba00,		2,	ARM_EXT_V6,  do_t_arit},
!   {"rev16",	0xba40,		2,	ARM_EXT_V6,  do_t_arit},
!   {"revsh",	0xbac0,		2,	ARM_EXT_V6,  do_t_arit},
!   {"setend",	0xb650,		2,	ARM_EXT_V6,  do_t_setend},
!   {"sxth",	0xb200,		2,	ARM_EXT_V6,  do_t_arit},
!   {"sxtb",	0xb240,		2,	ARM_EXT_V6,  do_t_arit},
!   {"uxth",	0xb280,		2,	ARM_EXT_V6,  do_t_arit},
!   {"uxtb",	0xb2c0,		2,	ARM_EXT_V6,  do_t_arit},
  };
  
  #define BAD_ARGS 	_("bad arguments to instruction")
--- 791,926 ----
    unsigned long variant;
  
    /* Function to call to parse args.  */
!   void (* parms) (char *);
  };
  
! /* Defines for various bits that we will want to toggle.  */
! #define INST_IMMEDIATE	0x02000000
! #define OFFSET_REG	0x02000000
! #define HWOFFSET_IMM    0x00400000
! #define SHIFT_BY_REG	0x00000010
! #define PRE_INDEX	0x01000000
! #define INDEX_UP	0x00800000
! #define WRITE_BACK	0x00200000
! #define LDM_TYPE_2_OR_3	0x00400000
  
! #define LITERAL_MASK	0xf000f000
! #define OPCODE_MASK	0xfe1fffff
! #define V4_STR_BIT	0x00000020
  
! #define DATA_OP_SHIFT	21
  
! /* Codes to distinguish the arithmetic instructions.  */
! #define OPCODE_AND	0
! #define OPCODE_EOR	1
! #define OPCODE_SUB	2
! #define OPCODE_RSB	3
! #define OPCODE_ADD	4
! #define OPCODE_ADC	5
! #define OPCODE_SBC	6
! #define OPCODE_RSC	7
! #define OPCODE_TST	8
! #define OPCODE_TEQ	9
! #define OPCODE_CMP	10
! #define OPCODE_CMN	11
! #define OPCODE_ORR	12
! #define OPCODE_MOV	13
! #define OPCODE_BIC	14
! #define OPCODE_MVN	15
  
! #define T_OPCODE_MUL 0x4340
! #define T_OPCODE_TST 0x4200
! #define T_OPCODE_CMN 0x42c0
! #define T_OPCODE_NEG 0x4240
! #define T_OPCODE_MVN 0x43c0
  
! #define T_OPCODE_ADD_R3	0x1800
! #define T_OPCODE_SUB_R3 0x1a00
! #define T_OPCODE_ADD_HI 0x4400
! #define T_OPCODE_ADD_ST 0xb000
! #define T_OPCODE_SUB_ST 0xb080
! #define T_OPCODE_ADD_SP 0xa800
! #define T_OPCODE_ADD_PC 0xa000
! #define T_OPCODE_ADD_I8 0x3000
! #define T_OPCODE_SUB_I8 0x3800
! #define T_OPCODE_ADD_I3 0x1c00
! #define T_OPCODE_SUB_I3 0x1e00
  
! #define T_OPCODE_ASR_R	0x4100
! #define T_OPCODE_LSL_R	0x4080
! #define T_OPCODE_LSR_R  0x40c0
! #define T_OPCODE_ASR_I	0x1000
! #define T_OPCODE_LSL_I	0x0000
! #define T_OPCODE_LSR_I	0x0800
  
! #define T_OPCODE_MOV_I8	0x2000
! #define T_OPCODE_CMP_I8 0x2800
! #define T_OPCODE_CMP_LR 0x4280
! #define T_OPCODE_MOV_HR 0x4600
! #define T_OPCODE_CMP_HR 0x4500
  
! #define T_OPCODE_LDR_PC 0x4800
! #define T_OPCODE_LDR_SP 0x9800
! #define T_OPCODE_STR_SP 0x9000
! #define T_OPCODE_LDR_IW 0x6800
! #define T_OPCODE_STR_IW 0x6000
! #define T_OPCODE_LDR_IH 0x8800
! #define T_OPCODE_STR_IH 0x8000
! #define T_OPCODE_LDR_IB 0x7800
! #define T_OPCODE_STR_IB 0x7000
! #define T_OPCODE_LDR_RW 0x5800
! #define T_OPCODE_STR_RW 0x5000
! #define T_OPCODE_LDR_RH 0x5a00
! #define T_OPCODE_STR_RH 0x5200
! #define T_OPCODE_LDR_RB 0x5c00
! #define T_OPCODE_STR_RB 0x5400
  
! #define T_OPCODE_PUSH	0xb400
! #define T_OPCODE_POP	0xbc00
  
! #define T_OPCODE_BRANCH 0xe7fe
  
! #define THUMB_SIZE	2	/* Size of thumb instruction.  */
! #define THUMB_REG_LO	0x1
! #define THUMB_REG_HI	0x2
! #define THUMB_REG_ANY	0x3
  
! #define THUMB_H1	0x0080
! #define THUMB_H2	0x0040
  
! #define THUMB_ASR 0
! #define THUMB_LSL 1
! #define THUMB_LSR 2
  
! #define THUMB_MOVE 0
! #define THUMB_COMPARE 1
! #define THUMB_CPY 2
  
! #define THUMB_LOAD 0
! #define THUMB_STORE 1
  
! #define THUMB_PP_PC_LR 0x0100
  
! /* These three are used for immediate shifts, do not alter.  */
! #define THUMB_WORD 2
! #define THUMB_HALFWORD 1
! #define THUMB_BYTE 0
  
! struct thumb_opcode
! {
!   /* Basic string to match.  */
!   const char * template;
  
!   /* Basic instruction code.  */
!   unsigned long value;
  
!   int size;
  
    /* Which CPU variants this exists for.  */
    unsigned long variant;
  
    /* Function to call to parse args.  */
!   void (* parms) (char *);
  };
  
  #define BAD_ARGS 	_("bad arguments to instruction")
*************** static struct hash_control * arm_cond_hs
*** 2425,2499 ****
  static struct hash_control * arm_shift_hsh = NULL;
  static struct hash_control * arm_psr_hsh   = NULL;
  
- /* This table describes all the machine specific pseudo-ops the assembler
-    has to support.  The fields are:
-      pseudo-op name without dot
-      function to call to execute this pseudo-op
-      Integer arg to pass to the function.  */
- 
- static void s_req PARAMS ((int));
- static void s_unreq PARAMS ((int));
- static void s_align PARAMS ((int));
- static void s_bss PARAMS ((int));
- static void s_even PARAMS ((int));
- static void s_ltorg PARAMS ((int));
- static void s_arm PARAMS ((int));
- static void s_thumb PARAMS ((int));
- static void s_code PARAMS ((int));
- static void s_force_thumb PARAMS ((int));
- static void s_thumb_func PARAMS ((int));
- static void s_thumb_set PARAMS ((int));
- #ifdef OBJ_ELF
- static void s_arm_elf_cons PARAMS ((int));
- static void s_arm_rel31 (int nbytes);
- #endif
- 
- static int my_get_expression PARAMS ((expressionS *, char **));
- 
- const pseudo_typeS md_pseudo_table[] =
- {
-   /* Never called because '.req' does not start a line.  */
-   { "req",         s_req,         0 },
-   { "unreq",       s_unreq,       0 },
-   { "bss",         s_bss,         0 },
-   { "align",       s_align,       0 },
-   { "arm",         s_arm,         0 },
-   { "thumb",       s_thumb,       0 },
-   { "code",        s_code,        0 },
-   { "force_thumb", s_force_thumb, 0 },
-   { "thumb_func",  s_thumb_func,  0 },
-   { "thumb_set",   s_thumb_set,   0 },
-   { "even",        s_even,        0 },
-   { "ltorg",       s_ltorg,       0 },
-   { "pool",        s_ltorg,       0 },
- #ifdef OBJ_ELF
-   { "word",        s_arm_elf_cons, 4 },
-   { "long",        s_arm_elf_cons, 4 },
-   { "rel31",       s_arm_rel31,   0 },
- #else
-   { "word",        cons, 4},
- #endif
-   { "extend",      float_cons, 'x' },
-   { "ldouble",     float_cons, 'x' },
-   { "packed",      float_cons, 'p' },
-   { 0, 0, 0 }
- };
- 
- /* Other internal functions.  */
- static int arm_parse_extension PARAMS ((char *, int *));
- static int arm_parse_cpu PARAMS ((char *));
- static int arm_parse_arch PARAMS ((char *));
- static int arm_parse_fpu PARAMS ((char *));
- static int arm_parse_float_abi PARAMS ((char *));
- #ifdef OBJ_ELF
- static int arm_parse_eabi PARAMS ((char *));
- #endif
- #if 0 /* Suppressed - for now.  */
- #if defined OBJ_COFF || defined OBJ_ELF
- static void arm_add_note PARAMS ((const char *, const char *, unsigned int));
- #endif
- #endif
- 
  /* Stuff needed to resolve the label ambiguity
     As:
       ...
--- 934,939 ----
*************** static void arm_add_note PARAMS ((const 
*** 2506,2518 ****
  
  symbolS *  last_label_seen;
  static int label_is_thumb_function_name = FALSE;
! 
  /* Literal Pool stuff.  */
  
  #define MAX_LITERAL_POOL_SIZE 1024
  
  /* Literal pool structure.  Held on a per-section
     and per-sub-section basis.  */
  typedef struct literal_pool
  {
    expressionS    literals [MAX_LITERAL_POOL_SIZE];
--- 946,959 ----
  
  symbolS *  last_label_seen;
  static int label_is_thumb_function_name = FALSE;
! 
  /* Literal Pool stuff.  */
  
  #define MAX_LITERAL_POOL_SIZE 1024
  
  /* Literal pool structure.  Held on a per-section
     and per-sub-section basis.  */
+ 
  typedef struct literal_pool
  {
    expressionS    literals [MAX_LITERAL_POOL_SIZE];
*************** typedef struct literal_pool
*** 2527,2537 ****
  /* Pointer to a linked list of literal pools.  */
  literal_pool * list_of_pools = NULL;
  
- static literal_pool * find_literal_pool PARAMS ((void));
- static literal_pool * find_or_make_literal_pool PARAMS ((void));
- 
  static literal_pool *
! find_literal_pool ()
  {
    literal_pool * pool;
  
--- 968,975 ----
  /* Pointer to a linked list of literal pools.  */
  literal_pool * list_of_pools = NULL;
  
  static literal_pool *
! find_literal_pool (void)
  {
    literal_pool * pool;
  
*************** find_literal_pool ()
*** 2546,2552 ****
  }
  
  static literal_pool *
! find_or_make_literal_pool ()
  {
    /* Next literal pool ID number.  */
    static unsigned int latest_pool_num = 1;
--- 984,990 ----
  }
  
  static literal_pool *
! find_or_make_literal_pool (void)
  {
    /* Next literal pool ID number.  */
    static unsigned int latest_pool_num = 1;
*************** find_or_make_literal_pool ()
*** 2557,2563 ****
    if (pool == NULL)
      {
        /* Create a new pool.  */
!       pool = (literal_pool *) xmalloc (sizeof (* pool));
        if (! pool)
  	return NULL;
  
--- 995,1001 ----
    if (pool == NULL)
      {
        /* Create a new pool.  */
!       pool = xmalloc (sizeof (* pool));
        if (! pool)
  	return NULL;
  
*************** find_or_make_literal_pool ()
*** 2585,2592 ****
  
  /* Add the literal in the global 'inst'
     structure to the relevent literal pool.  */
  static int
! add_to_lit_pool ()
  {
    literal_pool * pool;
    unsigned int entry;
--- 1023,1031 ----
  
  /* Add the literal in the global 'inst'
     structure to the relevent literal pool.  */
+ 
  static int
! add_to_lit_pool (void)
  {
    literal_pool * pool;
    unsigned int entry;
*************** add_to_lit_pool ()
*** 2639,2650 ****
     a later date assign it a value. Thats what these functions do.  */
  
  static void
! symbol_locate (symbolP, name, segment, valu, frag)
!      symbolS *    symbolP;
!      const char * name;		/* It is copied, the caller can modify.  */
!      segT         segment;	/* Segment identifier (SEG_<something>).  */
!      valueT       valu;		/* Symbol value.  */
!      fragS *      frag;		/* Associated fragment.  */
  {
    unsigned int name_length;
    char * preserved_copy_of_name;
--- 1078,1088 ----
     a later date assign it a value. Thats what these functions do.  */
  
  static void
! symbol_locate (symbolS *    symbolP,
! 	       const char * name,	/* It is copied, the caller can modify.  */
! 	       segT         segment,	/* Segment identifier (SEG_<something>).  */
! 	       valueT       valu,	/* Symbol value.  */
! 	       fragS *      frag)	/* Associated fragment.  */
  {
    unsigned int name_length;
    char * preserved_copy_of_name;
*************** symbol_locate (symbolP, name, segment, v
*** 2673,2678 ****
--- 1111,1117 ----
    /* Link to end of symbol chain.  */
    {
      extern int symbol_table_frozen;
+ 
      if (symbol_table_frozen)
        abort ();
    }
*************** symbol_locate (symbolP, name, segment, v
*** 2694,2701 ****
     If so, convert it to the right format.  */
  
  static unsigned int
! validate_immediate (val)
!      unsigned int val;
  {
    unsigned int a;
    unsigned int i;
--- 1133,1139 ----
     If so, convert it to the right format.  */
  
  static unsigned int
! validate_immediate (unsigned int val)
  {
    unsigned int a;
    unsigned int i;
*************** validate_immediate (val)
*** 2714,2722 ****
     computed by just one ARM instruction.  */
  
  static unsigned int
! validate_immediate_twopart (val, highpart)
!      unsigned int   val;
!      unsigned int * highpart;
  {
    unsigned int a;
    unsigned int i;
--- 1152,1159 ----
     computed by just one ARM instruction.  */
  
  static unsigned int
! validate_immediate_twopart (unsigned int   val,
! 			    unsigned int * highpart)
  {
    unsigned int a;
    unsigned int i;
*************** validate_immediate_twopart (val, highpar
*** 2749,2757 ****
  }
  
  static int
! validate_offset_imm (val, hwse)
!      unsigned int val;
!      int hwse;
  {
    if ((hwse && val > 255) || val > 4095)
      return FAIL;
--- 1186,1192 ----
  }
  
  static int
! validate_offset_imm (unsigned int val, int hwse)
  {
    if ((hwse && val > 255) || val > 4095)
      return FAIL;
*************** mapping_state (enum mstate state)
*** 2865,2871 ****
        type = BSF_FUNCTION;
        break;
      case MAP_UNDEFINED:
!       return;     
      default:
        abort ();
      }
--- 1300,1306 ----
        type = BSF_FUNCTION;
        break;
      case MAP_UNDEFINED:
!       return;
      default:
        abort ();
      }
*************** mapping_state (enum mstate state)
*** 2875,2881 ****
    symbolP = symbol_new (symname, now_seg, (valueT) frag_now_fix (), frag_now);
    symbol_table_insert (symbolP);
    symbol_get_bfdsym (symbolP)->flags |= type | BSF_LOCAL;
!   
    switch (state)
      {
      case MAP_ARM:
--- 1310,1316 ----
    symbolP = symbol_new (symname, now_seg, (valueT) frag_now_fix (), frag_now);
    symbol_table_insert (symbolP);
    symbol_get_bfdsym (symbolP)->flags |= type | BSF_LOCAL;
! 
    switch (state)
      {
      case MAP_ARM:
*************** mapping_state (enum mstate state)
*** 2883,2927 ****
        ARM_SET_THUMB (symbolP, 0);
        ARM_SET_INTERWORK (symbolP, support_interwork);
        break;
!       
      case MAP_THUMB:
        THUMB_SET_FUNC (symbolP, 1);
        ARM_SET_THUMB (symbolP, 1);
        ARM_SET_INTERWORK (symbolP, support_interwork);
        break;
!       
      case MAP_DATA:
      default:
        return;
      }
  }
  
! /* When we change sections we need to issue a new mapping symbol.  */
  
! void
! arm_elf_change_section (void)
  {
!   flagword flags;
  
!   if (!SEG_NORMAL (now_seg))
!     return;
  
!   flags = bfd_get_section_flags (stdoutput, now_seg);
  
!   /* We can ignore sections that only contain debug info.  */
!   if ((flags & SEC_ALLOC) == 0)
!     return;
  
!   mapstate = seg_info (now_seg)->tc_segment_info_data;
  }
- #else
- #define mapping_state(a)
- #endif /* OBJ_ELF */
- 
  
  static void
! s_req (a)
!      int a ATTRIBUTE_UNUSED;
  {
    as_bad (_("invalid syntax for .req directive"));
  }
--- 1318,1458 ----
        ARM_SET_THUMB (symbolP, 0);
        ARM_SET_INTERWORK (symbolP, support_interwork);
        break;
! 
      case MAP_THUMB:
        THUMB_SET_FUNC (symbolP, 1);
        ARM_SET_THUMB (symbolP, 1);
        ARM_SET_INTERWORK (symbolP, support_interwork);
        break;
! 
      case MAP_DATA:
      default:
        return;
      }
  }
  
! /* When we change sections we need to issue a new mapping symbol.  */
! 
! void
! arm_elf_change_section (void)
! {
!   flagword flags;
! 
!   if (!SEG_NORMAL (now_seg))
!     return;
! 
!   flags = bfd_get_section_flags (stdoutput, now_seg);
! 
!   /* We can ignore sections that only contain debug info.  */
!   if ((flags & SEC_ALLOC) == 0)
!     return;
! 
!   mapstate = seg_info (now_seg)->tc_segment_info_data;
! }
! #else
! #define mapping_state(a)
! #endif /* OBJ_ELF */
! 
! /* arm_reg_parse () := if it looks like a register, return its token and
!    advance the pointer.  */
! 
! static int
! arm_reg_parse (char ** ccp, struct hash_control * htab)
! {
!   char * start = * ccp;
!   char   c;
!   char * p;
!   struct reg_entry * reg;
! 
! #ifdef REGISTER_PREFIX
!   if (*start != REGISTER_PREFIX)
!     return FAIL;
!   p = start + 1;
! #else
!   p = start;
! #ifdef OPTIONAL_REGISTER_PREFIX
!   if (*p == OPTIONAL_REGISTER_PREFIX)
!     p++, start++;
! #endif
! #endif
!   if (!ISALPHA (*p) || !is_name_beginner (*p))
!     return FAIL;
! 
!   c = *p++;
!   while (ISALPHA (c) || ISDIGIT (c) || c == '_')
!     c = *p++;
! 
!   *--p = 0;
!   reg = (struct reg_entry *) hash_find (htab, start);
!   *p = c;
! 
!   if (reg)
!     {
!       *ccp = p;
!       return reg->number;
!     }
! 
!   return FAIL;
! }
! 
! /* Search for the following register name in each of the possible reg name
!    tables.  Return the classification if found, or REG_TYPE_MAX if not
!    present.  */
  
! static enum arm_reg_type
! arm_reg_parse_any (char *cp)
  {
!   int i;
  
!   for (i = (int) REG_TYPE_FIRST; i < (int) REG_TYPE_MAX; i++)
!     if (arm_reg_parse (&cp, all_reg_maps[i].htab) != FAIL)
!       return (enum arm_reg_type) i;
  
!   return REG_TYPE_MAX;
! }
  
! static void
! opcode_select (int width)
! {
!   switch (width)
!     {
!     case 16:
!       if (! thumb_mode)
! 	{
! 	  if (! (cpu_variant & ARM_EXT_V4T))
! 	    as_bad (_("selected processor does not support THUMB opcodes"));
  
! 	  thumb_mode = 1;
! 	  /* No need to force the alignment, since we will have been
!              coming from ARM mode, which is word-aligned.  */
! 	  record_alignment (now_seg, 1);
! 	}
!       mapping_state (MAP_THUMB);
!       break;
! 
!     case 32:
!       if (thumb_mode)
! 	{
! 	  if ((cpu_variant & ARM_ALL) == ARM_EXT_V4T)
! 	    as_bad (_("selected processor does not support ARM opcodes"));
! 
! 	  thumb_mode = 0;
! 
! 	  if (!need_pass_2)
! 	    frag_align (2, 0, 0);
! 
! 	  record_alignment (now_seg, 1);
! 	}
!       mapping_state (MAP_ARM);
!       break;
! 
!     default:
!       as_bad (_("invalid instruction size selected (%d)"), width);
!     }
  }
  
  static void
! s_req (int a ATTRIBUTE_UNUSED)
  {
    as_bad (_("invalid syntax for .req directive"));
  }
*************** s_req (a)
*** 2935,2941 ****
  static void
  s_unreq (int a ATTRIBUTE_UNUSED)
  {
!   char *name;
    char saved_char;
  
    skip_whitespace (input_line_pointer);
--- 1466,1472 ----
  static void
  s_unreq (int a ATTRIBUTE_UNUSED)
  {
!   char * name;
    char saved_char;
  
    skip_whitespace (input_line_pointer);
*************** s_unreq (int a ATTRIBUTE_UNUSED)
*** 2998,3005 ****
  }
  
  static void
! s_bss (ignore)
!      int ignore ATTRIBUTE_UNUSED;
  {
    /* We don't support putting frags in the BSS segment, we fake it by
       marking in_bss, then looking at s_skip for clues.  */
--- 1529,1535 ----
  }
  
  static void
! s_bss (int ignore ATTRIBUTE_UNUSED)
  {
    /* We don't support putting frags in the BSS segment, we fake it by
       marking in_bss, then looking at s_skip for clues.  */
*************** s_bss (ignore)
*** 3009,3016 ****
  }
  
  static void
! s_even (ignore)
!      int ignore ATTRIBUTE_UNUSED;
  {
    /* Never make frag if expect extra pass.  */
    if (!need_pass_2)
--- 1539,1545 ----
  }
  
  static void
! s_even (int ignore ATTRIBUTE_UNUSED)
  {
    /* Never make frag if expect extra pass.  */
    if (!need_pass_2)
*************** s_even (ignore)
*** 3022,3029 ****
  }
  
  static void
! s_ltorg (ignored)
!      int ignored ATTRIBUTE_UNUSED;
  {
    unsigned int entry;
    literal_pool * pool;
--- 1551,1557 ----
  }
  
  static void
! s_ltorg (int ignored ATTRIBUTE_UNUSED)
  {
    unsigned int entry;
    literal_pool * pool;
*************** s_ltorg (ignored)
*** 3068,3078 ****
  /* Same as s_align_ptwo but align 0 => align 2.  */
  
  static void
! s_align (unused)
!      int unused ATTRIBUTE_UNUSED;
  {
!   register int temp;
!   register long temp_fill;
    long max_alignment = 15;
  
    temp = get_absolute_expression ();
--- 1596,1605 ----
  /* Same as s_align_ptwo but align 0 => align 2.  */
  
  static void
! s_align (int unused ATTRIBUTE_UNUSED)
  {
!   int temp;
!   long temp_fill;
    long max_alignment = 15;
  
    temp = get_absolute_expression ();
*************** s_align (unused)
*** 3104,3111 ****
  }
  
  static void
! s_force_thumb (ignore)
!      int ignore ATTRIBUTE_UNUSED;
  {
    /* If we are not already in thumb mode go into it, EVEN if
       the target processor does not support thumb instructions.
--- 1631,1637 ----
  }
  
  static void
! s_force_thumb (int ignore ATTRIBUTE_UNUSED)
  {
    /* If we are not already in thumb mode go into it, EVEN if
       the target processor does not support thumb instructions.
*************** s_force_thumb (ignore)
*** 3123,3130 ****
  }
  
  static void
! s_thumb_func (ignore)
!      int ignore ATTRIBUTE_UNUSED;
  {
    if (! thumb_mode)
      opcode_select (16);
--- 1649,1655 ----
  }
  
  static void
! s_thumb_func (int ignore ATTRIBUTE_UNUSED)
  {
    if (! thumb_mode)
      opcode_select (16);
*************** s_thumb_func (ignore)
*** 3140,3155 ****
     being a thumb function.  */
  
  static void
! s_thumb_set (equiv)
!      int equiv;
  {
    /* XXX the following is a duplicate of the code for s_set() in read.c
       We cannot just call that code as we need to get at the symbol that
       is created.  */
!   register char *    name;
!   register char      delim;
!   register char *    end_name;
!   register symbolS * symbolP;
  
    /* Especial apologies for the random logic:
       This just grew, and could be parsed much more simply!
--- 1665,1679 ----
     being a thumb function.  */
  
  static void
! s_thumb_set (int equiv)
  {
    /* XXX the following is a duplicate of the code for s_set() in read.c
       We cannot just call that code as we need to get at the symbol that
       is created.  */
!   char *    name;
!   char      delim;
!   char *    end_name;
!   symbolS * symbolP;
  
    /* Especial apologies for the random logic:
       This just grew, and could be parsed much more simply!
*************** s_thumb_set (equiv)
*** 3189,3195 ****
        if (listing & LISTING_SYMBOLS)
  	{
  	  extern struct list_info_struct * listing_tail;
! 	  fragS * dummy_frag = (fragS *) xmalloc (sizeof (fragS));
  
  	  memset (dummy_frag, 0, sizeof (fragS));
  	  dummy_frag->fr_type = rs_fill;
--- 1713,1719 ----
        if (listing & LISTING_SYMBOLS)
  	{
  	  extern struct list_info_struct * listing_tail;
! 	  fragS * dummy_frag = xmalloc (sizeof (fragS));
  
  	  memset (dummy_frag, 0, sizeof (fragS));
  	  dummy_frag->fr_type = rs_fill;
*************** s_thumb_set (equiv)
*** 3230,3296 ****
  }
  
  static void
! opcode_select (width)
!      int width;
! {
!   switch (width)
!     {
!     case 16:
!       if (! thumb_mode)
! 	{
! 	  if (! (cpu_variant & ARM_EXT_V4T))
! 	    as_bad (_("selected processor does not support THUMB opcodes"));
! 
! 	  thumb_mode = 1;
! 	  /* No need to force the alignment, since we will have been
!              coming from ARM mode, which is word-aligned.  */
! 	  record_alignment (now_seg, 1);
! 	}
!       mapping_state (MAP_THUMB);
!       break;
! 
!     case 32:
!       if (thumb_mode)
! 	{
! 	  if ((cpu_variant & ARM_ALL) == ARM_EXT_V4T)
! 	    as_bad (_("selected processor does not support ARM opcodes"));
! 
! 	  thumb_mode = 0;
! 
! 	  if (!need_pass_2)
! 	    frag_align (2, 0, 0);
! 
! 	  record_alignment (now_seg, 1);
! 	}
!       mapping_state (MAP_ARM);
!       break;
! 
!     default:
!       as_bad (_("invalid instruction size selected (%d)"), width);
!     }
! }
! 
! static void
! s_arm (ignore)
!      int ignore ATTRIBUTE_UNUSED;
  {
    opcode_select (32);
    demand_empty_rest_of_line ();
  }
  
  static void
! s_thumb (ignore)
!      int ignore ATTRIBUTE_UNUSED;
  {
    opcode_select (16);
    demand_empty_rest_of_line ();
  }
  
  static void
! s_code (unused)
!      int unused ATTRIBUTE_UNUSED;
  {
!   register int temp;
  
    temp = get_absolute_expression ();
    switch (temp)
--- 1754,1776 ----
  }
  
  static void
! s_arm (int ignore ATTRIBUTE_UNUSED)
  {
    opcode_select (32);
    demand_empty_rest_of_line ();
  }
  
  static void
! s_thumb (int ignore ATTRIBUTE_UNUSED)
  {
    opcode_select (16);
    demand_empty_rest_of_line ();
  }
  
  static void
! s_code (int unused ATTRIBUTE_UNUSED)
  {
!   int temp;
  
    temp = get_absolute_expression ();
    switch (temp)
*************** s_code (unused)
*** 3306,3313 ****
  }
  
  static void
! end_of_line (str)
!      char *str;
  {
    skip_whitespace (str);
  
--- 1786,1792 ----
  }
  
  static void
! end_of_line (char * str)
  {
    skip_whitespace (str);
  
*************** end_of_line (str)
*** 3316,3323 ****
  }
  
  static int
! skip_past_comma (str)
!      char ** str;
  {
    char * p = * str, c;
    int comma = 0;
--- 1795,1801 ----
  }
  
  static int
! skip_past_comma (char ** str)
  {
    char * p = * str, c;
    int comma = 0;
*************** skip_past_comma (str)
*** 3336,3350 ****
    return comma ? SUCCESS : FAIL;
  }
  
  /* A standard register must be given at this point.
     SHIFT is the place to put it in inst.instruction.
     Restores input start point on error.
     Returns the reg#, or FAIL.  */
  
  static int
! reg_required_here (str, shift)
!      char ** str;
!      int     shift;
  {
    static char buff [128]; /* XXX  */
    int         reg;
--- 1814,1900 ----
    return comma ? SUCCESS : FAIL;
  }
  
+ /* Return TRUE if anything in the expression is a bignum.  */
+ 
+ static int
+ walk_no_bignums (symbolS * sp)
+ {
+   if (symbol_get_value_expression (sp)->X_op == O_big)
+     return 1;
+ 
+   if (symbol_get_value_expression (sp)->X_add_symbol)
+     {
+       return (walk_no_bignums (symbol_get_value_expression (sp)->X_add_symbol)
+ 	      || (symbol_get_value_expression (sp)->X_op_symbol
+ 		  && walk_no_bignums (symbol_get_value_expression (sp)->X_op_symbol)));
+     }
+ 
+   return 0;
+ }
+ 
+ static int in_my_get_expression = 0;
+ 
+ static int
+ my_get_expression (expressionS * ep, char ** str)
+ {
+   char * save_in;
+   segT   seg;
+ 
+   save_in = input_line_pointer;
+   input_line_pointer = *str;
+   in_my_get_expression = 1;
+   seg = expression (ep);
+   in_my_get_expression = 0;
+ 
+   if (ep->X_op == O_illegal)
+     {
+       /* We found a bad expression in md_operand().  */
+       *str = input_line_pointer;
+       input_line_pointer = save_in;
+       return 1;
+     }
+ 
+ #ifdef OBJ_AOUT
+   if (seg != absolute_section
+       && seg != text_section
+       && seg != data_section
+       && seg != bss_section
+       && seg != undefined_section)
+     {
+       inst.error = _("bad_segment");
+       *str = input_line_pointer;
+       input_line_pointer = save_in;
+       return 1;
+     }
+ #endif
+ 
+   /* Get rid of any bignums now, so that we don't generate an error for which
+      we can't establish a line number later on.  Big numbers are never valid
+      in instructions, which is where this routine is always called.  */
+   if (ep->X_op == O_big
+       || (ep->X_add_symbol
+ 	  && (walk_no_bignums (ep->X_add_symbol)
+ 	      || (ep->X_op_symbol
+ 		  && walk_no_bignums (ep->X_op_symbol)))))
+     {
+       inst.error = _("invalid constant");
+       *str = input_line_pointer;
+       input_line_pointer = save_in;
+       return 1;
+     }
+ 
+   *str = input_line_pointer;
+   input_line_pointer = save_in;
+   return 0;
+ }
+ 
  /* A standard register must be given at this point.
     SHIFT is the place to put it in inst.instruction.
     Restores input start point on error.
     Returns the reg#, or FAIL.  */
  
  static int
! reg_required_here (char ** str, int shift)
  {
    static char buff [128]; /* XXX  */
    int         reg;
*************** reg_required_here (str, shift)
*** 3375,3384 ****
     Returns the reg#, or FAIL.  */
  
  static int
! wreg_required_here (str, shift, reg_type)
!      char ** str;
!      int     shift;
!      enum wreg_type reg_type;
  {
    static char buff [128];
    int    reg;
--- 1925,1933 ----
     Returns the reg#, or FAIL.  */
  
  static int
! wreg_required_here (char ** str,
! 		    int shift,
! 		    enum wreg_type reg_type)
  {
    static char buff [128];
    int    reg;
*************** wreg_required_here (str, shift, reg_type
*** 3420,3427 ****
  }
  
  static const struct asm_psr *
! arm_psr_parse (ccp)
!      register char ** ccp;
  {
    char * start = * ccp;
    char   c;
--- 1969,1975 ----
  }
  
  static const struct asm_psr *
! arm_psr_parse (char ** ccp)
  {
    char * start = * ccp;
    char   c;
*************** arm_psr_parse (ccp)
*** 3463,3470 ****
  /* Parse the input looking for a PSR flag.  */
  
  static int
! psr_required_here (str)
!      char ** str;
  {
    char * start = * str;
    const struct asm_psr * psr;
--- 2011,2017 ----
  /* Parse the input looking for a PSR flag.  */
  
  static int
! psr_required_here (char ** str)
  {
    char * start = * str;
    const struct asm_psr * psr;
*************** psr_required_here (str)
*** 3493,3500 ****
  }
  
  static int
! co_proc_number (str)
!      char **str;
  {
    int processor, pchar;
    char *start;
--- 2040,2046 ----
  }
  
  static int
! co_proc_number (char ** str)
  {
    int processor, pchar;
    char *start;
*************** co_proc_number (str)
*** 3536,3545 ****
  }
  
  static int
! cp_opc_expr (str, where, length)
!      char ** str;
!      int where;
!      int length;
  {
    expressionS expr;
  
--- 2082,2088 ----
  }
  
  static int
! cp_opc_expr (char ** str, int where, int length)
  {
    expressionS expr;
  
*************** cp_opc_expr (str, where, length)
*** 3566,3574 ****
  }
  
  static int
! cp_reg_required_here (str, where)
!      char ** str;
!      int     where;
  {
    int    reg;
    char * start = *str;
--- 2109,2115 ----
  }
  
  static int
! cp_reg_required_here (char ** str, int where)
  {
    int    reg;
    char * start = *str;
*************** cp_reg_required_here (str, where)
*** 3589,3597 ****
  }
  
  static int
! fp_reg_required_here (str, where)
!      char ** str;
!      int     where;
  {
    int    reg;
    char * start = * str;
--- 2130,2136 ----
  }
  
  static int
! fp_reg_required_here (char ** str, int where)
  {
    int    reg;
    char * start = * str;
*************** fp_reg_required_here (str, where)
*** 3612,3619 ****
  }
  
  static int
! cp_address_offset (str)
!      char ** str;
  {
    int offset;
  
--- 2151,2157 ----
  }
  
  static int
! cp_address_offset (char ** str)
  {
    int offset;
  
*************** cp_address_offset (str)
*** 3660,3668 ****
  }
  
  static int
! cp_address_required_here (str, wb_ok)
!      char ** str;
!      int wb_ok;
  {
    char * p = * str;
    int    pre_inc = 0;
--- 2198,2204 ----
  }
  
  static int
! cp_address_required_here (char ** str, int wb_ok)
  {
    char * p = * str;
    int    pre_inc = 0;
*************** cp_address_required_here (str, wb_ok)
*** 3689,3705 ****
  	  if (*p == '\0')
  	    {
  	      /* As an extension to the official ARM syntax we allow:
- 		 
  		   [Rn]
- 		   
  	         as a short hand for:
- 
  		   [Rn,#0]  */
  	      inst.instruction |= PRE_INDEX | INDEX_UP;
  	      *str = p;
  	      return SUCCESS;
  	    }
! 	  
  	  if (skip_past_comma (& p) == FAIL)
  	    {
  	      inst.error = _("comma expected after closing square bracket");
--- 2225,2238 ----
  	  if (*p == '\0')
  	    {
  	      /* As an extension to the official ARM syntax we allow:
  		   [Rn]
  	         as a short hand for:
  		   [Rn,#0]  */
  	      inst.instruction |= PRE_INDEX | INDEX_UP;
  	      *str = p;
  	      return SUCCESS;
  	    }
! 
  	  if (skip_past_comma (& p) == FAIL)
  	    {
  	      inst.error = _("comma expected after closing square bracket");
*************** cp_address_required_here (str, wb_ok)
*** 3772,3778 ****
  	  else
  	    {
  	      inst.error = _("# or { expected after comma");
! 	      return FAIL;	      
  	    }
  	}
        else
--- 2305,2311 ----
  	  else
  	    {
  	      inst.error = _("# or { expected after comma");
! 	      return FAIL;
  	    }
  	}
        else
*************** cp_address_required_here (str, wb_ok)
*** 3831,3838 ****
  }
  
  static int
! cp_byte_address_offset (str)
!      char ** str;
  {
    int offset;
  
--- 2364,2370 ----
  }
  
  static int
! cp_byte_address_offset (char ** str)
  {
    int offset;
  
*************** cp_byte_address_offset (str)
*** 3845,3858 ****
      }
  
    (*str)++;
!   
    if (my_get_expression (& inst.reloc.exp, str))
      return FAIL;
!   
    if (inst.reloc.exp.X_op == O_constant)
      {
        offset = inst.reloc.exp.X_add_number;
!       
        if (offset > 255 || offset < -255)
          {
            inst.error = _("offset too large");
--- 2377,2390 ----
      }
  
    (*str)++;
! 
    if (my_get_expression (& inst.reloc.exp, str))
      return FAIL;
! 
    if (inst.reloc.exp.X_op == O_constant)
      {
        offset = inst.reloc.exp.X_add_number;
! 
        if (offset > 255 || offset < -255)
          {
            inst.error = _("offset too large");
*************** cp_byte_address_offset (str)
*** 3873,3880 ****
  }
  
  static int
! cp_byte_address_required_here (str)
!      char ** str;
  {
    char * p = * str;
    int    pre_inc = 0;
--- 2405,2411 ----
  }
  
  static int
! cp_byte_address_required_here (char ** str)
  {
    char * p = * str;
    int    pre_inc = 0;
*************** cp_byte_address_required_here (str)
*** 3895,3906 ****
        if (*p == ']')
          {
            p++;
!           
            if (skip_past_comma (& p) == SUCCESS)
              {
                /* [Rn], #expr */
                write_back = WRITE_BACK;
!               
                if (reg == REG_PC)
                  {
                    inst.error = _("pc may not be used in post-increment");
--- 2426,2437 ----
        if (*p == ']')
          {
            p++;
! 
            if (skip_past_comma (& p) == SUCCESS)
              {
                /* [Rn], #expr */
                write_back = WRITE_BACK;
! 
                if (reg == REG_PC)
                  {
                    inst.error = _("pc may not be used in post-increment");
*************** cp_byte_address_required_here (str)
*** 3924,3930 ****
              }
  
            pre_inc = PRE_INDEX;
!           
            if (cp_byte_address_offset (& p) == FAIL)
              return FAIL;
  
--- 2455,2461 ----
              }
  
            pre_inc = PRE_INDEX;
! 
            if (cp_byte_address_offset (& p) == FAIL)
              return FAIL;
  
*************** cp_byte_address_required_here (str)
*** 3969,3984 ****
  }
  
  static void
! do_empty (str)
!      char * str;
  {
    /* Do nothing really.  */
    end_of_line (str);
  }
  
  static void
! do_mrs (str)
!      char *str;
  {
    int skip = 0;
  
--- 2500,2513 ----
  }
  
  static void
! do_empty (char * str)
  {
    /* Do nothing really.  */
    end_of_line (str);
  }
  
  static void
! do_mrs (char * str)
  {
    int skip = 0;
  
*************** do_mrs (str)
*** 3999,4014 ****
  
    skip_whitespace (str);
  
!   if (   strcmp (str, "CPSR") == 0
!       || strcmp (str, "SPSR") == 0
  	 /* Lower case versions for backwards compatibility.  */
!       || strcmp (str, "cpsr") == 0
!       || strcmp (str, "spsr") == 0)
      skip = 4;
  
    /* This is for backwards compatibility with older toolchains.  */
!   else if (   strcmp (str, "cpsr_all") == 0
! 	   || strcmp (str, "spsr_all") == 0)
      skip = 8;
    else
      {
--- 2528,2543 ----
  
    skip_whitespace (str);
  
!   if (   streq (str, "CPSR")
!       || streq (str, "SPSR")
  	 /* Lower case versions for backwards compatibility.  */
!       || streq (str, "cpsr")
!       || streq (str, "spsr"))
      skip = 4;
  
    /* This is for backwards compatibility with older toolchains.  */
!   else if (   streq (str, "cpsr_all")
! 	   || streq (str, "spsr_all"))
      skip = 8;
    else
      {
*************** do_mrs (str)
*** 4028,4035 ****
        "{C|S}PSR_f, #expression".  */
  
  static void
! do_msr (str)
!      char * str;
  {
    skip_whitespace (str);
  
--- 2557,2563 ----
        "{C|S}PSR_f, #expression".  */
  
  static void
! do_msr (char * str)
  {
    skip_whitespace (str);
  
*************** do_msr (str)
*** 4111,4118 ****
     SMLAL RdLo, RdHi, Rm, Rs.  */
  
  static void
! do_mull (str)
!      char * str;
  {
    int rdlo, rdhi, rm, rs;
  
--- 2639,2645 ----
     SMLAL RdLo, RdHi, Rm, Rs.  */
  
  static void
! do_mull (char * str)
  {
    int rdlo, rdhi, rm, rs;
  
*************** do_mull (str)
*** 4160,4167 ****
  }
  
  static void
! do_mul (str)
!      char * str;
  {
    int rd, rm;
  
--- 2687,2693 ----
  }
  
  static void
! do_mul (char * str)
  {
    int rd, rm;
  
*************** do_mul (str)
*** 4213,4220 ****
  }
  
  static void
! do_mla (str)
!      char * str;
  {
    int rd, rm;
  
--- 2739,2745 ----
  }
  
  static void
! do_mla (char * str)
  {
    int rd, rm;
  
*************** do_mla (str)
*** 4275,4282 ****
    At that time this routine and its callers can be upgraded to suit.)  */
  
  static int
! accum0_required_here (str)
!      char ** str;
  {
    static char buff [128];	/* Note the address is taken.  Hence, static.  */
    char * p = * str;
--- 2800,2806 ----
    At that time this routine and its callers can be upgraded to suit.)  */
  
  static int
! accum0_required_here (char ** str)
  {
    static char buff [128];	/* Note the address is taken.  Hence, static.  */
    char * p = * str;
*************** accum0_required_here (str)
*** 4285,4307 ****
  
    skip_whitespace (p);
  
!   *str = p;			/* Advance caller's string pointer too.  */
!   c = *p++;
!   while (ISALNUM (c))
!     c = *p++;
  
!   *--p = 0;			/* Aap nul into input buffer at non-alnum.  */
  
!   if (! ( streq (*str, "acc0") || streq (*str, "ACC0")))
!     {
!       sprintf (buff, _("acc0 expected, not '%.100s'"), *str);
!       inst.error = buff;
!       result = FAIL;
      }
- 
-   *p = c;			/* Unzap.  */
-   *str = p;			/* Caller's string pointer to after match.  */
-   return result;
  }
  
  /* Expects **str -> after a comma. May be leading blanks.
--- 2809,2890 ----
  
    skip_whitespace (p);
  
!   *str = p;			/* Advance caller's string pointer too.  */
!   c = *p++;
!   while (ISALNUM (c))
!     c = *p++;
! 
!   *--p = 0;			/* Aap nul into input buffer at non-alnum.  */
! 
!   if (! ( streq (*str, "acc0") || streq (*str, "ACC0")))
!     {
!       sprintf (buff, _("acc0 expected, not '%.100s'"), *str);
!       inst.error = buff;
!       result = FAIL;
!     }
! 
!   *p = c;			/* Unzap.  */
!   *str = p;			/* Caller's string pointer to after match.  */
!   return result;
! }
! 
! static int
! ldst_extend_v4 (char ** str)
! {
!   int add = INDEX_UP;
! 
!   switch (**str)
!     {
!     case '#':
!     case '$':
!       (*str)++;
!       if (my_get_expression (& inst.reloc.exp, str))
! 	return FAIL;
! 
!       if (inst.reloc.exp.X_op == O_constant)
! 	{
! 	  int value = inst.reloc.exp.X_add_number;
! 
! 	  if (value < -255 || value > 255)
! 	    {
! 	      inst.error = _("address offset too large");
! 	      return FAIL;
! 	    }
! 
! 	  if (value < 0)
! 	    {
! 	      value = -value;
! 	      add = 0;
! 	    }
! 
! 	  /* Halfword and signextension instructions have the
!              immediate value split across bits 11..8 and bits 3..0.  */
! 	  inst.instruction |= (add | HWOFFSET_IMM
! 			       | ((value >> 4) << 8) | (value & 0xF));
! 	}
!       else
! 	{
! 	  inst.instruction |= HWOFFSET_IMM;
! 	  inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
! 	  inst.reloc.pc_rel = 0;
! 	}
!       return SUCCESS;
! 
!     case '-':
!       add = 0;
!       /* Fall through.  */
! 
!     case '+':
!       (*str)++;
!       /* Fall through.  */
  
!     default:
!       if (reg_required_here (str, 0) == FAIL)
! 	return FAIL;
  
!       inst.instruction |= add;
!       return SUCCESS;
      }
  }
  
  /* Expects **str -> after a comma. May be leading blanks.
*************** accum0_required_here (str)
*** 4312,4319 ****
     Note: doesn't know Rd, so no err checks that require such knowledge.  */
  
  static int
! ld_mode_required_here (string)
!      char ** string;
  {
    char * str = * string;
    int    rn;
--- 2895,2901 ----
     Note: doesn't know Rd, so no err checks that require such knowledge.  */
  
  static int
! ld_mode_required_here (char ** string)
  {
    char * str = * string;
    int    rn;
*************** ld_mode_required_here (string)
*** 4417,4424 ****
     Error if any register is R15.  */
  
  static void
! do_smla (str)
!      char *        str;
  {
    int rd, rm, rs, rn;
  
--- 2999,3005 ----
     Error if any register is R15.  */
  
  static void
! do_smla (char * str)
  {
    int rd, rm, rs, rn;
  
*************** do_smla (str)
*** 4446,4453 ****
     Warning if Rdlo == Rdhi.  */
  
  static void
! do_smlal (str)
!      char *        str;
  {
    int rdlo, rdhi, rm, rs;
  
--- 3027,3033 ----
     Warning if Rdlo == Rdhi.  */
  
  static void
! do_smlal (char * str)
  {
    int rdlo, rdhi, rm, rs;
  
*************** do_smlal (str)
*** 4482,4489 ****
     Error if any register is R15.  */
  
  static void
! do_smul (str)
!      char *        str;
  {
    int rd, rm, rs;
  
--- 3062,3068 ----
     Error if any register is R15.  */
  
  static void
! do_smul (char * str)
  {
    int rd, rm, rs;
  
*************** do_smul (str)
*** 4508,4515 ****
     Error if any register is R15.  */
  
  static void
! do_qadd (str)
!      char *        str;
  {
    int rd, rm, rn;
  
--- 3087,3093 ----
     Error if any register is R15.  */
  
  static void
! do_qadd (char * str)
  {
    int rd, rm, rn;
  
*************** do_qadd (str)
*** 4539,4546 ****
     Result unpredicatable if Rd or Rn is R15.  */
  
  static void
! do_co_reg2c (str)
!      char *        str;
  {
    int rd, rn;
  
--- 3117,3123 ----
     Result unpredicatable if Rd or Rn is R15.  */
  
  static void
! do_co_reg2c (char * str)
  {
    int rd, rn;
  
*************** do_co_reg2c (str)
*** 4599,4606 ****
       Error if Rd or Rm are R15.  */
  
  static void
! do_clz (str)
!      char *        str;
  {
    int rd, rm;
  
--- 3176,3182 ----
       Error if Rd or Rm are R15.  */
  
  static void
! do_clz (char * str)
  {
    int rd, rm;
  
*************** do_clz (str)
*** 4625,4632 ****
       Otherwise, it's the same as LDC/STC.  */
  
  static void
! do_lstc2 (str)
!      char *        str;
  {
    skip_whitespace (str);
  
--- 3201,3207 ----
       Otherwise, it's the same as LDC/STC.  */
  
  static void
! do_lstc2 (char * str)
  {
    skip_whitespace (str);
  
*************** do_lstc2 (str)
*** 4657,4664 ****
       Otherwise, it's the same as CDP.  */
  
  static void
! do_cdp2 (str)
!      char *        str;
  {
    skip_whitespace (str);
  
--- 3232,3238 ----
       Otherwise, it's the same as CDP.  */
  
  static void
! do_cdp2 (char * str)
  {
    skip_whitespace (str);
  
*************** do_cdp2 (str)
*** 4721,4728 ****
       Otherwise, it's the same as MCR/MRC.  */
  
  static void
! do_co_reg2 (str)
!      char *        str;
  {
    skip_whitespace (str);
  
--- 3295,3301 ----
       Otherwise, it's the same as MCR/MRC.  */
  
  static void
! do_co_reg2 (char * str)
  {
    skip_whitespace (str);
  
*************** do_co_reg2 (str)
*** 4778,4787 ****
    end_of_line (str);
  }
  
  /* ARM v5TEJ.  Jump to Jazelle code.  */
  static void
! do_bxj (str)
!      char * str;
  {
    int reg;
  
--- 3351,3380 ----
    end_of_line (str);
  }
  
+ static void
+ do_bx (char * str)
+ {
+   int reg;
+ 
+   skip_whitespace (str);
+ 
+   if ((reg = reg_required_here (&str, 0)) == FAIL)
+     {
+       inst.error = BAD_ARGS;
+       return;
+     }
+ 
+   /* Note - it is not illegal to do a "bx pc".  Useless, but not illegal.  */
+   if (reg == REG_PC)
+     as_tsktsk (_("use of r15 in bx in ARM mode is not really useful"));
+ 
+   end_of_line (str);
+ }
+ 
  /* ARM v5TEJ.  Jump to Jazelle code.  */
+ 
  static void
! do_bxj (char * str)
  {
    int reg;
  
*************** do_bxj (str)
*** 4793,4928 ****
        return;
      }
  
!   /* Note - it is not illegal to do a "bxj pc".  Useless, but not illegal.  */
!   if (reg == REG_PC)
!     as_tsktsk (_("use of r15 in bxj is not really useful"));
! 
!   end_of_line (str);
  }
  
- /* ARM V6 umaal (argument parse). */
- 
  static void
! do_umaal (str)
!      char *str;
  {
  
!   int rdlo, rdhi, rm, rs;
  
!   skip_whitespace (str);
!   if ((rdlo = reg_required_here (& str, 12)) == FAIL
!       || skip_past_comma (& str) == FAIL
!       || (rdhi = reg_required_here (& str, 16)) == FAIL
!       || skip_past_comma (& str) == FAIL
!       || (rm = reg_required_here (& str, 0)) == FAIL
!       || skip_past_comma (& str) == FAIL
!       || (rs = reg_required_here (& str, 8)) == FAIL)
      {
        inst.error = BAD_ARGS;
!       return;      
      }
! 
!   if (rdlo == REG_PC || rdhi == REG_PC || rm == REG_PC || rs == REG_PC)
      {
        inst.error = BAD_PC;
        return;
      }
  
!   end_of_line (str);
! }
! 
! /* ARM V6 strex (argument parse). */
! 
! static void 
! do_strex (str)
!      char *str;
! {
!   int rd, rm, rn;
! 
!   /* Parse Rd, Rm,. */
!   skip_whitespace (str);
!   if ((rd = reg_required_here (& str, 12)) == FAIL
!       || skip_past_comma (& str) == FAIL
!       || (rm = reg_required_here (& str, 0)) == FAIL
!       || skip_past_comma (& str) == FAIL)
      {
!       inst.error = BAD_ARGS;
        return;
      }
!   if (rd == REG_PC || rm == REG_PC)
      {
!       inst.error = BAD_PC;
        return;
      }
!   if (rd == rm)
      {
!       inst.error = _("Rd equal to Rm or Rn yields unpredictable results");
        return;
      }
! 
!   /* Skip past '['. */
!   if ((strlen (str) >= 1) 
!       && strncmp (str, "[", 1) == 0)
!     str+=1;
!   skip_whitespace (str);  
! 
!   /* Parse Rn. */
!   if ((rn = reg_required_here (& str, 16)) == FAIL)
      {
        inst.error = BAD_ARGS;
        return;
      }
!   else if (rn == REG_PC)
      {
!       inst.error = BAD_PC;
        return;
      }
!   if (rd == rn)
      {
!       inst.error = _("Rd equal to Rm or Rn yields unpredictable results");
        return;
      }
-   skip_whitespace (str);  
  
!   /* Skip past ']'. */
!   if ((strlen (str) >= 1) 
!       && strncmp (str, "]", 1) == 0)
!     str+=1;
!   
!   end_of_line (str);
  }
  
! /* ARM V6 ssat (argument parse). */
  
  static void
! do_ssat (str)
!      char* str;
  {
    do_sat (&str, /*bias=*/-1);
    end_of_line (str);
  }
  
! /* ARM V6 usat (argument parse). */
  
  static void
! do_usat (str)
!      char* str;
  {
    do_sat (&str, /*bias=*/0);
    end_of_line (str);
  }
  
  static void
! do_sat (str, bias)
!      char **str;
!      int    bias;
  {
    int rd, rm;
    expressionS expr;
  
    skip_whitespace (*str);
!   
!   /* Parse <Rd>, field. */
    if ((rd = reg_required_here (str, 12)) == FAIL
        || skip_past_comma (str) == FAIL)
      {
--- 3386,3714 ----
        return;
      }
  
!   /* Note - it is not illegal to do a "bxj pc".  Useless, but not illegal.  */
!   if (reg == REG_PC)
!     as_tsktsk (_("use of r15 in bxj is not really useful"));
! 
!   end_of_line (str);
! }
! 
! /* ARM V6 umaal (argument parse).  */
! 
! static void
! do_umaal (char * str)
! {
!   int rdlo, rdhi, rm, rs;
! 
!   skip_whitespace (str);
!   if ((rdlo = reg_required_here (& str, 12)) == FAIL
!       || skip_past_comma (& str) == FAIL
!       || (rdhi = reg_required_here (& str, 16)) == FAIL
!       || skip_past_comma (& str) == FAIL
!       || (rm = reg_required_here (& str, 0)) == FAIL
!       || skip_past_comma (& str) == FAIL
!       || (rs = reg_required_here (& str, 8)) == FAIL)
!     {
!       inst.error = BAD_ARGS;
!       return;
!     }
! 
!   if (rdlo == REG_PC || rdhi == REG_PC || rm == REG_PC || rs == REG_PC)
!     {
!       inst.error = BAD_PC;
!       return;
!     }
! 
!   end_of_line (str);
! }
! 
! /* ARM V6 strex (argument parse).  */
! 
! static void
! do_strex (char * str)
! {
!   int rd, rm, rn;
! 
!   /* Parse Rd, Rm,.  */
!   skip_whitespace (str);
!   if ((rd = reg_required_here (& str, 12)) == FAIL
!       || skip_past_comma (& str) == FAIL
!       || (rm = reg_required_here (& str, 0)) == FAIL
!       || skip_past_comma (& str) == FAIL)
!     {
!       inst.error = BAD_ARGS;
!       return;
!     }
!   if (rd == REG_PC || rm == REG_PC)
!     {
!       inst.error = BAD_PC;
!       return;
!     }
!   if (rd == rm)
!     {
!       inst.error = _("Rd equal to Rm or Rn yields unpredictable results");
!       return;
!     }
! 
!   /* Skip past '['.  */
!   if ((strlen (str) >= 1)
!       && strncmp (str, "[", 1) == 0)
!     str += 1;
! 
!   skip_whitespace (str);
! 
!   /* Parse Rn.  */
!   if ((rn = reg_required_here (& str, 16)) == FAIL)
!     {
!       inst.error = BAD_ARGS;
!       return;
!     }
!   else if (rn == REG_PC)
!     {
!       inst.error = BAD_PC;
!       return;
!     }
!   if (rd == rn)
!     {
!       inst.error = _("Rd equal to Rm or Rn yields unpredictable results");
!       return;
!     }
!   skip_whitespace (str);
! 
!   /* Skip past ']'.  */
!   if ((strlen (str) >= 1)
!       && strncmp (str, "]", 1) == 0)
!     str += 1;
! 
!   end_of_line (str);
! }
! 
! /* KIND indicates what kind of shifts are accepted.  */
! 
! static int
! decode_shift (char ** str, int kind)
! {
!   const struct asm_shift_name * shift;
!   char * p;
!   char   c;
! 
!   skip_whitespace (* str);
! 
!   for (p = * str; ISALPHA (* p); p ++)
!     ;
! 
!   if (p == * str)
!     {
!       inst.error = _("shift expression expected");
!       return FAIL;
!     }
! 
!   c = * p;
!   * p = '\0';
!   shift = (const struct asm_shift_name *) hash_find (arm_shift_hsh, * str);
!   * p = c;
! 
!   if (shift == NULL)
!     {
!       inst.error = _("shift expression expected");
!       return FAIL;
!     }
! 
!   assert (shift->properties->index == shift_properties[shift->properties->index].index);
! 
!   if (kind == SHIFT_LSL_OR_ASR_IMMEDIATE
!       && shift->properties->index != SHIFT_LSL
!       && shift->properties->index != SHIFT_ASR)
!     {
!       inst.error = _("'LSL' or 'ASR' required");
!       return FAIL;
!     }
!   else if (kind == SHIFT_LSL_IMMEDIATE
! 	   && shift->properties->index != SHIFT_LSL)
!     {
!       inst.error = _("'LSL' required");
!       return FAIL;
!     }
!   else if (kind == SHIFT_ASR_IMMEDIATE
! 	   && shift->properties->index != SHIFT_ASR)
!     {
!       inst.error = _("'ASR' required");
!       return FAIL;
!     }
! 
!   if (shift->properties->index == SHIFT_RRX)
!     {
!       * str = p;
!       inst.instruction |= shift->properties->bit_field;
!       return SUCCESS;
!     }
! 
!   skip_whitespace (p);
! 
!   if (kind == NO_SHIFT_RESTRICT && reg_required_here (& p, 8) != FAIL)
!     {
!       inst.instruction |= shift->properties->bit_field | SHIFT_BY_REG;
!       * str = p;
!       return SUCCESS;
!     }
!   else if (! is_immediate_prefix (* p))
!     {
!       inst.error = (NO_SHIFT_RESTRICT
! 		    ? _("shift requires register or #expression")
! 		    : _("shift requires #expression"));
!       * str = p;
!       return FAIL;
!     }
! 
!   inst.error = NULL;
!   p ++;
! 
!   if (my_get_expression (& inst.reloc.exp, & p))
!     return FAIL;
! 
!   /* Validate some simple #expressions.  */
!   if (inst.reloc.exp.X_op == O_constant)
!     {
!       unsigned num = inst.reloc.exp.X_add_number;
! 
!       /* Reject operations greater than 32.  */
!       if (num > 32
! 	  /* Reject a shift of 0 unless the mode allows it.  */
! 	  || (num == 0 && shift->properties->allows_0 == 0)
! 	  /* Reject a shift of 32 unless the mode allows it.  */
! 	  || (num == 32 && shift->properties->allows_32 == 0)
! 	  )
! 	{
! 	  /* As a special case we allow a shift of zero for
! 	     modes that do not support it to be recoded as an
! 	     logical shift left of zero (ie nothing).  We warn
! 	     about this though.  */
! 	  if (num == 0)
! 	    {
! 	      as_warn (_("shift of 0 ignored."));
! 	      shift = & shift_names[0];
! 	      assert (shift->properties->index == SHIFT_LSL);
! 	    }
! 	  else
! 	    {
! 	      inst.error = _("invalid immediate shift");
! 	      return FAIL;
! 	    }
! 	}
! 
!       /* Shifts of 32 are encoded as 0, for those shifts that
! 	 support it.  */
!       if (num == 32)
! 	num = 0;
! 
!       inst.instruction |= (num << 7) | shift->properties->bit_field;
!     }
!   else
!     {
!       inst.reloc.type   = BFD_RELOC_ARM_SHIFT_IMM;
!       inst.reloc.pc_rel = 0;
!       inst.instruction |= shift->properties->bit_field;
!     }
! 
!   * str = p;
!   return SUCCESS;
  }
  
  static void
! do_sat (char ** str, int bias)
  {
+   int rd, rm;
+   expressionS expr;
  
!   skip_whitespace (*str);
  
!   /* Parse <Rd>, field.  */
!   if ((rd = reg_required_here (str, 12)) == FAIL
!       || skip_past_comma (str) == FAIL)
      {
        inst.error = BAD_ARGS;
!       return;
      }
!   if (rd == REG_PC)
      {
        inst.error = BAD_PC;
        return;
      }
  
!   /* Parse #<immed>,  field.  */
!   if (is_immediate_prefix (**str))
!     (*str)++;
!   else
      {
!       inst.error = _("immediate expression expected");
        return;
      }
!   if (my_get_expression (&expr, str))
      {
!       inst.error = _("bad expression");
        return;
      }
!   if (expr.X_op != O_constant)
      {
!       inst.error = _("constant expression expected");
        return;
      }
!   if (expr.X_add_number + bias < 0
!       || expr.X_add_number + bias > 31)
!     {
!       inst.error = _("immediate value out of range");
!       return;
!     }
!   inst.instruction |= (expr.X_add_number + bias) << 16;
!   if (skip_past_comma (str) == FAIL)
      {
        inst.error = BAD_ARGS;
        return;
      }
! 
!   /* Parse <Rm> field.  */
!   if ((rm = reg_required_here (str, 0)) == FAIL)
      {
!       inst.error = BAD_ARGS;
        return;
      }
!   if (rm == REG_PC)
      {
!       inst.error = BAD_PC;
        return;
      }
  
!   if (skip_past_comma (str) == SUCCESS)
!     decode_shift (str, SHIFT_LSL_OR_ASR_IMMEDIATE);
  }
  
! /* ARM V6 ssat (argument parse).  */
  
  static void
! do_ssat (char * str)
  {
    do_sat (&str, /*bias=*/-1);
    end_of_line (str);
  }
  
! /* ARM V6 usat (argument parse).  */
  
  static void
! do_usat (char * str)
  {
    do_sat (&str, /*bias=*/0);
    end_of_line (str);
  }
  
  static void
! do_sat16 (char ** str, int bias)
  {
    int rd, rm;
    expressionS expr;
  
    skip_whitespace (*str);
! 
!   /* Parse the <Rd> field.  */
    if ((rd = reg_required_here (str, 12)) == FAIL
        || skip_past_comma (str) == FAIL)
      {
*************** do_sat (str, bias)
*** 4935,4941 ****
        return;
      }
  
!   /* Parse #<immed>,  field. */
    if (is_immediate_prefix (**str))
      (*str)++;
    else
--- 3721,3727 ----
        return;
      }
  
!   /* Parse #<immed>, field.  */
    if (is_immediate_prefix (**str))
      (*str)++;
    else
*************** do_sat (str, bias)
*** 4954,4960 ****
        return;
      }
    if (expr.X_add_number + bias < 0
!       || expr.X_add_number + bias > 31)
      {
        inst.error = _("immediate value out of range");
        return;
--- 3740,3746 ----
        return;
      }
    if (expr.X_add_number + bias < 0
!       || expr.X_add_number + bias > 15)
      {
        inst.error = _("immediate value out of range");
        return;
*************** do_sat (str, bias)
*** 4966,4972 ****
        return;
      }
  
!   /* Parse <Rm> field. */
    if ((rm = reg_required_here (str, 0)) == FAIL)
      {
        inst.error = BAD_ARGS;
--- 3752,3758 ----
        return;
      }
  
!   /* Parse <Rm> field.  */
    if ((rm = reg_required_here (str, 0)) == FAIL)
      {
        inst.error = BAD_ARGS;
*************** do_sat (str, bias)
*** 4977,5077 ****
        inst.error = BAD_PC;
        return;
      }
- 
-   if (skip_past_comma (str) == SUCCESS)
-     decode_shift (str, SHIFT_LSL_OR_ASR_IMMEDIATE);
  }
  
! /* ARM V6 ssat16 (argument parse). */
  
  static void
! do_ssat16 (str)
!      char *str;
  {
    do_sat16 (&str, /*bias=*/-1);
    end_of_line (str);
  }
  
  static void
! do_usat16 (str)
!      char *str;
  {
    do_sat16 (&str, /*bias=*/0);
    end_of_line (str);
  }
  
  static void
! do_sat16 (str, bias)
!      char **str;
!      int bias;
  {
-   int rd, rm;
    expressionS expr;
  
    skip_whitespace (*str);
  
!   /* Parse the <Rd> field. */
!   if ((rd = reg_required_here (str, 12)) == FAIL
!       || skip_past_comma (str) == FAIL)
!     {
!       inst.error = BAD_ARGS;
!       return;
!     }
!   if (rd == REG_PC)
!     {
!       inst.error = BAD_PC;
!       return;
!     }
! 
!   /* Parse #<immed>, field. */
!   if (is_immediate_prefix (**str))
!     (*str)++;
!   else
      {
        inst.error = _("immediate expression expected");
        return;
      }
    if (my_get_expression (&expr, str))
      {
        inst.error = _("bad expression");
        return;
      }
    if (expr.X_op != O_constant)
      {
        inst.error = _("constant expression expected");
        return;
      }
-   if (expr.X_add_number + bias < 0
-       || expr.X_add_number + bias > 15)
-     {
-       inst.error = _("immediate value out of range");
-       return;
-     }
-   inst.instruction |= (expr.X_add_number + bias) << 16;
-   if (skip_past_comma (str) == FAIL)
-     {
-       inst.error = BAD_ARGS;
-       return;
-     }
  
!   /* Parse <Rm> field. */
!   if ((rm = reg_required_here (str, 0)) == FAIL)
!     {
!       inst.error = BAD_ARGS;
!       return;
!     }
!   if (rm == REG_PC)
      {
!       inst.error = BAD_PC;
        return;
      }
  }
  
! /* ARM V6 srs (argument parse). */
  
  static void
! do_srs (str)
!      char* str;
  {
    char *exclam;
    skip_whitespace (str);
--- 3763,3827 ----
        inst.error = BAD_PC;
        return;
      }
  }
  
! /* ARM V6 ssat16 (argument parse).  */
  
  static void
! do_ssat16 (char * str)
  {
    do_sat16 (&str, /*bias=*/-1);
    end_of_line (str);
  }
  
  static void
! do_usat16 (char * str)
  {
    do_sat16 (&str, /*bias=*/0);
    end_of_line (str);
  }
  
  static void
! do_cps_mode (char ** str)
  {
    expressionS expr;
  
    skip_whitespace (*str);
  
!   if (! is_immediate_prefix (**str))
      {
        inst.error = _("immediate expression expected");
        return;
      }
+ 
+   (*str)++; /* Strip off the immediate signifier.  */
    if (my_get_expression (&expr, str))
      {
        inst.error = _("bad expression");
        return;
      }
+ 
    if (expr.X_op != O_constant)
      {
        inst.error = _("constant expression expected");
        return;
      }
  
!   /* The mode is a 5 bit field.  Valid values are 0-31.  */
!   if (((unsigned) expr.X_add_number) > 31
!       || (inst.reloc.exp.X_add_number) < 0)
      {
!       inst.error = _("invalid constant");
        return;
      }
+ 
+   inst.instruction |= expr.X_add_number;
  }
  
! /* ARM V6 srs (argument parse).  */
  
  static void
! do_srs (char * str)
  {
    char *exclam;
    skip_whitespace (str);
*************** do_srs (str)
*** 5081,5087 ****
    do_cps_mode (&str);
    if (exclam)
      *exclam = '!';
!   if (*str == '!') 
      {
        inst.instruction |= WRITE_BACK;
        str++;
--- 3831,3837 ----
    do_cps_mode (&str);
    if (exclam)
      *exclam = '!';
!   if (*str == '!')
      {
        inst.instruction |= WRITE_BACK;
        str++;
*************** do_srs (str)
*** 5089,5102 ****
    end_of_line (str);
  }
  
! /* ARM V6 SMMUL (argument parse). */
  
  static void
! do_smmul (str)
!      char* str;
  {
    int rd, rm, rs;
!   
    skip_whitespace (str);
    if ((rd = reg_required_here (&str, 16)) == FAIL
        || skip_past_comma (&str) == FAIL
--- 3839,3851 ----
    end_of_line (str);
  }
  
! /* ARM V6 SMMUL (argument parse).  */
  
  static void
! do_smmul (char * str)
  {
    int rd, rm, rs;
! 
    skip_whitespace (str);
    if ((rd = reg_required_here (&str, 16)) == FAIL
        || skip_past_comma (&str) == FAIL
*************** do_smmul (str)
*** 5108,5114 ****
        return;
      }
  
!   if (rd == REG_PC 
        || rm == REG_PC
        || rs == REG_PC)
      {
--- 3857,3863 ----
        return;
      }
  
!   if (   rd == REG_PC
        || rm == REG_PC
        || rs == REG_PC)
      {
*************** do_smmul (str)
*** 5117,5132 ****
      }
  
    end_of_line (str);
-   
  }
  
! /* ARM V6 SMLALD (argument parse). */
  
  static void
! do_smlald (str)
!     char* str;
  {
    int rdlo, rdhi, rm, rs;
    skip_whitespace (str);
    if ((rdlo = reg_required_here (&str, 12)) == FAIL
        || skip_past_comma (&str) == FAIL
--- 3866,3880 ----
      }
  
    end_of_line (str);
  }
  
! /* ARM V6 SMLALD (argument parse).  */
  
  static void
! do_smlald (char * str)
  {
    int rdlo, rdhi, rm, rs;
+ 
    skip_whitespace (str);
    if ((rdlo = reg_required_here (&str, 12)) == FAIL
        || skip_past_comma (&str) == FAIL
*************** do_smlald (str)
*** 5140,5147 ****
        return;
      }
  
!   if (rdlo == REG_PC 
!       || rdhi == REG_PC 
        || rm == REG_PC
        || rs == REG_PC)
      {
--- 3888,3895 ----
        return;
      }
  
!   if (   rdlo == REG_PC
!       || rdhi == REG_PC
        || rm == REG_PC
        || rs == REG_PC)
      {
*************** do_smlald (str)
*** 5152,5166 ****
    end_of_line (str);
  }
  
! /* ARM V6 SMLAD (argument parse).  Signed multiply accumulate dual. 
     smlad{x}{<cond>} Rd, Rm, Rs, Rn */
  
! static void 
! do_smlad (str)
!      char *str;
  {
    int rd, rm, rs, rn;
!   
    skip_whitespace (str);
    if ((rd = reg_required_here (&str, 16)) == FAIL
        || skip_past_comma (&str) == FAIL
--- 3900,3913 ----
    end_of_line (str);
  }
  
! /* ARM V6 SMLAD (argument parse).  Signed multiply accumulate dual.
     smlad{x}{<cond>} Rd, Rm, Rs, Rn */
  
! static void
! do_smlad (char * str)
  {
    int rd, rm, rs, rn;
! 
    skip_whitespace (str);
    if ((rd = reg_required_here (&str, 16)) == FAIL
        || skip_past_comma (&str) == FAIL
*************** do_smlad (str)
*** 5173,5181 ****
        inst.error = BAD_ARGS;
        return;
      }
!   
!   if (rd == REG_PC 
!       || rn == REG_PC 
        || rs == REG_PC
        || rm == REG_PC)
      {
--- 3920,3928 ----
        inst.error = BAD_ARGS;
        return;
      }
! 
!   if (   rd == REG_PC
!       || rn == REG_PC
        || rs == REG_PC
        || rm == REG_PC)
      {
*************** do_smlad (str)
*** 5184,5210 ****
      }
  
    end_of_line (str);
- } 
- 
- /* ARM V6 SETEND (argument parse).  Sets the E bit in the CPSR while
-    preserving the other bits.
- 
-    setend <endian_specifier>, where <endian_specifier> is either 
-    BE or LE. */
- 
- static void 
- do_setend (str)
-      char *str;
- {
-   if (do_endian_specifier (str))
-     inst.instruction |= 0x200;
  }
  
  /* Returns true if the endian-specifier indicates big-endianness.  */
  
  static int
! do_endian_specifier (str)
!      char *str;
  {
    int big_endian = 0;
  
--- 3931,3942 ----
      }
  
    end_of_line (str);
  }
  
  /* Returns true if the endian-specifier indicates big-endianness.  */
  
  static int
! do_endian_specifier (char * str)
  {
    int big_endian = 0;
  
*************** do_endian_specifier (str)
*** 5226,5240 ****
    return big_endian;
  }
  
  /* ARM V6 SXTH.
  
     SXTH {<cond>} <Rd>, <Rm>{, <rotation>}
     Condition defaults to COND_ALWAYS.
!    Error if any register uses R15. */
  
! static void 
! do_sxth (str)
!      char *str;
  {
    int rd, rm;
    expressionS expr;
--- 3958,3984 ----
    return big_endian;
  }
  
+ /* ARM V6 SETEND (argument parse).  Sets the E bit in the CPSR while
+    preserving the other bits.
+ 
+    setend <endian_specifier>, where <endian_specifier> is either
+    BE or LE.  */
+ 
+ static void
+ do_setend (char * str)
+ {
+   if (do_endian_specifier (str))
+     inst.instruction |= 0x200;
+ }
+ 
  /* ARM V6 SXTH.
  
     SXTH {<cond>} <Rd>, <Rm>{, <rotation>}
     Condition defaults to COND_ALWAYS.
!    Error if any register uses R15.  */
  
! static void
! do_sxth (char * str)
  {
    int rd, rm;
    expressionS expr;
*************** do_sxth (str)
*** 5242,5248 ****
    int rotation_eight_mask = 0x00000400;
    int rotation_sixteen_mask = 0x00000800;
    int rotation_twenty_four_mask = 0x00000c00;
!   
    skip_whitespace (str);
    if ((rd = reg_required_here (&str, 12)) == FAIL
        || skip_past_comma (&str) == FAIL
--- 3986,3992 ----
    int rotation_eight_mask = 0x00000400;
    int rotation_sixteen_mask = 0x00000800;
    int rotation_twenty_four_mask = 0x00000c00;
! 
    skip_whitespace (str);
    if ((rd = reg_required_here (&str, 12)) == FAIL
        || skip_past_comma (&str) == FAIL
*************** do_sxth (str)
*** 5257,5284 ****
        inst.error = BAD_PC;
        return;
      }
!   
!   /* Zero out the rotation field. */
    inst.instruction &= rotation_clear_mask;
!   
!   /* Check for lack of optional rotation field. */
    if (skip_past_comma (&str) == FAIL)
      {
        end_of_line (str);
        return;
      }
!   
!   /* Move past 'ROR'. */
    skip_whitespace (str);
    if (strncasecmp (str, "ROR", 3) == 0)
!     str+=3;
    else
      {
        inst.error = _("missing rotation field after comma");
        return;
      }
!   
!   /* Get the immediate constant. */
    skip_whitespace (str);
    if (is_immediate_prefix (* str))
      str++;
--- 4001,4028 ----
        inst.error = BAD_PC;
        return;
      }
! 
!   /* Zero out the rotation field.  */
    inst.instruction &= rotation_clear_mask;
! 
!   /* Check for lack of optional rotation field.  */
    if (skip_past_comma (&str) == FAIL)
      {
        end_of_line (str);
        return;
      }
! 
!   /* Move past 'ROR'.  */
    skip_whitespace (str);
    if (strncasecmp (str, "ROR", 3) == 0)
!     str += 3;
    else
      {
        inst.error = _("missing rotation field after comma");
        return;
      }
! 
!   /* Get the immediate constant.  */
    skip_whitespace (str);
    if (is_immediate_prefix (* str))
      str++;
*************** do_sxth (str)
*** 5287,5293 ****
        inst.error = _("immediate expression expected");
        return;
      }
!   
    if (my_get_expression (&expr, &str))
      {
        inst.error = _("bad expression");
--- 4031,4037 ----
        inst.error = _("immediate expression expected");
        return;
      }
! 
    if (my_get_expression (&expr, &str))
      {
        inst.error = _("bad expression");
*************** do_sxth (str)
*** 5299,5309 ****
        inst.error = _("constant expression expected");
        return;
      }
!   
!   switch (expr.X_add_number) 
      {
      case 0:
!       /* Rotation field has already been zeroed. */
        break;
      case 8:
        inst.instruction |= rotation_eight_mask;
--- 4043,4053 ----
        inst.error = _("constant expression expected");
        return;
      }
! 
!   switch (expr.X_add_number)
      {
      case 0:
!       /* Rotation field has already been zeroed.  */
        break;
      case 8:
        inst.instruction |= rotation_eight_mask;
*************** do_sxth (str)
*** 5312,5318 ****
      case 16:
        inst.instruction |= rotation_sixteen_mask;
        break;
!       
      case 24:
        inst.instruction |= rotation_twenty_four_mask;
        break;
--- 4056,4062 ----
      case 16:
        inst.instruction |= rotation_sixteen_mask;
        break;
! 
      case 24:
        inst.instruction |= rotation_twenty_four_mask;
        break;
*************** do_sxth (str)
*** 5323,5329 ****
      }
  
    end_of_line (str);
-   
  }
  
  /* ARM V6 SXTAH extracts a 16-bit value from a register, sign
--- 4067,4072 ----
*************** do_sxth (str)
*** 5332,5342 ****
     before extracting the 16-bit value.
     SXTAH{<cond>} <Rd>, <Rn>, <Rm>{, <rotation>}
     Condition defaults to COND_ALWAYS.
!    Error if any register uses R15. */
  
! static void 
! do_sxtah (str)
!      char *str;
  {
    int rd, rn, rm;
    expressionS expr;
--- 4075,4084 ----
     before extracting the 16-bit value.
     SXTAH{<cond>} <Rd>, <Rn>, <Rm>{, <rotation>}
     Condition defaults to COND_ALWAYS.
!    Error if any register uses R15.  */
  
! static void
! do_sxtah (char * str)
  {
    int rd, rn, rm;
    expressionS expr;
*************** do_sxtah (str)
*** 5344,5350 ****
    int rotation_eight_mask = 0x00000400;
    int rotation_sixteen_mask = 0x00000800;
    int rotation_twenty_four_mask = 0x00000c00;
!   
    skip_whitespace (str);
    if ((rd = reg_required_here (&str, 12)) == FAIL
        || skip_past_comma (&str) == FAIL
--- 4086,4092 ----
    int rotation_eight_mask = 0x00000400;
    int rotation_sixteen_mask = 0x00000800;
    int rotation_twenty_four_mask = 0x00000c00;
! 
    skip_whitespace (str);
    if ((rd = reg_required_here (&str, 12)) == FAIL
        || skip_past_comma (&str) == FAIL
*************** do_sxtah (str)
*** 5361,5388 ****
        inst.error = BAD_PC;
        return;
      }
!   
!   /* Zero out the rotation field. */
    inst.instruction &= rotation_clear_mask;
!   
!   /* Check for lack of optional rotation field. */
    if (skip_past_comma (&str) == FAIL)
      {
        end_of_line (str);
        return;
      }
!   
!   /* Move past 'ROR'. */
    skip_whitespace (str);
    if (strncasecmp (str, "ROR", 3) == 0)
!     str+=3;
    else
      {
        inst.error = _("missing rotation field after comma");
        return;
      }
!   
!   /* Get the immediate constant. */
    skip_whitespace (str);
    if (is_immediate_prefix (* str))
      str++;
--- 4103,4130 ----
        inst.error = BAD_PC;
        return;
      }
! 
!   /* Zero out the rotation field.  */
    inst.instruction &= rotation_clear_mask;
! 
!   /* Check for lack of optional rotation field.  */
    if (skip_past_comma (&str) == FAIL)
      {
        end_of_line (str);
        return;
      }
! 
!   /* Move past 'ROR'.  */
    skip_whitespace (str);
    if (strncasecmp (str, "ROR", 3) == 0)
!     str += 3;
    else
      {
        inst.error = _("missing rotation field after comma");
        return;
      }
! 
!   /* Get the immediate constant.  */
    skip_whitespace (str);
    if (is_immediate_prefix (* str))
      str++;
*************** do_sxtah (str)
*** 5391,5397 ****
        inst.error = _("immediate expression expected");
        return;
      }
!   
    if (my_get_expression (&expr, &str))
      {
        inst.error = _("bad expression");
--- 4133,4139 ----
        inst.error = _("immediate expression expected");
        return;
      }
! 
    if (my_get_expression (&expr, &str))
      {
        inst.error = _("bad expression");
*************** do_sxtah (str)
*** 5403,5413 ****
        inst.error = _("constant expression expected");
        return;
      }
!   
!   switch (expr.X_add_number) 
      {
      case 0:
!       /* Rotation field has already been zeroed. */
        break;
  
      case 8:
--- 4145,4155 ----
        inst.error = _("constant expression expected");
        return;
      }
! 
!   switch (expr.X_add_number)
      {
      case 0:
!       /* Rotation field has already been zeroed.  */
        break;
  
      case 8:
*************** do_sxtah (str)
*** 5417,5423 ****
      case 16:
        inst.instruction |= rotation_sixteen_mask;
        break;
!       
      case 24:
        inst.instruction |= rotation_twenty_four_mask;
        break;
--- 4159,4165 ----
      case 16:
        inst.instruction |= rotation_sixteen_mask;
        break;
! 
      case 24:
        inst.instruction |= rotation_twenty_four_mask;
        break;
*************** do_sxtah (str)
*** 5428,5452 ****
      }
  
    end_of_line (str);
-   
  }
!    
  
  /* ARM V6 RFE (Return from Exception) loads the PC and CPSR from the
     word at the specified address and the following word
!    respectively. 
     Unconditionally executed.
!    Error if Rn is R15.   
! */
  
  static void
! do_rfe (str)
!      char *str;
  {
    int rn;
  
    skip_whitespace (str);
!   
    if ((rn = reg_required_here (&str, 16)) == FAIL)
      return;
  
--- 4170,4191 ----
      }
  
    end_of_line (str);
  }
! 
  
  /* ARM V6 RFE (Return from Exception) loads the PC and CPSR from the
     word at the specified address and the following word
!    respectively.
     Unconditionally executed.
!    Error if Rn is R15.  */
  
  static void
! do_rfe (char * str)
  {
    int rn;
  
    skip_whitespace (str);
! 
    if ((rn = reg_required_here (&str, 16)) == FAIL)
      return;
  
*************** do_rfe (str)
*** 5457,5463 ****
      }
  
    skip_whitespace (str);
!   
    if (*str == '!')
      {
        inst.instruction |= WRITE_BACK;
--- 4196,4202 ----
      }
  
    skip_whitespace (str);
! 
    if (*str == '!')
      {
        inst.instruction |= WRITE_BACK;
*************** do_rfe (str)
*** 5470,5480 ****
     register (argument parse).
     REV{<cond>} Rd, Rm.
     Condition defaults to COND_ALWAYS.
!    Error if Rd or Rm are R15. */ 
  
  static void
! do_rev (str)
!      char* str;
  {
    int rd, rm;
  
--- 4209,4218 ----
     register (argument parse).
     REV{<cond>} Rd, Rm.
     Condition defaults to COND_ALWAYS.
!    Error if Rd or Rm are R15.  */
  
  static void
! do_rev (char * str)
  {
    int rd, rm;
  
*************** do_rev (str)
*** 5493,5505 ****
  }
  
  /* ARM V6 Perform Two Sixteen Bit Integer Additions. (argument parse).
!    QADD16{<cond>} <Rd>, <Rn>, <Rm>  
     Condition defaults to COND_ALWAYS.
     Error if Rd, Rn or Rm are R15.  */
  
  static void
! do_qadd16 (str) 
!      char* str;
  {
    int rd, rm, rn;
  
--- 4231,4242 ----
  }
  
  /* ARM V6 Perform Two Sixteen Bit Integer Additions. (argument parse).
!    QADD16{<cond>} <Rd>, <Rn>, <Rm>
     Condition defaults to COND_ALWAYS.
     Error if Rd, Rn or Rm are R15.  */
  
  static void
! do_qadd16 (char * str)
  {
    int rd, rm, rn;
  
*************** do_qadd16 (str) 
*** 5519,5549 ****
      end_of_line (str);
  }
  
- /* ARM V6 Pack Halfword Bottom Top instruction (argument parse).
-    PKHBT {<cond>} <Rd>, <Rn>, <Rm> {, LSL #<shift_imm>} 
-    Condition defaults to COND_ALWAYS.
-    Error if Rd, Rn or Rm are R15.  */
- 
- static void 
- do_pkhbt (str)
-      char* str;
- {
-   do_pkh_core (str, SHIFT_LSL_IMMEDIATE);
- }
- 
- /* ARM V6 PKHTB (Argument Parse). */
- 
- static void 
- do_pkhtb (str)
-      char* str;
- {
-   do_pkh_core (str, SHIFT_ASR_IMMEDIATE);
- }
- 
  static void
! do_pkh_core (str, shift)
!      char* str;
!      int shift;
  {
    int rd, rn, rm;
  
--- 4256,4263 ----
      end_of_line (str);
  }
  
  static void
! do_pkh_core (char * str, int shift)
  {
    int rd, rn, rm;
  
*************** do_pkh_core (str, shift)
*** 5564,5571 ****
        return;
      }
  
!   /* Check for optional shift immediate constant. */
!   if (skip_past_comma (&str) == FAIL) 
      {
        if (shift == SHIFT_ASR_IMMEDIATE)
  	{
--- 4278,4285 ----
        return;
      }
  
!   /* Check for optional shift immediate constant.  */
!   if (skip_past_comma (&str) == FAIL)
      {
        if (shift == SHIFT_ASR_IMMEDIATE)
  	{
*************** do_pkh_core (str, shift)
*** 5582,5603 ****
    decode_shift (&str, shift);
  }
  
  /* ARM V6 Load Register Exclusive instruction (argument parse).
     LDREX{<cond>} <Rd, [<Rn>]
     Condition defaults to COND_ALWAYS.
!    Error if Rd or Rn are R15. 
!    See ARMARMv6 A4.1.27: LDREX. */
! 
  
  static void
! do_ldrex (str)
!      char * str;
  {
    int rd, rn;
  
    skip_whitespace (str);
  
!   /* Parse Rd. */
    if (((rd = reg_required_here (&str, 12)) == FAIL)
        || (skip_past_comma (&str) == FAIL))
      {
--- 4296,4334 ----
    decode_shift (&str, shift);
  }
  
+ /* ARM V6 Pack Halfword Bottom Top instruction (argument parse).
+    PKHBT {<cond>} <Rd>, <Rn>, <Rm> {, LSL #<shift_imm>}
+    Condition defaults to COND_ALWAYS.
+    Error if Rd, Rn or Rm are R15.  */
+ 
+ static void
+ do_pkhbt (char * str)
+ {
+   do_pkh_core (str, SHIFT_LSL_IMMEDIATE);
+ }
+ 
+ /* ARM V6 PKHTB (Argument Parse).  */
+ 
+ static void
+ do_pkhtb (char * str)
+ {
+   do_pkh_core (str, SHIFT_ASR_IMMEDIATE);
+ }
+ 
  /* ARM V6 Load Register Exclusive instruction (argument parse).
     LDREX{<cond>} <Rd, [<Rn>]
     Condition defaults to COND_ALWAYS.
!    Error if Rd or Rn are R15.
!    See ARMARMv6 A4.1.27: LDREX.  */
  
  static void
! do_ldrex (char * str)
  {
    int rd, rn;
  
    skip_whitespace (str);
  
!   /* Parse Rd.  */
    if (((rd = reg_required_here (&str, 12)) == FAIL)
        || (skip_past_comma (&str) == FAIL))
      {
*************** do_ldrex (str)
*** 5609,5623 ****
        inst.error = BAD_PC;
        return;
      }
!   skip_whitespace (str);  
  
!   /* Skip past '['. */
!   if ((strlen (str) >= 1) 
        &&strncmp (str, "[", 1) == 0)
!     str+=1;
!   skip_whitespace (str);  
  
!   /* Parse Rn. */
    if ((rn = reg_required_here (&str, 16)) == FAIL)
      {
        inst.error = BAD_ARGS;
--- 4340,4354 ----
        inst.error = BAD_PC;
        return;
      }
!   skip_whitespace (str);
  
!   /* Skip past '['.  */
!   if ((strlen (str) >= 1)
        &&strncmp (str, "[", 1) == 0)
!     str += 1;
!   skip_whitespace (str);
  
!   /* Parse Rn.  */
    if ((rn = reg_required_here (&str, 16)) == FAIL)
      {
        inst.error = BAD_ARGS;
*************** do_ldrex (str)
*** 5628,5717 ****
        inst.error = BAD_PC;
        return;
      }
!   skip_whitespace (str);  
  
!   /* Skip past ']'. */
!   if ((strlen (str) >= 1) 
        && strncmp (str, "]", 1) == 0)
!     str+=1;
!   
    end_of_line (str);
  }
  
  /* ARM V6 change processor state instruction (argument parse)
!       CPS, CPSIE, CSPID . */
  
  static void
! do_cps (str)
!      char * str;
  {
    do_cps_mode (&str);
    end_of_line (str);
  }
  
  static void
! do_cpsi (str)
!      char * str;
! {
!   do_cps_flags (&str, /*thumb_p=*/0);
! 
!   if (skip_past_comma (&str) == SUCCESS)
!     {
!       skip_whitespace (str);
!       do_cps_mode (&str);
!     }
!   end_of_line (str);
! }
! 
! static void
! do_cps_mode (str)
!      char **str;
! {
!   expressionS expr;
! 
!   skip_whitespace (*str);
! 
!   if (! is_immediate_prefix (**str))
!     {
!       inst.error = _("immediate expression expected");
!       return;
!     }
! 
!   (*str)++; /* Strip off the immediate signifier. */
!   if (my_get_expression (&expr, str))
!     {
!       inst.error = _("bad expression");
!       return;
!     }
! 
!   if (expr.X_op != O_constant)
!     {
!       inst.error = _("constant expression expected");
!       return;
!     }
!   
!   /* The mode is a 5 bit field.  Valid values are 0-31. */
!   if (((unsigned) expr.X_add_number) > 31
!       || (inst.reloc.exp.X_add_number) < 0)
!     {
!       inst.error = _("invalid constant");
!       return;
!     }
!   
!   inst.instruction |= expr.X_add_number;
! }
! 
! static void
! do_cps_flags (str, thumb_p)
!      char **str;
!      int    thumb_p;
  {
!   struct cps_flag { 
      char character;
      unsigned long arm_value;
      unsigned long thumb_value;
    };
!   static struct cps_flag flag_table[] = {
      {'a', 0x100, 0x4 },
      {'i', 0x080, 0x2 },
      {'f', 0x040, 0x1 }
--- 4359,4395 ----
        inst.error = BAD_PC;
        return;
      }
!   skip_whitespace (str);
  
!   /* Skip past ']'.  */
!   if ((strlen (str) >= 1)
        && strncmp (str, "]", 1) == 0)
!     str += 1;
! 
    end_of_line (str);
  }
  
  /* ARM V6 change processor state instruction (argument parse)
!       CPS, CPSIE, CSPID .  */
  
  static void
! do_cps (char * str)
  {
    do_cps_mode (&str);
    end_of_line (str);
  }
  
  static void
! do_cps_flags (char ** str, int thumb_p)
  {
!   struct cps_flag
!   {
      char character;
      unsigned long arm_value;
      unsigned long thumb_value;
    };
!   static struct cps_flag flag_table[] =
!   {
      {'a', 0x100, 0x4 },
      {'i', 0x080, 0x2 },
      {'f', 0x040, 0x1 }
*************** do_cps_flags (str, thumb_p)
*** 5721,5731 ****
  
    skip_whitespace (*str);
  
!   /* Get the a, f and i flags. */
    while (**str && **str != ',')
      {
        struct cps_flag *p;
        struct cps_flag *q = flag_table + sizeof (flag_table)/sizeof (*p);
        for (p = flag_table; p < q; ++p)
  	if (strncasecmp (*str, &p->character, 1) == 0)
  	  {
--- 4399,4410 ----
  
    skip_whitespace (*str);
  
!   /* Get the a, f and i flags.  */
    while (**str && **str != ',')
      {
        struct cps_flag *p;
        struct cps_flag *q = flag_table + sizeof (flag_table)/sizeof (*p);
+ 
        for (p = flag_table; p < q; ++p)
  	if (strncasecmp (*str, &p->character, 1) == 0)
  	  {
*************** do_cps_flags (str, thumb_p)
*** 5740,5755 ****
  	}
        (*str)++;
      }
!   if (!saw_a_flag) 
!     inst.error = _("no 'a', 'i', or 'f' flags for 'cps'");
  }
  
  /* THUMB V5 breakpoint instruction (argument parse)
  	BKPT <immed_8>.  */
  
  static void
! do_t_bkpt (str)
!      char * str;
  {
    expressionS expr;
    unsigned long number;
--- 4419,4447 ----
  	}
        (*str)++;
      }
! 
!   if (!saw_a_flag)
!     inst.error = _("no 'a', 'i', or 'f' flags for 'cps'");
! }
! 
! static void
! do_cpsi (char * str)
! {
!   do_cps_flags (&str, /*thumb_p=*/0);
! 
!   if (skip_past_comma (&str) == SUCCESS)
!     {
!       skip_whitespace (str);
!       do_cps_mode (&str);
!     }
!   end_of_line (str);
  }
  
  /* THUMB V5 breakpoint instruction (argument parse)
  	BKPT <immed_8>.  */
  
  static void
! do_t_bkpt (char * str)
  {
    expressionS expr;
    unsigned long number;
*************** do_t_bkpt (str)
*** 5784,5797 ****
    end_of_line (str);
  }
  
  /* ARM V5 branch-link-exchange (argument parse) for BLX(1) only.
     Expects inst.instruction is set for BLX(1).
     Note: this is cloned from do_branch, and the reloc changed to be a
  	new one that can cope with setting one extra bit (the H bit).  */
  
  static void
! do_branch25 (str)
!      char *        str;
  {
    if (my_get_expression (& inst.reloc.exp, & str))
      return;
--- 4476,4529 ----
    end_of_line (str);
  }
  
+ static bfd_reloc_code_real_type
+ arm_parse_reloc (void)
+ {
+   char         id [16];
+   char *       ip;
+   unsigned int i;
+   static struct
+   {
+     char * str;
+     int    len;
+     bfd_reloc_code_real_type reloc;
+   }
+   reloc_map[] =
+   {
+ #define MAP(str,reloc) { str, sizeof (str) - 1, reloc }
+     MAP ("(got)",    BFD_RELOC_ARM_GOT32),
+     MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF),
+     /* ScottB: Jan 30, 1998 - Added support for parsing "var(PLT)"
+        branch instructions generated by GCC for PLT relocs.  */
+     MAP ("(plt)",    BFD_RELOC_ARM_PLT32),
+     MAP ("(target1)", BFD_RELOC_ARM_TARGET1),
+     MAP ("(sbrel)", BFD_RELOC_ARM_SBREL32),
+     MAP ("(target2)", BFD_RELOC_ARM_TARGET2),
+     { NULL, 0,         BFD_RELOC_UNUSED }
+ #undef MAP
+   };
+ 
+   for (i = 0, ip = input_line_pointer;
+        i < sizeof (id) && (ISALNUM (*ip) || ISPUNCT (*ip));
+        i++, ip++)
+     id[i] = TOLOWER (*ip);
+ 
+   for (i = 0; reloc_map[i].str; i++)
+     if (strncmp (id, reloc_map[i].str, reloc_map[i].len) == 0)
+       break;
+ 
+   input_line_pointer += reloc_map[i].len;
+ 
+   return reloc_map[i].reloc;
+ }
+ 
  /* ARM V5 branch-link-exchange (argument parse) for BLX(1) only.
     Expects inst.instruction is set for BLX(1).
     Note: this is cloned from do_branch, and the reloc changed to be a
  	new one that can cope with setting one extra bit (the H bit).  */
  
  static void
! do_branch25 (char * str)
  {
    if (my_get_expression (& inst.reloc.exp, & str))
      return;
*************** do_branch25 (str)
*** 5844,5851 ****
     Also, the <target_addr> can be 25 bits, hence has its own reloc.  */
  
  static void
! do_blx (str)
!      char *        str;
  {
    char * mystr = str;
    int rm;
--- 4576,4582 ----
     Also, the <target_addr> can be 25 bits, hence has its own reloc.  */
  
  static void
! do_blx (char * str)
  {
    char * mystr = str;
    int rm;
*************** do_blx (str)
*** 5889,5896 ****
  	into inst.instruction.	*/
  
  static void
! do_t_blx (str)
!      char * str;
  {
    char * mystr = str;
    int rm;
--- 4620,4626 ----
  	into inst.instruction.	*/
  
  static void
! do_t_blx (char * str)
  {
    char * mystr = str;
    int rm;
*************** do_t_blx (str)
*** 5932,5939 ****
  	and it is an error if the caller tried to override that.  */
  
  static void
! do_bkpt (str)
!      char *        str;
  {
    expressionS expr;
    unsigned long number;
--- 4662,4668 ----
  	and it is an error if the caller tried to override that.  */
  
  static void
! do_bkpt (char * str)
  {
    expressionS expr;
    unsigned long number;
*************** do_bkpt (str)
*** 5976,5993 ****
  /* THUMB CPS instruction (argument parse).  */
  
  static void
! do_t_cps (str)
!      char *str;
  {
    do_cps_flags (&str, /*thumb_p=*/1);
    end_of_line (str);
  }
  
  /* THUMB CPY instruction (argument parse).  */
  
  static void
! do_t_cpy (str)
!      char *str;
  {
    thumb_mov_compare (str, THUMB_CPY);
  }
--- 4705,4845 ----
  /* THUMB CPS instruction (argument parse).  */
  
  static void
! do_t_cps (char * str)
  {
    do_cps_flags (&str, /*thumb_p=*/1);
    end_of_line (str);
  }
  
+ /* Parse and validate that a register is of the right form, this saves
+    repeated checking of this information in many similar cases.
+    Unlike the 32-bit case we do not insert the register into the opcode
+    here, since the position is often unknown until the full instruction
+    has been parsed.  */
+ 
+ static int
+ thumb_reg (char ** strp, int hi_lo)
+ {
+   int reg;
+ 
+   if ((reg = reg_required_here (strp, -1)) == FAIL)
+     return FAIL;
+ 
+   switch (hi_lo)
+     {
+     case THUMB_REG_LO:
+       if (reg > 7)
+ 	{
+ 	  inst.error = _("lo register required");
+ 	  return FAIL;
+ 	}
+       break;
+ 
+     case THUMB_REG_HI:
+       if (reg < 8)
+ 	{
+ 	  inst.error = _("hi register required");
+ 	  return FAIL;
+ 	}
+       break;
+ 
+     default:
+       break;
+     }
+ 
+   return reg;
+ }
+ 
+ static void
+ thumb_mov_compare (char * str, int move)
+ {
+   int Rd, Rs = FAIL;
+ 
+   skip_whitespace (str);
+ 
+   if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
+       || skip_past_comma (&str) == FAIL)
+     {
+       if (! inst.error)
+ 	inst.error = BAD_ARGS;
+       return;
+     }
+ 
+   if (move != THUMB_CPY && is_immediate_prefix (*str))
+     {
+       str++;
+       if (my_get_expression (&inst.reloc.exp, &str))
+ 	return;
+     }
+   else if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
+     return;
+ 
+   if (Rs != FAIL)
+     {
+       if (move != THUMB_CPY && Rs < 8 && Rd < 8)
+ 	{
+ 	  if (move == THUMB_MOVE)
+ 	    /* A move of two lowregs is encoded as ADD Rd, Rs, #0
+ 	       since a MOV instruction produces unpredictable results.  */
+ 	    inst.instruction = T_OPCODE_ADD_I3;
+ 	  else
+ 	    inst.instruction = T_OPCODE_CMP_LR;
+ 	  inst.instruction |= Rd | (Rs << 3);
+ 	}
+       else
+ 	{
+ 	  if (move == THUMB_MOVE)
+ 	    inst.instruction = T_OPCODE_MOV_HR;
+ 	  else if (move != THUMB_CPY)
+ 	    inst.instruction = T_OPCODE_CMP_HR;
+ 
+ 	  if (Rd > 7)
+ 	    inst.instruction |= THUMB_H1;
+ 
+ 	  if (Rs > 7)
+ 	    inst.instruction |= THUMB_H2;
+ 
+ 	  inst.instruction |= (Rd & 7) | ((Rs & 7) << 3);
+ 	}
+     }
+   else
+     {
+       if (Rd > 7)
+ 	{
+ 	  inst.error = _("only lo regs allowed with immediate");
+ 	  return;
+ 	}
+ 
+       if (move == THUMB_MOVE)
+ 	inst.instruction = T_OPCODE_MOV_I8;
+       else
+ 	inst.instruction = T_OPCODE_CMP_I8;
+ 
+       inst.instruction |= Rd << 8;
+ 
+       if (inst.reloc.exp.X_op != O_constant)
+ 	inst.reloc.type = BFD_RELOC_ARM_THUMB_IMM;
+       else
+ 	{
+ 	  unsigned value = inst.reloc.exp.X_add_number;
+ 
+ 	  if (value > 255)
+ 	    {
+ 	      inst.error = _("invalid immediate");
+ 	      return;
+ 	    }
+ 
+ 	  inst.instruction |= value;
+ 	}
+     }
+ 
+   end_of_line (str);
+ }
+ 
  /* THUMB CPY instruction (argument parse).  */
  
  static void
! do_t_cpy (char * str)
  {
    thumb_mov_compare (str, THUMB_CPY);
  }
*************** do_t_cpy (str)
*** 5995,6016 ****
  /* THUMB SETEND instruction (argument parse).  */
  
  static void
! do_t_setend (str)
!      char *str;
  {
    if (do_endian_specifier (str))
      inst.instruction |= 0x8;
  }
  
- static unsigned long check_iwmmxt_insn PARAMS ((char *, enum iwmmxt_insn_type, int));
- 
  /* Parse INSN_TYPE insn STR having a possible IMMEDIATE_SIZE immediate.  */
  
  static unsigned long
! check_iwmmxt_insn (str, insn_type, immediate_size)
!      char * str;
!      enum iwmmxt_insn_type insn_type;
!      int immediate_size;
  {
    int reg = 0;
    const char *  inst_error;
--- 4847,4864 ----
  /* THUMB SETEND instruction (argument parse).  */
  
  static void
! do_t_setend (char * str)
  {
    if (do_endian_specifier (str))
      inst.instruction |= 0x8;
  }
  
  /* Parse INSN_TYPE insn STR having a possible IMMEDIATE_SIZE immediate.  */
  
  static unsigned long
! check_iwmmxt_insn (char * str,
! 		   enum iwmmxt_insn_type insn_type,
! 		   int immediate_size)
  {
    int reg = 0;
    const char *  inst_error;
*************** check_iwmmxt_insn (str, insn_type, immed
*** 6028,6046 ****
        if ((reg = reg_required_here (&str, 12)) == FAIL)
  	return FAIL;
        break;
!       
      case check_wr:
         if ((wreg_required_here (&str, 0, IWMMXT_REG_WR)) == FAIL)
  	 return FAIL;
         break;
!        
      case check_wrwr:
        if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
  	   || skip_past_comma (&str) == FAIL
  	   || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL))
  	return FAIL;
        break;
!       
      case check_wrwrwr:
        if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
  	   || skip_past_comma (&str) == FAIL
--- 4876,4894 ----
        if ((reg = reg_required_here (&str, 12)) == FAIL)
  	return FAIL;
        break;
! 
      case check_wr:
         if ((wreg_required_here (&str, 0, IWMMXT_REG_WR)) == FAIL)
  	 return FAIL;
         break;
! 
      case check_wrwr:
        if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
  	   || skip_past_comma (&str) == FAIL
  	   || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL))
  	return FAIL;
        break;
! 
      case check_wrwrwr:
        if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
  	   || skip_past_comma (&str) == FAIL
*************** check_iwmmxt_insn (str, insn_type, immed
*** 6049,6055 ****
  	   || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL))
  	return FAIL;
        break;
!       
      case check_wrwrwcg:
        if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
  	   || skip_past_comma (&str) == FAIL
--- 4897,4903 ----
  	   || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL))
  	return FAIL;
        break;
! 
      case check_wrwrwcg:
        if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
  	   || skip_past_comma (&str) == FAIL
*************** check_iwmmxt_insn (str, insn_type, immed
*** 6058,6078 ****
  	   || wreg_required_here (&str, 0, IWMMXT_REG_WCG) == FAIL))
  	return FAIL;
        break;
!       
      case check_tbcst:
        if ((wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
  	   || skip_past_comma (&str) == FAIL
  	   || reg_required_here (&str, 12) == FAIL))
  	return FAIL;
        break;
!       
      case check_tmovmsk:
        if ((reg_required_here (&str, 12) == FAIL
  	   || skip_past_comma (&str) == FAIL
  	   || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL))
  	return FAIL;
        break;
!       
      case check_tmia:
        if ((wreg_required_here (&str, 5, IWMMXT_REG_WR) == FAIL
  	   || skip_past_comma (&str) == FAIL
--- 4906,4926 ----
  	   || wreg_required_here (&str, 0, IWMMXT_REG_WCG) == FAIL))
  	return FAIL;
        break;
! 
      case check_tbcst:
        if ((wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
  	   || skip_past_comma (&str) == FAIL
  	   || reg_required_here (&str, 12) == FAIL))
  	return FAIL;
        break;
! 
      case check_tmovmsk:
        if ((reg_required_here (&str, 12) == FAIL
  	   || skip_past_comma (&str) == FAIL
  	   || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL))
  	return FAIL;
        break;
! 
      case check_tmia:
        if ((wreg_required_here (&str, 5, IWMMXT_REG_WR) == FAIL
  	   || skip_past_comma (&str) == FAIL
*************** check_iwmmxt_insn (str, insn_type, immed
*** 6081,6087 ****
  	   || reg_required_here (&str, 12) == FAIL))
  	return FAIL;
        break;
!       
      case check_tmcrr:
        if ((wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL
  	   || skip_past_comma (&str) == FAIL
--- 4929,4935 ----
  	   || reg_required_here (&str, 12) == FAIL))
  	return FAIL;
        break;
! 
      case check_tmcrr:
        if ((wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL
  	   || skip_past_comma (&str) == FAIL
*************** check_iwmmxt_insn (str, insn_type, immed
*** 6090,6096 ****
  	   || reg_required_here (&str, 16) == FAIL))
  	return FAIL;
        break;
!       
      case check_tmrrc:
        if ((reg_required_here (&str, 12) == FAIL
  	   || skip_past_comma (&str) == FAIL
--- 4938,4944 ----
  	   || reg_required_here (&str, 16) == FAIL))
  	return FAIL;
        break;
! 
      case check_tmrrc:
        if ((reg_required_here (&str, 12) == FAIL
  	   || skip_past_comma (&str) == FAIL
*************** check_iwmmxt_insn (str, insn_type, immed
*** 6099,6119 ****
  	   || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL))
  	return FAIL;
        break;
!       
      case check_tmcr:
        if ((wreg_required_here (&str, 16, IWMMXT_REG_WC) == FAIL
  	   || skip_past_comma (&str) == FAIL
  	   || reg_required_here (&str, 12) == FAIL))
  	return FAIL;
        break;
!       
      case check_tmrc:
        if ((reg_required_here (&str, 12) == FAIL
  	   || skip_past_comma (&str) == FAIL
  	   || wreg_required_here (&str, 16, IWMMXT_REG_WC) == FAIL))
  	return FAIL;
        break;
!       
      case check_tinsr:
        if ((wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
  	   || skip_past_comma (&str) == FAIL
--- 4947,4967 ----
  	   || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL))
  	return FAIL;
        break;
! 
      case check_tmcr:
        if ((wreg_required_here (&str, 16, IWMMXT_REG_WC) == FAIL
  	   || skip_past_comma (&str) == FAIL
  	   || reg_required_here (&str, 12) == FAIL))
  	return FAIL;
        break;
! 
      case check_tmrc:
        if ((reg_required_here (&str, 12) == FAIL
  	   || skip_past_comma (&str) == FAIL
  	   || wreg_required_here (&str, 16, IWMMXT_REG_WC) == FAIL))
  	return FAIL;
        break;
! 
      case check_tinsr:
        if ((wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
  	   || skip_past_comma (&str) == FAIL
*************** check_iwmmxt_insn (str, insn_type, immed
*** 6121,6133 ****
  	   || skip_past_comma (&str) == FAIL))
  	return FAIL;
        break;
!       
      case check_textrc:
        if ((reg_required_here (&str, 12) == FAIL
  	   || skip_past_comma (&str) == FAIL))
  	return FAIL;
        break;
!       
      case check_waligni:
        if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
  	   || skip_past_comma (&str) == FAIL
--- 4969,4981 ----
  	   || skip_past_comma (&str) == FAIL))
  	return FAIL;
        break;
! 
      case check_textrc:
        if ((reg_required_here (&str, 12) == FAIL
  	   || skip_past_comma (&str) == FAIL))
  	return FAIL;
        break;
! 
      case check_waligni:
        if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
  	   || skip_past_comma (&str) == FAIL
*************** check_iwmmxt_insn (str, insn_type, immed
*** 6137,6143 ****
  	   || skip_past_comma (&str) == FAIL))
  	return FAIL;
        break;
!       
      case check_textrm:
        if ((reg_required_here (&str, 12) == FAIL
  	   || skip_past_comma (&str) == FAIL
--- 4985,4991 ----
  	   || skip_past_comma (&str) == FAIL))
  	return FAIL;
        break;
! 
      case check_textrm:
        if ((reg_required_here (&str, 12) == FAIL
  	   || skip_past_comma (&str) == FAIL
*************** check_iwmmxt_insn (str, insn_type, immed
*** 6145,6151 ****
  	   || skip_past_comma (&str) == FAIL))
  	return FAIL;
        break;
!       
      case check_wshufh:
        if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
  	   || skip_past_comma (&str) == FAIL
--- 4993,4999 ----
  	   || skip_past_comma (&str) == FAIL))
  	return FAIL;
        break;
! 
      case check_wshufh:
        if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
  	   || skip_past_comma (&str) == FAIL
*************** check_iwmmxt_insn (str, insn_type, immed
*** 6154,6160 ****
  	return FAIL;
        break;
      }
!   
    if (immediate_size == 0)
      {
        end_of_line (str);
--- 5002,5008 ----
  	return FAIL;
        break;
      }
! 
    if (immediate_size == 0)
      {
        end_of_line (str);
*************** check_iwmmxt_insn (str, insn_type, immed
*** 6163,6184 ****
      }
    else
      {
!       skip_whitespace (str);      
!   
!       /* Allow optional leading '#'. */
        if (is_immediate_prefix (* str))
          str++;
  
        memset (& expr, '\0', sizeof (expr));
!   
        if (my_get_expression (& expr, & str) || (expr.X_op != O_constant))
          {
            inst.error = _("bad or missing expression");
            return FAIL;
          }
!   
        number = expr.X_add_number;
!   
        if (number != (number & immediate_size))
          {
            inst.error = _("immediate value out of range");
--- 5011,5032 ----
      }
    else
      {
!       skip_whitespace (str);
! 
!       /* Allow optional leading '#'.  */
        if (is_immediate_prefix (* str))
          str++;
  
        memset (& expr, '\0', sizeof (expr));
! 
        if (my_get_expression (& expr, & str) || (expr.X_op != O_constant))
          {
            inst.error = _("bad or missing expression");
            return FAIL;
          }
! 
        number = expr.X_add_number;
! 
        if (number != (number & immediate_size))
          {
            inst.error = _("immediate value out of range");
*************** check_iwmmxt_insn (str, insn_type, immed
*** 6191,6204 ****
  }
  
  static void
! do_iwmmxt_byte_addr (str)
!      char * str;
  {
    int op = (inst.instruction & 0x300) >> 8;
    int reg;
  
    inst.instruction &= ~0x300;
!   inst.instruction |= (op & 1) << 22 | (op & 2) << 7;  
  
    skip_whitespace (str);
  
--- 5039,5051 ----
  }
  
  static void
! do_iwmmxt_byte_addr (char * str)
  {
    int op = (inst.instruction & 0x300) >> 8;
    int reg;
  
    inst.instruction &= ~0x300;
!   inst.instruction |= (op & 1) << 22 | (op & 2) << 7;
  
    skip_whitespace (str);
  
*************** do_iwmmxt_byte_addr (str)
*** 6221,6228 ****
  }
  
  static void
! do_iwmmxt_tandc (str)
!      char * str;
  {
    int reg;
  
--- 5068,5074 ----
  }
  
  static void
! do_iwmmxt_tandc (char * str)
  {
    int reg;
  
*************** do_iwmmxt_tandc (str)
*** 6233,6247 ****
  }
  
  static void
! do_iwmmxt_tbcst (str)
!      char * str;
  {
    check_iwmmxt_insn (str, check_tbcst, 0);
  }
  
  static void
! do_iwmmxt_textrc (str)
!      char * str;
  {
    unsigned long number;
  
--- 5079,5091 ----
  }
  
  static void
! do_iwmmxt_tbcst (char * str)
  {
    check_iwmmxt_insn (str, check_tbcst, 0);
  }
  
  static void
! do_iwmmxt_textrc (char * str)
  {
    unsigned long number;
  
*************** do_iwmmxt_textrc (str)
*** 6252,6259 ****
  }
  
  static void
! do_iwmmxt_textrm (str)
!      char * str;
  {
    unsigned long number;
  
--- 5096,5102 ----
  }
  
  static void
! do_iwmmxt_textrm (char * str)
  {
    unsigned long number;
  
*************** do_iwmmxt_textrm (str)
*** 6264,6271 ****
  }
  
  static void
! do_iwmmxt_tinsr (str)
!      char * str;
  {
    unsigned long number;
  
--- 5107,5113 ----
  }
  
  static void
! do_iwmmxt_tinsr (char * str)
  {
    unsigned long number;
  
*************** do_iwmmxt_tinsr (str)
*** 6276,6332 ****
  }
  
  static void
! do_iwmmxt_tmcr (str)
!      char * str;
  {
    check_iwmmxt_insn (str, check_tmcr, 0);
  }
  
  static void
! do_iwmmxt_tmcrr (str)
!      char * str;
  {
    check_iwmmxt_insn (str, check_tmcrr, 0);
  }
  
  static void
! do_iwmmxt_tmia (str)
!      char * str;
  {
    check_iwmmxt_insn (str, check_tmia, 0);
  }
  
  static void
! do_iwmmxt_tmovmsk (str)
!      char * str;
  {
    check_iwmmxt_insn (str, check_tmovmsk, 0);
  }
  
  static void
! do_iwmmxt_tmrc (str)
!      char * str;
  {
    check_iwmmxt_insn (str, check_tmrc, 0);
  }
  
  static void
! do_iwmmxt_tmrrc (str)
!      char * str;
  {
    check_iwmmxt_insn (str, check_tmrrc, 0);
  }
  
  static void
! do_iwmmxt_torc (str)
!      char * str;
  {
    check_iwmmxt_insn (str, check_rd, 0);
  }
  
  static void
! do_iwmmxt_waligni (str)
!      char * str;
  {
    unsigned long number;
  
--- 5118,5166 ----
  }
  
  static void
! do_iwmmxt_tmcr (char * str)
  {
    check_iwmmxt_insn (str, check_tmcr, 0);
  }
  
  static void
! do_iwmmxt_tmcrr (char * str)
  {
    check_iwmmxt_insn (str, check_tmcrr, 0);
  }
  
  static void
! do_iwmmxt_tmia (char * str)
  {
    check_iwmmxt_insn (str, check_tmia, 0);
  }
  
  static void
! do_iwmmxt_tmovmsk (char * str)
  {
    check_iwmmxt_insn (str, check_tmovmsk, 0);
  }
  
  static void
! do_iwmmxt_tmrc (char * str)
  {
    check_iwmmxt_insn (str, check_tmrc, 0);
  }
  
  static void
! do_iwmmxt_tmrrc (char * str)
  {
    check_iwmmxt_insn (str, check_tmrrc, 0);
  }
  
  static void
! do_iwmmxt_torc (char * str)
  {
    check_iwmmxt_insn (str, check_rd, 0);
  }
  
  static void
! do_iwmmxt_waligni (char * str)
  {
    unsigned long number;
  
*************** do_iwmmxt_waligni (str)
*** 6337,6360 ****
  }
  
  static void
! do_iwmmxt_wmov (str)
!      char * str;
  {
    if (check_iwmmxt_insn (str, check_wrwr, 0) == (unsigned long) FAIL)
      return;
!   
    inst.instruction |= ((inst.instruction >> 16) & 0xf);
  }
  
  static void
! do_iwmmxt_word_addr (str)
!      char * str;
  {
    int op = (inst.instruction & 0x300) >> 8;
    int reg;
  
    inst.instruction &= ~0x300;
!   inst.instruction |= (op & 1) << 22 | (op & 2) << 7;  
  
    skip_whitespace (str);
  
--- 5171,5192 ----
  }
  
  static void
! do_iwmmxt_wmov (char * str)
  {
    if (check_iwmmxt_insn (str, check_wrwr, 0) == (unsigned long) FAIL)
      return;
! 
    inst.instruction |= ((inst.instruction >> 16) & 0xf);
  }
  
  static void
! do_iwmmxt_word_addr (char * str)
  {
    int op = (inst.instruction & 0x300) >> 8;
    int reg;
  
    inst.instruction &= ~0x300;
!   inst.instruction |= (op & 1) << 22 | (op & 2) << 7;
  
    skip_whitespace (str);
  
*************** do_iwmmxt_word_addr (str)
*** 6380,6408 ****
  }
  
  static void
! do_iwmmxt_wrwr (str)
!      char * str;
  {
    check_iwmmxt_insn (str, check_wrwr, 0);
  }
  
  static void
! do_iwmmxt_wrwrwcg (str)
!      char * str;
  {
    check_iwmmxt_insn (str, check_wrwrwcg, 0);
  }
  
  static void
! do_iwmmxt_wrwrwr (str)
!      char * str;
  {
    check_iwmmxt_insn (str, check_wrwrwr, 0);
  }
  
  static void
! do_iwmmxt_wshufh (str)
!      char * str;
  {
    unsigned long number;
  
--- 5212,5236 ----
  }
  
  static void
! do_iwmmxt_wrwr (char * str)
  {
    check_iwmmxt_insn (str, check_wrwr, 0);
  }
  
  static void
! do_iwmmxt_wrwrwcg (char * str)
  {
    check_iwmmxt_insn (str, check_wrwrwcg, 0);
  }
  
  static void
! do_iwmmxt_wrwrwr (char * str)
  {
    check_iwmmxt_insn (str, check_wrwrwr, 0);
  }
  
  static void
! do_iwmmxt_wshufh (char * str)
  {
    unsigned long number;
  
*************** do_iwmmxt_wshufh (str)
*** 6413,6420 ****
  }
  
  static void
! do_iwmmxt_wzero (str)
!      char * str;
  {
    if (check_iwmmxt_insn (str, check_wr, 0) == (unsigned long) FAIL)
      return;
--- 5241,5247 ----
  }
  
  static void
! do_iwmmxt_wzero (char * str)
  {
    if (check_iwmmxt_insn (str, check_wr, 0) == (unsigned long) FAIL)
      return;
*************** do_iwmmxt_wzero (str)
*** 6428,6435 ****
       MIAxycc acc0,Rm,Rs.  */
  
  static void
! do_xsc_mia (str)
!      char * str;
  {
    int rs;
    int rm;
--- 5255,5261 ----
       MIAxycc acc0,Rm,Rs.  */
  
  static void
! do_xsc_mia (char * str)
  {
    int rs;
    int rm;
*************** do_xsc_mia (str)
*** 6458,6465 ****
       MARcc   acc0,RdLo,RdHi.  */
  
  static void
! do_xsc_mar (str)
!      char * str;
  {
    int rdlo, rdhi;
  
--- 5284,5290 ----
       MARcc   acc0,RdLo,RdHi.  */
  
  static void
! do_xsc_mar (char * str)
  {
    int rdlo, rdhi;
  
*************** do_xsc_mar (str)
*** 6487,6494 ****
       MRAcc   RdLo,RdHi,acc0.  */
  
  static void
! do_xsc_mra (str)
!      char * str;
  {
    int rdlo;
    int rdhi;
--- 5312,5318 ----
       MRAcc   RdLo,RdHi,acc0.  */
  
  static void
! do_xsc_mra (char * str)
  {
    int rdlo;
    int rdhi;
*************** do_xsc_mra (str)
*** 6506,6519 ****
  	    || accum0_required_here (& str) == FAIL)
      inst.error = ERR_NO_ACCUM;
  
!   /* inst.instruction has now been zapped with both rdlo and rdhi.  */
!   else if (rdlo == rdhi)
!     inst.error = BAD_ARGS;	/* Undefined result if 2 writes to same reg.  */
  
!   else if (rdlo == REG_PC || rdhi == REG_PC)
!     inst.error = BAD_PC;	/* Undefined result if rdlo or rdhi is R15.  */
!   else
!     end_of_line (str);
  }
  
  /* ARMv5TE: Preload-Cache
--- 5330,5401 ----
  	    || accum0_required_here (& str) == FAIL)
      inst.error = ERR_NO_ACCUM;
  
!   /* inst.instruction has now been zapped with both rdlo and rdhi.  */
!   else if (rdlo == rdhi)
!     inst.error = BAD_ARGS;	/* Undefined result if 2 writes to same reg.  */
! 
!   else if (rdlo == REG_PC || rdhi == REG_PC)
!     inst.error = BAD_PC;	/* Undefined result if rdlo or rdhi is R15.  */
!   else
!     end_of_line (str);
! }
! 
! static int
! ldst_extend (char ** str)
! {
!   int add = INDEX_UP;
! 
!   switch (**str)
!     {
!     case '#':
!     case '$':
!       (*str)++;
!       if (my_get_expression (& inst.reloc.exp, str))
! 	return FAIL;
! 
!       if (inst.reloc.exp.X_op == O_constant)
! 	{
! 	  int value = inst.reloc.exp.X_add_number;
! 
! 	  if (value < -4095 || value > 4095)
! 	    {
! 	      inst.error = _("address offset too large");
! 	      return FAIL;
! 	    }
! 
! 	  if (value < 0)
! 	    {
! 	      value = -value;
! 	      add = 0;
! 	    }
! 
! 	  inst.instruction |= add | value;
! 	}
!       else
! 	{
! 	  inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
! 	  inst.reloc.pc_rel = 0;
! 	}
!       return SUCCESS;
! 
!     case '-':
!       add = 0;
!       /* Fall through.  */
! 
!     case '+':
!       (*str)++;
!       /* Fall through.  */
! 
!     default:
!       if (reg_required_here (str, 0) == FAIL)
! 	return FAIL;
! 
!       inst.instruction |= add | OFFSET_REG;
!       if (skip_past_comma (str) == SUCCESS)
! 	return decode_shift (str, SHIFT_IMMEDIATE);
  
!       return SUCCESS;
!     }
  }
  
  /* ARMv5TE: Preload-Cache
*************** do_xsc_mra (str)
*** 6523,6530 ****
    Syntactically, like LDR with B=1, W=0, L=1.  */
  
  static void
! do_pld (str)
!      char * str;
  {
    int rd;
  
--- 5405,5411 ----
    Syntactically, like LDR with B=1, W=0, L=1.  */
  
  static void
! do_pld (char * str)
  {
    int rd;
  
*************** do_pld (str)
*** 6606,6613 ****
       STRccD R, mode.  */
  
  static void
! do_ldrd (str)
!      char * str;
  {
    int rd;
    int rn;
--- 5487,5493 ----
       STRccD R, mode.  */
  
  static void
! do_ldrd (char * str)
  {
    int rd;
    int rn;
*************** do_ldrd (str)
*** 6625,6957 ****
      {
        if (!inst.error)
  	inst.error = BAD_ARGS;
!       return;
!     }
! 
!   /* inst.instruction has now been zapped with Rd and the addressing mode.  */
!   if (rd & 1)		/* Unpredictable result if Rd is odd.  */
!     {
!       inst.error = _("destination register must be even");
!       return;
!     }
! 
!   if (rd == REG_LR)
!     {
!       inst.error = _("r14 not allowed here");
!       return;
!     }
! 
!   if (((rd == rn) || (rd + 1 == rn))
!       && ((inst.instruction & WRITE_BACK)
! 	  || (!(inst.instruction & PRE_INDEX))))
!     as_warn (_("pre/post-indexing used when modified address register is destination"));
! 
!   /* For an index-register load, the index register must not overlap the
!      destination (even if not write-back).  */
!   if ((inst.instruction & V4_STR_BIT) == 0
!       && (inst.instruction & HWOFFSET_IMM) == 0)
!     {
!       int rm = inst.instruction & 0x0000000f;
! 
!       if (rm == rd || (rm == rd + 1))
! 	as_warn (_("ldrd destination registers must not overlap index register"));
!     }
! 
!   end_of_line (str);
! }
! 
! /* Returns the index into fp_values of a floating point number,
!    or -1 if not in the table.  */
! 
! static int
! my_get_float_expression (str)
!      char ** str;
! {
!   LITTLENUM_TYPE words[MAX_LITTLENUMS];
!   char *         save_in;
!   expressionS    exp;
!   int            i;
!   int            j;
! 
!   memset (words, 0, MAX_LITTLENUMS * sizeof (LITTLENUM_TYPE));
! 
!   /* Look for a raw floating point number.  */
!   if ((save_in = atof_ieee (*str, 'x', words)) != NULL
!       && is_end_of_line[(unsigned char) *save_in])
!     {
!       for (i = 0; i < NUM_FLOAT_VALS; i++)
! 	{
! 	  for (j = 0; j < MAX_LITTLENUMS; j++)
! 	    {
! 	      if (words[j] != fp_values[i][j])
! 		break;
! 	    }
! 
! 	  if (j == MAX_LITTLENUMS)
! 	    {
! 	      *str = save_in;
! 	      return i;
! 	    }
! 	}
!     }
! 
!   /* Try and parse a more complex expression, this will probably fail
!      unless the code uses a floating point prefix (eg "0f").  */
!   save_in = input_line_pointer;
!   input_line_pointer = *str;
!   if (expression (&exp) == absolute_section
!       && exp.X_op == O_big
!       && exp.X_add_number < 0)
!     {
!       /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
! 	 Ditto for 15.  */
!       if (gen_to_words (words, 5, (long) 15) == 0)
! 	{
! 	  for (i = 0; i < NUM_FLOAT_VALS; i++)
! 	    {
! 	      for (j = 0; j < MAX_LITTLENUMS; j++)
! 		{
! 		  if (words[j] != fp_values[i][j])
! 		    break;
! 		}
! 
! 	      if (j == MAX_LITTLENUMS)
! 		{
! 		  *str = input_line_pointer;
! 		  input_line_pointer = save_in;
! 		  return i;
! 		}
! 	    }
! 	}
!     }
! 
!   *str = input_line_pointer;
!   input_line_pointer = save_in;
!   return -1;
! }
! 
! /* Return TRUE if anything in the expression is a bignum.  */
! 
! static int
! walk_no_bignums (sp)
!      symbolS * sp;
! {
!   if (symbol_get_value_expression (sp)->X_op == O_big)
!     return 1;
! 
!   if (symbol_get_value_expression (sp)->X_add_symbol)
!     {
!       return (walk_no_bignums (symbol_get_value_expression (sp)->X_add_symbol)
! 	      || (symbol_get_value_expression (sp)->X_op_symbol
! 		  && walk_no_bignums (symbol_get_value_expression (sp)->X_op_symbol)));
!     }
! 
!   return 0;
! }
! 
! static int in_my_get_expression = 0;
! 
! static int
! my_get_expression (ep, str)
!      expressionS * ep;
!      char ** str;
! {
!   char * save_in;
!   segT   seg;
! 
!   save_in = input_line_pointer;
!   input_line_pointer = *str;
!   in_my_get_expression = 1;
!   seg = expression (ep);
!   in_my_get_expression = 0;
! 
!   if (ep->X_op == O_illegal)
!     {
!       /* We found a bad expression in md_operand().  */
!       *str = input_line_pointer;
!       input_line_pointer = save_in;
!       return 1;
!     }
! 
! #ifdef OBJ_AOUT
!   if (seg != absolute_section
!       && seg != text_section
!       && seg != data_section
!       && seg != bss_section
!       && seg != undefined_section)
!     {
!       inst.error = _("bad_segment");
!       *str = input_line_pointer;
!       input_line_pointer = save_in;
!       return 1;
!     }
! #endif
! 
!   /* Get rid of any bignums now, so that we don't generate an error for which
!      we can't establish a line number later on.  Big numbers are never valid
!      in instructions, which is where this routine is always called.  */
!   if (ep->X_op == O_big
!       || (ep->X_add_symbol
! 	  && (walk_no_bignums (ep->X_add_symbol)
! 	      || (ep->X_op_symbol
! 		  && walk_no_bignums (ep->X_op_symbol)))))
!     {
!       inst.error = _("invalid constant");
!       *str = input_line_pointer;
!       input_line_pointer = save_in;
!       return 1;
!     }
! 
!   *str = input_line_pointer;
!   input_line_pointer = save_in;
!   return 0;
! }
! 
! /* We handle all bad expressions here, so that we can report the faulty
!    instruction in the error message.  */
! void
! md_operand (expr)
!      expressionS *expr;
! {
!   if (in_my_get_expression)
!     {
!       expr->X_op = O_illegal;
!       if (inst.error == NULL)
! 	inst.error = _("bad expression");
!     }
! }
! 
! /* KIND indicates what kind of shifts are accepted.  */
! 
! static int
! decode_shift (str, kind)
!      char ** str;
!      int     kind;
! {
!   const struct asm_shift_name * shift;
!   char * p;
!   char   c;
! 
!   skip_whitespace (* str);
! 
!   for (p = * str; ISALPHA (* p); p ++)
!     ;
! 
!   if (p == * str)
!     {
!       inst.error = _("shift expression expected");
!       return FAIL;
!     }
! 
!   c = * p;
!   * p = '\0';
!   shift = (const struct asm_shift_name *) hash_find (arm_shift_hsh, * str);
!   * p = c;
! 
!   if (shift == NULL)
!     {
!       inst.error = _("shift expression expected");
!       return FAIL;
!     }
! 
!   assert (shift->properties->index == shift_properties[shift->properties->index].index);
! 
!   if (kind == SHIFT_LSL_OR_ASR_IMMEDIATE
!       && shift->properties->index != SHIFT_LSL
!       && shift->properties->index != SHIFT_ASR)
!     {
!       inst.error = _("'LSL' or 'ASR' required");
!       return FAIL;
!     }
!   else if (kind == SHIFT_LSL_IMMEDIATE
! 	   && shift->properties->index != SHIFT_LSL)
!     {
!       inst.error = _("'LSL' required");
!       return FAIL;
!     }
!   else if (kind == SHIFT_ASR_IMMEDIATE
! 	   && shift->properties->index != SHIFT_ASR)
!     {
!       inst.error = _("'ASR' required");
!       return FAIL;
!     }
!     
!   if (shift->properties->index == SHIFT_RRX)
!     {
!       * str = p;
!       inst.instruction |= shift->properties->bit_field;
!       return SUCCESS;
      }
  
!   skip_whitespace (p);
  
!   if (kind == NO_SHIFT_RESTRICT && reg_required_here (& p, 8) != FAIL)
      {
!       inst.instruction |= shift->properties->bit_field | SHIFT_BY_REG;
!       * str = p;
!       return SUCCESS;
      }
!   else if (! is_immediate_prefix (* p))
      {
!       inst.error = (NO_SHIFT_RESTRICT
! 		    ? _("shift requires register or #expression")
! 		    : _("shift requires #expression"));
!       * str = p;
!       return FAIL;
      }
  
!   inst.error = NULL;
!   p ++;
  
!   if (my_get_expression (& inst.reloc.exp, & p))
!     return FAIL;
  
!   /* Validate some simple #expressions.  */
!   if (inst.reloc.exp.X_op == O_constant)
!     {
!       unsigned num = inst.reloc.exp.X_add_number;
  
!       /* Reject operations greater than 32.  */
!       if (num > 32
! 	  /* Reject a shift of 0 unless the mode allows it.  */
! 	  || (num == 0 && shift->properties->allows_0 == 0)
! 	  /* Reject a shift of 32 unless the mode allows it.  */
! 	  || (num == 32 && shift->properties->allows_32 == 0)
! 	  )
  	{
! 	  /* As a special case we allow a shift of zero for
! 	     modes that do not support it to be recoded as an
! 	     logical shift left of zero (ie nothing).  We warn
! 	     about this though.  */
! 	  if (num == 0)
  	    {
! 	      as_warn (_("shift of 0 ignored."));
! 	      shift = & shift_names[0];
! 	      assert (shift->properties->index == SHIFT_LSL);
  	    }
! 	  else
  	    {
! 	      inst.error = _("invalid immediate shift");
! 	      return FAIL;
  	    }
  	}
  
!       /* Shifts of 32 are encoded as 0, for those shifts that
! 	 support it.  */
!       if (num == 32)
! 	num = 0;
  
!       inst.instruction |= (num << 7) | shift->properties->bit_field;
      }
!   else
      {
!       inst.reloc.type   = BFD_RELOC_ARM_SHIFT_IMM;
!       inst.reloc.pc_rel = 0;
!       inst.instruction |= shift->properties->bit_field;
      }
- 
-   * str = p;
-   return SUCCESS;
  }
  
  /* Do those data_ops which can take a negative immediate constant
--- 5505,5625 ----
      {
        if (!inst.error)
  	inst.error = BAD_ARGS;
!       return;
      }
  
!   /* inst.instruction has now been zapped with Rd and the addressing mode.  */
!   if (rd & 1)		/* Unpredictable result if Rd is odd.  */
!     {
!       inst.error = _("destination register must be even");
!       return;
!     }
  
!   if (rd == REG_LR)
      {
!       inst.error = _("r14 not allowed here");
!       return;
      }
! 
!   if (((rd == rn) || (rd + 1 == rn))
!       && ((inst.instruction & WRITE_BACK)
! 	  || (!(inst.instruction & PRE_INDEX))))
!     as_warn (_("pre/post-indexing used when modified address register is destination"));
! 
!   /* For an index-register load, the index register must not overlap the
!      destination (even if not write-back).  */
!   if ((inst.instruction & V4_STR_BIT) == 0
!       && (inst.instruction & HWOFFSET_IMM) == 0)
      {
!       int rm = inst.instruction & 0x0000000f;
! 
!       if (rm == rd || (rm == rd + 1))
! 	as_warn (_("ldrd destination registers must not overlap index register"));
      }
  
!   end_of_line (str);
! }
  
! /* Returns the index into fp_values of a floating point number,
!    or -1 if not in the table.  */
  
! static int
! my_get_float_expression (char ** str)
! {
!   LITTLENUM_TYPE words[MAX_LITTLENUMS];
!   char *         save_in;
!   expressionS    exp;
!   int            i;
!   int            j;
  
!   memset (words, 0, MAX_LITTLENUMS * sizeof (LITTLENUM_TYPE));
! 
!   /* Look for a raw floating point number.  */
!   if ((save_in = atof_ieee (*str, 'x', words)) != NULL
!       && is_end_of_line[(unsigned char) *save_in])
!     {
!       for (i = 0; i < NUM_FLOAT_VALS; i++)
  	{
! 	  for (j = 0; j < MAX_LITTLENUMS; j++)
  	    {
! 	      if (words[j] != fp_values[i][j])
! 		break;
  	    }
! 
! 	  if (j == MAX_LITTLENUMS)
  	    {
! 	      *str = save_in;
! 	      return i;
  	    }
  	}
+     }
  
!   /* Try and parse a more complex expression, this will probably fail
!      unless the code uses a floating point prefix (eg "0f").  */
!   save_in = input_line_pointer;
!   input_line_pointer = *str;
!   if (expression (&exp) == absolute_section
!       && exp.X_op == O_big
!       && exp.X_add_number < 0)
!     {
!       /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
! 	 Ditto for 15.  */
!       if (gen_to_words (words, 5, (long) 15) == 0)
! 	{
! 	  for (i = 0; i < NUM_FLOAT_VALS; i++)
! 	    {
! 	      for (j = 0; j < MAX_LITTLENUMS; j++)
! 		{
! 		  if (words[j] != fp_values[i][j])
! 		    break;
! 		}
  
! 	      if (j == MAX_LITTLENUMS)
! 		{
! 		  *str = input_line_pointer;
! 		  input_line_pointer = save_in;
! 		  return i;
! 		}
! 	    }
! 	}
      }
! 
!   *str = input_line_pointer;
!   input_line_pointer = save_in;
!   return -1;
! }
! 
! /* We handle all bad expressions here, so that we can report the faulty
!    instruction in the error message.  */
! void
! md_operand (expressionS * expr)
! {
!   if (in_my_get_expression)
      {
!       expr->X_op = O_illegal;
!       if (inst.error == NULL)
! 	inst.error = _("bad expression");
      }
  }
  
  /* Do those data_ops which can take a negative immediate constant
*************** decode_shift (str, kind)
*** 6965,6973 ****
          by negating the second operand.  */
  
  static int
! negate_data_op (instruction, value)
!      unsigned long * instruction;
!      unsigned long   value;
  {
    int op, new_inst;
    unsigned long negated, inverted;
--- 5633,5640 ----
          by negating the second operand.  */
  
  static int
! negate_data_op (unsigned long * instruction,
! 		unsigned long   value)
  {
    int op, new_inst;
    unsigned long negated, inverted;
*************** negate_data_op (instruction, value)
*** 7044,7051 ****
  }
  
  static int
! data_op2 (str)
!      char ** str;
  {
    int value;
    expressionS expr;
--- 5711,5717 ----
  }
  
  static int
! data_op2 (char ** str)
  {
    int value;
    expressionS expr;
*************** data_op2 (str)
*** 7134,7141 ****
  }
  
  static int
! fp_op2 (str)
!      char ** str;
  {
    skip_whitespace (* str);
  
--- 5800,5806 ----
  }
  
  static int
! fp_op2 (char ** str)
  {
    skip_whitespace (* str);
  
*************** fp_op2 (str)
*** 7191,7198 ****
  }
  
  static void
! do_arit (str)
!      char * str;
  {
    skip_whitespace (str);
  
--- 5856,5862 ----
  }
  
  static void
! do_arit (char * str)
  {
    skip_whitespace (str);
  
*************** do_arit (str)
*** 7211,7218 ****
  }
  
  static void
! do_adr (str)
!      char * str;
  {
    /* This is a pseudo-op of the form "adr rd, label" to be converted
       into a relative address of the form "add rd, pc, #label-.-8".  */
--- 5875,5881 ----
  }
  
  static void
! do_adr (char * str)
  {
    /* This is a pseudo-op of the form "adr rd, label" to be converted
       into a relative address of the form "add rd, pc, #label-.-8".  */
*************** do_adr (str)
*** 7239,7246 ****
  }
  
  static void
! do_adrl (str)
!      char * str;
  {
    /* This is a pseudo-op of the form "adrl rd, label" to be converted
       into a relative address of the form:
--- 5902,5908 ----
  }
  
  static void
! do_adrl (char * str)
  {
    /* This is a pseudo-op of the form "adrl rd, label" to be converted
       into a relative address of the form:
*************** do_adrl (str)
*** 7263,7269 ****
    /* Frag hacking will turn this into a sub instruction if the offset turns
       out to be negative.  */
    inst.reloc.type              = BFD_RELOC_ARM_ADRL_IMMEDIATE;
! #ifndef TE_WINCE  
    inst.reloc.exp.X_add_number -= 8; /* PC relative adjust  */
  #endif
    inst.reloc.pc_rel            = 1;
--- 5925,5931 ----
    /* Frag hacking will turn this into a sub instruction if the offset turns
       out to be negative.  */
    inst.reloc.type              = BFD_RELOC_ARM_ADRL_IMMEDIATE;
! #ifndef TE_WINCE
    inst.reloc.exp.X_add_number -= 8; /* PC relative adjust  */
  #endif
    inst.reloc.pc_rel            = 1;
*************** do_adrl (str)
*** 7271,7278 ****
  }
  
  static void
! do_cmp (str)
!      char * str;
  {
    skip_whitespace (str);
  
--- 5933,5939 ----
  }
  
  static void
! do_cmp (char * str)
  {
    skip_whitespace (str);
  
*************** do_cmp (str)
*** 7295,7302 ****
  }
  
  static void
! do_mov (str)
!      char * str;
  {
    skip_whitespace (str);
  
--- 5956,5962 ----
  }
  
  static void
! do_mov (char * str)
  {
    skip_whitespace (str);
  
*************** do_mov (str)
*** 7318,7385 ****
    end_of_line (str);
  }
  
- static int
- ldst_extend (str)
-      char ** str;
- {
-   int add = INDEX_UP;
- 
-   switch (**str)
-     {
-     case '#':
-     case '$':
-       (*str)++;
-       if (my_get_expression (& inst.reloc.exp, str))
- 	return FAIL;
- 
-       if (inst.reloc.exp.X_op == O_constant)
- 	{
- 	  int value = inst.reloc.exp.X_add_number;
- 
- 	  if (value < -4095 || value > 4095)
- 	    {
- 	      inst.error = _("address offset too large");
- 	      return FAIL;
- 	    }
- 
- 	  if (value < 0)
- 	    {
- 	      value = -value;
- 	      add = 0;
- 	    }
- 
- 	  inst.instruction |= add | value;
- 	}
-       else
- 	{
- 	  inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
- 	  inst.reloc.pc_rel = 0;
- 	}
-       return SUCCESS;
- 
-     case '-':
-       add = 0;
-       /* Fall through.  */
- 
-     case '+':
-       (*str)++;
-       /* Fall through.  */
- 
-     default:
-       if (reg_required_here (str, 0) == FAIL)
- 	return FAIL;
- 
-       inst.instruction |= add | OFFSET_REG;
-       if (skip_past_comma (str) == SUCCESS)
- 	return decode_shift (str, SHIFT_IMMEDIATE);
- 
-       return SUCCESS;
-     }
- }
- 
  static void
! do_ldst (str)
!      char *        str;
  {
    int pre_inc = 0;
    int conflict_reg;
--- 5978,5985 ----
    end_of_line (str);
  }
  
  static void
! do_ldst (char * str)
  {
    int pre_inc = 0;
    int conflict_reg;
*************** do_ldst (str)
*** 7569,7576 ****
  }
  
  static void
! do_ldstt (str)
!      char *        str;
  {
    int conflict_reg;
  
--- 6169,6175 ----
  }
  
  static void
! do_ldstt (char * str)
  {
    int conflict_reg;
  
*************** do_ldstt (str)
*** 7646,7715 ****
    end_of_line (str);
  }
  
- static int
- ldst_extend_v4 (str)
-      char ** str;
- {
-   int add = INDEX_UP;
- 
-   switch (**str)
-     {
-     case '#':
-     case '$':
-       (*str)++;
-       if (my_get_expression (& inst.reloc.exp, str))
- 	return FAIL;
- 
-       if (inst.reloc.exp.X_op == O_constant)
- 	{
- 	  int value = inst.reloc.exp.X_add_number;
- 
- 	  if (value < -255 || value > 255)
- 	    {
- 	      inst.error = _("address offset too large");
- 	      return FAIL;
- 	    }
- 
- 	  if (value < 0)
- 	    {
- 	      value = -value;
- 	      add = 0;
- 	    }
- 
- 	  /* Halfword and signextension instructions have the
-              immediate value split across bits 11..8 and bits 3..0.  */
- 	  inst.instruction |= (add | HWOFFSET_IMM
- 			       | ((value >> 4) << 8) | (value & 0xF));
- 	}
-       else
- 	{
- 	  inst.instruction |= HWOFFSET_IMM;
- 	  inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
- 	  inst.reloc.pc_rel = 0;
- 	}
-       return SUCCESS;
- 
-     case '-':
-       add = 0;
-       /* Fall through.  */
- 
-     case '+':
-       (*str)++;
-       /* Fall through.  */
- 
-     default:
-       if (reg_required_here (str, 0) == FAIL)
- 	return FAIL;
- 
-       inst.instruction |= add;
-       return SUCCESS;
-     }
- }
- 
  /* Halfword and signed-byte load/store operations.  */
  static void
! do_ldstv4 (str)
!      char *        str;
  {
    int pre_inc = 0;
    int conflict_reg;
--- 6245,6254 ----
    end_of_line (str);
  }
  
  /* Halfword and signed-byte load/store operations.  */
+ 
  static void
! do_ldstv4 (char * str)
  {
    int pre_inc = 0;
    int conflict_reg;
*************** do_ldstv4 (str)
*** 7902,7909 ****
  }
  
  static long
! reg_list (strp)
!      char ** strp;
  {
    char * str = * strp;
    long   range = 0;
--- 6441,6447 ----
  }
  
  static long
! reg_list (char ** strp)
  {
    char * str = * strp;
    long   range = 0;
*************** reg_list (strp)
*** 8029,8036 ****
  }
  
  static void
! do_ldmstm (str)
!      char * str;
  {
    int base_reg;
    long range;
--- 6567,6573 ----
  }
  
  static void
! do_ldmstm (char * str)
  {
    int base_reg;
    long range;
*************** do_ldmstm (str)
*** 8098,8105 ****
  }
  
  static void
! do_swi (str)
!      char * str;
  {
    skip_whitespace (str);
  
--- 6635,6641 ----
  }
  
  static void
! do_swi (char * str)
  {
    skip_whitespace (str);
  
*************** do_swi (str)
*** 8116,8123 ****
  }
  
  static void
! do_swap (str)
!      char * str;
  {
    int reg;
  
--- 6652,6658 ----
  }
  
  static void
! do_swap (char * str)
  {
    int reg;
  
*************** do_swap (str)
*** 8176,8183 ****
  }
  
  static void
! do_branch (str)
!      char * str;
  {
    if (my_get_expression (&inst.reloc.exp, &str))
      return;
--- 6711,6717 ----
  }
  
  static void
! do_branch (char * str)
  {
    if (my_get_expression (&inst.reloc.exp, &str))
      return;
*************** do_branch (str)
*** 8220,8248 ****
  }
  
  static void
! do_bx (str)
!      char * str;
! {
!   int reg;
! 
!   skip_whitespace (str);
! 
!   if ((reg = reg_required_here (&str, 0)) == FAIL)
!     {
!       inst.error = BAD_ARGS;
!       return;
!     }
! 
!   /* Note - it is not illegal to do a "bx pc".  Useless, but not illegal.  */
!   if (reg == REG_PC)
!     as_tsktsk (_("use of r15 in bx in ARM mode is not really useful"));
! 
!   end_of_line (str);
! }
! 
! static void
! do_cdp (str)
!      char * str;
  {
    /* Co-processor data operation.
       Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>}  */
--- 6754,6760 ----
  }
  
  static void
! do_cdp (char * str)
  {
    /* Co-processor data operation.
       Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>}  */
*************** do_cdp (str)
*** 8301,8308 ****
  }
  
  static void
! do_lstc (str)
!      char * str;
  {
    /* Co-processor register load/store.
       Format: <LDC|STC{cond}[L] CP#,CRd,<address>  */
--- 6813,6819 ----
  }
  
  static void
! do_lstc (char * str)
  {
    /* Co-processor register load/store.
       Format: <LDC|STC{cond}[L] CP#,CRd,<address>  */
*************** do_lstc (str)
*** 8336,8343 ****
  }
  
  static void
! do_co_reg (str)
!      char * str;
  {
    /* Co-processor register transfer.
       Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>}  */
--- 6847,6853 ----
  }
  
  static void
! do_co_reg (char * str)
  {
    /* Co-processor register transfer.
       Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>}  */
*************** do_co_reg (str)
*** 8397,8404 ****
  }
  
  static void
! do_fpa_ctrl (str)
!      char * str;
  {
    /* FP control registers.
       Format: <WFS|RFS|WFC|RFC>{cond} Rn  */
--- 6907,6913 ----
  }
  
  static void
! do_fpa_ctrl (char * str)
  {
    /* FP control registers.
       Format: <WFS|RFS|WFC|RFC>{cond} Rn  */
*************** do_fpa_ctrl (str)
*** 8416,8423 ****
  }
  
  static void
! do_fpa_ldst (str)
!      char * str;
  {
    skip_whitespace (str);
  
--- 6925,6931 ----
  }
  
  static void
! do_fpa_ldst (char * str)
  {
    skip_whitespace (str);
  
*************** do_fpa_ldst (str)
*** 8440,8447 ****
  }
  
  static void
! do_fpa_ldmstm (str)
!      char * str;
  {
    int num_regs;
  
--- 6948,6954 ----
  }
  
  static void
! do_fpa_ldmstm (char * str)
  {
    int num_regs;
  
*************** do_fpa_ldmstm (str)
*** 8579,8586 ****
  }
  
  static void
! do_fpa_dyadic (str)
!      char * str;
  {
    skip_whitespace (str);
  
--- 7086,7092 ----
  }
  
  static void
! do_fpa_dyadic (char * str)
  {
    skip_whitespace (str);
  
*************** do_fpa_dyadic (str)
*** 8611,8618 ****
  }
  
  static void
! do_fpa_monadic (str)
!      char * str;
  {
    skip_whitespace (str);
  
--- 7117,7123 ----
  }
  
  static void
! do_fpa_monadic (char * str)
  {
    skip_whitespace (str);
  
*************** do_fpa_monadic (str)
*** 8635,8642 ****
  }
  
  static void
! do_fpa_cmp (str)
!      char * str;
  {
    skip_whitespace (str);
  
--- 7140,7146 ----
  }
  
  static void
! do_fpa_cmp (char * str)
  {
    skip_whitespace (str);
  
*************** do_fpa_cmp (str)
*** 8659,8666 ****
  }
  
  static void
! do_fpa_from_reg (str)
!      char * str;
  {
    skip_whitespace (str);
  
--- 7163,7169 ----
  }
  
  static void
! do_fpa_from_reg (char * str)
  {
    skip_whitespace (str);
  
*************** do_fpa_from_reg (str)
*** 8683,8690 ****
  }
  
  static void
! do_fpa_to_reg (str)
!      char * str;
  {
    skip_whitespace (str);
  
--- 7186,7192 ----
  }
  
  static void
! do_fpa_to_reg (char * str)
  {
    skip_whitespace (str);
  
*************** do_fpa_to_reg (str)
*** 8703,8711 ****
  }
  
  static int
! vfp_sp_reg_required_here (str, pos)
!      char **str;
!      enum vfp_sp_reg_pos pos;
  {
    int    reg;
    char *start = *str;
--- 7205,7212 ----
  }
  
  static int
! vfp_sp_reg_required_here (char ** str,
! 			  enum vfp_sp_reg_pos pos)
  {
    int    reg;
    char *start = *str;
*************** vfp_sp_reg_required_here (str, pos)
*** 8742,8753 ****
  }
  
  static int
! vfp_dp_reg_required_here (str, pos)
!      char **str;
!      enum vfp_dp_reg_pos pos;
  {
!   int   reg;
!   char *start = *str;
  
    if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_DN].htab)) != FAIL)
      {
--- 7243,7253 ----
  }
  
  static int
! vfp_dp_reg_required_here (char ** str,
! 			  enum vfp_dp_reg_pos pos)
  {
!   int    reg;
!   char * start = *str;
  
    if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_DN].htab)) != FAIL)
      {
*************** vfp_dp_reg_required_here (str, pos)
*** 8781,8788 ****
  }
  
  static void
! do_vfp_sp_monadic (str)
!      char *str;
  {
    skip_whitespace (str);
  
--- 7281,7287 ----
  }
  
  static void
! do_vfp_sp_monadic (char * str)
  {
    skip_whitespace (str);
  
*************** do_vfp_sp_monadic (str)
*** 8801,8808 ****
  }
  
  static void
! do_vfp_dp_monadic (str)
!      char *str;
  {
    skip_whitespace (str);
  
--- 7300,7306 ----
  }
  
  static void
! do_vfp_dp_monadic (char * str)
  {
    skip_whitespace (str);
  
*************** do_vfp_dp_monadic (str)
*** 8821,8828 ****
  }
  
  static void
! do_vfp_sp_dyadic (str)
!      char *str;
  {
    skip_whitespace (str);
  
--- 7319,7325 ----
  }
  
  static void
! do_vfp_sp_dyadic (char * str)
  {
    skip_whitespace (str);
  
*************** do_vfp_sp_dyadic (str)
*** 8843,8850 ****
  }
  
  static void
! do_vfp_dp_dyadic (str)
!      char *str;
  {
    skip_whitespace (str);
  
--- 7340,7346 ----
  }
  
  static void
! do_vfp_dp_dyadic (char * str)
  {
    skip_whitespace (str);
  
*************** do_vfp_dp_dyadic (str)
*** 8865,8872 ****
  }
  
  static void
! do_vfp_reg_from_sp (str)
!      char *str;
  {
    skip_whitespace (str);
  
--- 7361,7367 ----
  }
  
  static void
! do_vfp_reg_from_sp (char * str)
  {
    skip_whitespace (str);
  
*************** do_vfp_reg_from_sp (str)
*** 8884,8892 ****
    end_of_line (str);
  }
  
  static void
! do_vfp_reg2_from_sp2 (str)
!      char *str;
  {
    skip_whitespace (str);
  
--- 7379,7503 ----
    end_of_line (str);
  }
  
+ /* Parse and encode a VFP SP register list, storing the initial
+    register in position POS and returning the range as the result.  If
+    the string is invalid return FAIL (an invalid range).  */
+ 
+ static long
+ vfp_sp_reg_list (char ** str, enum vfp_sp_reg_pos pos)
+ {
+   long range = 0;
+   int base_reg = 0;
+   int new_base;
+   long base_bits = 0;
+   int count = 0;
+   long tempinst;
+   unsigned long mask = 0;
+   int warned = 0;
+ 
+   if (**str != '{')
+     return FAIL;
+ 
+   (*str)++;
+   skip_whitespace (*str);
+ 
+   tempinst = inst.instruction;
+ 
+   do
+     {
+       inst.instruction = 0;
+ 
+       if ((new_base = vfp_sp_reg_required_here (str, pos)) == FAIL)
+ 	return FAIL;
+ 
+       if (count == 0 || base_reg > new_base)
+ 	{
+ 	  base_reg = new_base;
+ 	  base_bits = inst.instruction;
+ 	}
+ 
+       if (mask & (1 << new_base))
+ 	{
+ 	  inst.error = _("invalid register list");
+ 	  return FAIL;
+ 	}
+ 
+       if ((mask >> new_base) != 0 && ! warned)
+ 	{
+ 	  as_tsktsk (_("register list not in ascending order"));
+ 	  warned = 1;
+ 	}
+ 
+       mask |= 1 << new_base;
+       count++;
+ 
+       skip_whitespace (*str);
+ 
+       if (**str == '-') /* We have the start of a range expression */
+ 	{
+ 	  int high_range;
+ 
+ 	  (*str)++;
+ 
+ 	  if ((high_range
+ 	       = arm_reg_parse (str, all_reg_maps[REG_TYPE_SN].htab))
+ 	      == FAIL)
+ 	    {
+ 	      inst.error = _(all_reg_maps[REG_TYPE_SN].expected);
+ 	      return FAIL;
+ 	    }
+ 
+ 	  if (high_range <= new_base)
+ 	    {
+ 	      inst.error = _("register range not in ascending order");
+ 	      return FAIL;
+ 	    }
+ 
+ 	  for (new_base++; new_base <= high_range; new_base++)
+ 	    {
+ 	      if (mask & (1 << new_base))
+ 		{
+ 		  inst.error = _("invalid register list");
+ 		  return FAIL;
+ 		}
+ 
+ 	      mask |= 1 << new_base;
+ 	      count++;
+ 	    }
+ 	}
+     }
+   while (skip_past_comma (str) != FAIL);
+ 
+   if (**str != '}')
+     {
+       inst.error = _("invalid register list");
+       return FAIL;
+     }
+ 
+   (*str)++;
+ 
+   range = count;
+ 
+   /* Sanity check -- should have raised a parse error above.  */
+   if (count == 0 || count > 32)
+     abort ();
+ 
+   /* Final test -- the registers must be consecutive.  */
+   while (count--)
+     {
+       if ((mask & (1 << base_reg++)) == 0)
+ 	{
+ 	  inst.error = _("non-contiguous register range");
+ 	  return FAIL;
+ 	}
+     }
+ 
+   inst.instruction = tempinst | base_bits;
+   return range;
+ }
+ 
  static void
! do_vfp_reg2_from_sp2 (char * str)
  {
    skip_whitespace (str);
  
*************** do_vfp_reg2_from_sp2 (str)
*** 8911,8918 ****
  }
  
  static void
! do_vfp_sp_from_reg (str)
!      char *str;
  {
    skip_whitespace (str);
  
--- 7522,7528 ----
  }
  
  static void
! do_vfp_sp_from_reg (char * str)
  {
    skip_whitespace (str);
  
*************** do_vfp_sp_from_reg (str)
*** 8931,8938 ****
  }
  
  static void
! do_vfp_sp2_from_reg2 (str)
!      char *str;
  {
    skip_whitespace (str);
  
--- 7541,7547 ----
  }
  
  static void
! do_vfp_sp2_from_reg2 (char * str)
  {
    skip_whitespace (str);
  
*************** do_vfp_sp2_from_reg2 (str)
*** 8957,8964 ****
  }
  
  static void
! do_vfp_reg_from_dp (str)
!      char *str;
  {
    skip_whitespace (str);
  
--- 7566,7572 ----
  }
  
  static void
! do_vfp_reg_from_dp (char * str)
  {
    skip_whitespace (str);
  
*************** do_vfp_reg_from_dp (str)
*** 8977,8984 ****
  }
  
  static void
! do_vfp_reg2_from_dp (str)
!      char *str;
  {
    skip_whitespace (str);
  
--- 7585,7591 ----
  }
  
  static void
! do_vfp_reg2_from_dp (char * str)
  {
    skip_whitespace (str);
  
*************** do_vfp_reg2_from_dp (str)
*** 8999,9006 ****
  }
  
  static void
! do_vfp_dp_from_reg (str)
!      char *str;
  {
    skip_whitespace (str);
  
--- 7606,7612 ----
  }
  
  static void
! do_vfp_dp_from_reg (char * str)
  {
    skip_whitespace (str);
  
*************** do_vfp_dp_from_reg (str)
*** 9019,9026 ****
  }
  
  static void
! do_vfp_dp_from_reg2 (str)
!      char *str;
  {
    skip_whitespace (str);
  
--- 7625,7631 ----
  }
  
  static void
! do_vfp_dp_from_reg2 (char * str)
  {
    skip_whitespace (str);
  
*************** do_vfp_dp_from_reg2 (str)
*** 9041,9048 ****
  }
  
  static const struct vfp_reg *
! vfp_psr_parse (str)
!      char **str;
  {
    char *start = *str;
    char  c;
--- 7646,7652 ----
  }
  
  static const struct vfp_reg *
! vfp_psr_parse (char ** str)
  {
    char *start = *str;
    char  c;
*************** vfp_psr_parse (str)
*** 9065,9071 ****
         vreg < vfp_regs + sizeof (vfp_regs) / sizeof (struct vfp_reg);
         vreg++)
      {
!       if (strcmp (start, vreg->name) == 0)
  	{
  	  *p = c;
  	  *str = p;
--- 7669,7675 ----
         vreg < vfp_regs + sizeof (vfp_regs) / sizeof (struct vfp_reg);
         vreg++)
      {
!       if (streq (start, vreg->name))
  	{
  	  *p = c;
  	  *str = p;
*************** vfp_psr_parse (str)
*** 9078,9085 ****
  }
  
  static int
! vfp_psr_required_here (str)
!      char **str;
  {
    char *start = *str;
    const struct vfp_reg *vreg;
--- 7682,7688 ----
  }
  
  static int
! vfp_psr_required_here (char ** str)
  {
    char *start = *str;
    const struct vfp_reg *vreg;
*************** vfp_psr_required_here (str)
*** 9099,9106 ****
  }
  
  static void
! do_vfp_reg_from_ctrl (str)
!      char *str;
  {
    skip_whitespace (str);
  
--- 7702,7708 ----
  }
  
  static void
! do_vfp_reg_from_ctrl (char * str)
  {
    skip_whitespace (str);
  
*************** do_vfp_reg_from_ctrl (str)
*** 9119,9126 ****
  }
  
  static void
! do_vfp_ctrl_from_reg (str)
!      char *str;
  {
    skip_whitespace (str);
  
--- 7721,7727 ----
  }
  
  static void
! do_vfp_ctrl_from_reg (char * str)
  {
    skip_whitespace (str);
  
*************** do_vfp_ctrl_from_reg (str)
*** 9139,9146 ****
  }
  
  static void
! do_vfp_sp_ldst (str)
!      char *str;
  {
    skip_whitespace (str);
  
--- 7740,7746 ----
  }
  
  static void
! do_vfp_sp_ldst (char * str)
  {
    skip_whitespace (str);
  
*************** do_vfp_sp_ldst (str)
*** 9163,9170 ****
  }
  
  static void
! do_vfp_dp_ldst (str)
!      char *str;
  {
    skip_whitespace (str);
  
--- 7763,7769 ----
  }
  
  static void
! do_vfp_dp_ldst (char * str)
  {
    skip_whitespace (str);
  
*************** do_vfp_dp_ldst (str)
*** 9179,9312 ****
        || cp_address_required_here (&str, CP_NO_WB) == FAIL)
      {
        if (!inst.error)
! 	inst.error = BAD_ARGS;
!       return;
!     }
! 
!   end_of_line (str);
! }
! 
! /* Parse and encode a VFP SP register list, storing the initial
!    register in position POS and returning the range as the result.  If
!    the string is invalid return FAIL (an invalid range).  */
! static long
! vfp_sp_reg_list (str, pos)
!      char **str;
!      enum vfp_sp_reg_pos pos;
! {
!   long range = 0;
!   int base_reg = 0;
!   int new_base;
!   long base_bits = 0;
!   int count = 0;
!   long tempinst;
!   unsigned long mask = 0;
!   int warned = 0;
! 
!   if (**str != '{')
!     return FAIL;
! 
!   (*str)++;
!   skip_whitespace (*str);
! 
!   tempinst = inst.instruction;
! 
!   do
!     {
!       inst.instruction = 0;
! 
!       if ((new_base = vfp_sp_reg_required_here (str, pos)) == FAIL)
! 	return FAIL;
! 
!       if (count == 0 || base_reg > new_base)
! 	{
! 	  base_reg = new_base;
! 	  base_bits = inst.instruction;
! 	}
! 
!       if (mask & (1 << new_base))
! 	{
! 	  inst.error = _("invalid register list");
! 	  return FAIL;
! 	}
! 
!       if ((mask >> new_base) != 0 && ! warned)
! 	{
! 	  as_tsktsk (_("register list not in ascending order"));
! 	  warned = 1;
! 	}
! 
!       mask |= 1 << new_base;
!       count++;
! 
!       skip_whitespace (*str);
! 
!       if (**str == '-') /* We have the start of a range expression */
! 	{
! 	  int high_range;
! 
! 	  (*str)++;
! 
! 	  if ((high_range
! 	       = arm_reg_parse (str, all_reg_maps[REG_TYPE_SN].htab))
! 	      == FAIL)
! 	    {
! 	      inst.error = _(all_reg_maps[REG_TYPE_SN].expected);
! 	      return FAIL;
! 	    }
! 
! 	  if (high_range <= new_base)
! 	    {
! 	      inst.error = _("register range not in ascending order");
! 	      return FAIL;
! 	    }
! 
! 	  for (new_base++; new_base <= high_range; new_base++)
! 	    {
! 	      if (mask & (1 << new_base))
! 		{
! 		  inst.error = _("invalid register list");
! 		  return FAIL;
! 		}
! 
! 	      mask |= 1 << new_base;
! 	      count++;
! 	    }
! 	}
!     }
!   while (skip_past_comma (str) != FAIL);
! 
!   if (**str != '}')
!     {
!       inst.error = _("invalid register list");
!       return FAIL;
!     }
! 
!   (*str)++;
! 
!   range = count;
! 
!   /* Sanity check -- should have raised a parse error above.  */
!   if (count == 0 || count > 32)
!     abort ();
! 
!   /* Final test -- the registers must be consecutive.  */
!   while (count--)
!     {
!       if ((mask & (1 << base_reg++)) == 0)
! 	{
! 	  inst.error = _("non-contiguous register range");
! 	  return FAIL;
! 	}
      }
  
!   inst.instruction = tempinst | base_bits;
!   return range;
  }
  
  static long
! vfp_dp_reg_list (str)
!      char **str;
  {
    long range = 0;
    int base_reg = 0;
--- 7778,7792 ----
        || cp_address_required_here (&str, CP_NO_WB) == FAIL)
      {
        if (!inst.error)
! 	inst.error = BAD_ARGS;
!       return;
      }
  
!   end_of_line (str);
  }
  
  static long
! vfp_dp_reg_list (char ** str)
  {
    long range = 0;
    int base_reg = 0;
*************** vfp_dp_reg_list (str)
*** 9418,9426 ****
  }
  
  static void
! vfp_sp_ldstm (str, ldstm_type)
!      char *str;
!      enum vfp_ldstm_type ldstm_type;
  {
    long range;
  
--- 7898,7904 ----
  }
  
  static void
! vfp_sp_ldstm (char * str, enum vfp_ldstm_type ldstm_type)
  {
    long range;
  
*************** vfp_sp_ldstm (str, ldstm_type)
*** 9455,9463 ****
  }
  
  static void
! vfp_dp_ldstm (str, ldstm_type)
!      char *str;
!      enum vfp_ldstm_type ldstm_type;
  {
    long range;
  
--- 7933,7939 ----
  }
  
  static void
! vfp_dp_ldstm (char * str, enum vfp_ldstm_type ldstm_type)
  {
    long range;
  
*************** vfp_dp_ldstm (str, ldstm_type)
*** 9495,9544 ****
  }
  
  static void
! do_vfp_sp_ldstmia (str)
!      char *str;
  {
    vfp_sp_ldstm (str, VFP_LDSTMIA);
  }
  
  static void
! do_vfp_sp_ldstmdb (str)
!      char *str;
  {
    vfp_sp_ldstm (str, VFP_LDSTMDB);
  }
  
  static void
! do_vfp_dp_ldstmia (str)
!      char *str;
  {
    vfp_dp_ldstm (str, VFP_LDSTMIA);
  }
  
  static void
! do_vfp_dp_ldstmdb (str)
!      char *str;
  {
    vfp_dp_ldstm (str, VFP_LDSTMDB);
  }
  
  static void
! do_vfp_xp_ldstmia (str)
!      char *str;
  {
    vfp_dp_ldstm (str, VFP_LDSTMIAX);
  }
  
  static void
! do_vfp_xp_ldstmdb (str)
!      char *str;
  {
    vfp_dp_ldstm (str, VFP_LDSTMDBX);
  }
  
  static void
! do_vfp_sp_compare_z (str)
!      char *str;
  {
    skip_whitespace (str);
  
--- 7971,8013 ----
  }
  
  static void
! do_vfp_sp_ldstmia (char * str)
  {
    vfp_sp_ldstm (str, VFP_LDSTMIA);
  }
  
  static void
! do_vfp_sp_ldstmdb (char * str)
  {
    vfp_sp_ldstm (str, VFP_LDSTMDB);
  }
  
  static void
! do_vfp_dp_ldstmia (char * str)
  {
    vfp_dp_ldstm (str, VFP_LDSTMIA);
  }
  
  static void
! do_vfp_dp_ldstmdb (char * str)
  {
    vfp_dp_ldstm (str, VFP_LDSTMDB);
  }
  
  static void
! do_vfp_xp_ldstmia (char *str)
  {
    vfp_dp_ldstm (str, VFP_LDSTMIAX);
  }
  
  static void
! do_vfp_xp_ldstmdb (char * str)
  {
    vfp_dp_ldstm (str, VFP_LDSTMDBX);
  }
  
  static void
! do_vfp_sp_compare_z (char * str)
  {
    skip_whitespace (str);
  
*************** do_vfp_sp_compare_z (str)
*** 9553,9560 ****
  }
  
  static void
! do_vfp_dp_compare_z (str)
!      char *str;
  {
    skip_whitespace (str);
  
--- 8022,8028 ----
  }
  
  static void
! do_vfp_dp_compare_z (char * str)
  {
    skip_whitespace (str);
  
*************** do_vfp_dp_compare_z (str)
*** 9569,9576 ****
  }
  
  static void
! do_vfp_dp_sp_cvt (str)
!      char *str;
  {
    skip_whitespace (str);
  
--- 8037,8043 ----
  }
  
  static void
! do_vfp_dp_sp_cvt (char * str)
  {
    skip_whitespace (str);
  
*************** do_vfp_dp_sp_cvt (str)
*** 9589,9596 ****
  }
  
  static void
! do_vfp_sp_dp_cvt (str)
!      char *str;
  {
    skip_whitespace (str);
  
--- 8056,8062 ----
  }
  
  static void
! do_vfp_sp_dp_cvt (char * str)
  {
    skip_whitespace (str);
  
*************** do_vfp_sp_dp_cvt (str)
*** 9610,9663 ****
  
  /* Thumb specific routines.  */
  
- /* Parse and validate that a register is of the right form, this saves
-    repeated checking of this information in many similar cases.
-    Unlike the 32-bit case we do not insert the register into the opcode
-    here, since the position is often unknown until the full instruction
-    has been parsed.  */
- 
- static int
- thumb_reg (strp, hi_lo)
-      char ** strp;
-      int     hi_lo;
- {
-   int reg;
- 
-   if ((reg = reg_required_here (strp, -1)) == FAIL)
-     return FAIL;
- 
-   switch (hi_lo)
-     {
-     case THUMB_REG_LO:
-       if (reg > 7)
- 	{
- 	  inst.error = _("lo register required");
- 	  return FAIL;
- 	}
-       break;
- 
-     case THUMB_REG_HI:
-       if (reg < 8)
- 	{
- 	  inst.error = _("hi register required");
- 	  return FAIL;
- 	}
-       break;
- 
-     default:
-       break;
-     }
- 
-   return reg;
- }
- 
  /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
     was SUB.  */
  
  static void
! thumb_add_sub (str, subtract)
!      char * str;
!      int    subtract;
  {
    int Rd, Rs, Rn = FAIL;
  
--- 8076,8086 ----
  
  /* Thumb specific routines.  */
  
  /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
     was SUB.  */
  
  static void
! thumb_add_sub (char * str, int subtract)
  {
    int Rd, Rs, Rn = FAIL;
  
*************** thumb_add_sub (str, subtract)
*** 9825,9833 ****
  }
  
  static void
! thumb_shift (str, shift)
!      char * str;
!      int    shift;
  {
    int Rd, Rs, Rn = FAIL;
  
--- 8248,8254 ----
  }
  
  static void
! thumb_shift (char * str, int shift)
  {
    int Rd, Rs, Rn = FAIL;
  
*************** thumb_shift (str, shift)
*** 9934,10031 ****
  }
  
  static void
! thumb_mov_compare (str, move)
!      char * str;
!      int    move;
! {
!   int Rd, Rs = FAIL;
! 
!   skip_whitespace (str);
! 
!   if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
!       || skip_past_comma (&str) == FAIL)
!     {
!       if (! inst.error)
! 	inst.error = BAD_ARGS;
!       return;
!     }
! 
!   if (move != THUMB_CPY && is_immediate_prefix (*str))
!     {
!       str++;
!       if (my_get_expression (&inst.reloc.exp, &str))
! 	return;
!     }
!   else if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
!     return;
! 
!   if (Rs != FAIL)
!     {
!       if (move != THUMB_CPY && Rs < 8 && Rd < 8)
! 	{
! 	  if (move == THUMB_MOVE)
! 	    /* A move of two lowregs is encoded as ADD Rd, Rs, #0
! 	       since a MOV instruction produces unpredictable results.  */
! 	    inst.instruction = T_OPCODE_ADD_I3;
! 	  else
! 	    inst.instruction = T_OPCODE_CMP_LR;
! 	  inst.instruction |= Rd | (Rs << 3);
! 	}
!       else
! 	{
! 	  if (move == THUMB_MOVE)
! 	    inst.instruction = T_OPCODE_MOV_HR;
! 	  else if (move != THUMB_CPY)
! 	    inst.instruction = T_OPCODE_CMP_HR;
! 
! 	  if (Rd > 7)
! 	    inst.instruction |= THUMB_H1;
! 
! 	  if (Rs > 7)
! 	    inst.instruction |= THUMB_H2;
! 
! 	  inst.instruction |= (Rd & 7) | ((Rs & 7) << 3);
! 	}
!     }
!   else
!     {
!       if (Rd > 7)
! 	{
! 	  inst.error = _("only lo regs allowed with immediate");
! 	  return;
! 	}
! 
!       if (move == THUMB_MOVE)
! 	inst.instruction = T_OPCODE_MOV_I8;
!       else
! 	inst.instruction = T_OPCODE_CMP_I8;
! 
!       inst.instruction |= Rd << 8;
! 
!       if (inst.reloc.exp.X_op != O_constant)
! 	inst.reloc.type = BFD_RELOC_ARM_THUMB_IMM;
!       else
! 	{
! 	  unsigned value = inst.reloc.exp.X_add_number;
! 
! 	  if (value > 255)
! 	    {
! 	      inst.error = _("invalid immediate");
! 	      return;
! 	    }
! 
! 	  inst.instruction |= value;
! 	}
!     }
! 
!   end_of_line (str);
! }
! 
! static void
! thumb_load_store (str, load_store, size)
!      char * str;
!      int    load_store;
!      int    size;
  {
    int Rd, Rb, Ro = FAIL;
  
--- 8355,8361 ----
  }
  
  static void
! thumb_load_store (char * str, int load_store, int size)
  {
    int Rd, Rb, Ro = FAIL;
  
*************** thumb_load_store (str, load_store, size)
*** 10235,10244 ****
     Returns the reg#, or FAIL.  */
  
  static int
! mav_reg_required_here (str, shift, regtype)
!      char ** str;
!      int shift;
!      enum arm_reg_type regtype;
  {
    int   reg;
    char *start = *str;
--- 8565,8571 ----
     Returns the reg#, or FAIL.  */
  
  static int
! mav_reg_required_here (char ** str, int shift, enum arm_reg_type regtype)
  {
    int   reg;
    char *start = *str;
*************** mav_reg_required_here (str, shift, regty
*** 10279,11468 ****
    return FAIL;
  }
  
! /* Cirrus Maverick Instructions.  */
  
! /* Wrapper functions.  */
  
  static void
! do_mav_binops_1a (str)
!      char * str;
  {
!   do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVF);
  }
  
  static void
! do_mav_binops_1b (str)
!      char * str;
  {
!   do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVD);
  }
  
  static void
! do_mav_binops_1c (str)
!      char * str;
  {
!   do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVDX);
  }
  
  static void
! do_mav_binops_1d (str)
!      char * str;
  {
!   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVF);
  }
  
  static void
! do_mav_binops_1e (str)
!      char * str;
  {
!   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVD);
  }
  
  static void
! do_mav_binops_1f (str)
!      char * str;
  {
!   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVF);
  }
  
  static void
! do_mav_binops_1g (str)
!      char * str;
  {
!   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVD);
  }
  
  static void
! do_mav_binops_1h (str)
!      char * str;
  {
!   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVFX);
  }
  
  static void
! do_mav_binops_1i (str)
!      char * str;
  {
!   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVFX);
  }
  
  static void
! do_mav_binops_1j (str)
!      char * str;
  {
!   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVDX);
  }
  
  static void
! do_mav_binops_1k (str)
!      char * str;
  {
!   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVDX);
  }
  
  static void
! do_mav_binops_1l (str)
!      char * str;
  {
!   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVF);
  }
  
  static void
! do_mav_binops_1m (str)
!      char * str;
  {
!   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVD);
  }
  
  static void
! do_mav_binops_1n (str)
!      char * str;
  {
!   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVFX);
  }
  
  static void
! do_mav_binops_1o (str)
!      char * str;
  {
!   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVDX, REG_TYPE_MVDX);
  }
  
  static void
! do_mav_binops_2a (str)
!      char * str;
  {
!   do_mav_binops (str, MAV_MODE2, REG_TYPE_MVF, REG_TYPE_RN);
  }
  
  static void
! do_mav_binops_2b (str)
!      char * str;
  {
!   do_mav_binops (str, MAV_MODE2, REG_TYPE_MVD, REG_TYPE_RN);
  }
  
  static void
! do_mav_binops_2c (str)
!      char * str;
  {
!   do_mav_binops (str, MAV_MODE2, REG_TYPE_MVDX, REG_TYPE_RN);
  }
  
  static void
! do_mav_binops_3a (str)
!      char * str;
  {
!   do_mav_binops (str, MAV_MODE3, REG_TYPE_MVAX, REG_TYPE_MVFX);
  }
  
  static void
! do_mav_binops_3b (str)
!      char * str;
  {
!   do_mav_binops (str, MAV_MODE3, REG_TYPE_MVFX, REG_TYPE_MVAX);
  }
  
  static void
! do_mav_binops_3c (str)
!      char * str;
  {
!   do_mav_binops (str, MAV_MODE3, REG_TYPE_MVAX, REG_TYPE_MVDX);
  }
  
  static void
! do_mav_binops_3d (str)
!      char * str;
  {
!   do_mav_binops (str, MAV_MODE3, REG_TYPE_MVDX, REG_TYPE_MVAX);
  }
  
! static void
! do_mav_triple_4a (str)
!      char * str;
! {
!   do_mav_triple (str, MAV_MODE4, REG_TYPE_MVFX, REG_TYPE_MVFX, REG_TYPE_RN);
! }
  
! static void
! do_mav_triple_4b (str)
!      char * str;
! {
!   do_mav_triple (str, MAV_MODE4, REG_TYPE_MVDX, REG_TYPE_MVDX, REG_TYPE_RN);
! }
  
! static void
! do_mav_triple_5a (str)
!      char * str;
! {
!   do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVF, REG_TYPE_MVF);
! }
  
! static void
! do_mav_triple_5b (str)
!      char * str;
! {
!   do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVD, REG_TYPE_MVD);
! }
  
! static void
! do_mav_triple_5c (str)
!      char * str;
! {
!   do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVFX, REG_TYPE_MVFX);
  }
  
  static void
! do_mav_triple_5d (str)
!      char * str;
  {
!   do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVDX, REG_TYPE_MVDX);
  }
  
  static void
! do_mav_triple_5e (str)
!      char * str;
  {
!   do_mav_triple (str, MAV_MODE5, REG_TYPE_MVF, REG_TYPE_MVF, REG_TYPE_MVF);
  }
  
  static void
! do_mav_triple_5f (str)
!      char * str;
  {
!   do_mav_triple (str, MAV_MODE5, REG_TYPE_MVD, REG_TYPE_MVD, REG_TYPE_MVD);
  }
  
  static void
! do_mav_triple_5g (str)
!      char * str;
  {
!   do_mav_triple (str, MAV_MODE5, REG_TYPE_MVFX, REG_TYPE_MVFX, REG_TYPE_MVFX);
  }
  
  static void
! do_mav_triple_5h (str)
!      char * str;
  {
!   do_mav_triple (str, MAV_MODE5, REG_TYPE_MVDX, REG_TYPE_MVDX, REG_TYPE_MVDX);
  }
  
! static void
! do_mav_quad_6a (str)
!      char * str;
! {
!   do_mav_quad (str, MAV_MODE6, REG_TYPE_MVAX, REG_TYPE_MVFX, REG_TYPE_MVFX,
! 	       REG_TYPE_MVFX);
! }
  
  static void
! do_mav_quad_6b (str)
!      char * str;
  {
!   do_mav_quad (str, MAV_MODE6, REG_TYPE_MVAX, REG_TYPE_MVAX, REG_TYPE_MVFX,
! 	       REG_TYPE_MVFX);
! }
  
- /* cfmvsc32<cond> DSPSC,MVDX[15:0].  */
- static void
- do_mav_dspsc_1 (str)
-      char * str;
- {
    skip_whitespace (str);
  
!   /* cfmvsc32.  */
!   if (mav_reg_required_here (&str, -1, REG_TYPE_DSPSC) == FAIL
        || skip_past_comma (&str) == FAIL
!       || mav_reg_required_here (&str, 12, REG_TYPE_MVDX) == FAIL)
      {
!       if (!inst.error)
! 	inst.error = BAD_ARGS;
! 
        return;
      }
  
!   end_of_line (str);
! }
! 
! /* cfmv32sc<cond> MVDX[15:0],DSPSC.  */
! static void
! do_mav_dspsc_2 (str)
!      char * str;
! {
!   skip_whitespace (str);
! 
!   /* cfmv32sc.  */
!   if (mav_reg_required_here (&str, 12, REG_TYPE_MVDX) == FAIL
!       || skip_past_comma (&str) == FAIL
!       || mav_reg_required_here (&str, -1, REG_TYPE_DSPSC) == FAIL)
      {
!       if (!inst.error)
! 	inst.error = BAD_ARGS;
  
!       return;
      }
  
    end_of_line (str);
  }
  
  static void
! do_mav_shift_1 (str)
!      char * str;
  {
!   do_mav_shift (str, REG_TYPE_MVFX, REG_TYPE_MVFX);
  }
  
  static void
! do_mav_shift_2 (str)
!      char * str;
  {
!   do_mav_shift (str, REG_TYPE_MVDX, REG_TYPE_MVDX);
  }
  
  static void
! do_mav_ldst_1 (str)
!      char * str;
  {
!   do_mav_ldst (str, REG_TYPE_MVF);
  }
  
  static void
! do_mav_ldst_2 (str)
!      char * str;
  {
!   do_mav_ldst (str, REG_TYPE_MVD);
  }
  
! static void
! do_mav_ldst_3 (str)
!      char * str;
! {
!   do_mav_ldst (str, REG_TYPE_MVFX);
! }
  
! static void
! do_mav_ldst_4 (str)
!      char * str;
  {
!   do_mav_ldst (str, REG_TYPE_MVDX);
! }
  
! /* Isnsn like "foo X,Y".  */
  
! static void
! do_mav_binops (str, mode, reg0, reg1)
!      char * str;
!      int mode;
!      enum arm_reg_type reg0;
!      enum arm_reg_type reg1;
! {
!   int shift0, shift1;
  
!   shift0 = mode & 0xff;
!   shift1 = (mode >> 8) & 0xff;
  
!   skip_whitespace (str);
  
!   if (mav_reg_required_here (&str, shift0, reg0) == FAIL
!       || skip_past_comma (&str) == FAIL
!       || mav_reg_required_here (&str, shift1, reg1) == FAIL)
      {
!       if (!inst.error)
! 	inst.error = BAD_ARGS;
      }
-   else
-     end_of_line (str);
- }
  
! /* Isnsn like "foo X,Y,Z".  */
  
  static void
! do_mav_triple (str, mode, reg0, reg1, reg2)
!      char * str;
!      int mode;
!      enum arm_reg_type reg0;
!      enum arm_reg_type reg1;
!      enum arm_reg_type reg2;
  {
!   int shift0, shift1, shift2;
! 
!   shift0 = mode & 0xff;
!   shift1 = (mode >> 8) & 0xff;
!   shift2 = (mode >> 16) & 0xff;
  
!   skip_whitespace (str);
  
!   if (mav_reg_required_here (&str, shift0, reg0) == FAIL
!       || skip_past_comma (&str) == FAIL
!       || mav_reg_required_here (&str, shift1, reg1) == FAIL
!       || skip_past_comma (&str) == FAIL
!       || mav_reg_required_here (&str, shift2, reg2) == FAIL)
!     {
!       if (!inst.error)
! 	inst.error = BAD_ARGS;
!     }
!   else
!     end_of_line (str);
  }
  
- /* Isnsn like "foo W,X,Y,Z".
-     where W=MVAX[0:3] and X,Y,Z=MVFX[0:15].  */
- 
  static void
! do_mav_quad (str, mode, reg0, reg1, reg2, reg3)
!      char * str;
!      int mode;
!      enum arm_reg_type reg0;
!      enum arm_reg_type reg1;
!      enum arm_reg_type reg2;
!      enum arm_reg_type reg3;
  {
!   int shift0, shift1, shift2, shift3;
! 
!   shift0= mode & 0xff;
!   shift1 = (mode >> 8) & 0xff;
!   shift2 = (mode >> 16) & 0xff;
!   shift3 = (mode >> 24) & 0xff;
  
    skip_whitespace (str);
  
!   if (mav_reg_required_here (&str, shift0, reg0) == FAIL
!       || skip_past_comma (&str) == FAIL
!       || mav_reg_required_here (&str, shift1, reg1) == FAIL
!       || skip_past_comma (&str) == FAIL
!       || mav_reg_required_here (&str, shift2, reg2) == FAIL
!       || skip_past_comma (&str) == FAIL
!       || mav_reg_required_here (&str, shift3, reg3) == FAIL)
!     {
!       if (!inst.error)
! 	inst.error = BAD_ARGS;
!     }
!   else
!     end_of_line (str);
  }
  
! /* Maverick shift immediate instructions.
!    cfsh32<cond> MVFX[15:0],MVFX[15:0],Shift[6:0].
!    cfsh64<cond> MVDX[15:0],MVDX[15:0],Shift[6:0].  */
  
  static void
! do_mav_shift (str, reg0, reg1)
!      char * str;
!      enum arm_reg_type reg0;
!      enum arm_reg_type reg1;
  {
!   int error;
!   int imm, neg = 0;
  
    skip_whitespace (str);
  
!   error = 0;
  
!   if (mav_reg_required_here (&str, 12, reg0) == FAIL
!       || skip_past_comma (&str) == FAIL
!       || mav_reg_required_here (&str, 16, reg1) == FAIL
!       || skip_past_comma  (&str) == FAIL)
      {
!       if (!inst.error)
  	inst.error = BAD_ARGS;
        return;
      }
  
!   /* Calculate the immediate operand.
!      The operand is a 7bit signed number.  */
!   skip_whitespace (str);
! 
!   if (*str == '#')
!     ++str;
! 
!   if (!ISDIGIT (*str) && *str != '-')
      {
!       inst.error = _("expecting immediate, 7bit operand");
        return;
      }
  
!   if (*str == '-')
!     {
!       neg = 1;
!       ++str;
!     }
! 
!   for (imm = 0; *str && ISDIGIT (*str); ++str)
!     imm = imm * 10 + *str - '0';
! 
!   if (imm > 64)
      {
!       inst.error = _("immediate out of range");
        return;
      }
  
!   /* Make negative imm's into 7bit signed numbers.  */
!   if (neg)
!     {
!       imm = -imm;
!       imm &= 0x0000007f;
!     }
! 
!   /* Bits 0-3 of the insn should have bits 0-3 of the immediate.
!      Bits 5-7 of the insn should have bits 4-6 of the immediate.
!      Bit 4 should be 0.  */
!   imm = (imm & 0xf) | ((imm & 0x70) << 1);
! 
!   inst.instruction |= imm;
    end_of_line (str);
  }
  
! static int
! mav_parse_offset (str, negative)
!      char ** str;
!      int *negative;
  {
!   char * p = *str;
!   int offset;
  
!   *negative = 0;
  
!   skip_whitespace (p);
  
!   if (*p == '#')
!     ++p;
  
!   if (*p == '-')
!     {
!       *negative = 1;
!       ++p;
!     }
  
!   if (!ISDIGIT (*p))
      {
!       inst.error = _("offset expected");
!       return 0;
      }
  
!   for (offset = 0; *p && ISDIGIT (*p); ++p)
!     offset = offset * 10 + *p - '0';
! 
!   if (offset > 0x3fc)
!     {
!       inst.error = _("offset out of range");
!       return 0;
!     }
!   if (offset & 0x3)
!     {
!       inst.error = _("offset not a multiple of 4");
!       return 0;
!     }
  
!   *str = p;
  
!   return *negative ? -offset : offset;
  }
  
! /* Maverick load/store instructions.
!   <insn><cond> CRd,[Rn,<offset>]{!}.
!   <insn><cond> CRd,[Rn],<offset>.  */
  
  static void
! do_mav_ldst (str, reg0)
!      char * str;
!      enum arm_reg_type reg0;
  {
!   int offset, negative;
  
    skip_whitespace (str);
  
!   if (mav_reg_required_here (&str, 12, reg0) == FAIL
!       || skip_past_comma (&str) == FAIL
!       || *str++ != '['
!       || reg_required_here (&str, 16) == FAIL)
!     goto fail_ldst;
! 
!   if (skip_past_comma (&str) == SUCCESS)
      {
!       /* You are here: "<offset>]{!}".  */
!       inst.instruction |= PRE_INDEX;
! 
!       offset = mav_parse_offset (&str, &negative);
! 
!       if (inst.error)
! 	return;
  
!       if (*str++ != ']')
! 	{
! 	  inst.error = _("missing ]");
! 	  return;
! 	}
  
!       if (*str == '!')
  	{
! 	  inst.instruction |= WRITE_BACK;
! 	  ++str;
  	}
!     }
!   else
!     {
!       /* You are here: "], <offset>".  */
!       if (*str++ != ']')
  	{
! 	  inst.error = _("missing ]");
  	  return;
  	}
- 
-       if (skip_past_comma (&str) == FAIL
- 	  || (offset = mav_parse_offset (&str, &negative), inst.error))
- 	goto fail_ldst;
- 
-       inst.instruction |= CP_T_WB; /* Post indexed, set bit W.  */
      }
  
!   if (negative)
!     offset = -offset;
!   else
!     inst.instruction |= CP_T_UD; /* Positive, so set bit U.  */
! 
!   inst.instruction |= offset >> 2;
    end_of_line (str);
!   return;
  
! fail_ldst:
!   if (!inst.error)
!      inst.error = BAD_ARGS;
  }
  
  static void
! do_t_nop (str)
!      char * str;
  {
!   /* Do nothing.  */
!   end_of_line (str);
  }
  
! /* Handle the Format 4 instructions that do not have equivalents in other
!    formats.  That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
!    BIC and MVN.  */
  
  static void
! do_t_arit (str)
!      char * str;
  {
!   int Rd, Rs, Rn;
  
    skip_whitespace (str);
  
!   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
!       || skip_past_comma (&str) == FAIL
!       || (Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
!     {
!       inst.error = BAD_ARGS;
!       return;
!     }
  
!   if (skip_past_comma (&str) != FAIL)
!     {
!       /* Three operand format not allowed for TST, CMN, NEG and MVN.
! 	 (It isn't allowed for CMP either, but that isn't handled by this
! 	 function.)  */
!       if (inst.instruction == T_OPCODE_TST
! 	  || inst.instruction == T_OPCODE_CMN
! 	  || inst.instruction == T_OPCODE_NEG
! 	  || inst.instruction == T_OPCODE_MVN)
! 	{
! 	  inst.error = BAD_ARGS;
! 	  return;
! 	}
  
!       if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
! 	return;
  
!       if (Rs != Rd)
! 	{
! 	  inst.error = _("dest and source1 must be the same register");
! 	  return;
! 	}
!       Rs = Rn;
      }
  
!   if (inst.instruction == T_OPCODE_MUL
!       && Rs == Rd)
!     as_tsktsk (_("Rs and Rd must be different in MUL"));
  
-   inst.instruction |= Rd | (Rs << 3);
    end_of_line (str);
  }
  
  static void
! do_t_add (str)
!      char * str;
  {
!   thumb_add_sub (str, 0);
! }
  
! static void
! do_t_asr (str)
!      char * str;
! {
!   thumb_shift (str, THUMB_ASR);
  }
  
  static void
! do_t_branch9 (str)
!      char * str;
  {
!   if (my_get_expression (&inst.reloc.exp, &str))
!     return;
!   inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH9;
!   inst.reloc.pc_rel = 1;
!   end_of_line (str);
  }
  
  static void
! do_t_branch12 (str)
!      char * str;
! {
!   if (my_get_expression (&inst.reloc.exp, &str))
!     return;
!   inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH12;
!   inst.reloc.pc_rel = 1;
!   end_of_line (str);
  }
  
! /* Find the real, Thumb encoded start of a Thumb function.  */
  
! static symbolS *
! find_real_start (symbolP)
!      symbolS * symbolP;
  {
!   char *       real_start;
!   const char * name = S_GET_NAME (symbolP);
!   symbolS *    new_target;
  
!   /* This definition must agree with the one in gcc/config/arm/thumb.c.  */
! #define STUB_NAME ".real_start_of"
  
!   if (name == NULL)
!     abort ();
  
!   /* Names that start with '.' are local labels, not function entry points.
!      The compiler may generate BL instructions to these labels because it
!      needs to perform a branch to a far away location.  */
!   if (name[0] == '.')
!     return symbolP;
  
!   real_start = malloc (strlen (name) + strlen (STUB_NAME) + 1);
!   sprintf (real_start, "%s%s", STUB_NAME, name);
  
!   new_target = symbol_find (real_start);
  
!   if (new_target == NULL)
!     {
!       as_warn ("Failed to find real start of function: %s\n", name);
!       new_target = symbolP;
!     }
  
!   free (real_start);
  
!   return new_target;
  }
  
  static void
! do_t_branch23 (str)
!      char * str;
  {
!   if (my_get_expression (& inst.reloc.exp, & str))
!     return;
! 
!   inst.reloc.type   = BFD_RELOC_THUMB_PCREL_BRANCH23;
!   inst.reloc.pc_rel = 1;
!   end_of_line (str);
  
!   /* If the destination of the branch is a defined symbol which does not have
!      the THUMB_FUNC attribute, then we must be calling a function which has
!      the (interfacearm) attribute.  We look for the Thumb entry point to that
!      function and change the branch to refer to that function instead.  */
!   if (   inst.reloc.exp.X_op == O_symbol
!       && inst.reloc.exp.X_add_symbol != NULL
!       && S_IS_DEFINED (inst.reloc.exp.X_add_symbol)
!       && ! THUMB_IS_FUNC (inst.reloc.exp.X_add_symbol))
!     inst.reloc.exp.X_add_symbol =
!       find_real_start (inst.reloc.exp.X_add_symbol);
  }
  
! static void
! do_t_bx (str)
!      char * str;
  {
!   int reg;
  
!   skip_whitespace (str);
  
!   if ((reg = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
!     return;
  
!   /* This sets THUMB_H2 from the top bit of reg.  */
!   inst.instruction |= reg << 3;
  
!   /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC.  The reloc
!      should cause the alignment to be checked once it is known.  This is
!      because BX PC only works if the instruction is word aligned.  */
  
!   end_of_line (str);
! }
  
! static void
! do_t_compare (str)
!      char * str;
! {
!   thumb_mov_compare (str, THUMB_COMPARE);
! }
  
! static void
! do_t_ldmstm (str)
!      char * str;
! {
!   int Rb;
!   long range;
  
!   skip_whitespace (str);
  
!   if ((Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
!     return;
  
!   if (*str != '!')
!     as_warn (_("inserted missing '!': load/store multiple always writes back base register"));
!   else
!     str++;
  
!   if (skip_past_comma (&str) == FAIL
!       || (range = reg_list (&str)) == FAIL)
!     {
!       if (! inst.error)
! 	inst.error = BAD_ARGS;
!       return;
!     }
  
!   if (inst.reloc.type != BFD_RELOC_NONE)
!     {
!       /* This really doesn't seem worth it.  */
!       inst.reloc.type = BFD_RELOC_NONE;
!       inst.error = _("expression too complex");
!       return;
!     }
  
!   if (range & ~0xff)
!     {
!       inst.error = _("only lo-regs valid in load/store multiple");
!       return;
!     }
  
!   inst.instruction |= (Rb << 8) | range;
!   end_of_line (str);
! }
  
! static void
! do_t_ldr (str)
!      char * str;
! {
!   thumb_load_store (str, THUMB_LOAD, THUMB_WORD);
! }
  
! static void
! do_t_ldrb (str)
!      char * str;
! {
!   thumb_load_store (str, THUMB_LOAD, THUMB_BYTE);
! }
  
! static void
! do_t_ldrh (str)
!      char * str;
! {
!   thumb_load_store (str, THUMB_LOAD, THUMB_HALFWORD);
! }
  
! static void
! do_t_lds (str)
!      char * str;
! {
!   int Rd, Rb, Ro;
  
!   skip_whitespace (str);
  
!   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
!       || skip_past_comma (&str) == FAIL
!       || *str++ != '['
!       || (Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL
!       || skip_past_comma (&str) == FAIL
!       || (Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL
!       || *str++ != ']')
!     {
!       if (! inst.error)
! 	inst.error = _("syntax: ldrs[b] Rd, [Rb, Ro]");
!       return;
!     }
  
!   inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
!   end_of_line (str);
! }
  
! static void
! do_t_lsl (str)
!      char * str;
! {
!   thumb_shift (str, THUMB_LSL);
! }
  
! static void
! do_t_lsr (str)
!      char * str;
! {
!   thumb_shift (str, THUMB_LSR);
! }
  
! static void
! do_t_mov (str)
!      char * str;
! {
!   thumb_mov_compare (str, THUMB_MOVE);
! }
  
! static void
! do_t_push_pop (str)
!      char * str;
! {
!   long range;
  
!   skip_whitespace (str);
  
!   if ((range = reg_list (&str)) == FAIL)
!     {
!       if (! inst.error)
! 	inst.error = BAD_ARGS;
!       return;
!     }
  
!   if (inst.reloc.type != BFD_RELOC_NONE)
!     {
!       /* This really doesn't seem worth it.  */
!       inst.reloc.type = BFD_RELOC_NONE;
!       inst.error = _("expression too complex");
!       return;
!     }
  
!   if (range & ~0xff)
!     {
!       if ((inst.instruction == T_OPCODE_PUSH
! 	   && (range & ~0xff) == 1 << REG_LR)
! 	  || (inst.instruction == T_OPCODE_POP
! 	      && (range & ~0xff) == 1 << REG_PC))
! 	{
! 	  inst.instruction |= THUMB_PP_PC_LR;
! 	  range &= 0xff;
! 	}
!       else
! 	{
! 	  inst.error = _("invalid register list to push/pop instruction");
! 	  return;
! 	}
!     }
  
!   inst.instruction |= range;
!   end_of_line (str);
! }
  
! static void
! do_t_str (str)
!      char * str;
! {
!   thumb_load_store (str, THUMB_STORE, THUMB_WORD);
! }
  
! static void
! do_t_strb (str)
!      char * str;
! {
!   thumb_load_store (str, THUMB_STORE, THUMB_BYTE);
! }
  
! static void
! do_t_strh (str)
!      char * str;
! {
!   thumb_load_store (str, THUMB_STORE, THUMB_HALFWORD);
! }
  
! static void
! do_t_sub (str)
!      char * str;
! {
!   thumb_add_sub (str, 1);
! }
  
! static void
! do_t_swi (str)
!      char * str;
! {
!   skip_whitespace (str);
  
!   if (my_get_expression (&inst.reloc.exp, &str))
!     return;
  
!   inst.reloc.type = BFD_RELOC_ARM_SWI;
!   end_of_line (str);
! }
  
! static void
! do_t_adr (str)
!      char * str;
! {
!   int reg;
  
!   /* This is a pseudo-op of the form "adr rd, label" to be converted
!      into a relative address of the form "add rd, pc, #label-.-4".  */
!   skip_whitespace (str);
  
!   /* Store Rd in temporary location inside instruction.  */
!   if ((reg = reg_required_here (&str, 4)) == FAIL
!       || (reg > 7)  /* For Thumb reg must be r0..r7.  */
!       || skip_past_comma (&str) == FAIL
!       || my_get_expression (&inst.reloc.exp, &str))
!     {
!       if (!inst.error)
! 	inst.error = BAD_ARGS;
!       return;
!     }
  
!   inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
!   inst.reloc.exp.X_add_number -= 4; /* PC relative adjust.  */
!   inst.reloc.pc_rel = 1;
!   inst.instruction |= REG_PC; /* Rd is already placed into the instruction.  */
  
!   end_of_line (str);
! }
  
! static void
! insert_reg (r, htab)
!      const struct reg_entry *r;
!      struct hash_control *htab;
! {
!   int    len  = strlen (r->name) + 2;
!   char * buf  = (char *) xmalloc (len);
!   char * buf2 = (char *) xmalloc (len);
!   int    i    = 0;
  
! #ifdef REGISTER_PREFIX
!   buf[i++] = REGISTER_PREFIX;
! #endif
  
!   strcpy (buf + i, r->name);
  
!   for (i = 0; buf[i]; i++)
!     buf2[i] = TOUPPER (buf[i]);
  
!   buf2[i] = '\0';
  
!   hash_insert (htab, buf,  (PTR) r);
!   hash_insert (htab, buf2, (PTR) r);
! }
  
! static void
! build_reg_hsh (map)
!      struct reg_map *map;
! {
!   const struct reg_entry *r;
  
!   if ((map->htab = hash_new ()) == NULL)
!     as_fatal (_("virtual memory exhausted"));
  
!   for (r = map->names; r->name != NULL; r++)
!     insert_reg (r, map->htab);
! }
  
! static void
! insert_reg_alias (str, regnum, htab)
!      char *str;
!      int regnum;
!      struct hash_control *htab;
! {
!   const char *error;
!   struct reg_entry *new = xmalloc (sizeof (struct reg_entry));
!   const char *name = xmalloc (strlen (str) + 1);
!   
!   strcpy ((char *) name, str);
!   
!   new->name = name;
!   new->number = regnum;
!   new->builtin = FALSE;
  
!   error = hash_insert (htab, name, (PTR) new);
!   if (error)
!     {
!       as_bad (_("failed to create an alias for %s, reason: %s"),
! 	    str, error);
!       free ((char *) name);
!       free (new);
!     }
! }
  
! /* Look for the .req directive.  This is of the form:
  
!    	new_register_name .req existing_register_name
  
!    If we find one, or if it looks sufficiently like one that we want to
!    handle any error here, return non-zero.  Otherwise return zero.  */
! static int
! create_register_alias (newname, p)
!      char *newname;
!      char *p;
! {
!   char *q;
!   char c;
  
!   q = p;
!   skip_whitespace (q);
  
!   c = *p;
!   *p = '\0';
  
!   if (*q && !strncmp (q, ".req ", 5))
!     {
!       char *copy_of_str;
!       char *r;
  
! #ifndef IGNORE_OPCODE_CASE
!       newname = original_case_string;
! #endif
!       copy_of_str = newname;
  
!       q += 4;
!       skip_whitespace (q);
  
!       for (r = q; *r != '\0'; r++)
! 	if (*r == ' ')
! 	  break;
  
!       if (r != q)
! 	{
! 	  enum arm_reg_type new_type, old_type;
! 	  int old_regno;
! 	  char d = *r;
  
! 	  *r = '\0';
! 	  old_type = arm_reg_parse_any (q);
! 	  *r = d;
  
! 	  new_type = arm_reg_parse_any (newname);
  
! 	  if (new_type == REG_TYPE_MAX)
! 	    {
! 	      if (old_type != REG_TYPE_MAX)
! 		{
! 		  old_regno = arm_reg_parse (&q, all_reg_maps[old_type].htab);
! 		  insert_reg_alias (newname, old_regno,
! 				    all_reg_maps[old_type].htab);
! 		}
! 	      else
! 		as_warn (_("register '%s' does not exist\n"), q);
! 	    }
! 	  else if (old_type == REG_TYPE_MAX)
! 	    {
! 	      as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
! 		       copy_of_str, q);
! 	    }
! 	  else
! 	    {
! 	      /* Do not warn about redefinitions to the same alias.  */
! 	      if (new_type != old_type
! 		  || (arm_reg_parse (&q, all_reg_maps[old_type].htab)
! 		      != arm_reg_parse (&q, all_reg_maps[new_type].htab)))
! 		as_warn (_("ignoring redefinition of register alias '%s'"),
! 			 copy_of_str);
  
! 	    }
! 	}
!       else
! 	as_warn (_("ignoring incomplete .req pseuso op"));
  
!       *p = c;
!       return 1;
!     }
!   
!   *p = c;
!   return 0;
! }
  
! static void
! set_constant_flonums ()
! {
!   int i;
  
!   for (i = 0; i < NUM_FLOAT_VALS; i++)
!     if (atof_ieee ((char *) fp_const[i], 'x', fp_values[i]) == NULL)
!       abort ();
! }
  
  /* Iterate over the base tables to create the instruction patterns.  */
  static void
! build_arm_ops_hsh ()
  {
    unsigned int i;
    unsigned int j;
--- 8606,10811 ----
    return FAIL;
  }
  
! /* Cirrus Maverick Instructions.  */
! 
! /* Isnsn like "foo X,Y".  */
! 
! static void
! do_mav_binops (char * str,
! 	       int mode,
! 	       enum arm_reg_type reg0,
! 	       enum arm_reg_type reg1)
! {
!   int shift0, shift1;
! 
!   shift0 = mode & 0xff;
!   shift1 = (mode >> 8) & 0xff;
! 
!   skip_whitespace (str);
! 
!   if (mav_reg_required_here (&str, shift0, reg0) == FAIL
!       || skip_past_comma (&str) == FAIL
!       || mav_reg_required_here (&str, shift1, reg1) == FAIL)
!     {
!       if (!inst.error)
! 	inst.error = BAD_ARGS;
!     }
!   else
!     end_of_line (str);
! }
! 
! /* Isnsn like "foo X,Y,Z".  */
! 
! static void
! do_mav_triple (char * str,
! 	       int mode,
! 	       enum arm_reg_type reg0,
! 	       enum arm_reg_type reg1,
! 	       enum arm_reg_type reg2)
! {
!   int shift0, shift1, shift2;
! 
!   shift0 = mode & 0xff;
!   shift1 = (mode >> 8) & 0xff;
!   shift2 = (mode >> 16) & 0xff;
! 
!   skip_whitespace (str);
! 
!   if (mav_reg_required_here (&str, shift0, reg0) == FAIL
!       || skip_past_comma (&str) == FAIL
!       || mav_reg_required_here (&str, shift1, reg1) == FAIL
!       || skip_past_comma (&str) == FAIL
!       || mav_reg_required_here (&str, shift2, reg2) == FAIL)
!     {
!       if (!inst.error)
! 	inst.error = BAD_ARGS;
!     }
!   else
!     end_of_line (str);
! }
! 
! /* Wrapper functions.  */
! 
! static void
! do_mav_binops_1a (char * str)
! {
!   do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVF);
! }
! 
! static void
! do_mav_binops_1b (char * str)
! {
!   do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVD);
! }
! 
! static void
! do_mav_binops_1c (char * str)
! {
!   do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVDX);
! }
! 
! static void
! do_mav_binops_1d (char * str)
! {
!   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVF);
! }
! 
! static void
! do_mav_binops_1e (char * str)
! {
!   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVD);
! }
! 
! static void
! do_mav_binops_1f (char * str)
! {
!   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVF);
! }
! 
! static void
! do_mav_binops_1g (char * str)
! {
!   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVD);
! }
! 
! static void
! do_mav_binops_1h (char * str)
! {
!   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVFX);
! }
! 
! static void
! do_mav_binops_1i (char * str)
! {
!   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVFX);
! }
! 
! static void
! do_mav_binops_1j (char * str)
! {
!   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVDX);
! }
! 
! static void
! do_mav_binops_1k (char * str)
! {
!   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVDX);
! }
! 
! static void
! do_mav_binops_1l (char * str)
! {
!   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVF);
! }
! 
! static void
! do_mav_binops_1m (char * str)
! {
!   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVD);
! }
! 
! static void
! do_mav_binops_1n (char * str)
! {
!   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVFX);
! }
! 
! static void
! do_mav_binops_1o (char * str)
! {
!   do_mav_binops (str, MAV_MODE1, REG_TYPE_MVDX, REG_TYPE_MVDX);
! }
! 
! static void
! do_mav_binops_2a (char * str)
! {
!   do_mav_binops (str, MAV_MODE2, REG_TYPE_MVF, REG_TYPE_RN);
! }
! 
! static void
! do_mav_binops_2b (char * str)
! {
!   do_mav_binops (str, MAV_MODE2, REG_TYPE_MVD, REG_TYPE_RN);
! }
  
! static void
! do_mav_binops_2c (char * str)
! {
!   do_mav_binops (str, MAV_MODE2, REG_TYPE_MVDX, REG_TYPE_RN);
! }
  
  static void
! do_mav_binops_3a (char * str)
  {
!   do_mav_binops (str, MAV_MODE3, REG_TYPE_MVAX, REG_TYPE_MVFX);
  }
  
  static void
! do_mav_binops_3b (char * str)
  {
!   do_mav_binops (str, MAV_MODE3, REG_TYPE_MVFX, REG_TYPE_MVAX);
  }
  
  static void
! do_mav_binops_3c (char * str)
  {
!   do_mav_binops (str, MAV_MODE3, REG_TYPE_MVAX, REG_TYPE_MVDX);
  }
  
  static void
! do_mav_binops_3d (char * str)
  {
!   do_mav_binops (str, MAV_MODE3, REG_TYPE_MVDX, REG_TYPE_MVAX);
  }
  
  static void
! do_mav_triple_4a (char * str)
  {
!   do_mav_triple (str, MAV_MODE4, REG_TYPE_MVFX, REG_TYPE_MVFX, REG_TYPE_RN);
  }
  
  static void
! do_mav_triple_4b (char * str)
  {
!   do_mav_triple (str, MAV_MODE4, REG_TYPE_MVDX, REG_TYPE_MVDX, REG_TYPE_RN);
  }
  
  static void
! do_mav_triple_5a (char * str)
  {
!   do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVF, REG_TYPE_MVF);
  }
  
  static void
! do_mav_triple_5b (char * str)
  {
!   do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVD, REG_TYPE_MVD);
  }
  
  static void
! do_mav_triple_5c (char * str)
  {
!   do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVFX, REG_TYPE_MVFX);
  }
  
  static void
! do_mav_triple_5d (char * str)
  {
!   do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVDX, REG_TYPE_MVDX);
  }
  
  static void
! do_mav_triple_5e (char * str)
  {
!   do_mav_triple (str, MAV_MODE5, REG_TYPE_MVF, REG_TYPE_MVF, REG_TYPE_MVF);
  }
  
  static void
! do_mav_triple_5f (char * str)
  {
!   do_mav_triple (str, MAV_MODE5, REG_TYPE_MVD, REG_TYPE_MVD, REG_TYPE_MVD);
  }
  
  static void
! do_mav_triple_5g (char * str)
  {
!   do_mav_triple (str, MAV_MODE5, REG_TYPE_MVFX, REG_TYPE_MVFX, REG_TYPE_MVFX);
  }
  
  static void
! do_mav_triple_5h (char * str)
  {
!   do_mav_triple (str, MAV_MODE5, REG_TYPE_MVDX, REG_TYPE_MVDX, REG_TYPE_MVDX);
  }
  
+ /* Isnsn like "foo W,X,Y,Z".
+     where W=MVAX[0:3] and X,Y,Z=MVFX[0:15].  */
+ 
  static void
! do_mav_quad (char * str,
! 	     int mode,
! 	     enum arm_reg_type reg0,
! 	     enum arm_reg_type reg1,
! 	     enum arm_reg_type reg2,
! 	     enum arm_reg_type reg3)
  {
!   int shift0, shift1, shift2, shift3;
! 
!   shift0= mode & 0xff;
!   shift1 = (mode >> 8) & 0xff;
!   shift2 = (mode >> 16) & 0xff;
!   shift3 = (mode >> 24) & 0xff;
! 
!   skip_whitespace (str);
! 
!   if (mav_reg_required_here (&str, shift0, reg0) == FAIL
!       || skip_past_comma (&str) == FAIL
!       || mav_reg_required_here (&str, shift1, reg1) == FAIL
!       || skip_past_comma (&str) == FAIL
!       || mav_reg_required_here (&str, shift2, reg2) == FAIL
!       || skip_past_comma (&str) == FAIL
!       || mav_reg_required_here (&str, shift3, reg3) == FAIL)
!     {
!       if (!inst.error)
! 	inst.error = BAD_ARGS;
!     }
!   else
!     end_of_line (str);
  }
  
  static void
! do_mav_quad_6a (char * str)
  {
!   do_mav_quad (str, MAV_MODE6, REG_TYPE_MVAX, REG_TYPE_MVFX, REG_TYPE_MVFX,
! 	       REG_TYPE_MVFX);
  }
  
  static void
! do_mav_quad_6b (char * str)
  {
!   do_mav_quad (str, MAV_MODE6, REG_TYPE_MVAX, REG_TYPE_MVAX, REG_TYPE_MVFX,
! 	       REG_TYPE_MVFX);
  }
  
+ /* cfmvsc32<cond> DSPSC,MVDX[15:0].  */
  static void
! do_mav_dspsc_1 (char * str)
  {
!   skip_whitespace (str);
! 
!   /* cfmvsc32.  */
!   if (mav_reg_required_here (&str, -1, REG_TYPE_DSPSC) == FAIL
!       || skip_past_comma (&str) == FAIL
!       || mav_reg_required_here (&str, 12, REG_TYPE_MVDX) == FAIL)
!     {
!       if (!inst.error)
! 	inst.error = BAD_ARGS;
! 
!       return;
!     }
! 
!   end_of_line (str);
  }
  
+ /* cfmv32sc<cond> MVDX[15:0],DSPSC.  */
  static void
! do_mav_dspsc_2 (char * str)
  {
!   skip_whitespace (str);
! 
!   /* cfmv32sc.  */
!   if (mav_reg_required_here (&str, 12, REG_TYPE_MVDX) == FAIL
!       || skip_past_comma (&str) == FAIL
!       || mav_reg_required_here (&str, -1, REG_TYPE_DSPSC) == FAIL)
!     {
!       if (!inst.error)
! 	inst.error = BAD_ARGS;
! 
!       return;
!     }
! 
!   end_of_line (str);
  }
  
+ /* Maverick shift immediate instructions.
+    cfsh32<cond> MVFX[15:0],MVFX[15:0],Shift[6:0].
+    cfsh64<cond> MVDX[15:0],MVDX[15:0],Shift[6:0].  */
+ 
  static void
! do_mav_shift (char * str,
! 	      enum arm_reg_type reg0,
! 	      enum arm_reg_type reg1)
  {
!   int error;
!   int imm, neg = 0;
! 
!   skip_whitespace (str);
! 
!   error = 0;
! 
!   if (mav_reg_required_here (&str, 12, reg0) == FAIL
!       || skip_past_comma (&str) == FAIL
!       || mav_reg_required_here (&str, 16, reg1) == FAIL
!       || skip_past_comma  (&str) == FAIL)
!     {
!       if (!inst.error)
! 	inst.error = BAD_ARGS;
!       return;
!     }
! 
!   /* Calculate the immediate operand.
!      The operand is a 7bit signed number.  */
!   skip_whitespace (str);
! 
!   if (*str == '#')
!     ++str;
! 
!   if (!ISDIGIT (*str) && *str != '-')
!     {
!       inst.error = _("expecting immediate, 7bit operand");
!       return;
!     }
! 
!   if (*str == '-')
!     {
!       neg = 1;
!       ++str;
!     }
! 
!   for (imm = 0; *str && ISDIGIT (*str); ++str)
!     imm = imm * 10 + *str - '0';
! 
!   if (imm > 64)
!     {
!       inst.error = _("immediate out of range");
!       return;
!     }
! 
!   /* Make negative imm's into 7bit signed numbers.  */
!   if (neg)
!     {
!       imm = -imm;
!       imm &= 0x0000007f;
!     }
! 
!   /* Bits 0-3 of the insn should have bits 0-3 of the immediate.
!      Bits 5-7 of the insn should have bits 4-6 of the immediate.
!      Bit 4 should be 0.  */
!   imm = (imm & 0xf) | ((imm & 0x70) << 1);
! 
!   inst.instruction |= imm;
!   end_of_line (str);
  }
  
  static void
! do_mav_shift_1 (char * str)
  {
!   do_mav_shift (str, REG_TYPE_MVFX, REG_TYPE_MVFX);
  }
  
  static void
! do_mav_shift_2 (char * str)
  {
!   do_mav_shift (str, REG_TYPE_MVDX, REG_TYPE_MVDX);
! }
! 
! static int
! mav_parse_offset (char ** str, int * negative)
! {
!   char * p = *str;
!   int offset;
! 
!   *negative = 0;
! 
!   skip_whitespace (p);
! 
!   if (*p == '#')
!     ++p;
! 
!   if (*p == '-')
!     {
!       *negative = 1;
!       ++p;
!     }
! 
!   if (!ISDIGIT (*p))
!     {
!       inst.error = _("offset expected");
!       return 0;
!     }
! 
!   for (offset = 0; *p && ISDIGIT (*p); ++p)
!     offset = offset * 10 + *p - '0';
! 
!   if (offset > 0x3fc)
!     {
!       inst.error = _("offset out of range");
!       return 0;
!     }
!   if (offset & 0x3)
!     {
!       inst.error = _("offset not a multiple of 4");
!       return 0;
!     }
! 
!   *str = p;
! 
!   return *negative ? -offset : offset;
  }
  
! /* Maverick load/store instructions.
!   <insn><cond> CRd,[Rn,<offset>]{!}.
!   <insn><cond> CRd,[Rn],<offset>.  */
! 
! static void
! do_mav_ldst (char * str, enum arm_reg_type reg0)
! {
!   int offset, negative;
! 
!   skip_whitespace (str);
! 
!   if (mav_reg_required_here (&str, 12, reg0) == FAIL
!       || skip_past_comma (&str) == FAIL
!       || *str++ != '['
!       || reg_required_here (&str, 16) == FAIL)
!     goto fail_ldst;
! 
!   if (skip_past_comma (&str) == SUCCESS)
!     {
!       /* You are here: "<offset>]{!}".  */
!       inst.instruction |= PRE_INDEX;
! 
!       offset = mav_parse_offset (&str, &negative);
! 
!       if (inst.error)
! 	return;
! 
!       if (*str++ != ']')
! 	{
! 	  inst.error = _("missing ]");
! 	  return;
! 	}
! 
!       if (*str == '!')
! 	{
! 	  inst.instruction |= WRITE_BACK;
! 	  ++str;
! 	}
!     }
!   else
!     {
!       /* You are here: "], <offset>".  */
!       if (*str++ != ']')
! 	{
! 	  inst.error = _("missing ]");
! 	  return;
! 	}
! 
!       if (skip_past_comma (&str) == FAIL
! 	  || (offset = mav_parse_offset (&str, &negative), inst.error))
! 	goto fail_ldst;
  
!       inst.instruction |= CP_T_WB; /* Post indexed, set bit W.  */
!     }
  
!   if (negative)
!     offset = -offset;
!   else
!     inst.instruction |= CP_T_UD; /* Positive, so set bit U.  */
  
!   inst.instruction |= offset >> 2;
!   end_of_line (str);
!   return;
  
! fail_ldst:
!   if (!inst.error)
!      inst.error = BAD_ARGS;
  }
  
  static void
! do_mav_ldst_1 (char * str)
  {
!   do_mav_ldst (str, REG_TYPE_MVF);
  }
  
  static void
! do_mav_ldst_2 (char * str)
  {
!   do_mav_ldst (str, REG_TYPE_MVD);
  }
  
  static void
! do_mav_ldst_3 (char * str)
  {
!   do_mav_ldst (str, REG_TYPE_MVFX);
  }
  
  static void
! do_mav_ldst_4 (char * str)
  {
!   do_mav_ldst (str, REG_TYPE_MVDX);
  }
  
  static void
! do_t_nop (char * str)
  {
!   /* Do nothing.  */
!   end_of_line (str);
  }
  
! /* Handle the Format 4 instructions that do not have equivalents in other
!    formats.  That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
!    BIC and MVN.  */
  
  static void
! do_t_arit (char * str)
  {
!   int Rd, Rs, Rn;
  
    skip_whitespace (str);
  
!   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
        || skip_past_comma (&str) == FAIL
!       || (Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
      {
!       inst.error = BAD_ARGS;
        return;
      }
  
!   if (skip_past_comma (&str) != FAIL)
      {
!       /* Three operand format not allowed for TST, CMN, NEG and MVN.
! 	 (It isn't allowed for CMP either, but that isn't handled by this
! 	 function.)  */
!       if (inst.instruction == T_OPCODE_TST
! 	  || inst.instruction == T_OPCODE_CMN
! 	  || inst.instruction == T_OPCODE_NEG
! 	  || inst.instruction == T_OPCODE_MVN)
! 	{
! 	  inst.error = BAD_ARGS;
! 	  return;
! 	}
  
!       if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
! 	return;
! 
!       if (Rs != Rd)
! 	{
! 	  inst.error = _("dest and source1 must be the same register");
! 	  return;
! 	}
!       Rs = Rn;
      }
  
+   if (inst.instruction == T_OPCODE_MUL
+       && Rs == Rd)
+     as_tsktsk (_("Rs and Rd must be different in MUL"));
+ 
+   inst.instruction |= Rd | (Rs << 3);
    end_of_line (str);
  }
  
  static void
! do_t_add (char * str)
  {
!   thumb_add_sub (str, 0);
  }
  
  static void
! do_t_asr (char * str)
  {
!   thumb_shift (str, THUMB_ASR);
  }
  
  static void
! do_t_branch9 (char * str)
  {
!   if (my_get_expression (&inst.reloc.exp, &str))
!     return;
!   inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH9;
!   inst.reloc.pc_rel = 1;
!   end_of_line (str);
  }
  
  static void
! do_t_branch12 (char * str)
  {
!   if (my_get_expression (&inst.reloc.exp, &str))
!     return;
!   inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH12;
!   inst.reloc.pc_rel = 1;
!   end_of_line (str);
  }
  
! /* Find the real, Thumb encoded start of a Thumb function.  */
  
! static symbolS *
! find_real_start (symbolS * symbolP)
  {
!   char *       real_start;
!   const char * name = S_GET_NAME (symbolP);
!   symbolS *    new_target;
  
!   /* This definition must agree with the one in gcc/config/arm/thumb.c.  */
! #define STUB_NAME ".real_start_of"
  
!   if (name == NULL)
!     abort ();
  
!   /* Names that start with '.' are local labels, not function entry points.
!      The compiler may generate BL instructions to these labels because it
!      needs to perform a branch to a far away location.  */
!   if (name[0] == '.')
!     return symbolP;
  
!   real_start = malloc (strlen (name) + strlen (STUB_NAME) + 1);
!   sprintf (real_start, "%s%s", STUB_NAME, name);
  
!   new_target = symbol_find (real_start);
! 
!   if (new_target == NULL)
      {
!       as_warn ("Failed to find real start of function: %s\n", name);
!       new_target = symbolP;
      }
  
!   free (real_start);
! 
!   return new_target;
! }
  
  static void
! do_t_branch23 (char * str)
  {
!   if (my_get_expression (& inst.reloc.exp, & str))
!     return;
  
!   inst.reloc.type   = BFD_RELOC_THUMB_PCREL_BRANCH23;
!   inst.reloc.pc_rel = 1;
!   end_of_line (str);
  
!   /* If the destination of the branch is a defined symbol which does not have
!      the THUMB_FUNC attribute, then we must be calling a function which has
!      the (interfacearm) attribute.  We look for the Thumb entry point to that
!      function and change the branch to refer to that function instead.  */
!   if (   inst.reloc.exp.X_op == O_symbol
!       && inst.reloc.exp.X_add_symbol != NULL
!       && S_IS_DEFINED (inst.reloc.exp.X_add_symbol)
!       && ! THUMB_IS_FUNC (inst.reloc.exp.X_add_symbol))
!     inst.reloc.exp.X_add_symbol =
!       find_real_start (inst.reloc.exp.X_add_symbol);
  }
  
  static void
! do_t_bx (char * str)
  {
!   int reg;
  
    skip_whitespace (str);
  
!   if ((reg = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
!     return;
! 
!   /* This sets THUMB_H2 from the top bit of reg.  */
!   inst.instruction |= reg << 3;
! 
!   /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC.  The reloc
!      should cause the alignment to be checked once it is known.  This is
!      because BX PC only works if the instruction is word aligned.  */
! 
!   end_of_line (str);
  }
  
! static void
! do_t_compare (char * str)
! {
!   thumb_mov_compare (str, THUMB_COMPARE);
! }
  
  static void
! do_t_ldmstm (char * str)
  {
!   int Rb;
!   long range;
  
    skip_whitespace (str);
  
!   if ((Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
!     return;
  
!   if (*str != '!')
!     as_warn (_("inserted missing '!': load/store multiple always writes back base register"));
!   else
!     str++;
! 
!   if (skip_past_comma (&str) == FAIL
!       || (range = reg_list (&str)) == FAIL)
      {
!       if (! inst.error)
  	inst.error = BAD_ARGS;
        return;
      }
  
!   if (inst.reloc.type != BFD_RELOC_NONE)
      {
!       /* This really doesn't seem worth it.  */
!       inst.reloc.type = BFD_RELOC_NONE;
!       inst.error = _("expression too complex");
        return;
      }
  
!   if (range & ~0xff)
      {
!       inst.error = _("only lo-regs valid in load/store multiple");
        return;
      }
  
!   inst.instruction |= (Rb << 8) | range;
    end_of_line (str);
  }
  
! static void
! do_t_ldr (char * str)
  {
!   thumb_load_store (str, THUMB_LOAD, THUMB_WORD);
! }
  
! static void
! do_t_ldrb (char * str)
! {
!   thumb_load_store (str, THUMB_LOAD, THUMB_BYTE);
! }
  
! static void
! do_t_ldrh (char * str)
! {
!   thumb_load_store (str, THUMB_LOAD, THUMB_HALFWORD);
! }
  
! static void
! do_t_lds (char * str)
! {
!   int Rd, Rb, Ro;
  
!   skip_whitespace (str);
  
!   if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
!       || skip_past_comma (&str) == FAIL
!       || *str++ != '['
!       || (Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL
!       || skip_past_comma (&str) == FAIL
!       || (Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL
!       || *str++ != ']')
      {
!       if (! inst.error)
! 	inst.error = _("syntax: ldrs[b] Rd, [Rb, Ro]");
!       return;
      }
  
!   inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
!   end_of_line (str);
! }
  
! static void
! do_t_lsl (char * str)
! {
!   thumb_shift (str, THUMB_LSL);
! }
  
! static void
! do_t_lsr (char * str)
! {
!   thumb_shift (str, THUMB_LSR);
  }
  
! static void
! do_t_mov (char * str)
! {
!   thumb_mov_compare (str, THUMB_MOVE);
! }
  
  static void
! do_t_push_pop (char * str)
  {
!   long range;
  
    skip_whitespace (str);
  
!   if ((range = reg_list (&str)) == FAIL)
      {
!       if (! inst.error)
! 	inst.error = BAD_ARGS;
!       return;
!     }
  
!   if (inst.reloc.type != BFD_RELOC_NONE)
!     {
!       /* This really doesn't seem worth it.  */
!       inst.reloc.type = BFD_RELOC_NONE;
!       inst.error = _("expression too complex");
!       return;
!     }
  
!   if (range & ~0xff)
!     {
!       if ((inst.instruction == T_OPCODE_PUSH
! 	   && (range & ~0xff) == 1 << REG_LR)
! 	  || (inst.instruction == T_OPCODE_POP
! 	      && (range & ~0xff) == 1 << REG_PC))
  	{
! 	  inst.instruction |= THUMB_PP_PC_LR;
! 	  range &= 0xff;
  	}
!       else
  	{
! 	  inst.error = _("invalid register list to push/pop instruction");
  	  return;
  	}
      }
  
!   inst.instruction |= range;
    end_of_line (str);
! }
  
! static void
! do_t_str (char * str)
! {
!   thumb_load_store (str, THUMB_STORE, THUMB_WORD);
  }
  
  static void
! do_t_strb (char * str)
  {
!   thumb_load_store (str, THUMB_STORE, THUMB_BYTE);
  }
  
! static void
! do_t_strh (char * str)
! {
!   thumb_load_store (str, THUMB_STORE, THUMB_HALFWORD);
! }
  
  static void
! do_t_sub (char * str)
  {
!   thumb_add_sub (str, 1);
! }
  
+ static void
+ do_t_swi (char * str)
+ {
    skip_whitespace (str);
  
!   if (my_get_expression (&inst.reloc.exp, &str))
!     return;
  
!   inst.reloc.type = BFD_RELOC_ARM_SWI;
!   end_of_line (str);
! }
  
! static void
! do_t_adr (char * str)
! {
!   int reg;
  
!   /* This is a pseudo-op of the form "adr rd, label" to be converted
!      into a relative address of the form "add rd, pc, #label-.-4".  */
!   skip_whitespace (str);
! 
!   /* Store Rd in temporary location inside instruction.  */
!   if ((reg = reg_required_here (&str, 4)) == FAIL
!       || (reg > 7)  /* For Thumb reg must be r0..r7.  */
!       || skip_past_comma (&str) == FAIL
!       || my_get_expression (&inst.reloc.exp, &str))
!     {
!       if (!inst.error)
! 	inst.error = BAD_ARGS;
!       return;
      }
  
!   inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
!   inst.reloc.exp.X_add_number -= 4; /* PC relative adjust.  */
!   inst.reloc.pc_rel = 1;
!   inst.instruction |= REG_PC; /* Rd is already placed into the instruction.  */
  
    end_of_line (str);
  }
  
  static void
! insert_reg (const struct reg_entry * r,
! 	    struct hash_control * htab)
  {
!   int    len  = strlen (r->name) + 2;
!   char * buf  = xmalloc (len);
!   char * buf2 = xmalloc (len);
!   int    i    = 0;
  
! #ifdef REGISTER_PREFIX
!   buf[i++] = REGISTER_PREFIX;
! #endif
! 
!   strcpy (buf + i, r->name);
! 
!   for (i = 0; buf[i]; i++)
!     buf2[i] = TOUPPER (buf[i]);
! 
!   buf2[i] = '\0';
! 
!   hash_insert (htab, buf,  (PTR) r);
!   hash_insert (htab, buf2, (PTR) r);
  }
  
  static void
! build_reg_hsh (struct reg_map * map)
  {
!   const struct reg_entry *r;
! 
!   if ((map->htab = hash_new ()) == NULL)
!     as_fatal (_("virtual memory exhausted"));
! 
!   for (r = map->names; r->name != NULL; r++)
!     insert_reg (r, map->htab);
  }
  
  static void
! insert_reg_alias (char * str,
! 		  int regnum,
! 		  struct hash_control *htab)
! {
!   const char * error;
!   struct reg_entry * new = xmalloc (sizeof (struct reg_entry));
!   const char * name = xmalloc (strlen (str) + 1);
! 
!   strcpy ((char *) name, str);
! 
!   new->name = name;
!   new->number = regnum;
!   new->builtin = FALSE;
! 
!   error = hash_insert (htab, name, (PTR) new);
!   if (error)
!     {
!       as_bad (_("failed to create an alias for %s, reason: %s"),
! 	    str, error);
!       free ((char *) name);
!       free (new);
!     }
  }
  
! /* Look for the .req directive.  This is of the form:
  
!    	new_register_name .req existing_register_name
! 
!    If we find one, or if it looks sufficiently like one that we want to
!    handle any error here, return non-zero.  Otherwise return zero.  */
! 
! static int
! create_register_alias (char * newname, char * p)
  {
!   char * q;
!   char c;
  
!   q = p;
!   skip_whitespace (q);
  
!   c = *p;
!   *p = '\0';
  
!   if (*q && !strncmp (q, ".req ", 5))
!     {
!       char *copy_of_str;
!       char *r;
  
! #ifndef IGNORE_OPCODE_CASE
!       newname = original_case_string;
! #endif
!       copy_of_str = newname;
  
!       q += 4;
!       skip_whitespace (q);
  
!       for (r = q; *r != '\0'; r++)
! 	if (*r == ' ')
! 	  break;
  
!       if (r != q)
! 	{
! 	  enum arm_reg_type new_type, old_type;
! 	  int old_regno;
! 	  char d = *r;
  
! 	  *r = '\0';
! 	  old_type = arm_reg_parse_any (q);
! 	  *r = d;
! 
! 	  new_type = arm_reg_parse_any (newname);
! 
! 	  if (new_type == REG_TYPE_MAX)
! 	    {
! 	      if (old_type != REG_TYPE_MAX)
! 		{
! 		  old_regno = arm_reg_parse (&q, all_reg_maps[old_type].htab);
! 		  insert_reg_alias (newname, old_regno,
! 				    all_reg_maps[old_type].htab);
! 		}
! 	      else
! 		as_warn (_("register '%s' does not exist\n"), q);
! 	    }
! 	  else if (old_type == REG_TYPE_MAX)
! 	    {
! 	      as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
! 		       copy_of_str, q);
! 	    }
! 	  else
! 	    {
! 	      /* Do not warn about redefinitions to the same alias.  */
! 	      if (new_type != old_type
! 		  || (arm_reg_parse (&q, all_reg_maps[old_type].htab)
! 		      != arm_reg_parse (&q, all_reg_maps[new_type].htab)))
! 		as_warn (_("ignoring redefinition of register alias '%s'"),
! 			 copy_of_str);
! 
! 	    }
! 	}
!       else
! 	as_warn (_("ignoring incomplete .req pseuso op"));
! 
!       *p = c;
!       return 1;
!     }
! 
!   *p = c;
!   return 0;
  }
  
  static void
! set_constant_flonums (void)
  {
!   int i;
  
!   for (i = 0; i < NUM_FLOAT_VALS; i++)
!     if (atof_ieee ((char *) fp_const[i], 'x', fp_values[i]) == NULL)
!       abort ();
  }
  
! 
! static const struct asm_opcode insns[] =
  {
!   /* Core ARM Instructions.  */
!   {"and",        0xe0000000, 3,  ARM_EXT_V1,       do_arit},
!   {"ands",       0xe0100000, 3,  ARM_EXT_V1,       do_arit},
!   {"eor",        0xe0200000, 3,  ARM_EXT_V1,       do_arit},
!   {"eors",       0xe0300000, 3,  ARM_EXT_V1,       do_arit},
!   {"sub",        0xe0400000, 3,  ARM_EXT_V1,       do_arit},
!   {"subs",       0xe0500000, 3,  ARM_EXT_V1,       do_arit},
!   {"rsb",        0xe0600000, 3,  ARM_EXT_V1,       do_arit},
!   {"rsbs",       0xe0700000, 3,  ARM_EXT_V1,       do_arit},
!   {"add",        0xe0800000, 3,  ARM_EXT_V1,       do_arit},
!   {"adds",       0xe0900000, 3,  ARM_EXT_V1,       do_arit},
!   {"adc",        0xe0a00000, 3,  ARM_EXT_V1,       do_arit},
!   {"adcs",       0xe0b00000, 3,  ARM_EXT_V1,       do_arit},
!   {"sbc",        0xe0c00000, 3,  ARM_EXT_V1,       do_arit},
!   {"sbcs",       0xe0d00000, 3,  ARM_EXT_V1,       do_arit},
!   {"rsc",        0xe0e00000, 3,  ARM_EXT_V1,       do_arit},
!   {"rscs",       0xe0f00000, 3,  ARM_EXT_V1,       do_arit},
!   {"orr",        0xe1800000, 3,  ARM_EXT_V1,       do_arit},
!   {"orrs",       0xe1900000, 3,  ARM_EXT_V1,       do_arit},
!   {"bic",        0xe1c00000, 3,  ARM_EXT_V1,       do_arit},
!   {"bics",       0xe1d00000, 3,  ARM_EXT_V1,       do_arit},
! 
!   {"tst",        0xe1100000, 3,  ARM_EXT_V1,       do_cmp},
!   {"tsts",       0xe1100000, 3,  ARM_EXT_V1,       do_cmp},
!   {"tstp",       0xe110f000, 3,  ARM_EXT_V1,       do_cmp},
!   {"teq",        0xe1300000, 3,  ARM_EXT_V1,       do_cmp},
!   {"teqs",       0xe1300000, 3,  ARM_EXT_V1,       do_cmp},
!   {"teqp",       0xe130f000, 3,  ARM_EXT_V1,       do_cmp},
!   {"cmp",        0xe1500000, 3,  ARM_EXT_V1,       do_cmp},
!   {"cmps",       0xe1500000, 3,  ARM_EXT_V1,       do_cmp},
!   {"cmpp",       0xe150f000, 3,  ARM_EXT_V1,       do_cmp},
!   {"cmn",        0xe1700000, 3,  ARM_EXT_V1,       do_cmp},
!   {"cmns",       0xe1700000, 3,  ARM_EXT_V1,       do_cmp},
!   {"cmnp",       0xe170f000, 3,  ARM_EXT_V1,       do_cmp},
! 
!   {"mov",        0xe1a00000, 3,  ARM_EXT_V1,       do_mov},
!   {"movs",       0xe1b00000, 3,  ARM_EXT_V1,       do_mov},
!   {"mvn",        0xe1e00000, 3,  ARM_EXT_V1,       do_mov},
!   {"mvns",       0xe1f00000, 3,  ARM_EXT_V1,       do_mov},
! 
!   {"ldr",        0xe4100000, 3,  ARM_EXT_V1,       do_ldst},
!   {"ldrb",       0xe4500000, 3,  ARM_EXT_V1,       do_ldst},
!   {"ldrt",       0xe4300000, 3,  ARM_EXT_V1,       do_ldstt},
!   {"ldrbt",      0xe4700000, 3,  ARM_EXT_V1,       do_ldstt},
!   {"str",        0xe4000000, 3,  ARM_EXT_V1,       do_ldst},
!   {"strb",       0xe4400000, 3,  ARM_EXT_V1,       do_ldst},
!   {"strt",       0xe4200000, 3,  ARM_EXT_V1,       do_ldstt},
!   {"strbt",      0xe4600000, 3,  ARM_EXT_V1,       do_ldstt},
! 
!   {"stmia",      0xe8800000, 3,  ARM_EXT_V1,       do_ldmstm},
!   {"stmib",      0xe9800000, 3,  ARM_EXT_V1,       do_ldmstm},
!   {"stmda",      0xe8000000, 3,  ARM_EXT_V1,       do_ldmstm},
!   {"stmdb",      0xe9000000, 3,  ARM_EXT_V1,       do_ldmstm},
!   {"stmfd",      0xe9000000, 3,  ARM_EXT_V1,       do_ldmstm},
!   {"stmfa",      0xe9800000, 3,  ARM_EXT_V1,       do_ldmstm},
!   {"stmea",      0xe8800000, 3,  ARM_EXT_V1,       do_ldmstm},
!   {"stmed",      0xe8000000, 3,  ARM_EXT_V1,       do_ldmstm},
! 
!   {"ldmia",      0xe8900000, 3,  ARM_EXT_V1,       do_ldmstm},
!   {"ldmib",      0xe9900000, 3,  ARM_EXT_V1,       do_ldmstm},
!   {"ldmda",      0xe8100000, 3,  ARM_EXT_V1,       do_ldmstm},
!   {"ldmdb",      0xe9100000, 3,  ARM_EXT_V1,       do_ldmstm},
!   {"ldmfd",      0xe8900000, 3,  ARM_EXT_V1,       do_ldmstm},
!   {"ldmfa",      0xe8100000, 3,  ARM_EXT_V1,       do_ldmstm},
!   {"ldmea",      0xe9100000, 3,  ARM_EXT_V1,       do_ldmstm},
!   {"ldmed",      0xe9900000, 3,  ARM_EXT_V1,       do_ldmstm},
  
!   {"swi",        0xef000000, 3,  ARM_EXT_V1,       do_swi},
! #ifdef TE_WINCE
!   /* XXX This is the wrong place to do this.  Think multi-arch.  */
!   {"bl",         0xeb000000, 2,  ARM_EXT_V1,       do_branch},
!   {"b",          0xea000000, 1,  ARM_EXT_V1,       do_branch},
! #else
!   {"bl",         0xebfffffe, 2,  ARM_EXT_V1,       do_branch},
!   {"b",          0xeafffffe, 1,  ARM_EXT_V1,       do_branch},
! #endif
  
!   /* Pseudo ops.  */
!   {"adr",        0xe28f0000, 3,  ARM_EXT_V1,       do_adr},
!   {"adrl",       0xe28f0000, 3,  ARM_EXT_V1,       do_adrl},
!   {"nop",        0xe1a00000, 3,  ARM_EXT_V1,       do_empty},
  
!   /* ARM 2 multiplies.  */
!   {"mul",        0xe0000090, 3,  ARM_EXT_V2,       do_mul},
!   {"muls",       0xe0100090, 3,  ARM_EXT_V2,       do_mul},
!   {"mla",        0xe0200090, 3,  ARM_EXT_V2,       do_mla},
!   {"mlas",       0xe0300090, 3,  ARM_EXT_V2,       do_mla},
  
!   /* Generic coprocessor instructions.  */
!   {"cdp",        0xee000000, 3,  ARM_EXT_V2,       do_cdp},
!   {"ldc",        0xec100000, 3,  ARM_EXT_V2,       do_lstc},
!   {"ldcl",       0xec500000, 3,  ARM_EXT_V2,       do_lstc},
!   {"stc",        0xec000000, 3,  ARM_EXT_V2,       do_lstc},
!   {"stcl",       0xec400000, 3,  ARM_EXT_V2,       do_lstc},
!   {"mcr",        0xee000010, 3,  ARM_EXT_V2,       do_co_reg},
!   {"mrc",        0xee100010, 3,  ARM_EXT_V2,       do_co_reg},
  
!   /* ARM 3 - swp instructions.  */
!   {"swp",        0xe1000090, 3,  ARM_EXT_V2S,      do_swap},
!   {"swpb",       0xe1400090, 3,  ARM_EXT_V2S,      do_swap},
  
!   /* ARM 6 Status register instructions.  */
!   {"mrs",        0xe10f0000, 3,  ARM_EXT_V3,       do_mrs},
!   {"msr",        0xe120f000, 3,  ARM_EXT_V3,       do_msr},
!   /* ScottB: our code uses     0xe128f000 for msr.
!      NickC:  but this is wrong because the bits 16 through 19 are
!              handled by the PSR_xxx defines above.  */
  
!   /* ARM 7M long multiplies.  */
!   {"smull",      0xe0c00090, 5,  ARM_EXT_V3M,      do_mull},
!   {"smulls",     0xe0d00090, 5,  ARM_EXT_V3M,      do_mull},
!   {"umull",      0xe0800090, 5,  ARM_EXT_V3M,      do_mull},
!   {"umulls",     0xe0900090, 5,  ARM_EXT_V3M,      do_mull},
!   {"smlal",      0xe0e00090, 5,  ARM_EXT_V3M,      do_mull},
!   {"smlals",     0xe0f00090, 5,  ARM_EXT_V3M,      do_mull},
!   {"umlal",      0xe0a00090, 5,  ARM_EXT_V3M,      do_mull},
!   {"umlals",     0xe0b00090, 5,  ARM_EXT_V3M,      do_mull},
  
!   /* ARM Architecture 4.  */
!   {"ldrh",       0xe01000b0, 3,  ARM_EXT_V4,       do_ldstv4},
!   {"ldrsh",      0xe01000f0, 3,  ARM_EXT_V4,       do_ldstv4},
!   {"ldrsb",      0xe01000d0, 3,  ARM_EXT_V4,       do_ldstv4},
!   {"strh",       0xe00000b0, 3,  ARM_EXT_V4,       do_ldstv4},
  
!   /* ARM Architecture 4T.  */
!   /* Note: bx (and blx) are required on V5, even if the processor does
!      not support Thumb.  */
!   {"bx",         0xe12fff10, 2,  ARM_EXT_V4T | ARM_EXT_V5, do_bx},
  
!   /*  ARM Architecture 5T.  */
!   /* Note: blx has 2 variants, so the .value is set dynamically.
!      Only one of the variants has conditional execution.  */
!   {"blx",        0xe0000000, 3,  ARM_EXT_V5,       do_blx},
!   {"clz",        0xe16f0f10, 3,  ARM_EXT_V5,       do_clz},
!   {"bkpt",       0xe1200070, 0,  ARM_EXT_V5,       do_bkpt},
!   {"ldc2",       0xfc100000, 0,  ARM_EXT_V5,       do_lstc2},
!   {"ldc2l",      0xfc500000, 0,  ARM_EXT_V5,       do_lstc2},
!   {"stc2",       0xfc000000, 0,  ARM_EXT_V5,       do_lstc2},
!   {"stc2l",      0xfc400000, 0,  ARM_EXT_V5,       do_lstc2},
!   {"cdp2",       0xfe000000, 0,  ARM_EXT_V5,       do_cdp2},
!   {"mcr2",       0xfe000010, 0,  ARM_EXT_V5,       do_co_reg2},
!   {"mrc2",       0xfe100010, 0,  ARM_EXT_V5,       do_co_reg2},
  
!   /*  ARM Architecture 5TExP.  */
!   {"smlabb",     0xe1000080, 6,  ARM_EXT_V5ExP,    do_smla},
!   {"smlatb",     0xe10000a0, 6,  ARM_EXT_V5ExP,    do_smla},
!   {"smlabt",     0xe10000c0, 6,  ARM_EXT_V5ExP,    do_smla},
!   {"smlatt",     0xe10000e0, 6,  ARM_EXT_V5ExP,    do_smla},
  
!   {"smlawb",     0xe1200080, 6,  ARM_EXT_V5ExP,    do_smla},
!   {"smlawt",     0xe12000c0, 6,  ARM_EXT_V5ExP,    do_smla},
  
!   {"smlalbb",    0xe1400080, 7,  ARM_EXT_V5ExP,    do_smlal},
!   {"smlaltb",    0xe14000a0, 7,  ARM_EXT_V5ExP,    do_smlal},
!   {"smlalbt",    0xe14000c0, 7,  ARM_EXT_V5ExP,    do_smlal},
!   {"smlaltt",    0xe14000e0, 7,  ARM_EXT_V5ExP,    do_smlal},
  
!   {"smulbb",     0xe1600080, 6,  ARM_EXT_V5ExP,    do_smul},
!   {"smultb",     0xe16000a0, 6,  ARM_EXT_V5ExP,    do_smul},
!   {"smulbt",     0xe16000c0, 6,  ARM_EXT_V5ExP,    do_smul},
!   {"smultt",     0xe16000e0, 6,  ARM_EXT_V5ExP,    do_smul},
  
!   {"smulwb",     0xe12000a0, 6,  ARM_EXT_V5ExP,    do_smul},
!   {"smulwt",     0xe12000e0, 6,  ARM_EXT_V5ExP,    do_smul},
  
!   {"qadd",       0xe1000050, 4,  ARM_EXT_V5ExP,    do_qadd},
!   {"qdadd",      0xe1400050, 5,  ARM_EXT_V5ExP,    do_qadd},
!   {"qsub",       0xe1200050, 4,  ARM_EXT_V5ExP,    do_qadd},
!   {"qdsub",      0xe1600050, 5,  ARM_EXT_V5ExP,    do_qadd},
  
!   /*  ARM Architecture 5TE.  */
!   {"pld",        0xf450f000, 0,  ARM_EXT_V5E,      do_pld},
!   {"ldrd",       0xe00000d0, 3,  ARM_EXT_V5E,      do_ldrd},
!   {"strd",       0xe00000f0, 3,  ARM_EXT_V5E,      do_ldrd},
  
!   {"mcrr",       0xec400000, 4,  ARM_EXT_V5E,      do_co_reg2c},
!   {"mrrc",       0xec500000, 4,  ARM_EXT_V5E,      do_co_reg2c},
  
!   /*  ARM Architecture 5TEJ.  */
!   {"bxj",	 0xe12fff20, 3,  ARM_EXT_V5J,	   do_bxj},
  
!   /*  ARM V6.  */
!   { "cps",       0xf1020000, 0,  ARM_EXT_V6,       do_cps},
!   { "cpsie",     0xf1080000, 0,  ARM_EXT_V6,       do_cpsi},
!   { "cpsid",     0xf10C0000, 0,  ARM_EXT_V6,       do_cpsi},
!   { "ldrex",     0xe1900f9f, 5,  ARM_EXT_V6,       do_ldrex},
!   { "mcrr2",     0xfc400000, 0,  ARM_EXT_V6,       do_co_reg2c},
!   { "mrrc2",     0xfc500000, 0,  ARM_EXT_V6,       do_co_reg2c},
!   { "pkhbt",     0xe6800010, 5,  ARM_EXT_V6,       do_pkhbt},
!   { "pkhtb",     0xe6800050, 5,  ARM_EXT_V6,       do_pkhtb},
!   { "qadd16",    0xe6200f10, 6,  ARM_EXT_V6,       do_qadd16},
!   { "qadd8",     0xe6200f90, 5,  ARM_EXT_V6,       do_qadd16},
!   { "qaddsubx",  0xe6200f30, 8,  ARM_EXT_V6,       do_qadd16},
!   { "qsub16",    0xe6200f70, 6,  ARM_EXT_V6,       do_qadd16},
!   { "qsub8",     0xe6200ff0, 5,  ARM_EXT_V6,       do_qadd16},
!   { "qsubaddx",  0xe6200f50, 8,  ARM_EXT_V6,       do_qadd16},
!   { "sadd16",    0xe6100f10, 6,  ARM_EXT_V6,       do_qadd16},
!   { "sadd8",     0xe6100f90, 5,  ARM_EXT_V6,       do_qadd16},
!   { "saddsubx",  0xe6100f30, 8,  ARM_EXT_V6,       do_qadd16},
!   { "shadd16",   0xe6300f10, 7,  ARM_EXT_V6,       do_qadd16},
!   { "shadd8",    0xe6300f90, 6,  ARM_EXT_V6,       do_qadd16},
!   { "shaddsubx", 0xe6300f30, 9,  ARM_EXT_V6,       do_qadd16},
!   { "shsub16",   0xe6300f70, 7,  ARM_EXT_V6,       do_qadd16},
!   { "shsub8",    0xe6300ff0, 6,  ARM_EXT_V6,       do_qadd16},
!   { "shsubaddx", 0xe6300f50, 9,  ARM_EXT_V6,       do_qadd16},
!   { "ssub16",    0xe6100f70, 6,  ARM_EXT_V6,       do_qadd16},
!   { "ssub8",     0xe6100ff0, 5,  ARM_EXT_V6,       do_qadd16},
!   { "ssubaddx",  0xe6100f50, 8,  ARM_EXT_V6,       do_qadd16},
!   { "uadd16",    0xe6500f10, 6,  ARM_EXT_V6,       do_qadd16},
!   { "uadd8",     0xe6500f90, 5,  ARM_EXT_V6,       do_qadd16},
!   { "uaddsubx",  0xe6500f30, 8,  ARM_EXT_V6,       do_qadd16},
!   { "uhadd16",   0xe6700f10, 7,  ARM_EXT_V6,       do_qadd16},
!   { "uhadd8",    0xe6700f90, 6,  ARM_EXT_V6,       do_qadd16},
!   { "uhaddsubx", 0xe6700f30, 9,  ARM_EXT_V6,       do_qadd16},
!   { "uhsub16",   0xe6700f70, 7,  ARM_EXT_V6,       do_qadd16},
!   { "uhsub8",    0xe6700ff0, 6,  ARM_EXT_V6,       do_qadd16},
!   { "uhsubaddx", 0xe6700f50, 9,  ARM_EXT_V6,       do_qadd16},
!   { "uqadd16",   0xe6600f10, 7,  ARM_EXT_V6,       do_qadd16},
!   { "uqadd8",    0xe6600f90, 6,  ARM_EXT_V6,       do_qadd16},
!   { "uqaddsubx", 0xe6600f30, 9,  ARM_EXT_V6,       do_qadd16},
!   { "uqsub16",   0xe6600f70, 7,  ARM_EXT_V6,       do_qadd16},
!   { "uqsub8",    0xe6600ff0, 6,  ARM_EXT_V6,       do_qadd16},
!   { "uqsubaddx", 0xe6600f50, 9,  ARM_EXT_V6,       do_qadd16},
!   { "usub16",    0xe6500f70, 6,  ARM_EXT_V6,       do_qadd16},
!   { "usub8",     0xe6500ff0, 5,  ARM_EXT_V6,       do_qadd16},
!   { "usubaddx",  0xe6500f50, 8,  ARM_EXT_V6,       do_qadd16},
!   { "rev",       0xe6bf0f30, 3,  ARM_EXT_V6,       do_rev},
!   { "rev16",     0xe6bf0fb0, 5,  ARM_EXT_V6,       do_rev},
!   { "revsh",     0xe6ff0fb0, 5,  ARM_EXT_V6,       do_rev},
!   { "rfeia",     0xf8900a00, 0,  ARM_EXT_V6,       do_rfe},
!   { "rfeib",     0xf9900a00, 0,  ARM_EXT_V6,       do_rfe},
!   { "rfeda",     0xf8100a00, 0,  ARM_EXT_V6,       do_rfe},
!   { "rfedb",     0xf9100a00, 0,  ARM_EXT_V6,       do_rfe},
!   { "rfefd",     0xf8900a00, 0,  ARM_EXT_V6,       do_rfe},
!   { "rfefa",     0xf9900a00, 0,  ARM_EXT_V6,       do_rfe},
!   { "rfeea",     0xf8100a00, 0,  ARM_EXT_V6,       do_rfe},
!   { "rfeed",     0xf9100a00, 0,  ARM_EXT_V6,       do_rfe},
!   { "sxtah",     0xe6b00070, 5,  ARM_EXT_V6,       do_sxtah},
!   { "sxtab16",   0xe6800070, 7,  ARM_EXT_V6,       do_sxtah},
!   { "sxtab",     0xe6a00070, 5,  ARM_EXT_V6,       do_sxtah},
!   { "sxth",      0xe6bf0070, 4,  ARM_EXT_V6,       do_sxth},
!   { "sxtb16",    0xe68f0070, 6,  ARM_EXT_V6,       do_sxth},
!   { "sxtb",      0xe6af0070, 4,  ARM_EXT_V6,       do_sxth},
!   { "uxtah",     0xe6f00070, 5,  ARM_EXT_V6,       do_sxtah},
!   { "uxtab16",   0xe6c00070, 7,  ARM_EXT_V6,       do_sxtah},
!   { "uxtab",     0xe6e00070, 5,  ARM_EXT_V6,       do_sxtah},
!   { "uxth",      0xe6ff0070, 4,  ARM_EXT_V6,       do_sxth},
!   { "uxtb16",    0xe6cf0070, 6,  ARM_EXT_V6,       do_sxth},
!   { "uxtb",      0xe6ef0070, 4,  ARM_EXT_V6,       do_sxth},
!   { "sel",       0xe68000b0, 3,  ARM_EXT_V6,       do_qadd16},
!   { "setend",    0xf1010000, 0,  ARM_EXT_V6,       do_setend},
!   { "smlad",     0xe7000010, 5,  ARM_EXT_V6,       do_smlad},
!   { "smladx",    0xe7000030, 6,  ARM_EXT_V6,       do_smlad},
!   { "smlald",    0xe7400010, 6,  ARM_EXT_V6,       do_smlald},
!   { "smlaldx",   0xe7400030, 7,  ARM_EXT_V6,       do_smlald},
!   { "smlsd",     0xe7000050, 5,  ARM_EXT_V6,       do_smlad},
!   { "smlsdx",    0xe7000070, 6,  ARM_EXT_V6,       do_smlad},
!   { "smlsld",    0xe7400050, 6,  ARM_EXT_V6,       do_smlald},
!   { "smlsldx",   0xe7400070, 7,  ARM_EXT_V6,       do_smlald},
!   { "smmla",     0xe7500010, 5,  ARM_EXT_V6,       do_smlad},
!   { "smmlar",    0xe7500030, 6,  ARM_EXT_V6,       do_smlad},
!   { "smmls",     0xe75000d0, 5,  ARM_EXT_V6,       do_smlad},
!   { "smmlsr",    0xe75000f0, 6,  ARM_EXT_V6,       do_smlad},
!   { "smmul",     0xe750f010, 5,  ARM_EXT_V6,       do_smmul},
!   { "smmulr",    0xe750f030, 6,  ARM_EXT_V6,       do_smmul},
!   { "smuad",     0xe700f010, 5,  ARM_EXT_V6,       do_smmul},
!   { "smuadx",    0xe700f030, 6,  ARM_EXT_V6,       do_smmul},
!   { "smusd",     0xe700f050, 5,  ARM_EXT_V6,       do_smmul},
!   { "smusdx",    0xe700f070, 6,  ARM_EXT_V6,       do_smmul},
!   { "srsia",     0xf8cd0500, 0,  ARM_EXT_V6,       do_srs},
!   { "srsib",     0xf9cd0500, 0,  ARM_EXT_V6,       do_srs},
!   { "srsda",     0xf84d0500, 0,  ARM_EXT_V6,       do_srs},
!   { "srsdb",     0xf94d0500, 0,  ARM_EXT_V6,       do_srs},
!   { "ssat",      0xe6a00010, 4,  ARM_EXT_V6,       do_ssat},
!   { "ssat16",    0xe6a00f30, 6,  ARM_EXT_V6,       do_ssat16},
!   { "strex",     0xe1800f90, 5,  ARM_EXT_V6,       do_strex},
!   { "umaal",     0xe0400090, 5,  ARM_EXT_V6,       do_umaal},
!   { "usad8",     0xe780f010, 5,  ARM_EXT_V6,       do_smmul},
!   { "usada8",    0xe7800010, 6,  ARM_EXT_V6,       do_smlad},
!   { "usat",      0xe6e00010, 4,  ARM_EXT_V6,       do_usat},
!   { "usat16",    0xe6e00f30, 6,  ARM_EXT_V6,       do_usat16},
  
!   /* Core FPA instruction set (V1).  */
!   {"wfs",        0xee200110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
!   {"rfs",        0xee300110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
!   {"wfc",        0xee400110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
!   {"rfc",        0xee500110, 3,  FPU_FPA_EXT_V1,   do_fpa_ctrl},
  
!   {"ldfs",       0xec100100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
!   {"ldfd",       0xec108100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
!   {"ldfe",       0xec500100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
!   {"ldfp",       0xec508100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
  
!   {"stfs",       0xec000100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
!   {"stfd",       0xec008100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
!   {"stfe",       0xec400100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
!   {"stfp",       0xec408100, 3,  FPU_FPA_EXT_V1,   do_fpa_ldst},
  
!   {"mvfs",       0xee008100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"mvfsp",      0xee008120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"mvfsm",      0xee008140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"mvfsz",      0xee008160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"mvfd",       0xee008180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"mvfdp",      0xee0081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"mvfdm",      0xee0081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"mvfdz",      0xee0081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"mvfe",       0xee088100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"mvfep",      0xee088120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"mvfem",      0xee088140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"mvfez",      0xee088160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
  
!   {"mnfs",       0xee108100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"mnfsp",      0xee108120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"mnfsm",      0xee108140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"mnfsz",      0xee108160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"mnfd",       0xee108180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"mnfdp",      0xee1081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"mnfdm",      0xee1081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"mnfdz",      0xee1081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"mnfe",       0xee188100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"mnfep",      0xee188120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"mnfem",      0xee188140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"mnfez",      0xee188160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
  
!   {"abss",       0xee208100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"abssp",      0xee208120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"abssm",      0xee208140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"abssz",      0xee208160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"absd",       0xee208180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"absdp",      0xee2081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"absdm",      0xee2081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"absdz",      0xee2081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"abse",       0xee288100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"absep",      0xee288120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"absem",      0xee288140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"absez",      0xee288160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
  
!   {"rnds",       0xee308100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"rndsp",      0xee308120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"rndsm",      0xee308140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"rndsz",      0xee308160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"rndd",       0xee308180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"rnddp",      0xee3081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"rnddm",      0xee3081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"rnddz",      0xee3081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"rnde",       0xee388100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"rndep",      0xee388120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"rndem",      0xee388140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"rndez",      0xee388160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
  
!   {"sqts",       0xee408100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"sqtsp",      0xee408120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"sqtsm",      0xee408140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"sqtsz",      0xee408160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"sqtd",       0xee408180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"sqtdp",      0xee4081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"sqtdm",      0xee4081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"sqtdz",      0xee4081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"sqte",       0xee488100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"sqtep",      0xee488120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"sqtem",      0xee488140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"sqtez",      0xee488160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
  
!   {"logs",       0xee508100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"logsp",      0xee508120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"logsm",      0xee508140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"logsz",      0xee508160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"logd",       0xee508180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"logdp",      0xee5081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"logdm",      0xee5081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"logdz",      0xee5081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"loge",       0xee588100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"logep",      0xee588120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"logem",      0xee588140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"logez",      0xee588160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
  
!   {"lgns",       0xee608100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"lgnsp",      0xee608120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"lgnsm",      0xee608140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"lgnsz",      0xee608160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"lgnd",       0xee608180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"lgndp",      0xee6081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"lgndm",      0xee6081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"lgndz",      0xee6081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"lgne",       0xee688100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"lgnep",      0xee688120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"lgnem",      0xee688140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"lgnez",      0xee688160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
  
!   {"exps",       0xee708100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"expsp",      0xee708120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"expsm",      0xee708140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"expsz",      0xee708160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"expd",       0xee708180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"expdp",      0xee7081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"expdm",      0xee7081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"expdz",      0xee7081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"expe",       0xee788100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"expep",      0xee788120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"expem",      0xee788140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"expdz",      0xee788160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
  
!   {"sins",       0xee808100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"sinsp",      0xee808120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"sinsm",      0xee808140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"sinsz",      0xee808160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"sind",       0xee808180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"sindp",      0xee8081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"sindm",      0xee8081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"sindz",      0xee8081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"sine",       0xee888100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"sinep",      0xee888120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"sinem",      0xee888140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"sinez",      0xee888160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
  
!   {"coss",       0xee908100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"cossp",      0xee908120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"cossm",      0xee908140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"cossz",      0xee908160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"cosd",       0xee908180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"cosdp",      0xee9081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"cosdm",      0xee9081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"cosdz",      0xee9081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"cose",       0xee988100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"cosep",      0xee988120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"cosem",      0xee988140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"cosez",      0xee988160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
  
!   {"tans",       0xeea08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"tansp",      0xeea08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"tansm",      0xeea08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"tansz",      0xeea08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"tand",       0xeea08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"tandp",      0xeea081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"tandm",      0xeea081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"tandz",      0xeea081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"tane",       0xeea88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"tanep",      0xeea88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"tanem",      0xeea88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"tanez",      0xeea88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
  
!   {"asns",       0xeeb08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"asnsp",      0xeeb08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"asnsm",      0xeeb08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"asnsz",      0xeeb08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"asnd",       0xeeb08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"asndp",      0xeeb081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"asndm",      0xeeb081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"asndz",      0xeeb081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"asne",       0xeeb88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"asnep",      0xeeb88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"asnem",      0xeeb88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"asnez",      0xeeb88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
  
!   {"acss",       0xeec08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"acssp",      0xeec08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"acssm",      0xeec08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"acssz",      0xeec08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"acsd",       0xeec08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"acsdp",      0xeec081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"acsdm",      0xeec081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"acsdz",      0xeec081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"acse",       0xeec88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"acsep",      0xeec88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"acsem",      0xeec88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"acsez",      0xeec88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
  
!   {"atns",       0xeed08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"atnsp",      0xeed08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"atnsm",      0xeed08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"atnsz",      0xeed08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"atnd",       0xeed08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"atndp",      0xeed081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"atndm",      0xeed081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"atndz",      0xeed081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"atne",       0xeed88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"atnep",      0xeed88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"atnem",      0xeed88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"atnez",      0xeed88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
  
!   {"urds",       0xeee08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"urdsp",      0xeee08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"urdsm",      0xeee08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"urdsz",      0xeee08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"urdd",       0xeee08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"urddp",      0xeee081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"urddm",      0xeee081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"urddz",      0xeee081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"urde",       0xeee88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"urdep",      0xeee88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"urdem",      0xeee88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"urdez",      0xeee88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
  
!   {"nrms",       0xeef08100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"nrmsp",      0xeef08120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"nrmsm",      0xeef08140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"nrmsz",      0xeef08160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"nrmd",       0xeef08180, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"nrmdp",      0xeef081a0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"nrmdm",      0xeef081c0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"nrmdz",      0xeef081e0, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"nrme",       0xeef88100, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"nrmep",      0xeef88120, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"nrmem",      0xeef88140, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
!   {"nrmez",      0xeef88160, 3,  FPU_FPA_EXT_V1,   do_fpa_monadic},
  
!   {"adfs",       0xee000100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"adfsp",      0xee000120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"adfsm",      0xee000140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"adfsz",      0xee000160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"adfd",       0xee000180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"adfdp",      0xee0001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"adfdm",      0xee0001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"adfdz",      0xee0001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"adfe",       0xee080100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"adfep",      0xee080120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"adfem",      0xee080140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"adfez",      0xee080160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
  
!   {"sufs",       0xee200100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"sufsp",      0xee200120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"sufsm",      0xee200140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"sufsz",      0xee200160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"sufd",       0xee200180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"sufdp",      0xee2001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"sufdm",      0xee2001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"sufdz",      0xee2001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"sufe",       0xee280100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"sufep",      0xee280120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"sufem",      0xee280140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"sufez",      0xee280160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
  
!   {"rsfs",       0xee300100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rsfsp",      0xee300120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rsfsm",      0xee300140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rsfsz",      0xee300160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rsfd",       0xee300180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rsfdp",      0xee3001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rsfdm",      0xee3001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rsfdz",      0xee3001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rsfe",       0xee380100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rsfep",      0xee380120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rsfem",      0xee380140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rsfez",      0xee380160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
  
!   {"mufs",       0xee100100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"mufsp",      0xee100120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"mufsm",      0xee100140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"mufsz",      0xee100160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"mufd",       0xee100180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"mufdp",      0xee1001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"mufdm",      0xee1001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"mufdz",      0xee1001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"mufe",       0xee180100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"mufep",      0xee180120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"mufem",      0xee180140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"mufez",      0xee180160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
  
!   {"dvfs",       0xee400100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"dvfsp",      0xee400120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"dvfsm",      0xee400140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"dvfsz",      0xee400160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"dvfd",       0xee400180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"dvfdp",      0xee4001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"dvfdm",      0xee4001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"dvfdz",      0xee4001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"dvfe",       0xee480100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"dvfep",      0xee480120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"dvfem",      0xee480140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"dvfez",      0xee480160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
  
!   {"rdfs",       0xee500100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rdfsp",      0xee500120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rdfsm",      0xee500140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rdfsz",      0xee500160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rdfd",       0xee500180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rdfdp",      0xee5001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rdfdm",      0xee5001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rdfdz",      0xee5001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rdfe",       0xee580100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rdfep",      0xee580120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rdfem",      0xee580140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rdfez",      0xee580160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
  
!   {"pows",       0xee600100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"powsp",      0xee600120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"powsm",      0xee600140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"powsz",      0xee600160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"powd",       0xee600180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"powdp",      0xee6001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"powdm",      0xee6001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"powdz",      0xee6001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"powe",       0xee680100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"powep",      0xee680120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"powem",      0xee680140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"powez",      0xee680160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
  
!   {"rpws",       0xee700100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rpwsp",      0xee700120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rpwsm",      0xee700140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rpwsz",      0xee700160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rpwd",       0xee700180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rpwdp",      0xee7001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rpwdm",      0xee7001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rpwdz",      0xee7001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rpwe",       0xee780100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rpwep",      0xee780120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rpwem",      0xee780140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rpwez",      0xee780160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
  
!   {"rmfs",       0xee800100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rmfsp",      0xee800120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rmfsm",      0xee800140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rmfsz",      0xee800160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rmfd",       0xee800180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rmfdp",      0xee8001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rmfdm",      0xee8001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rmfdz",      0xee8001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rmfe",       0xee880100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rmfep",      0xee880120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rmfem",      0xee880140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"rmfez",      0xee880160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
  
!   {"fmls",       0xee900100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"fmlsp",      0xee900120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"fmlsm",      0xee900140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"fmlsz",      0xee900160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"fmld",       0xee900180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"fmldp",      0xee9001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"fmldm",      0xee9001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"fmldz",      0xee9001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"fmle",       0xee980100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"fmlep",      0xee980120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"fmlem",      0xee980140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"fmlez",      0xee980160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
  
!   {"fdvs",       0xeea00100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"fdvsp",      0xeea00120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"fdvsm",      0xeea00140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"fdvsz",      0xeea00160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"fdvd",       0xeea00180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"fdvdp",      0xeea001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"fdvdm",      0xeea001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"fdvdz",      0xeea001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"fdve",       0xeea80100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"fdvep",      0xeea80120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"fdvem",      0xeea80140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"fdvez",      0xeea80160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
  
!   {"frds",       0xeeb00100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"frdsp",      0xeeb00120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"frdsm",      0xeeb00140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"frdsz",      0xeeb00160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"frdd",       0xeeb00180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"frddp",      0xeeb001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"frddm",      0xeeb001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"frddz",      0xeeb001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"frde",       0xeeb80100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"frdep",      0xeeb80120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"frdem",      0xeeb80140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"frdez",      0xeeb80160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
  
!   {"pols",       0xeec00100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"polsp",      0xeec00120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"polsm",      0xeec00140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"polsz",      0xeec00160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"pold",       0xeec00180, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"poldp",      0xeec001a0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"poldm",      0xeec001c0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"poldz",      0xeec001e0, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"pole",       0xeec80100, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"polep",      0xeec80120, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"polem",      0xeec80140, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
!   {"polez",      0xeec80160, 3,  FPU_FPA_EXT_V1,   do_fpa_dyadic},
  
!   {"cmf",        0xee90f110, 3,  FPU_FPA_EXT_V1,   do_fpa_cmp},
!   {"cmfe",       0xeed0f110, 3,  FPU_FPA_EXT_V1,   do_fpa_cmp},
!   {"cnf",        0xeeb0f110, 3,  FPU_FPA_EXT_V1,   do_fpa_cmp},
!   {"cnfe",       0xeef0f110, 3,  FPU_FPA_EXT_V1,   do_fpa_cmp},
!   /* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should
!      not be an optional suffix, but part of the instruction.  To be
!      compatible, we accept either.  */
!   {"cmfe",       0xeed0f110, 4,  FPU_FPA_EXT_V1,   do_fpa_cmp},
!   {"cnfe",       0xeef0f110, 4,  FPU_FPA_EXT_V1,   do_fpa_cmp},
  
!   {"flts",       0xee000110, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
!   {"fltsp",      0xee000130, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
!   {"fltsm",      0xee000150, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
!   {"fltsz",      0xee000170, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
!   {"fltd",       0xee000190, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
!   {"fltdp",      0xee0001b0, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
!   {"fltdm",      0xee0001d0, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
!   {"fltdz",      0xee0001f0, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
!   {"flte",       0xee080110, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
!   {"fltep",      0xee080130, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
!   {"fltem",      0xee080150, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
!   {"fltez",      0xee080170, 3,  FPU_FPA_EXT_V1,   do_fpa_from_reg},
  
!   /* The implementation of the FIX instruction is broken on some
!      assemblers, in that it accepts a precision specifier as well as a
!      rounding specifier, despite the fact that this is meaningless.
!      To be more compatible, we accept it as well, though of course it
!      does not set any bits.  */
!   {"fix",        0xee100110, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
!   {"fixp",       0xee100130, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
!   {"fixm",       0xee100150, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
!   {"fixz",       0xee100170, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
!   {"fixsp",      0xee100130, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
!   {"fixsm",      0xee100150, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
!   {"fixsz",      0xee100170, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
!   {"fixdp",      0xee100130, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
!   {"fixdm",      0xee100150, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
!   {"fixdz",      0xee100170, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
!   {"fixep",      0xee100130, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
!   {"fixem",      0xee100150, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
!   {"fixez",      0xee100170, 3,  FPU_FPA_EXT_V1,   do_fpa_to_reg},
  
!   /* Instructions that were new with the real FPA, call them V2.  */
!   {"lfm",        0xec100200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
!   {"lfmfd",      0xec900200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
!   {"lfmea",      0xed100200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
!   {"sfm",        0xec000200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
!   {"sfmfd",      0xed000200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
!   {"sfmea",      0xec800200, 3,  FPU_FPA_EXT_V2,   do_fpa_ldmstm},
  
!   /* VFP V1xD (single precision).  */
!   /* Moves and type conversions.  */
!   {"fcpys",   0xeeb00a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
!   {"fmrs",    0xee100a10, 4, FPU_VFP_EXT_V1xD, do_vfp_reg_from_sp},
!   {"fmsr",    0xee000a10, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_from_reg},
!   {"fmstat",  0xeef1fa10, 6, FPU_VFP_EXT_V1xD, do_empty},
!   {"fsitos",  0xeeb80ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
!   {"fuitos",  0xeeb80a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
!   {"ftosis",  0xeebd0a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
!   {"ftosizs", 0xeebd0ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
!   {"ftouis",  0xeebc0a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
!   {"ftouizs", 0xeebc0ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
!   {"fmrx",    0xeef00a10, 4, FPU_VFP_EXT_V1xD, do_vfp_reg_from_ctrl},
!   {"fmxr",    0xeee00a10, 4, FPU_VFP_EXT_V1xD, do_vfp_ctrl_from_reg},
  
!   /* Memory operations.  */
!   {"flds",    0xed100a00, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_ldst},
!   {"fsts",    0xed000a00, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_ldst},
!   {"fldmias", 0xec900a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
!   {"fldmfds", 0xec900a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
!   {"fldmdbs", 0xed300a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
!   {"fldmeas", 0xed300a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
!   {"fldmiax", 0xec900b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
!   {"fldmfdx", 0xec900b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
!   {"fldmdbx", 0xed300b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
!   {"fldmeax", 0xed300b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
!   {"fstmias", 0xec800a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
!   {"fstmeas", 0xec800a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
!   {"fstmdbs", 0xed200a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
!   {"fstmfds", 0xed200a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
!   {"fstmiax", 0xec800b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
!   {"fstmeax", 0xec800b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
!   {"fstmdbx", 0xed200b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
!   {"fstmfdx", 0xed200b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
  
!   /* Monadic operations.  */
!   {"fabss",   0xeeb00ac0, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
!   {"fnegs",   0xeeb10a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
!   {"fsqrts",  0xeeb10ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
  
!   /* Dyadic operations.  */
!   {"fadds",   0xee300a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
!   {"fsubs",   0xee300a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
!   {"fmuls",   0xee200a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
!   {"fdivs",   0xee800a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
!   {"fmacs",   0xee000a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
!   {"fmscs",   0xee100a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
!   {"fnmuls",  0xee200a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
!   {"fnmacs",  0xee000a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
!   {"fnmscs",  0xee100a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
  
!   /* Comparisons.  */
!   {"fcmps",   0xeeb40a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
!   {"fcmpzs",  0xeeb50a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_compare_z},
!   {"fcmpes",  0xeeb40ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
!   {"fcmpezs", 0xeeb50ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_compare_z},
  
!   /* VFP V1 (Double precision).  */
!   /* Moves and type conversions.  */
!   {"fcpyd",   0xeeb00b40, 5, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
!   {"fcvtds",  0xeeb70ac0, 6, FPU_VFP_EXT_V1,   do_vfp_dp_sp_cvt},
!   {"fcvtsd",  0xeeb70bc0, 6, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
!   {"fmdhr",   0xee200b10, 5, FPU_VFP_EXT_V1,   do_vfp_dp_from_reg},
!   {"fmdlr",   0xee000b10, 5, FPU_VFP_EXT_V1,   do_vfp_dp_from_reg},
!   {"fmrdh",   0xee300b10, 5, FPU_VFP_EXT_V1,   do_vfp_reg_from_dp},
!   {"fmrdl",   0xee100b10, 5, FPU_VFP_EXT_V1,   do_vfp_reg_from_dp},
!   {"fsitod",  0xeeb80bc0, 6, FPU_VFP_EXT_V1,   do_vfp_dp_sp_cvt},
!   {"fuitod",  0xeeb80b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_sp_cvt},
!   {"ftosid",  0xeebd0b40, 6, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
!   {"ftosizd", 0xeebd0bc0, 7, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
!   {"ftouid",  0xeebc0b40, 6, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
!   {"ftouizd", 0xeebc0bc0, 7, FPU_VFP_EXT_V1,   do_vfp_sp_dp_cvt},
  
!   /* Memory operations.  */
!   {"fldd",    0xed100b00, 4, FPU_VFP_EXT_V1,   do_vfp_dp_ldst},
!   {"fstd",    0xed000b00, 4, FPU_VFP_EXT_V1,   do_vfp_dp_ldst},
!   {"fldmiad", 0xec900b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmia},
!   {"fldmfdd", 0xec900b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmia},
!   {"fldmdbd", 0xed300b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmdb},
!   {"fldmead", 0xed300b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmdb},
!   {"fstmiad", 0xec800b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmia},
!   {"fstmead", 0xec800b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmia},
!   {"fstmdbd", 0xed200b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmdb},
!   {"fstmfdd", 0xed200b00, 7, FPU_VFP_EXT_V1,   do_vfp_dp_ldstmdb},
  
!   /* Monadic operations.  */
!   {"fabsd",   0xeeb00bc0, 5, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
!   {"fnegd",   0xeeb10b40, 5, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
!   {"fsqrtd",  0xeeb10bc0, 6, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
  
!   /* Dyadic operations.  */
!   {"faddd",   0xee300b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
!   {"fsubd",   0xee300b40, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
!   {"fmuld",   0xee200b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
!   {"fdivd",   0xee800b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
!   {"fmacd",   0xee000b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
!   {"fmscd",   0xee100b00, 5, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
!   {"fnmuld",  0xee200b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
!   {"fnmacd",  0xee000b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
!   {"fnmscd",  0xee100b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_dyadic},
  
!   /* Comparisons.  */
!   {"fcmpd",   0xeeb40b40, 5, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
!   {"fcmpzd",  0xeeb50b40, 6, FPU_VFP_EXT_V1,   do_vfp_dp_compare_z},
!   {"fcmped",  0xeeb40bc0, 6, FPU_VFP_EXT_V1,   do_vfp_dp_monadic},
!   {"fcmpezd", 0xeeb50bc0, 7, FPU_VFP_EXT_V1,   do_vfp_dp_compare_z},
  
!   /* VFP V2.  */
!   {"fmsrr",   0xec400a10, 5, FPU_VFP_EXT_V2,   do_vfp_sp2_from_reg2},
!   {"fmrrs",   0xec500a10, 5, FPU_VFP_EXT_V2,   do_vfp_reg2_from_sp2},
!   {"fmdrr",   0xec400b10, 5, FPU_VFP_EXT_V2,   do_vfp_dp_from_reg2},
!   {"fmrrd",   0xec500b10, 5, FPU_VFP_EXT_V2,   do_vfp_reg2_from_dp},
  
!   /* Intel XScale extensions to ARM V5 ISA.  (All use CP0).  */
!   {"mia",        0xee200010, 3,  ARM_CEXT_XSCALE,   do_xsc_mia},
!   {"miaph",      0xee280010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
!   {"miabb",      0xee2c0010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
!   {"miabt",      0xee2d0010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
!   {"miatb",      0xee2e0010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
!   {"miatt",      0xee2f0010, 5,  ARM_CEXT_XSCALE,   do_xsc_mia},
!   {"mar",        0xec400000, 3,  ARM_CEXT_XSCALE,   do_xsc_mar},
!   {"mra",        0xec500000, 3,  ARM_CEXT_XSCALE,   do_xsc_mra},
  
!   /* Intel Wireless MMX technology instructions.  */
!   {"tandcb",     0xee130130, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tandc},
!   {"tandch",     0xee530130, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tandc},
!   {"tandcw",     0xee930130, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tandc},
!   {"tbcstb",     0xee400010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tbcst},
!   {"tbcsth",     0xee400050, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tbcst},
!   {"tbcstw",     0xee400090, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tbcst},
!   {"textrcb",    0xee130170, 7, ARM_CEXT_IWMMXT, do_iwmmxt_textrc},
!   {"textrch",    0xee530170, 7, ARM_CEXT_IWMMXT, do_iwmmxt_textrc},
!   {"textrcw",    0xee930170, 7, ARM_CEXT_IWMMXT, do_iwmmxt_textrc},
!   {"textrmub",   0xee100070, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
!   {"textrmuh",   0xee500070, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
!   {"textrmuw",   0xee900070, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
!   {"textrmsb",   0xee100078, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
!   {"textrmsh",   0xee500078, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
!   {"textrmsw",   0xee900078, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
!   {"tinsrb",     0xee600010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tinsr},
!   {"tinsrh",     0xee600050, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tinsr},
!   {"tinsrw",     0xee600090, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tinsr},
!   {"tmcr",       0xee000110, 4, ARM_CEXT_IWMMXT, do_iwmmxt_tmcr},
!   {"tmcrr",      0xec400000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_tmcrr},
!   {"tmia",       0xee200010, 4, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
!   {"tmiaph",     0xee280010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
!   {"tmiabb",     0xee2c0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
!   {"tmiabt",     0xee2d0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
!   {"tmiatb",     0xee2e0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
!   {"tmiatt",     0xee2f0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
!   {"tmovmskb",   0xee100030, 8, ARM_CEXT_IWMMXT, do_iwmmxt_tmovmsk},
!   {"tmovmskh",   0xee500030, 8, ARM_CEXT_IWMMXT, do_iwmmxt_tmovmsk},
!   {"tmovmskw",   0xee900030, 8, ARM_CEXT_IWMMXT, do_iwmmxt_tmovmsk},
!   {"tmrc",       0xee100110, 4, ARM_CEXT_IWMMXT, do_iwmmxt_tmrc},
!   {"tmrrc",      0xec500000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_tmrrc},
!   {"torcb",      0xee130150, 5, ARM_CEXT_IWMMXT, do_iwmmxt_torc},
!   {"torch",      0xee530150, 5, ARM_CEXT_IWMMXT, do_iwmmxt_torc},
!   {"torcw",      0xee930150, 5, ARM_CEXT_IWMMXT, do_iwmmxt_torc},
!   {"waccb",      0xee0001c0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
!   {"wacch",      0xee4001c0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
!   {"waccw",      0xee8001c0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
!   {"waddbss",    0xee300180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"waddb",      0xee000180, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"waddbus",    0xee100180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"waddhss",    0xee700180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"waddh",      0xee400180, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"waddhus",    0xee500180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"waddwss",    0xeeb00180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"waddw",      0xee800180, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"waddwus",    0xee900180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"waligni",    0xee000020, 7, ARM_CEXT_IWMMXT, do_iwmmxt_waligni},
!   {"walignr0",   0xee800020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"walignr1",   0xee900020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"walignr2",   0xeea00020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"walignr3",   0xeeb00020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wand",       0xee200000, 4, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wandn",      0xee300000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wavg2b",     0xee800000, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wavg2br",    0xee900000, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wavg2h",     0xeec00000, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wavg2hr",    0xeed00000, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wcmpeqb",    0xee000060, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wcmpeqh",    0xee400060, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wcmpeqw",    0xee800060, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wcmpgtub",   0xee100060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wcmpgtuh",   0xee500060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wcmpgtuw",   0xee900060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wcmpgtsb",   0xee300060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wcmpgtsh",   0xee700060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wcmpgtsw",   0xeeb00060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wldrb",      0xec100000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
!   {"wldrh",      0xec100100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
!   {"wldrw",      0xec100200, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
!   {"wldrd",      0xec100300, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
!   {"wmacs",      0xee600100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wmacsz",     0xee700100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wmacu",      0xee400100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wmacuz",     0xee500100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wmadds",     0xeea00100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wmaddu",     0xee800100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wmaxsb",     0xee200160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wmaxsh",     0xee600160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wmaxsw",     0xeea00160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wmaxub",     0xee000160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wmaxuh",     0xee400160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wmaxuw",     0xee800160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wminsb",     0xee300160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wminsh",     0xee700160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wminsw",     0xeeb00160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wminub",     0xee100160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wminuh",     0xee500160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wminuw",     0xee900160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wmov",       0xee000000, 4, ARM_CEXT_IWMMXT, do_iwmmxt_wmov},
!   {"wmulsm",     0xee300100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wmulsl",     0xee200100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wmulum",     0xee100100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wmulul",     0xee000100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wor",        0xee000000, 3, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wpackhss",   0xee700080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wpackhus",   0xee500080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wpackwss",   0xeeb00080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wpackwus",   0xee900080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wpackdss",   0xeef00080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wpackdus",   0xeed00080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wrorh",      0xee700040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wrorhg",     0xee700148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
!   {"wrorw",      0xeeb00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wrorwg",     0xeeb00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
!   {"wrord",      0xeef00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wrordg",     0xeef00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
!   {"wsadb",      0xee000120, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wsadbz",     0xee100120, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wsadh",      0xee400120, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wsadhz",     0xee500120, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wshufh",     0xee0001e0, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wshufh},
!   {"wsllh",      0xee500040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wsllhg",     0xee500148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
!   {"wsllw",      0xee900040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wsllwg",     0xee900148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
!   {"wslld",      0xeed00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wslldg",     0xeed00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
!   {"wsrah",      0xee400040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wsrahg",     0xee400148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
!   {"wsraw",      0xee800040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wsrawg",     0xee800148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
!   {"wsrad",      0xeec00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wsradg",     0xeec00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
!   {"wsrlh",      0xee600040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wsrlhg",     0xee600148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
!   {"wsrlw",      0xeea00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wsrlwg",     0xeea00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
!   {"wsrld",      0xeee00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wsrldg",     0xeee00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
!   {"wstrb",      0xec000000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
!   {"wstrh",      0xec000100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
!   {"wstrw",      0xec000200, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
!   {"wstrd",      0xec000300, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
!   {"wsubbss",    0xee3001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wsubb",      0xee0001a0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wsubbus",    0xee1001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wsubhss",    0xee7001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wsubh",      0xee4001a0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wsubhus",    0xee5001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wsubwss",    0xeeb001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wsubw",      0xee8001a0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wsubwus",    0xee9001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wunpckehub", 0xee0000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
!   {"wunpckehuh", 0xee4000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
!   {"wunpckehuw", 0xee8000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
!   {"wunpckehsb", 0xee2000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
!   {"wunpckehsh", 0xee6000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
!   {"wunpckehsw", 0xeea000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
!   {"wunpckihb",  0xee1000c0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wunpckihh",  0xee5000c0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wunpckihw",  0xee9000c0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wunpckelub", 0xee0000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
!   {"wunpckeluh", 0xee4000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
!   {"wunpckeluw", 0xee8000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
!   {"wunpckelsb", 0xee2000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
!   {"wunpckelsh", 0xee6000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
!   {"wunpckelsw", 0xeea000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
!   {"wunpckilb",  0xee1000e0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wunpckilh",  0xee5000e0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wunpckilw",  0xee9000e0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wxor",       0xee100000, 4, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
!   {"wzero",      0xee300000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wzero},
  
!   /* Cirrus Maverick instructions.  */
!   {"cfldrs",     0xec100400, 6,  ARM_CEXT_MAVERICK, do_mav_ldst_1},
!   {"cfldrd",     0xec500400, 6,  ARM_CEXT_MAVERICK, do_mav_ldst_2},
!   {"cfldr32",    0xec100500, 7,  ARM_CEXT_MAVERICK, do_mav_ldst_3},
!   {"cfldr64",    0xec500500, 7,  ARM_CEXT_MAVERICK, do_mav_ldst_4},
!   {"cfstrs",     0xec000400, 6,  ARM_CEXT_MAVERICK, do_mav_ldst_1},
!   {"cfstrd",     0xec400400, 6,  ARM_CEXT_MAVERICK, do_mav_ldst_2},
!   {"cfstr32",    0xec000500, 7,  ARM_CEXT_MAVERICK, do_mav_ldst_3},
!   {"cfstr64",    0xec400500, 7,  ARM_CEXT_MAVERICK, do_mav_ldst_4},
!   {"cfmvsr",     0xee000450, 6,  ARM_CEXT_MAVERICK, do_mav_binops_2a},
!   {"cfmvrs",     0xee100450, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1a},
!   {"cfmvdlr",    0xee000410, 7,  ARM_CEXT_MAVERICK, do_mav_binops_2b},
!   {"cfmvrdl",    0xee100410, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1b},
!   {"cfmvdhr",    0xee000430, 7,  ARM_CEXT_MAVERICK, do_mav_binops_2b},
!   {"cfmvrdh",    0xee100430, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1b},
!   {"cfmv64lr",   0xee000510, 8,  ARM_CEXT_MAVERICK, do_mav_binops_2c},
!   {"cfmvr64l",   0xee100510, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1c},
!   {"cfmv64hr",   0xee000530, 8,  ARM_CEXT_MAVERICK, do_mav_binops_2c},
!   {"cfmvr64h",   0xee100530, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1c},
!   {"cfmval32",   0xee200440, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3a},
!   {"cfmv32al",   0xee100440, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3b},
!   {"cfmvam32",   0xee200460, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3a},
!   {"cfmv32am",   0xee100460, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3b},
!   {"cfmvah32",   0xee200480, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3a},
!   {"cfmv32ah",   0xee100480, 8,  ARM_CEXT_MAVERICK, do_mav_binops_3b},
!   {"cfmva32",    0xee2004a0, 7,  ARM_CEXT_MAVERICK, do_mav_binops_3a},
!   {"cfmv32a",    0xee1004a0, 7,  ARM_CEXT_MAVERICK, do_mav_binops_3b},
!   {"cfmva64",    0xee2004c0, 7,  ARM_CEXT_MAVERICK, do_mav_binops_3c},
!   {"cfmv64a",    0xee1004c0, 7,  ARM_CEXT_MAVERICK, do_mav_binops_3d},
!   {"cfmvsc32",   0xee2004e0, 8,  ARM_CEXT_MAVERICK, do_mav_dspsc_1},
!   {"cfmv32sc",   0xee1004e0, 8,  ARM_CEXT_MAVERICK, do_mav_dspsc_2},
!   {"cfcpys",     0xee000400, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1d},
!   {"cfcpyd",     0xee000420, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1e},
!   {"cfcvtsd",    0xee000460, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1f},
!   {"cfcvtds",    0xee000440, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1g},
!   {"cfcvt32s",   0xee000480, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1h},
!   {"cfcvt32d",   0xee0004a0, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1i},
!   {"cfcvt64s",   0xee0004c0, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1j},
!   {"cfcvt64d",   0xee0004e0, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1k},
!   {"cfcvts32",   0xee100580, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1l},
!   {"cfcvtd32",   0xee1005a0, 8,  ARM_CEXT_MAVERICK, do_mav_binops_1m},
!   {"cftruncs32", 0xee1005c0, 10, ARM_CEXT_MAVERICK, do_mav_binops_1l},
!   {"cftruncd32", 0xee1005e0, 10, ARM_CEXT_MAVERICK, do_mav_binops_1m},
!   {"cfrshl32",   0xee000550, 8,  ARM_CEXT_MAVERICK, do_mav_triple_4a},
!   {"cfrshl64",   0xee000570, 8,  ARM_CEXT_MAVERICK, do_mav_triple_4b},
!   {"cfsh32",     0xee000500, 6,  ARM_CEXT_MAVERICK, do_mav_shift_1},
!   {"cfsh64",     0xee200500, 6,  ARM_CEXT_MAVERICK, do_mav_shift_2},
!   {"cfcmps",     0xee100490, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5a},
!   {"cfcmpd",     0xee1004b0, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5b},
!   {"cfcmp32",    0xee100590, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5c},
!   {"cfcmp64",    0xee1005b0, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5d},
!   {"cfabss",     0xee300400, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1d},
!   {"cfabsd",     0xee300420, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1e},
!   {"cfnegs",     0xee300440, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1d},
!   {"cfnegd",     0xee300460, 6,  ARM_CEXT_MAVERICK, do_mav_binops_1e},
!   {"cfadds",     0xee300480, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5e},
!   {"cfaddd",     0xee3004a0, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5f},
!   {"cfsubs",     0xee3004c0, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5e},
!   {"cfsubd",     0xee3004e0, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5f},
!   {"cfmuls",     0xee100400, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5e},
!   {"cfmuld",     0xee100420, 6,  ARM_CEXT_MAVERICK, do_mav_triple_5f},
!   {"cfabs32",    0xee300500, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1n},
!   {"cfabs64",    0xee300520, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1o},
!   {"cfneg32",    0xee300540, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1n},
!   {"cfneg64",    0xee300560, 7,  ARM_CEXT_MAVERICK, do_mav_binops_1o},
!   {"cfadd32",    0xee300580, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
!   {"cfadd64",    0xee3005a0, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5h},
!   {"cfsub32",    0xee3005c0, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
!   {"cfsub64",    0xee3005e0, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5h},
!   {"cfmul32",    0xee100500, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
!   {"cfmul64",    0xee100520, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5h},
!   {"cfmac32",    0xee100540, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
!   {"cfmsc32",    0xee100560, 7,  ARM_CEXT_MAVERICK, do_mav_triple_5g},
!   {"cfmadd32",   0xee000600, 8,  ARM_CEXT_MAVERICK, do_mav_quad_6a},
!   {"cfmsub32",   0xee100600, 8,  ARM_CEXT_MAVERICK, do_mav_quad_6a},
!   {"cfmadda32",  0xee200600, 9,  ARM_CEXT_MAVERICK, do_mav_quad_6b},
!   {"cfmsuba32",  0xee300600, 9,  ARM_CEXT_MAVERICK, do_mav_quad_6b},
! };
  
  /* Iterate over the base tables to create the instruction patterns.  */
+ 
  static void
! build_arm_ops_hsh (void)
  {
    unsigned int i;
    unsigned int j;
*************** typedef struct
*** 11528,11544 ****
  #define ARM_NOTE_DESCRIPTION_LENGTH	8
  
  static void
! arm_add_note (name, description, type)
!      const char * name;
!      const char * description;
!      unsigned int type;
  {
    arm_Note     note ATTRIBUTE_UNUSED;
    char *       p;
    unsigned int name_len;
  
    name_len = (strlen (name) + 1 + 3) & ~3;
!   
    p = frag_more (sizeof (note.namesz));
    md_number_to_chars (p, (valueT) name_len, sizeof (note.namesz));
  
--- 10871,10886 ----
  #define ARM_NOTE_DESCRIPTION_LENGTH	8
  
  static void
! arm_add_note (const char * name,
! 	      const char * description,
! 	      unsigned int type)
  {
    arm_Note     note ATTRIBUTE_UNUSED;
    char *       p;
    unsigned int name_len;
  
    name_len = (strlen (name) + 1 + 3) & ~3;
! 
    p = frag_more (sizeof (note.namesz));
    md_number_to_chars (p, (valueT) name_len, sizeof (note.namesz));
  
*************** arm_add_note (name, description, type)
*** 11551,11565 ****
    p = frag_more (name_len);
    strcpy (p, name);
  
!   p = frag_more (ARM_NOTE_DESCRIPTION_LENGTH);
!   strncpy (p, description, ARM_NOTE_DESCRIPTION_LENGTH);
!   frag_align (2, 0, 0);
! }
! #endif
! #endif
  
  void
! md_begin ()
  {
    unsigned mach;
    unsigned int i;
--- 10893,10987 ----
    p = frag_more (name_len);
    strcpy (p, name);
  
!   p = frag_more (ARM_NOTE_DESCRIPTION_LENGTH);
!   strncpy (p, description, ARM_NOTE_DESCRIPTION_LENGTH);
!   frag_align (2, 0, 0);
! }
! #endif
! #endif
! 
! 
! static const struct thumb_opcode tinsns[] =
! {
!   /* Thumb v1 (ARMv4T).  */
!   {"adc",	0x4140,		2,	ARM_EXT_V4T, do_t_arit},
!   {"add",	0x0000,		2,	ARM_EXT_V4T, do_t_add},
!   {"and",	0x4000,		2,	ARM_EXT_V4T, do_t_arit},
!   {"asr",	0x0000,		2,	ARM_EXT_V4T, do_t_asr},
!   {"b",		T_OPCODE_BRANCH, 2,	ARM_EXT_V4T, do_t_branch12},
!   {"beq",	0xd0fe,		2,	ARM_EXT_V4T, do_t_branch9},
!   {"bne",	0xd1fe,		2,	ARM_EXT_V4T, do_t_branch9},
!   {"bcs",	0xd2fe,		2,	ARM_EXT_V4T, do_t_branch9},
!   {"bhs",	0xd2fe,		2,	ARM_EXT_V4T, do_t_branch9},
!   {"bcc",	0xd3fe,		2,	ARM_EXT_V4T, do_t_branch9},
!   {"bul",	0xd3fe,		2,	ARM_EXT_V4T, do_t_branch9},
!   {"blo",	0xd3fe,		2,	ARM_EXT_V4T, do_t_branch9},
!   {"bmi",	0xd4fe,		2,	ARM_EXT_V4T, do_t_branch9},
!   {"bpl",	0xd5fe,		2,	ARM_EXT_V4T, do_t_branch9},
!   {"bvs",	0xd6fe,		2,	ARM_EXT_V4T, do_t_branch9},
!   {"bvc",	0xd7fe,		2,	ARM_EXT_V4T, do_t_branch9},
!   {"bhi",	0xd8fe,		2,	ARM_EXT_V4T, do_t_branch9},
!   {"bls",	0xd9fe,		2,	ARM_EXT_V4T, do_t_branch9},
!   {"bge",	0xdafe,		2,	ARM_EXT_V4T, do_t_branch9},
!   {"blt",	0xdbfe,		2,	ARM_EXT_V4T, do_t_branch9},
!   {"bgt",	0xdcfe,		2,	ARM_EXT_V4T, do_t_branch9},
!   {"ble",	0xddfe,		2,	ARM_EXT_V4T, do_t_branch9},
!   {"bal",	0xdefe,		2,	ARM_EXT_V4T, do_t_branch9},
!   {"bic",	0x4380,		2,	ARM_EXT_V4T, do_t_arit},
!   {"bl",	0xf7fffffe,	4,	ARM_EXT_V4T, do_t_branch23},
!   {"bx",	0x4700,		2,	ARM_EXT_V4T, do_t_bx},
!   {"cmn",	T_OPCODE_CMN,	2,	ARM_EXT_V4T, do_t_arit},
!   {"cmp",	0x0000,		2,	ARM_EXT_V4T, do_t_compare},
!   {"eor",	0x4040,		2,	ARM_EXT_V4T, do_t_arit},
!   {"ldmia",	0xc800,		2,	ARM_EXT_V4T, do_t_ldmstm},
!   {"ldr",	0x0000,		2,	ARM_EXT_V4T, do_t_ldr},
!   {"ldrb",	0x0000,		2,	ARM_EXT_V4T, do_t_ldrb},
!   {"ldrh",	0x0000,		2,	ARM_EXT_V4T, do_t_ldrh},
!   {"ldrsb",	0x5600,		2,	ARM_EXT_V4T, do_t_lds},
!   {"ldrsh",	0x5e00,		2,	ARM_EXT_V4T, do_t_lds},
!   {"ldsb",	0x5600,		2,	ARM_EXT_V4T, do_t_lds},
!   {"ldsh",	0x5e00,		2,	ARM_EXT_V4T, do_t_lds},
!   {"lsl",	0x0000,		2,	ARM_EXT_V4T, do_t_lsl},
!   {"lsr",	0x0000,		2,	ARM_EXT_V4T, do_t_lsr},
!   {"mov",	0x0000,		2,	ARM_EXT_V4T, do_t_mov},
!   {"mul",	T_OPCODE_MUL,	2,	ARM_EXT_V4T, do_t_arit},
!   {"mvn",	T_OPCODE_MVN,	2,	ARM_EXT_V4T, do_t_arit},
!   {"neg",	T_OPCODE_NEG,	2,	ARM_EXT_V4T, do_t_arit},
!   {"orr",	0x4300,		2,	ARM_EXT_V4T, do_t_arit},
!   {"pop",	0xbc00,		2,	ARM_EXT_V4T, do_t_push_pop},
!   {"push",	0xb400,		2,	ARM_EXT_V4T, do_t_push_pop},
!   {"ror",	0x41c0,		2,	ARM_EXT_V4T, do_t_arit},
!   {"sbc",	0x4180,		2,	ARM_EXT_V4T, do_t_arit},
!   {"stmia",	0xc000,		2,	ARM_EXT_V4T, do_t_ldmstm},
!   {"str",	0x0000,		2,	ARM_EXT_V4T, do_t_str},
!   {"strb",	0x0000,		2,	ARM_EXT_V4T, do_t_strb},
!   {"strh",	0x0000,		2,	ARM_EXT_V4T, do_t_strh},
!   {"swi",	0xdf00,		2,	ARM_EXT_V4T, do_t_swi},
!   {"sub",	0x0000,		2,	ARM_EXT_V4T, do_t_sub},
!   {"tst",	T_OPCODE_TST,	2,	ARM_EXT_V4T, do_t_arit},
!   /* Pseudo ops:  */
!   {"adr",       0x0000,         2,      ARM_EXT_V4T, do_t_adr},
!   {"nop",       0x46C0,         2,      ARM_EXT_V4T, do_t_nop},      /* mov r8,r8  */
!   /* Thumb v2 (ARMv5T).  */
!   {"blx",	0,		0,	ARM_EXT_V5T, do_t_blx},
!   {"bkpt",	0xbe00,		2,	ARM_EXT_V5T, do_t_bkpt},
! 
!   /* ARM V6.  */
!   {"cpsie",	0xb660,		2,	ARM_EXT_V6,  do_t_cps},
!   {"cpsid",     0xb670,		2,	ARM_EXT_V6,  do_t_cps},
!   {"cpy",	0x4600,		2,	ARM_EXT_V6,  do_t_cpy},
!   {"rev",	0xba00,		2,	ARM_EXT_V6,  do_t_arit},
!   {"rev16",	0xba40,		2,	ARM_EXT_V6,  do_t_arit},
!   {"revsh",	0xbac0,		2,	ARM_EXT_V6,  do_t_arit},
!   {"setend",	0xb650,		2,	ARM_EXT_V6,  do_t_setend},
!   {"sxth",	0xb200,		2,	ARM_EXT_V6,  do_t_arit},
!   {"sxtb",	0xb240,		2,	ARM_EXT_V6,  do_t_arit},
!   {"uxth",	0xb280,		2,	ARM_EXT_V6,  do_t_arit},
!   {"uxtb",	0xb2c0,		2,	ARM_EXT_V6,  do_t_arit},
! };
  
  void
! md_begin (void)
  {
    unsigned mach;
    unsigned int i;
*************** md_begin ()
*** 11766,11772 ****
  #define NT_VERSION  1
  #define NT_ARCH     2
  #endif
!   
    {
      segT current_seg = now_seg;
      subsegT current_subseg = now_subseg;
--- 11188,11194 ----
  #define NT_VERSION  1
  #define NT_ARCH     2
  #endif
! 
    {
      segT current_seg = now_seg;
      subsegT current_subseg = now_subseg;
*************** md_begin ()
*** 11801,11807 ****
        case bfd_mach_arm_5TE:     arch_string = "armv5te"; break;
        case bfd_mach_arm_XScale:  arch_string = "XScale"; break;
        case bfd_mach_arm_ep9312:  arch_string = "ep9312"; break;
!       case bfd_mach_arm_iWMMXt:  arch_string = "iWMMXt"; break;	
        }
  
      arm_add_note (NOTE_ARCH_STRING, arch_string, NT_ARCH);
--- 11223,11229 ----
        case bfd_mach_arm_5TE:     arch_string = "armv5te"; break;
        case bfd_mach_arm_XScale:  arch_string = "XScale"; break;
        case bfd_mach_arm_ep9312:  arch_string = "ep9312"; break;
!       case bfd_mach_arm_iWMMXt:  arch_string = "iWMMXt"; break;
        }
  
      arm_add_note (NOTE_ARCH_STRING, arch_string, NT_ARCH);
*************** md_begin ()
*** 11810,11816 ****
    }
  #endif
  #endif /* Suppressed code.  */
!   
    bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
  }
  
--- 11232,11238 ----
    }
  #endif
  #endif /* Suppressed code.  */
! 
    bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
  }
  
*************** md_begin ()
*** 11822,11831 ****
     LITTLENUMS (shorts, here at least).  */
  
  void
! md_number_to_chars (buf, val, n)
!      char * buf;
!      valueT val;
!      int    n;
  {
    if (target_big_endian)
      number_to_chars_bigendian (buf, val, n);
--- 11244,11250 ----
     LITTLENUMS (shorts, here at least).  */
  
  void
! md_number_to_chars (char * buf, valueT val, int n)
  {
    if (target_big_endian)
      number_to_chars_bigendian (buf, val, n);
*************** md_number_to_chars (buf, val, n)
*** 11834,11842 ****
  }
  
  static valueT
! md_chars_to_number (buf, n)
!      char * buf;
!      int    n;
  {
    valueT result = 0;
    unsigned char * where = (unsigned char *) buf;
--- 11253,11259 ----
  }
  
  static valueT
! md_chars_to_number (char * buf, int n)
  {
    valueT result = 0;
    unsigned char * where = (unsigned char *) buf;
*************** md_chars_to_number (buf, n)
*** 11876,11885 ****
     ??? The format of 12 byte floats is uncertain according to gcc's arm.h.  */
  
  char *
! md_atof (type, litP, sizeP)
!      char   type;
!      char * litP;
!      int *  sizeP;
  {
    int prec;
    LITTLENUM_TYPE words[MAX_LITTLENUMS];
--- 11293,11299 ----
     ??? The format of 12 byte floats is uncertain according to gcc's arm.h.  */
  
  char *
! md_atof (int type, char * litP, int * sizeP)
  {
    int prec;
    LITTLENUM_TYPE words[MAX_LITTLENUMS];
*************** md_atof (type, litP, sizeP)
*** 11956,11963 ****
     themselves.  */
  
  long
! md_pcrel_from (fixP)
!      fixS * fixP;
  {
    if (fixP->fx_addsy
        && S_GET_SEGMENT (fixP->fx_addsy) == undefined_section
--- 11370,11376 ----
     themselves.  */
  
  long
! md_pcrel_from (fixS * fixP)
  {
    if (fixP->fx_addsy
        && S_GET_SEGMENT (fixP->fx_addsy) == undefined_section
*************** md_pcrel_from (fixP)
*** 11984,11992 ****
  /* Round up a section size to the appropriate boundary.  */
  
  valueT
! md_section_align (segment, size)
!      segT   segment ATTRIBUTE_UNUSED;
!      valueT size;
  {
  #ifdef OBJ_ELF
    return size;
--- 11397,11404 ----
  /* Round up a section size to the appropriate boundary.  */
  
  valueT
! md_section_align (segT   segment ATTRIBUTE_UNUSED,
! 		  valueT size)
  {
  #ifdef OBJ_ELF
    return size;
*************** md_section_align (segment, size)
*** 12000,12007 ****
     Otherwise we have no need to default values of symbols.  */
  
  symbolS *
! md_undefined_symbol (name)
!      char * name ATTRIBUTE_UNUSED;
  {
  #ifdef OBJ_ELF
    if (name[0] == '_' && name[1] == 'G'
--- 11412,11418 ----
     Otherwise we have no need to default values of symbols.  */
  
  symbolS *
! md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
  {
  #ifdef OBJ_ELF
    if (name[0] == '_' && name[1] == 'G'
*************** md_undefined_symbol (name)
*** 12023,12093 ****
    return 0;
  }
  
- /* arm_reg_parse () := if it looks like a register, return its token and
-    advance the pointer.  */
- 
- static int
- arm_reg_parse (ccp, htab)
-      register char ** ccp;
-      struct hash_control *htab;
- {
-   char * start = * ccp;
-   char   c;
-   char * p;
-   struct reg_entry * reg;
- 
- #ifdef REGISTER_PREFIX
-   if (*start != REGISTER_PREFIX)
-     return FAIL;
-   p = start + 1;
- #else
-   p = start;
- #ifdef OPTIONAL_REGISTER_PREFIX
-   if (*p == OPTIONAL_REGISTER_PREFIX)
-     p++, start++;
- #endif
- #endif
-   if (!ISALPHA (*p) || !is_name_beginner (*p))
-     return FAIL;
- 
-   c = *p++;
-   while (ISALPHA (c) || ISDIGIT (c) || c == '_')
-     c = *p++;
- 
-   *--p = 0;
-   reg = (struct reg_entry *) hash_find (htab, start);
-   *p = c;
- 
-   if (reg)
-     {
-       *ccp = p;
-       return reg->number;
-     }
- 
-   return FAIL;
- }
- 
- /* Search for the following register name in each of the possible reg name
-    tables.  Return the classification if found, or REG_TYPE_MAX if not
-    present.  */
- static enum arm_reg_type
- arm_reg_parse_any (cp)
-      char *cp;
- {
-   int i;
- 
-   for (i = (int) REG_TYPE_FIRST; i < (int) REG_TYPE_MAX; i++)
-     if (arm_reg_parse (&cp, all_reg_maps[i].htab) != FAIL)
-       return (enum arm_reg_type) i;
- 
-   return REG_TYPE_MAX;
- }
- 
  void
! md_apply_fix3 (fixP, valP, seg)
!      fixS *   fixP;
!      valueT * valP;
!      segT     seg;
  {
    offsetT        value = * valP;
    offsetT        newval;
--- 11434,11443 ----
    return 0;
  }
  
  void
! md_apply_fix3 (fixS *   fixP,
! 	       valueT * valP,
! 	       segT     seg)
  {
    offsetT        value = * valP;
    offsetT        newval;
*************** md_apply_fix3 (fixP, valP, seg)
*** 12743,12758 ****
     format.  */
  
  arelent *
! tc_gen_reloc (section, fixp)
!      asection * section ATTRIBUTE_UNUSED;
!      fixS * fixp;
  {
    arelent * reloc;
    bfd_reloc_code_real_type code;
  
!   reloc = (arelent *) xmalloc (sizeof (arelent));
  
!   reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
    *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
    reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
  
--- 12093,12107 ----
     format.  */
  
  arelent *
! tc_gen_reloc (asection * section ATTRIBUTE_UNUSED,
! 	      fixS *     fixp)
  {
    arelent * reloc;
    bfd_reloc_code_real_type code;
  
!   reloc = xmalloc (sizeof (arelent));
  
!   reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
    *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
    reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
  
*************** tc_gen_reloc (section, fixp)
*** 12900,12916 ****
  }
  
  int
! md_estimate_size_before_relax (fragP, segtype)
!      fragS * fragP ATTRIBUTE_UNUSED;
!      segT    segtype ATTRIBUTE_UNUSED;
  {
    as_fatal (_("md_estimate_size_before_relax\n"));
    return 1;
  }
  
  static void
! output_inst (str)
!      const char *str;
  {
    char * to = NULL;
  
--- 12249,12303 ----
  }
  
  int
! md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED,
! 			       segT    segtype ATTRIBUTE_UNUSED)
  {
    as_fatal (_("md_estimate_size_before_relax\n"));
    return 1;
  }
  
+ /* We need to be able to fix up arbitrary expressions in some statements.
+    This is so that we can handle symbols that are an arbitrary distance from
+    the pc.  The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
+    which returns part of an address in a form which will be valid for
+    a data instruction.  We do this by pushing the expression into a symbol
+    in the expr_section, and creating a fix for that.  */
+ 
+ static void
+ fix_new_arm (fragS *       frag,
+ 	     int           where,
+ 	     short int     size,
+ 	     expressionS * exp,
+ 	     int           pc_rel,
+ 	     int           reloc)
+ {
+   fixS *           new_fix;
+   arm_fix_data *   arm_data;
+ 
+   switch (exp->X_op)
+     {
+     case O_constant:
+     case O_symbol:
+     case O_add:
+     case O_subtract:
+       new_fix = fix_new_exp (frag, where, size, exp, pc_rel, reloc);
+       break;
+ 
+     default:
+       new_fix = fix_new (frag, where, size, make_expr_symbol (exp), 0,
+ 			 pc_rel, reloc);
+       break;
+     }
+ 
+   /* Mark whether the fix is to a THUMB instruction, or an ARM
+      instruction.  */
+   arm_data = obstack_alloc (& notes, sizeof (arm_fix_data));
+   new_fix->tc_fix_data = (PTR) arm_data;
+   arm_data->thumb_mode = thumb_mode;
+ }
+ 
  static void
! output_inst (const char * str)
  {
    char * to = NULL;
  
*************** output_inst (str)
*** 12948,12955 ****
  }
  
  void
! md_assemble (str)
!      char * str;
  {
    char  c;
    char *p;
--- 12335,12341 ----
  }
  
  void
! md_assemble (char * str)
  {
    char  c;
    char *p;
*************** md_assemble (str)
*** 13007,13013 ****
  	  mapping_state (MAP_THUMB);
  	  inst.instruction = opcode->value;
  	  inst.size = opcode->size;
! 	  (*opcode->parms) (p);
  	  output_inst (str);
  	  return;
  	}
--- 12393,12399 ----
  	  mapping_state (MAP_THUMB);
  	  inst.instruction = opcode->value;
  	  inst.size = opcode->size;
! 	  opcode->parms (p);
  	  output_inst (str);
  	  return;
  	}
*************** md_assemble (str)
*** 13033,13039 ****
            mapping_state (MAP_ARM);
  	  inst.instruction = opcode->value;
  	  inst.size = INSN_SIZE;
! 	  (*opcode->parms) (p);
  	  output_inst (str);
  	  return;
  	}
--- 12419,12425 ----
            mapping_state (MAP_ARM);
  	  inst.instruction = opcode->value;
  	  inst.size = INSN_SIZE;
! 	  opcode->parms (p);
  	  output_inst (str);
  	  return;
  	}
*************** static struct arm_eabi_option_table arm_
*** 13479,13499 ****
  
  struct arm_long_option_table
  {
!   char *option;		/* Substring to match.  */
!   char *help;		/* Help information.  */
!   int (*func) PARAMS ((char *subopt));	/* Function to decode sub-option.  */
!   char *deprecated;	/* If non-null, print this message.  */
  };
  
  static int
! arm_parse_extension (str, opt_p)
!      char *str;
!      int *opt_p;
  {
    while (str != NULL && *str != 0)
      {
!       struct arm_arch_extension_table *opt;
!       char *ext;
        int optlen;
  
        if (*str != '+')
--- 12865,12883 ----
  
  struct arm_long_option_table
  {
!   char * option;		/* Substring to match.  */
!   char * help;			/* Help information.  */
!   int (* func) (char * subopt);	/* Function to decode sub-option.  */
!   char * deprecated;		/* If non-null, print this message.  */
  };
  
  static int
! arm_parse_extension (char * str, int * opt_p)
  {
    while (str != NULL && *str != 0)
      {
!       struct arm_arch_extension_table * opt;
!       char * ext;
        int optlen;
  
        if (*str != '+')
*************** arm_parse_extension (str, opt_p)
*** 13536,13546 ****
  }
  
  static int
! arm_parse_cpu (str)
!      char *str;
  {
!   struct arm_cpu_option_table *opt;
!   char *ext = strchr (str, '+');
    int optlen;
  
    if (ext != NULL)
--- 12920,12929 ----
  }
  
  static int
! arm_parse_cpu (char * str)
  {
!   struct arm_cpu_option_table * opt;
!   char * ext = strchr (str, '+');
    int optlen;
  
    if (ext != NULL)
*************** arm_parse_cpu (str)
*** 13571,13578 ****
  }
  
  static int
! arm_parse_arch (str)
!      char *str;
  {
    struct arm_arch_option_table *opt;
    char *ext = strchr (str, '+');
--- 12954,12960 ----
  }
  
  static int
! arm_parse_arch (char * str)
  {
    struct arm_arch_option_table *opt;
    char *ext = strchr (str, '+');
*************** arm_parse_arch (str)
*** 13591,13597 ****
  
  
    for (opt = arm_archs; opt->name != NULL; opt++)
!     if (strcmp (opt->name, str) == 0)
        {
  	march_cpu_opt = opt->value;
  	march_fpu_opt = opt->default_fpu;
--- 12973,12979 ----
  
  
    for (opt = arm_archs; opt->name != NULL; opt++)
!     if (streq (opt->name, str))
        {
  	march_cpu_opt = opt->value;
  	march_fpu_opt = opt->default_fpu;
*************** arm_parse_arch (str)
*** 13607,13619 ****
  }
  
  static int
! arm_parse_fpu (str)
!      char *str;
  {
!   struct arm_fpu_option_table *opt;
  
    for (opt = arm_fpus; opt->name != NULL; opt++)
!     if (strcmp (opt->name, str) == 0)
        {
  	mfpu_opt = opt->value;
  	return 1;
--- 12989,13000 ----
  }
  
  static int
! arm_parse_fpu (char * str)
  {
!   struct arm_fpu_option_table * opt;
  
    for (opt = arm_fpus; opt->name != NULL; opt++)
!     if (streq (opt->name, str))
        {
  	mfpu_opt = opt->value;
  	return 1;
*************** arm_parse_fpu (str)
*** 13624,13636 ****
  }
  
  static int
! arm_parse_float_abi (str)
!      char * str;
  {
!   struct arm_float_abi_option_table *opt;
  
    for (opt = arm_float_abis; opt->name != NULL; opt++)
!     if (strcmp (opt->name, str) == 0)
        {
  	mfloat_abi_opt = opt->value;
  	return 1;
--- 13005,13016 ----
  }
  
  static int
! arm_parse_float_abi (char * str)
  {
!   struct arm_float_abi_option_table * opt;
  
    for (opt = arm_float_abis; opt->name != NULL; opt++)
!     if (streq (opt->name, str))
        {
  	mfloat_abi_opt = opt->value;
  	return 1;
*************** arm_parse_float_abi (str)
*** 13642,13654 ****
  
  #ifdef OBJ_ELF
  static int
! arm_parse_eabi (str)
!      char * str;
  {
    struct arm_eabi_option_table *opt;
  
    for (opt = arm_eabis; opt->name != NULL; opt++)
!     if (strcmp (opt->name, str) == 0)
        {
  	meabi_flags = opt->value;
  	return 1;
--- 13022,13033 ----
  
  #ifdef OBJ_ELF
  static int
! arm_parse_eabi (char * str)
  {
    struct arm_eabi_option_table *opt;
  
    for (opt = arm_eabis; opt->name != NULL; opt++)
!     if (streq (opt->name, str))
        {
  	meabi_flags = opt->value;
  	return 1;
*************** struct arm_long_option_table arm_long_op
*** 13676,13684 ****
  };
  
  int
! md_parse_option (c, arg)
!      int    c;
!      char * arg;
  {
    struct arm_option_table *opt;
    struct arm_long_option_table *lopt;
--- 13055,13061 ----
  };
  
  int
! md_parse_option (int c, char * arg)
  {
    struct arm_option_table *opt;
    struct arm_long_option_table *lopt;
*************** md_parse_option (c, arg)
*** 13707,13713 ****
  	{
  	  if (c == opt->option[0]
  	      && ((arg == NULL && opt->option[1] == 0)
! 		  || strcmp (arg, opt->option + 1) == 0))
  	    {
  #if WARN_DEPRECATED
  	      /* If the option is deprecated, tell the user.  */
--- 13084,13090 ----
  	{
  	  if (c == opt->option[0]
  	      && ((arg == NULL && opt->option[1] == 0)
! 		  || streq (arg, opt->option + 1)))
  	    {
  #if WARN_DEPRECATED
  	      /* If the option is deprecated, tell the user.  */
*************** md_parse_option (c, arg)
*** 13739,13745 ****
  #endif
  
  	      /* Call the sup-option parser.  */
! 	      return (*lopt->func)(arg + strlen (lopt->option) - 1);
  	    }
  	}
  
--- 13116,13122 ----
  #endif
  
  	      /* Call the sup-option parser.  */
! 	      return lopt->func (arg + strlen (lopt->option) - 1);
  	    }
  	}
  
*************** md_parse_option (c, arg)
*** 13750,13757 ****
  }
  
  void
! md_show_usage (fp)
!      FILE * fp;
  {
    struct arm_option_table *opt;
    struct arm_long_option_table *lopt;
--- 13127,13133 ----
  }
  
  void
! md_show_usage (FILE * fp)
  {
    struct arm_option_table *opt;
    struct arm_long_option_table *lopt;
*************** md_show_usage (fp)
*** 13777,13831 ****
  #endif
  }
  
- /* We need to be able to fix up arbitrary expressions in some statements.
-    This is so that we can handle symbols that are an arbitrary distance from
-    the pc.  The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
-    which returns part of an address in a form which will be valid for
-    a data instruction.  We do this by pushing the expression into a symbol
-    in the expr_section, and creating a fix for that.  */
- 
- static void
- fix_new_arm (frag, where, size, exp, pc_rel, reloc)
-      fragS *       frag;
-      int           where;
-      short int     size;
-      expressionS * exp;
-      int           pc_rel;
-      int           reloc;
- {
-   fixS *           new_fix;
-   arm_fix_data *   arm_data;
- 
-   switch (exp->X_op)
-     {
-     case O_constant:
-     case O_symbol:
-     case O_add:
-     case O_subtract:
-       new_fix = fix_new_exp (frag, where, size, exp, pc_rel, reloc);
-       break;
- 
-     default:
-       new_fix = fix_new (frag, where, size, make_expr_symbol (exp), 0,
- 			 pc_rel, reloc);
-       break;
-     }
- 
-   /* Mark whether the fix is to a THUMB instruction, or an ARM
-      instruction.  */
-   arm_data = (arm_fix_data *) obstack_alloc (& notes, sizeof (arm_fix_data));
-   new_fix->tc_fix_data = (PTR) arm_data;
-   arm_data->thumb_mode = thumb_mode;
- }
- 
  /* This fix_new is called by cons via TC_CONS_FIX_NEW.  */
  
  void
! cons_fix_new_arm (frag, where, size, exp)
!      fragS *       frag;
!      int           where;
!      int           size;
!      expressionS * exp;
  {
    bfd_reloc_code_real_type type;
    int pcrel = 0;
--- 13153,13165 ----
  #endif
  }
  
  /* This fix_new is called by cons via TC_CONS_FIX_NEW.  */
  
  void
! cons_fix_new_arm (fragS *       frag,
! 		  int           where,
! 		  int           size,
! 		  expressionS * exp)
  {
    bfd_reloc_code_real_type type;
    int pcrel = 0;
*************** cons_fix_new_arm (frag, where, size, exp
*** 13857,13863 ****
     references are made to a null symbol pointer.  */
  
  void
! arm_cleanup ()
  {
    literal_pool * pool;
  
--- 13191,13197 ----
     references are made to a null symbol pointer.  */
  
  void
! arm_cleanup (void)
  {
    literal_pool * pool;
  
*************** arm_cleanup ()
*** 13873,13886 ****
  }
  
  void
! arm_start_line_hook ()
  {
    last_label_seen = NULL;
  }
  
  void
! arm_frob_label (sym)
!      symbolS * sym;
  {
    last_label_seen = sym;
  
--- 13207,13219 ----
  }
  
  void
! arm_start_line_hook (void)
  {
    last_label_seen = NULL;
  }
  
  void
! arm_frob_label (symbolS * sym)
  {
    last_label_seen = sym;
  
*************** arm_frob_label (sym)
*** 13938,13944 ****
     ARM ones.  */
  
  void
! arm_adjust_symtab ()
  {
  #ifdef OBJ_COFF
    symbolS * sym;
--- 13271,13277 ----
     ARM ones.  */
  
  void
! arm_adjust_symtab (void)
  {
  #ifdef OBJ_COFF
    symbolS * sym;
*************** arm_adjust_symtab ()
*** 14008,14014 ****
  }
  
  int
! arm_data_in_code ()
  {
    if (thumb_mode && ! strncmp (input_line_pointer + 1, "data:", 5))
      {
--- 13341,13347 ----
  }
  
  int
! arm_data_in_code (void)
  {
    if (thumb_mode && ! strncmp (input_line_pointer + 1, "data:", 5))
      {
*************** arm_data_in_code ()
*** 14022,14029 ****
  }
  
  char *
! arm_canonicalize_symbol_name (name)
!      char * name;
  {
    int len;
  
--- 13355,13361 ----
  }
  
  char *
! arm_canonicalize_symbol_name (char * name)
  {
    int len;
  
*************** arm_canonicalize_symbol_name (name)
*** 14036,14043 ****
  
  #if defined OBJ_COFF || defined OBJ_ELF
  void
! arm_validate_fix (fixP)
!      fixS * fixP;
  {
    /* If the destination of the branch is a defined symbol which does not have
       the THUMB_FUNC attribute, then we must be calling a function which has
--- 13368,13374 ----
  
  #if defined OBJ_COFF || defined OBJ_ELF
  void
! arm_validate_fix (fixS * fixP)
  {
    /* If the destination of the branch is a defined symbol which does not have
       the THUMB_FUNC attribute, then we must be calling a function which has
*************** arm_validate_fix (fixP)
*** 14054,14061 ****
  #endif
  
  int
! arm_force_relocation (fixp)
!      struct fix * fixp;
  {
  #if defined (OBJ_COFF) && defined (TE_PE)
    if (fixp->fx_r_type == BFD_RELOC_RVA)
--- 13385,13391 ----
  #endif
  
  int
! arm_force_relocation (struct fix * fixp)
  {
  #if defined (OBJ_COFF) && defined (TE_PE)
    if (fixp->fx_r_type == BFD_RELOC_RVA)
*************** arm_force_relocation (fixp)
*** 14086,14093 ****
     it is adjustable.  */
  
  bfd_boolean
! arm_fix_adjustable (fixP)
!    fixS * fixP;
  {
    if (fixP->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE)
      return 1;
--- 13416,13422 ----
     it is adjustable.  */
  
  bfd_boolean
! arm_fix_adjustable (fixS * fixP)
  {
    if (fixP->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE)
      return 1;
*************** arm_fix_adjustable (fixP)
*** 14110,14117 ****
     they reside in Thumb code), but at the moment they will not.  */
  
  bfd_boolean
! arm_fix_adjustable (fixP)
!    fixS * fixP;
  {
    if (fixP->fx_addsy == NULL)
      return 1;
--- 13439,13445 ----
     they reside in Thumb code), but at the moment they will not.  */
  
  bfd_boolean
! arm_fix_adjustable (fixS * fixP)
  {
    if (fixP->fx_addsy == NULL)
      return 1;
*************** arm_fix_adjustable (fixP)
*** 14136,14148 ****
  }
  
  const char *
! elf32_arm_target_format ()
  {
  #ifdef TE_SYMBIAN
    return (target_big_endian
  	  ? "elf32-bigarm-symbian"
  	  : "elf32-littlearm-symbian");
! #else 
    if (target_big_endian)
      {
        if (target_oabi)
--- 13464,13476 ----
  }
  
  const char *
! elf32_arm_target_format (void)
  {
  #ifdef TE_SYMBIAN
    return (target_big_endian
  	  ? "elf32-bigarm-symbian"
  	  : "elf32-littlearm-symbian");
! #else
    if (target_big_endian)
      {
        if (target_oabi)
*************** elf32_arm_target_format ()
*** 14161,14217 ****
  }
  
  void
! armelf_frob_symbol (symp, puntp)
!      symbolS * symp;
!      int *     puntp;
  {
    elf_frob_symbol (symp, puntp);
  }
  
- static bfd_reloc_code_real_type
- arm_parse_reloc ()
- {
-   char         id [16];
-   char *       ip;
-   unsigned int i;
-   static struct
-   {
-     char * str;
-     int    len;
-     bfd_reloc_code_real_type reloc;
-   }
-   reloc_map[] =
-   {
- #define MAP(str,reloc) { str, sizeof (str) - 1, reloc }
-     MAP ("(got)",    BFD_RELOC_ARM_GOT32),
-     MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF),
-     /* ScottB: Jan 30, 1998 - Added support for parsing "var(PLT)"
-        branch instructions generated by GCC for PLT relocs.  */
-     MAP ("(plt)",    BFD_RELOC_ARM_PLT32),
-     MAP ("(target1)", BFD_RELOC_ARM_TARGET1),
-     MAP ("(sbrel)", BFD_RELOC_ARM_SBREL32),
-     MAP ("(target2)", BFD_RELOC_ARM_TARGET2),
-     { NULL, 0,         BFD_RELOC_UNUSED }
- #undef MAP
-   };
- 
-   for (i = 0, ip = input_line_pointer;
-        i < sizeof (id) && (ISALNUM (*ip) || ISPUNCT (*ip));
-        i++, ip++)
-     id[i] = TOLOWER (*ip);
- 
-   for (i = 0; reloc_map[i].str; i++)
-     if (strncmp (id, reloc_map[i].str, reloc_map[i].len) == 0)
-       break;
- 
-   input_line_pointer += reloc_map[i].len;
- 
-   return reloc_map[i].reloc;
- }
- 
  static void
! s_arm_elf_cons (nbytes)
!      int nbytes;
  {
    expressionS exp;
  
--- 13489,13502 ----
  }
  
  void
! armelf_frob_symbol (symbolS * symp,
! 		    int *     puntp)
  {
    elf_frob_symbol (symp, puntp);
  }
  
  static void
! s_arm_elf_cons (int nbytes)
  {
    expressionS exp;
  
*************** s_arm_elf_cons (nbytes)
*** 14248,14254 ****
  		    howto->name, nbytes);
  	  else
  	    {
! 	      register char *p = frag_more ((int) nbytes);
  	      int offset = nbytes - size;
  
  	      fix_new_exp (frag_now, p - frag_now->fr_literal + offset, size,
--- 13533,13539 ----
  		    howto->name, nbytes);
  	  else
  	    {
! 	      char *p = frag_more ((int) nbytes);
  	      int offset = nbytes - size;
  
  	      fix_new_exp (frag_now, p - frag_now->fr_literal + offset, size,
*************** s_arm_rel31 (int ignored ATTRIBUTE_UNUSE
*** 14274,14280 ****
    expressionS exp;
    char *p;
    valueT highbit;
!     
    SKIP_WHITESPACE ();
  
    highbit = 0;
--- 13559,13565 ----
    expressionS exp;
    char *p;
    valueT highbit;
! 
    SKIP_WHITESPACE ();
  
    highbit = 0;
*************** s_arm_rel31 (int ignored ATTRIBUTE_UNUSE
*** 14315,14322 ****
     of an rs_align_code fragment.  */
  
  void
! arm_handle_align (fragP)
!      fragS *fragP;
  {
    static char const arm_noop[4] = { 0x00, 0x00, 0xa0, 0xe1 };
    static char const thumb_noop[2] = { 0xc0, 0x46 };
--- 13600,13606 ----
     of an rs_align_code fragment.  */
  
  void
! arm_handle_align (fragS * fragP)
  {
    static char const arm_noop[4] = { 0x00, 0x00, 0xa0, 0xe1 };
    static char const thumb_noop[2] = { 0xc0, 0x46 };
*************** arm_handle_align (fragP)
*** 14378,14386 ****
     frag in a code section.  */
  
  void
! arm_frag_align_code (n, max)
!      int n;
!      int max;
  {
    char * p;
  
--- 13662,13668 ----
     frag in a code section.  */
  
  void
! arm_frag_align_code (int n, int max)
  {
    char * p;
  
*************** arm_frag_align_code (n, max)
*** 14397,14411 ****
  		(offsetT) n,
  		(char *) NULL);
    *p = 0;
- 
  }
  
  /* Perform target specific initialisation of a frag.  */
  
  void
! arm_init_frag (fragP)
!      fragS *fragP;
  {
    /* Record whether this frag is in an ARM or a THUMB area.  */
    fragP->tc_frag_data = thumb_mode;
  }
--- 13679,13726 ----
  		(offsetT) n,
  		(char *) NULL);
    *p = 0;
  }
  
  /* Perform target specific initialisation of a frag.  */
  
  void
! arm_init_frag (fragS * fragP)
  {
    /* Record whether this frag is in an ARM or a THUMB area.  */
    fragP->tc_frag_data = thumb_mode;
  }
+ 
+ /* This table describes all the machine specific pseudo-ops the assembler
+    has to support.  The fields are:
+      pseudo-op name without dot
+      function to call to execute this pseudo-op
+      Integer arg to pass to the function.  */
+ 
+ const pseudo_typeS md_pseudo_table[] =
+ {
+   /* Never called because '.req' does not start a line.  */
+   { "req",         s_req,         0 },
+   { "unreq",       s_unreq,       0 },
+   { "bss",         s_bss,         0 },
+   { "align",       s_align,       0 },
+   { "arm",         s_arm,         0 },
+   { "thumb",       s_thumb,       0 },
+   { "code",        s_code,        0 },
+   { "force_thumb", s_force_thumb, 0 },
+   { "thumb_func",  s_thumb_func,  0 },
+   { "thumb_set",   s_thumb_set,   0 },
+   { "even",        s_even,        0 },
+   { "ltorg",       s_ltorg,       0 },
+   { "pool",        s_ltorg,       0 },
+ #ifdef OBJ_ELF
+   { "word",        s_arm_elf_cons, 4 },
+   { "long",        s_arm_elf_cons, 4 },
+   { "rel31",       s_arm_rel31,   0 },
+ #else
+   { "word",        cons, 4},
+ #endif
+   { "extend",      float_cons, 'x' },
+   { "ldouble",     float_cons, 'x' },
+   { "packed",      float_cons, 'p' },
+   { 0, 0, 0 }
+ };

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]