Skip to content

Commit

Permalink
RISC-V: Add RVV v0.7 supports.
Browse files Browse the repository at this point in the history
This patch support RVV 0.7 instruction and compatible with RVV 1.0,
Distinguish two different vector version with the input version number,
like --with-arch=rv64gcv0p7 will get RVV0.7 enable, rv64gcv1p0 get RVV 1.0.
Notice that there are many instruction use the same assembly names,
the disassembler may not generate correct disassembly in result when you both
enable two different version vector extensions.

bfd/ChangeLog:

        * elfxx-riscv.c (check_rvv_verison_1p0): New func.
        (check_rvv_verison_0p7): Ditto.
        (riscv_parse_check_conflicts): Split diff versions.
        (riscv_multi_subset_supports): New checks.
        (riscv_multi_subset_supports_ext): New missing logs.

gas/ChangeLog:

        * config/tc-riscv.c (my_getVsetvliExpression): RVV 0.7 case.

include/ChangeLog:

        * opcode/riscv-opc.h : RVV 0.7 opcodes.
        * opcode/riscv.h (enum riscv_insn_class):  New instrunction class.
                         (riscv_vlen): New vsetvli args.
                         (riscv_vediv): Ditto.

opcodes/ChangeLog:

        * riscv-opc.c: Merge RVV 0.7 and 1.0 instruction definations.
  • Loading branch information
pz9115 committed Jun 28, 2023
1 parent 7e21c2c commit 9518572
Show file tree
Hide file tree
Showing 5 changed files with 1,247 additions and 295 deletions.
50 changes: 43 additions & 7 deletions bfd/elfxx-riscv.c
Original file line number Diff line number Diff line change
Expand Up @@ -1030,6 +1030,24 @@ check_implicit_for_i (const char *implicit ATTRIBUTE_UNUSED,
&& subset->minor_version < 1));
}

/* Check RVV version. */

static bool
check_rvv_verison_1p0 (const char *implicit ATTRIBUTE_UNUSED,
riscv_subset_t *subset)
{
return (subset->major_version == 1
&& subset->minor_version == 0);
}

static bool
check_rvv_verison_0p7 (const char *implicit ATTRIBUTE_UNUSED,
riscv_subset_t *subset)
{
return (subset->major_version == 0
&& subset->minor_version == 7);
}

