diff options
author | Alan Modra <amodra@gmail.com> | 2018-08-16 16:14:12 +0930 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2018-08-21 16:05:36 +0930 |
commit | 9cf7e5687f823a1009d25cb25ff653ee8372e517 (patch) | |
tree | 33fc95350dcbe996766c532ed4349dba4d01e4a0 /opcodes/ppc-dis.c | |
parent | 46807bf45106af5523ad06cf84e7b825dcb9f089 (diff) | |
download | gdb-9cf7e5687f823a1009d25cb25ff653ee8372e517.zip gdb-9cf7e5687f823a1009d25cb25ff653ee8372e517.tar.gz gdb-9cf7e5687f823a1009d25cb25ff653ee8372e517.tar.bz2 |
Use operand->extract to provide defaults for optional PowerPC operands
Most optional operands to powerpc instructions use a default value of
zero, but there are a few exceptions. Those have been handled by
PPC_OPERAND_OPTIONAL_VALUE and an entry in the powerpc_operands table
for the default value, smuggled in the shift field. This patch
changes that to using the operand extract function to provide non-zero
defaults.
I've also moved the code determining whether optional operands are
provided or omitted, to the point the first optional operand is seen,
and allowed for the possibility of optional base register operands
in a future patch.
The patch does change the error you get on invalid assembly like
ld 3,4
You'll now see "missing operand" rather than
"syntax error; end of line, expected `('".
gas/
* config/tc-ppc.c (md_assemble): Delay counting of optional
operands until one is encountered. Allow for the possibility
of optional base regs, ie. PPC_OPERAND_PARENS. Call
ppc_optional_operand_value with extra args.
include/
* opcode/ppc.h (struct powerpc_operand): Correct "insert" comment.
Mention use of "extract" function to provide default value.
(PPC_OPERAND_OPTIONAL_VALUE): Delete.
(ppc_optional_operand_value): Rewrite to use extract function.
opcodes/
* ppc-dis.c (operand_value_powerpc): Init "invalid".
(skip_optional_operands): Count optional operands, and update
ppc_optional_operand_value call.
* ppc-opc.c (extract_dxdn): Remove ATTRIBUTE_UNUSED from used arg.
(extract_vlensi): Likewise.
(extract_fxm): Return default value for missing optional operand.
(extract_ls, extract_raq, extract_tbr): Likewise.
(insert_sxl, extract_sxl): New functions.
(insert_esync, extract_esync): Remove Power9 handling and simplify.
(powerpc_operands <FXM4, TBR>): Delete PPC_OPERAND_OPTIONAL_VALUE
flag and extra entry.
(powerpc_operands <SXL>): Likewise, and use insert_sxl and
extract_sxl.
Diffstat (limited to 'opcodes/ppc-dis.c')
-rw-r--r-- | opcodes/ppc-dis.c | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/opcodes/ppc-dis.c b/opcodes/ppc-dis.c index 035767c..adbd124 100644 --- a/opcodes/ppc-dis.c +++ b/opcodes/ppc-dis.c @@ -451,7 +451,7 @@ operand_value_powerpc (const struct powerpc_operand *operand, uint64_t insn, ppc_cpu_t dialect) { int64_t value; - int invalid; + int invalid = 0; /* Extract the value from the instruction. */ if (operand->extract) value = (*operand->extract) (insn, dialect, &invalid); @@ -484,15 +484,22 @@ skip_optional_operands (const unsigned char *opindex, uint64_t insn, ppc_cpu_t dialect) { const struct powerpc_operand *operand; + int num_optional; - for (; *opindex != 0; opindex++) + for (num_optional = 0; *opindex != 0; opindex++) { operand = &powerpc_operands[*opindex]; - if ((operand->flags & PPC_OPERAND_NEXT) != 0 - || ((operand->flags & PPC_OPERAND_OPTIONAL) != 0 - && operand_value_powerpc (operand, insn, dialect) != - ppc_optional_operand_value (operand))) + if ((operand->flags & PPC_OPERAND_NEXT) != 0) return 0; + if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0) + { + /* Negative count is used as a flag to extract function. */ + --num_optional; + if (operand_value_powerpc (operand, insn, dialect) + != ppc_optional_operand_value (operand, insn, dialect, + num_optional)) + return 0; + } } return 1; |