gas/
authorBernd Schmidt <bernds@codesourcery.com>
Tue, 11 Aug 2009 18:29:41 +0000 (18:29 +0000)
committerBernd Schmidt <bernds@codesourcery.com>
Tue, 11 Aug 2009 18:29:41 +0000 (18:29 +0000)
* config/bfin-parse.y (gen_multi_instr_1): New function.
(asm): Use it instead of bfin_gen_multi_instr.
(error): Add a format string when calling as_bad.
* config/bfin-defs.h (insn_regmask): Declare.
* config/tc-bfin.c (DREG_MASK, DREGH_MASK, DREGL_MASK, IREG_MASK): New
macros.
(decode_ProgCtrl_0, decode_LDSTpmod_0, decode_dagMODim_0,
decode_dagMODik_0, decode_dspLDST_0, decode_LDST_0, decode_LDSTiiFP_0,
decode_LDSTii_0, decode_dsp32mac_0, decode_dsp32mult_0,
decode_dsp32alu_0, decode_dsp32shift_0, decode_dsp32shitimm_0,
insn_regmask): New functions.
gas/testsuite/
* gas/bfin/parallel.s: Add more test cases.
* gas/bfin/parallel.d: Update accordingly.
* gas/bfin/resource_conflict.l: New test.
* gas/bfin/resource_conflict.s: New test.
* gas/bfin/bfin.exp: Add resource_conflict.

gas/ChangeLog
gas/config/bfin-defs.h
gas/config/bfin-parse.y
gas/config/tc-bfin.c
gas/testsuite/ChangeLog
gas/testsuite/gas/bfin/bfin.exp
gas/testsuite/gas/bfin/parallel.d
gas/testsuite/gas/bfin/parallel.s
gas/testsuite/gas/bfin/resource_conflict.l [new file with mode: 0644]
gas/testsuite/gas/bfin/resource_conflict.s [new file with mode: 0644]

index 33954c3..2ea810c 100644 (file)
@@ -1,3 +1,17 @@
+2009-08-11  Bernd Schmidt  <bernd.schmidt@analog.com>
+
+       * config/bfin-parse.y (gen_multi_instr_1): New function.
+       (asm): Use it instead of bfin_gen_multi_instr.
+       (error): Add a format string when calling as_bad.
+       * config/bfin-defs.h (insn_regmask): Declare.
+       * config/tc-bfin.c (DREG_MASK, DREGH_MASK, DREGL_MASK, IREG_MASK): New
+       macros.
+       (decode_ProgCtrl_0, decode_LDSTpmod_0, decode_dagMODim_0,
+       decode_dagMODik_0, decode_dspLDST_0, decode_LDST_0, decode_LDSTiiFP_0,
+       decode_LDSTii_0, decode_dsp32mac_0, decode_dsp32mult_0,
+       decode_dsp32alu_0, decode_dsp32shift_0, decode_dsp32shitimm_0,
+       insn_regmask): New functions.
+
 2009-08-11  Mike Frysinger  <vapier@gentoo.org>
 
        * config/bfin-parse.y (binary): Change "compiler" to "assembler".
index 2d96ab0..410c47b 100644 (file)
@@ -374,6 +374,7 @@ EXPR_T mkexpr (int, SYMBOL_T);
 /* Defined in bfin-lex.l.  */
 void set_start_state (void);
 
+extern int insn_regmask (int, int);
 #ifdef __cplusplus
 }
 #endif
index ef84a72..f64fc02 100644 (file)
@@ -385,6 +385,18 @@ 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");
+  return bfin_gen_multi_instr (dsp32, dsp16_grp1, dsp16_grp2);
+}
+
 %}
 
 %union {
@@ -608,27 +620,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 +653,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");
        }
index 271709e..8e47581 100644 (file)
@@ -1164,8 +1164,7 @@ Expr_Node_Gen_Reloc_R (Expr_Node * head)
     }
   return note;
 }
