From 11a0cf2ec0ed6e70ff25e9a50c2223dcd98c1c10 Mon Sep 17 00:00:00 2001 From: Peter Bergner Date: Fri, 19 Jun 2015 17:17:07 -0500 Subject: Allow for optional operands with non-zero default values. ISA 2.07 (ie, POWER8) added the rfebb instruction which takes one operand with the value of either a 0 or 1. It also defines an extended mnemonic with no operands (ie, "rfebb") that is supposed to be equivalent to "rfebb 1". I implemented rfebb's lone operand with PPC_OPERAND_OPTIONAL, but the problem is, optional operands that are ommitted always default to the value 0, which is wrong in this case. I have added support for allowing non-zero default values by adding an additional flag PPC_OPERAND_OPTIONAL_VALUE that specifies that the default operand value to be used is stored in the SHIFT field of the operand field immediately following this one. This fixes the rfebb issue. I also fixed the mftb and mfcr instructions so they use the same mechanism. This allows us to flag invalid uses of mfcr where we explicitly pass in a zero FXM value, like the use in a2.[sd]. include/opcode/ * ppc.h (PPC_OPERAND_OPTIONAL_VALUE): New. (ppc_optional_operand_value): New inline function. opcodes/ * ppc-dis.h (skip_optional_operands): Use ppc_optional_operand_value. * ppc-opc.c (FXM4): Add non-zero optional value. (TBR): Likewise. (SXL): Likewise. (insert_fxm): Handle new default operand value. (extract_fxm): Likewise. (insert_tbr): Likewise. (extract_tbr): Likewise. gas/ * config/tc-ppc.c (md_assemble): Use ppc_optional_operand_value. Allow for optional operands without insert functions. gas/testsuite/ * gas/ppc/power8.d: Fixup rfebb test results. * gas/ppc/a2.s: Fix invalid mfcr test. * gas/ppc/a2.d: Likewise. --- include/opcode/ChangeLog | 5 +++++ include/opcode/ppc.h | 13 +++++++++++++ 2 files changed, 18 insertions(+) (limited to 'include/opcode') diff --git a/include/opcode/ChangeLog b/include/opcode/ChangeLog index 0caabd5..f1b3f1f 100644 --- a/include/opcode/ChangeLog +++ b/include/opcode/ChangeLog @@ -1,3 +1,8 @@ +2015-06-19 Peter Bergner + + * ppc.h (PPC_OPERAND_OPTIONAL_VALUE): New. + (ppc_optional_operand_value): New inline function. + 2015-06-04 Matthew Wahab * aarch64.h (AARCH64_V8_1): New. diff --git a/include/opcode/ppc.h b/include/opcode/ppc.h index 5dc132e..5246365 100644 --- a/include/opcode/ppc.h +++ b/include/opcode/ppc.h @@ -380,6 +380,11 @@ extern const unsigned int num_powerpc_operands; /* This is a CR FIELD that does not use symbolic names. */ #define PPC_OPERAND_CR_REG (0x200000) + +/* 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 (0x400000) /* The POWER and PowerPC assemblers use a few macros. We keep them with the operands table for simplicity. The macro table is an @@ -409,4 +414,12 @@ extern const int powerpc_num_macros; extern ppc_cpu_t ppc_parse_cpu (ppc_cpu_t, ppc_cpu_t *, const char *); +static inline long +ppc_optional_operand_value (const struct powerpc_operand *operand) +{ + if ((operand->flags & PPC_OPERAND_OPTIONAL_VALUE) != 0) + return (operand+1)->shift; + return 0; +} + #endif /* PPC_H */ -- cgit v1.1