Update year range in copyright notice of binutils files
[deliverable/binutils-gdb.git] / gas / config / tc-ppc.c
index ccc627cfe993962278fe817c3456b26f237cfda8..35da05c510e5f664368b2f22fa2a0616f86b425c 100644 (file)
@@ -1,5 +1,5 @@
 /* tc-ppc.c -- Assemble for the PowerPC or POWER (RS/6000)
-   Copyright (C) 1994-2017 Free Software Foundation, Inc.
+   Copyright (C) 1994-2018 Free Software Foundation, Inc.
    Written by Ian Lance Taylor, Cygnus Support.
 
    This file is part of GAS, the GNU Assembler.
@@ -217,7 +217,7 @@ static enum {
 
 /* Warn on emitting data to code sections.  */
 int warn_476;
-unsigned long last_insn;
+uint64_t last_insn;
 segT last_seg;
 subsegT last_subseg;
 \f
@@ -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 &regs[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_warn (_("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_warn (_("invalid register expression"));
+    }
+
+  return 0;
+}
 \f
 /* Local variables.  */
 
@@ -1141,7 +1193,8 @@ md_parse_option (int c, const char *arg)
 
     case 'm':
       new_cpu = ppc_parse_cpu (ppc_cpu, &sticky, arg);
-      if (new_cpu != 0)
+      /* "raw" is only valid for the disassembler.  */
+      if (new_cpu != 0 && (new_cpu & PPC_OPCODE_RAW) == 0)
        {
          ppc_cpu = new_cpu;
          if (strcmp (arg, "vle") == 0)
@@ -1153,6 +1206,16 @@ md_parse_option (int c, const char *arg)
            }
        }
 
+      else if (strcmp (arg, "no-vle") == 0)
+       {
+         sticky &= ~PPC_OPCODE_VLE;
+
+         new_cpu = ppc_parse_cpu (ppc_cpu, &sticky, "booke");
+         new_cpu &= ~PPC_OPCODE_VLE;
+
+         ppc_cpu = new_cpu;
+       }
+
       else if (strcmp (arg, "regnames") == 0)
        reg_names_p = TRUE;
 
@@ -1205,6 +1268,10 @@ md_parse_option (int c, const char *arg)
          msolaris = FALSE;
          ppc_comment_chars = ppc_eabi_comment_chars;
        }
