diff options
author | Nelson Chu <nelson.chu@sifive.com> | 2021-03-16 17:23:23 +0800 |
---|---|---|
committer | Nelson Chu <nelson.chu@sifive.com> | 2021-10-28 08:48:42 +0800 |
commit | 5a2f56d1ae112dd71230ab09cb3a0be98cee88e1 (patch) | |
tree | c48fdbe551f6ecdfb2f69d82000300ccf2e5707e /include | |
parent | 28c26ce5fddaf21692c077b5b366a95bce991d64 (diff) | |
download | gdb-5a2f56d1ae112dd71230ab09cb3a0be98cee88e1.zip gdb-5a2f56d1ae112dd71230ab09cb3a0be98cee88e1.tar.gz gdb-5a2f56d1ae112dd71230ab09cb3a0be98cee88e1.tar.bz2 |
RISC-V/extended: Add assembler and dis-assembler hooks for extended extensions.
To keep the original functions clean, we try to provide assembler
and dis-assembler hooks as enough as possible for extended extensions.
We probably need to add more once they are not enough in the future.
However, there are several changes that might need to be discussed
as follows,
* Change the type of enums to int directly, to extend them for
extended extensions. Not sure if the change is good enough, but
it should be the easiler way to extend enums.
* The extended operands should be parsed in the extended hooks,
validate_riscv_extended_insn and riscv_parse_extended_operands.
Obviously, we may need to reparse the opernad string in the extended
hooks, when the original functions cannot recognize them. But the
original functions have already pointed the parsed poniter to the
next characters. Therefore, we should use a new pointer, opargStart,
to record the position before parsing, and then pass it to the hooks
when we need to reparse the extended operands.
* Part of the "internal: unknown" errors are reported in the extended
hooks rather than the original functions. For example, we used to
report the "internal: unreachable" in the riscv_multi_subset_supports,
to tell developers that they forgot to handle the new defined INSN_CLASS_.
And the function returns TRUE/FALSE if the instruction is allowed or not
according to the architecture string. The riscv_extended_subset_supports
is the extended hook of riscv_multi_subset_supports, so it also returns
a bfd_boolean to check the same thing. But it is hard to know if the
INSN_CLASS_* is unknown from the same returned bfd_boolean, unless we add
another new flag, or we just move the error report to the hook directly.
I choose the latter for now, but it may cause the code of mainline and
integration branches are inconsistent, which may affect the difficulty
of the regular merge between these two branches.
The same inconsistent problem also happens in riscv_parse_extended_operands.
The hook only parse an operand rather than all, so it just has a switch
without a for loop. We used to set "continue" to skip the loop in the
switch, but the extended hook doesn't need the "continue". Perhaps we
should use a single while/for in the hooks to keep the code consistent,
then the regular merge may be more easiler.
* Rename the variables to the more meaningful names in the riscv_ip,
validate_riscv_insn and print_insn_args.
- oparg: Renamed from args, means the arguments in the opcode table.
- opargStart: Added to record the start of the argument.
- asarg: Renamed from s, means the arguments of assembly string.
- asargStart: Renamed from argsStart.
* Extract the part that parsing the instruction opcode from the
riscv_disassemble_insn, since we will need to call it for many times
to search multiple opcode tables.
gas/
* config/tc-riscv.c (enum EXTENDED_EXT_NUM): Added to choose the
right extended opcode hashes in the riscv_find_extended_opcode_hash.
(enum riscv_csr_class): Added CSR_CLASS_EXTENDED.
(enum reg_class): Added RCLASS_EXTENDED_NUM.
(enum reg_extended_class): Added to define extended registers.
(struct riscv_csr_extra): Changed enum riscv_csr_class to int,
to increase the expandability of enum.
(riscv_init_csr_hash): Likewise.
(riscv_find_opcode_hash): Handle more than one opcode hashes.
(md_begin): Included riscv-opc-extended.h to define extended CSR.
(init_ext_version_hash): Updated.
(riscv_get_default_ext_version): Likewise.
(md_assemble): Likewise.
(s_riscv_insn): Likewsie.
(riscv_after_parse_args): Likewise.
(riscv_find_extended_opcode_hash): Extended hook for
riscv_find_opcode_hash.
(riscv_extended_subset_supports): Extended hook for
riscv_multi_subset_supports.
(riscv_extended_csr_class_check): Extended hook for riscv_csr_address,
to check the CSR ISA dependency.
(extended_macro): Extended hook for macro.
(validate_riscv_extended_insn): Extended hook for validate_riscv_insn.
(extended_macro_build): Extended hook for macro_build.
(riscv_parse_extended_operands): Extended hook for riscv_ip.
(riscv_multi_subset_supports): Updated to call extended hook.
(riscv_csr_address): Likewise
(macro): Likewise.
(validate_riscv_insn): Likewise. Also define new variables, xxx
and xxxStart, in case single letters are not enough to represent
all extended operands.
(macro_build): Likewise.
(riscv_ip): Likewise. The asarg means assembly operand string,
and oparg means operand string defined in the opcode table.
* testsuite/gas/riscv/extended/extended.exp: New file to run
extended testcases.
include/
* opcode/riscv-opc-extended.h: New file to define encoding macros
and CSR for extended extensions.
* opcode/riscv.h: Included riscv-opc-extended.h.
(enum riscv_insn_class): Added INSN_CLASS_EXTENDED.
(struct riscv_opcode): Same as struct riscv_csr_extra.
(enum M_EXTENDED): Added to support extended pseudo macros.
opcode/
* riscv-dis.c (print_extended_insn_args): Extended hook for
print_insn_args.
(print_insn_args): Updated to call extended hook, and same as
what validate_riscv_insn does. Also include riscv-opc-extended.h
to show extended CSR correctly.
* riscv-opc.c (riscv_extended_opcodes): Added to store all
supported extended instruction opcodes.
Diffstat (limited to 'include')
-rw-r--r-- | include/opcode/riscv-opc-extended.h | 22 | ||||
-rw-r--r-- | include/opcode/riscv.h | 11 |
2 files changed, 30 insertions, 3 deletions
diff --git a/include/opcode/riscv-opc-extended.h b/include/opcode/riscv-opc-extended.h new file mode 100644 index 0000000..c9c292a --- /dev/null +++ b/include/opcode/riscv-opc-extended.h @@ -0,0 +1,22 @@ +/* riscv-opcextended.h. RISC-V extended instruction opcode. + Copyright (C) 2021 Free Software Foundation, Inc. + + This file is part of GDB, GAS, and the GNU binutils. + + GDB, GAS, and the GNU binutils are free software; you can redistribute + them and/or modify them under the terms of the GNU General Public + License as published by the Free Software Foundation; either version + 3, or (at your option) any later version. + + GDB, GAS, and the GNU binutils are distributed in the hope that they + will be useful, but WITHOUT ANY WARRANTY; without even the implied + warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING3. If not, + see <http://www.gnu.org/licenses/>. */ + +#ifndef RISCV_EXTENDED_ENCODING_H +#define RISCV_EXTENDED_ENCODING_H +#endif /* RISCV_EXTENDED_ENCODING_H */ diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h index afcd41f..a336eb4 100644 --- a/include/opcode/riscv.h +++ b/include/opcode/riscv.h @@ -22,6 +22,7 @@ #define _RISCV_H_ #include "riscv-opc.h" +#include "riscv-opc-extended.h" #include <stdlib.h> #include <stdint.h> @@ -303,7 +304,6 @@ static const char * const riscv_pred_succ[16] = enum riscv_insn_class { INSN_CLASS_NONE, - INSN_CLASS_I, INSN_CLASS_C, INSN_CLASS_A, @@ -320,6 +320,7 @@ enum riscv_insn_class INSN_CLASS_ZBB, INSN_CLASS_ZBC, INSN_CLASS_ZBS, + INSN_CLASS_EXTENDED }; /* This structure holds information for a particular instruction. */ @@ -333,7 +334,7 @@ struct riscv_opcode /* Class to which this instruction belongs. Used to decide whether or not this instruction is legal in the current -march context. */ - enum riscv_insn_class insn_class; + int insn_class; /* A string describing the arguments for this instruction. */ const char *args; @@ -423,7 +424,7 @@ enum M_ZEXTW, M_SEXTB, M_SEXTH, - M_NUM_MACROS + M_EXTENDED }; /* The mapping symbol states. */ @@ -442,4 +443,8 @@ extern const char * const riscv_fpr_names_abi[NFPR]; extern const struct riscv_opcode riscv_opcodes[]; extern const struct riscv_opcode riscv_insn_types[]; +/* Extended extensions. */ + +extern const struct riscv_opcode *riscv_extended_opcodes[]; + #endif /* _RISCV_H_ */ |