Skip to content

Commit 64e319d

Browse files
bfd, gas, binutils: add support for the Xarcvudsp extension
This commit implements support for the ARC-V micro-DSP extension version 1.4, which is a 32-bit DSP-style extension mostly operating on 16-bit data. The assembly mnemonics resemble RVV instructions, but SEW and LMUL are embedded in the instruction encoding instead of coming from a CSR. Since it reuses reserved RVV encodings, it is a non-conforming extension. TODO: add more text and pointers to public documentation. Signed-off-by: Artemiy Volkov <[email protected]>
1 parent 4acd941 commit 64e319d

File tree

11 files changed

+934
-0
lines changed

11 files changed

+934
-0
lines changed

bfd/elfxx-riscv.c

+13
Original file line numberDiff line numberDiff line change
@@ -1511,6 +1511,7 @@ static struct riscv_supported_ext riscv_supported_vendor_x_ext[] =
15111511
{"xventanacondops", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
15121512
{"xsfvcp", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
15131513
{"xsfcease", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
1514+
{"xarcvudsp", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
15141515
{NULL, 0, 0, 0, 0}
15151516
};
15161517

@@ -2121,6 +2122,14 @@ riscv_parse_check_conflicts (riscv_parse_subset_t *rps)
21212122
(_("`xtheadvector' is conflict with the `v' extension"));
21222123
no_conflict = false;
21232124
}
2125+
if (riscv_lookup_subset (rps->subset_list, "xarcvudsp", &subset)
2126+
&& riscv_lookup_subset (rps->subset_list, "v", &subset))
2127+
{
2128+
rps->error_handler
2129+
(_("`xarcvudsp' is conflict with the `v' extension"));
2130+
no_conflict = false;
2131+
}
2132+
21242133

21252134
bool support_zve = false;
21262135
bool support_zvl = false;
@@ -2786,6 +2795,8 @@ riscv_multi_subset_supports (riscv_parse_subset_t *rps,
27862795
return riscv_subset_supports (rps, "xsfvcp");
27872796
case INSN_CLASS_XSFCEASE:
27882797
return riscv_subset_supports (rps, "xsfcease");
2798+
case INSN_CLASS_XARCVUDSP:
2799+
return riscv_subset_supports (rps, "xarcvudsp");
27892800
default:
27902801
rps->error_handler
27912802
(_("internal: unreachable INSN_CLASS_*"));
@@ -3058,6 +3069,8 @@ riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps,
30583069
return "xtheadzvamo";
30593070
case INSN_CLASS_XSFCEASE:
30603071
return "xsfcease";
3072+
case INSN_CLASS_XARCVUDSP:
3073+
return "xarcvudsp";
30613074
default:
30623075
rps->error_handler
30633076
(_("internal: unreachable INSN_CLASS_*"));

gas/config/tc-riscv.c

+114
Original file line numberDiff line numberDiff line change
@@ -1717,6 +1717,14 @@ validate_riscv_insn (const struct riscv_opcode *opc, int length)
17171717
goto unknown_validate_operand;
17181718
}
17191719
break;
1720+
case 'a': /* Vendor-specific (ARC-V) operands. */
1721+
switch (*++oparg)
1722+
{
1723+
case 'v': USE_BITS (OP_MASK_FUNCT3, OP_SH_FUNCT3); break;
1724+
default:
1725+
goto unknown_validate_operand;
1726+
}
1727+
break;
17201728
default:
17211729
goto unknown_validate_operand;
17221730
}
@@ -2685,6 +2693,97 @@ my_getThVsetvliExpression (expressionS *ep, char *str)
26852693
}
26862694
}
26872695

