Skip to content

Commit

Permalink
RISC-V: Allocate "various" operand type
Browse files Browse the repository at this point in the history
This commit intends to move operands that require very special handling or
operand types that are so minor (e.g. only useful on a few instructions)
under "W".  I also intend this "W" to be "temporary" operand storage until
we can find good two character (or less) operand type.

In this commit, prefetch offset operand "f" for 'Zicbop' extension is moved
to "Wif" because of its special handling (and allocating single character
"f" for this operand type seemed too much).

Current expected allocation guideline is as follows:

1.  'W'
2.  The most closely related single-letter extension in lowercase
    (strongly recommended but not mandatory)
3.  Identify operand type

The author currently plans to allocate following three-character operand
types (for operands including instructions from unratified extensions).

1.  "Wif" ('Zicbop': fetch offset)
2.  "Wfv" (unratified 'Zfa': value operand from FLI.[HSDQ] instructions)
3.  "Wfm" / "WfM"
    'Zfh', 'F', 'D', 'Q': rounding modes "m" with special handling
                          solely for widening conversion instructions.

gas/ChangeLog:

	* config/tc-riscv.c (validate_riscv_insn, riscv_ip): Move from
	"f" to "Wif".

opcodes/ChangeLog:

	* riscv-dis.c (print_insn_args): Move from "f" to "Wif".
	* riscv-opc.c (riscv_opcodes): Reflect new operand type.
  • Loading branch information
a4lg authored and ptomsich committed Mar 31, 2023
1 parent 6967633 commit 54bca63
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 25 deletions.
64 changes: 47 additions & 17 deletions gas/config/tc-riscv.c
Original file line number Diff line number Diff line change
Expand Up @@ -1362,7 +1362,6 @@ validate_riscv_insn (const struct riscv_opcode *opc, int length)
case 'j': used_bits |= ENCODE_ITYPE_IMM (-1U); break;
case 'a': used_bits |= ENCODE_JTYPE_IMM (-1U); break;
case 'p': used_bits |= ENCODE_BTYPE_IMM (-1U); break;
case 'f': /* Fall through. */
case 'q': used_bits |= ENCODE_STYPE_IMM (-1U); break;
case 'u': used_bits |= ENCODE_UTYPE_IMM (-1U); break;
case 'z': break; /* Zero immediate. */
Expand All @@ -1389,6 +1388,21 @@ validate_riscv_insn (const struct riscv_opcode *opc, int length)
goto unknown_validate_operand;
}
break;
case 'W': /* Various operands. */
switch (*++oparg)
{
case 'i':
switch (*++oparg)
{
case 'f': used_bits |= ENCODE_STYPE_IMM (-1U); break;
default:
goto unknown_validate_operand;
}
break;
default:
goto unknown_validate_operand;
}
break;
case 'X': /* Integer immediate. */
{
size_t n;
Expand Down Expand Up @@ -3420,22 +3434,37 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
imm_expr->X_op = O_absent;
continue;

case 'f': /* Prefetch offset, pseudo S-type but lower 5-bits zero. */
if (riscv_handle_implicit_zero_offset (imm_expr, asarg))
continue;
my_getExpression (imm_expr, asarg);
check_absolute_expr (ip, imm_expr, false);
if (((unsigned) (imm_expr->X_add_number) & 0x1fU)
|| imm_expr->X_add_number >= (signed) RISCV_IMM_REACH / 2
|| imm_expr->X_add_number < -(signed) RISCV_IMM_REACH / 2)
as_bad (_("improper prefetch offset (%ld)"),
(long) imm_expr->X_add_number);
ip->insn_opcode |=
ENCODE_STYPE_IMM ((unsigned) (imm_expr->X_add_number) &
~ 0x1fU);
imm_expr->X_op = O_absent;
asarg = expr_parse_end;
continue;
case 'W': /* Various operands. */
switch (*++oparg)
{
case 'i':
switch (*++oparg)
{
case 'f':
/* Prefetch offset for 'Zicbop' extension.
pseudo S-type but lower 5-bits zero. */
if (riscv_handle_implicit_zero_offset (imm_expr, asarg))
continue;
my_getExpression (imm_expr, asarg);
check_absolute_expr (ip, imm_expr, false);
if (((unsigned) (imm_expr->X_add_number) & 0x1fU)
|| imm_expr->X_add_number >= RISCV_IMM_REACH / 2
|| imm_expr->X_add_number < -RISCV_IMM_REACH / 2)
as_bad (_ ("improper prefetch offset (%ld)"),
(long) imm_expr->X_add_number);
ip->insn_opcode |= ENCODE_STYPE_IMM (
(unsigned) (imm_expr->X_add_number) & ~0x1fU);
imm_expr->X_op = O_absent;
asarg = expr_parse_end;
continue;
default:
goto unknown_riscv_ip_operand;
}
break;
default:
goto unknown_riscv_ip_operand;
}
break;

case 'X': /* Integer immediate. */
{
Expand Down Expand Up @@ -3488,6 +3517,7 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
}
}
break;

