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]

PATCH gas/arm support for VFP



Finally, this is what it has all been leading up to...

This patch adds support to the assembler for the new VFP instructions, 
as defined in the ARM Architecture Reference Manual (second edition).

R.

2002-01-15  Richard Earnshaw  <rearnsha@arm.com>

	Support for VFP instructions
	* tc-arm.c (CP_WB_OK, CP_NO_WB): New defines.
	(cp_address_required_here): New argument wb_ok.  When false, do not
	accept write-back forms of addressing.  Change all callers.
	(FPU_VFP_EXT_NONE, FPU_VFP_EXT_V1xD, FPU_VFP_VFP_V1)
	(FPU_VFP_EXT_V2): Define.
	(FPU_ARCH_VFP, FPU_ARCH_VFP_V1xD, FPU_ARCH_VFP_V1, FPU_ARCH_VFP_V2):
	Define in terms of above.
	(vfp_dp_reg_pos, vfp_sp_reg_pos, vfp_ldstm_type): New enums.
	(vfp_reg): New struct.
	(vfp_regs): New array of registers.
	(insns): Add VFP instructions.
	(sn_table): New array of VFP single-precision register names.
	(dn_table): New array of VFP double-precision register names.
	(all_reg_maps): Add the new register tables.
	(arm_reg_type): Add new values for above.  Increase RET_TYPE_MAX.
	(vfp_sp_reg_required_here, vfp_dp_reg_required_here, do_vfp_sp_monadic)
	(do_vfp_dp_monadic, do_vfp_sp_dyadic, do_vfp_dp_dyadic)
	(do_vfp_reg_from_sp, do_vfp_sp_reg2, do_vfp_sp_from_reg)
	(do_vfp_reg_from_dp, do_vfp_reg2_from_dp, do_vfp_dp_from_reg)
	(do_vfp_dp_from_reg2, vfp_psr_parse, vfp_psr_required_here)
	(do_vfp_reg_from_ctrl, do_vfp_ctrl_from_reg, do_vfp_sp_ldst)
	(do_vfp_dp_ldst, vfp_sp_reg_list, vfp_dp_reg_list, vfp_sp_ldstm)
	(vfp_dp_ldstm, do_vfp_sp_ldstmia, do_vfp_sp_ldstmdb, do_vfp_ldstmia)
	(do_vfp_dp_ldstmdb, do_vfp_xp_ldstmia, do_vfp_xp_ldstmdb)
	(do_vfp_sp_compare_z, do_vfp_dp_compare_z, do_vfp_dp_sp_cvt)
	(do_vfp_sp_dp_cvt): New functions.
	(md_begin): Set soft-float flag for appropriate VFP work.
	(md_atof): Handle VFP-format doubles.
	(md_parse_option): Handle VFP command-line options.
	(md_show_usage): Display VFP command-line options.

Testsuite:

2002-01-15   Richard Earnshaw  <rearnsha@arm.com>

	* gas/arm/vfp1.s gas/arm/vf1.d: New files.
	* gas/arm/vfp1xD.s gas/arm/vf1xD.d: New files.
	* gas/arm/vfp-bad.s gas/arm/vfp-bad.l: New files.
	* gas/arm/arm.exp: Run new VFP tests.


Index: config/tc-arm.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-arm.c,v
retrieving revision 1.111
diff -p -r1.111 tc-arm.c
*** tc-arm.c	2002/01/15 14:43:09	1.111
--- tc-arm.c	2002/01/15 15:50:32
***************
*** 82,94 ****
  #define ARM_ANY		0x00ffffff
  #define ARM_ALL		ARM_ANY
  
! #define FPU_FPA_EXT_V1	0x80000000	/* Base FPA instruction set.  */
! #define FPU_FPA_EXT_V2	0x40000000	/* LFM/SFM.		      */
! #define FPU_NONE	0
  
  #define FPU_ARCH_FPE	 FPU_FPA_EXT_V1
  #define FPU_ARCH_FPA	(FPU_ARCH_FPE | FPU_FPA_EXT_V2)
  
  /* Some useful combinations.  */
  #define FPU_ANY		0xff000000	/* Note this is ~ARM_ANY.  */
  
--- 82,103 ----
  #define ARM_ANY		0x00ffffff
  #define ARM_ALL		ARM_ANY
  
! #define FPU_FPA_EXT_V1	 0x80000000	/* Base FPA instruction set.  */
! #define FPU_FPA_EXT_V2	 0x40000000	/* LFM/SFM.		      */
! #define FPU_VFP_EXT_NONE 0x20000000	/* Use VFP word-ordering.     */
! #define FPU_VFP_EXT_V1xD 0x10000000	/* Base VFP instruction set.  */
! #define FPU_VFP_EXT_V1	 0x08000000	/* Double-precision insns.    */
! #define FPU_VFP_EXT_V2	 0x04000000	/* ARM10E VFPr1.	      */
! #define FPU_NONE	 0
  
  #define FPU_ARCH_FPE	 FPU_FPA_EXT_V1
  #define FPU_ARCH_FPA	(FPU_ARCH_FPE | FPU_FPA_EXT_V2)
  
+ #define FPU_ARCH_VFP       FPU_VFP_EXT_NONE
+ #define FPU_ARCH_VFP_V1xD (FPU_VFP_EXT_V1xD | FPU_VFP_EXT_NONE)
+ #define FPU_ARCH_VFP_V1   (FPU_ARCH_VFP_V1xD | FPU_VFP_EXT_V1)
+ #define FPU_ARCH_VFP_V2	  (FPU_ARCH_VFP_V1 | FPU_VFP_EXT_V2)
+ 
  /* Some useful combinations.  */
  #define FPU_ANY		0xff000000	/* Note this is ~ARM_ANY.  */
  
***************
*** 116,121 ****
--- 125,131 ----
  #endif
  #endif
  
+ /* For backwards compatibility we default to the FPA.  */
  #ifndef FPU_DEFAULT
  #define FPU_DEFAULT FPU_ARCH_FPA
  #endif
*************** LITTLENUM_TYPE fp_values[NUM_FLOAT_VALS]
*** 264,269 ****
--- 274,283 ----
  #define FAIL	(-1)
  #define SUCCESS (0)
  
+ /* Whether a Co-processor load/store operation accepts write-back forms.  */
+ #define CP_WB_OK 1
+ #define CP_NO_WB 0
+ 
  #define SUFF_S 1
  #define SUFF_D 2
  #define SUFF_E 3
*************** static const struct asm_psr psrs[] =
*** 468,473 ****
--- 482,519 ----
    {"SPSR_cxsf",	false, PSR_c | PSR_x | PSR_s | PSR_f},
  };
  
+ enum vfp_dp_reg_pos
+ {
+   VFP_REG_Dd, VFP_REG_Dm, VFP_REG_Dn
+ };
+ 
+ enum vfp_sp_reg_pos
+ {
+   VFP_REG_Sd, VFP_REG_Sm, VFP_REG_Sn
+ };
+ 
+ enum vfp_ldstm_type
+ {
+   VFP_LDSTMIA, VFP_LDSTMDB, VFP_LDSTMIAX, VFP_LDSTMDBX
+ };
+ 
+ /* VFP system registers.  */
+ struct vfp_reg
+ {
+   const char *name;
+   unsigned long regno;
+ };
+ 
+ static const struct vfp_reg vfp_regs[] = 
+ {
+   {"fpsid", 0x00000000},
+   {"FPSID", 0x00000000},
+   {"fpscr", 0x00010000},
+   {"FPSCR", 0x00010000},
+   {"fpexc", 0x00080000},
+   {"FPEXC", 0x00080000}
+ };
+ 
  /* Structure for a hash table entry for a register.  */
  struct reg_entry
  {
*************** static const struct reg_entry fn_table[]
*** 532,537 ****
--- 578,607 ----
    {NULL, 0}
  };
  
+ /* VFP SP Registers.  */
+ static const struct reg_entry sn_table[] =
+ {
+   {"s0",  0},  {"s1",  1},  {"s2",  2},	 {"s3", 3},
+   {"s4",  4},  {"s5",  5},  {"s6",  6},	 {"s7", 7},
+   {"s8",  8},  {"s9",  9},  {"s10", 10}, {"s11", 11},
+   {"s12", 12}, {"s13", 13}, {"s14", 14}, {"s15", 15},
+   {"s16", 16}, {"s17", 17}, {"s18", 18}, {"s19", 19},
+   {"s20", 20}, {"s21", 21}, {"s22", 22}, {"s23", 23},
+   {"s24", 24}, {"s25", 25}, {"s26", 26}, {"s27", 27},
+   {"s28", 28}, {"s29", 29}, {"s30", 30}, {"s31", 31},
+   {NULL, 0}
+ };
+ 
+ /* VFP DP Registers.  */
+ static const struct reg_entry dn_table[] =
+ {
+   {"d0",  0},  {"d1",  1},  {"d2",  2},	 {"d3", 3},
+   {"d4",  4},  {"d5",  5},  {"d6",  6},	 {"d7", 7},
+   {"d8",  8},  {"d9",  9},  {"d10", 10}, {"d11", 11},
+   {"d12", 12}, {"d13", 13}, {"d14", 14}, {"d15", 15},
+   {NULL, 0}
+ };
+ 
  /* Cirrus DSP coprocessor registers.  */
  static const struct reg_entry mav_mvf_table[] =
  {
*************** struct reg_map all_reg_maps[] =
*** 595,600 ****
--- 665,672 ----
    {cp_table,        15, NULL, N_("bad or missing co-processor number")},
    {cn_table,        15, NULL, N_("co-processor register expected")},
    {fn_table,         7, NULL, N_("FPA register expected")},
+   {sn_table,	    31, NULL, N_("VFP single precision register expected")},
+   {dn_table,	    15, NULL, N_("VFP double precision register expected")},
    {mav_mvf_table,   15, NULL, N_("Maverick MVF register expected")},
    {mav_mvd_table,   15, NULL, N_("Maverick MVD register expected")},
    {mav_mvfx_table,  15, NULL, N_("Maverick MVFX register expected")},
*************** enum arm_reg_type
*** 611,624 ****
    REG_TYPE_CP = 1,
    REG_TYPE_CN = 2,
    REG_TYPE_FN = 3,
!   REG_TYPE_MVF = 4,
!   REG_TYPE_MVD = 5,
!   REG_TYPE_MVFX = 6,
!   REG_TYPE_MVDX = 7,
!   REG_TYPE_MVAX = 8,
!   REG_TYPE_DSPSC = 9,
  
!   REG_TYPE_MAX = 10
  };
  
  /* Functions called by parser.  */
--- 683,698 ----
    REG_TYPE_CP = 1,
    REG_TYPE_CN = 2,
    REG_TYPE_FN = 3,
!   REG_TYPE_SN = 4,
!   REG_TYPE_DN = 5,
!   REG_TYPE_MVF = 6,
!   REG_TYPE_MVD = 7,
!   REG_TYPE_MVFX = 8,
!   REG_TYPE_MVDX = 9,
!   REG_TYPE_MVAX = 10,
!   REG_TYPE_DSPSC = 11,
  
!   REG_TYPE_MAX = 12
  };
  
  /* Functions called by parser.  */