2696+
static struct arcv_udsp_insn_vtype_combination {
2697+
const char *insn;
2698+
int sew;
2699+
int lmul;
2700+
} arcv_udsp_insn_vtype_combinations[] = {
2701+
{ "arcv.xvadd.vv", 0x1, 0 },
2702+
{ "arcv.xvsub.vv", 0x1, 0 },
2703+
{ "arcv.xvsadd.vv", 0x1, 0 },
2704+
{ "arcv.xvsadd.vv", 0x2, 0 },
2705+
{ "arcv.xvssub.vv", 0x1, 0 },
2706+
{ "arcv.xvssub.vv", 0x2, 0 },
2707+
{ "arcv.xvsll.vx", 0x1, 0 },
2708+
{ "arcv.xvsra.vx", 0x1, 0 },
2709+
{ "arcv.xvnclip.wx", 0x1, 0 },
2710+
{ "arcv.xvnclip.wx", 0x1, 0x7 },
2711+
{ "arcv.xvwmul.vv", 0x1, 0 },
2712+
{ "arcv.xvwmul.vv", 0x1, 0x7 },
2713+
{ "arcv.xvwsrdot.vv", 0x1, 0 },
2714+
{ "arcv.xvscmul.vv", 0x1, 0 },
2715+
{ "arcv.xvscjmul.vv", 0x1, 0 },
2716+
{ "arcv.xvwscmul.vv", 0x1, 0 },
2717+
{ "arcv.xvwscjmul.vv", 0x1, 0 },
2718+
{ "arcv.xvwscrdot.vv", 0x1, 0 },
2719+
{ "arcv.xvwscjrdot.vv", 0x1, 0 },
2720+
{ 0 },
2721+
};
2722+
2723+
static bool
2724+
arcv_udsp_opcode_supports_sew_lmul (char *insn, int sew, int lmul)
2725+
{
2726+
for (struct arcv_udsp_insn_vtype_combination *ivc =
2727+
arcv_udsp_insn_vtype_combinations;
2728+
ivc->insn;
2729+
ivc++)
2730+
if (!strcmp (ivc->insn, insn) && ivc->sew == sew && ivc->lmul == lmul)
2731+
return true;
2732+
2733+
as_bad (_("bad ARC-V UDSP instruction: "
2734+
"combination of SEW and LMUL not supported for opcode"));
2735+
2736+
return false;
2737+
}
2738+
2739+
/* Parse string STR as a set of "vtype" operands of an ARC-V UDSP instruction
2740+
(the format is "eXX, mf?X"). Check legality of operands depending on the
2741+
instruction. Store the expression in *EP.
2742+
On exit, EXPR_PARSE_END points to the first character after the
2743+
expression. */
2744+
2745+
static void
2746+
my_getArcvVtypeExpression (expressionS *ep, char *str, char *insn)
2747+
{
2748+
unsigned int sew = 0, lmul = 0;
2749+
bfd_boolean vsew_found = FALSE, vlmul_found = FALSE;
2750+
2751+
if (arg_lookup (&str, riscv_vsew, ARRAY_SIZE (riscv_vsew),
2752+
&sew))
2753+
{
2754+
if (*str == ',')
2755+
++str;
2756+
vsew_found = TRUE;
2757+
}
2758+
else as_bad (_("bad ARC-V UDSP instruction: SEW not specified"));
2759+
2760+
if (arg_lookup (&str, riscv_vlmul, ARRAY_SIZE (riscv_vlmul), &lmul))
2761+
{
2762+
if (*str == ',')
2763+
++str;
2764+
vlmul_found = TRUE;
2765+
}
2766+
else as_bad (_("bad ARC-V UDSP instruction: LMUL not specified"));
2767+
2768+
if (!vsew_found || !vlmul_found
2769+
|| !arcv_udsp_opcode_supports_sew_lmul (insn, sew, lmul))
2770+
{
2771+
my_getExpression (ep, str);
2772+
str = expr_parse_end;
2773+
}
2774+
else
2775+
{
2776+
gas_assert ((sew == 0x2 && lmul == 0)
2777+
|| (sew == 0x1 && (lmul == 0 || lmul == 0x7)));
2778+
2779+
ep->X_op = O_constant;
2780+
ep->X_add_number = (sew == 0x2 ? 0x4 :
2781+
(lmul == 0 ? 0x2 : 0x1));
2782+
expr_parse_end = str;
2783+
}
2784+
}
2785+
2786+
26882787
/* Detect and handle implicitly zero load-store offsets. For example,
26892788
"lw t0, (t1)" is shorthand for "lw t0, 0(t1)". Return true if such
26902789
an implicit offset was detected. */
@@ -4070,6 +4169,21 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
40704169
#undef ENCODE_UIMM_BIT_FIELD
40714170
break;
40724171

4172+
case 'a': /* Vendor-specific (ARC-V) operands. */
4173+
switch (*++oparg)
4174+
{
4175+
case 'v':
4176+
my_getArcvVtypeExpression (imm_expr, asarg, insn->name);
4177+
asarg = expr_parse_end;
4178+
ip->insn_opcode
4179+
|= (imm_expr->X_add_number & OP_MASK_FUNCT3)
4180+
<< OP_SH_FUNCT3;
4181+
continue;
4182+
default:
4183+
goto unknown_riscv_ip_operand;
4184+
}
4185+
break;
4186+
40734187
default:
40744188
goto unknown_riscv_ip_operand;
40754189
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#as: -march=rv32i_xarcvudsp -I$srcdir/$subdir/
2+
#error_output: x-arcv-udsp-fail.l

0 commit comments

Comments
 (0)