-
-
+\f
 /* Blackfin opcode generation.  */
 
 /* These functions are called by the generated parser
@@ -1964,3 +1963,743 @@ bfin_force_relocation (struct fix *fixp)
 
   return generic_force_reloc (fixp);
 }
+\f
+/* This is a stripped down version of the disassembler.  The only thing it
+   does is return a mask of registers modified by an instruction.  Only
+   instructions that can occur in a parallel-issue bundle are handled, and
+   only the registers that can cause a conflict are recorded.  */
+
+#define DREG_MASK(n) (0x101 << (n))
+#define DREGH_MASK(n) (0x100 << (n))
+#define DREGL_MASK(n) (0x001 << (n))
+#define IREG_MASK(n) (1 << ((n) + 16))
+
+static int
+decode_ProgCtrl_0 (int iw0)
+{
+  if (iw0 == 0)
+    return 0;
+  abort ();
+}
+
+static int
+decode_LDSTpmod_0 (int iw0)
+{
+  /* LDSTpmod
+     +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+     | 1 | 0 | 0 | 0 |.W.|.aop...|.reg.......|.idx.......|.ptr.......|
+     +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
+  int W   = ((iw0 >> LDSTpmod_W_bits) & LDSTpmod_W_mask);
+  int aop = ((iw0 >> LDSTpmod_aop_bits) & LDSTpmod_aop_mask);
+  int idx = ((iw0 >> LDSTpmod_idx_bits) & LDSTpmod_idx_mask);
+  int ptr = ((iw0 >> LDSTpmod_ptr_bits) & LDSTpmod_ptr_mask);
+  int reg = ((iw0 >> LDSTpmod_reg_bits) & LDSTpmod_reg_mask);
+
+  if (aop == 1 && W == 0 && idx == ptr)
+    return DREGL_MASK (reg);
+  else if (aop == 2 && W == 0 && idx == ptr)
+    return DREGH_MASK (reg);
+  else if (aop == 1 && W == 1 && idx == ptr)
+    return 0;
+  else if (aop == 2 && W == 1 && idx == ptr)
+    return 0;
+  else if (aop == 0 && W == 0)
+    return DREG_MASK (reg);
+  else if (aop == 1 && W == 0)
+    return DREGL_MASK (reg);
+  else if (aop == 2 && W == 0)
+    return DREGH_MASK (reg);
+  else if (aop == 3 && W == 0)
+    return DREG_MASK (reg);
+  else if (aop == 3 && W == 1)
+    return DREG_MASK (reg);
+  else if (aop == 0 && W == 1)
+    return 0;
+  else if (aop == 1 && W == 1)
+    return 0;
+  else if (aop == 2 && W == 1)
+    return 0;
+  else
+    return 0;
+
+  return 2;
+}
+
+static int
+decode_dagMODim_0 (int iw0)
+{
+  /* dagMODim
+     +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+     | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 0 |.br| 1 | 1 |.op|.m.....|.i.....|
+     +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
+  int i  = ((iw0 >> DagMODim_i_bits) & DagMODim_i_mask);
+  int op  = ((iw0 >> DagMODim_op_bits) & DagMODim_op_mask);
+
+  if (op == 0 || op == 1)
+    return IREG_MASK (i);
+  else
+    return 0;
+
+  return 2;
+}
+
+static int
+decode_dagMODik_0 (int iw0)
+{
+  /* dagMODik
+     +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+     | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 0 |.op....|.i.....|
+     +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
+  int i  = ((iw0 >> DagMODik_i_bits) & DagMODik_i_mask);
+  return IREG_MASK (i);
+}
+
+/* GOOD */
+static int
+decode_dspLDST_0 (int iw0)
+{
+  /* dspLDST
+     +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+     | 1 | 0 | 0 | 1 | 1 | 1 |.W.|.aop...|.m.....|.i.....|.reg.......|
+     +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
+  int i   = ((iw0 >> DspLDST_i_bits) & DspLDST_i_mask);
+  int m   = ((iw0 >> DspLDST_m_bits) & DspLDST_m_mask);
+  int W   = ((iw0 >> DspLDST_W_bits) & DspLDST_W_mask);
+  int aop = ((iw0 >> DspLDST_aop_bits) & DspLDST_aop_mask);
+  int reg = ((iw0 >> DspLDST_reg_bits) & DspLDST_reg_mask);
+
+  if (aop == 0 && W == 0 && m == 0)
+    return DREG_MASK (reg) | IREG_MASK (i);
+  else if (aop == 0 && W == 0 && m == 1)
+    return DREGL_MASK (reg) | IREG_MASK (i);
+  else if (aop == 0 && W == 0 && m == 2)
+    return DREGH_MASK (reg) | IREG_MASK (i);
+  else if (aop == 1 && W == 0 && m == 0)
+    return DREG_MASK (reg) | IREG_MASK (i);
+  else if (aop == 1 && W == 0 && m == 1)
+    return DREGL_MASK (reg) | IREG_MASK (i);
+  else if (aop == 1 && W == 0 && m == 2)
+    return DREGH_MASK (reg) | IREG_MASK (i);
+  else if (aop == 2 && W == 0 && m == 0)
+    return DREG_MASK (reg);
+  else if (aop == 2 && W == 0 && m == 1)
+    return DREGL_MASK (reg);
+  else if (aop == 2 && W == 0 && m == 2)
+    return DREGH_MASK (reg);
+  else if (aop == 0 && W == 1 && m == 0)
+    return IREG_MASK (i);
+  else if (aop == 0 && W == 1 && m == 1)
+    return IREG_MASK (i);
+  else if (aop == 0 && W == 1 && m == 2)
+    return IREG_MASK (i);
+  else if (aop == 1 && W == 1 && m == 0)
+    return IREG_MASK (i);
+  else if (aop == 1 && W == 1 && m == 1)
+    return IREG_MASK (i);
+  else if (aop == 1 && W == 1 && m == 2)
+    return IREG_MASK (i);
+  else if (aop == 2 && W == 1 && m == 0)
+    return 0;
+  else if (aop == 2 && W == 1 && m == 1)
+    return 0;
+  else if (aop == 2 && W == 1 && m == 2)
+    return 0;
+  else if (aop == 3 && W == 0)
+    return DREG_MASK (reg) | IREG_MASK (i);
+  else if (aop == 3 && W == 1)
+    return IREG_MASK (i);
+
+  abort ();
+}
+
+/* GOOD */
+static int
+decode_LDST_0 (int iw0)
+{
+  /* LDST
+     +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+     | 1 | 0 | 0 | 1 |.sz....|.W.|.aop...|.Z.|.ptr.......|.reg.......|
+     +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
+  int Z   = ((iw0 >> LDST_Z_bits) & LDST_Z_mask);
+  int W   = ((iw0 >> LDST_W_bits) & LDST_W_mask);
+  int sz  = ((iw0 >> LDST_sz_bits) & LDST_sz_mask);
+  int aop = ((iw0 >> LDST_aop_bits) & LDST_aop_mask);
+  int reg = ((iw0 >> LDST_reg_bits) & LDST_reg_mask);
+
+  if (aop == 0 && sz == 0 && Z == 0 && W == 0)
+    return DREG_MASK (reg);
+  else if (aop == 0 && sz == 0 && Z == 1 && W == 0)
+    return 0;
+  else if (aop == 0 && sz == 1 && Z == 0 && W == 0)
+    return DREG_MASK (reg);
+  else if (aop == 0 && sz == 1 && Z == 1 && W == 0)
+    return DREG_MASK (reg);
+  else if (aop == 0 && sz == 2 && Z == 0 && W == 0)
+    return DREG_MASK (reg);
+  else if (aop == 0 && sz == 2 && Z == 1 && W == 0)
+    return DREG_MASK (reg);
+  else if (aop == 1 && sz == 0 && Z == 0 && W == 0)
+    return DREG_MASK (reg);
+  else if (aop == 1 && sz == 0 && Z == 1 && W == 0)
+    return 0;
+  else if (aop == 1 && sz == 1 && Z == 0 && W == 0)
+    return DREG_MASK (reg);
+  else if (aop == 1 && sz == 1 && Z == 1 && W == 0)
+    return DREG_MASK (reg);
+  else if (aop == 1 && sz == 2 && Z == 0 && W == 0)
+    return DREG_MASK (reg);
+  else if (aop == 1 && sz == 2 && Z == 1 && W == 0)
+    return DREG_MASK (reg);
+  else if (aop == 2 && sz == 0 && Z == 0 && W == 0)
+    return DREG_MASK (reg);
+  else if (aop == 2 && sz == 0 && Z == 1 && W == 0)
+    return 0;
+  else if (aop == 2 && sz == 1 && Z == 0 && W == 0)
+    return DREG_MASK (reg);
+  else if (aop == 2 && sz == 1 && Z == 1 && W == 0)
+    return DREG_MASK (reg);
+  else if (aop == 2 && sz == 2 && Z == 0 && W == 0)
+    return DREG_MASK (reg);
+  else if (aop == 2 && sz == 2 && Z == 1 && W == 0)
+    return DREG_MASK (reg);
+  else if (aop == 0 && sz == 0 && Z == 0 && W == 1)
+    return 0;
+  else if (aop == 0 && sz == 0 && Z == 1 && W == 1)
+    return 0;
+  else if (aop == 0 && sz == 1 && Z == 0 && W == 1)
+    return 0;
+  else if (aop == 0 && sz == 2 && Z == 0 && W == 1)
+    return 0;
+  else if (aop == 1 && sz == 0 && Z == 0 && W == 1)
+    return 0;
+  else if (aop == 1 && sz == 0 && Z == 1 && W == 1)
+    return 0;
+  else if (aop == 1 && sz == 1 && Z == 0 && W == 1)
+    return 0;
+  else if (aop == 1 && sz == 2 && Z == 0 && W == 1)
+    return 0;
+  else if (aop == 2 && sz == 0 && Z == 0 && W == 1)
+    return 0;
+  else if (aop == 2 && sz == 0 && Z == 1 && W == 1)
+    return 0;
+  else if (aop == 2 && sz == 1 && Z == 0 && W == 1)
+    return 0;
+  else if (aop == 2 && sz == 2 && Z == 0 && W == 1)
+    return 0;
+
+  abort ();
+}
+
+static int
+decode_LDSTiiFP_0 (int iw0)
+{
+  /* LDSTiiFP
+     +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+     | 1 | 0 | 1 | 1 | 1 | 0 |.W.|.offset............|.reg...........|
+     +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
+  int reg = ((iw0 >> LDSTiiFP_reg_bits) & LDSTiiFP_reg_mask);
+  int W = ((iw0 >> LDSTiiFP_W_bits) & LDSTiiFP_W_mask);
+
+  if (W == 0)
+    return reg < 8 ? DREG_MASK (reg) : 0;
+  else
+    return 0;
+}
+
+static int
+decode_LDSTii_0 (int iw0)
+{
+  /* LDSTii
+     +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+     | 1 | 0 | 1 |.W.|.op....|.offset........|.ptr.......|.reg.......|
+     +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
+  int reg = ((iw0 >> LDSTii_reg_bit) & LDSTii_reg_mask);
+  int op = ((iw0 >> LDSTii_op_bit) & LDSTii_op_mask);
+  int W = ((iw0 >> LDSTii_W_bit) & LDSTii_W_mask);
+
+  if (W == 0 && op != 3)
+    return DREG_MASK (reg);
+  else if (W == 0 && op == 3)
+   return 0;
+  else if (W == 1 && op == 0)
+    return 0;
+  else if (W == 1 && op == 1)
+    return 0;
+  else if (W == 1 && op == 3)
+    return 0;
+
+  abort ();
+}
+
+static int
+decode_dsp32mac_0 (int iw0, int iw1)
+{
+  int result = 0;
+  /* dsp32mac
+     +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+     | 1 | 1 | 0 | 0 |.M.| 0 | 0 |.mmod..........|.MM|.P.|.w1|.op1...|
+     |.h01|.h11|.w0|.op0...|.h00|.h10|.dst.......|.src0......|.src1..|
+     +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
+  int op1  = ((iw0 >> (DSP32Mac_op1_bits - 16)) & DSP32Mac_op1_mask);
+  int w1   = ((iw0 >> (DSP32Mac_w1_bits - 16)) & DSP32Mac_w1_mask);
+  int P    = ((iw0 >> (DSP32Mac_p_bits - 16)) & DSP32Mac_p_mask);
+  int mmod = ((iw0 >> (DSP32Mac_mmod_bits - 16)) & DSP32Mac_mmod_mask);
+  int w0   = ((iw1 >> DSP32Mac_w0_bits) & DSP32Mac_w0_mask);
+  int MM   = ((iw1 >> DSP32Mac_MM_bits) & DSP32Mac_MM_mask);
+  int dst  = ((iw1 >> DSP32Mac_dst_bits) & DSP32Mac_dst_mask);
+  int op0  = ((iw1 >> DSP32Mac_op0_bits) & DSP32Mac_op0_mask);
+
+  if (w0 == 0 && w1 == 0 && op1 == 3 && op0 == 3)
+    return 0;
+
+  if (op1 == 3 && MM)
+    return 0;
+
+  if ((w1 || w0) && mmod == M_W32)
+    return 0;
+
+  if (((1 << mmod) & (P ? 0x131b : 0x1b5f)) == 0)
+    return 0;
+
+  if (w1 == 1 || op1 != 3)
+    {
+      if (w1)
+       {
+         if (P)
+           return DREG_MASK (dst + 1);
+         else
+           return DREGH_MASK (dst);
+       }
+    }
+
+  if (w0 == 1 || op0 != 3)
+    {
+      if (w0)
+       {
+         if (P)
+           return DREG_MASK (dst);
+         else
+           return DREGL_MASK (dst);
+       }
+    }
+
+  return result;
+}
+
+static int
+decode_dsp32mult_0 (int iw0, int iw1)
+{
+  /* dsp32mult
+     +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+     | 1 | 1 | 0 | 0 |.M.| 0 | 1 |.mmod..........|.MM|.P.|.w1|.op1...|
+     |.h01|.h11|.w0|.op0...|.h00|.h10|.dst.......|.src0......|.src1..|
+     +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
+  int w1   = ((iw0 >> (DSP32Mac_w1_bits - 16)) & DSP32Mac_w1_mask);
+  int P    = ((iw0 >> (DSP32Mac_p_bits - 16)) & DSP32Mac_p_mask);
+  int mmod = ((iw0 >> (DSP32Mac_mmod_bits - 16)) & DSP32Mac_mmod_mask);
+  int w0   = ((iw1 >> DSP32Mac_w0_bits) & DSP32Mac_w0_mask);
+  int dst  = ((iw1 >> DSP32Mac_dst_bits) & DSP32Mac_dst_mask);
+  int result = 0;
+
+  if (w1 == 0 && w0 == 0)
+    return 0;
+
+  if (((1 << mmod) & (P ? 0x313 : 0x1b57)) == 0)
+    return 0;
+
+  if (w1)
+    {
+      if (P)
+       return DREG_MASK (dst | 1);
+      else
+       return DREGH_MASK (dst);
+    }
+
+  if (w0)
+    {
+      if (P)
+       return DREG_MASK (dst);
+      else
+       return DREGL_MASK (dst);
+    }
+
+  return result;
+}
+
+static int
+decode_dsp32alu_0 (int iw0, int iw1)
+{
+  /* dsp32alu
+     +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+     | 1 | 1 | 0 | 0 |.M.| 1 | 0 | - | - | - |.HL|.aopcde............|
+     |.aop...|.s.|.x.|.dst0......|.dst1......|.src0......|.src1......|
+     +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
+  int s    = ((iw1 >> DSP32Alu_s_bits) & DSP32Alu_s_mask);
+  int x    = ((iw1 >> DSP32Alu_x_bits) & DSP32Alu_x_mask);
+  int aop  = ((iw1 >> DSP32Alu_aop_bits) & DSP32Alu_aop_mask);
+  int dst0 = ((iw1 >> DSP32Alu_dst0_bits) & DSP32Alu_dst0_mask);
+  int dst1 = ((iw1 >> DSP32Alu_dst1_bits) & DSP32Alu_dst1_mask);
+  int HL   = ((iw0 >> (DSP32Alu_HL_bits - 16)) & DSP32Alu_HL_mask);
+  int aopcde = ((iw0 >> (DSP32Alu_aopcde_bits - 16)) & DSP32Alu_aopcde_mask);
+
+  if (aop == 0 && aopcde == 9 && s == 0)
+    return 0;
+  else if (aop == 2 && aopcde == 9 && HL == 0 && s == 0)
+    return 0;
+  else if (aop >= x * 2 && aopcde == 5)
+    return HL ? DREGH_MASK (dst0) : DREGL_MASK (dst0);
+  else if (HL == 0 && aopcde == 2)
+    return DREGL_MASK (dst0);
+  else if (HL == 1 && aopcde == 2)
+    return DREGH_MASK (dst0);
+  else if (HL == 0 && aopcde == 3)
+    return DREGL_MASK (dst0);
+  else if (HL == 1 && aopcde == 3)
+    return DREGH_MASK (dst0);
+
+  else if (aop == 0 && aopcde == 9 && s == 1)
+    return 0;
+  else if (aop == 1 && aopcde == 9 && s == 0)
+    return 0;
+  else if (aop == 2 && aopcde == 9 && s == 1)
+    return 0;
+  else if (aop == 3 && aopcde == 9 && s == 0)
+    return 0;
+  else if (aopcde == 8)
+    return 0;
+  else if (aop == 0 && aopcde == 11)
+    return DREG_MASK (dst0);
+  else if (aop == 1 && aopcde == 11)
+    return HL ? DREGH_MASK (dst0) : DREGL_MASK (dst0);
+  else if (aopcde == 11)
+    return 0;
+  else if (aopcde == 22)
+    return DREG_MASK (dst0);
+
+  else if ((aop == 0 || aop == 1) && aopcde == 14)
+    return 0;
+  else if (aop == 3 && HL == 0 && aopcde == 14)
+    return 0;
+
+  else if (aop == 3 && HL == 0 && aopcde == 15)
+    return DREG_MASK (dst0);
+
+  else if (aop == 1 && aopcde == 16)
+    return 0;
+
+  else if (aop == 0 && aopcde == 16)
+    return 0;
+
+  else if (aop == 3 && HL == 0 && aopcde == 16)
+    return 0;
+
+  else if (aop == 3 && HL == 0 && aopcde == 7)
+    return DREG_MASK (dst0);
+  else if ((aop == 0 || aop == 1 || aop == 2) && aopcde == 7)
+    return DREG_MASK (dst0);
+
+  else if (aop == 0 && aopcde == 12)
+    return DREG_MASK (dst0);
+  else if (aop == 1 && aopcde == 12)
+    return DREG_MASK (dst0) | DREG_MASK (dst1);
+  else if (aop == 3 && aopcde == 12)
+    return HL ? DREGH_MASK (dst0) : DREGL_MASK (dst0);
+
+  else if (aopcde == 0)
+    return DREG_MASK (dst0);
+  else if (aopcde == 1)
+    return DREG_MASK (dst0) | DREG_MASK (dst1);
+
+  else if (aop == 0 && aopcde == 10)
+    return DREGL_MASK (dst0);
+  else if (aop == 1 && aopcde == 10)
+    return DREGL_MASK (dst0);
+
+  else if ((aop == 1 || aop == 0) && aopcde == 4)
+    return DREG_MASK (dst0);
+  else if (aop == 2 && aopcde == 4)
+    return DREG_MASK (dst0) | DREG_MASK (dst1);
+
+  else if (aop == 0 && aopcde == 17)
+    return DREG_MASK (dst0) | DREG_MASK (dst1);
+  else if (aop == 1 && aopcde == 17)
+    return DREG_MASK (dst0) | DREG_MASK (dst1);
+  else if (aop == 0 && aopcde == 18)
+    return 0;
+  else if (aop == 3 && aopcde == 18)
+    return 0;
+
+  else if ((aop == 0 || aop == 1 || aop == 2) && aopcde == 6)
+    return DREG_MASK (dst0);
+
+  else if ((aop == 0 || aop == 1) && aopcde == 20)
+    return DREG_MASK (dst0);
+
+  else if ((aop == 0 || aop == 1) && aopcde == 21)
+    return DREG_MASK (dst0) | DREG_MASK (dst1);
+
+  else if (aop == 0 && aopcde == 23 && HL == 1)
+    return DREG_MASK (dst0);
+  else if (aop == 0 && aopcde == 23 && HL == 0)
+    return DREG_MASK (dst0);
+
+  else if (aop == 0 && aopcde == 24)
+    return DREG_MASK (dst0);
+  else if (aop == 1 && aopcde == 24) 
+    return DREG_MASK (dst0) | DREG_MASK (dst1);
+  else if (aopcde == 13)
+    return DREG_MASK (dst0) | DREG_MASK (dst1);
+  else
+    return 0;
+
+  return 4;
+}
+
+static int
+decode_dsp32shift_0 (int iw0, int iw1)
+{
+  /* dsp32shift
+     +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+     | 1 | 1 | 0 | 0 |.M.| 1 | 1 | 0 | 0 | - | - |.sopcde............|
+     |.sop...|.HLs...|.dst0......| - | - | - |.src0......|.src1......|
+     +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
+  int HLs  = ((iw1 >> DSP32Shift_HLs_bits) & DSP32Shift_HLs_mask);
+  int sop  = ((iw1 >> DSP32Shift_sop_bits) & DSP32Shift_sop_mask);
+  int src0 = ((iw1 >> DSP32Shift_src0_bits) & DSP32Shift_src0_mask);
+  int src1 = ((iw1 >> DSP32Shift_src1_bits) & DSP32Shift_src1_mask);
+  int dst0 = ((iw1 >> DSP32Shift_dst0_bits) & DSP32Shift_dst0_mask);
+  int sopcde = ((iw0 >> (DSP32Shift_sopcde_bits - 16)) & DSP32Shift_sopcde_mask);
+
+  if (sop == 0 && sopcde == 0)
+    return HLs & 2 ? DREGH_MASK (dst0) : DREGL_MASK (dst0);
+  else if (sop == 1 && sopcde == 0)
+    return HLs & 2 ? DREGH_MASK (dst0) : DREGL_MASK (dst0);
+  else if (sop == 2 && sopcde == 0)
+    return HLs & 2 ? DREGH_MASK (dst0) : DREGL_MASK (dst0);
+  else if (sop == 0 && sopcde == 3)
+    return 0;
+  else if (sop == 1 && sopcde == 3)
+    return 0;
+  else if (sop == 2 && sopcde == 3)
+    return 0;
+  else if (sop == 3 && sopcde == 3)
+    return DREG_MASK (dst0);
+  else if (sop == 0 && sopcde == 1)
+    return DREG_MASK (dst0);
+  else if (sop == 1 && sopcde == 1)
+    return DREG_MASK (dst0);
+  else if (sop == 2 && sopcde == 1)
+    return DREG_MASK (dst0);
+  else if (sopcde == 2)
+    return DREG_MASK (dst0);
+  else if (sopcde == 4)
+    return DREG_MASK (dst0);
+  else if (sop == 0 && sopcde == 5)
+    return DREGL_MASK (dst0);
+  else if (sop == 1 && sopcde == 5)
+    return DREGL_MASK (dst0);
+  else if (sop == 2 && sopcde == 5)
+    return DREGL_MASK (dst0);
+  else if (sop == 0 && sopcde == 6)
+    return DREGL_MASK (dst0);
+  else if (sop == 1 && sopcde == 6)
+    return DREGL_MASK (dst0);
+  else if (sop == 3 && sopcde == 6)
+    return DREGL_MASK (dst0);
+  else if (sop == 0 && sopcde == 7)
+    return DREGL_MASK (dst0);
+  else if (sop == 1 && sopcde == 7)
+    return DREGL_MASK (dst0);
+  else if (sop == 2 && sopcde == 7)
+    return DREGL_MASK (dst0);
+  else if (sop == 3 && sopcde == 7)
+    return DREGL_MASK (dst0);
+  else if (sop == 0 && sopcde == 8)
+    return DREG_MASK (src0) | DREG_MASK (src1);
+#if 0
+    {
+      OUTS (outf, "BITMUX (");
+      OUTS (outf, dregs (src0));
+      OUTS (outf, ", ");
+      OUTS (outf, dregs (src1));
+      OUTS (outf, ", A0) (ASR)");
+    }
+#endif
+  else if (sop == 1 && sopcde == 8)
+    return DREG_MASK (src0) | DREG_MASK (src1);
+#if 0
+    {
+      OUTS (outf, "BITMUX (");
+      OUTS (outf, dregs (src0));
+      OUTS (outf, ", ");
+      OUTS (outf, dregs (src1));
+      OUTS (outf, ", A0) (ASL)");
+    }
+#endif
+  else if (sopcde == 9)
+    return sop < 2 ? DREGL_MASK (dst0) : DREG_MASK (dst0);
+  else if (sopcde == 10)
+    return DREG_MASK (dst0);
+  else if (sop == 0 && sopcde == 11)
+    return DREGL_MASK (dst0);
+  else if (sop == 1 && sopcde == 11)
+    return DREGL_MASK (dst0);
+  else if (sop == 0 && sopcde == 12)
+    return 0;
+  else if (sop == 1 && sopcde == 12)
+    return DREGL_MASK (dst0);
+  else if (sop == 0 && sopcde == 13)
+    return DREG_MASK (dst0);
+  else if (sop == 1 && sopcde == 13)
+    return DREG_MASK (dst0);
+  else if (sop == 2 && sopcde == 13)
+    return DREG_MASK (dst0);
+
+  abort ();
+}
+
+static int
+decode_dsp32shiftimm_0 (int iw0, int iw1)
+{
+  /* dsp32shiftimm
+     +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
+     | 1 | 1 | 0 | 0 |.M.| 1 | 1 | 0 | 1 | - | - |.sopcde............|
+     |.sop...|.HLs...|.dst0......|.immag.................|.src1......|
+     +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
+  int sop      = ((iw1 >> DSP32ShiftImm_sop_bits) & DSP32ShiftImm_sop_mask);
+  int bit8     = ((iw1 >> 8) & 0x1);
+  int dst0     = ((iw1 >> DSP32ShiftImm_dst0_bits) & DSP32ShiftImm_dst0_mask);
+  int sopcde   = ((iw0 >> (DSP32ShiftImm_sopcde_bits - 16)) & DSP32ShiftImm_sopcde_mask);
+  int HLs      = ((iw1 >> DSP32ShiftImm_HLs_bits) & DSP32ShiftImm_HLs_mask);
+
+
+  if (sop == 0 && sopcde == 0)
+    return HLs & 2 ? DREGH_MASK (dst0) : DREGL_MASK (dst0);
+  else if (sop == 1 && sopcde == 0 && bit8 == 0)
+    return HLs & 2 ? DREGH_MASK (dst0) : DREGL_MASK (dst0);
+  else if (sop == 1 && sopcde == 0 && bit8 == 1)
+    return HLs & 2 ? DREGH_MASK (dst0) : DREGL_MASK (dst0);
+  else if (sop == 2 && sopcde == 0 && bit8 == 0)
+    return HLs & 2 ? DREGH_MASK (dst0) : DREGL_MASK (dst0);
+  else if (sop == 2 && sopcde == 0 && bit8 == 1)
+    return HLs & 2 ? DREGH_MASK (dst0) : DREGL_MASK (dst0);
+  else if (sop == 2 && sopcde == 3 && HLs == 1)
+    return 0;
+  else if (sop == 0 && sopcde == 3 && HLs == 0 && bit8 == 0)
+    return 0;
+  else if (sop == 0 && sopcde == 3 && HLs == 0 && bit8 == 1)
+    return 0;
+  else if (sop == 0 && sopcde == 3 && HLs == 1 && bit8 == 0)
+    return 0;
+  else if (sop == 0 && sopcde == 3 && HLs == 1 && bit8 == 1)
+    return 0;
+  else if (sop == 1 && sopcde == 3 && HLs == 0)
+    return 0;
+  else if (sop == 1 && sopcde == 3 && HLs == 1)
+    return 0;
+  else if (sop == 2 && sopcde == 3 && HLs == 0)
+    return 0;
+  else if (sop == 1 && sopcde == 1 && bit8 == 0)
+    return DREG_MASK (dst0);
+  else if (sop == 1 && sopcde == 1 && bit8 == 1)
+    return DREG_MASK (dst0);
+  else if (sop == 2 && sopcde == 1 && bit8 == 1)
+    return DREG_MASK (dst0);
+  else if (sop == 2 && sopcde == 1 && bit8 == 0)
+    return DREG_MASK (dst0);
+  else if (sop == 0 && sopcde == 1)
+    return DREG_MASK (dst0);
+  else if (sop == 1 && sopcde == 2)
+    return DREG_MASK (dst0);
+  else if (sop == 2 && sopcde == 2 && bit8 == 1)
+    return DREG_MASK (dst0);
+  else if (sop == 2 && sopcde == 2 && bit8 == 0)
+    return DREG_MASK (dst0);
+  else if (sop == 3 && sopcde == 2)
+    return DREG_MASK (dst0);
+  else if (sop == 0 && sopcde == 2)
+    return DREG_MASK (dst0);
+
+  abort ();
+}
+
+int
+insn_regmask (int iw0, int iw1)
+{
+  if ((iw0 & 0xf7ff) == 0xc003 && iw1 == 0x1800)
+    return 0; /* MNOP */
+  else if ((iw0 & 0xff00) == 0x0000)
+    return decode_ProgCtrl_0 (iw0);
+  else if ((iw0 & 0xffc0) == 0x0240)
+    abort ();
+  else if ((iw0 & 0xff80) == 0x0100)
+    abort ();
+  else if ((iw0 & 0xfe00) == 0x0400)
+    abort ();
+  else if ((iw0 & 0xfe00) == 0x0600)
+    abort ();
+  else if ((iw0 & 0xf800) == 0x0800)
+    abort ();
+  else if ((iw0 & 0xffe0) == 0x0200)
+    abort ();
+  else if ((iw0 & 0xff00) == 0x0300)
+    abort ();
+  else if ((iw0 & 0xf000) == 0x1000)
+    abort ();
+  else if ((iw0 & 0xf000) == 0x2000)
+    abort ();
+  else if ((iw0 & 0xf000) == 0x3000)
+    abort ();
+  else if ((iw0 & 0xfc00) == 0x4000)
+    abort ();
+  else if ((iw0 & 0xfe00) == 0x4400)
+    abort ();
+  else if ((iw0 & 0xf800) == 0x4800)
+    abort ();
+  else if ((iw0 & 0xf000) == 0x5000)
+    abort ();
+  else if ((iw0 & 0xf800) == 0x6000)
+    abort ();
+  else if ((iw0 & 0xf800) == 0x6800)
+    abort ();
+  else if ((iw0 & 0xf000) == 0x8000)
+    return decode_LDSTpmod_0 (iw0);
+  else if ((iw0 & 0xff60) == 0x9e60)
+    return decode_dagMODim_0 (iw0);
+  else if ((iw0 & 0xfff0) == 0x9f60)
+    return decode_dagMODik_0 (iw0);
+  else if ((iw0 & 0xfc00) == 0x9c00)
+    return decode_dspLDST_0 (iw0);
+  else if ((iw0 & 0xf000) == 0x9000)
+    return decode_LDST_0 (iw0);
+  else if ((iw0 & 0xfc00) == 0xb800)
+    return decode_LDSTiiFP_0 (iw0);
+  else if ((iw0 & 0xe000) == 0xA000)
+    return decode_LDSTii_0 (iw0);
+  else if ((iw0 & 0xff80) == 0xe080 && (iw1 & 0x0C00) == 0x0000)
+    abort ();
+  else if ((iw0 & 0xff00) == 0xe100 && (iw1 & 0x0000) == 0x0000)
+    abort ();
+  else if ((iw0 & 0xfe00) == 0xe200 && (iw1 & 0x0000) == 0x0000)
+    abort ();
+  else if ((iw0 & 0xfc00) == 0xe400 && (iw1 & 0x0000) == 0x0000)
+    abort ();
+  else if ((iw0 & 0xfffe) == 0xe800 && (iw1 & 0x0000) == 0x0000)
+    abort ();
+  else if ((iw0 & 0xf600) == 0xc000 && (iw1 & 0x0000) == 0x0000)
+    return decode_dsp32mac_0 (iw0, iw1);
+  else if ((iw0 & 0xf600) == 0xc200 && (iw1 & 0x0000) == 0x0000)
+    return decode_dsp32mult_0 (iw0, iw1);
+  else if ((iw0 & 0xf7c0) == 0xc400 && (iw1 & 0x0000) == 0x0000)
+    return decode_dsp32alu_0 (iw0, iw1);
+  else if ((iw0 & 0xf780) == 0xc600 && (iw1 & 0x01c0) == 0x0000)
+    return decode_dsp32shift_0 (iw0, iw1);
+  else if ((iw0 & 0xf780) == 0xc680 && (iw1 & 0x0000) == 0x0000)
+    return decode_dsp32shiftimm_0 (iw0, iw1);
+  else if ((iw0 & 0xff00) == 0xf800)
+    abort ();
+  else if ((iw0 & 0xFFC0) == 0xf000 && (iw1 & 0x0000) == 0x0000)
+    abort ();
+
+  abort ();
+}
index ea96952..6b6d75a 100644 (file)
@@ -1,3 +1,11 @@
+2006-08-11  Bernd Schmidt  <bernd.schmidt@analog.com>
+
+       * gas/bfin/parallel.s: Add more test cases.
+       * gas/bfin/parallel.d: Update accordingly.
+       * gas/bfin/resource_conflict.l: New test.
+       * gas/bfin/resource_conflict.s: New test.
+       * gas/bfin/bfin.exp: Add resource_conflict.
+
 2009-08-11  Nick Clifton  <nickc@redhat.com>
 
        PR 10443
index 4a8643a..58d33b5 100644 (file)
@@ -28,6 +28,7 @@ if [istarget bfin*-*-*] {
        run_dump_test "parallel3"
        run_dump_test "parallel4"
        run_dump_test "reloc"
+       run_list_test "resource_conflict" ""
        run_dump_test "shift"
        run_dump_test "shift2"
        run_dump_test "stack"
index b5fec71..06b8a6e 100644 (file)
@@ -223,4 +223,17 @@ Disassembly of section .text:
  35c:  55 94 12 9f 
  360:  07 cc 10 84     R2 = ABS R2 \|\| R1 = \[I0\+\+\] \|\| NOP;
  364:  01 9c 00 00 
-
+ 368:  03 c8 00 18     MNOP \|\| P0 = \[FP \+ 0x14\] \|\| R0 = \[I2\+\+\];
+ 36c:  78 ad 10 9c 
+ 370:  0a cc 00 08     R4.L = A0.X \|\| R6 = \[FP \+ 0x3c\] \|\| R4.H = W\[I1\+\+\];
+ 374:  fe a3 4c 9c 
+ 378:  0a cc 00 08     R4.L = A0.X \|\| R4.H = W\[I1\+\+\] \|\| W\[I0\] = R4.H;
+ 37c:  4c 9c 44 9f 
+ 380:  0a cc 00 08     R4.L = A0.X \|\| W\[I1\+\+\] = R4.L \|\| R4.H = W\[I0--\];
+ 384:  2c 9e c4 9c 
+ 388:  0a cc 00 48     R4.L = A1.X \|\| R6 = B\[SP--\] \(Z\) \|\| R4.H = W\[I1\+\+\];
+ 38c:  b6 98 4c 9c 
+ 390:  0b cc 00 a0     A0 \+= A1 \(W32\) \|\| R3.L = W\[I0\] \|\| R0 = \[I0 \+\+ M3\];
+ 394:  23 9d e0 9d 
+ 398:  0b cc 00 c0     A0 -= A1 \|\| R0 = W\[P0\+\+\] \(X\) \|\| W\[I0\+\+\] = R3.L;
+ 39c:  40 94 23 9e 
index 1735223..36f1157 100644 (file)
        r0.H = r3.l - r3.h (NS) || r5 = w [p2++] (x) || [i2] = r2;
 
        R1 = [I0++] || R2 = ABS R2 || NOP;
+
+       P0 = [FP+20] || R0 = [I2++];
+
+       R4.L = A0.x || R6 = [FP + 60] || R4.H = W[I1++] ;
+       R4.L = A0.x || R4.H = W[I1++] || W[I0] = R4.H ;
+       R4.L = A0.x || W[I1++] = R4.L || R4.H = W[I0--] ;
+       R4.L = A1.x || R6 = B[SP--] (Z) || R4.H = W[I1++] ;
+       A0 += A1 (W32) || R3.L = W[I0] || R0 = [I0++ M3] ;
+       A0 -= A1 || R0 = W[P0++] (X) || W[I0++] = R3.L ;
+       
diff --git a/gas/testsuite/gas/bfin/resource_conflict.l b/gas/testsuite/gas/bfin/resource_conflict.l
new file mode 100644 (file)
index 0000000..af01fda
--- /dev/null
@@ -0,0 +1,11 @@
+.*: Assembler messages:
+.*:3: Error: resource conflict in multi-issue instruction.
+.*:4: Error: resource conflict in multi-issue instruction.
+.*:5: Error: resource conflict in multi-issue instruction.
+.*:6: Error: resource conflict in multi-issue instruction.
+.*:7: Error: resource conflict in multi-issue instruction.
+.*:8: Error: resource conflict in multi-issue instruction.
+.*:10: Error: resource conflict in multi-issue instruction.
+.*:11: Error: resource conflict in multi-issue instruction.
+.*:12: Error: resource conflict in multi-issue instruction.
+.*:13: Error: resource conflict in multi-issue instruction.
diff --git a/gas/testsuite/gas/bfin/resource_conflict.s b/gas/testsuite/gas/bfin/resource_conflict.s
new file mode 100644 (file)
index 0000000..714cd73
--- /dev/null
@@ -0,0 +1,14 @@
+       .text
+
+       r6 = r1.h * r2.l || r6 = [p0 ++];
+       r6 = [p0++] || r6 = [i0];
+       r0 = [i0++] || r1 = [i0--];
+       r6.h = ashift r0.h by r1.l || r6 = [i0 ++ m0];
+       r6.h = ashift r0.h by r1.l || r6.h = W [p0];
+       r6.l = (a0 = r1.l * r2.l) || r6 = [i0--];
+
+       R0 = (A0 += A1) || R0.L = W [I0++];
+       R0 = (A0 += A1) || R0.H = W [I0++];
+       R0.h = (A0 += A1) || R0.H = W [I0++];
+       R0.l = (A0 += A1) || R0.L = W [I0++];
+