mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-24 18:44:20 +08:00
RISC-V: Allocate "various" operand type
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.
This commit is contained in:
parent
6967633c8b
commit
54bca63b5c
@ -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. */
|
||||
@ -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;
|
||||
@ -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. */
|
||||
{
|
||||
@ -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'"),
|
||||
|
@ -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);
|
||||
@ -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;
|
||||
|
@ -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. */
|
||||
|
Loading…
Reference in New Issue
Block a user