Skip to content
This repository was archived by the owner on Aug 17, 2022. It is now read-only.

Commit bfcd49d

Browse files
linsinan1995sinan-lin
authored andcommitted
Add p-ext support with spec v0.94
1 parent 9e61e0b commit bfcd49d

File tree

11 files changed

+2367
-3
lines changed

11 files changed

+2367
-3
lines changed

bfd/elfxx-riscv.c

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1598,7 +1598,8 @@ riscv_parse_prefixed_ext (riscv_parse_subset_t *rps,
15981598

15991599
static const char * const riscv_std_z_ext_strtab[] =
16001600
{
1601-
"zicsr", "zifencei", "zihintpause", "zba", "zbb", "zbc", NULL
1601+
"zicsr", "zifencei", "zihintpause", "zba", "zbb", "zbc",
1602+
"zpn", "zprv", "zpsf",NULL
16021603
};
16031604

16041605
static const char * const riscv_std_s_ext_strtab[] =
@@ -1770,6 +1771,15 @@ riscv_parse_add_implicit_subsets (riscv_parse_subset_t *rps)
17701771
RISCV_UNKNOWN_VERSION,
17711772
RISCV_UNKNOWN_VERSION, TRUE);
17721773
}
1774+
if (riscv_lookup_subset (rps->subset_list, "p", &subset))
1775+
{
1776+
riscv_parse_add_subset (rps, "zpn",
1777+
RISCV_UNKNOWN_VERSION,
1778+
RISCV_UNKNOWN_VERSION, TRUE);
1779+
riscv_parse_add_subset (rps, "zpsf",
1780+
RISCV_UNKNOWN_VERSION,
1781+
RISCV_UNKNOWN_VERSION, TRUE);
1782+
}
17731783
}
17741784

17751785
/* Function for parsing ISA string.
@@ -1873,6 +1883,14 @@ riscv_parse_subset (riscv_parse_subset_t *rps,
18731883
arch);
18741884
no_conflict = FALSE;
18751885
}
1886+
if (riscv_lookup_subset (rps->subset_list, "zprv", &subset)
1887+
&& *rps->xlen < 64)
1888+
{
1889+
rps->error_handler
1890+
(_("-march=%s: rv32 does not support the `zprv' extension"),
1891+
arch);
1892+
no_conflict = FALSE;
1893+
}
18761894
return no_conflict;
18771895
}
18781896

gas/config/tc-riscv.c

Lines changed: 167 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,8 @@ static const struct riscv_ext_version ext_version_table[] =
131131
{"c", ISA_SPEC_CLASS_20190608, 2, 0},
132132
{"c", ISA_SPEC_CLASS_2P2, 2, 0},
133133

134+
{"p", ISA_SPEC_CLASS_DRAFT, 0, 94},
135+
134136
{"zicsr", ISA_SPEC_CLASS_20191213, 2, 0},
135137
{"zicsr", ISA_SPEC_CLASS_20190608, 2, 0},
136138

@@ -142,7 +144,10 @@ static const struct riscv_ext_version ext_version_table[] =
142144
{"zbb", ISA_SPEC_CLASS_DRAFT, 0, 93},
143145
{"zba", ISA_SPEC_CLASS_DRAFT, 0, 93},
144146
{"zbc", ISA_SPEC_CLASS_DRAFT, 0, 93},
145-
147+
148+
{"zpn", ISA_SPEC_CLASS_DRAFT, 0, 94},
149+
{"zprv", ISA_SPEC_CLASS_DRAFT, 0, 94},
150+
{"zpsf", ISA_SPEC_CLASS_DRAFT, 0, 94},
146151
/* Terminate the list. */
147152
{NULL, 0, 0, 0}
148153
};
@@ -340,6 +345,13 @@ riscv_multi_subset_supports (enum riscv_insn_class insn_class)
340345
return riscv_subset_supports ("zba");
341346
case INSN_CLASS_ZBC:
342347
return riscv_subset_supports ("zbc");
348+
349+
case INSN_CLASS_ZPN:
350+
return riscv_subset_supports ("zpn");
351+
case INSN_CLASS_ZPRV:
352+
return riscv_subset_supports ("zprv");
353+
case INSN_CLASS_ZPSF:
354+
return riscv_subset_supports ("zpsf");
343355

344356
default:
345357
as_fatal ("internal: unreachable");
@@ -973,6 +985,29 @@ arg_lookup (char **s, const char *const *array, size_t size, unsigned *regnop)
973985
return FALSE;
974986
}
975987

