From: Alan Modra Date: Tue, 14 Feb 2017 10:08:21 +0000 (+1030) Subject: PowerPC register expression checks X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=7e0de605cbacbbbb2531bb70506c0843aea13111;p=binutils-gdb.git 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. --- diff --git a/gas/ChangeLog b/gas/ChangeLog index c3ae0a5803b..a72ae128b08 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,19 @@ +2017-02-14 Alan Modra + + 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 * testsuite/gas/ppc/cell.s: Correct invalid registers. diff --git a/gas/NEWS b/gas/NEWS index e95a9d8779e..ef0780dd590 100644 --- a/gas/NEWS +++ b/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: diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c index ccc627cfe99..fd5cc35cd26 100644 --- a/gas/config/tc-ppc.c +++ b/gas/config/tc-ppc.c @@ -307,7 +307,8 @@ const pseudo_typeS md_pseudo_table[] = struct pd_reg { const char *name; - int value; + unsigned short value; + unsigned short flags; }; /* List of registers that are pre-defined: @@ -331,11 +332,9 @@ struct pd_reg There are individual registers as well: sp or r.sp has the value 1 rtoc or r.toc has the value 2 - fpscr has the value 0 xer has the value 1 lr has the value 8 ctr has the value 9 - pmr has the value 0 dar has the value 19 dsisr has the value 18 dec has the value 22 @@ -347,463 +346,460 @@ struct pd_reg static const struct pd_reg pre_defined_registers[] = { - { "cr.0", 0 }, /* Condition Registers */ - { "cr.1", 1 }, - { "cr.2", 2 }, - { "cr.3", 3 }, - { "cr.4", 4 }, - { "cr.5", 5 }, - { "cr.6", 6 }, - { "cr.7", 7 }, - - { "cr0", 0 }, - { "cr1", 1 }, - { "cr2", 2 }, - { "cr3", 3 }, - { "cr4", 4 }, - { "cr5", 5 }, - { "cr6", 6 }, - { "cr7", 7 }, - - { "ctr", 9 }, - - { "dar", 19 }, /* Data Access Register */ - { "dec", 22 }, /* Decrementer */ - { "dsisr", 18 }, /* Data Storage Interrupt Status Register */ - - { "f.0", 0 }, /* Floating point registers */ - { "f.1", 1 }, - { "f.10", 10 }, - { "f.11", 11 }, - { "f.12", 12 }, - { "f.13", 13 }, - { "f.14", 14 }, - { "f.15", 15 }, - { "f.16", 16 }, - { "f.17", 17 }, - { "f.18", 18 }, - { "f.19", 19 }, - { "f.2", 2 }, - { "f.20", 20 }, - { "f.21", 21 }, - { "f.22", 22 }, - { "f.23", 23 }, - { "f.24", 24 }, - { "f.25", 25 }, - { "f.26", 26 }, - { "f.27", 27 }, - { "f.28", 28 }, - { "f.29", 29 }, - { "f.3", 3 }, - { "f.30", 30 }, - { "f.31", 31 }, - - { "f.32", 32 }, /* Extended floating point scalar registers (ISA 2.06). */ - { "f.33", 33 }, - { "f.34", 34 }, - { "f.35", 35 }, - { "f.36", 36 }, - { "f.37", 37 }, - { "f.38", 38 }, - { "f.39", 39 }, - { "f.4", 4 }, - { "f.40", 40 }, - { "f.41", 41 }, - { "f.42", 42 }, - { "f.43", 43 }, - { "f.44", 44 }, - { "f.45", 45 }, - { "f.46", 46 }, - { "f.47", 47 }, - { "f.48", 48 }, - { "f.49", 49 }, - { "f.5", 5 }, - { "f.50", 50 }, - { "f.51", 51 }, - { "f.52", 52 }, - { "f.53", 53 }, - { "f.54", 54 }, - { "f.55", 55 }, - { "f.56", 56 }, - { "f.57", 57 }, - { "f.58", 58 }, - { "f.59", 59 }, - { "f.6", 6 }, - { "f.60", 60 }, - { "f.61", 61 }, - { "f.62", 62 }, - { "f.63", 63 }, - { "f.7", 7 }, - { "f.8", 8 }, - { "f.9", 9 }, - - { "f0", 0 }, - { "f1", 1 }, - { "f10", 10 }, - { "f11", 11 }, - { "f12", 12 }, - { "f13", 13 }, - { "f14", 14 }, - { "f15", 15 }, - { "f16", 16 }, - { "f17", 17 }, - { "f18", 18 }, - { "f19", 19 }, - { "f2", 2 }, - { "f20", 20 }, - { "f21", 21 }, - { "f22", 22 }, - { "f23", 23 }, - { "f24", 24 }, - { "f25", 25 }, - { "f26", 26 }, - { "f27", 27 }, - { "f28", 28 }, - { "f29", 29 }, - { "f3", 3 }, - { "f30", 30 }, - { "f31", 31 }, - - { "f32", 32 }, /* Extended floating point scalar registers (ISA 2.06). */ - { "f33", 33 }, - { "f34", 34 }, - { "f35", 35 }, - { "f36", 36 }, - { "f37", 37 }, - { "f38", 38 }, - { "f39", 39 }, - { "f4", 4 }, - { "f40", 40 }, - { "f41", 41 }, - { "f42", 42 }, - { "f43", 43 }, - { "f44", 44 }, - { "f45", 45 }, - { "f46", 46 }, - { "f47", 47 }, - { "f48", 48 }, - { "f49", 49 }, - { "f5", 5 }, - { "f50", 50 }, - { "f51", 51 }, - { "f52", 52 }, - { "f53", 53 }, - { "f54", 54 }, - { "f55", 55 }, - { "f56", 56 }, - { "f57", 57 }, - { "f58", 58 }, - { "f59", 59 }, - { "f6", 6 }, - { "f60", 60 }, - { "f61", 61 }, - { "f62", 62 }, - { "f63", 63 }, - { "f7", 7 }, - { "f8", 8 }, - { "f9", 9 }, - - { "fpscr", 0 }, + /* Condition Registers */ + { "cr.0", 0, PPC_OPERAND_CR_REG }, + { "cr.1", 1, PPC_OPERAND_CR_REG }, + { "cr.2", 2, PPC_OPERAND_CR_REG }, + { "cr.3", 3, PPC_OPERAND_CR_REG }, + { "cr.4", 4, PPC_OPERAND_CR_REG }, + { "cr.5", 5, PPC_OPERAND_CR_REG }, + { "cr.6", 6, PPC_OPERAND_CR_REG }, + { "cr.7", 7, PPC_OPERAND_CR_REG }, + + { "cr0", 0, PPC_OPERAND_CR_REG }, + { "cr1", 1, PPC_OPERAND_CR_REG }, + { "cr2", 2, PPC_OPERAND_CR_REG }, + { "cr3", 3, PPC_OPERAND_CR_REG }, + { "cr4", 4, PPC_OPERAND_CR_REG }, + { "cr5", 5, PPC_OPERAND_CR_REG }, + { "cr6", 6, PPC_OPERAND_CR_REG }, + { "cr7", 7, PPC_OPERAND_CR_REG }, + + { "ctr", 9, PPC_OPERAND_SPR }, + { "dar", 19, PPC_OPERAND_SPR }, + { "dec", 22, PPC_OPERAND_SPR }, + { "dsisr", 18, PPC_OPERAND_SPR }, + + /* Floating point registers */ + { "f.0", 0, PPC_OPERAND_FPR }, + { "f.1", 1, PPC_OPERAND_FPR }, + { "f.10", 10, PPC_OPERAND_FPR }, + { "f.11", 11, PPC_OPERAND_FPR }, + { "f.12", 12, PPC_OPERAND_FPR }, + { "f.13", 13, PPC_OPERAND_FPR }, + { "f.14", 14, PPC_OPERAND_FPR }, + { "f.15", 15, PPC_OPERAND_FPR }, + { "f.16", 16, PPC_OPERAND_FPR }, + { "f.17", 17, PPC_OPERAND_FPR }, + { "f.18", 18, PPC_OPERAND_FPR }, + { "f.19", 19, PPC_OPERAND_FPR }, + { "f.2", 2, PPC_OPERAND_FPR }, + { "f.20", 20, PPC_OPERAND_FPR }, + { "f.21", 21, PPC_OPERAND_FPR }, + { "f.22", 22, PPC_OPERAND_FPR }, + { "f.23", 23, PPC_OPERAND_FPR }, + { "f.24", 24, PPC_OPERAND_FPR }, + { "f.25", 25, PPC_OPERAND_FPR }, + { "f.26", 26, PPC_OPERAND_FPR }, + { "f.27", 27, PPC_OPERAND_FPR }, + { "f.28", 28, PPC_OPERAND_FPR }, + { "f.29", 29, PPC_OPERAND_FPR }, + { "f.3", 3, PPC_OPERAND_FPR }, + { "f.30", 30, PPC_OPERAND_FPR }, + { "f.31", 31, PPC_OPERAND_FPR }, + { "f.32", 32, PPC_OPERAND_VSR }, + { "f.33", 33, PPC_OPERAND_VSR }, + { "f.34", 34, PPC_OPERAND_VSR }, + { "f.35", 35, PPC_OPERAND_VSR }, + { "f.36", 36, PPC_OPERAND_VSR }, + { "f.37", 37, PPC_OPERAND_VSR }, + { "f.38", 38, PPC_OPERAND_VSR }, + { "f.39", 39, PPC_OPERAND_VSR }, + { "f.4", 4, PPC_OPERAND_FPR }, + { "f.40", 40, PPC_OPERAND_VSR }, + { "f.41", 41, PPC_OPERAND_VSR }, + { "f.42", 42, PPC_OPERAND_VSR }, + { "f.43", 43, PPC_OPERAND_VSR }, + { "f.44", 44, PPC_OPERAND_VSR }, + { "f.45", 45, PPC_OPERAND_VSR }, + { "f.46", 46, PPC_OPERAND_VSR }, + { "f.47", 47, PPC_OPERAND_VSR }, + { "f.48", 48, PPC_OPERAND_VSR }, + { "f.49", 49, PPC_OPERAND_VSR }, + { "f.5", 5, PPC_OPERAND_FPR }, + { "f.50", 50, PPC_OPERAND_VSR }, + { "f.51", 51, PPC_OPERAND_VSR }, + { "f.52", 52, PPC_OPERAND_VSR }, + { "f.53", 53, PPC_OPERAND_VSR }, + { "f.54", 54, PPC_OPERAND_VSR }, + { "f.55", 55, PPC_OPERAND_VSR }, + { "f.56", 56, PPC_OPERAND_VSR }, + { "f.57", 57, PPC_OPERAND_VSR }, + { "f.58", 58, PPC_OPERAND_VSR }, + { "f.59", 59, PPC_OPERAND_VSR }, + { "f.6", 6, PPC_OPERAND_FPR }, + { "f.60", 60, PPC_OPERAND_VSR }, + { "f.61", 61, PPC_OPERAND_VSR }, + { "f.62", 62, PPC_OPERAND_VSR }, + { "f.63", 63, PPC_OPERAND_VSR }, + { "f.7", 7, PPC_OPERAND_FPR }, + { "f.8", 8, PPC_OPERAND_FPR }, + { "f.9", 9, PPC_OPERAND_FPR }, + + { "f0", 0, PPC_OPERAND_FPR }, + { "f1", 1, PPC_OPERAND_FPR }, + { "f10", 10, PPC_OPERAND_FPR }, + { "f11", 11, PPC_OPERAND_FPR }, + { "f12", 12, PPC_OPERAND_FPR }, + { "f13", 13, PPC_OPERAND_FPR }, + { "f14", 14, PPC_OPERAND_FPR }, + { "f15", 15, PPC_OPERAND_FPR }, + { "f16", 16, PPC_OPERAND_FPR }, + { "f17", 17, PPC_OPERAND_FPR }, + { "f18", 18, PPC_OPERAND_FPR }, + { "f19", 19, PPC_OPERAND_FPR }, + { "f2", 2, PPC_OPERAND_FPR }, + { "f20", 20, PPC_OPERAND_FPR }, + { "f21", 21, PPC_OPERAND_FPR }, + { "f22", 22, PPC_OPERAND_FPR }, + { "f23", 23, PPC_OPERAND_FPR }, + { "f24", 24, PPC_OPERAND_FPR }, + { "f25", 25, PPC_OPERAND_FPR }, + { "f26", 26, PPC_OPERAND_FPR }, + { "f27", 27, PPC_OPERAND_FPR }, + { "f28", 28, PPC_OPERAND_FPR }, + { "f29", 29, PPC_OPERAND_FPR }, + { "f3", 3, PPC_OPERAND_FPR }, + { "f30", 30, PPC_OPERAND_FPR }, + { "f31", 31, PPC_OPERAND_FPR }, + { "f32", 32, PPC_OPERAND_VSR }, + { "f33", 33, PPC_OPERAND_VSR }, + { "f34", 34, PPC_OPERAND_VSR }, + { "f35", 35, PPC_OPERAND_VSR }, + { "f36", 36, PPC_OPERAND_VSR }, + { "f37", 37, PPC_OPERAND_VSR }, + { "f38", 38, PPC_OPERAND_VSR }, + { "f39", 39, PPC_OPERAND_VSR }, + { "f4", 4, PPC_OPERAND_FPR }, + { "f40", 40, PPC_OPERAND_VSR }, + { "f41", 41, PPC_OPERAND_VSR }, + { "f42", 42, PPC_OPERAND_VSR }, + { "f43", 43, PPC_OPERAND_VSR }, + { "f44", 44, PPC_OPERAND_VSR }, + { "f45", 45, PPC_OPERAND_VSR }, + { "f46", 46, PPC_OPERAND_VSR }, + { "f47", 47, PPC_OPERAND_VSR }, + { "f48", 48, PPC_OPERAND_VSR }, + { "f49", 49, PPC_OPERAND_VSR }, + { "f5", 5, PPC_OPERAND_FPR }, + { "f50", 50, PPC_OPERAND_VSR }, + { "f51", 51, PPC_OPERAND_VSR }, + { "f52", 52, PPC_OPERAND_VSR }, + { "f53", 53, PPC_OPERAND_VSR }, + { "f54", 54, PPC_OPERAND_VSR }, + { "f55", 55, PPC_OPERAND_VSR }, + { "f56", 56, PPC_OPERAND_VSR }, + { "f57", 57, PPC_OPERAND_VSR }, + { "f58", 58, PPC_OPERAND_VSR }, + { "f59", 59, PPC_OPERAND_VSR }, + { "f6", 6, PPC_OPERAND_FPR }, + { "f60", 60, PPC_OPERAND_VSR }, + { "f61", 61, PPC_OPERAND_VSR }, + { "f62", 62, PPC_OPERAND_VSR }, + { "f63", 63, PPC_OPERAND_VSR }, + { "f7", 7, PPC_OPERAND_FPR }, + { "f8", 8, PPC_OPERAND_FPR }, + { "f9", 9, PPC_OPERAND_FPR }, /* Quantization registers used with pair single instructions. */ - { "gqr.0", 0 }, - { "gqr.1", 1 }, - { "gqr.2", 2 }, - { "gqr.3", 3 }, - { "gqr.4", 4 }, - { "gqr.5", 5 }, - { "gqr.6", 6 }, - { "gqr.7", 7 }, - { "gqr0", 0 }, - { "gqr1", 1 }, - { "gqr2", 2 }, - { "gqr3", 3 }, - { "gqr4", 4 }, - { "gqr5", 5 }, - { "gqr6", 6 }, - { "gqr7", 7 }, - - { "lr", 8 }, /* Link Register */ - - { "pmr", 0 }, - - { "r.0", 0 }, /* General Purpose Registers */ - { "r.1", 1 }, - { "r.10", 10 }, - { "r.11", 11 }, - { "r.12", 12 }, - { "r.13", 13 }, - { "r.14", 14 }, - { "r.15", 15 }, - { "r.16", 16 }, - { "r.17", 17 }, - { "r.18", 18 }, - { "r.19", 19 }, - { "r.2", 2 }, - { "r.20", 20 }, - { "r.21", 21 }, - { "r.22", 22 }, - { "r.23", 23 }, - { "r.24", 24 }, - { "r.25", 25 }, - { "r.26", 26 }, - { "r.27", 27 }, - { "r.28", 28 }, - { "r.29", 29 }, - { "r.3", 3 }, - { "r.30", 30 }, - { "r.31", 31 }, - { "r.4", 4 }, - { "r.5", 5 }, - { "r.6", 6 }, - { "r.7", 7 }, - { "r.8", 8 }, - { "r.9", 9 }, - - { "r.sp", 1 }, /* Stack Pointer */ - - { "r.toc", 2 }, /* Pointer to the table of contents */ - - { "r0", 0 }, /* More general purpose registers */ - { "r1", 1 }, - { "r10", 10 }, - { "r11", 11 }, - { "r12", 12 }, - { "r13", 13 }, - { "r14", 14 }, - { "r15", 15 }, - { "r16", 16 }, - { "r17", 17 }, - { "r18", 18 }, - { "r19", 19 }, - { "r2", 2 }, - { "r20", 20 }, - { "r21", 21 }, - { "r22", 22 }, - { "r23", 23 }, - { "r24", 24 }, - { "r25", 25 }, - { "r26", 26 }, - { "r27", 27 }, - { "r28", 28 }, - { "r29", 29 }, - { "r3", 3 }, - { "r30", 30 }, - { "r31", 31 }, - { "r4", 4 }, - { "r5", 5 }, - { "r6", 6 }, - { "r7", 7 }, - { "r8", 8 }, - { "r9", 9 }, - - { "rtoc", 2 }, /* Table of contents */ - - { "sdr1", 25 }, /* Storage Description Register 1 */ - - { "sp", 1 }, - - { "srr0", 26 }, /* Machine Status Save/Restore Register 0 */ - { "srr1", 27 }, /* Machine Status Save/Restore Register 1 */ - - { "v.0", 0 }, /* Vector (Altivec/VMX) registers */ - { "v.1", 1 }, - { "v.10", 10 }, - { "v.11", 11 }, - { "v.12", 12 }, - { "v.13", 13 }, - { "v.14", 14 }, - { "v.15", 15 }, - { "v.16", 16 }, - { "v.17", 17 }, - { "v.18", 18 }, - { "v.19", 19 }, - { "v.2", 2 }, - { "v.20", 20 }, - { "v.21", 21 }, - { "v.22", 22 }, - { "v.23", 23 }, - { "v.24", 24 }, - { "v.25", 25 }, - { "v.26", 26 }, - { "v.27", 27 }, - { "v.28", 28 }, - { "v.29", 29 }, - { "v.3", 3 }, - { "v.30", 30 }, - { "v.31", 31 }, - { "v.4", 4 }, - { "v.5", 5 }, - { "v.6", 6 }, - { "v.7", 7 }, - { "v.8", 8 }, - { "v.9", 9 }, - - { "v0", 0 }, - { "v1", 1 }, - { "v10", 10 }, - { "v11", 11 }, - { "v12", 12 }, - { "v13", 13 }, - { "v14", 14 }, - { "v15", 15 }, - { "v16", 16 }, - { "v17", 17 }, - { "v18", 18 }, - { "v19", 19 }, - { "v2", 2 }, - { "v20", 20 }, - { "v21", 21 }, - { "v22", 22 }, - { "v23", 23 }, - { "v24", 24 }, - { "v25", 25 }, - { "v26", 26 }, - { "v27", 27 }, - { "v28", 28 }, - { "v29", 29 }, - { "v3", 3 }, - { "v30", 30 }, - { "v31", 31 }, - { "v4", 4 }, - { "v5", 5 }, - { "v6", 6 }, - { "v7", 7 }, - { "v8", 8 }, - { "v9", 9 }, - - { "vs.0", 0 }, /* Vector Scalar (VSX) registers (ISA 2.06). */ - { "vs.1", 1 }, - { "vs.10", 10 }, - { "vs.11", 11 }, - { "vs.12", 12 }, - { "vs.13", 13 }, - { "vs.14", 14 }, - { "vs.15", 15 }, - { "vs.16", 16 }, - { "vs.17", 17 }, - { "vs.18", 18 }, - { "vs.19", 19 }, - { "vs.2", 2 }, - { "vs.20", 20 }, - { "vs.21", 21 }, - { "vs.22", 22 }, - { "vs.23", 23 }, - { "vs.24", 24 }, - { "vs.25", 25 }, - { "vs.26", 26 }, - { "vs.27", 27 }, - { "vs.28", 28 }, - { "vs.29", 29 }, - { "vs.3", 3 }, - { "vs.30", 30 }, - { "vs.31", 31 }, - { "vs.32", 32 }, - { "vs.33", 33 }, - { "vs.34", 34 }, - { "vs.35", 35 }, - { "vs.36", 36 }, - { "vs.37", 37 }, - { "vs.38", 38 }, - { "vs.39", 39 }, - { "vs.4", 4 }, - { "vs.40", 40 }, - { "vs.41", 41 }, - { "vs.42", 42 }, - { "vs.43", 43 }, - { "vs.44", 44 }, - { "vs.45", 45 }, - { "vs.46", 46 }, - { "vs.47", 47 }, - { "vs.48", 48 }, - { "vs.49", 49 }, - { "vs.5", 5 }, - { "vs.50", 50 }, - { "vs.51", 51 }, - { "vs.52", 52 }, - { "vs.53", 53 }, - { "vs.54", 54 }, - { "vs.55", 55 }, - { "vs.56", 56 }, - { "vs.57", 57 }, - { "vs.58", 58 }, - { "vs.59", 59 }, - { "vs.6", 6 }, - { "vs.60", 60 }, - { "vs.61", 61 }, - { "vs.62", 62 }, - { "vs.63", 63 }, - { "vs.7", 7 }, - { "vs.8", 8 }, - { "vs.9", 9 }, - - { "vs0", 0 }, - { "vs1", 1 }, - { "vs10", 10 }, - { "vs11", 11 }, - { "vs12", 12 }, - { "vs13", 13 }, - { "vs14", 14 }, - { "vs15", 15 }, - { "vs16", 16 }, - { "vs17", 17 }, - { "vs18", 18 }, - { "vs19", 19 }, - { "vs2", 2 }, - { "vs20", 20 }, - { "vs21", 21 }, - { "vs22", 22 }, - { "vs23", 23 }, - { "vs24", 24 }, - { "vs25", 25 }, - { "vs26", 26 }, - { "vs27", 27 }, - { "vs28", 28 }, - { "vs29", 29 }, - { "vs3", 3 }, - { "vs30", 30 }, - { "vs31", 31 }, - { "vs32", 32 }, - { "vs33", 33 }, - { "vs34", 34 }, - { "vs35", 35 }, - { "vs36", 36 }, - { "vs37", 37 }, - { "vs38", 38 }, - { "vs39", 39 }, - { "vs4", 4 }, - { "vs40", 40 }, - { "vs41", 41 }, - { "vs42", 42 }, - { "vs43", 43 }, - { "vs44", 44 }, - { "vs45", 45 }, - { "vs46", 46 }, - { "vs47", 47 }, - { "vs48", 48 }, - { "vs49", 49 }, - { "vs5", 5 }, - { "vs50", 50 }, - { "vs51", 51 }, - { "vs52", 52 }, - { "vs53", 53 }, - { "vs54", 54 }, - { "vs55", 55 }, - { "vs56", 56 }, - { "vs57", 57 }, - { "vs58", 58 }, - { "vs59", 59 }, - { "vs6", 6 }, - { "vs60", 60 }, - { "vs61", 61 }, - { "vs62", 62 }, - { "vs63", 63 }, - { "vs7", 7 }, - { "vs8", 8 }, - { "vs9", 9 }, - - { "xer", 1 }, - + { "gqr.0", 0, PPC_OPERAND_GQR }, + { "gqr.1", 1, PPC_OPERAND_GQR }, + { "gqr.2", 2, PPC_OPERAND_GQR }, + { "gqr.3", 3, PPC_OPERAND_GQR }, + { "gqr.4", 4, PPC_OPERAND_GQR }, + { "gqr.5", 5, PPC_OPERAND_GQR }, + { "gqr.6", 6, PPC_OPERAND_GQR }, + { "gqr.7", 7, PPC_OPERAND_GQR }, + { "gqr0", 0, PPC_OPERAND_GQR }, + { "gqr1", 1, PPC_OPERAND_GQR }, + { "gqr2", 2, PPC_OPERAND_GQR }, + { "gqr3", 3, PPC_OPERAND_GQR }, + { "gqr4", 4, PPC_OPERAND_GQR }, + { "gqr5", 5, PPC_OPERAND_GQR }, + { "gqr6", 6, PPC_OPERAND_GQR }, + { "gqr7", 7, PPC_OPERAND_GQR }, + + { "lr", 8, PPC_OPERAND_SPR }, + + /* General Purpose Registers */ + { "r.0", 0, PPC_OPERAND_GPR }, + { "r.1", 1, PPC_OPERAND_GPR }, + { "r.10", 10, PPC_OPERAND_GPR }, + { "r.11", 11, PPC_OPERAND_GPR }, + { "r.12", 12, PPC_OPERAND_GPR }, + { "r.13", 13, PPC_OPERAND_GPR }, + { "r.14", 14, PPC_OPERAND_GPR }, + { "r.15", 15, PPC_OPERAND_GPR }, + { "r.16", 16, PPC_OPERAND_GPR }, + { "r.17", 17, PPC_OPERAND_GPR }, + { "r.18", 18, PPC_OPERAND_GPR }, + { "r.19", 19, PPC_OPERAND_GPR }, + { "r.2", 2, PPC_OPERAND_GPR }, + { "r.20", 20, PPC_OPERAND_GPR }, + { "r.21", 21, PPC_OPERAND_GPR }, + { "r.22", 22, PPC_OPERAND_GPR }, + { "r.23", 23, PPC_OPERAND_GPR }, + { "r.24", 24, PPC_OPERAND_GPR }, + { "r.25", 25, PPC_OPERAND_GPR }, + { "r.26", 26, PPC_OPERAND_GPR }, + { "r.27", 27, PPC_OPERAND_GPR }, + { "r.28", 28, PPC_OPERAND_GPR }, + { "r.29", 29, PPC_OPERAND_GPR }, + { "r.3", 3, PPC_OPERAND_GPR }, + { "r.30", 30, PPC_OPERAND_GPR }, + { "r.31", 31, PPC_OPERAND_GPR }, + { "r.4", 4, PPC_OPERAND_GPR }, + { "r.5", 5, PPC_OPERAND_GPR }, + { "r.6", 6, PPC_OPERAND_GPR }, + { "r.7", 7, PPC_OPERAND_GPR }, + { "r.8", 8, PPC_OPERAND_GPR }, + { "r.9", 9, PPC_OPERAND_GPR }, + + { "r.sp", 1, PPC_OPERAND_GPR }, + + { "r.toc", 2, PPC_OPERAND_GPR }, + + { "r0", 0, PPC_OPERAND_GPR }, + { "r1", 1, PPC_OPERAND_GPR }, + { "r10", 10, PPC_OPERAND_GPR }, + { "r11", 11, PPC_OPERAND_GPR }, + { "r12", 12, PPC_OPERAND_GPR }, + { "r13", 13, PPC_OPERAND_GPR }, + { "r14", 14, PPC_OPERAND_GPR }, + { "r15", 15, PPC_OPERAND_GPR }, + { "r16", 16, PPC_OPERAND_GPR }, + { "r17", 17, PPC_OPERAND_GPR }, + { "r18", 18, PPC_OPERAND_GPR }, + { "r19", 19, PPC_OPERAND_GPR }, + { "r2", 2, PPC_OPERAND_GPR }, + { "r20", 20, PPC_OPERAND_GPR }, + { "r21", 21, PPC_OPERAND_GPR }, + { "r22", 22, PPC_OPERAND_GPR }, + { "r23", 23, PPC_OPERAND_GPR }, + { "r24", 24, PPC_OPERAND_GPR }, + { "r25", 25, PPC_OPERAND_GPR }, + { "r26", 26, PPC_OPERAND_GPR }, + { "r27", 27, PPC_OPERAND_GPR }, + { "r28", 28, PPC_OPERAND_GPR }, + { "r29", 29, PPC_OPERAND_GPR }, + { "r3", 3, PPC_OPERAND_GPR }, + { "r30", 30, PPC_OPERAND_GPR }, + { "r31", 31, PPC_OPERAND_GPR }, + { "r4", 4, PPC_OPERAND_GPR }, + { "r5", 5, PPC_OPERAND_GPR }, + { "r6", 6, PPC_OPERAND_GPR }, + { "r7", 7, PPC_OPERAND_GPR }, + { "r8", 8, PPC_OPERAND_GPR }, + { "r9", 9, PPC_OPERAND_GPR }, + + { "rtoc", 2, PPC_OPERAND_GPR }, + + { "sdr1", 25, PPC_OPERAND_SPR }, + + { "sp", 1, PPC_OPERAND_GPR }, + + { "srr0", 26, PPC_OPERAND_SPR }, + { "srr1", 27, PPC_OPERAND_SPR }, + + /* Vector (Altivec/VMX) registers */ + { "v.0", 0, PPC_OPERAND_VR }, + { "v.1", 1, PPC_OPERAND_VR }, + { "v.10", 10, PPC_OPERAND_VR }, + { "v.11", 11, PPC_OPERAND_VR }, + { "v.12", 12, PPC_OPERAND_VR }, + { "v.13", 13, PPC_OPERAND_VR }, + { "v.14", 14, PPC_OPERAND_VR }, + { "v.15", 15, PPC_OPERAND_VR }, + { "v.16", 16, PPC_OPERAND_VR }, + { "v.17", 17, PPC_OPERAND_VR }, + { "v.18", 18, PPC_OPERAND_VR }, + { "v.19", 19, PPC_OPERAND_VR }, + { "v.2", 2, PPC_OPERAND_VR }, + { "v.20", 20, PPC_OPERAND_VR }, + { "v.21", 21, PPC_OPERAND_VR }, + { "v.22", 22, PPC_OPERAND_VR }, + { "v.23", 23, PPC_OPERAND_VR }, + { "v.24", 24, PPC_OPERAND_VR }, + { "v.25", 25, PPC_OPERAND_VR }, + { "v.26", 26, PPC_OPERAND_VR }, + { "v.27", 27, PPC_OPERAND_VR }, + { "v.28", 28, PPC_OPERAND_VR }, + { "v.29", 29, PPC_OPERAND_VR }, + { "v.3", 3, PPC_OPERAND_VR }, + { "v.30", 30, PPC_OPERAND_VR }, + { "v.31", 31, PPC_OPERAND_VR }, + { "v.4", 4, PPC_OPERAND_VR }, + { "v.5", 5, PPC_OPERAND_VR }, + { "v.6", 6, PPC_OPERAND_VR }, + { "v.7", 7, PPC_OPERAND_VR }, + { "v.8", 8, PPC_OPERAND_VR }, + { "v.9", 9, PPC_OPERAND_VR }, + + { "v0", 0, PPC_OPERAND_VR }, + { "v1", 1, PPC_OPERAND_VR }, + { "v10", 10, PPC_OPERAND_VR }, + { "v11", 11, PPC_OPERAND_VR }, + { "v12", 12, PPC_OPERAND_VR }, + { "v13", 13, PPC_OPERAND_VR }, + { "v14", 14, PPC_OPERAND_VR }, + { "v15", 15, PPC_OPERAND_VR }, + { "v16", 16, PPC_OPERAND_VR }, + { "v17", 17, PPC_OPERAND_VR }, + { "v18", 18, PPC_OPERAND_VR }, + { "v19", 19, PPC_OPERAND_VR }, + { "v2", 2, PPC_OPERAND_VR }, + { "v20", 20, PPC_OPERAND_VR }, + { "v21", 21, PPC_OPERAND_VR }, + { "v22", 22, PPC_OPERAND_VR }, + { "v23", 23, PPC_OPERAND_VR }, + { "v24", 24, PPC_OPERAND_VR }, + { "v25", 25, PPC_OPERAND_VR }, + { "v26", 26, PPC_OPERAND_VR }, + { "v27", 27, PPC_OPERAND_VR }, + { "v28", 28, PPC_OPERAND_VR }, + { "v29", 29, PPC_OPERAND_VR }, + { "v3", 3, PPC_OPERAND_VR }, + { "v30", 30, PPC_OPERAND_VR }, + { "v31", 31, PPC_OPERAND_VR }, + { "v4", 4, PPC_OPERAND_VR }, + { "v5", 5, PPC_OPERAND_VR }, + { "v6", 6, PPC_OPERAND_VR }, + { "v7", 7, PPC_OPERAND_VR }, + { "v8", 8, PPC_OPERAND_VR }, + { "v9", 9, PPC_OPERAND_VR }, + + /* Vector Scalar (VSX) registers (ISA 2.06). */ + { "vs.0", 0, PPC_OPERAND_VSR }, + { "vs.1", 1, PPC_OPERAND_VSR }, + { "vs.10", 10, PPC_OPERAND_VSR }, + { "vs.11", 11, PPC_OPERAND_VSR }, + { "vs.12", 12, PPC_OPERAND_VSR }, + { "vs.13", 13, PPC_OPERAND_VSR }, + { "vs.14", 14, PPC_OPERAND_VSR }, + { "vs.15", 15, PPC_OPERAND_VSR }, + { "vs.16", 16, PPC_OPERAND_VSR }, + { "vs.17", 17, PPC_OPERAND_VSR }, + { "vs.18", 18, PPC_OPERAND_VSR }, + { "vs.19", 19, PPC_OPERAND_VSR }, + { "vs.2", 2, PPC_OPERAND_VSR }, + { "vs.20", 20, PPC_OPERAND_VSR }, + { "vs.21", 21, PPC_OPERAND_VSR }, + { "vs.22", 22, PPC_OPERAND_VSR }, + { "vs.23", 23, PPC_OPERAND_VSR }, + { "vs.24", 24, PPC_OPERAND_VSR }, + { "vs.25", 25, PPC_OPERAND_VSR }, + { "vs.26", 26, PPC_OPERAND_VSR }, + { "vs.27", 27, PPC_OPERAND_VSR }, + { "vs.28", 28, PPC_OPERAND_VSR }, + { "vs.29", 29, PPC_OPERAND_VSR }, + { "vs.3", 3, PPC_OPERAND_VSR }, + { "vs.30", 30, PPC_OPERAND_VSR }, + { "vs.31", 31, PPC_OPERAND_VSR }, + { "vs.32", 32, PPC_OPERAND_VSR }, + { "vs.33", 33, PPC_OPERAND_VSR }, + { "vs.34", 34, PPC_OPERAND_VSR }, + { "vs.35", 35, PPC_OPERAND_VSR }, + { "vs.36", 36, PPC_OPERAND_VSR }, + { "vs.37", 37, PPC_OPERAND_VSR }, + { "vs.38", 38, PPC_OPERAND_VSR }, + { "vs.39", 39, PPC_OPERAND_VSR }, + { "vs.4", 4, PPC_OPERAND_VSR }, + { "vs.40", 40, PPC_OPERAND_VSR }, + { "vs.41", 41, PPC_OPERAND_VSR }, + { "vs.42", 42, PPC_OPERAND_VSR }, + { "vs.43", 43, PPC_OPERAND_VSR }, + { "vs.44", 44, PPC_OPERAND_VSR }, + { "vs.45", 45, PPC_OPERAND_VSR }, + { "vs.46", 46, PPC_OPERAND_VSR }, + { "vs.47", 47, PPC_OPERAND_VSR }, + { "vs.48", 48, PPC_OPERAND_VSR }, + { "vs.49", 49, PPC_OPERAND_VSR }, + { "vs.5", 5, PPC_OPERAND_VSR }, + { "vs.50", 50, PPC_OPERAND_VSR }, + { "vs.51", 51, PPC_OPERAND_VSR }, + { "vs.52", 52, PPC_OPERAND_VSR }, + { "vs.53", 53, PPC_OPERAND_VSR }, + { "vs.54", 54, PPC_OPERAND_VSR }, + { "vs.55", 55, PPC_OPERAND_VSR }, + { "vs.56", 56, PPC_OPERAND_VSR }, + { "vs.57", 57, PPC_OPERAND_VSR }, + { "vs.58", 58, PPC_OPERAND_VSR }, + { "vs.59", 59, PPC_OPERAND_VSR }, + { "vs.6", 6, PPC_OPERAND_VSR }, + { "vs.60", 60, PPC_OPERAND_VSR }, + { "vs.61", 61, PPC_OPERAND_VSR }, + { "vs.62", 62, PPC_OPERAND_VSR }, + { "vs.63", 63, PPC_OPERAND_VSR }, + { "vs.7", 7, PPC_OPERAND_VSR }, + { "vs.8", 8, PPC_OPERAND_VSR }, + { "vs.9", 9, PPC_OPERAND_VSR }, + + { "vs0", 0, PPC_OPERAND_VSR }, + { "vs1", 1, PPC_OPERAND_VSR }, + { "vs10", 10, PPC_OPERAND_VSR }, + { "vs11", 11, PPC_OPERAND_VSR }, + { "vs12", 12, PPC_OPERAND_VSR }, + { "vs13", 13, PPC_OPERAND_VSR }, + { "vs14", 14, PPC_OPERAND_VSR }, + { "vs15", 15, PPC_OPERAND_VSR }, + { "vs16", 16, PPC_OPERAND_VSR }, + { "vs17", 17, PPC_OPERAND_VSR }, + { "vs18", 18, PPC_OPERAND_VSR }, + { "vs19", 19, PPC_OPERAND_VSR }, + { "vs2", 2, PPC_OPERAND_VSR }, + { "vs20", 20, PPC_OPERAND_VSR }, + { "vs21", 21, PPC_OPERAND_VSR }, + { "vs22", 22, PPC_OPERAND_VSR }, + { "vs23", 23, PPC_OPERAND_VSR }, + { "vs24", 24, PPC_OPERAND_VSR }, + { "vs25", 25, PPC_OPERAND_VSR }, + { "vs26", 26, PPC_OPERAND_VSR }, + { "vs27", 27, PPC_OPERAND_VSR }, + { "vs28", 28, PPC_OPERAND_VSR }, + { "vs29", 29, PPC_OPERAND_VSR }, + { "vs3", 3, PPC_OPERAND_VSR }, + { "vs30", 30, PPC_OPERAND_VSR }, + { "vs31", 31, PPC_OPERAND_VSR }, + { "vs32", 32, PPC_OPERAND_VSR }, + { "vs33", 33, PPC_OPERAND_VSR }, + { "vs34", 34, PPC_OPERAND_VSR }, + { "vs35", 35, PPC_OPERAND_VSR }, + { "vs36", 36, PPC_OPERAND_VSR }, + { "vs37", 37, PPC_OPERAND_VSR }, + { "vs38", 38, PPC_OPERAND_VSR }, + { "vs39", 39, PPC_OPERAND_VSR }, + { "vs4", 4, PPC_OPERAND_VSR }, + { "vs40", 40, PPC_OPERAND_VSR }, + { "vs41", 41, PPC_OPERAND_VSR }, + { "vs42", 42, PPC_OPERAND_VSR }, + { "vs43", 43, PPC_OPERAND_VSR }, + { "vs44", 44, PPC_OPERAND_VSR }, + { "vs45", 45, PPC_OPERAND_VSR }, + { "vs46", 46, PPC_OPERAND_VSR }, + { "vs47", 47, PPC_OPERAND_VSR }, + { "vs48", 48, PPC_OPERAND_VSR }, + { "vs49", 49, PPC_OPERAND_VSR }, + { "vs5", 5, PPC_OPERAND_VSR }, + { "vs50", 50, PPC_OPERAND_VSR }, + { "vs51", 51, PPC_OPERAND_VSR }, + { "vs52", 52, PPC_OPERAND_VSR }, + { "vs53", 53, PPC_OPERAND_VSR }, + { "vs54", 54, PPC_OPERAND_VSR }, + { "vs55", 55, PPC_OPERAND_VSR }, + { "vs56", 56, PPC_OPERAND_VSR }, + { "vs57", 57, PPC_OPERAND_VSR }, + { "vs58", 58, PPC_OPERAND_VSR }, + { "vs59", 59, PPC_OPERAND_VSR }, + { "vs6", 6, PPC_OPERAND_VSR }, + { "vs60", 60, PPC_OPERAND_VSR }, + { "vs61", 61, PPC_OPERAND_VSR }, + { "vs62", 62, PPC_OPERAND_VSR }, + { "vs63", 63, PPC_OPERAND_VSR }, + { "vs7", 7, PPC_OPERAND_VSR }, + { "vs8", 8, PPC_OPERAND_VSR }, + { "vs9", 9, PPC_OPERAND_VSR }, + + { "xer", 1, PPC_OPERAND_SPR } }; #define REG_NAME_CNT (sizeof (pre_defined_registers) / sizeof (struct pd_reg)) @@ -811,7 +807,7 @@ static const struct pd_reg pre_defined_registers[] = /* Given NAME, find the register number associated with that name, return the integer value associated with the given name or -1 on failure. */ -static int +static const struct pd_reg * reg_name_search (const struct pd_reg *regs, int regcount, const char *name) { int middle, low, high; @@ -829,11 +825,11 @@ reg_name_search (const struct pd_reg *regs, int regcount, const char *name) else if (cmp > 0) low = middle + 1; else - return regs[middle].value; + return ®s[middle]; } while (low <= high); - return -1; + return NULL; } /* @@ -851,7 +847,7 @@ reg_name_search (const struct pd_reg *regs, int regcount, const char *name) static bfd_boolean register_name (expressionS *expressionP) { - int reg_number; + const struct pd_reg *reg; char *name; char *start; char c; @@ -865,16 +861,17 @@ register_name (expressionS *expressionP) return FALSE; c = get_symbol_name (&name); - reg_number = reg_name_search (pre_defined_registers, REG_NAME_CNT, name); + reg = reg_name_search (pre_defined_registers, REG_NAME_CNT, name); /* Put back the delimiting char. */ *input_line_pointer = c; /* Look to see if it's in the register table. */ - if (reg_number >= 0) + if (reg != NULL) { expressionP->X_op = O_register; - expressionP->X_add_number = reg_number; + expressionP->X_add_number = reg->value; + expressionP->X_md = reg->flags; /* Make the rest nice. */ expressionP->X_add_symbol = NULL; @@ -897,19 +894,19 @@ static bfd_boolean cr_operand; /* Names to recognize in a condition code. This table is sorted. */ static const struct pd_reg cr_names[] = { - { "cr0", 0 }, - { "cr1", 1 }, - { "cr2", 2 }, - { "cr3", 3 }, - { "cr4", 4 }, - { "cr5", 5 }, - { "cr6", 6 }, - { "cr7", 7 }, - { "eq", 2 }, - { "gt", 1 }, - { "lt", 0 }, - { "so", 3 }, - { "un", 3 } + { "cr0", 0, PPC_OPERAND_CR_REG }, + { "cr1", 1, PPC_OPERAND_CR_REG }, + { "cr2", 2, PPC_OPERAND_CR_REG }, + { "cr3", 3, PPC_OPERAND_CR_REG }, + { "cr4", 4, PPC_OPERAND_CR_REG }, + { "cr5", 5, PPC_OPERAND_CR_REG }, + { "cr6", 6, PPC_OPERAND_CR_REG }, + { "cr7", 7, PPC_OPERAND_CR_REG }, + { "eq", 2, PPC_OPERAND_CR_BIT }, + { "gt", 1, PPC_OPERAND_CR_BIT }, + { "lt", 0, PPC_OPERAND_CR_BIT }, + { "so", 3, PPC_OPERAND_CR_BIT }, + { "un", 3, PPC_OPERAND_CR_BIT } }; /* Parsing function. This returns non-zero if it recognized an @@ -918,23 +915,78 @@ static const struct pd_reg cr_names[] = int ppc_parse_name (const char *name, expressionS *exp) { - int val; + const struct pd_reg *reg; if (! cr_operand) return 0; if (*name == '%') ++name; - val = reg_name_search (cr_names, sizeof cr_names / sizeof cr_names[0], + reg = reg_name_search (cr_names, sizeof cr_names / sizeof cr_names[0], name); - if (val < 0) + if (reg == NULL) return 0; - exp->X_op = O_constant; - exp->X_add_number = val; + exp->X_op = O_register; + exp->X_add_number = reg->value; + exp->X_md = reg->flags; return 1; } + +/* Propagate X_md and check register expressions. This is to support + condition codes like 4*cr5+eq. */ + +int +ppc_optimize_expr (expressionS *left, operatorT op, expressionS *right) +{ + /* Accept 4*cr and cr*4. */ + if (op == O_multiply + && ((right->X_op == O_register + && right->X_md == PPC_OPERAND_CR_REG + && left->X_op == O_constant + && left->X_add_number == 4) + || (left->X_op == O_register + && left->X_md == PPC_OPERAND_CR_REG + && right->X_op == O_constant + && right->X_add_number == 4))) + { + left->X_op = O_register; + left->X_md = PPC_OPERAND_CR_REG | PPC_OPERAND_CR_BIT; + left->X_add_number *= right->X_add_number; + return 1; + } + + /* Accept the above plus , and plus the above. */ + if (right->X_op == O_register + && left->X_op == O_register + && op == O_add + && ((right->X_md == PPC_OPERAND_CR_BIT + && left->X_md == (PPC_OPERAND_CR_REG | PPC_OPERAND_CR_BIT)) + || (right->X_md == (PPC_OPERAND_CR_REG | PPC_OPERAND_CR_BIT) + && left->X_md == PPC_OPERAND_CR_BIT))) + { + left->X_md = PPC_OPERAND_CR_BIT; + right->X_op = O_constant; + return 0; + } + + /* Accept reg +/- constant. */ + if (left->X_op == O_register + && !((op == O_add || op == O_subtract) && right->X_op == O_constant)) + as_bad (_("invalid register expression")); + + /* Accept constant + reg. */ + if (right->X_op == O_register) + { + if (op == O_add && left->X_op == O_constant) + left->X_md = right->X_md; + else + as_bad (_("invalid register expression")); + } + + return 0; +} /* Local variables. */ @@ -2916,7 +2968,16 @@ md_assemble (char *str) as_bad (_("missing operand")); else if (ex.X_op == O_register) { - insn = ppc_insert_operand (insn, operand, ex.X_add_number, + if ((ex.X_md + & ~operand->flags + & (PPC_OPERAND_GPR | PPC_OPERAND_FPR | PPC_OPERAND_VR + | PPC_OPERAND_VSR | PPC_OPERAND_CR_BIT | PPC_OPERAND_CR_REG + | PPC_OPERAND_SPR | PPC_OPERAND_GQR)) != 0 + && !((ex.X_md & PPC_OPERAND_GPR) != 0 + && ex.X_add_number != 0 + && (operand->flags & PPC_OPERAND_GPR_0) != 0)) + as_bad (_("invalid register expression")); + insn = ppc_insert_operand (insn, operand, ex.X_add_number & 0xff, ppc_cpu, (char *) NULL, 0); } else if (ex.X_op == O_constant) diff --git a/gas/config/tc-ppc.h b/gas/config/tc-ppc.h index e739f9c8670..077224bef2f 100644 --- a/gas/config/tc-ppc.h +++ b/gas/config/tc-ppc.h @@ -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 () diff --git a/include/ChangeLog b/include/ChangeLog index 8bcb0cf7b3d..e90166ce1c2 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,9 @@ +2017-02-14 Alan Modra + + PR 21118 + * opcode/ppc.h (PPC_OPERAND_*): Reassign values, regs first. + (PPC_OPERAND_SPR, PPC_OPERAND_GQR): Define. + 2017-01-24 Dimitar Dimitrov * opcode/hppa.h: Clarify that file is part of GNU opcodes. diff --git a/include/opcode/ppc.h b/include/opcode/ppc.h index a32dae2f5f4..34cf27ed424 100644 --- a/include/opcode/ppc.h +++ b/include/opcode/ppc.h @@ -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 takes signed values. */ -#define PPC_OPERAND_SIGNED (0x1) +/* This operand names a register. The disassembler uses this to print + register names with a leading 'r'. */ +#define PPC_OPERAND_GPR (0x1) -/* 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) +/* Like PPC_OPERAND_GPR, but don't print a leading 'r' for r0. */ +#define PPC_OPERAND_GPR_0 (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) +/* This operand names a floating point register. The disassembler + prints these with a leading 'f'. */ +#define PPC_OPERAND_FPR (0x4) -/* 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 names a vector unit register. The disassembler + prints these with a leading 'v'. */ +#define PPC_OPERAND_VR (0x8) -/* This operand may use the symbolic names for the CR fields, which - are +/* 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 (0x10) +#define PPC_OPERAND_CR_BIT (0x20) -/* This operand names a register. The disassembler uses this to print - register names with a leading 'r'. */ -#define PPC_OPERAND_GPR (0x20) +/* This is a CR FIELD that does not use symbolic names (unless + -mregnames is in effect). */ +#define PPC_OPERAND_CR_REG (0x40) -/* Like PPC_OPERAND_GPR, but don't print a leading 'r' for r0. */ -#define PPC_OPERAND_GPR_0 (0x40) +/* This operand names a special purpose register. */ +#define PPC_OPERAND_SPR (0x80) -/* This operand names a floating point register. The disassembler - prints these with a leading 'f'. */ -#define PPC_OPERAND_FPR (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 (0x100) +#define PPC_OPERAND_RELATIVE (0x200) /* 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) +#define PPC_OPERAND_ABSOLUTE (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 takes signed values. */ +#define PPC_OPERAND_SIGNED (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 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 (0x1000) -/* This operand names a vector unit register. The disassembler - prints these with a leading 'v'. */ -#define PPC_OPERAND_VR (0x2000) +/* 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 (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 diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index fc6637b5640..eafd7d20060 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,9 @@ +2017-02-14 Alan Modra + + 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 Alan Modra diff --git a/opcodes/ppc-opc.c b/opcodes/ppc-opc.c index 9ac779c96ae..68d978b4516 100644 --- a/opcodes/ppc-opc.c +++ b/opcodes/ppc-opc.c @@ -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