aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Selyutin <ghostmansd@gmail.com>2022-05-12 10:32:11 +0300
committerAlan Modra <amodra@gmail.com>2022-05-25 12:13:44 +0930
commit8e5eb8e1b0cb2a408008a3e40e571f193917dcc8 (patch)
tree57e88dbca3937b38a3dcb22cb7a316b27e5773c9
parentf59e7b128933d96b53ee948ab306334e87b2f03c (diff)
downloadgdb-8e5eb8e1b0cb2a408008a3e40e571f193917dcc8.zip
gdb-8e5eb8e1b0cb2a408008a3e40e571f193917dcc8.tar.gz
gdb-8e5eb8e1b0cb2a408008a3e40e571f193917dcc8.tar.bz2
ppc: extend opindex to 16 bits
With the upcoming SVP64 extension[0] to PowerPC architecture, it became evident that PowerPC operand indices no longer fit 8 bits. This patch switches the underlying type to uint16_t, also introducing a special typedef so that any future extension goes even smoother. [0] https://libre-soc.org include/ * opcode/ppc.h (ppc_opindex_t): New typedef. (struct powerpc_opcode): Use it. (PPC_OPINDEX_MAX): Define. gas/ * write.h (struct fix): Increase size of fx_pcrel_adjust. Reorganise. * config/tc-ppc.c (insn_validate): Use ppc_opindex_t for operands. (md_assemble): Likewise. (md_apply_fix): Likewise. Mask fx_pcrel_adjust with PPC_OPINDEX_MAX. (ppc_setup_opcodes): Adjust opcode index assertion. opcodes/ * ppc-dis.c (skip_optional_operands): Use ppc_opindex_t for operand pointer. (lookup_powerpc, lookup_prefix, lookup_vle, lookup_spe2): Likewise. (print_insn_powerpc): Likewise.
-rw-r--r--gas/config/tc-ppc.c12
-rw-r--r--gas/write.h18
-rw-r--r--include/opcode/ppc.h8
-rw-r--r--opcodes/ppc-dis.c12
4 files changed, 30 insertions, 20 deletions
diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c
index 72128af..4d789fd 100644
--- a/gas/config/tc-ppc.c
+++ b/gas/config/tc-ppc.c
@@ -1553,7 +1553,7 @@ ppc_target_format (void)
static bool
insn_validate (const struct powerpc_opcode *op)
{
- const unsigned char *o;
+ const ppc_opindex_t *o;
uint64_t omask = op->mask;
/* The mask had better not trim off opcode bits. */
@@ -1634,8 +1634,8 @@ ppc_setup_opcodes (void)
unsigned int i;
/* An index into powerpc_operands is stored in struct fix
- fx_pcrel_adjust which is 8 bits wide. */
- gas_assert (num_powerpc_operands < 256);
+ fx_pcrel_adjust which is a 16 bit field. */
+ gas_assert (num_powerpc_operands <= PPC_OPINDEX_MAX + 1);
/* Check operand masks. Code here and in the disassembler assumes
all the 1's in the mask are contiguous. */
@@ -3251,7 +3251,7 @@ md_assemble (char *str)
char *s;
const struct powerpc_opcode *opcode;
uint64_t insn;
- const unsigned char *opindex_ptr;
+ const ppc_opindex_t *opindex_ptr;
int need_paren;
int next_opindex;
struct ppc_fixup fixups[MAX_INSN_FIXUPS];
@@ -3348,7 +3348,7 @@ md_assemble (char *str)
{
if (num_optional_operands == 0)
{
- const unsigned char *optr;
+ const ppc_opindex_t *optr;
int total = 0;
int provided = 0;
int omitted;
@@ -7011,7 +7011,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg)
if (fixP->fx_pcrel_adjust != 0)
{
/* This is a fixup on an instruction. */
- int opindex = fixP->fx_pcrel_adjust & 0xff;
+ ppc_opindex_t opindex = fixP->fx_pcrel_adjust & PPC_OPINDEX_MAX;
operand = &powerpc_operands[opindex];
#ifdef OBJ_XCOFF
diff --git a/gas/write.h b/gas/write.h
index 501bdd8..3e31342 100644
--- a/gas/write.h
+++ b/gas/write.h
@@ -52,6 +52,16 @@ struct fix
/* These small fields are grouped together for compactness of
this structure, and efficiency of access on some architectures. */
+ /* pc-relative offset adjust (only used by some CPU specific code).
+ A 4-bit field would be sufficient for most uses, except for ppc
+ which pokes an operand table index here. Bits may be stolen
+ from here should that be necessary, provided PPC_OPINDEX_MAX is
+ adjusted suitably. */
+ int fx_pcrel_adjust : 16;
+
+ /* How many bytes are involved? */
+ unsigned fx_size : 8;
+
/* Is this a pc-relative relocation? */
unsigned fx_pcrel : 1;
@@ -73,13 +83,7 @@ struct fix
unsigned fx_tcbit2 : 1;
/* Spare bits. */
- unsigned fx_unused : 10;
-
- /* pc-relative offset adjust (only used by some CPU specific code) */
- int fx_pcrel_adjust : 8;
-
- /* How many bytes are involved? */
- unsigned fx_size : 8;
+ unsigned fx_unused : 2;
bfd_reloc_code_real_type fx_r_type;
diff --git a/include/opcode/ppc.h b/include/opcode/ppc.h
index a9c2529..7bc6ee2 100644
--- a/include/opcode/ppc.h
+++ b/include/opcode/ppc.h
@@ -29,6 +29,12 @@ extern "C" {
#endif
typedef uint64_t ppc_cpu_t;
+typedef uint16_t ppc_opindex_t;
+
+/* Smaller of ppc_opindex_t and fx_pcrel_adjust maximum. Note that
+ values extracted from fx_pcrel_adjust are masked with this constant,
+ effectively making the field unsigned. */
+#define PPC_OPINDEX_MAX 0xffff
/* The opcode table is an array of struct powerpc_opcode. */
@@ -60,7 +66,7 @@ struct powerpc_opcode
/* An array of operand codes. Each code is an index into the
operand table. They appear in the order which the operands must
appear in assembly code, and are terminated by a zero. */
- unsigned char operands[8];
+ ppc_opindex_t operands[8];
};
/* The table itself is sorted by major opcode number, and is otherwise
diff --git a/opcodes/ppc-dis.c b/opcodes/ppc-dis.c
index 38ddeca..45e8fae 100644
--- a/opcodes/ppc-dis.c
+++ b/opcodes/ppc-dis.c
@@ -546,7 +546,7 @@ operand_value_powerpc (const struct powerpc_operand *operand,
/* Determine whether the optional operand(s) should be printed. */
static bool
-skip_optional_operands (const unsigned char *opindex,
+skip_optional_operands (const ppc_opindex_t *opindex,
uint64_t insn, ppc_cpu_t dialect, bool *is_pcrel)
{
const struct powerpc_operand *operand;
@@ -592,7 +592,7 @@ lookup_powerpc (uint64_t insn, ppc_cpu_t dialect)
opcode < opcode_end;
++opcode)
{
- const unsigned char *opindex;
+ const ppc_opindex_t *opindex;
const struct powerpc_operand *operand;
int invalid;
@@ -637,7 +637,7 @@ lookup_prefix (uint64_t insn, ppc_cpu_t dialect)
opcode < opcode_end;
++opcode)
{
- const unsigned char *opindex;
+ const ppc_opindex_t *opindex;
const struct powerpc_operand *operand;
int invalid;
@@ -691,7 +691,7 @@ lookup_vle (uint64_t insn, ppc_cpu_t dialect)
uint64_t table_mask = opcode->mask;
bool table_op_is_short = PPC_OP_SE_VLE(table_mask);
uint64_t insn2;
- const unsigned char *opindex;
+ const ppc_opindex_t *opindex;
const struct powerpc_operand *operand;
int invalid;
@@ -746,7 +746,7 @@ lookup_spe2 (uint64_t insn, ppc_cpu_t dialect)
uint64_t table_opcd = opcode->opcode;
uint64_t table_mask = opcode->mask;
uint64_t insn2;
- const unsigned char *opindex;
+ const ppc_opindex_t *opindex;
const struct powerpc_operand *operand;
int invalid;
@@ -925,7 +925,7 @@ print_insn_powerpc (bfd_vma memaddr,
if (opcode != NULL)
{
- const unsigned char *opindex;
+ const ppc_opindex_t *opindex;
const struct powerpc_operand *operand;
enum {
need_comma = 0,