*************** static void do_fpa_cmp		PARAMS ((char *)
*** 691,696 ****
--- 765,797 ----
  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_sp_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_mia		PARAMS ((char *));
  static void do_mar		PARAMS ((char *));
*************** static int co_proc_number	PARAMS ((char 
*** 776,783 ****
  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 cp_address_offset	PARAMS ((char **));
! static int cp_address_required_here	PARAMS ((char **));
  static int my_get_float_expression	PARAMS ((char **));
  static int skip_past_comma	PARAMS ((char **));
  static int walk_no_bignums	PARAMS ((symbolS *));
--- 877,892 ----
  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 const struct asm_opcode insns[] =
*** 1473,1478 ****
--- 1582,1700 ----
    {"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_sp_reg2},
+   {"fmrrs",   0xec500a10, 5, FPU_VFP_EXT_V2,   do_vfp_sp_reg2},
+   {"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_EXT_XSCALE,   do_mia},
    {"miaph",      0xee280010, 5,  ARM_EXT_XSCALE,   do_mia},
*************** cp_address_offset (str)
*** 2723,2730 ****
  }
  
  static int
! cp_address_required_here (str)
       char ** str;
  {
    char * p = * str;
    int    pre_inc = 0;
--- 2945,2953 ----
  }
  
  static int
! cp_address_required_here (str, wb_ok)
       char ** str;
+      int wb_ok;
  {
    char * p = * str;
    int    pre_inc = 0;
*************** cp_address_required_here (str)
*** 2746,2752 ****
  	{
  	  p++;
  
! 	  if (skip_past_comma (& p) == SUCCESS)
  	    {
  	      /* [Rn], #expr  */
  	      write_back = WRITE_BACK;
--- 2969,2975 ----
  	{
  	  p++;
  
! 	  if (wb_ok && skip_past_comma (& p) == SUCCESS)
  	    {
  	      /* [Rn], #expr  */
  	      write_back = WRITE_BACK;
*************** cp_address_required_here (str)
*** 2788,2794 ****
  
  	  skip_whitespace (p);
  
! 	  if (*p == '!')
  	    {
  	      if (reg == REG_PC)
  		{
--- 3011,3017 ----
  
  	  skip_whitespace (p);
  
! 	  if (wb_ok && *p == '!')
  	    {
  	      if (reg == REG_PC)
  		{
*************** do_lstc2 (str)
*** 3496,3502 ****
  	inst.error = BAD_ARGS;
      }
    else if (skip_past_comma (& str) == FAIL
! 	   || cp_address_required_here (& str) == FAIL)
      {
        if (! inst.error)
  	inst.error = BAD_ARGS;
--- 3719,3725 ----
  	inst.error = BAD_ARGS;
      }
    else if (skip_past_comma (& str) == FAIL
! 	   || cp_address_required_here (&str, CP_WB_OK) == FAIL)
      {
        if (! inst.error)
  	inst.error = BAD_ARGS;
*************** do_lstc (str)
*** 5724,5730 ****
      }
  
    if (skip_past_comma (&str) == FAIL
!       || cp_address_required_here (&str) == FAIL)
      {
        if (! inst.error)
  	inst.error = BAD_ARGS;
--- 5947,5953 ----
      }
  
    if (skip_past_comma (&str) == FAIL
!       || cp_address_required_here (&str, CP_WB_OK) == FAIL)
      {
        if (! inst.error)
  	inst.error = BAD_ARGS;
*************** do_fpa_ldst (str)
*** 5831,5837 ****
      }
  
    if (skip_past_comma (&str) == FAIL
!       || cp_address_required_here (&str) == FAIL)
      {
        if (!inst.error)
  	inst.error = BAD_ARGS;
--- 6054,6060 ----
      }
  
    if (skip_past_comma (&str) == FAIL
!       || cp_address_required_here (&str, CP_WB_OK) == FAIL)
      {
        if (!inst.error)
  	inst.error = BAD_ARGS;
*************** do_fpa_ldmstm (str)
*** 5970,5976 ****
        inst.instruction |= offset;
      }
    else if (skip_past_comma (&str) == FAIL
! 	   || cp_address_required_here (&str) == FAIL)
      {
        if (! inst.error)
  	inst.error = BAD_ARGS;
--- 6193,6199 ----
        inst.instruction |= offset;
      }
    else if (skip_past_comma (&str) == FAIL
! 	   || cp_address_required_here (&str, CP_WB_OK) == FAIL)
      {
        if (! inst.error)
  	inst.error = BAD_ARGS;
*************** do_fpa_to_reg (str)
*** 6109,6285 ****
    return;
  }
  
- /* 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;
- 
    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 (is_immediate_prefix (*str))
      {
!       Rs = Rd;
!       str++;
!       if (my_get_expression (&inst.reloc.exp, &str))
! 	return;
      }
-   else
-     {
-       if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
- 	return;
  
!       if (skip_past_comma (&str) == FAIL)
! 	{
! 	  /* Two operand format, shuffle the registers
! 	     and pretend there are 3.  */
! 	  Rn = Rs;
! 	  Rs = Rd;
! 	}
!       else if (is_immediate_prefix (*str))
! 	{
! 	  str++;
! 	  if (my_get_expression (&inst.reloc.exp, &str))
! 	    return;
! 	}
!       else if ((Rn = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
! 	return;
!     }
  
!   /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
!      for the latter case, EXPR contains the immediate that was found.  */
!   if (Rn != FAIL)
!     {
!       /* All register format.  */
!       if (Rd > 7 || Rs > 7 || Rn > 7)
! 	{
! 	  if (Rs != Rd)
! 	    {
! 	      inst.error = _("dest and source1 must be the same register");
! 	      return;
! 	    }
  
! 	  /* Can't do this for SUB.  */
! 	  if (subtract)
! 	    {
! 	      inst.error = _("subtract valid only on lo regs");
! 	      return;
! 	    }
  
! 	  inst.instruction = (T_OPCODE_ADD_HI
! 			      | (Rd > 7 ? THUMB_H1 : 0)
! 			      | (Rn > 7 ? THUMB_H2 : 0));
! 	  inst.instruction |= (Rd & 7) | ((Rn & 7) << 3);
! 	}
!       else
! 	{
! 	  inst.instruction = subtract ? T_OPCODE_SUB_R3 : T_OPCODE_ADD_R3;
! 	  inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
! 	}
!     }
!   else
      {
!       /* Immediate expression, now things start to get nasty.  */
  
!       /* First deal with HI regs, only very restricted cases allowed:
! 	 Adjusting SP, and using PC or SP to get an address.  */
!       if ((Rd > 7 && (Rd != REG_SP || Rs != REG_SP))
! 	  || (Rs > 7 && Rs != REG_SP && Rs != REG_PC))
! 	{
! 	  inst.error = _("invalid Hi register with immediate");
! 	  return;
! 	}
  
!       if (inst.reloc.exp.X_op != O_constant)
! 	{
! 	  /* Value isn't known yet, all we can do is store all the fragments
! 	     we know about in the instruction and let the reloc hacking
! 	     work it all out.  */
! 	  inst.instruction = (subtract ? 0x8000 : 0) | (Rd << 4) | Rs;
! 	  inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
! 	}
!       else
! 	{
! 	  int offset = inst.reloc.exp.X_add_number;
  
! 	  if (subtract)
! 	    offset = -offset;
  
! 	  if (offset < 0)
! 	    {
! 	      offset = -offset;
! 	      subtract = 1;
  
! 	      /* Quick check, in case offset is MIN_INT.  */
! 	      if (offset < 0)
! 		{
! 		  inst.error = _("immediate value out of range");
! 		  return;
! 		}
! 	    }
! 	  else
! 	    subtract = 0;
  
! 	  if (Rd == REG_SP)
! 	    {
! 	      if (offset & ~0x1fc)
! 		{
! 		  inst.error = _("invalid immediate value for stack adjust");
  		  return;
  		}
  	      inst.instruction = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
--- 6332,7409 ----
    return;
  }
  
  static int
! vfp_sp_reg_required_here (str, pos)
!      char **str;
!      enum vfp_sp_reg_pos pos;
  {
!   int    reg;
!   char *start = *str;
  
!   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_SN].htab)) != FAIL)
      {
!       switch (pos)
  	{
! 	case VFP_REG_Sd:
! 	  inst.instruction |= ((reg >> 1) << 12) | ((reg & 1) << 22);
! 	  break;
! 
! 	case VFP_REG_Sn:
! 	  inst.instruction |= ((reg >> 1) << 16) | ((reg & 1) << 7);
! 	  break;
! 
! 	case VFP_REG_Sm:
! 	  inst.instruction |= ((reg >> 1) << 0) | ((reg & 1) << 5);
! 	  break;
! 
! 	default:
! 	  abort ();
  	}
!       return reg;
!     }
  
!   /* In the few cases where we might be able to accept something else
!      this error can be overridden.  */
!   inst.error = _(all_reg_maps[REG_TYPE_SN].expected);
! 
!   /* Restore the start point.  */
!   *str = start;
!   return FAIL;
! }
! 
! static int
! vfp_dp_reg_required_here (str, pos)
!      char **str;
!      enum vfp_sp_reg_pos pos;
! {
!   int   reg;
!   char *start = *str;
! 
!   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_DN].htab)) != FAIL)
!     {
!       switch (pos)
  	{
! 	case VFP_REG_Dd:
! 	  inst.instruction |= reg << 12;
! 	  break;
  
! 	case VFP_REG_Dn:
! 	  inst.instruction |= reg << 16;
! 	  break;
! 
! 	case VFP_REG_Dm:
! 	  inst.instruction |= reg << 0;
! 	  break;
! 
! 	default:
! 	  abort ();
! 	}
!       return reg;
      }
  
!   /* In the few cases where we might be able to accept something else
!      this error can be overridden.  */
!   inst.error = _(all_reg_maps[REG_TYPE_DN].expected);
  
!   /* Restore the start point.  */
!   *str = start;
!   return FAIL;
! }
  
  static void
! do_vfp_sp_monadic (str)
!      char *str;
  {
    skip_whitespace (str);
  
!   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
!     return;
! 
!   if (skip_past_comma (&str) == FAIL
!       || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
      {
        if (! inst.error)
  	inst.error = BAD_ARGS;
        return;
      }
  
!   end_of_line (str);
!   return;
! }
! 
! static void
! do_vfp_dp_monadic (str)
!      char *str;
! {
!   skip_whitespace (str);
! 
!   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
!     return;
! 
!   if (skip_past_comma (&str) == FAIL
!       || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
      {
!       if (! inst.error)
! 	inst.error = BAD_ARGS;
!       return;
      }
  
!   end_of_line (str);
!   return;
! }
  
! static void
! do_vfp_sp_dyadic (str)
!      char *str;
! {
!   skip_whitespace (str);
  
!   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
!     return;
  
!   if (skip_past_comma (&str) == FAIL
!       || vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL
!       || skip_past_comma (&str) == FAIL
!       || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
      {
!       if (! inst.error)
! 	inst.error = BAD_ARGS;
!       return;
!     }
  
!   end_of_line (str);
!   return;
! }
  
! static void
! do_vfp_dp_dyadic (str)
!      char *str;
! {
!   skip_whitespace (str);
  
!   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
!     return;
  
!   if (skip_past_comma (&str) == FAIL
!       || vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL
!       || skip_past_comma (&str) == FAIL
!       || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
!     {
!       if (! inst.error)
! 	inst.error = BAD_ARGS;
!       return;
!     }
  
!   end_of_line (str);
!   return;
! }
  
! static void
! do_vfp_reg_from_sp (str)
!      char *str;
! {
!   skip_whitespace (str);
! 
!   if (reg_required_here (&str, 12) == FAIL)
!     return;
! 
!   if (skip_past_comma (&str) == FAIL
!       || vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL)
!     {
!       if (! inst.error)
! 	inst.error = BAD_ARGS;
!       return;
!     }
! 
!   end_of_line (str);
!   return;
! }
! 
! static void
! do_vfp_sp_reg2 (str)
!      char *str;
! {
!   skip_whitespace (str);
! 
!   if (reg_required_here (&str, 12) == FAIL)
!     return;
! 
!   if (skip_past_comma (&str) == FAIL
!       || reg_required_here (&str, 16) == FAIL
!       || skip_past_comma (&str) == FAIL)
!     {
!       if (! inst.error)
! 	inst.error = BAD_ARGS;
!       return;
!     }
! 
!   /* We require exactly two consecutive SP registers.  */
!   if (vfp_sp_reg_list (&str, VFP_REG_Sm) != 2)
!     {
!       if (! inst.error)
! 	inst.error = _("only two consecutive VFP SP registers allowed here");
!     }
! 
!   end_of_line (str);
!   return;
! }
! 
! static void
! do_vfp_sp_from_reg (str)
!      char *str;
! {
!   skip_whitespace (str);
! 
!   if (vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL)
!     return;
! 
!   if (skip_past_comma (&str) == FAIL
!       || reg_required_here (&str, 12) == FAIL)
!     {
!       if (! inst.error)
! 	inst.error = BAD_ARGS;
!       return;
!     }
! 
!   end_of_line (str);
!   return;
! }
! 
! static void
! do_vfp_reg_from_dp (str)
!      char *str;
! {
!   skip_whitespace (str);
! 
!   if (reg_required_here (&str, 12) == FAIL)
!     return;
! 
!   if (skip_past_comma (&str) == FAIL
!       || vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL)
!     {
!       if (! inst.error)
! 	inst.error = BAD_ARGS;
!       return;
!     }
! 
!   end_of_line (str);
!   return;
! }
! 
! static void
! do_vfp_reg2_from_dp (str)
!      char *str;
! {
!   skip_whitespace (str);
! 
!   if (reg_required_here (&str, 12) == FAIL)
!     return;
! 
!   if (skip_past_comma (&str) == FAIL
!       || reg_required_here (&str, 16) == FAIL
!       || skip_past_comma (&str) == FAIL
!       || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
!     {
!       if (! inst.error)
! 	inst.error = BAD_ARGS;
!       return;
!     }
! 
!   end_of_line (str);
!   return;
! }
! 
! static void
! do_vfp_dp_from_reg (str)
!      char *str;
! {
!   skip_whitespace (str);
! 
!   if (vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL)
!     return;
! 
!   if (skip_past_comma (&str) == FAIL
!       || reg_required_here (&str, 12) == FAIL)
!     {
!       if (! inst.error)
! 	inst.error = BAD_ARGS;
!       return;
!     }
! 
!   end_of_line (str);
!   return;
! }
! 
! static void
! do_vfp_dp_from_reg2 (str)
!      char *str;
! {
!   skip_whitespace (str);
! 
!   if (vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
!     return;
! 
!   if (skip_past_comma (&str) == FAIL
!       || reg_required_here (&str, 12) == FAIL
!       || skip_past_comma (&str) == FAIL
!       || reg_required_here (&str, 16))
!     {
!       if (! inst.error)
! 	inst.error = BAD_ARGS;
!       return;
!     }
! 
!   end_of_line (str);
!   return;
! }
! 
! static const struct vfp_reg *
! vfp_psr_parse (str)
!      char **str;
! {
!   char *start = *str;
!   char  c;
!   char *p;
!   const struct vfp_reg *vreg;
! 
!   p = start;
! 
!   /* Find the end of the current token.  */
!   do
!     {
!       c = *p++;
!     }
!   while (ISALPHA (c));
! 
!   /* Mark it.  */
!   *--p = 0;
! 
!   for (vreg = vfp_regs + 0; 
!        vreg < vfp_regs + sizeof (vfp_regs) / sizeof (struct vfp_reg);
!        vreg++)
!     {
!       if (strcmp (start, vreg->name) == 0)
! 	{
! 	  *p = c;
! 	  *str = p;
! 	  return vreg;
! 	}
!     }
! 
!   *p = c;
!   return NULL;
! }
! 
! static int
! vfp_psr_required_here (str)
!      char **str;
! {
!   char *start = *str;
!   const struct vfp_reg *vreg;
! 
!   vreg = vfp_psr_parse (str);
! 
!   if (vreg)
!     {
!       inst.instruction |= vreg->regno;
!       return SUCCESS;
!     }
! 
!   inst.error = _("VFP system register expected");
! 
!   *str = start;
!   return FAIL;
! }
! 
! static void
! do_vfp_reg_from_ctrl (str)
!      char *str;
! {
!   skip_whitespace (str);
! 
!   if (reg_required_here (&str, 12) == FAIL)
!     return;
! 
!   if (skip_past_comma (&str) == FAIL
!       || vfp_psr_required_here (&str) == FAIL)
!     {
!       if (! inst.error)
! 	inst.error = BAD_ARGS;
!       return;
!     }
! 
!   end_of_line (str);
!   return;
! }
! 
! static void
! do_vfp_ctrl_from_reg (str)
!      char *str;
! {
!   skip_whitespace (str);
! 
!   if (vfp_psr_required_here (&str) == FAIL)
!     return;
! 
!   if (skip_past_comma (&str) == FAIL
!       || reg_required_here (&str, 12) == FAIL)
!     {
!       if (! inst.error)
! 	inst.error = BAD_ARGS;
!       return;
!     }
! 
!   end_of_line (str);
!   return;
! }
! 
! static void
! do_vfp_sp_ldst (str)
!      char *str;
! {
!   skip_whitespace (str);
! 
!   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
!     {
!       if (!inst.error)
! 	inst.error = BAD_ARGS;
!       return;
!     }
! 
!   if (skip_past_comma (&str) == FAIL
!       || cp_address_required_here (&str, CP_NO_WB) == FAIL)
!     {
!       if (!inst.error)
! 	inst.error = BAD_ARGS;
!       return;
!     }
! 
!   end_of_line (str);
!   return;
! }
! 
! static void
! do_vfp_dp_ldst (str)
!      char *str;
! {
!   skip_whitespace (str);
! 
!   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
!     {
!       if (!inst.error)
! 	inst.error = BAD_ARGS;
!       return;
!     }
! 
!   if (skip_past_comma (&str) == FAIL
!       || cp_address_required_here (&str, CP_NO_WB) == FAIL)
!     {
!       if (!inst.error)
! 	inst.error = BAD_ARGS;
!       return;
!     }
! 
!   end_of_line (str);
!   return;
! }
! 
! /* 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;
!   int new_base;
!   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_dp_reg_required_here (str, VFP_REG_Dd)) == FAIL)
! 	return FAIL;
! 
!       if (count == 0 || base_reg > new_base)
! 	{
! 	  base_reg = new_base;
! 	  range = 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_DN].htab))
! 	      == FAIL)
! 	    {
! 	      inst.error = _(all_reg_maps[REG_TYPE_DN].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 |= 2 * count;
! 
!   /* Sanity check -- should have raised a parse error above.  */
!   if (count == 0 || count > 16)
!     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;
!   return range;
! }
! 
! static void
! vfp_sp_ldstm(str, ldstm_type)
!      char *str;
!      enum vfp_ldstm_type ldstm_type;
! {
!   long range;
! 
!   skip_whitespace (str);
! 
!   if (reg_required_here (&str, 16) == FAIL)
!     return;
! 
!   skip_whitespace (str);
! 
!   if (*str == '!')
!     {
!       inst.instruction |= WRITE_BACK;
!       str++;
!     }
!   else if (ldstm_type != VFP_LDSTMIA)
!     {
!       inst.error = _("this addressing mode requires base-register writeback");
!       return;
!     }
! 
!   if (skip_past_comma (&str) == FAIL
!       || (range = vfp_sp_reg_list (&str, VFP_REG_Sd)) == FAIL)
!     {
!       if (!inst.error)
! 	inst.error = BAD_ARGS;
!       return;
!     }
! 
!   inst.instruction |= range;
!   end_of_line (str);
! }
! 
! static void
! vfp_dp_ldstm(str, ldstm_type)
!      char *str;
!      enum vfp_ldstm_type ldstm_type;
! {
!   long range;
! 
!   skip_whitespace (str);
! 
!   if (reg_required_here (&str, 16) == FAIL)
!     return;
! 
!   skip_whitespace (str);
! 
!   if (*str == '!')
!     {
!       inst.instruction |= WRITE_BACK;
!       str++;
!     }
!   else if (ldstm_type != VFP_LDSTMIA && ldstm_type != VFP_LDSTMIAX)
!     {
!       inst.error = _("this addressing mode requires base-register writeback");
!       return;
!     }
! 
!   if (skip_past_comma (&str) == FAIL
!       || (range = vfp_dp_reg_list (&str)) == FAIL)
!     {
!       if (!inst.error)
! 	inst.error = BAD_ARGS;
!       return;
!     }
! 
!   if (ldstm_type == VFP_LDSTMIAX || ldstm_type == VFP_LDSTMDBX)
!     range += 1;
! 
!   inst.instruction |= range;
!   end_of_line (str);
! }
! 
! 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);
! 
!   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
!     {
!       if (!inst.error)
! 	inst.error = BAD_ARGS;
!       return;
!     }
! 
!   end_of_line (str);
!   return;
! }
! 
! static void
! do_vfp_dp_compare_z (str)
!      char *str;
! {
!   skip_whitespace (str);
! 
!   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
!     {
!       if (!inst.error)
! 	inst.error = BAD_ARGS;
!       return;
!     }
! 
!   end_of_line (str);
!   return;
! }
! 
! static void
! do_vfp_dp_sp_cvt (str)
!      char *str;
! {
!   skip_whitespace (str);
! 
!   if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
!     return;
! 
!   if (skip_past_comma (&str) == FAIL
!       || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
!     {
!       if (! inst.error)
! 	inst.error = BAD_ARGS;
!       return;
!     }
! 
!   end_of_line (str);
!   return;
! }
! 
! static void
! do_vfp_sp_dp_cvt (str)
!      char *str;
! {
!   skip_whitespace (str);
! 
!   if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
!     return;
! 
!   if (skip_past_comma (&str) == FAIL
!       || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
!     {
!       if (! inst.error)
! 	inst.error = BAD_ARGS;
!       return;
!     }
! 
!   end_of_line (str);
!   return;
! }
! 
! /* 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;
! 
!   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 (is_immediate_prefix (*str))
!     {
!       Rs = Rd;
!       str++;
!       if (my_get_expression (&inst.reloc.exp, &str))
! 	return;
!     }
!   else
!     {
!       if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
! 	return;
! 
!       if (skip_past_comma (&str) == FAIL)
! 	{
! 	  /* Two operand format, shuffle the registers
! 	     and pretend there are 3.  */
! 	  Rn = Rs;
! 	  Rs = Rd;
! 	}
!       else if (is_immediate_prefix (*str))
! 	{
! 	  str++;
! 	  if (my_get_expression (&inst.reloc.exp, &str))
! 	    return;
! 	}
!       else if ((Rn = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
! 	return;
!     }
! 
!   /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
!      for the latter case, EXPR contains the immediate that was found.  */
!   if (Rn != FAIL)
!     {
!       /* All register format.  */
!       if (Rd > 7 || Rs > 7 || Rn > 7)
! 	{
! 	  if (Rs != Rd)
! 	    {
! 	      inst.error = _("dest and source1 must be the same register");
! 	      return;
! 	    }
! 
! 	  /* Can't do this for SUB.  */
! 	  if (subtract)
! 	    {
! 	      inst.error = _("subtract valid only on lo regs");
! 	      return;
! 	    }
! 
! 	  inst.instruction = (T_OPCODE_ADD_HI
! 			      | (Rd > 7 ? THUMB_H1 : 0)
! 			      | (Rn > 7 ? THUMB_H2 : 0));
! 	  inst.instruction |= (Rd & 7) | ((Rn & 7) << 3);
! 	}
!       else
! 	{
! 	  inst.instruction = subtract ? T_OPCODE_SUB_R3 : T_OPCODE_ADD_R3;
! 	  inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
! 	}
!     }
!   else
!     {
!       /* Immediate expression, now things start to get nasty.  */
! 
!       /* First deal with HI regs, only very restricted cases allowed:
! 	 Adjusting SP, and using PC or SP to get an address.  */
!       if ((Rd > 7 && (Rd != REG_SP || Rs != REG_SP))
! 	  || (Rs > 7 && Rs != REG_SP && Rs != REG_PC))
! 	{
! 	  inst.error = _("invalid Hi register with immediate");
! 	  return;
! 	}
! 
!       if (inst.reloc.exp.X_op != O_constant)
! 	{
! 	  /* Value isn't known yet, all we can do is store all the fragments
! 	     we know about in the instruction and let the reloc hacking
! 	     work it all out.  */
! 	  inst.instruction = (subtract ? 0x8000 : 0) | (Rd << 4) | Rs;
! 	  inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
! 	}
!       else
! 	{
! 	  int offset = inst.reloc.exp.X_add_number;
! 
! 	  if (subtract)
! 	    offset = -offset;
! 
! 	  if (offset < 0)
! 	    {
! 	      offset = -offset;
! 	      subtract = 1;
! 
! 	      /* Quick check, in case offset is MIN_INT.  */
! 	      if (offset < 0)
! 		{
! 		  inst.error = _("immediate value out of range");
! 		  return;
! 		}
! 	    }
! 	  else
! 	    subtract = 0;
! 
! 	  if (Rd == REG_SP)
! 	    {
! 	      if (offset & ~0x1fc)
! 		{
! 		  inst.error = _("invalid immediate value for stack adjust");
  		  return;
  		}
  	      inst.instruction = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
*************** md_begin ()
*** 8014,8020 ****
      if (support_interwork) flags |= F_INTERWORK;
      if (uses_apcs_float)   flags |= F_APCS_FLOAT;
      if (pic_code)          flags |= F_PIC;
!     if ((cpu_variant & FPU_ANY) == FPU_NONE) flags |= F_SOFT_FLOAT;
  
      bfd_set_private_flags (stdoutput, flags);
  
--- 9138,9146 ----
      if (support_interwork) flags |= F_INTERWORK;
      if (uses_apcs_float)   flags |= F_APCS_FLOAT;
      if (pic_code)          flags |= F_PIC;
!     if ((cpu_variant & FPU_ANY) == FPU_NONE
! 	|| (cpu_variant & FPU_ANY) == FPU_ARCH_VFP)
!       flags |= F_SOFT_FLOAT;
  
      bfd_set_private_flags (stdoutput, flags);
  
*************** md_atof (type, litP, sizeP)
*** 8201,8214 ****
      }
    else
      {
!       /* For a 4 byte float the order of elements in `words' is 1 0.  For an
! 	 8 byte float the order is 1 0 3 2.  */
!       for (i = 0; i < prec; i += 2)
! 	{
! 	  md_number_to_chars (litP, (valueT) words[i + 1], 2);
! 	  md_number_to_chars (litP + 2, (valueT) words[i], 2);
! 	  litP += 4;
! 	}
      }
  
    return 0;
--- 9327,9347 ----
      }
    else
      {
!       if (cpu_variant & FPU_ARCH_VFP)
! 	for (i = prec - 1; i >= 0; i--)
! 	  {
! 	    md_number_to_chars (litP, (valueT) words[i], 2);
! 	    litP += 2;
! 	  }
!       else
! 	/* For a 4 byte float the order of elements in `words' is 1 0.
! 	   For an 8 byte float the order is 1 0 3 2.  */
! 	for (i = 0; i < prec; i += 2)
! 	  {
! 	    md_number_to_chars (litP, (valueT) words[i + 1], 2);
! 	    md_number_to_chars (litP + 2, (valueT) words[i], 2);
! 	    litP += 4;
! 	  }
      }
  
    return 0;
*************** md_assemble (str)
*** 9271,9276 ****
--- 10404,10411 ----
        FP variants:
                -mfpa10, -mfpa11        FPA10 and 11 co-processor instructions
                -mfpe-old               (No float load/store multiples)
+ 	      -mvfpxd		      VFP Single precision
+ 	      -mvfp		      All VFP
                -mno-fpu                Disable all floating point instructions
        Run-time endian selection:
                -EB                     big endian cpu
*************** md_parse_option (c, arg)
*** 9378,9383 ****
--- 10513,10527 ----
  	    goto bad;
  	  break;
  
+ 	case 'v':
+ 	  if (streq (str, "vfpxd"))
+ 	    cpu_variant = (cpu_variant & ~FPU_ANY) | FPU_ARCH_VFP_V1xD;
+ 	  else if (streq (str, "vfp"))
+ 	    cpu_variant = (cpu_variant & ~FPU_ANY) | FPU_ARCH_VFP_V2;
+ 	  else
+ 	    goto bad;
+ 	  break;
+ 
  	default:
  	  if (streq (str, "all"))
  	    {
*************** md_show_usage (fp)
*** 9676,9681 ****
--- 10820,10827 ----
    -mall                     allow any instruction\n\
    -mfpa10, -mfpa11          select floating point architecture\n\
    -mfpe-old                 don't allow floating-point multiple instructions\n\
+   -mvfpxd                   allow vfp single-precision instructions\n\
+   -mvfp                     allow all vfp instructions\n\
    -mno-fpu                  don't allow any floating-point instructions.\n\
    -k                        generate PIC code.\n"));
  #if defined OBJ_COFF || defined OBJ_ELF
Index: testsuite/gas/arm/arm.exp
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/arm/arm.exp,v
retrieving revision 1.10
diff -p -r1.10 arm.exp
*** arm.exp	2002/01/14 17:39:01	1.10
--- arm.exp	2002/01/15 15:50:32
*************** if {[istarget *arm*-*-*] || [istarget "x
*** 47,52 ****
--- 47,58 ----
  
      run_dump_test "fpa-mem"
  
+     run_dump_test "vfp1xD"
+ 
+     run_dump_test "vfp1"
+ 
+     run_errors_test "vfp-bad" "-mvfp" "VFP errors"
+ 
      run_dump_test "xscale"
  
      run_dump_test "adrl"
Index: testsuite/gas/arm/vfp-bad.l
===================================================================
RCS file: vfp-bad.l
diff -N vfp-bad.l
*** /dev/null	Tue May  5 13:32:27 1998
--- vfp-bad.l	Tue Jan 15 07:50:32 2002
***************
*** 0 ****
--- 1,9 ----
+ [^:]*: Assembler messages:
+ [^:]*:4: Error: garbage following instruction -- `fstd d0,\[r0\],#8'
+ [^:]*:5: Error: garbage following instruction -- `fstd d0,\[r0,#-8\]!'
+ [^:]*:6: Error: garbage following instruction -- `fsts s0,\[r0\],#8'
+ [^:]*:7: Error: garbage following instruction -- `fsts s0,\[r0,#-8\]!'
+ [^:]*:8: Error: garbage following instruction -- `fldd d0,\[r0\],#8'
+ [^:]*:9: Error: garbage following instruction -- `fldd d0,\[r0,#-8\]!'
+ [^:]*:10: Error: garbage following instruction -- `flds s0,\[r0\],#8'
+ [^:]*:11: Error: garbage following instruction -- `flds s0,\[r0,#-8\]!'
Index: testsuite/gas/arm/vfp-bad.s
===================================================================
RCS file: vfp-bad.s
diff -N vfp-bad.s
*** /dev/null	Tue May  5 13:32:27 1998
--- vfp-bad.s	Tue Jan 15 07:50:32 2002
***************
*** 0 ****
--- 1,11 ----
+         .global entry
+         .text
+ entry:
+ 	fstd	d0, [r0], #8
+ 	fstd	d0, [r0, #-8]!
+ 	fsts	s0, [r0], #8
+ 	fsts	s0, [r0, #-8]!
+ 	fldd	d0, [r0], #8
+ 	fldd	d0, [r0, #-8]!
+ 	flds	s0, [r0], #8
+ 	flds	s0, [r0, #-8]!
Index: testsuite/gas/arm/vfp1.d
===================================================================
RCS file: vfp1.d
diff -N vfp1.d
*** /dev/null	Tue May  5 13:32:27 1998
--- vfp1.d	Tue Jan 15 07:50:32 2002
***************
*** 0 ****
--- 1,190 ----
+ #objdump: -dr --prefix-addresses --show-raw-insn
+ #name: VFP Double-precision instructions
+ #as: -mvfp
+ 
+ # Test the ARM VFP Double Precision instructions
+ 
+ .*: +file format .*arm.*
+ 
+ Disassembly of section .text:
+ 0+000 <[^>]*> eeb40bc0 	fcmped	d0, d0
+ 0+004 <[^>]*> eeb50bc0 	fcmpezd	d0
+ 0+008 <[^>]*> eeb40b40 	fcmpd	d0, d0
+ 0+00c <[^>]*> eeb50b40 	fcmpzd	d0
+ 0+010 <[^>]*> eeb00bc0 	fabsd	d0, d0
+ 0+014 <[^>]*> eeb00b40 	fcpyd	d0, d0
+ 0+018 <[^>]*> eeb10b40 	fnegd	d0, d0
+ 0+01c <[^>]*> eeb10bc0 	fsqrtd	d0, d0
+ 0+020 <[^>]*> ee300b00 	faddd	d0, d0, d0
+ 0+024 <[^>]*> ee800b00 	fdivd	d0, d0, d0
+ 0+028 <[^>]*> ee000b00 	fmacd	d0, d0, d0
+ 0+02c <[^>]*> ee100b00 	fmscd	d0, d0, d0
+ 0+030 <[^>]*> ee200b00 	fmuld	d0, d0, d0
+ 0+034 <[^>]*> ee000b40 	fnmacd	d0, d0, d0
+ 0+038 <[^>]*> ee100b40 	fnmscd	d0, d0, d0
+ 0+03c <[^>]*> ee200b40 	fnmuld	d0, d0, d0
+ 0+040 <[^>]*> ee300b40 	fsubd	d0, d0, d0
+ 0+044 <[^>]*> ed900b00 	fldd	d0, \[r0\]
+ 0+048 <[^>]*> ed800b00 	fstd	d0, \[r0\]
+ 0+04c <[^>]*> ec900b02 	fldmiad	r0, {d0}
+ 0+050 <[^>]*> ec900b02 	fldmiad	r0, {d0}
+ 0+054 <[^>]*> ecb00b02 	fldmiad	r0!, {d0}
+ 0+058 <[^>]*> ecb00b02 	fldmiad	r0!, {d0}
+ 0+05c <[^>]*> ed300b02 	fldmdbd	r0!, {d0}
+ 0+060 <[^>]*> ed300b02 	fldmdbd	r0!, {d0}
+ 0+064 <[^>]*> ec800b02 	fstmiad	r0, {d0}
+ 0+068 <[^>]*> ec800b02 	fstmiad	r0, {d0}
+ 0+06c <[^>]*> eca00b02 	fstmiad	r0!, {d0}
+ 0+070 <[^>]*> eca00b02 	fstmiad	r0!, {d0}
+ 0+074 <[^>]*> ed200b02 	fstmdbd	r0!, {d0}
+ 0+078 <[^>]*> ed200b02 	fstmdbd	r0!, {d0}
+ 0+07c <[^>]*> eeb80bc0 	fsitod	d0, s0
+ 0+080 <[^>]*> eeb80b40 	fuitod	d0, s0
+ 0+084 <[^>]*> eebd0b40 	ftosid	s0, d0
+ 0+088 <[^>]*> eebd0bc0 	ftosizd	s0, d0
+ 0+08c <[^>]*> eebc0b40 	ftouid	s0, d0
+ 0+090 <[^>]*> eebc0bc0 	ftouizd	s0, d0
+ 0+094 <[^>]*> eeb70ac0 	fcvtds	d0, s0
+ 0+098 <[^>]*> eeb70bc0 	fcvtsd	s0, d0
+ 0+09c <[^>]*> ee300b10 	fmrdh	r0, d0
+ 0+0a0 <[^>]*> ee100b10 	fmrdl	r0, d0
+ 0+0a4 <[^>]*> ee200b10 	fmdhr	d0, r0
+ 0+0a8 <[^>]*> ee000b10 	fmdlr	d0, r0
+ 0+0ac <[^>]*> eeb51b40 	fcmpzd	d1
+ 0+0b0 <[^>]*> eeb52b40 	fcmpzd	d2
+ 0+0b4 <[^>]*> eeb5fb40 	fcmpzd	d15
+ 0+0b8 <[^>]*> eeb40b41 	fcmpd	d0, d1
+ 0+0bc <[^>]*> eeb40b42 	fcmpd	d0, d2
+ 0+0c0 <[^>]*> eeb40b4f 	fcmpd	d0, d15
+ 0+0c4 <[^>]*> eeb41b40 	fcmpd	d1, d0
+ 0+0c8 <[^>]*> eeb42b40 	fcmpd	d2, d0
+ 0+0cc <[^>]*> eeb4fb40 	fcmpd	d15, d0
+ 0+0d0 <[^>]*> eeb45b4c 	fcmpd	d5, d12
+ 0+0d4 <[^>]*> eeb10b41 	fnegd	d0, d1
+ 0+0d8 <[^>]*> eeb10b42 	fnegd	d0, d2
+ 0+0dc <[^>]*> eeb10b4f 	fnegd	d0, d15
+ 0+0e0 <[^>]*> eeb11b40 	fnegd	d1, d0
+ 0+0e4 <[^>]*> eeb12b40 	fnegd	d2, d0
+ 0+0e8 <[^>]*> eeb1fb40 	fnegd	d15, d0
+ 0+0ec <[^>]*> eeb1cb45 	fnegd	d12, d5
+ 0+0f0 <[^>]*> ee300b01 	faddd	d0, d0, d1
+ 0+0f4 <[^>]*> ee300b02 	faddd	d0, d0, d2
+ 0+0f8 <[^>]*> ee300b0f 	faddd	d0, d0, d15
+ 0+0fc <[^>]*> ee310b00 	faddd	d0, d1, d0
+ 0+100 <[^>]*> ee320b00 	faddd	d0, d2, d0
+ 0+104 <[^>]*> ee3f0b00 	faddd	d0, d15, d0
+ 0+108 <[^>]*> ee301b00 	faddd	d1, d0, d0
+ 0+10c <[^>]*> ee302b00 	faddd	d2, d0, d0
+ 0+110 <[^>]*> ee30fb00 	faddd	d15, d0, d0
+ 0+114 <[^>]*> ee39cb05 	faddd	d12, d9, d5
+ 0+118 <[^>]*> eeb70ae0 	fcvtds	d0, s1
+ 0+11c <[^>]*> eeb70ac1 	fcvtds	d0, s2
+ 0+120 <[^>]*> eeb70aef 	fcvtds	d0, s31
+ 0+124 <[^>]*> eeb71ac0 	fcvtds	d1, s0
+ 0+128 <[^>]*> eeb72ac0 	fcvtds	d2, s0
+ 0+12c <[^>]*> eeb7fac0 	fcvtds	d15, s0
+ 0+130 <[^>]*> eef70bc0 	fcvtsd	s1, d0
+ 0+134 <[^>]*> eeb71bc0 	fcvtsd	s2, d0
+ 0+138 <[^>]*> eef7fbc0 	fcvtsd	s31, d0
+ 0+13c <[^>]*> eeb70bc1 	fcvtsd	s0, d1
+ 0+140 <[^>]*> eeb70bc2 	fcvtsd	s0, d2
+ 0+144 <[^>]*> eeb70bcf 	fcvtsd	s0, d15
+ 0+148 <[^>]*> ee301b10 	fmrdh	r1, d0
+ 0+14c <[^>]*> ee30eb10 	fmrdh	lr, d0
+ 0+150 <[^>]*> ee310b10 	fmrdh	r0, d1
+ 0+154 <[^>]*> ee320b10 	fmrdh	r0, d2
+ 0+158 <[^>]*> ee3f0b10 	fmrdh	r0, d15
+ 0+15c <[^>]*> ee101b10 	fmrdl	r1, d0
+ 0+160 <[^>]*> ee10eb10 	fmrdl	lr, d0
+ 0+164 <[^>]*> ee110b10 	fmrdl	r0, d1
+ 0+168 <[^>]*> ee120b10 	fmrdl	r0, d2
+ 0+16c <[^>]*> ee1f0b10 	fmrdl	r0, d15
+ 0+170 <[^>]*> ee201b10 	fmdhr	d0, r1
+ 0+174 <[^>]*> ee20eb10 	fmdhr	d0, lr
+ 0+178 <[^>]*> ee210b10 	fmdhr	d1, r0
+ 0+17c <[^>]*> ee220b10 	fmdhr	d2, r0
+ 0+180 <[^>]*> ee2f0b10 	fmdhr	d15, r0
+ 0+184 <[^>]*> ee001b10 	fmdlr	d0, r1
+ 0+188 <[^>]*> ee00eb10 	fmdlr	d0, lr
+ 0+18c <[^>]*> ee010b10 	fmdlr	d1, r0
+ 0+190 <[^>]*> ee020b10 	fmdlr	d2, r0
+ 0+194 <[^>]*> ee0f0b10 	fmdlr	d15, r0
+ 0+198 <[^>]*> ed910b00 	fldd	d0, \[r1\]
+ 0+19c <[^>]*> ed9e0b00 	fldd	d0, \[lr\]
+ 0+1a0 <[^>]*> ed900b00 	fldd	d0, \[r0\]
+ 0+1a4 <[^>]*> ed900bff 	fldd	d0, \[r0, #1020\]
+ 0+1a8 <[^>]*> ed100bff 	fldd	d0, \[r0, -#1020\]
+ 0+1ac <[^>]*> ed901b00 	fldd	d1, \[r0\]
+ 0+1b0 <[^>]*> ed902b00 	fldd	d2, \[r0\]
+ 0+1b4 <[^>]*> ed90fb00 	fldd	d15, \[r0\]
+ 0+1b8 <[^>]*> ed8ccbc9 	fstd	d12, \[ip, #804\]
+ 0+1bc <[^>]*> ec901b02 	fldmiad	r0, {d1}
+ 0+1c0 <[^>]*> ec902b02 	fldmiad	r0, {d2}
+ 0+1c4 <[^>]*> ec90fb02 	fldmiad	r0, {d15}
+ 0+1c8 <[^>]*> ec900b04 	fldmiad	r0, {d0-d1}
+ 0+1cc <[^>]*> ec900b06 	fldmiad	r0, {d0-d2}
+ 0+1d0 <[^>]*> ec900b20 	fldmiad	r0, {d0-d15}
+ 0+1d4 <[^>]*> ec901b1e 	fldmiad	r0, {d1-d15}
+ 0+1d8 <[^>]*> ec902b1c 	fldmiad	r0, {d2-d15}
+ 0+1dc <[^>]*> ec90eb04 	fldmiad	r0, {d14-d15}
+ 0+1e0 <[^>]*> ec910b02 	fldmiad	r1, {d0}
+ 0+1e4 <[^>]*> ec9e0b02 	fldmiad	lr, {d0}
+ 0+1e8 <[^>]*> eeb50b40 	fcmpzd	d0
+ 0+1ec <[^>]*> eeb51b40 	fcmpzd	d1
+ 0+1f0 <[^>]*> eeb52b40 	fcmpzd	d2
+ 0+1f4 <[^>]*> eeb53b40 	fcmpzd	d3
+ 0+1f8 <[^>]*> eeb54b40 	fcmpzd	d4
+ 0+1fc <[^>]*> eeb55b40 	fcmpzd	d5
+ 0+200 <[^>]*> eeb56b40 	fcmpzd	d6
+ 0+204 <[^>]*> eeb57b40 	fcmpzd	d7
+ 0+208 <[^>]*> eeb58b40 	fcmpzd	d8
+ 0+20c <[^>]*> eeb59b40 	fcmpzd	d9
+ 0+210 <[^>]*> eeb5ab40 	fcmpzd	d10
+ 0+214 <[^>]*> eeb5bb40 	fcmpzd	d11
+ 0+218 <[^>]*> eeb5cb40 	fcmpzd	d12
+ 0+21c <[^>]*> eeb5db40 	fcmpzd	d13
+ 0+220 <[^>]*> eeb5eb40 	fcmpzd	d14
+ 0+224 <[^>]*> eeb5fb40 	fcmpzd	d15
+ 0+228 <[^>]*> 0eb41bcf 	fcmpedeq	d1, d15
+ 0+22c <[^>]*> 0eb52bc0 	fcmpezdeq	d2
+ 0+230 <[^>]*> 0eb43b4e 	fcmpdeq	d3, d14
+ 0+234 <[^>]*> 0eb54b40 	fcmpzdeq	d4
+ 0+238 <[^>]*> 0eb05bcd 	fabsdeq	d5, d13
+ 0+23c <[^>]*> 0eb06b4c 	fcpydeq	d6, d12
+ 0+240 <[^>]*> 0eb17b4b 	fnegdeq	d7, d11
+ 0+244 <[^>]*> 0eb18bca 	fsqrtdeq	d8, d10
+ 0+248 <[^>]*> 0e319b0f 	fadddeq	d9, d1, d15
+ 0+24c <[^>]*> 0e832b0e 	fdivdeq	d2, d3, d14
+ 0+250 <[^>]*> 0e0d4b0c 	fmacdeq	d4, d13, d12
+ 0+254 <[^>]*> 0e165b0b 	fmscdeq	d5, d6, d11
+ 0+258 <[^>]*> 0e2a7b09 	fmuldeq	d7, d10, d9
+ 0+25c <[^>]*> 0e098b4a 	fnmacdeq	d8, d9, d10
+ 0+260 <[^>]*> 0e167b4b 	fnmscdeq	d7, d6, d11
+ 0+264 <[^>]*> 0e245b4c 	fnmuldeq	d5, d4, d12
+ 0+268 <[^>]*> 0e3d3b4e 	fsubdeq	d3, d13, d14
+ 0+26c <[^>]*> 0d952b00 	flddeq	d2, \[r5\]
+ 0+270 <[^>]*> 0d8c1b00 	fstdeq	d1, \[ip\]
+ 0+274 <[^>]*> 0c911b02 	fldmiadeq	r1, {d1}
+ 0+278 <[^>]*> 0c922b02 	fldmiadeq	r2, {d2}
+ 0+27c <[^>]*> 0cb33b02 	fldmiadeq	r3!, {d3}
+ 0+280 <[^>]*> 0cb44b02 	fldmiadeq	r4!, {d4}
+ 0+284 <[^>]*> 0d355b02 	fldmdbdeq	r5!, {d5}
+ 0+288 <[^>]*> 0d366b02 	fldmdbdeq	r6!, {d6}
+ 0+28c <[^>]*> 0c87fb02 	fstmiadeq	r7, {d15}
+ 0+290 <[^>]*> 0c88eb02 	fstmiadeq	r8, {d14}
+ 0+294 <[^>]*> 0ca9db02 	fstmiadeq	r9!, {d13}
+ 0+298 <[^>]*> 0caacb02 	fstmiadeq	sl!, {d12}
+ 0+29c <[^>]*> 0d2bbb02 	fstmdbdeq	fp!, {d11}
+ 0+2a0 <[^>]*> 0d2cab02 	fstmdbdeq	ip!, {d10}
+ 0+2a4 <[^>]*> 0eb8fbe0 	fsitodeq	d15, s1
+ 0+2a8 <[^>]*> 0eb81b6f 	fuitodeq	d1, s31
+ 0+2ac <[^>]*> 0efd0b4f 	ftosideq	s1, d15
+ 0+2b0 <[^>]*> 0efdfbc2 	ftosizdeq	s31, d2
+ 0+2b4 <[^>]*> 0efc7b42 	ftouideq	s15, d2
+ 0+2b8 <[^>]*> 0efc5bc3 	ftouizdeq	s11, d3
+ 0+2bc <[^>]*> 0eb71ac5 	fcvtdseq	d1, s10
+ 0+2c0 <[^>]*> 0ef75bc1 	fcvtsdeq	s11, d1
+ 0+2c4 <[^>]*> 0e318b10 	fmrdheq	r8, d1
+ 0+2c8 <[^>]*> 0e1f7b10 	fmrdleq	r7, d15
+ 0+2cc <[^>]*> 0e21fb10 	fmdhreq	d1, pc
+ 0+2d0 <[^>]*> 0e0f1b10 	fmdlreq	d15, r1
Index: testsuite/gas/arm/vfp1.s
===================================================================
RCS file: vfp1.s
diff -N vfp1.s
*** /dev/null	Tue May  5 13:32:27 1998
--- vfp1.s	Tue Jan 15 07:50:32 2002
***************
*** 0 ****
--- 1,278 ----
+ @ VFP Instructions for D variants (Double precision)
+ 	.text
+ 	.global F
+ F:
+ 	@ First we test the basic syntax and bit patterns of the opcodes.
+ 	@ Most of these tests deliberatly use d0/r0 to avoid setting
+ 	@ any more bits than necessary.
+ 
+ 	@ Comparison operations
+ 
+ 	fcmped	d0, d0
+ 	fcmpezd	d0
+ 	fcmpd	d0, d0
+ 	fcmpzd	d0
+ 
+ 	@ Monadic data operations
+ 
+ 	fabsd	d0, d0
+ 	fcpyd	d0, d0
+ 	fnegd	d0, d0
+ 	fsqrtd	d0, d0
+ 
+ 	@ Dyadic data operations
+ 
+ 	faddd	d0, d0, d0
+ 	fdivd	d0, d0, d0
+ 	fmacd	d0, d0, d0
+ 	fmscd	d0, d0, d0
+ 	fmuld	d0, d0, d0
+ 	fnmacd	d0, d0, d0
+ 	fnmscd	d0, d0, d0
+ 	fnmuld	d0, d0, d0
+ 	fsubd	d0, d0, d0
+ 
+ 	@ Load/store operations
+ 
+ 	fldd	d0, [r0]
+ 	fstd	d0, [r0]
+ 
+ 	@ Load/store multiple operations
+ 
+ 	fldmiad	r0, {d0}
+ 	fldmfdd	r0, {d0}
+ 	fldmiad	r0!, {d0}
+ 	fldmfdd	r0!, {d0}
+ 	fldmdbd	r0!, {d0}
+ 	fldmead	r0!, {d0}
+ 
+ 	fstmiad	r0, {d0}
+ 	fstmead	r0, {d0}
+ 	fstmiad	r0!, {d0}
+ 	fstmead	r0!, {d0}
+ 	fstmdbd	r0!, {d0}
+ 	fstmfdd	r0!, {d0}
+ 
+ 	@ Conversion operations
+ 
+ 	fsitod	d0, s0
+ 	fuitod	d0, s0
+ 
+ 	ftosid	s0, d0
+ 	ftosizd	s0, d0
+ 	ftouid	s0, d0
+ 	ftouizd	s0, d0
+ 
+ 	fcvtds	d0, s0
+ 	fcvtsd	s0, d0
+ 	
+ 	@ ARM from VFP operations
+ 
+ 	fmrdh	r0, d0
+ 	fmrdl	r0, d0
+ 
+ 	@ VFP From ARM operations
+ 
+ 	fmdhr	d0, r0
+ 	fmdlr	d0, r0
+ 
+ 	@ Now we test that the register fields are updated correctly for
+ 	@ each class of instruction.
+ 
+ 	@ Single register operations (compare-zero):
+ 
+ 	fcmpzd	d1
+ 	fcmpzd	d2
+ 	fcmpzd	d15
+ 
+ 	@ Two register comparison operations:
+ 
+ 	fcmpd	d0, d1
+ 	fcmpd	d0, d2
+ 	fcmpd	d0, d15
+ 	fcmpd	d1, d0
+ 	fcmpd	d2, d0
+ 	fcmpd	d15, d0
+ 	fcmpd	d5, d12
+ 
+ 	@ Two register data operations (monadic)
+ 
+ 	fnegd	d0, d1
+ 	fnegd	d0, d2
+ 	fnegd	d0, d15
+ 	fnegd	d1, d0
+ 	fnegd	d2, d0
+ 	fnegd	d15, d0
+ 	fnegd	d12, d5
+ 	
+ 	@ Three register data operations (dyadic)
+ 
+ 	faddd	d0, d0, d1
+ 	faddd	d0, d0, d2
+ 	faddd	d0, d0, d15
+ 	faddd	d0, d1, d0
+ 	faddd	d0, d2, d0
+ 	faddd	d0, d15, d0
+ 	faddd	d1, d0, d0
+ 	faddd	d2, d0, d0
+ 	faddd	d15, d0, d0
+ 	faddd	d12, d9, d5
+ 
+ 	@ Conversion operations
+ 
+ 	fcvtds	d0, s1
+ 	fcvtds	d0, s2
+ 	fcvtds	d0, s31
+ 	fcvtds	d1, s0
+ 	fcvtds	d2, s0
+ 	fcvtds	d15, s0
+ 	fcvtsd	s1, d0
+ 	fcvtsd	s2, d0
+ 	fcvtsd	s31, d0
+ 	fcvtsd	s0, d1
+ 	fcvtsd	s0, d2
+ 	fcvtsd	s0, d15
+ 
+ 	@ Move to VFP from ARM
+ 
+ 	fmrdh	r1, d0
+ 	fmrdh	r14, d0
+ 	fmrdh	r0, d1
+ 	fmrdh	r0, d2
+ 	fmrdh	r0, d15
+ 	fmrdl	r1, d0
+ 	fmrdl	r14, d0
+ 	fmrdl	r0, d1
+ 	fmrdl	r0, d2
+ 	fmrdl	r0, d15
+ 
+ 	@ Move to ARM from VFP
+ 
+ 	fmdhr	d0, r1
+ 	fmdhr	d0, r14
+ 	fmdhr	d1, r0
+ 	fmdhr	d2, r0
+ 	fmdhr	d15, r0
+ 	fmdlr	d0, r1
+ 	fmdlr	d0, r14
+ 	fmdlr	d1, r0
+ 	fmdlr	d2, r0
+ 	fmdlr	d15, r0
+ 
+ 	@ Load/store operations
+ 
+ 	fldd	d0, [r1]
+ 	fldd	d0, [r14]
+ 	fldd	d0, [r0, #0]
+ 	fldd	d0, [r0, #1020]
+ 	fldd	d0, [r0, #-1020]
+ 	fldd	d1, [r0]
+ 	fldd	d2, [r0]
+ 	fldd	d15, [r0]
+ 	fstd	d12, [r12, #804]
+ 
+ 	@ Load/store multiple operations
+ 
+ 	fldmiad	r0, {d1}
+ 	fldmiad	r0, {d2}
+ 	fldmiad	r0, {d15}
+ 	fldmiad	r0, {d0-d1}
+ 	fldmiad	r0, {d0-d2}
+ 	fldmiad	r0, {d0-d15}
+ 	fldmiad	r0, {d1-d15}
+ 	fldmiad	r0, {d2-d15}
+ 	fldmiad	r0, {d14-d15}
+ 	fldmiad	r1, {d0}
+ 	fldmiad	r14, {d0}
+ 
+ 	@ Check that we assemble all the register names correctly
+ 
+ 	fcmpzd	d0
+ 	fcmpzd	d1
+ 	fcmpzd	d2
+ 	fcmpzd	d3
+ 	fcmpzd	d4
+ 	fcmpzd	d5
+ 	fcmpzd	d6
+ 	fcmpzd	d7
+ 	fcmpzd	d8
+ 	fcmpzd	d9
+ 	fcmpzd	d10
+ 	fcmpzd	d11
+ 	fcmpzd	d12
+ 	fcmpzd	d13
+ 	fcmpzd	d14
+ 	fcmpzd	d15
+ 
+ 	@ Now we check the placement of the conditional execution substring.
+ 	@ On VFP this is always at the end of the instruction.
+ 	
+ 	@ Comparison operations
+ 
+ 	fcmpedeq	d1, d15
+ 	fcmpezdeq	d2
+ 	fcmpdeq	d3, d14
+ 	fcmpzdeq	d4
+ 
+ 	@ Monadic data operations
+ 
+ 	fabsdeq	d5, d13
+ 	fcpydeq	d6, d12
+ 	fnegdeq	d7, d11
+ 	fsqrtdeq	d8, d10
+ 
+ 	@ Dyadic data operations
+ 
+ 	fadddeq	d9, d1, d15
+ 	fdivdeq	d2, d3, d14
+ 	fmacdeq	d4, d13, d12
+ 	fmscdeq	d5, d6, d11
+ 	fmuldeq	d7, d10, d9
+ 	fnmacdeq	d8, d9, d10
+ 	fnmscdeq	d7, d6, d11
+ 	fnmuldeq	d5, d4, d12
+ 	fsubdeq	d3, d13, d14
+ 
+ 	@ Load/store operations
+ 
+ 	flddeq	d2, [r5]
+ 	fstdeq	d1, [r12]
+ 
+ 	@ Load/store multiple operations
+ 
+ 	fldmiadeq	r1, {d1}
+ 	fldmfddeq	r2, {d2}
+ 	fldmiadeq	r3!, {d3}
+ 	fldmfddeq	r4!, {d4}
+ 	fldmdbdeq	r5!, {d5}
+ 	fldmeadeq	r6!, {d6}
+ 
+ 	fstmiadeq	r7, {d15}
+ 	fstmeadeq	r8, {d14}
+ 	fstmiadeq	r9!, {d13}
+ 	fstmeadeq	r10!, {d12}
+ 	fstmdbdeq	r11!, {d11}
+ 	fstmfddeq	r12!, {d10}
+ 
+ 	@ Conversion operations
+ 
+ 	fsitodeq	d15, s1
+ 	fuitodeq	d1, s31
+ 
+ 	ftosideq	s1, d15
+ 	ftosizdeq	s31, d2
+ 	ftouideq	s15, d2
+ 	ftouizdeq	s11, d3
+ 
+ 	fcvtdseq	d1, s10
+ 	fcvtsdeq	s11, d1
+ 	
+ 	@ ARM from VFP operations
+ 
+ 	fmrdheq	r8, d1
+ 	fmrdleq	r7, d15
+ 
+ 	@ VFP From ARM operations
+ 
+ 	fmdhreq	d1, r15
+ 	fmdlreq	d15, r1
Index: testsuite/gas/arm/vfp1xD.d
===================================================================
RCS file: vfp1xD.d
diff -N vfp1xD.d
*** /dev/null	Tue May  5 13:32:27 1998
--- vfp1xD.d	Tue Jan 15 07:50:32 2002
***************
*** 0 ****
--- 1,241 ----
+ #objdump: -dr --prefix-addresses --show-raw-insn
+ #name: VFP Single-precision instructions
+ #as: -mvfpxd
+ 
+ # Test the ARM VFP Single Precision instructions
+ 
+ .*: +file format .*arm.*
+ 
+ Disassembly of section .text:
+ 0+000 <[^>]*> eef1fa10 	fmstat
+ 0+004 <[^>]*> eeb40ac0 	fcmpes	s0, s0
+ 0+008 <[^>]*> eeb50ac0 	fcmpezs	s0
+ 0+00c <[^>]*> eeb40a40 	fcmps	s0, s0
+ 0+010 <[^>]*> eeb50a40 	fcmpzs	s0
+ 0+014 <[^>]*> eeb00ac0 	fabss	s0, s0
+ 0+018 <[^>]*> eeb00a40 	fcpys	s0, s0
+ 0+01c <[^>]*> eeb10a40 	fnegs	s0, s0
+ 0+020 <[^>]*> eeb10ac0 	fsqrts	s0, s0
+ 0+024 <[^>]*> ee300a00 	fadds	s0, s0, s0
+ 0+028 <[^>]*> ee800a00 	fdivs	s0, s0, s0
+ 0+02c <[^>]*> ee000a00 	fmacs	s0, s0, s0
+ 0+030 <[^>]*> ee100a00 	fmscs	s0, s0, s0
+ 0+034 <[^>]*> ee200a00 	fmuls	s0, s0, s0
+ 0+038 <[^>]*> ee000a40 	fnmacs	s0, s0, s0
+ 0+03c <[^>]*> ee100a40 	fnmscs	s0, s0, s0
+ 0+040 <[^>]*> ee200a40 	fnmuls	s0, s0, s0
+ 0+044 <[^>]*> ee300a40 	fsubs	s0, s0, s0
+ 0+048 <[^>]*> ed900a00 	flds	s0, \[r0\]
+ 0+04c <[^>]*> ed800a00 	fsts	s0, \[r0\]
+ 0+050 <[^>]*> ec900a01 	fldmias	r0, {s0}
+ 0+054 <[^>]*> ec900a01 	fldmias	r0, {s0}
+ 0+058 <[^>]*> ecb00a01 	fldmias	r0!, {s0}
+ 0+05c <[^>]*> ecb00a01 	fldmias	r0!, {s0}
+ 0+060 <[^>]*> ed300a01 	fldmdbs	r0!, {s0}
+ 0+064 <[^>]*> ed300a01 	fldmdbs	r0!, {s0}
+ 0+068 <[^>]*> ec900b03 	fldmiax	r0, {d0}
+ 0+06c <[^>]*> ec900b03 	fldmiax	r0, {d0}
+ 0+070 <[^>]*> ecb00b03 	fldmiax	r0!, {d0}
+ 0+074 <[^>]*> ecb00b03 	fldmiax	r0!, {d0}
+ 0+078 <[^>]*> ed300b03 	fldmdbx	r0!, {d0}
+ 0+07c <[^>]*> ed300b03 	fldmdbx	r0!, {d0}
+ 0+080 <[^>]*> ec800a01 	fstmias	r0, {s0}
+ 0+084 <[^>]*> ec800a01 	fstmias	r0, {s0}
+ 0+088 <[^>]*> eca00a01 	fstmias	r0!, {s0}
+ 0+08c <[^>]*> eca00a01 	fstmias	r0!, {s0}
+ 0+090 <[^>]*> ed200a01 	fstmdbs	r0!, {s0}
+ 0+094 <[^>]*> ed200a01 	fstmdbs	r0!, {s0}
+ 0+098 <[^>]*> ec800b03 	fstmiax	r0, {d0}
+ 0+09c <[^>]*> ec800b03 	fstmiax	r0, {d0}
+ 0+0a0 <[^>]*> eca00b03 	fstmiax	r0!, {d0}
+ 0+0a4 <[^>]*> eca00b03 	fstmiax	r0!, {d0}
+ 0+0a8 <[^>]*> ed200b03 	fstmdbx	r0!, {d0}
+ 0+0ac <[^>]*> ed200b03 	fstmdbx	r0!, {d0}
+ 0+0b0 <[^>]*> eeb80ac0 	fsitos	s0, s0
+ 0+0b4 <[^>]*> eeb80a40 	fuitos	s0, s0
+ 0+0b8 <[^>]*> eebd0a40 	ftosis	s0, s0
+ 0+0bc <[^>]*> eebd0ac0 	ftosizs	s0, s0
+ 0+0c0 <[^>]*> eebc0a40 	ftouis	s0, s0
+ 0+0c4 <[^>]*> eebc0ac0 	ftouizs	s0, s0
+ 0+0c8 <[^>]*> ee100a10 	fmrs	r0, s0
+ 0+0cc <[^>]*> eef00a10 	fmrx	r0, fpsid
+ 0+0d0 <[^>]*> eef10a10 	fmrx	r0, fpscr
+ 0+0d4 <[^>]*> eef80a10 	fmrx	r0, fpexc
+ 0+0d8 <[^>]*> ee000a10 	fmsr	s0, r0
+ 0+0dc <[^>]*> eee00a10 	fmxr	fpsid, r0
+ 0+0e0 <[^>]*> eee10a10 	fmxr	fpscr, r0
+ 0+0e4 <[^>]*> eee80a10 	fmxr	fpexc, r0
+ 0+0e8 <[^>]*> eef50a40 	fcmpzs	s1
+ 0+0ec <[^>]*> eeb51a40 	fcmpzs	s2
+ 0+0f0 <[^>]*> eef5fa40 	fcmpzs	s31
+ 0+0f4 <[^>]*> eeb40a60 	fcmps	s0, s1
+ 0+0f8 <[^>]*> eeb40a41 	fcmps	s0, s2
+ 0+0fc <[^>]*> eeb40a6f 	fcmps	s0, s31
+ 0+100 <[^>]*> eef40a40 	fcmps	s1, s0
+ 0+104 <[^>]*> eeb41a40 	fcmps	s2, s0
+ 0+108 <[^>]*> eef4fa40 	fcmps	s31, s0
+ 0+10c <[^>]*> eef4aa46 	fcmps	s21, s12
+ 0+110 <[^>]*> eeb10a60 	fnegs	s0, s1
+ 0+114 <[^>]*> eeb10a41 	fnegs	s0, s2
+ 0+118 <[^>]*> eeb10a6f 	fnegs	s0, s31
+ 0+11c <[^>]*> eef10a40 	fnegs	s1, s0
+ 0+120 <[^>]*> eeb11a40 	fnegs	s2, s0
+ 0+124 <[^>]*> eef1fa40 	fnegs	s31, s0
+ 0+128 <[^>]*> eeb16a6a 	fnegs	s12, s21
+ 0+12c <[^>]*> ee300a20 	fadds	s0, s0, s0
+ 0+130 <[^>]*> ee300a01 	fadds	s0, s0, s0
+ 0+134 <[^>]*> ee300a2f 	fadds	s0, s0, s0
+ 0+138 <[^>]*> ee300a80 	fadds	s0, s1, s0
+ 0+13c <[^>]*> ee310a00 	fadds	s0, s2, s0
+ 0+140 <[^>]*> ee3f0a80 	fadds	s0, s31, s0
+ 0+144 <[^>]*> ee700a00 	fadds	s1, s0, s1
+ 0+148 <[^>]*> ee301a00 	fadds	s2, s0, s2
+ 0+14c <[^>]*> ee70fa00 	fadds	s31, s0, s31
+ 0+150 <[^>]*> ee3a6aa2 	fadds	s12, s21, s12
+ 0+154 <[^>]*> eeb80ae0 	fsitos	s0, s1
+ 0+158 <[^>]*> eeb80ac1 	fsitos	s0, s2
+ 0+15c <[^>]*> eeb80aef 	fsitos	s0, s31
+ 0+160 <[^>]*> eef80ac0 	fsitos	s1, s0
+ 0+164 <[^>]*> eeb81ac0 	fsitos	s2, s0
+ 0+168 <[^>]*> eef8fac0 	fsitos	s31, s0
+ 0+16c <[^>]*> eebd0a60 	ftosis	s0, s1
+ 0+170 <[^>]*> eebd0a41 	ftosis	s0, s2
+ 0+174 <[^>]*> eebd0a6f 	ftosis	s0, s31
+ 0+178 <[^>]*> eefd0a40 	ftosis	s1, s0
+ 0+17c <[^>]*> eebd1a40 	ftosis	s2, s0
+ 0+180 <[^>]*> eefdfa40 	ftosis	s31, s0
+ 0+184 <[^>]*> ee001a10 	fmsr	s0, r1
+ 0+188 <[^>]*> ee007a10 	fmsr	s0, r7
+ 0+18c <[^>]*> ee00ea10 	fmsr	s0, lr
+ 0+190 <[^>]*> ee000a90 	fmsr	s1, r0
+ 0+194 <[^>]*> ee010a10 	fmsr	s2, r0
+ 0+198 <[^>]*> ee0f0a90 	fmsr	s31, r0
+ 0+19c <[^>]*> ee0a7a90 	fmsr	s21, r7
+ 0+1a0 <[^>]*> eee01a10 	fmxr	fpsid, r1
+ 0+1a4 <[^>]*> eee0ea10 	fmxr	fpsid, lr
+ 0+1a8 <[^>]*> ee100a90 	fmrs	r0, s1
+ 0+1ac <[^>]*> ee110a10 	fmrs	r0, s2
+ 0+1b0 <[^>]*> ee1f0a90 	fmrs	r0, s31
+ 0+1b4 <[^>]*> ee101a10 	fmrs	r1, s0
+ 0+1b8 <[^>]*> ee107a10 	fmrs	r7, s0
+ 0+1bc <[^>]*> ee10ea10 	fmrs	lr, s0
+ 0+1c0 <[^>]*> ee159a90 	fmrs	r9, s11
+ 0+1c4 <[^>]*> eef01a10 	fmrx	r1, fpsid
+ 0+1c8 <[^>]*> eef0ea10 	fmrx	lr, fpsid
+ 0+1cc <[^>]*> ed910a00 	flds	s0, \[r1\]
+ 0+1d0 <[^>]*> ed9e0a00 	flds	s0, \[lr\]
+ 0+1d4 <[^>]*> ed900a00 	flds	s0, \[r0\]
+ 0+1d8 <[^>]*> ed900aff 	flds	s0, \[r0, #1020\]
+ 0+1dc <[^>]*> ed100aff 	flds	s0, \[r0, -#1020\]
+ 0+1e0 <[^>]*> edd00a00 	flds	s1, \[r0\]
+ 0+1e4 <[^>]*> ed901a00 	flds	s2, \[r0\]
+ 0+1e8 <[^>]*> edd0fa00 	flds	s31, \[r0\]
+ 0+1ec <[^>]*> edccaac9 	fsts	s21, \[ip, #804\]
+ 0+1f0 <[^>]*> ecd00a01 	fldmias	r0, {s1}
+ 0+1f4 <[^>]*> ec901a01 	fldmias	r0, {s2}
+ 0+1f8 <[^>]*> ecd0fa01 	fldmias	r0, {s31}
+ 0+1fc <[^>]*> ec900a02 	fldmias	r0, {s0-s1}
+ 0+200 <[^>]*> ec900a03 	fldmias	r0, {s0-s2}
+ 0+204 <[^>]*> ec900a20 	fldmias	r0, {s0-s31}
+ 0+208 <[^>]*> ecd00a1f 	fldmias	r0, {s1-s31}
+ 0+20c <[^>]*> ec901a1e 	fldmias	r0, {s2-s31}
+ 0+210 <[^>]*> ec90fa02 	fldmias	r0, {s30-s31}
+ 0+214 <[^>]*> ec910a01 	fldmias	r1, {s0}
+ 0+218 <[^>]*> ec9e0a01 	fldmias	lr, {s0}
+ 0+21c <[^>]*> ec801b03 	fstmiax	r0, {d1}
+ 0+220 <[^>]*> ec802b03 	fstmiax	r0, {d2}
+ 0+224 <[^>]*> ec80fb03 	fstmiax	r0, {d15}
+ 0+228 <[^>]*> ec800b05 	fstmiax	r0, {d0-d1}
+ 0+22c <[^>]*> ec800b07 	fstmiax	r0, {d0-d2}
+ 0+230 <[^>]*> ec800b21 	fstmiax	r0, {d0-d15}
+ 0+234 <[^>]*> ec801b1f 	fstmiax	r0, {d1-d15}
+ 0+238 <[^>]*> ec802b1d 	fstmiax	r0, {d2-d15}
+ 0+23c <[^>]*> ec80eb05 	fstmiax	r0, {d14-d15}
+ 0+240 <[^>]*> ec810b03 	fstmiax	r1, {d0}
+ 0+244 <[^>]*> ec8e0b03 	fstmiax	lr, {d0}
+ 0+248 <[^>]*> eeb50a40 	fcmpzs	s0
+ 0+24c <[^>]*> eef50a40 	fcmpzs	s1
+ 0+250 <[^>]*> eeb51a40 	fcmpzs	s2
+ 0+254 <[^>]*> eef51a40 	fcmpzs	s3
+ 0+258 <[^>]*> eeb52a40 	fcmpzs	s4
+ 0+25c <[^>]*> eef52a40 	fcmpzs	s5
+ 0+260 <[^>]*> eeb53a40 	fcmpzs	s6
+ 0+264 <[^>]*> eef53a40 	fcmpzs	s7
+ 0+268 <[^>]*> eeb54a40 	fcmpzs	s8
+ 0+26c <[^>]*> eef54a40 	fcmpzs	s9
+ 0+270 <[^>]*> eeb55a40 	fcmpzs	s10
+ 0+274 <[^>]*> eef55a40 	fcmpzs	s11
+ 0+278 <[^>]*> eeb56a40 	fcmpzs	s12
+ 0+27c <[^>]*> eef56a40 	fcmpzs	s13
+ 0+280 <[^>]*> eeb57a40 	fcmpzs	s14
+ 0+284 <[^>]*> eef57a40 	fcmpzs	s15
+ 0+288 <[^>]*> eeb58a40 	fcmpzs	s16
+ 0+28c <[^>]*> eef58a40 	fcmpzs	s17
+ 0+290 <[^>]*> eeb59a40 	fcmpzs	s18
+ 0+294 <[^>]*> eef59a40 	fcmpzs	s19
+ 0+298 <[^>]*> eeb5aa40 	fcmpzs	s20
+ 0+29c <[^>]*> eef5aa40 	fcmpzs	s21
+ 0+2a0 <[^>]*> eeb5ba40 	fcmpzs	s22
+ 0+2a4 <[^>]*> eef5ba40 	fcmpzs	s23
+ 0+2a8 <[^>]*> eeb5ca40 	fcmpzs	s24
+ 0+2ac <[^>]*> eef5ca40 	fcmpzs	s25
+ 0+2b0 <[^>]*> eeb5da40 	fcmpzs	s26
+ 0+2b4 <[^>]*> eef5da40 	fcmpzs	s27
+ 0+2b8 <[^>]*> eeb5ea40 	fcmpzs	s28
+ 0+2bc <[^>]*> eef5ea40 	fcmpzs	s29
+ 0+2c0 <[^>]*> eeb5fa40 	fcmpzs	s30
+ 0+2c4 <[^>]*> eef5fa40 	fcmpzs	s31
+ 0+2c8 <[^>]*> 0ef1fa10 	fmstateq
+ 0+2cc <[^>]*> 0ef41ae3 	fcmpeseq	s3, s7
+ 0+2d0 <[^>]*> 0ef52ac0 	fcmpezseq	s5
+ 0+2d4 <[^>]*> 0ef40a41 	fcmpseq	s1, s2
+ 0+2d8 <[^>]*> 0ef50a40 	fcmpzseq	s1
+ 0+2dc <[^>]*> 0ef00ae1 	fabsseq	s1, s3
+ 0+2e0 <[^>]*> 0ef0fa69 	fcpyseq	s31, s19
+ 0+2e4 <[^>]*> 0eb1aa44 	fnegseq	s20, s8
+ 0+2e8 <[^>]*> 0ef12ae3 	fsqrtseq	s5, s7
+ 0+2ec <[^>]*> 0e323a82 	faddseq	s6, s5, s6
+ 0+2f0 <[^>]*> 0ec11a20 	fdivseq	s3, s2, s1
+ 0+2f4 <[^>]*> 0e4ffa2e 	fmacseq	s31, s30, s29
+ 0+2f8 <[^>]*> 0e1dea8d 	fmscseq	s28, s27, s26
+ 0+2fc <[^>]*> 0e6cca2b 	fmulseq	s25, s24, s23
+ 0+300 <[^>]*> 0e0abaca 	fnmacseq	s22, s21, s20
+ 0+304 <[^>]*> 0e599a68 	fnmscseq	s19, s18, s17
+ 0+308 <[^>]*> 0e278ac7 	fnmulseq	s16, s15, s14
+ 0+30c <[^>]*> 0e766a65 	fsubseq	s13, s12, s11
+ 0+310 <[^>]*> 0d985a00 	fldseq	s10, \[r8\]
+ 0+314 <[^>]*> 0dc74a00 	fstseq	s9, \[r7\]
+ 0+318 <[^>]*> 0c914a01 	fldmiaseq	r1, {s8}
+ 0+31c <[^>]*> 0cd23a01 	fldmiaseq	r2, {s7}
+ 0+320 <[^>]*> 0cb33a01 	fldmiaseq	r3!, {s6}
+ 0+324 <[^>]*> 0cf42a01 	fldmiaseq	r4!, {s5}
+ 0+328 <[^>]*> 0d352a01 	fldmdbseq	r5!, {s4}
+ 0+32c <[^>]*> 0d761a01 	fldmdbseq	r6!, {s3}
+ 0+330 <[^>]*> 0c971b03 	fldmiaxeq	r7, {d1}
+ 0+334 <[^>]*> 0c982b03 	fldmiaxeq	r8, {d2}
+ 0+338 <[^>]*> 0cb93b03 	fldmiaxeq	r9!, {d3}
+ 0+33c <[^>]*> 0cba4b03 	fldmiaxeq	sl!, {d4}
+ 0+340 <[^>]*> 0d3b5b03 	fldmdbxeq	fp!, {d5}
+ 0+344 <[^>]*> 0d3c6b03 	fldmdbxeq	ip!, {d6}
+ 0+348 <[^>]*> 0c8d1a01 	fstmiaseq	sp, {s2}
+ 0+34c <[^>]*> 0cce0a01 	fstmiaseq	lr, {s1}
+ 0+350 <[^>]*> 0ce1fa01 	fstmiaseq	r1!, {s31}
+ 0+354 <[^>]*> 0ca2fa01 	fstmiaseq	r2!, {s30}
+ 0+358 <[^>]*> 0d63ea01 	fstmdbseq	r3!, {s29}
+ 0+35c <[^>]*> 0d24ea01 	fstmdbseq	r4!, {s28}
+ 0+360 <[^>]*> 0c857b03 	fstmiaxeq	r5, {d7}
+ 0+364 <[^>]*> 0c868b03 	fstmiaxeq	r6, {d8}
+ 0+368 <[^>]*> 0ca79b03 	fstmiaxeq	r7!, {d9}
+ 0+36c <[^>]*> 0ca8ab03 	fstmiaxeq	r8!, {d10}
+ 0+370 <[^>]*> 0d29bb03 	fstmdbxeq	r9!, {d11}
+ 0+374 <[^>]*> 0d2acb03 	fstmdbxeq	sl!, {d12}
+ 0+378 <[^>]*> 0ef8dac3 	fsitoseq	s27, s6
+ 0+37c <[^>]*> 0efdca62 	ftosiseq	s25, s5
+ 0+380 <[^>]*> 0efdbac2 	ftosizseq	s23, s4
+ 0+384 <[^>]*> 0efcaa61 	ftouiseq	s21, s3
+ 0+388 <[^>]*> 0efc9ac1 	ftouizseq	s19, s2
+ 0+38c <[^>]*> 0ef88a60 	fuitoseq	s17, s1
+ 0+390 <[^>]*> 0e11ba90 	fmrseq	fp, s3
+ 0+394 <[^>]*> 0ef09a10 	fmrxeq	r9, fpsid
+ 0+398 <[^>]*> 0e019a90 	fmsreq	s3, r9
+ 0+39c <[^>]*> 0ee08a10 	fmxreq	fpsid, r8
Index: testsuite/gas/arm/vfp1xD.s
===================================================================
RCS file: vfp1xD.s
diff -N vfp1xD.s
*** /dev/null	Tue May  5 13:32:27 1998
--- vfp1xD.s	Tue Jan 15 07:50:32 2002
***************
*** 0 ****
--- 1,339 ----
+ @ VFP Instructions for v1xD variants (Single precision only)
+ 	.text
+ 	.global F
+ F:
+ 	@ First we test the basic syntax and bit patterns of the opcodes.
+ 	@ Most of these tests deliberatly use s0/r0 to avoid setting
+ 	@ any more bits than necessary.
+ 
+ 	@ Comparison operations
+ 
+ 	fmstat
+ 
+ 	fcmpes	s0, s0
+ 	fcmpezs	s0
+ 	fcmps	s0, s0
+ 	fcmpzs	s0
+ 
+ 	@ Monadic data operations
+ 
+ 	fabss	s0, s0
+ 	fcpys	s0, s0
+ 	fnegs	s0, s0
+ 	fsqrts	s0, s0
+ 
+ 	@ Dyadic data operations
+ 
+ 	fadds	s0, s0, s0
+ 	fdivs	s0, s0, s0
+ 	fmacs	s0, s0, s0
+ 	fmscs	s0, s0, s0
+ 	fmuls	s0, s0, s0
+ 	fnmacs	s0, s0, s0
+ 	fnmscs	s0, s0, s0
+ 	fnmuls	s0, s0, s0
+ 	fsubs	s0, s0, s0
+ 
+ 	@ Load/store operations
+ 
+ 	flds	s0, [r0]
+ 	fsts	s0, [r0]
+ 
+ 	@ Load/store multiple operations
+ 
+ 	fldmias	r0, {s0}
+ 	fldmfds	r0, {s0}
+ 	fldmias	r0!, {s0}
+ 	fldmfds	r0!, {s0}
+ 	fldmdbs	r0!, {s0}
+ 	fldmeas	r0!, {s0}
+ 
+ 	fldmiax	r0, {d0}
+ 	fldmfdx	r0, {d0}
+ 	fldmiax	r0!, {d0}
+ 	fldmfdx	r0!, {d0}
+ 	fldmdbx	r0!, {d0}
+ 	fldmeax	r0!, {d0}
+ 
+ 	fstmias	r0, {s0}
+ 	fstmeas	r0, {s0}
+ 	fstmias	r0!, {s0}
+ 	fstmeas	r0!, {s0}
+ 	fstmdbs	r0!, {s0}
+ 	fstmfds	r0!, {s0}
+ 
+ 	fstmiax	r0, {d0}
+ 	fstmeax	r0, {d0}
+ 	fstmiax	r0!, {d0}
+ 	fstmeax	r0!, {d0}
+ 	fstmdbx	r0!, {d0}
+ 	fstmfdx	r0!, {d0}
+ 
+ 	@ Conversion operations
+ 
+ 	fsitos	s0, s0
+ 	fuitos	s0, s0
+ 
+ 	ftosis	s0, s0
+ 	ftosizs	s0, s0
+ 	ftouis	s0, s0
+ 	ftouizs	s0, s0
+ 
+ 	@ ARM from VFP operations
+ 
+ 	fmrs	r0, s0
+ 	fmrx	r0, fpsid
+ 	fmrx	r0, fpscr
+ 	fmrx	r0, fpexc
+ 
+ 	@ VFP From ARM operations
+ 
+ 	fmsr	s0, r0
+ 	fmxr	fpsid, r0
+ 	fmxr	fpscr, r0
+ 	fmxr	fpexc, r0
+ 
+ 	@ Now we test that the register fields are updated correctly for
+ 	@ each class of instruction.
+ 
+ 	@ Single register operations (compare-zero):
+ 
+ 	fcmpzs	s1
+ 	fcmpzs	s2
+ 	fcmpzs	s31
+ 
+ 	@ Two register comparison operations:
+ 
+ 	fcmps	s0, s1
+ 	fcmps	s0, s2
+ 	fcmps	s0, s31
+ 	fcmps	s1, s0
+ 	fcmps	s2, s0
+ 	fcmps	s31, s0
+ 	fcmps	s21, s12
+ 
+ 	@ Two register data operations (monadic)
+ 
+ 	fnegs	s0, s1
+ 	fnegs	s0, s2
+ 	fnegs	s0, s31
+ 	fnegs	s1, s0
+ 	fnegs	s2, s0
+ 	fnegs	s31, s0
+ 	fnegs	s12, s21
+ 	
+ 	@ Three register data operations (dyadic)
+ 
+ 	fadds	s0, s0, s1
+ 	fadds	s0, s0, s2
+ 	fadds	s0, s0, s31
+ 	fadds	s0, s1, s0
+ 	fadds	s0, s2, s0
+ 	fadds	s0, s31, s0
+ 	fadds	s1, s0, s0
+ 	fadds	s2, s0, s0
+ 	fadds	s31, s0, s0
+ 	fadds	s12, s21, s5
+ 
+ 	@ Conversion operations
+ 
+ 	fsitos	s0, s1
+ 	fsitos	s0, s2
+ 	fsitos	s0, s31
+ 	fsitos	s1, s0
+ 	fsitos	s2, s0
+ 	fsitos	s31, s0
+ 
+ 	ftosis	s0, s1
+ 	ftosis	s0, s2
+ 	ftosis	s0, s31
+ 	ftosis	s1, s0
+ 	ftosis	s2, s0
+ 	ftosis	s31, s0
+ 
+ 	@ Move to VFP from ARM
+ 
+ 	fmsr	s0, r1
+ 	fmsr	s0, r7
+ 	fmsr	s0, r14
+ 	fmsr	s1, r0
+ 	fmsr	s2, r0
+ 	fmsr	s31, r0
+ 	fmsr	s21, r7
+ 
+ 	fmxr	fpsid, r1
+ 	fmxr	fpsid, r14
+ 
+ 	@ Move to ARM from VFP
+ 
+ 	fmrs	r0, s1
+ 	fmrs	r0, s2
+ 	fmrs	r0, s31
+ 	fmrs	r1, s0
+ 	fmrs	r7, s0
+ 	fmrs	r14, s0
+ 	fmrs	r9, s11
+ 
+ 	fmrx	r1, fpsid
+ 	fmrx	r14, fpsid
+ 
+ 	@ Load/store operations
+ 
+ 	flds	s0, [r1]
+ 	flds	s0, [r14]
+ 	flds	s0, [r0, #0]
+ 	flds	s0, [r0, #1020]
+ 	flds	s0, [r0, #-1020]
+ 	flds	s1, [r0]
+ 	flds	s2, [r0]
+ 	flds	s31, [r0]
+ 	fsts	s21, [r12, #804]
+ 
+ 	@ Load/store multiple operations
+ 
+ 	fldmias	r0, {s1}
+ 	fldmias	r0, {s2}
+ 	fldmias	r0, {s31}
+ 	fldmias	r0, {s0-s1}
+ 	fldmias	r0, {s0-s2}
+ 	fldmias	r0, {s0-s31}
+ 	fldmias	r0, {s1-s31}
+ 	fldmias	r0, {s2-s31}
+ 	fldmias	r0, {s30-s31}
+ 	fldmias	r1, {s0}
+ 	fldmias	r14, {s0}
+ 
+ 	fstmiax	r0, {d1}
+ 	fstmiax	r0, {d2}
+ 	fstmiax	r0, {d15}
+ 	fstmiax	r0, {d0-d1}
+ 	fstmiax	r0, {d0-d2}
+ 	fstmiax	r0, {d0-d15}
+ 	fstmiax	r0, {d1-d15}
+ 	fstmiax	r0, {d2-d15}
+ 	fstmiax	r0, {d14-d15}
+ 	fstmiax	r1, {d0}
+ 	fstmiax	r14, {d0}
+ 
+ 	@ Check that we assemble all the register names correctly
+ 
+ 	fcmpzs	s0
+ 	fcmpzs	s1
+ 	fcmpzs	s2
+ 	fcmpzs	s3
+ 	fcmpzs	s4
+ 	fcmpzs	s5
+ 	fcmpzs	s6
+ 	fcmpzs	s7
+ 	fcmpzs	s8
+ 	fcmpzs	s9
+ 	fcmpzs	s10
+ 	fcmpzs	s11
+ 	fcmpzs	s12
+ 	fcmpzs	s13
+ 	fcmpzs	s14
+ 	fcmpzs	s15
+ 	fcmpzs	s16
+ 	fcmpzs	s17
+ 	fcmpzs	s18
+ 	fcmpzs	s19
+ 	fcmpzs	s20
+ 	fcmpzs	s21
+ 	fcmpzs	s22
+ 	fcmpzs	s23
+ 	fcmpzs	s24
+ 	fcmpzs	s25
+ 	fcmpzs	s26
+ 	fcmpzs	s27
+ 	fcmpzs	s28
+ 	fcmpzs	s29
+ 	fcmpzs	s30
+ 	fcmpzs	s31
+ 
+ 	@ Now we check the placement of the conditional execution substring.
+ 	@ On VFP this is always at the end of the instruction.
+ 	@ We use different register numbers here to check for correct
+ 	@ disassembly
+ 	
+ 	@ Comparison operations
+ 
+ 	fmstateq
+ 
+ 	fcmpeseq	s3, s7
+ 	fcmpezseq	s5
+ 	fcmpseq	s1, s2
+ 	fcmpzseq	s1
+ 
+ 	@ Monadic data operations
+ 
+ 	fabsseq	s1, s3
+ 	fcpyseq	s31, s19
+ 	fnegseq	s20, s8
+ 	fsqrtseq	s5, s7
+ 
+ 	@ Dyadic data operations
+ 
+ 	faddseq	s6, s5, s4
+ 	fdivseq	s3, s2, s1
+ 	fmacseq	s31, s30, s29
+ 	fmscseq	s28, s27, s26
+ 	fmulseq	s25, s24, s23
+ 	fnmacseq	s22, s21, s20
+ 	fnmscseq	s19, s18, s17
+ 	fnmulseq	s16, s15, s14
+ 	fsubseq	s13, s12, s11
+ 
+ 	@ Load/store operations
+ 
+ 	fldseq	s10, [r8]
+ 	fstseq	s9, [r7]
+ 
+ 	@ Load/store multiple operations
+ 
+ 	fldmiaseq	r1, {s8}
+ 	fldmfdseq	r2, {s7}
+ 	fldmiaseq	r3!, {s6}
+ 	fldmfdseq	r4!, {s5}
+ 	fldmdbseq	r5!, {s4}
+ 	fldmeaseq	r6!, {s3}
+ 
+ 	fldmiaxeq	r7, {d1}
+ 	fldmfdxeq	r8, {d2}
+ 	fldmiaxeq	r9!, {d3}
+ 	fldmfdxeq	r10!, {d4}
+ 	fldmdbxeq	r11!, {d5}
+ 	fldmeaxeq	r12!, {d6}
+ 
+ 	fstmiaseq	r13, {s2}
+ 	fstmeaseq	r14, {s1}
+ 	fstmiaseq	r1!, {s31}
+ 	fstmeaseq	r2!, {s30}
+ 	fstmdbseq	r3!, {s29}
+ 	fstmfdseq	r4!, {s28}
+ 
+ 	fstmiaxeq	r5, {d7}
+ 	fstmeaxeq	r6, {d8}
+ 	fstmiaxeq	r7!, {d9}
+ 	fstmeaxeq	r8!, {d10}
+ 	fstmdbxeq	r9!, {d11}
+ 	fstmfdxeq	r10!, {d12}
+ 
+ 	@ Conversion operations
+ 
+ 	fsitoseq	s27, s6
+ 	ftosiseq	s25, s5
+ 	ftosizseq	s23, s4
+ 	ftouiseq	s21, s3
+ 	ftouizseq	s19, s2
+ 	fuitoseq	s17, s1
+ 
+ 	@ ARM from VFP operations
+ 
+ 	fmrseq	r11, s3
+ 	fmrxeq	r9, fpsid
+ 
+ 	@ VFP From ARM operations
+ 
+ 	fmsreq	s3, r9
+ 	fmxreq	fpsid, r8
+ 

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