aboutsummaryrefslogtreecommitdiff
path: root/gas/config/bfin-parse.y
diff options
context:
space:
mode:
authorBernd Schmidt <bernds@codesourcery.com>2008-03-26 15:58:27 +0000
committerBernd Schmidt <bernds@codesourcery.com>2008-03-26 15:58:27 +0000
commitc1db045b89dfb593a18aabb0e2b868b7b717d940 (patch)
treecb4832d099de0596f0728a5ce982de40ed8d7eea /gas/config/bfin-parse.y
parent99bfa74a539321b7c476a33880f9afa04d69894a (diff)
downloadgdb-c1db045b89dfb593a18aabb0e2b868b7b717d940.zip
gdb-c1db045b89dfb593a18aabb0e2b868b7b717d940.tar.gz
gdb-c1db045b89dfb593a18aabb0e2b868b7b717d940.tar.bz2
gas/:
* config/bfin-parse.y (check_macfunc_option): New. (check_macfuncs): Check option by calling check_macfunc_option. Fix comparison always true warnings. Both scalar instructions of vector instruction must share the same mode option. Only allow option mode at the end of the second instruction of the vector. (asm_1): Check option by calling check_macfunc_option. gas/testsuite/: * gas/bfin/expected_errors.l, gas/bfin/expected_errors.s: Add tests for bad options of "multiply and multipy-accumulate to accumulator" instructions. Add new vector instruction option mode tests. * gas/bfin/vector2.s: Add new vector instruction option mode test. * gas/bfin/vector2.d: Adjust accordingly. * gas/bfin/expected_errors.s, gas/bfin/expected_errors.l: Add test for mismatched half registers in vector multipy-accumulate instructions.
Diffstat (limited to 'gas/config/bfin-parse.y')
-rw-r--r--gas/config/bfin-parse.y53
1 files changed, 47 insertions, 6 deletions
diff --git a/gas/config/bfin-parse.y b/gas/config/bfin-parse.y
index b320c72..6a36863 100644
--- a/gas/config/bfin-parse.y
+++ b/gas/config/bfin-parse.y
@@ -264,6 +264,35 @@ check_multiply_halfregs (Macfunc *aa, Macfunc *ab)
}
+/* Check mac option. */
+
+static int
+check_macfunc_option (Macfunc *a, Opt_mode *opt)
+{
+ /* Default option is always valid. */
+ 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)
+ || (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))
+ return -1;
+
+ return 0;
+}
+
/* Check (vector) mac funcs and ops. */
static int
@@ -274,6 +303,11 @@ check_macfuncs (Macfunc *aa, Opt_mode *opa,
Macfunc mtmp;
Opt_mode otmp;
+ /* The option mode should be put at the end of the second instruction
+ of the vector except M, which should follow MAC1 instruction. */
+ if (opa->mod != 0)
+ return yyerror ("Bad opt mode");
+
/* If a0macfunc comes before a1macfunc, swap them. */
if (aa->n == 0)
@@ -291,16 +325,14 @@ check_macfuncs (Macfunc *aa, Opt_mode *opa,
{
if (opb->MM != 0)
return yyerror ("(M) not allowed with A0MAC");
- if (opa->mod != 0)
- return yyerror ("Bad opt mode");
if (ab->n != 0)
return yyerror ("Vector AxMACs can't be same");
}
/* If both ops are one of 0, 1, or 2, we have multiply_halfregs in both
assignment_or_macfuncs. */
- if (aa->op < 3 && aa->op >=0
- && ab->op < 3 && ab->op >= 0)
+ if ((aa->op == 0 || aa->op == 1 || aa->op == 2)
+ && (ab->op == 0 || ab->op == 1 || ab->op == 2))
{
if (check_multiply_halfregs (aa, ab) < 0)
return -1;
@@ -330,11 +362,17 @@ check_macfuncs (Macfunc *aa, Opt_mode *opa,
|| (ab->w && !aa->P && IS_H (ab->dst)))
return yyerror ("High/Low register assignment mismatch");
+ /* Make sure mod flags get ORed, too. */
+ opb->mod |= opa->mod;
+
+ /* Check option. */
+ if (check_macfunc_option (aa, opb) < 0
+ && check_macfunc_option (ab, opb) < 0)
+ return yyerror ("bad option");
+
/* Make sure first macfunc has got both P flags ORed. */
aa->P |= ab->P;
- /* Make sure mod flags get ORed, too. */
- opb->mod |= opa->mod;
return 0;
}
@@ -660,6 +698,9 @@ asm_1:
int w0 = 0, w1 = 0;
int h00, h10, h01, h11;
+ if (check_macfunc_option (&$1, &$2) < 0)
+ return yyerror ("bad option");
+
if ($1.n == 0)
{
if ($2.MM)