988+
#define RVP_MAX_KEYWORD_LEN 32
989+
990+
static bfd_boolean
991+
parse_rvp_field (const char **str, char name[RVP_MAX_KEYWORD_LEN])
992+
{
993+
char *p = name;
994+
const char *str_t;
995+
996+
str_t = *str;
997+
str_t--;
998+
while (ISALNUM (*str_t) || *str_t == '.' || *str_t == '_')
999+
*p++ = *str_t++;
1000+
*p = '\0';
1001+
1002+
if (strncmp (name, "nds_", 4) == 0)
1003+
{
1004+
*str = str_t;
1005+
return TRUE;
1006+
}
1007+
else
1008+
return FALSE;
1009+
}
1010+
9761011
/* For consistency checking, verify that all bits are specified either
9771012
by the match/mask part of the instruction definition, or by the
9781013
operand list. The `length` could be 0, 4 or 8, 0 for auto detection. */
@@ -1083,6 +1118,7 @@ validate_riscv_insn (const struct riscv_opcode *opc, int length)
10831118
case 'P': USE_BITS (OP_MASK_PRED, OP_SH_PRED); break;
10841119
case 'Q': USE_BITS (OP_MASK_SUCC, OP_SH_SUCC); break;
10851120
case 'o': /* ITYPE immediate, load displacement. */
1121+
case 'l': /* IMM6L */
10861122
case 'j': used_bits |= ENCODE_ITYPE_IMM (-1U); break;
10871123
case 'a': used_bits |= ENCODE_JTYPE_IMM (-1U); break;
10881124
case 'p': used_bits |= ENCODE_BTYPE_IMM (-1U); break;
@@ -1118,6 +1154,40 @@ validate_riscv_insn (const struct riscv_opcode *opc, int length)
11181154
return FALSE;
11191155
}
11201156
break;
1157+
case 'n':
1158+
{
1159+
char field_name[RVP_MAX_KEYWORD_LEN];
1160+
if (parse_rvp_field (&p, field_name))
1161+
{
1162+
if (strcmp (field_name, "nds_rc") == 0)
1163+
USE_BITS (OP_MASK_RC, OP_SH_RC);
1164+
else if (strcmp (field_name, "nds_rdp") == 0)
1165+
USE_BITS (OP_MASK_RD, OP_SH_RD);
1166+
else if (strcmp (field_name, "nds_rsp") == 0)
1167+
USE_BITS (OP_MASK_RD, OP_SH_RS1);
1168+
else if (strcmp (field_name, "nds_rtp") == 0)
1169+
USE_BITS (OP_MASK_RD, OP_SH_RS2);
1170+
else if (strcmp (field_name, "nds_i3u") == 0)
1171+
used_bits |= ENCODE_PTYPE_IMM3U (-1U);
1172+
else if (strcmp (field_name, "nds_i4u") == 0)
1173+
used_bits |= ENCODE_PTYPE_IMM4U (-1U);
1174+
else if (strcmp (field_name, "nds_i5u") == 0)
1175+
used_bits |= ENCODE_PTYPE_IMM5U (-1U);
1176+
else if (strcmp (field_name, "nds_i6u") == 0)
1177+
used_bits |= ENCODE_PTYPE_IMM6U (-1U);
1178+
else if (strcmp (field_name, "nds_i15s") == 0)
1179+
used_bits |= ENCODE_PTYPE_IMM15S (-1U);
1180+
else
1181+
as_bad (_("internal: bad RISC-V opcode "
1182+
"(unknown operand type `%s'): %s %s"),
1183+
field_name, opc->name, opc->args);
1184+
}
1185+
else
1186+
as_bad (_("internal: bad RISC-V opcode "
1187+
"(unknown operand type `%c'): %s %s"),
1188+
c, opc->name, opc->args);
1189+
}
1190+
break;
11211191
default:
11221192
as_bad (_("internal: bad RISC-V opcode "
11231193
"(unknown operand type `%c'): %s %s"),
@@ -2402,6 +2472,17 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
24022472
}
24032473
continue;
24042474

