* config/bfin-parse.y (check_macfunc_option): Fix instruction
authorJie Zhang <jie.zhang@analog.com>
Tue, 26 Aug 2008 10:03:24 +0000 (10:03 +0000)
committerJie Zhang <jie.zhang@analog.com>
Tue, 26 Aug 2008 10:03:24 +0000 (10:03 +0000)
mode checking.
(asm_1): Check mode for 16-bit multiply instructions.

testsuite/
* gas/bfin/arith_mode.d: New test.
* gas/bfin/arith_mode.s: New test.
* gas/bfin/invalid_arith_mode.l: New test.
* gas/bfin/invalid_arith_mode.s: New test.
* gas/bfin/bfin.exp: Add arith_mode and invalid_arith_mode.

gas/ChangeLog
gas/config/bfin-parse.y
gas/testsuite/ChangeLog
gas/testsuite/gas/bfin/arith_mode.d [new file with mode: 0644]
gas/testsuite/gas/bfin/arith_mode.s [new file with mode: 0644]
gas/testsuite/gas/bfin/bfin.exp
gas/testsuite/gas/bfin/invalid_arith_mode.l [new file with mode: 0644]
gas/testsuite/gas/bfin/invalid_arith_mode.s [new file with mode: 0644]

index 140d293bdc7ea3a0dfd5fa1a940c3c40e734ed85..ca0e411c3599b5e068f99a427eb42300b2795f47 100644 (file)
@@ -1,3 +1,9 @@
+2008-08-26  Jie Zhang  <jie.zhang@analog.com>
+
+       * config/bfin-parse.y (check_macfunc_option): Fix instruction
+       mode checking.
+       (asm_1): Check mode for 16-bit multiply instructions.
+
 2008-08-24  Alan Modra  <amodra@bigpond.net.au>
 
        * configure.in: Update a number of obsolete autoconf macros.
index 0110482705f9c3ddc443695300d6cec6df706e59..283b8130fc3003da2ed115aa30936132a89becd0 100644 (file)
@@ -273,21 +273,15 @@ check_macfunc_option (Macfunc *a, Opt_mode *opt)
   if (opt->mod == 0)
     return 0;
 
-  if ((a->op == 3 && a->w == 1 && a->P == 1
-       && opt->mod != M_FU && opt->mod != M_S2RND && opt->mod != M_ISS2)
-      || (a->op == 3 && a->w == 1 && a->P == 0
-         && opt->mod != M_FU && opt->mod != M_IS && opt->mod != M_IU
-         && opt->mod != M_T && opt->mod != M_S2RND && opt->mod != M_ISS2
-         && opt->mod != M_IH)
-      || (a->w == 0 && a->P == 0
-         && opt->mod != M_FU && opt->mod != M_IS && opt->mod != M_W32)
-      || (a->w == 1 && a->P == 1
-         && opt->mod != M_FU && opt->mod != M_IS && opt->mod != M_S2RND
-         && opt->mod != M_ISS2 && opt->mod != M_IU)
+  if ((a->w == 1 && a->P == 1
+       && opt->mod != M_FU && opt->mod != M_IS && opt->mod != M_IU
+       && opt->mod != M_S2RND && opt->mod != M_ISS2)
       || (a->w == 1 && a->P == 0
          && opt->mod != M_FU && opt->mod != M_IS && opt->mod != M_IU
          && opt->mod != M_T && opt->mod != M_TFU && opt->mod != M_S2RND
-         && opt->mod != M_ISS2 && opt->mod != M_IH))
+         && opt->mod != M_ISS2 && opt->mod != M_IH)
+      || (a->w == 0 && a->P == 0
+         && opt->mod != M_FU && opt->mod != M_IS && opt->mod != M_W32))
     return -1;
 
   return 0;
@@ -1756,6 +1750,11 @@ asm_1:
          if (!IS_H ($1) && $4.MM)
            return yyerror ("(M) not allowed with MAC0");
 
