PowerPC register expression checks

This stops powerpc gas blithely accepting such nonsense as
"addi %f4,%cr3,%r31".

	PR 21118
gas/
	* NEWS: Mention powerpc register checks.
	* config/tc-ppc.c (struct pd_reg): Make value a short.  Add flags.
	(pre_defined_registers): Delete fpscr and pmr entries.  Set
	register type in flags.
	(cr_names): Set type in flags.
	(reg_name_search): Return pointer to struct pd_reg rather than value.
	(register_name): Adjust to suit.  Set X_md from flags.
	(ppc_parse_name): Likewise.
	(ppc_optimize_expr): New function.
	(md_assemble): Verify expresion reg flags match operand.
	* config/tc-ppc.h (md_optimize_expr): Define.
	(ppc_optimize_expr): Declare.
include/
	* opcode/ppc.h (PPC_OPERAND_*): Reassign values, regs first.
	(PPC_OPERAND_SPR, PPC_OPERAND_GQR): Define.
opcodes/
	* ppc-opc.c (powerpc_operands): Flag SPR, SPRG and TBR entries
	with PPC_OPERAND_SPR.  Flag PSQ and PSQM with PPC_OPERAND_GQR.
This commit is contained in:
Alan Modra 2017-02-14 20:38:21 +10:30
parent 606a935e3a
commit 7e0de605cb
8 changed files with 654 additions and 550 deletions

View File

@ -1,3 +1,19 @@
2017-02-14 Alan Modra <amodra@gmail.com>
PR 21118
* NEWS: Mention powerpc register checks.
* config/tc-ppc.c (struct pd_reg): Make value a short. Add flags.
(pre_defined_registers): Delete fpscr and pmr entries. Set
register type in flags.
(cr_names): Set type in flags.
(reg_name_search): Return pointer to struct pd_reg rather than value.
(register_name): Adjust to suit. Set X_md from flags.
(ppc_parse_name): Likewise.
(ppc_optimize_expr): New function.
(md_assemble): Verify expresion reg flags match operand.
* config/tc-ppc.h (md_optimize_expr): Define.
(ppc_optimize_expr): Declare.
2017-02-14 Alan Modra <amodra@gmail.com>
* testsuite/gas/ppc/cell.s: Correct invalid registers.

View File

@ -1,5 +1,9 @@
-*- text -*-
* PowerPC gas now checks that the correct register class is used in
instructions. For instance, "addi %f4,%cr3,%r31" is now rejected
rather than silently producing "addi r4,r3,31".
* Add support for the Texas Instruments PRU processor.
Changes in 2.28:

File diff suppressed because it is too large Load Diff

View File

@ -264,6 +264,9 @@ extern long md_pcrel_from_section (struct fix *, segT);
#define md_parse_name(name, exp, mode, c) ppc_parse_name (name, exp)
extern int ppc_parse_name (const char *, struct expressionS *);
#define md_optimize_expr(left, op, right) ppc_optimize_expr (left, op, right)
extern int ppc_optimize_expr (expressionS *, operatorT, expressionS *);
#define md_operand(x)
#define md_cleanup() ppc_cleanup ()

View File

@ -1,3 +1,9 @@
2017-02-14 Alan Modra <amodra@gmail.com>
PR 21118
* opcode/ppc.h (PPC_OPERAND_*): Reassign values, regs first.
(PPC_OPERAND_SPR, PPC_OPERAND_GQR): Define.
2017-01-24 Dimitar Dimitrov <dimitar@dinux.eu>
* opcode/hppa.h: Clarify that file is part of GNU opcodes.

View File

