This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
PowerPC register expression checks
- From: Alan Modra <amodra at gmail dot com>
- To: binutils at sourceware dot org
- Date: Tue, 14 Feb 2017 21:11:21 +1030
- Subject: PowerPC register expression checks
- Authentication-results: sourceware.org; auth=none
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/NEWS b/gas/NEWS
index e95a9d8..ef0780d 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 ccc627c..fd5cc35 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<n> and cr<n>*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 <cr bit>, and <cr bit> 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 e739f9c..077224b 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/opcode/ppc.h b/include/opcode/ppc.h
index a32dae2..34cf27e 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/ppc-opc.c b/opcodes/ppc-opc.c
index 9ac779c..68d978b 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
--
Alan Modra
Australia Development Lab, IBM