+         if ($4.mod != 0 && $4.mod != M_FU && $4.mod != M_IS
+             && $4.mod != M_IU && $4.mod != M_T && $4.mod != M_TFU
+             && $4.mod != M_S2RND && $4.mod != M_ISS2 && $4.mod != M_IH)
+           return yyerror ("bad option.");
+
          if (IS_H ($1))
            {
              $$ = DSP32MULT (0, $4.MM, $4.mod, 1, 0,
@@ -1779,6 +1778,10 @@ asm_1:
          if (IS_EVEN ($1) && $4.MM)
            return yyerror ("(M) not allowed with MAC0");
 
+         if ($4.mod != 0 && $4.mod != M_FU && $4.mod != M_IS
+             && $4.mod != M_S2RND && $4.mod != M_ISS2)
+           return yyerror ("bad option");
+
          if (!IS_EVEN ($1))
            {
              notethat ("dsp32mult: dregs = multiply_halfregs (opt_mode)\n");
index 633a4b473242cde7f725eefd4da5cb0bfde41bb2..1b0b40f173110462e2cb41b1cf830283a0fcfbfb 100644 (file)
@@ -1,3 +1,11 @@
+2008-08-26  Jie Zhang  <jie.zhang@analog.com>
+
+       * gas/bfin/arith_mode.d: New test.
+       * gas/bfin/arith_mode.s: New test.
+       * gas/bfin/invalid_arith_mode.l: New test.
+       * gas/bfin/invalid_arith_mode.s: New test.
+       * gas/bfin/bfin.exp: Add arith_mode and invalid_arith_mode.
+
 2008-08-22  Jie Zhang  <jie.zhang@analog.com>
 
        * gas/bfin/misc.s: New test.
diff --git a/gas/testsuite/gas/bfin/arith_mode.d b/gas/testsuite/gas/bfin/arith_mode.d
new file mode 100644 (file)
index 0000000..4c50de8
--- /dev/null
@@ -0,0 +1,56 @@
+#objdump: -dr
+#name: arith_mode
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+00000000 <.text>:
+   0:  03 c0 00 38     R0.L = A0;
+   4:  83 c0 00 38     R0.L = A0 \(FU\);
+   8:  03 c1 00 38     R0.L = A0 \(IS\);
+   c:  83 c1 00 38     R0.L = A0 \(IU\);
+  10:  43 c0 00 38     R0.L = A0 \(T\);
+  14:  c3 c0 00 38     R0.L = A0 \(TFU\);
+  18:  23 c0 00 38     R0.L = A0 \(S2RND\);
+  1c:  23 c1 00 38     R0.L = A0 \(ISS2\);
+  20:  63 c1 00 38     R0.L = A0 \(IH\);
+  24:  0b c0 00 38     R0 = A0;
+  28:  8b c0 00 38     R0 = A0 \(FU\);
+  2c:  0b c1 00 38     R0 = A0 \(IS\);
+  30:  8b c1 00 38     R0 = A0 \(IU\);
+  34:  2b c0 00 38     R0 = A0 \(S2RND\);
+  38:  2b c1 00 38     R0 = A0 \(ISS2\);
+  3c:  04 c2 0a 40     R0.H = R1.L \* R2.H;
+  40:  84 c2 0a 40     R0.H = R1.L \* R2.H \(FU\);
+  44:  04 c3 0a 40     R0.H = R1.L \* R2.H \(IS\);
+  48:  84 c3 0a 40     R0.H = R1.L \* R2.H \(IU\);
+  4c:  44 c2 0a 40     R0.H = R1.L \* R2.H \(T\);
+  50:  c4 c2 0a 40     R0.H = R1.L \* R2.H \(TFU\);
+  54:  24 c2 0a 40     R0.H = R1.L \* R2.H \(S2RND\);
+  58:  24 c3 0a 40     R0.H = R1.L \* R2.H \(ISS2\);
+  5c:  64 c3 0a 40     R0.H = R1.L \* R2.H \(IH\);
+  60:  08 c2 0a 22     R0 = R1.L \* R2.H;
+  64:  88 c2 0a 22     R0 = R1.L \* R2.H \(FU\);
+  68:  08 c3 0a 22     R0 = R1.L \* R2.H \(IS\);
+  6c:  28 c2 0a 22     R0 = R1.L \* R2.H \(S2RND\);
+  70:  28 c3 0a 22     R0 = R1.L \* R2.H \(ISS2\);
+  74:  03 c0 0a 02     A0 = R1.L \* R2.H;
+  78:  83 c0 0a 02     A0 = R1.L \* R2.H \(FU\);
+  7c:  03 c1 0a 02     A0 = R1.L \* R2.H \(IS\);
+  80:  63 c0 0a 02     A0 = R1.L \* R2.H \(W32\);
+  84:  03 c0 0a 22     R0.L = \(A0 = R1.L \* R2.H\);
+  88:  83 c0 0a 22     R0.L = \(A0 = R1.L \* R2.H\) \(FU\);
+  8c:  03 c1 0a 22     R0.L = \(A0 = R1.L \* R2.H\) \(IS\);
+  90:  83 c1 0a 22     R0.L = \(A0 = R1.L \* R2.H\) \(IU\);
+  94:  43 c0 0a 22     R0.L = \(A0 = R1.L \* R2.H\) \(T\);
+  98:  c3 c0 0a 22     R0.L = \(A0 = R1.L \* R2.H\) \(TFU\);
+  9c:  23 c0 0a 22     R0.L = \(A0 = R1.L \* R2.H\) \(S2RND\);
+  a0:  23 c1 0a 22     R0.L = \(A0 = R1.L \* R2.H\) \(ISS2\);
+  a4:  63 c1 0a 22     R0.L = \(A0 = R1.L \* R2.H\) \(IH\);
+  a8:  0b c0 0a 22     R0 = \(A0 = R1.L \* R2.H\);
+  ac:  8b c0 0a 22     R0 = \(A0 = R1.L \* R2.H\) \(FU\);
+  b0:  0b c1 0a 22     R0 = \(A0 = R1.L \* R2.H\) \(IS\);
+  b4:  8b c1 0a 22     R0 = \(A0 = R1.L \* R2.H\) \(IU\);
+  b8:  2b c0 0a 22     R0 = \(A0 = R1.L \* R2.H\) \(S2RND\);
+  bc:  2b c1 0a 22     R0 = \(A0 = R1.L \* R2.H\) \(ISS2\);
diff --git a/gas/testsuite/gas/bfin/arith_mode.s b/gas/testsuite/gas/bfin/arith_mode.s
new file mode 100644 (file)
index 0000000..c686eaf
--- /dev/null
@@ -0,0 +1,72 @@
+       .text
+
+       // Accumulator to Half D-register Moves
+
+       R0.L = A0;
+       R0.L = A0 (FU);
+       R0.L = A0 (IS);
+       R0.L = A0 (IU);
+       R0.L = A0 (T);
+       R0.L = A0 (TFU); // Not documented
+       R0.L = A0 (S2RND);
+       R0.L = A0 (ISS2);
+       R0.L = A0 (IH);
+
+       // Accumulator to D-register Moves
+
+       R0 = A0;
+       R0 = A0 (FU);
+       R0 = A0 (IS); // Not documented
+       R0 = A0 (IU); // Not documented
+       R0 = A0 (S2RND);
+       R0 = A0 (ISS2);
+
+       // Multiply 16-Bit Operands to Half Dreg
+
+       R0.H = R1.L * R2.H;
+       R0.H = R1.L * R2.H (FU);
+       R0.H = R1.L * R2.H (IS);
+       R0.H = R1.L * R2.H (IU);
+       R0.H = R1.L * R2.H (T);
+       R0.H = R1.L * R2.H (TFU);
+       R0.H = R1.L * R2.H (S2RND);
+       R0.H = R1.L * R2.H (ISS2);
+       R0.H = R1.L * R2.H (IH);
+
+       // Multiply 16-Bit Operands to Dreg
+
+       R0 = R1.L * R2.H;
+       R0 = R1.L * R2.H (FU);
+       R0 = R1.L * R2.H (IS);
+       R0 = R1.L * R2.H (S2RND); // Not documented
+       R0 = R1.L * R2.H (ISS2);
+
+       // Multiply and Multiply-Accumulate to Accumulator
+
+       A0 = R1.L * R2.H;
+       A0 = R1.L * R2.H (FU);
+       A0 = R1.L * R2.H (IS);
+       A0 = R1.L * R2.H (W32);
+
+       // Multiply and Multiply-Accumulate to Half-Register
+
+       R0.L = (A0 = R1.L * R2.H);
+       R0.L = (A0 = R1.L * R2.H) (FU);
+       R0.L = (A0 = R1.L * R2.H) (IS);
+       R0.L = (A0 = R1.L * R2.H) (IU);
+       R0.L = (A0 = R1.L * R2.H) (T);
+       R0.L = (A0 = R1.L * R2.H) (TFU);
+       R0.L = (A0 = R1.L * R2.H) (S2RND);
+       R0.L = (A0 = R1.L * R2.H) (ISS2);
+       R0.L = (A0 = R1.L * R2.H) (IH);
+
+       // Multiply and Multiply-Accumulate to Data Register
+
+       R0 = (A0 = R1.L * R2.H);
+       R0 = (A0 = R1.L * R2.H) (FU);
+       R0 = (A0 = R1.L * R2.H) (IS);
+       R0 = (A0 = R1.L * R2.H) (IU); // Not documented
+       R0 = (A0 = R1.L * R2.H) (S2RND);
+       R0 = (A0 = R1.L * R2.H) (ISS2);
+
+
index e4463463995a45707a64ece574a64766b5fe28e1..4a8643a18995307b53c863bff2d426c3c4d8d8e4 100644 (file)
@@ -2,6 +2,7 @@
 
 if [istarget bfin*-*-*] {
        run_dump_test "arithmetic"
+       run_dump_test "arith_mode"
        run_dump_test "bit"
        run_dump_test "bit2"
        run_dump_test "cache"
@@ -15,6 +16,7 @@ if [istarget bfin*-*-*] {
        run_list_test "expected_comparison_errors" ""
        run_dump_test "flow"
        run_dump_test "flow2"
+       run_list_test "invalid_arith_mode" ""
        run_dump_test "load"
        run_dump_test "logical"
        run_dump_test "logical2"
diff --git a/gas/testsuite/gas/bfin/invalid_arith_mode.l b/gas/testsuite/gas/bfin/invalid_arith_mode.l
new file mode 100644 (file)
index 0000000..674ca4a
--- /dev/null
@@ -0,0 +1,23 @@
+.*: Assembler messages:
+.*:7: Error: bad option.
+.*:11: Error: bad option.
+.*:12: Error: bad option.
+.*:13: Error: bad option.
+.*:14: Error: bad option.
+.*:18: Error: bad option..
+.*:22: Error: bad option.
+.*:23: Error: bad option.
+.*:24: Error: bad option.
+.*:25: Error: bad option.
+.*:26: Error: bad option.
+.*:30: Error: bad option.
+.*:31: Error: bad option.
+.*:32: Error: bad option.
+.*:33: Error: bad option.
+.*:34: Error: bad option.
+.*:35: Error: bad option.
+.*:39: Error: bad option.
+.*:43: Error: bad option.
+.*:44: Error: bad option.
+.*:45: Error: bad option.
+.*:46: Error: bad option.
diff --git a/gas/testsuite/gas/bfin/invalid_arith_mode.s b/gas/testsuite/gas/bfin/invalid_arith_mode.s
new file mode 100644 (file)
index 0000000..33a4337
--- /dev/null
@@ -0,0 +1,46 @@
+       .text
+
+       // All available modes: FU, IS, IU, T, TFU, S2RND, ISS2, IH, W32
+
+       // Accumulator to Half D-register Moves
+
+       R0.L = A0 (W32);
+
+       // Accumulator to D-register Moves
+
+       R0 = A0 (T);
+       R0 = A0 (TFU);
+       R0 = A0 (IH);
+       R0 = A0 (W32);
+
+       // Multiply 16-Bit Operands to Half Dreg
+
+       R0.H = R1.L * R2.H (W32);
+
+       // Multiply 16-Bit Operands to Dreg
+
+       R0 = R1.L * R2.H (IU);
+       R0 = R1.L * R2.H (T);
+       R0 = R1.L * R2.H (TFU);
+       R0 = R1.L * R2.H (IH);
+       R0 = R1.L * R2.H (W32);
+
+       // Multiply and Multiply-Accumulate to Accumulator
+
+       A0 = R1.L * R2.H (IU);
+       A0 = R1.L * R2.H (T);
+       A0 = R1.L * R2.H (TFU);
+       A0 = R1.L * R2.H (S2RND);
+       A0 = R1.L * R2.H (ISS2);
+       A0 = R1.L * R2.H (IH);
+
+       // Multiply and Multiply-Accumulate to Half-Register
+
+       R0.L = (A0 = R1.L * R2.H) (W32);
+
+       // Multiply and Multiply-Accumulate to Data Register
+
+       R0 = (A0 = R1.L * R2.H) (T);
+       R0 = (A0 = R1.L * R2.H) (TFU);
+       R0 = (A0 = R1.L * R2.H) (IH);
+       R0 = (A0 = R1.L * R2.H) (W32);