* 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.
This commit is contained in:
Bernd Schmidt 2008-03-26 15:58:27 +00:00
parent 99bfa74a53
commit c1db045b89
7 changed files with 771 additions and 681 deletions

View File

@ -2,8 +2,14 @@
From Jie Zhang <jie.zhang@analog.com>
* config/bfin-parse.y (asm_1): Check AREGS in comparison
instructions. And call yyerror () when comparing PREG with
instructions. And call yyerror when comparing PREG with
DREG.
(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.
2008-03-19 Andreas Krebbel <krebbel1@de.ibm.com>

View File

@ -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)

View File

@ -5,6 +5,17 @@
* gas/bfin/expected_comparison_errors.l: New test.
* gas/bfin/expected_comparison_errors.s: New test.
* gas/bfin/bfin.exp: Add expected_comparison_errors.
* 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.
From Mike Frysinger <michael.frysinger@analog.com>
* gas/bfin/expected_errors.s, gas/bfin/expected_errors.l: Add test
for mismatched half registers in vector multipy-accumulate
instructions.
2008-03-19 Andreas Krebbel <krebbel1@de.ibm.com>

View File

@ -8,3 +8,12 @@
.*:10: Error: Bad constant value.
.*:11: Error: Bad constant value.
.*:13: Error: Dregs expected. Input text was R3.L.
.*:15: Error: Source multiplication register mismatch. Input text was \).
.*:17: Error: bad option.
.*:18: Error: bad option.
.*:19: Error: bad option.
.*:20: Error: bad option.
.*:21: Error: bad option.
.*:22: Error: bad option.
.*:23: Error: Bad opt mode.
.*:24: Error: Bad opt mode.

View File

@ -11,3 +11,14 @@
CC = R3 <= 8;
A1 -= M2.h * R3.L, A0 -= M2.l * R3.L;
R1.H = (A1=R7.L*R5.L) , A0 += R1.L*R0.L (IS);
a0 += R2.L * R3.L (IU);
a0 += R2.L * R3.L (T);
a0 += R2.L * R3.L (TFU);
a0 += R2.L * R3.L (S2RND);
a0 += R2.L * R3.L (ISS2);
a0 += R2.L * R3.L (IH);
R0.H = (A1 = R4.L * R3.L) (T), A0 = R4.H * R3.L;
R0.L = (A0 = R7.L * R4.H) (T), A1 += R7.H * R4.H;

View File

@ -471,4 +471,9 @@ Disassembly of section .text:
73c: 72 9e 00 00
740: 14 c2 1a a0 R0.H = R3.H \* R2.L \(M\), R0 = R3.L \* R2.L;
744: 1c c2 b8 60 R3 = R7.L \* R0.H \(M\), R2 = R7.L \* R0.L;
748: 1c c0 b8 60 R3 = \(a1 = R7.L \* R0.H\) \(M\), R2 = \(a0 = R7.L \* R0.L\);
748: 1c c0 b8 60 R3 = \(a1 = R7.L \* R0.H\) \(M\), R2 = \(a0 = R7.L \* R0.L\);
74c: 44 c0 23 04 R0.H = \(a1 = R4.L \* R3.L\), a0 = R4.H \* R3.L \(T\);
750: 54 c0 23 04 R0.H = \(a1 = R4.L \* R3.L\) \(M\), a0 = R4.H \* R3.L \(T\);
754: 44 c0 23 04 R0.H = \(a1 = R4.L \* R3.L\), a0 = R4.H \* R3.L \(T\);
758: 54 c0 23 04 R0.H = \(a1 = R4.L \* R3.L\) \(M\), a0 = R4.H \* R3.L \(T\);
75c: 41 c0 3c e2 a1 \+= R7.H \* R4.H, R0.L = \(a0 = R7.L \* R4.H\) \(T\);

File diff suppressed because it is too large Load Diff