2007-09-28 Bernd Schmidt <bernd.schmidt@analog.com>
[deliverable/binutils-gdb.git] / gas / config / bfin-parse.y
index 283b8130fc3003da2ed115aa30936132a89becd0..d22f774b1c850ffcf38038a5f604917f22267a80 100644 (file)
@@ -1,5 +1,5 @@
 /* bfin-parse.y  ADI Blackfin parser
-   Copyright 2005, 2006, 2007
+   Copyright 2005, 2006, 2007, 2008
    Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
@@ -23,7 +23,7 @@
 #include "as.h"
 #include <obstack.h>
 
-#include "bfin-aux.h"  // opcode generating auxiliaries
+#include "bfin-aux.h"  /* Opcode generating auxiliaries.  */
 #include "libbfd.h"
 #include "elf/common.h"
 #include "elf/bfin.h"
@@ -169,13 +169,13 @@ int yyerror (char *msg);
 void error (char *format, ...)
 {
     va_list ap;
-    char buffer[2000];
+    static char buffer[2000];
     
     va_start (ap, format);
     vsprintf (buffer, format, ap);
     va_end (ap);
 
-    as_bad (buffer);
+    as_bad ("%s", buffer);
 }
 
 int
@@ -385,6 +385,28 @@ is_group2 (INSTR_T x)
   return 0;
 }
 
+static INSTR_T
+gen_multi_instr_1 (INSTR_T dsp32, INSTR_T dsp16_grp1, INSTR_T dsp16_grp2)
+{
+  int mask1 = dsp32 ? insn_regmask (dsp32->value, dsp32->next->value) : 0;
+  int mask2 = dsp16_grp1 ? insn_regmask (dsp16_grp1->value, 0) : 0;
+  int mask3 = dsp16_grp2 ? insn_regmask (dsp16_grp2->value, 0) : 0;
+
+  if ((mask1 & mask2) || (mask1 & mask3) || (mask2 & mask3))
+    yyerror ("resource conflict in multi-issue instruction");
+
+  /* Anomaly 05000074 */
+  if (ENABLE_AC_05000074
+      && (dsp32->value & 0xf780) == 0xc680
+      && ((dsp16_grp1->value & 0xfe40) == 0x9240
+         || (dsp16_grp1->value & 0xfe08) == 0xba08
+         || (dsp16_grp1->value & 0xfc00) == 0xbc00))
+    yyerror ("anomaly 05000074 - Multi-Issue Instruction with \
+dsp32shiftimm in slot1 and P-reg Store in slot2 Not Supported");
+
+  return bfin_gen_multi_instr (dsp32, dsp16_grp1, dsp16_grp2);
+}
+
 %}
 
 %union {
@@ -608,27 +630,27 @@ asm: asm_1 SEMICOLON
          if (($1->value & 0xf800) == 0xc000)
            {
              if (is_group1 ($3) && is_group2 ($5))
-               $$ = bfin_gen_multi_instr ($1, $3, $5);
+               $$ = gen_multi_instr_1 ($1, $3, $5);
              else if (is_group2 ($3) && is_group1 ($5))
-               $$ = bfin_gen_multi_instr ($1, $5, $3);
+               $$ = gen_multi_instr_1 ($1, $5, $3);
              else
                return yyerror ("Wrong 16 bit instructions groups, slot 2 and slot 3 must be 16-bit instrution group");
            }
          else if (($3->value & 0xf800) == 0xc000)
            {
              if (is_group1 ($1) && is_group2 ($5))
-               $$ = bfin_gen_multi_instr ($3, $1, $5);
+               $$ = gen_multi_instr_1 ($3, $1, $5);
              else if (is_group2 ($1) && is_group1 ($5))
-               $$ = bfin_gen_multi_instr ($3, $5, $1);
+               $$ = gen_multi_instr_1 ($3, $5, $1);
              else
                return yyerror ("Wrong 16 bit instructions groups, slot 1 and slot 3 must be 16-bit instrution group");
            }
          else if (($5->value & 0xf800) == 0xc000)
            {
              if (is_group1 ($1) && is_group2 ($3))
-               $$ = bfin_gen_multi_instr ($5, $1, $3);
+               $$ = gen_multi_instr_1 ($5, $1, $3);
              else if (is_group2 ($1) && is_group1 ($3))
-               $$ = bfin_gen_multi_instr ($5, $3, $1);
+               $$ = gen_multi_instr_1 ($5, $3, $1);
              else
                return yyerror ("Wrong 16 bit instructions groups, slot 1 and slot 2 must be 16-bit instrution group");
            }
@@ -641,25 +663,25 @@ asm: asm_1 SEMICOLON
          if (($1->value & 0xf800) == 0xc000)
            {
              if (is_group1 ($3))
-               $$ = bfin_gen_multi_instr ($1, $3, 0);
+               $$ = gen_multi_instr_1 ($1, $3, 0);
              else if (is_group2 ($3))
-               $$ = bfin_gen_multi_instr ($1, 0, $3);
+               $$ = gen_multi_instr_1 ($1, 0, $3);
              else
                return yyerror ("Wrong 16 bit instructions groups, slot 2 must be the 16-bit instruction group");
            }
          else if (($3->value & 0xf800) == 0xc000)
            {
              if (is_group1 ($1))
-               $$ = bfin_gen_multi_instr ($3, $1, 0);
+               $$ = gen_multi_instr_1 ($3, $1, 0);
              else if (is_group2 ($1))
-               $$ = bfin_gen_multi_instr ($3, 0, $1);
+               $$ = gen_multi_instr_1 ($3, 0, $1);
              else
                return yyerror ("Wrong 16 bit instructions groups, slot 1 must be the 16-bit instruction group");
            }
          else if (is_group1 ($1) && is_group2 ($3))
-             $$ = bfin_gen_multi_instr (0, $1, $3);
+             $$ = gen_multi_instr_1 (0, $1, $3);
          else if (is_group2 ($1) && is_group1 ($3))
-           $$ = bfin_gen_multi_instr (0, $3, $1);
+           $$ = gen_multi_instr_1 (0, $3, $1);
          else
            return yyerror ("Wrong 16 bit instructions groups, slot 1 and slot 2 must be the 16-bit instruction group");
        }
