/* ppc.h -- Header file for PowerPC opcode table
- Copyright (C) 1994-2018 Free Software Foundation, Inc.
+ Copyright (C) 1994-2020 Free Software Foundation, Inc.
Written by Ian Lance Taylor, Cygnus Support
This file is part of GDB, GAS, and the GNU binutils.
typedef uint64_t ppc_cpu_t;
-#if BFD_HOST_64BIT_LONG
-# define PPC_INT_FMT "l"
-#elif defined (__MSVCRT__)
-# define PPC_INT_FMT "I64"
-#else
-# define PPC_INT_FMT "ll"
-#endif
-
/* The opcode table is an array of struct powerpc_opcode. */
struct powerpc_opcode
instructions. */
extern const struct powerpc_opcode powerpc_opcodes[];
extern const unsigned int powerpc_num_opcodes;
+extern const struct powerpc_opcode prefix_opcodes[];
+extern const unsigned int prefix_num_opcodes;
extern const struct powerpc_opcode vle_opcodes[];
extern const unsigned int vle_num_opcodes;
extern const struct powerpc_opcode spe2_opcodes[];
/* Opcode is supported by EFS2. */
#define PPC_OPCODE_EFS2 0x200000000000ull
+/* Opcode is only supported by powerxx architecture. */
+#define PPC_OPCODE_POWERXX 0x400000000000ull
+
/* A macro to extract the major opcode from an instruction. */
#define PPC_OP(i) (((i) >> 26) & 0x3f)
/* A macro to convert a SPE2 extended opcode to a SPE2 xopcode segment. */
#define SPE2_XOP_TO_SEG(i) ((i) >> 7)
+
+/* A macro to extract the prefix word from an 8-byte PREFIX instruction. */
+#define PPC_GET_PREFIX(i) (((i) >> 32) & ((1LL << 32) - 1))
+
+/* A macro to extract the suffix word from an 8-byte PREFIX instruction. */
+#define PPC_GET_SUFFIX(i) ((i) & ((1LL << 32) - 1))
+
+/* A macro to determine whether insn I is an 8-byte prefix instruction. */
+#define PPC_PREFIX_P(i) (PPC_OP (PPC_GET_PREFIX (i)) == 0x1)
+
+/* A macro used to hash 8-byte PREFIX instructions. */
+#define PPC_PREFIX_SEG(i) (PPC_OP (i) >> 1)
+
\f
/* The operands table is an array of struct powerpc_operand. */
If this field is not NULL, then simply call it with the
instruction and the operand value. It will return the new value
- of the instruction. If the ERRMSG argument is not NULL, then if
- the operand value is illegal, *ERRMSG will be set to a warning
- string (the operand will be inserted in any case). If the
- operand value is legal, *ERRMSG will be unchanged (most operands
- can accept any value). */
+ of the instruction. If the operand value is illegal, *ERRMSG
+ will be set to a warning string (the operand will be inserted in
+ any case). If the operand value is legal, *ERRMSG will be
+ unchanged (most operands can accept any value). */
uint64_t (*insert)
(uint64_t instruction, int64_t op, ppc_cpu_t dialect, const char **errmsg);
is the result).
If this field is not NULL, then simply call it with the
- instruction value. It will return the value of the operand. If
- the INVALID argument is not NULL, *INVALID will be set to
- non-zero if this operand type can not actually be extracted from
- this operand (i.e., the instruction does not match). If the
- operand is valid, *INVALID will not be changed. */
+ instruction value. It will return the value of the operand.
+ *INVALID will be set to one by the extraction function if this
+ operand type can not be extracted from this operand (i.e., the
+ instruction does not match). If the operand is valid, *INVALID
+ will not be changed. *INVALID will always be non-negative when
+ used to extract a field from an instruction.
+
+ The extraction function is also called by both the assembler and
+ disassembler if an operand is optional, in which case the
+ function should return the default value of the operand.
+ *INVALID is negative in this case, and is the negative count of
+ omitted optional operands up to and including this operand. */
int64_t (*extract) (uint64_t instruction, ppc_cpu_t dialect, int *invalid);
/* One bit syntax flags. */
#define PPC_OPERAND_CR_BIT (0x20)
/* This is a CR FIELD that does not use symbolic names (unless
- -mregnames is in effect). */
+ -mregnames is in effect). If both PPC_OPERAND_CR_BIT and
+ PPC_OPERAND_CR_REG are set then treat the field as per
+ PPC_OPERAND_CR_BIT for assembly, but as if neither of these
+ bits are set for disassembly. */
#define PPC_OPERAND_CR_REG (0x40)
/* This operand names a special purpose register. */
out regardless of the PPC_OPERAND_OPTIONAL field. */
#define PPC_OPERAND_NEXT (0x100000)
-/* This flag is only used with PPC_OPERAND_OPTIONAL. If this operand
- is omitted, then the value it should use for the operand is stored
- in the SHIFT field of the immediatly following operand field. */
-#define PPC_OPERAND_OPTIONAL_VALUE (0x200000)
-
/* This flag is only used with PPC_OPERAND_OPTIONAL. The operand is
only optional when generating 32-bit code. */
#define PPC_OPERAND_OPTIONAL32 (0x400000)
extern ppc_cpu_t ppc_parse_cpu (ppc_cpu_t, ppc_cpu_t *, const char *);
static inline int64_t
-ppc_optional_operand_value (const struct powerpc_operand *operand)
+ppc_optional_operand_value (const struct powerpc_operand *operand,
+ uint64_t insn,
+ ppc_cpu_t dialect,
+ int num_optional)
{
- if ((operand->flags & PPC_OPERAND_OPTIONAL_VALUE) != 0)
- return (operand+1)->shift;
+ if (operand->extract)
+ return (*operand->extract) (insn, dialect, &num_optional);
return 0;
}
/* PowerPC VLE insns. */
+#define E_OPCODE_MASK 0xfc00f800
+
/* Form I16L, uses 16A relocs. */
#define E_OR2I_INSN 0x7000C000
#define E_AND2I_DOT_INSN 0x7000C800
#define E_CMPH16I_INSN 0x7000B000
#define E_CMPHL16I_INSN 0x7000B800
+#define E_LI_INSN 0x70000000
+#define E_LI_MASK 0xfc008000
+
#ifdef __cplusplus
}
#endif