+      else if (strcmp (arg, "spe2") == 0)
+       {
+         ppc_cpu |= PPC_OPCODE_SPE2;
+       }
 #endif
       else
        {
@@ -1293,7 +1360,6 @@ PowerPC options:\n\
   fprintf (stream, _("\
 -maltivec               generate code for AltiVec\n\
 -mvsx                   generate code for Vector-Scalar (VSX) instructions\n\
--mhtm                   generate code for Hardware Transactional Memory\n\
 -me300                  generate code for PowerPC e300 family\n\
 -me500, -me500x2        generate code for Motorola e500 core complex\n\
 -me500mc,               generate code for Freescale e500mc core complex\n\
@@ -1301,6 +1367,7 @@ PowerPC options:\n\
 -me5500,                generate code for Freescale e5500 core complex\n\
 -me6500,                generate code for Freescale e6500 core complex\n\
 -mspe                   generate code for Motorola SPE instructions\n\
+-mspe2                  generate code for Freescale SPE2 instructions\n\
 -mvle                   generate code for Freescale VLE instructions\n\
 -mtitan                 generate code for AppliedMicro Titan core complex\n\
 -mregnames              Allow symbolic names for registers\n\
@@ -1430,7 +1497,7 @@ static bfd_boolean
 insn_validate (const struct powerpc_opcode *op)
 {
   const unsigned char *o;
-  unsigned long omask = op->mask;
+  uint64_t omask = op->mask;
 
   /* The mask had better not trim off opcode bits.  */
   if ((op->opcode & omask) != op->opcode)
@@ -1452,7 +1519,7 @@ insn_validate (const struct powerpc_opcode *op)
          const struct powerpc_operand *operand = &powerpc_operands[*o];
          if (operand->shift != (int) PPC_OPSHIFT_INV)
            {
-             unsigned long mask;
+             uint64_t mask;
 
              if (operand->shift >= 0)
                mask = operand->bitm << operand->shift;
@@ -1503,8 +1570,8 @@ ppc_setup_opcodes (void)
         all the 1's in the mask are contiguous.  */
       for (i = 0; i < num_powerpc_operands; ++i)
        {
-         unsigned long mask = powerpc_operands[i].bitm;
-         unsigned long right_bit;
+         uint64_t mask = powerpc_operands[i].bitm;
+         uint64_t right_bit;
          unsigned int j;
 
          right_bit = mask & -mask;
@@ -1537,10 +1604,10 @@ ppc_setup_opcodes (void)
              int new_opcode = PPC_OP (op[0].opcode);
 
 #ifdef PRINT_OPCODE_TABLE
-             printf ("%-14s\t#%04u\tmajor op: 0x%x\top: 0x%x\tmask: 0x%x\tflags: 0x%llx\n",
+             printf ("%-14s\t#%04u\tmajor op: 0x%x\top: 0x%llx\tmask: 0x%llx\tflags: 0x%llx\n",
                      op->name, (unsigned int) (op - powerpc_opcodes),
-                     (unsigned int) new_opcode, (unsigned int) op->opcode,
-                     (unsigned int) op->mask, (unsigned long long) op->flags);
+                     (unsigned int) new_opcode, (unsigned long long) op->opcode,
+                     (unsigned long long) op->mask, (unsigned long long) op->flags);
 #endif
 
              /* The major opcodes had better be sorted.  Code in the
@@ -1602,10 +1669,10 @@ ppc_setup_opcodes (void)
              new_seg = VLE_OP_TO_SEG (new_seg);
 
 #ifdef PRINT_OPCODE_TABLE
-             printf ("%-14s\t#%04u\tmajor op: 0x%x\top: 0x%x\tmask: 0x%x\tflags: 0x%llx\n",
+             printf ("%-14s\t#%04u\tmajor op: 0x%x\top: 0x%llx\tmask: 0x%llx\tflags: 0x%llx\n",
                      op->name, (unsigned int) (op - powerpc_opcodes),
-                     (unsigned int) new_seg, (unsigned int) op->opcode,
-                     (unsigned int) op->mask, (unsigned long long) op->flags);
+                     (unsigned int) new_seg, (unsigned long long) op->opcode,
+                     (unsigned long long) op->mask, (unsigned long long) op->flags);
 #endif
              /* The major opcodes had better be sorted.  Code in the
                 disassembler assumes the insns are sorted according to
@@ -1636,6 +1703,54 @@ ppc_setup_opcodes (void)
        }
     }
 
+  /* SPE2 instructions */
+  if ((ppc_cpu & PPC_OPCODE_SPE2) == PPC_OPCODE_SPE2)
+    {
+      op_end = spe2_opcodes + spe2_num_opcodes;
+      for (op = spe2_opcodes; op < op_end; op++)
+       {
+         if (ENABLE_CHECKING)
+           {
+             if (op != spe2_opcodes)
+               {
+               unsigned old_seg, new_seg;
+
+               old_seg = VLE_OP (op[-1].opcode, op[-1].mask);
+               old_seg = VLE_OP_TO_SEG (old_seg);
+               new_seg = VLE_OP (op[0].opcode, op[0].mask);
+               new_seg = VLE_OP_TO_SEG (new_seg);
+
+               /* The major opcodes had better be sorted.  Code in the
+                   disassembler assumes the insns are sorted according to
+                   major opcode.  */
+               if (new_seg < old_seg)
+                 {
+                 as_bad (_("major opcode is not sorted for %s"), op->name);
+                 bad_insn = TRUE;
+                 }
+               }
+
+             bad_insn |= insn_validate (op);
+           }
+
+         if ((ppc_cpu & op->flags) != 0 && !(ppc_cpu & op->deprecated))
+           {
+             const char *retval;
+
+             retval = hash_insert (ppc_hash, op->name, (void *) op);
+             if (retval != NULL)
+               {
+                 as_bad (_("duplicate instruction %s"),
+                         op->name);
+                 bad_insn = TRUE;
+               }
+           }
+       }
+
+      for (op = spe2_opcodes; op < op_end; op++)
+       hash_insert (ppc_hash, op->name, (void *) op);
+    }
+
   /* Insert the macros into a hash table.  */
   ppc_macro_hash = hash_new ();
 
@@ -1769,15 +1884,15 @@ ppc_cleanup (void)
 
 /* Insert an operand value into an instruction.  */
 
-static unsigned long
-ppc_insert_operand (unsigned long insn,
+static uint64_t
+ppc_insert_operand (uint64_t insn,
                    const struct powerpc_operand *operand,
-                   offsetT val,
+                   int64_t val,
                    ppc_cpu_t cpu,
                    const char *file,
                    unsigned int line)
 {
-  long min, max, right;
+  int64_t min, max, right;
 
   max = operand->bitm;
   right = max & -max;
@@ -1806,7 +1921,7 @@ ppc_insert_operand (unsigned long insn,
 
   if ((operand->flags & PPC_OPERAND_NEGATIVE) != 0)
     {
-      long tmp = min;
+      int64_t tmp = min;
       min = -max;
       max = -tmp;
     }
@@ -1819,18 +1934,18 @@ ppc_insert_operand (unsigned long insn,
         sign extend the 32-bit value to 64 bits if so doing makes the
         value valid.  */
       if (val > max
-         && (offsetT) (val - 0x80000000 - 0x80000000) >= min
-         && (offsetT) (val - 0x80000000 - 0x80000000) <= max
-         && ((val - 0x80000000 - 0x80000000) & (right - 1)) == 0)
-       val = val - 0x80000000 - 0x80000000;
+         && (val - (1LL << 32)) >= min
+         && (val - (1LL << 32)) <= max
+         && ((val - (1LL << 32)) & (right - 1)) == 0)
+       val = val - (1LL << 32);
 
       /* Similarly, people write expressions like ~(1<<15), and expect
         this to be OK for a 32-bit unsigned value.  */
       else if (val < min
-              && (offsetT) (val + 0x80000000 + 0x80000000) >= min
-              && (offsetT) (val + 0x80000000 + 0x80000000) <= max
-              && ((val + 0x80000000 + 0x80000000) & (right - 1)) == 0)
-       val = val + 0x80000000 + 0x80000000;
+              && (val + (1LL << 32)) >= min
+              && (val + (1LL << 32)) <= max
+              && ((val + (1LL << 32)) & (right - 1)) == 0)
+       val = val + (1LL << 32);
 
       else if (val < min
               || val > max
@@ -1843,14 +1958,14 @@ ppc_insert_operand (unsigned long insn,
       const char *errmsg;
 
       errmsg = NULL;
-      insn = (*operand->insert) (insn, (long) val, cpu, &errmsg);
+      insn = (*operand->insert) (insn, val, cpu, &errmsg);
       if (errmsg != (const char *) NULL)
        as_bad_where (file, line, "%s", errmsg);
     }
   else if (operand->shift >= 0)
-    insn |= ((long) val & operand->bitm) << operand->shift;
+    insn |= (val & operand->bitm) << operand->shift;
   else
-    insn |= ((long) val & operand->bitm) >> -operand->shift;
+    insn |= (val & operand->bitm) >> -operand->shift;
 
   return insn;
 }
@@ -2624,7 +2739,7 @@ md_assemble (char *str)
 {
   char *s;
   const struct powerpc_opcode *opcode;
-  unsigned long insn;
+  uint64_t insn;
   const unsigned char *opindex_ptr;
   int skip_optional;
   int need_paren;
@@ -2753,7 +2868,7 @@ md_assemble (char *str)
          && !((operand->flags & PPC_OPERAND_OPTIONAL32) != 0 && ppc_obj64)
          && skip_optional)
        {
-         long val = ppc_optional_operand_value (operand);
+         int64_t val = ppc_optional_operand_value (operand);
          if (operand->insert)
            {
              insn = (*operand->insert) (insn, val, ppc_cpu, &errmsg);
@@ -2761,9 +2876,9 @@ md_assemble (char *str)
                as_bad ("%s", errmsg);
            }
          else if (operand->shift >= 0)
-           insn |= ((long) val & operand->bitm) << operand->shift;
+           insn |= (val & operand->bitm) << operand->shift;
          else
-           insn |= ((long) val & operand->bitm) >> -operand->shift;
+           insn |= (val & operand->bitm) >> -operand->shift;
 
          if ((operand->flags & PPC_OPERAND_NEXT) != 0)
            next_opindex = *opindex_ptr + 1;
@@ -2916,6 +3031,15 @@ md_assemble (char *str)
        as_bad (_("missing operand"));
       else if (ex.X_op == O_register)
        {
+         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_warn (_("invalid register expression"));
          insn = ppc_insert_operand (insn, operand, ex.X_add_number,
                                     ppc_cpu, (char *) NULL, 0);
        }
@@ -3090,12 +3214,12 @@ md_assemble (char *str)
              /* addpcis.  */
              if (opcode->opcode == (19 << 26) + (2 << 1)
                  && reloc == BFD_RELOC_HI16_S)
-               reloc = BFD_RELOC_PPC_REL16DX_HA;
+               reloc = BFD_RELOC_PPC_16DX_HA;
 
              /* If VLE-mode convert LO/HI/HA relocations.  */
              if (opcode->flags & PPC_OPCODE_VLE)
                {
-                 int tmp_insn = insn & opcode->mask;
+                 uint64_t tmp_insn = insn & opcode->mask;
 
                  int use_a_reloc = (tmp_insn == E_OR2I_INSN
                                     || tmp_insn == E_AND2I_DOT_INSN
@@ -3569,6 +3693,16 @@ ppc_section_flags (flagword flags, bfd_vma attr ATTRIBUTE_UNUSED, int type)
 
   return flags;
 }
+
+bfd_vma
+ppc_elf_section_letter (int letter, const char **ptrmsg)
+{
+  if (letter == 'v')
+    return SHF_PPC_VLE;
+
+  *ptrmsg = _("bad .section directive: want a,e,v,w,x,M,S,G,T in string");
+  return -1;
+}
 #endif /* OBJ_ELF */
 
 \f
@@ -6505,10 +6639,50 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg)
     }
 #endif
 
-  if (fixP->fx_subsy != (symbolS *) NULL)
+  /* We are only able to convert some relocs to pc-relative.  */
+  if (fixP->fx_pcrel)
+    {
+      switch (fixP->fx_r_type)
+       {
+       case BFD_RELOC_LO16:
+         fixP->fx_r_type = BFD_RELOC_LO16_PCREL;
+         break;
+
+       case BFD_RELOC_HI16:
+         fixP->fx_r_type = BFD_RELOC_HI16_PCREL;
+         break;
+
+       case BFD_RELOC_HI16_S:
+         fixP->fx_r_type = BFD_RELOC_HI16_S_PCREL;
+         break;
+
+       case BFD_RELOC_64:
+         fixP->fx_r_type = BFD_RELOC_64_PCREL;
+         break;
+
+       case BFD_RELOC_32:
+         fixP->fx_r_type = BFD_RELOC_32_PCREL;
+         break;
+
+       case BFD_RELOC_16:
+         fixP->fx_r_type = BFD_RELOC_16_PCREL;
+         break;
+
+       case BFD_RELOC_PPC_16DX_HA:
+         fixP->fx_r_type = BFD_RELOC_PPC_REL16DX_HA;
+         break;
+
+       default:
+         break;
+       }
+    }
+  else if (!fixP->fx_done
+          && fixP->fx_r_type == BFD_RELOC_PPC_16DX_HA)
     {
-      /* We can't actually support subtracting a symbol.  */
-      as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex"));
+      /* addpcis is relative to next insn address.  */
+      value -= 4;
+      fixP->fx_r_type = BFD_RELOC_PPC_REL16DX_HA;
+      fixP->fx_pcrel = 1;
     }
 
   operand = NULL;
@@ -6590,6 +6764,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg)
 
     case BFD_RELOC_HI16_S:
     case BFD_RELOC_HI16_S_PCREL:
+    case BFD_RELOC_PPC_16DX_HA:
     case BFD_RELOC_PPC_REL16DX_HA:
 #ifdef OBJ_ELF
       if (REPORT_OVERFLOW_HI && ppc_obj64)
@@ -7017,83 +7192,6 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg)
                       _("data in executable section"));
     }
 
-  /* We are only able to convert some relocs to pc-relative.  */
-  if (!fixP->fx_done && fixP->fx_pcrel)
-    {
-      switch (fixP->fx_r_type)
-       {
-       case BFD_RELOC_LO16:
-         fixP->fx_r_type = BFD_RELOC_LO16_PCREL;
-         break;
-
-       case BFD_RELOC_HI16:
-         fixP->fx_r_type = BFD_RELOC_HI16_PCREL;
-         break;
-
-       case BFD_RELOC_HI16_S:
-         fixP->fx_r_type = BFD_RELOC_HI16_S_PCREL;
-         break;
-
-       case BFD_RELOC_64:
-         fixP->fx_r_type = BFD_RELOC_64_PCREL;
-         break;
-
-       case BFD_RELOC_32:
-         fixP->fx_r_type = BFD_RELOC_32_PCREL;
-         break;
-
-       case BFD_RELOC_16:
-         fixP->fx_r_type = BFD_RELOC_16_PCREL;
-         break;
-
-         /* Some of course are already pc-relative.  */
-       case BFD_RELOC_LO16_PCREL:
-       case BFD_RELOC_HI16_PCREL:
-       case BFD_RELOC_HI16_S_PCREL:
-       case BFD_RELOC_PPC_REL16DX_HA:
-       case BFD_RELOC_64_PCREL:
-       case BFD_RELOC_32_PCREL:
-       case BFD_RELOC_16_PCREL:
-       case BFD_RELOC_PPC_B16:
-       case BFD_RELOC_PPC_B16_BRTAKEN:
-       case BFD_RELOC_PPC_B16_BRNTAKEN:
-       case BFD_RELOC_PPC_B26:
-       case BFD_RELOC_PPC_LOCAL24PC:
-       case BFD_RELOC_24_PLT_PCREL:
-       case BFD_RELOC_32_PLT_PCREL:
-       case BFD_RELOC_64_PLT_PCREL:
-       case BFD_RELOC_PPC_VLE_REL8:
-       case BFD_RELOC_PPC_VLE_REL15:
-       case BFD_RELOC_PPC_VLE_REL24:
-         break;
-
-       default:
-         if (fixP->fx_addsy)
-           {
-             const char *sfile;
-             unsigned int sline;
-
-             /* Use expr_symbol_where to see if this is an
-                expression symbol.  */
-             if (expr_symbol_where (fixP->fx_addsy, &sfile, &sline))
-               as_bad_where (fixP->fx_file, fixP->fx_line,
-                             _("unresolved expression that must"
-                               " be resolved"));
-             else
-               as_bad_where (fixP->fx_file, fixP->fx_line,
-                             _("cannot emit PC relative %s relocation"
-                               " against %s"),
-                             bfd_get_reloc_code_name (fixP->fx_r_type),
-                             S_GET_NAME (fixP->fx_addsy));
-           }
-         else
-           as_bad_where (fixP->fx_file, fixP->fx_line,
-                         _("unable to resolve expression"));
-         fixP->fx_done = 1;
-         break;
-       }
-    }
-
 #ifdef OBJ_ELF
   ppc_elf_validate_fix (fixP, seg);
   fixP->fx_addnumber = value;
This page took 0.057134 seconds and 4 git commands to generate.