public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
From: Mark Shinwell <shinwell@codesourcery.com>
To: binutils@sourceware.org
Subject: [PATCH] .savev6 directive for ARM
Date: Tue, 20 Jun 2006 16:34:00 -0000	[thread overview]
Message-ID: <44981F80.7060205@codesourcery.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 1455 bytes --]

The FLDMX/FSTMX VFP multiple load/store instructions are deprecated as
of ARMv6 in favour of FLDMD and FSTMD.  The unwind opcodes corresponding
to FSTMD are different from those corresponding to FSTMX.

This patch provides a new gas directive .savev6 that can be used to
generate unwind information corresponding to the saving of VFP registers
with FSTMD.  It also works with VFPv3 registers saved with VSTM.
Assembly source using .save will still use the FSTMX-style unwind
opcodes; thus, backwards compatibility is maintained.

I've also corrected a typo in the example of .save in the manual, see
below.

Up my sleeve I have a gcc patch to go along with this that causes the
compiler to emit .savev6 directives and to no longer emit FLDMX and
FSTMX instructions -- along with the necessary unwinder support and a few
bugfixes in that area.  At the moment that requires this patch, so I'm
posting here first.

Tested for arm-none-linux-gnueabi.

OK?

Mark

--

gas/ChangeLog:

2006-06-20  Mark Shinwell  <shinwell@codesourcery.com>

	* config/tc-arm.c (s_arm_unwind_save_vfp_armv6): New.  Parse
	a directive saving VFP registers for ARMv6 or later.
	(s_arm_unwind_save): Add parameter arch_v6 and call
	s_arm_unwind_save_vfp or s_arm_unwind_save_vfp_armv6 as
	appropriate.
	(md_pseudo_table): Add entry for new "savev6" directive.
	* doc/c-arm.texi: Correct error in example for "save"
	directive (fstmdf -> fstmdx).  Also document "savev6" directive.


[-- Attachment #2: fstmd-binutils.patch --]
[-- Type: text/plain, Size: 4536 bytes --]

Index: gas/config/tc-arm.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-arm.c,v
retrieving revision 1.250.2.16
diff -U3 -p -r1.250.2.16 tc-arm.c
--- gas/config/tc-arm.c	15 May 2006 20:46:24 -0000	1.250.2.16
+++ gas/config/tc-arm.c	20 Jun 2006 15:48:00 -0000
@@ -3271,7 +3271,57 @@ s_arm_unwind_save_fpa (int reg)
 }
 
 
-/* Parse a directive saving VFP registers.  */
+/* Parse a directive saving VFP registers for ARMv6 and above.  */
+
+static void
+s_arm_unwind_save_vfp_armv6 (void)
+{
+  int count;
+  unsigned int start;
+  valueT op;
+  int num_vfpv3_regs = 0;
+  int num_regs_below_16;
+
+  count = parse_vfp_reg_list (&input_line_pointer, &start, REGLIST_VFP_D);
+  if (count == FAIL)
+    {
+      as_bad (_("expected register list"));
+      ignore_rest_of_line ();
+      return;
+    }
+
+  demand_empty_rest_of_line ();
+
+  /* We always generate FSTMD/FLDMD-style unwinding opcodes (rather
+     than FSTMX/FLDMX-style ones).  */
+
+  /* Generate opcode for (VFPv3) registers numbered in the range 16 .. 31.  */
+  if (start >= 16)
+    num_vfpv3_regs = count;
+  else if (start + count > 16)
+    num_vfpv3_regs = start + count - 16;
+
+  if (num_vfpv3_regs > 0)
+    {
+      int start_offset = start > 16 ? start - 16 : 0;
+      op = 0xc800 | (start_offset << 4) | (num_vfpv3_regs - 1);
+      add_unwind_opcode (op, 2);
+    }
+
+  /* Generate opcode for registers numbered in the range 0 .. 15.  */
+  num_regs_below_16 = num_vfpv3_regs > 0 ? 16 - (int) start : count;
+  assert (num_regs_below_16 + num_vfpv3_regs == count);
+  if (num_regs_below_16 > 0)
+    {
+      op = 0xc900 | (start << 4) | (num_regs_below_16 - 1);
+      add_unwind_opcode (op, 2);
+    }
+
+  unwind.frame_size += count * 8;
+}
+
+
+/* Parse a directive saving VFP registers for pre-ARMv6.  */
 
 static void
 s_arm_unwind_save_vfp (void)
