}
+/* 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
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)
{
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;
|| (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;
}
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)
notethat ("COMPI2opD: dregs += imm7\n");
$$ = COMPI2OPD (&$1, imm7 ($3), 1);
}
+ else if ((IS_DREG ($1) || IS_PREG ($1)) && IS_CONST ($3))
+ return yyerror ("Immediate value out of range");
else
return yyerror ("Register mismatch");
}
}
| CCREG ASSIGN REG_A _ASSIGN_ASSIGN REG_A
{
- if (!REG_SAME ($3, $5))
+ if ($3.regno == REG_A0 && $5.regno == REG_A1)
{
notethat ("CCflag: CC = A0 == A1\n");
$$ = CCFLAG (0, 0, 5, 0, 0);
}
else
- return yyerror ("CC register expected");
+ return yyerror ("AREGs are in bad order or same");
}
| CCREG ASSIGN REG_A LESS_THAN REG_A
{
- if (!REG_SAME ($3, $5))
+ if ($3.regno == REG_A0 && $5.regno == REG_A1)
{
notethat ("CCflag: CC = A0 < A1\n");
$$ = CCFLAG (0, 0, 6, 0, 0);
}
else
- return yyerror ("Register mismatch");
+ return yyerror ("AREGs are in bad order or same");
}
| CCREG ASSIGN REG LESS_THAN REG iu_or_nothing
{
{
notethat ("CCflag: CC = dpregs == dpregs\n");
$$ = CCFLAG (&$3, $5.regno & CODE_MASK, 0, 0, IS_PREG ($3) ? 1 : 0);
- }
+ }
+ else
+ return yyerror ("Compare only of same register class");
}
| CCREG ASSIGN REG _ASSIGN_ASSIGN expr
{
}
| CCREG ASSIGN REG_A _LESS_THAN_ASSIGN REG_A
{
- if (!REG_SAME ($3, $5))
+ if ($3.regno == REG_A0 && $5.regno == REG_A1)
{
notethat ("CCflag: CC = A0 <= A1\n");
$$ = CCFLAG (0, 0, 7, 0, 0);
}
else
- return yyerror ("CC register expected");
+ return yyerror ("AREGs are in bad order or same");
}
| CCREG ASSIGN REG _LESS_THAN_ASSIGN REG iu_or_nothing
{