2475+
case 'l':
2476+
my_getExpression (imm_expr, s);
2477+
if (imm_expr->X_op != O_constant
2478+
|| imm_expr->X_add_number >= xlen
2479+
|| imm_expr->X_add_number < 0)
2480+
break;
2481+
ip->insn_opcode |= ENCODE_ITYPE_IMM6L (imm_expr->X_add_number);
2482+
s = expr_end;
2483+
imm_expr->X_op = O_absent;
2484+
continue;
2485+
24052486
case 'm': /* Rounding mode. */
24062487
if (arg_lookup (&s, riscv_rm, ARRAY_SIZE (riscv_rm), &regno))
24072488
{
@@ -2410,6 +2491,91 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
24102491
}
24112492
break;
24122493

2494+
case 'n':
2495+
{
2496+
char field_name[RVP_MAX_KEYWORD_LEN];
2497+
args++;
2498+
if (parse_rvp_field (&args, field_name))
2499+
{
2500+
if (strcmp (field_name, "nds_rc") == 0
2501+
&& reg_lookup (&s, RCLASS_GPR, &regno))
2502+
{
2503+
INSERT_OPERAND (RC, *ip, regno);
2504+
args--;
2505+
continue;
2506+
}
2507+
else if (strcmp (field_name, "nds_rdp") == 0
2508+
&& reg_lookup (&s, RCLASS_GPR, &regno))
2509+
{
2510+
if (xlen == 32 && (regno % 2) != 0)
2511+
{
2512+
as_bad (_("the number of Rd must be even "
2513+
"(limitation of register pair)"));
2514+
break;
2515+
}
2516+
INSERT_OPERAND (RD, *ip, regno);
2517+
args--;
2518+
continue;
2519+
}
2520+
else if (strcmp (field_name, "nds_rsp") == 0
2521+
&& reg_lookup (&s, RCLASS_GPR, &regno))
2522+
{
2523+
if (xlen == 32 && (regno % 2) != 0)
2524+
{
2525+
as_bad (_("the number of Rs1 must be even "
2526+
"(limitation of register pair)"));
2527+
break;
2528+
}
2529+
INSERT_OPERAND (RS1, *ip, regno);
2530+
args--;
2531+
continue;
2532+
}
2533+
else if (strcmp (field_name, "nds_rtp") == 0
2534+
&& reg_lookup (&s, RCLASS_GPR, &regno))
2535+
{
2536+
if (xlen == 32 && (regno % 2) != 0)
2537+
{
2538+
as_bad (_("the number of Rs2 must be even "
2539+
"(limitation of register pair)"));
2540+
break;
2541+
}
2542+
INSERT_OPERAND (RS2, *ip, regno);
2543+
args--;
2544+
continue;
2545+
}
2546+
2547+
my_getExpression (imm_expr, s);
2548+
if (imm_expr->X_op != O_constant
2549+
|| imm_expr->X_add_number >= xlen
2550+
|| imm_expr->X_add_number < 0)
2551+
break;
2552+
2553+
if (strcmp (field_name, "nds_i3u") == 0
2554+
&& VALID_PTYPE_IMM3U (imm_expr->X_add_number))
2555+
ip->insn_opcode |= ENCODE_PTYPE_IMM3U (imm_expr->X_add_number);
2556+
else if (strcmp (field_name, "nds_i4u") == 0
2557+
&& VALID_PTYPE_IMM4U (imm_expr->X_add_number))
2558+
ip->insn_opcode |= ENCODE_PTYPE_IMM4U (imm_expr->X_add_number);
2559+
else if (strcmp (field_name, "nds_i5u") == 0
2560+
&& VALID_PTYPE_IMM5U (imm_expr->X_add_number))
2561+
ip->insn_opcode |= ENCODE_PTYPE_IMM5U (imm_expr->X_add_number);
2562+
else if (strcmp (field_name, "nds_i6u") == 0
2563+
&& VALID_PTYPE_IMM6U (imm_expr->X_add_number))
2564+
ip->insn_opcode |= ENCODE_PTYPE_IMM6U (imm_expr->X_add_number);
2565+
else if (strcmp (field_name, "nds_i15s") == 0
2566+
&& VALID_PTYPE_IMM15S (imm_expr->X_add_number))
2567+
ip->insn_opcode |= ENCODE_PTYPE_IMM15S (imm_expr->X_add_number);
2568+
else
2569+
break;
2570+
2571+
s = expr_end;
2572+
imm_expr->X_op = O_absent;
2573+
args--;
2574+
continue;
2575+
}
2576+
break;
2577+
}
2578+
24132579
case 'P':
24142580
case 'Q': /* Fence predecessor/successor. */
24152581
if (arg_lookup (&s, riscv_pred_succ, ARRAY_SIZE (riscv_pred_succ),

0 commit comments

Comments
 (0)