@@ -1932,22 +1954,20 @@ asm_1:
          else
            return yyerror ("Bad shift value or register");
        }
-       | HALF_REG ASSIGN HALF_REG LESS_LESS expr
-       {
-         if (IS_UIMM ($5, 4))
-           {
-             notethat ("dsp32shiftimm: dregs_half = dregs_half << uimm4\n");
-             $$ = DSP32SHIFTIMM (0x0, &$1, imm5 ($5), &$3, 2, HL2 ($1, $3));
-           }
-         else
-           return yyerror ("Bad shift value");
-       }
        | HALF_REG ASSIGN HALF_REG LESS_LESS expr smod 
        {
          if (IS_UIMM ($5, 4))
            {
-             notethat ("dsp32shiftimm: dregs_half = dregs_half << uimm4\n");
-             $$ = DSP32SHIFTIMM (0x0, &$1, imm5 ($5), &$3, $6.s0, HL2 ($1, $3));
+             if ($6.s0)
+               {
+                 notethat ("dsp32shiftimm: dregs_half = dregs_half << uimm4 (S)\n");
+                 $$ = DSP32SHIFTIMM (0x0, &$1, imm5 ($5), &$3, $6.s0, HL2 ($1, $3));
+               }
+             else
+               {
+                 notethat ("dsp32shiftimm: dregs_half = dregs_half << uimm4\n");
+                 $$ = DSP32SHIFTIMM (0x0, &$1, imm5 ($5), &$3, 2, HL2 ($1, $3));
+               }
            }
          else
            return yyerror ("Bad shift value");
@@ -4372,7 +4392,7 @@ binary (Expr_Op_Type op, Expr_Node *x, Expr_Node *y)
          break;
 
        default:
-         error ("%s:%d: Internal compiler error\n", __FILE__, __LINE__); 
+         error ("%s:%d: Internal assembler error\n", __FILE__, __LINE__);
        }
       return x;
     }
@@ -4418,7 +4438,7 @@ unary (Expr_Op_Type op, Expr_Node *x)
          x->value.i_value = ~x->value.i_value;
          break;
        default:
-         error ("%s:%d: Internal compiler error\n", __FILE__, __LINE__); 
+         error ("%s:%d: Internal assembler error\n", __FILE__, __LINE__);
        }
       return x;
     }
This page took 0.027326 seconds and 4 git commands to generate.