RISC-V: fold duplicate code in vector_macro()

There's no need to have almost identical code twice. Do away with
M_VMSGEU and instead simply use an unused (for these macros) field to
tell apart both variants.
This commit is contained in:
Jan Beulich
2023-09-05 10:03:35 +02:00
parent 404def8928
commit d486800436
3 changed files with 7 additions and 43 deletions
+5 -40
View File
@@ -1958,6 +1958,7 @@ vector_macro (struct riscv_cl_insn *ip)
int vs2 = (ip->insn_opcode >> OP_SH_VS2) & OP_MASK_VS2;
int vm = (ip->insn_opcode >> OP_SH_VMASK) & OP_MASK_VMASK;
int vtemp = (ip->insn_opcode >> OP_SH_VFUNCT6) & OP_MASK_VFUNCT6;
const char *vmslt_vx = ip->insn_mo->match ? "vmsltu.vx" : "vmslt.vx";
int mask = ip->insn_mo->mask;
switch (mask)
@@ -1966,7 +1967,7 @@ vector_macro (struct riscv_cl_insn *ip)
if (vm)
{
/* Unmasked. */
macro_build (NULL, "vmslt.vx", "Vd,Vt,sVm", vd, vs2, vs1, -1);
macro_build (NULL, vmslt_vx, "Vd,Vt,sVm", vd, vs2, vs1, -1);
macro_build (NULL, "vmnand.mm", "Vd,Vt,Vs", vd, vd, vd);
break;
}
@@ -1975,13 +1976,13 @@ vector_macro (struct riscv_cl_insn *ip)
/* Masked. Have vtemp to avoid overlap constraints. */
if (vd == vm)
{
macro_build (NULL, "vmslt.vx", "Vd,Vt,sVm", vtemp, vs2, vs1, -1);
macro_build (NULL, vmslt_vx, "Vd,Vt,sVm", vtemp, vs2, vs1, -1);
macro_build (NULL, "vmandnot.mm", "Vd,Vt,Vs", vd, vm, vtemp);
}
else
{
/* Preserve the value of vd if not updating by vm. */
macro_build (NULL, "vmslt.vx", "Vd,Vt,sVm", vtemp, vs2, vs1, -1);
macro_build (NULL, vmslt_vx, "Vd,Vt,sVm", vtemp, vs2, vs1, -1);
macro_build (NULL, "vmandnot.mm", "Vd,Vt,Vs", vtemp, vm, vtemp);
macro_build (NULL, "vmandnot.mm", "Vd,Vt,Vs", vd, vd, vm);
macro_build (NULL, "vmor.mm", "Vd,Vt,Vs", vd, vtemp, vd);
@@ -1990,42 +1991,7 @@ vector_macro (struct riscv_cl_insn *ip)
else if (vd != vm)
{
/* Masked. This may cause the vd overlaps vs2, when LMUL > 1. */
macro_build (NULL, "vmslt.vx", "Vd,Vt,sVm", vd, vs2, vs1, vm);
macro_build (NULL, "vmxor.mm", "Vd,Vt,Vs", vd, vd, vm);
}
else
as_bad (_("must provide temp if destination overlaps mask"));
break;
case M_VMSGEU:
if (vm)
{
/* Unmasked. */
macro_build (NULL, "vmsltu.vx", "Vd,Vt,sVm", vd, vs2, vs1, -1);
macro_build (NULL, "vmnand.mm", "Vd,Vt,Vs", vd, vd, vd);
break;
}
if (vtemp != 0)
{
/* Masked. Have vtemp to avoid overlap constraints. */
if (vd == vm)
{
macro_build (NULL, "vmsltu.vx", "Vd,Vt,sVm", vtemp, vs2, vs1, -1);
macro_build (NULL, "vmandnot.mm", "Vd,Vt,Vs", vd, vm, vtemp);
}
else
{
/* Preserve the value of vd if not updating by vm. */
macro_build (NULL, "vmsltu.vx", "Vd,Vt,sVm", vtemp, vs2, vs1, -1);
macro_build (NULL, "vmandnot.mm", "Vd,Vt,Vs", vtemp, vm, vtemp);
macro_build (NULL, "vmandnot.mm", "Vd,Vt,Vs", vd, vd, vm);
macro_build (NULL, "vmor.mm", "Vd,Vt,Vs", vd, vtemp, vd);
}
}
else if (vd != vm)
{
/* Masked. This may cause the vd overlaps vs2, when LMUL > 1. */
macro_build (NULL, "vmsltu.vx", "Vd,Vt,sVm", vd, vs2, vs1, vm);
macro_build (NULL, vmslt_vx, "Vd,Vt,sVm", vd, vs2, vs1, vm);
macro_build (NULL, "vmxor.mm", "Vd,Vt,Vs", vd, vd, vm);
}
else
@@ -2180,7 +2146,6 @@ macro (struct riscv_cl_insn *ip, expressionS *imm_expr,
break;
case M_VMSGE:
case M_VMSGEU:
vector_macro (ip);
break;
-1
View File
@@ -563,7 +563,6 @@ enum
M_SEXTB,
M_SEXTH,
M_VMSGE,
M_VMSGEU,
M_FLH,
M_FSH,
M_NUM_MACROS
+2 -2
View File
@@ -1620,8 +1620,8 @@ const struct riscv_opcode riscv_opcodes[] =
{"vmsge.vx", 0, INSN_CLASS_V, "Vd,Vt,sVm", 0, (int) M_VMSGE, match_never, INSN_MACRO },
{"vmsge.vx", 0, INSN_CLASS_V, "Vd,Vt,s,VM,VT", 0, (int) M_VMSGE, match_never, INSN_MACRO },
{"vmsgeu.vx", 0, INSN_CLASS_V, "Vd,Vt,sVm", 0, (int) M_VMSGEU, match_never, INSN_MACRO },
{"vmsgeu.vx", 0, INSN_CLASS_V, "Vd,Vt,s,VM,VT", 0, (int) M_VMSGEU, match_never, INSN_MACRO },
{"vmsgeu.vx", 0, INSN_CLASS_V, "Vd,Vt,sVm", 1, (int) M_VMSGE, match_never, INSN_MACRO },
{"vmsgeu.vx", 0, INSN_CLASS_V, "Vd,Vt,s,VM,VT", 1, (int) M_VMSGE, match_never, INSN_MACRO },
{"vminu.vv", 0, INSN_CLASS_V, "Vd,Vt,VsVm", MATCH_VMINUVV, MASK_VMINUVV, match_opcode, 0},
{"vminu.vx", 0, INSN_CLASS_V, "Vd,Vt,sVm", MATCH_VMINUVX, MASK_VMINUVX, match_opcode, 0},