@@ -3509,10 +3559,11 @@ error:
 }
 
 
-/* Parse an unwind_save directive.  */
+/* Parse an unwind_save directive.
+   If the argument is non-zero, this is a .savev6 directive.  */
 
 static void
-s_arm_unwind_save (int ignored ATTRIBUTE_UNUSED)
+s_arm_unwind_save (int arch_v6)
 {
   char *peek;
   struct reg_entry *reg;
@@ -3549,7 +3600,12 @@ s_arm_unwind_save (int ignored ATTRIBUTE
       return;
 
     case REG_TYPE_RN:	  s_arm_unwind_save_core ();   return;
-    case REG_TYPE_VFD:	   s_arm_unwind_save_vfp ();	return;
+    case REG_TYPE_VFD:
+      if (arch_v6)
+        s_arm_unwind_save_vfp_armv6 ();
+      else
+        s_arm_unwind_save_vfp ();
+      return;
     case REG_TYPE_MMXWR:  s_arm_unwind_save_mmxwr ();  return;
     case REG_TYPE_MMXWCG: s_arm_unwind_save_mmxwcg (); return;
 
@@ -3856,6 +3912,7 @@ const pseudo_typeS md_pseudo_table[] =
   { "personalityindex",	s_arm_unwind_personalityindex, 0 },
   { "handlerdata",	s_arm_unwind_handlerdata, 0 },
   { "save",		s_arm_unwind_save,	0 },
+  { "savev6",		s_arm_unwind_save,	1 },
   { "movsp",		s_arm_unwind_movsp,	0 },
   { "pad",		s_arm_unwind_pad,	0 },
   { "setfp",		s_arm_unwind_setfp,	0 },
Index: gas/doc/c-arm.texi
===================================================================
RCS file: /cvs/src/src/gas/doc/c-arm.texi,v
retrieving revision 1.37.2.2
diff -U3 -p -r1.37.2.2 c-arm.texi
--- gas/doc/c-arm.texi	3 May 2006 16:13:43 -0000	1.37.2.2
+++ gas/doc/c-arm.texi	20 Jun 2006 15:48:01 -0000
@@ -535,7 +535,7 @@ instruction.
   sfmfd f4, 2, [sp]!
 @exdent @emph{VFP registers}
   .save @{d8, d9, d10@}
-  fstmdf sp!, @{d8, d9, d10@}
+  fstmdx sp!, @{d8, d9, d10@}
 @exdent @emph{iWMMXt registers}
   .save @{wr10, wr11@}
   wstrd wr11, [sp, #-8]!
@@ -547,6 +547,26 @@ or
   wstrd wr10, [sp, #-8]!
 @end smallexample
 
+@cindex @code{.savev6} directive, ARM
+@item .savev6 @var{vfp-reglist}
+Generate unwinder annotations to restore the VFP registers in @var{vfp-reglist}
+using FLDMD.  Also works for VFPv3 registers
+that are to be restored using VLDM.
+The format of @var{vfp-reglist} is the same as the corresponding store-multiple
+instruction.
+
+@smallexample
+@exdent @emph{VFP registers}
+  .savev6 @{d8, d9, d10@}
+  fstmdd sp!, @{d8, d9, d10@}
+@exdent @emph{VFPv3 registers}
+  .savev6 @{d15, d16, d17@}
+  vstm sp!, @{d15, d16, d17@}
+@end smallexample
+
+Since FLDMX and FSTMX are now deprecated, this directive should be
+used in favour of @code{.save} for saving VFP registers for ARMv6 and above.
+
 @cindex @code{.pad} directive, ARM
 @item .pad #@var{count}
 Generate unwinder annotations for a stack adjustment of @var{count} bytes.

             reply	other threads:[~2006-06-20 16:17 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-06-20 16:34 Mark Shinwell [this message]
2006-06-20 16:36 ` Richard Earnshaw
2006-06-20 17:59   ` Mark Shinwell
2006-06-21 10:41     ` Richard Earnshaw
2006-06-21 11:21       ` Mark Shinwell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=44981F80.7060205@codesourcery.com \
    --to=shinwell@codesourcery.com \
    --cc=binutils@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).