/* Record all implicit information for the subsets. */
struct riscv_implicit_subset
{
Expand All @@ -1054,8 +1072,10 @@ static struct riscv_implicit_subset riscv_implicit_subsets[] =
{"h", "zicsr", check_implicit_always},
{"q", "d", check_implicit_always},
{"v", "d", check_implicit_always},
{"v", "zve64d", check_implicit_always},
{"v", "zvl128b", check_implicit_always},
{"v", "zve64d", check_rvv_verison_1p0},
{"v", "zvl128b", check_rvv_verison_1p0},
{"v", "zvlsseg", check_rvv_verison_0p7},
{"v", "zvamo", check_rvv_verison_0p7},
{"zve64d", "d", check_implicit_always},
{"zve64d", "zve64f", check_implicit_always},
{"zve64f", "zve32f", check_implicit_always},
Expand Down Expand Up @@ -1853,7 +1873,8 @@ riscv_parse_check_conflicts (riscv_parse_subset_t *rps)
&& strncmp (s->name, "zve", 3) == 0)
support_zve = true;
if (!support_zvl
&& strncmp (s->name, "zvl", 3) == 0)
&& strncmp (s->name, "zvl", 3) == 0
&& strncmp (s->name, "zvls", 4) != 0)
support_zvl = true;
if (support_zve && support_zvl)
break;
Expand Down Expand Up @@ -2347,14 +2368,24 @@ riscv_multi_subset_supports (riscv_parse_subset_t *rps,
case INSN_CLASS_ZKSH:
return riscv_subset_supports (rps, "zksh");
case INSN_CLASS_V:
return (riscv_subset_supports (rps, "v")
return ((riscv_subset_supports (rps, "v")
|| riscv_subset_supports (rps, "zve64x")
|| riscv_subset_supports (rps, "zve32x"));
|| riscv_subset_supports (rps, "zve32x"))
&& !riscv_subset_supports (rps, "zvamo"));
case INSN_CLASS_ZV:
return ((riscv_subset_supports (rps, "v")
|| riscv_subset_supports (rps, "zvlsseg")
|| riscv_subset_supports (rps, "zvamo"))
&& !riscv_subset_supports (rps, "zve32x"));
case INSN_CLASS_ZVEF:
return (riscv_subset_supports (rps, "v")
return ((riscv_subset_supports (rps, "v")
|| riscv_subset_supports (rps, "zve64d")
|| riscv_subset_supports (rps, "zve64f")
|| riscv_subset_supports (rps, "zve32f"));
|| riscv_subset_supports (rps, "zve32f"))
&& !riscv_subset_supports (rps, "zvamo"));
case INSN_CLASS_V_OR_ZV:
case INSN_CLASS_ZVEF_OR_ZV:
return riscv_subset_supports (rps, "v");
case INSN_CLASS_SVINVAL:
return riscv_subset_supports (rps, "svinval");
case INSN_CLASS_H:
Expand Down Expand Up @@ -2511,8 +2542,13 @@ riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps,
return "zksh";
case INSN_CLASS_V:
return _("v' or `zve64x' or `zve32x");
case INSN_CLASS_ZV:
return _("v' or `zvlsseg' or `zvamo");
case INSN_CLASS_ZVEF:
return _("v' or `zve64d' or `zve64f' or `zve32f");
case INSN_CLASS_V_OR_ZV:
case INSN_CLASS_ZVEF_OR_ZV:
return "v";
case INSN_CLASS_SVINVAL:
return "svinval";
case INSN_CLASS_H:
Expand Down
64 changes: 56 additions & 8 deletions gas/config/tc-riscv.c
Original file line number Diff line number Diff line change
Expand Up @@ -2306,34 +2306,38 @@ my_getVsetvliExpression (expressionS *ep, char *str)
{
unsigned int vsew_value = 0, vlmul_value = 0;
unsigned int vta_value = 0, vma_value = 0;
unsigned int vlen_value = 0, vediv_value = 0; /* RVV 0.7. */
bfd_boolean vsew_found = FALSE, vlmul_found = FALSE;
bfd_boolean vta_found = FALSE, vma_found = FALSE;
bfd_boolean vlen_found = FALSE, vediv_found = FALSE; /* RVV 0.7. */

if (arg_lookup (&str, riscv_vsew, ARRAY_SIZE (riscv_vsew), &vsew_value))
if(riscv_subset_supports (&riscv_rps_as, "zve32x"))
{
if (arg_lookup (&str, riscv_vsew, ARRAY_SIZE (riscv_vsew), &vsew_value))
{
if (*str == ',')
++str;
if (vsew_found)
as_bad (_("multiple vsew constants"));
vsew_found = TRUE;
}
if (arg_lookup (&str, riscv_vlmul, ARRAY_SIZE (riscv_vlmul), &vlmul_value))
if (arg_lookup (&str, riscv_vlmul, ARRAY_SIZE (riscv_vlmul), &vlmul_value))
{
if (*str == ',')
++str;
if (vlmul_found)
as_bad (_("multiple vlmul constants"));
vlmul_found = TRUE;
}
if (arg_lookup (&str, riscv_vta, ARRAY_SIZE (riscv_vta), &vta_value))
if (arg_lookup (&str, riscv_vta, ARRAY_SIZE (riscv_vta), &vta_value))
{
if (*str == ',')
++str;
if (vta_found)
as_bad (_("multiple vta constants"));
vta_found = TRUE;
}
if (arg_lookup (&str, riscv_vma, ARRAY_SIZE (riscv_vma), &vma_value))
if (arg_lookup (&str, riscv_vma, ARRAY_SIZE (riscv_vma), &vma_value))
{
if (*str == ',')
++str;
Expand All @@ -2342,20 +2346,64 @@ my_getVsetvliExpression (expressionS *ep, char *str)
vma_found = TRUE;
}

if (vsew_found || vlmul_found || vta_found || vma_found)
if (vsew_found || vlmul_found || vta_found || vma_found)
{
ep->X_op = O_constant;
ep->X_add_number = (vlmul_value << OP_SH_VLMUL)
| (vsew_value << OP_SH_VSEW)
| (vta_value << OP_SH_VTA)
| (vma_value << OP_SH_VMA);
| (vsew_value << OP_SH_VSEW)
| (vta_value << OP_SH_VTA)
| (vma_value << OP_SH_VMA);
expr_end = str;
}
else
{
my_getExpression (ep, str);
str = expr_end;
}
}
else
{
/* RVV 0.7. */
if (arg_lookup (&str, riscv_vsew, ARRAY_SIZE (riscv_vsew), &vsew_value))
{
if (*str == ',')
++str;
if (vsew_found)
as_bad (_("multiple vsew constants"));
vsew_found = TRUE;
}

if (arg_lookup (&str, riscv_vlen, ARRAY_SIZE (riscv_vlen), &vlen_value))
{
if (*str == ',')
++str;
if (vlen_found)
as_bad (_("multiple vlen constants"));
vlen_found = TRUE;
}
if (arg_lookup (&str, riscv_vediv, ARRAY_SIZE (riscv_vediv), &vediv_value))
{
if (*str == ',')
++str;
if (vediv_found)
as_bad (_("multiple vediv constants"));
vediv_found = TRUE;
}

if (vsew_found || vlmul_found || vta_found || vma_found)
{
ep->X_op = O_constant;
ep->X_add_number = (vediv_value << 5)
| (vsew_value << 2)
| (vlen_value);
expr_end = str;
}
else
{
my_getExpression (ep, str);
str = expr_end;
}
}
}

/* Detect and handle implicitly zero load-store offsets. For example,
Expand Down
Loading

0 comments on commit 9518572

Please sign in to comment.