binutils: added Maverick support (done by Hasjim Williams)
authorMarcin Juszkiewicz <marcin@juszkiewicz.com.pl>
Thu, 4 Jun 2009 14:43:11 +0000 (16:43 +0200)
committerMarcin Juszkiewicz <marcin@juszkiewicz.com.pl>
Mon, 8 Jun 2009 13:12:31 +0000 (15:12 +0200)
Signed-off-by: Marcin Juszkiewicz <marcin@juszkiewicz.com.pl>
Acked-by: Koen Kooi <koen@openembedded.org>
recipes/binutils/binutils_2.18.bb
recipes/binutils/files/binutils-crunch.patch [new file with mode: 0644]

index 0155fb1..3b650c6 100644 (file)
@@ -1,4 +1,4 @@
-PR = "r5"
+PR = "r6"
 
 require binutils.inc
 LICENSE = "GPLv3"
@@ -18,3 +18,6 @@ SRC_URI = "\
 
 # powerpc patches
 SRC_URI += "file://binutils-2.16.1-e300c2c3.patch;patch=1"
+
+# ep93xx crunch patches
+SRC_URI_append_ep9312 = " file://binutils-crunch.patch;patch=1"
diff --git a/recipes/binutils/files/binutils-crunch.patch b/recipes/binutils/files/binutils-crunch.patch
new file mode 100644 (file)
index 0000000..79771aa
--- /dev/null
@@ -0,0 +1,163 @@
+--- 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),