@ -301,86 +301,70 @@ extern const unsigned int num_powerpc_operands;
goes in the insn. */
#define PPC_OPSHIFT_INV (-1U << 31)
/* Values defined for the flags field of a struct powerpc_operand. */
/* Values defined for the flags field of a struct powerpc_operand.
Keep the register bits low: They need to fit in an unsigned short. */
/* This operand names a register. The disassembler uses this to print
register names with a leading 'r'. */
#define PPC_OPERAND_GPR (0x1)
/* Like PPC_OPERAND_GPR, but don't print a leading 'r' for r0. */
#define PPC_OPERAND_GPR_0 (0x2)
/* This operand names a floating point register. The disassembler
prints these with a leading 'f'. */
#define PPC_OPERAND_FPR (0x4)
/* This operand names a vector unit register. The disassembler
prints these with a leading 'v'. */
#define PPC_OPERAND_VR (0x8)
/* This operand names a vector-scalar unit register. The disassembler
prints these with a leading 'vs'. */
#define PPC_OPERAND_VSR (0x10)
/* This operand may use the symbolic names for the CR fields (even
without -mregnames), which are
lt 0 gt 1 eq 2 so 3 un 3
cr0 0 cr1 1 cr2 2 cr3 3
cr4 4 cr5 5 cr6 6 cr7 7
These may be combined arithmetically, as in cr2*4+gt. These are
only supported on the PowerPC, not the POWER. */
#define PPC_OPERAND_CR_BIT (0x20)
/* This is a CR FIELD that does not use symbolic names (unless
-mregnames is in effect). */
#define PPC_OPERAND_CR_REG (0x40)
/* This operand names a special purpose register. */
#define PPC_OPERAND_SPR (0x80)
/* This operand names a paired-single graphics quantization register. */
#define PPC_OPERAND_GQR (0x100)
/* This operand is a relative branch displacement. The disassembler
prints these symbolically if possible. */
#define PPC_OPERAND_RELATIVE (0x200)
/* This operand is an absolute branch address. The disassembler
prints these symbolically if possible. */
#define PPC_OPERAND_ABSOLUTE (0x400)
/* This operand takes signed values. */
#define PPC_OPERAND_SIGNED (0x1)
#define PPC_OPERAND_SIGNED (0x800)
/* This operand takes signed values, but also accepts a full positive
range of values when running in 32 bit mode. That is, if bits is
16, it takes any value from -0x8000 to 0xffff. In 64 bit mode,
this flag is ignored. */
#define PPC_OPERAND_SIGNOPT (0x2)
/* This operand does not actually exist in the assembler input. This
is used to support extended mnemonics such as mr, for which two
operands fields are identical. The assembler should call the
insert function with any op value. The disassembler should call
the extract function, ignore the return value, and check the value
placed in the valid argument. */
#define PPC_OPERAND_FAKE (0x4)
#define PPC_OPERAND_SIGNOPT (0x1000)
/* The next operand should be wrapped in parentheses rather than
separated from this one by a comma. This is used for the load and
store instructions which want their operands to look like
reg,displacement(reg)
*/
#define PPC_OPERAND_PARENS (0x8)
/* This operand may use the symbolic names for the CR fields, which
are
lt 0 gt 1 eq 2 so 3 un 3
cr0 0 cr1 1 cr2 2 cr3 3
cr4 4 cr5 5 cr6 6 cr7 7
These may be combined arithmetically, as in cr2*4+gt. These are
only supported on the PowerPC, not the POWER. */
#define PPC_OPERAND_CR_BIT (0x10)
/* This operand names a register. The disassembler uses this to print
register names with a leading 'r'. */
#define PPC_OPERAND_GPR (0x20)
/* Like PPC_OPERAND_GPR, but don't print a leading 'r' for r0. */
#define PPC_OPERAND_GPR_0 (0x40)
/* This operand names a floating point register. The disassembler
prints these with a leading 'f'. */
#define PPC_OPERAND_FPR (0x80)
/* This operand is a relative branch displacement. The disassembler
prints these symbolically if possible. */
#define PPC_OPERAND_RELATIVE (0x100)
/* This operand is an absolute branch address. The disassembler
prints these symbolically if possible. */
#define PPC_OPERAND_ABSOLUTE (0x200)
/* This operand is optional, and is zero if omitted. This is used for
example, in the optional BF field in the comparison instructions. The
assembler must count the number of operands remaining on the line,
and the number of operands remaining for the opcode, and decide
whether this operand is present or not. The disassembler should
print this operand out only if it is not zero. */
#define PPC_OPERAND_OPTIONAL (0x400)
/* This flag is only used with PPC_OPERAND_OPTIONAL. If this operand
is omitted, then for the next operand use this operand value plus
1, ignoring the next operand field for the opcode. This wretched
hack is needed because the Power rotate instructions can take
either 4 or 5 operands. The disassembler should print this operand
out regardless of the PPC_OPERAND_OPTIONAL field. */
#define PPC_OPERAND_NEXT (0x800)
/* This operand should be regarded as a negative number for the
purposes of overflow checking (i.e., the normal most negative
number is disallowed and one more than the normal most positive
number is allowed). This flag will only be set for a signed
operand. */
#define PPC_OPERAND_NEGATIVE (0x1000)
/* This operand names a vector unit register. The disassembler
prints these with a leading 'v'. */
#define PPC_OPERAND_VR (0x2000)
#define PPC_OPERAND_PARENS (0x2000)
/* This operand is for the DS field in a DS form instruction. */
#define PPC_OPERAND_DS (0x4000)
@ -388,29 +372,53 @@ extern const unsigned int num_powerpc_operands;
/* This operand is for the DQ field in a DQ form instruction. */
#define PPC_OPERAND_DQ (0x8000)
/* This operand should be regarded as a negative number for the
purposes of overflow checking (i.e., the normal most negative
number is disallowed and one more than the normal most positive
number is allowed). This flag will only be set for a signed
operand. */
#define PPC_OPERAND_NEGATIVE (0x10000)
/* Valid range of operand is 0..n rather than 0..n-1. */
#define PPC_OPERAND_PLUS1 (0x10000)
#define PPC_OPERAND_PLUS1 (0x20000)
/* Xilinx APU and FSL related operands */
#define PPC_OPERAND_FSL (0x20000)
#define PPC_OPERAND_FCR (0x40000)
#define PPC_OPERAND_UDI (0x80000)
/* This operand does not actually exist in the assembler input. This
is used to support extended mnemonics such as mr, for which two
operands fields are identical. The assembler should call the
insert function with any op value. The disassembler should call
the extract function, ignore the return value, and check the value
placed in the valid argument. */
#define PPC_OPERAND_FAKE (0x40000)
/* This operand names a vector-scalar unit register. The disassembler
prints these with a leading 'vs'. */
#define PPC_OPERAND_VSR (0x100000)
/* This operand is optional, and is zero if omitted. This is used for
example, in the optional BF field in the comparison instructions. The
assembler must count the number of operands remaining on the line,
and the number of operands remaining for the opcode, and decide
whether this operand is present or not. The disassembler should
print this operand out only if it is not zero. */
#define PPC_OPERAND_OPTIONAL (0x80000)
/* 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 for the next operand use this operand value plus
1, ignoring the next operand field for the opcode. This wretched
hack is needed because the Power rotate instructions can take
either 4 or 5 operands. The disassembler should print this operand
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 (0x400000)
#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 (0x800000)
#define PPC_OPERAND_OPTIONAL32 (0x400000)
/* Xilinx APU and FSL related operands */
#define PPC_OPERAND_FSL (0x800000)
#define PPC_OPERAND_FCR (0x1000000)
#define PPC_OPERAND_UDI (0x2000000)
/* The POWER and PowerPC assemblers use a few macros. We keep them
with the operands table for simplicity. The macro table is an

View File

@ -1,3 +1,9 @@
2017-02-14 Alan Modra <amodra@gmail.com>
PR 21118
* ppc-opc.c (powerpc_operands): Flag SPR, SPRG and TBR entries
with PPC_OPERAND_SPR. Flag PSQ and PSQM with PPC_OPERAND_GQR.
2017-02-11 Stafford Horne <shorne@gmail.com>
Alan Modra <amodra@gmail.com>

View File

@ -667,7 +667,7 @@ const struct powerpc_operand powerpc_operands[] =
#define PMR SPR
#define TMR SPR
#define SPR_MASK (0x3ff << 11)
{ 0x3ff, 11, insert_spr, extract_spr, 0 },
{ 0x3ff, 11, insert_spr, extract_spr, PPC_OPERAND_SPR },
/* The BAT index number in an XFX form m[ft]ibat[lu] instruction. */
#define SPRBAT SPR + 1
@ -676,7 +676,7 @@ const struct powerpc_operand powerpc_operands[] =
/* The SPRG register number in an XFX form m[ft]sprg instruction. */
#define SPRG SPRBAT + 1
{ 0x1f, 16, insert_sprg, extract_sprg, 0 },
{ 0x1f, 16, insert_sprg, extract_sprg, PPC_OPERAND_SPR },
/* The SR field in an X form instruction. */
#define SR SPRG + 1
@ -704,7 +704,7 @@ const struct powerpc_operand powerpc_operands[] =
field, but it is optional. */
#define TBR SV + 1
{ 0x3ff, 11, insert_tbr, extract_tbr,
PPC_OPERAND_OPTIONAL | PPC_OPERAND_OPTIONAL_VALUE},
PPC_OPERAND_SPR | PPC_OPERAND_OPTIONAL | PPC_OPERAND_OPTIONAL_VALUE},
/* If the TBR operand is ommitted, use the value 268. */
{ -1, 268, NULL, NULL, 0},
@ -806,11 +806,11 @@ const struct powerpc_operand powerpc_operands[] =
/* IDX bits for quantization in the pair singles instructions. */
#define PSQ PSWM + 1
{ 0x7, 12, 0, 0, 0 },
{ 0x7, 12, 0, 0, PPC_OPERAND_GQR },
/* IDX bits for quantization in the pair singles x-type instructions. */
#define PSQM PSQ + 1
{ 0x7, 7, 0, 0, 0 },
{ 0x7, 7, 0, 0, PPC_OPERAND_GQR },
/* Smaller D field for quantization in the pair singles instructions. */
#define PSD PSQM + 1