--- binutils-2.18-original/gas/config/tc-arm.c	2007-05-18 13:45:49.000000000 +1000
+++ binutils-2.18/gas/config/tc-arm.c	2008-04-03 12:38:28.000000000 +1000
@@ -3573,6 +3575,140 @@
   ignore_rest_of_line ();
 }
 
+/* Parse a directive saving Maverick Crunch double registers.  */
+
+static void
+s_arm_unwind_save_mvd (void)
+{
+  int reg;
+  int hi_reg;
+  int i;
+  unsigned mask = 0;
+  valueT op;
+
+  if (*input_line_pointer == '{')
+    input_line_pointer++;
+
+  do
+    {
+      reg = arm_reg_parse (&input_line_pointer, REG_TYPE_MVD);
+
+      if (reg == FAIL)
+	{
+	  as_bad (_(reg_expected_msgs[REG_TYPE_MVD]));
+	  goto error;
+	}
+
+      if (mask >> reg)
+        as_tsktsk (_("register list not in ascending order"));
+      mask |= 1 << reg;
+
+      if (*input_line_pointer == '-')
+	{
+	  input_line_pointer++;
+	  hi_reg = arm_reg_parse (&input_line_pointer, REG_TYPE_MVD);
+	  if (hi_reg == FAIL)
+	    {
+	      as_bad (_(reg_expected_msgs[REG_TYPE_MVD]));
+	      goto error;
+	    }
+	  else if (reg >= hi_reg)
+	    {
+	      as_bad (_("bad register range"));
+	      goto error;
+	    }
+	  for (; reg < hi_reg; reg++)
+	    mask |= 1 << reg;
+	}
+    }
+  while (skip_past_comma (&input_line_pointer) != FAIL);
+
+  if (*input_line_pointer == '}')
+    input_line_pointer++;
+
+  demand_empty_rest_of_line ();
+
+  /* Generate any deferred opcodes because we're going to be looking at
+     the list.	*/
+  flush_pending_unwind ();
+
+  for (i = 0; i < 16; i++)
+    {
+      if (mask & (1 << i))
+	unwind.frame_size += 8;
+    }
+
+  /* Attempt to combine with a previous opcode.	 We do this because gcc
+     likes to output separate unwind directives for a single block of
+     registers.	 */
+  if (unwind.opcode_count > 0)
+    {
+      i = unwind.opcodes[unwind.opcode_count - 1];
+      if ((i & 0xf8) == 0xd8)
+        {
+          i &= 7;
+          /* Only merge if the blocks are contiguous.  */
+          if (i < 6)
+	         {
+               if ((mask & 0xfe00) == (1 << 9))
+		        {
+                 mask |= ((1 << (i + 11)) - 1) & 0xfc00;
+                 unwind.opcode_count--;
+               }
+	         }
+          else if (i == 6 && unwind.opcode_count >= 2)
+	         {
+	      i = unwind.opcodes[unwind.opcode_count - 2];
+	      reg = i >> 4;
+	      i &= 0xf;
+
+	      op = 0xffff << (reg - 1);
+         if (reg > 0
+		     && ((mask & op) == (1u << (reg - 1))))
+		   {
+		     op = (1 << (reg + i + 1)) - 1;
+		     op &= ~((1 << reg) - 1);
+		     mask |= op;
+		     unwind.opcode_count -= 2;
+		   }
+        }
+      }
+    }
+
+  hi_reg = 15;
+  /* We want to generate opcodes in the order the registers have been
+     saved, ie. descending order.  */
+  for (reg = 15; reg >= -1; reg--)
+    {
+      /* Save registers in blocks.  */
+      if (reg < 0
+	  || !(mask & (1 << reg)))
+	{
+	  /* We found an unsaved reg.  Generate opcodes to save the
+	     preceeding block.	*/
+	  if (reg != hi_reg)
+	    {
+	      if (reg == 9)
+		{
+		  /* Short form.  */
+		  op = 0xd8 | (hi_reg - 10);
+		  add_unwind_opcode (op, 1);
+		}
+	      else
+		{
+		  /* Long form.	 */
+		  op = 0xde00 | ((reg + 1) << 4) | ((hi_reg - reg) - 1);
+		  add_unwind_opcode (op, 2);
+		}
+	    }
+	  hi_reg = reg - 1;
+	}
+    }
+
+  return;
+error:
+  ignore_rest_of_line ();
+}
 
 /* Parse an unwind_save directive.
    If the argument is non-zero, this is a .vsave directive.  */
@@ -3624,6 +3760,8 @@
     case REG_TYPE_MMXWR:  s_arm_unwind_save_mmxwr ();  return;
     case REG_TYPE_MMXWCG: s_arm_unwind_save_mmxwcg (); return;
 
+    case REG_TYPE_MVD:    s_arm_unwind_save_mvd (); return;    
+
     default:
       as_bad (_(".unwind_save does not support this kind of register"));
       ignore_rest_of_line ();
@@ -14256,8 +14394,8 @@
   REGDEF(FPSID,0,VFC), REGDEF(FPSCR,1,VFC), REGDEF(FPEXC,8,VFC),
 
   /* Maverick DSP coprocessor registers.  */
-  REGSET(mvf,MVF),  REGSET(mvd,MVD),  REGSET(mvfx,MVFX),  REGSET(mvdx,MVDX),
-  REGSET(MVF,MVF),  REGSET(MVD,MVD),  REGSET(MVFX,MVFX),  REGSET(MVDX,MVDX),
+  REGSET(mv,MVD),  REGSET(mvf,MVF),  REGSET(mvd,MVD),  REGSET(mvfx,MVFX),  REGSET(mvdx,MVDX),
+  REGSET(MV,MVD),  REGSET(MVF,MVF),  REGSET(MVD,MVD),  REGSET(MVFX,MVFX),  REGSET(MVDX,MVDX),
 
   REGNUM(mvax,0,MVAX), REGNUM(mvax,1,MVAX),
   REGNUM(mvax,2,MVAX), REGNUM(mvax,3,MVAX),