default:
unknown_riscv_ip_operand:
as_fatal (_("internal: unknown argument type `%s'"),
Expand Down
26 changes: 21 additions & 5 deletions opcodes/riscv-dis.c
Original file line number Diff line number Diff line change
Expand Up @@ -473,11 +473,6 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
(int)EXTRACT_STYPE_IMM (l));
break;

case 'f':
print (info->stream, dis_style_address_offset, "%d",
(int)EXTRACT_STYPE_IMM (l));
break;

case 'a':
info->target = EXTRACT_JTYPE_IMM (l) + pc;
(*info->print_address_func) (info->target, info);
Expand Down Expand Up @@ -582,6 +577,27 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
print (info->stream, dis_style_immediate, "%d", rs1);
break;

case 'W': /* Various operands. */
{
switch (*++oparg)
{
case 'i':
switch (*++oparg)
{
case 'f':
print (info->stream, dis_style_address_offset, "%d",
(int) EXTRACT_STYPE_IMM (l));
break;
default:
goto undefined_modifier;
}
break;
default:
goto undefined_modifier;
}
}
break;

case 'X': /* Integer immediate. */
{
size_t n;
Expand Down
6 changes: 3 additions & 3 deletions opcodes/riscv-opc.c
Original file line number Diff line number Diff line change
Expand Up @@ -313,9 +313,9 @@ const struct riscv_opcode riscv_opcodes[] =
/* name, xlen, isa, operands, match, mask, match_func, pinfo. */

/* Standard hints. */
{"prefetch.i", 0, INSN_CLASS_ZICBOP, "f(s)", MATCH_PREFETCH_I, MASK_PREFETCH_I, match_opcode, 0 },
{"prefetch.r", 0, INSN_CLASS_ZICBOP, "f(s)", MATCH_PREFETCH_R, MASK_PREFETCH_R, match_opcode, 0 },
{"prefetch.w", 0, INSN_CLASS_ZICBOP, "f(s)", MATCH_PREFETCH_W, MASK_PREFETCH_W, match_opcode, 0 },
{"prefetch.i", 0, INSN_CLASS_ZICBOP, "Wif(s)", MATCH_PREFETCH_I, MASK_PREFETCH_I, match_opcode, 0 },
{"prefetch.r", 0, INSN_CLASS_ZICBOP, "Wif(s)", MATCH_PREFETCH_R, MASK_PREFETCH_R, match_opcode, 0 },
{"prefetch.w", 0, INSN_CLASS_ZICBOP, "Wif(s)", MATCH_PREFETCH_W, MASK_PREFETCH_W, match_opcode, 0 },
{"pause", 0, INSN_CLASS_ZIHINTPAUSE, "", MATCH_PAUSE, MASK_PAUSE, match_opcode, 0 },

/* Basic RVI instructions and aliases. */
Expand Down

0 comments on commit 54bca63

Please sign in to comment.