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:
parent
606a935e3a
commit
7e0de605cb
|
@ -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.
|
||||
|
|
4
gas/NEWS
4
gas/NEWS
|
@ -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
|
@ -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 ()
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue