From 69fe9ce501f5fde501443648fe4243dc9fe8d5b1 Mon Sep 17 00:00:00 2001
From: Alan Modra <amodra@gmail.com>
Date: Tue, 10 Mar 2009 06:53:46 +0000
Subject: [PATCH] include/opcode/ 	* ppc.h (ppc_parse_cpu): Declare.
 opcodes/ 	* ppc-dis.c: Include "opintl.h". 	(struct ppc_mopt,
 ppc_opts): New. 	(ppc_parse_cpu): New function. 
 (powerpc_init_dialect): Use it. 	(print_ppc_disassembler_options): Dump
 options from ppc_opts. 	Internationalize message. gas/ 	*
 config/tc-ppc.c (parse_cpu): Delete. 	(md_parse_option, ppc_machine): Use
 ppc_parse_cpu. gas/testsuite/ 	* gas/ppc/altivec_and_spe.d (objdump): Add
 -Maltivec. 	* gas/ppc/common.d: Adjust for -Mcom not including -Mppc.

---
 gas/ChangeLog                           |   5 +
 gas/config/tc-ppc.c                     | 159 +------------
 gas/testsuite/ChangeLog                 |   5 +
 gas/testsuite/gas/ppc/altivec_and_spe.d |   2 +-
 gas/testsuite/gas/ppc/common.d          | 112 ++++-----
 include/opcode/ChangeLog                |   4 +
 include/opcode/ppc.h                    |   4 +-
 opcodes/ChangeLog                       |   9 +
 opcodes/ppc-dis.c                       | 291 ++++++++++++++++--------
 9 files changed, 288 insertions(+), 303 deletions(-)

diff --git a/gas/ChangeLog b/gas/ChangeLog
index 12ad6469b5e..d16cfddb02b 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,8 @@
+2009-03-10  Alan Modra  <amodra@bigpond.net.au>
+
+	* config/tc-ppc.c (parse_cpu): Delete.
+	(md_parse_option, ppc_machine): Use ppc_parse_cpu.
+
 2009-03-09  H.J. Lu  <hongjiu.lu@intel.com>
 
 	PR gas/9915
diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c
index 8b5c662984a..691d9434215 100644
--- a/gas/config/tc-ppc.c
+++ b/gas/config/tc-ppc.c
@@ -1015,157 +1015,11 @@ const struct option md_longopts[] = {
 };
 const size_t md_longopts_size = sizeof (md_longopts);
 
-
-/* Handle -m options that set cpu type, and .machine arg.  */
-
-static int
-parse_cpu (const char *arg)
-{
-  ppc_cpu_t retain_flags =
-    ppc_cpu & (PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX | PPC_OPCODE_SPE);
-
-  /* -mpwrx and -mpwr2 mean to assemble for the IBM POWER/2
-     (RIOS2).  */
-  if (strcmp (arg, "pwrx") == 0 || strcmp (arg, "pwr2") == 0)
-    ppc_cpu = PPC_OPCODE_POWER | PPC_OPCODE_POWER2 | PPC_OPCODE_32;
-  /* -mpwr means to assemble for the IBM POWER (RIOS1).  */
-  else if (strcmp (arg, "pwr") == 0)
-    ppc_cpu = PPC_OPCODE_POWER | PPC_OPCODE_32;
-  /* -m601 means to assemble for the PowerPC 601, which includes
-     instructions that are holdovers from the Power.  */
-  else if (strcmp (arg, "601") == 0)
-    ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC
-	       | PPC_OPCODE_601 | PPC_OPCODE_32);
-  /* -mppc, -mppc32, -m603, and -m604 mean to assemble for the
-     PowerPC 603/604.  */
-  else if (strcmp (arg, "ppc") == 0
-	   || strcmp (arg, "ppc32") == 0
-	   || strcmp (arg, "603") == 0
-	   || strcmp (arg, "604") == 0)
-    ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_32;
-  /* Do all PPC750s have paired single ops?  */
-  else if (strcmp (arg, "750cl") == 0)
-    ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_PPCPS;
-  else if (strcmp (arg, "403") == 0)
-    ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC
-	       | PPC_OPCODE_403 | PPC_OPCODE_32);
-  else if (strcmp (arg, "405") == 0)
-    ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC
-	       | PPC_OPCODE_403 | PPC_OPCODE_405 | PPC_OPCODE_32);
-  else if (strcmp (arg, "440") == 0
-	   || strcmp (arg, "464") == 0)
-    ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_32
-	       | PPC_OPCODE_440 | PPC_OPCODE_ISEL | PPC_OPCODE_RFMCI);
-  else if (strcmp (arg, "7400") == 0
-	   || strcmp (arg, "7410") == 0
-	   || strcmp (arg, "7450") == 0
-	   || strcmp (arg, "7455") == 0)
-    ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC
-	       | PPC_OPCODE_ALTIVEC | PPC_OPCODE_32);
-  else if (strcmp (arg, "e300") == 0)
-    ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_32
-	       | PPC_OPCODE_E300);
-  else if (strcmp (arg, "altivec") == 0)
-    {
-      if (ppc_cpu == 0)
-	ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC;
-
-      retain_flags |= PPC_OPCODE_ALTIVEC;
-    }
-  else if (strcmp (arg, "vsx") == 0)
-    {
-      if (ppc_cpu == 0)
-	ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC;
-
-      retain_flags |= PPC_OPCODE_VSX;
-    }
-  else if (strcmp (arg, "e500") == 0 || strcmp (arg, "e500x2") == 0)
-    {
-      ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_SPE
-		 | PPC_OPCODE_ISEL | PPC_OPCODE_EFS | PPC_OPCODE_BRLOCK
-		 | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK
-		 | PPC_OPCODE_RFMCI | PPC_OPCODE_E500MC);
-    }
-  else if (strcmp (arg, "e500mc") == 0)
-    {
-      ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_ISEL
-		 | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK
-		 | PPC_OPCODE_RFMCI | PPC_OPCODE_E500MC);
-    }
-  else if (strcmp (arg, "spe") == 0)
-    {
-      if (ppc_cpu == 0)
-	ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_EFS;
-
-      retain_flags |= PPC_OPCODE_SPE;
-    }
-  /* -mppc64 and -m620 mean to assemble for the 64-bit PowerPC
-     620.  */
-  else if (strcmp (arg, "ppc64") == 0 || strcmp (arg, "620") == 0)
-    {
-      ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_64;
-    }
-  else if (strcmp (arg, "ppc64bridge") == 0)
-    {
-      ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC
-		 | PPC_OPCODE_64_BRIDGE | PPC_OPCODE_64);
-    }
-  /* -mbooke/-mbooke32 mean enable 32-bit BookE support.  */
-  else if (strcmp (arg, "booke") == 0 || strcmp (arg, "booke32") == 0)
-    {
-      ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_32;
-    }
-  else if (strcmp (arg, "power4") == 0)
-    {
-      ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC
-		 | PPC_OPCODE_64 | PPC_OPCODE_POWER4);
-    }
-  else if (strcmp (arg, "power5") == 0)
-    {
-      ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC
-		 | PPC_OPCODE_64 | PPC_OPCODE_POWER4
-		 | PPC_OPCODE_POWER5);
-    }
-  else if (strcmp (arg, "power6") == 0)
-    {
-      ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC
-		 | PPC_OPCODE_64 | PPC_OPCODE_POWER4
-		 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
-		 | PPC_OPCODE_ALTIVEC);
-    }
-  else if (strcmp (arg, "power7") == 0)
-    {
-      ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC
-		 | PPC_OPCODE_ISEL | PPC_OPCODE_64
-		 | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5
-		 | PPC_OPCODE_POWER6 | PPC_OPCODE_POWER7
-		 | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX);
-    }
-  else if (strcmp (arg, "cell") == 0)
-    {
-      ppc_cpu = (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC
-		 | PPC_OPCODE_64 | PPC_OPCODE_POWER4
-		 | PPC_OPCODE_CELL | PPC_OPCODE_ALTIVEC);
-    }
-  /* -mcom means assemble for the common intersection between Power
-     and PowerPC.  At present, we just allow the union, rather
-     than the intersection.  */
-  else if (strcmp (arg, "com") == 0)
-    ppc_cpu = PPC_OPCODE_COMMON | PPC_OPCODE_32;
-  /* -many means to assemble for any architecture (PWR/PWRX/PPC).  */
-  else if (strcmp (arg, "any") == 0)
-    ppc_cpu |= PPC_OPCODE_ANY;
-  else
-    return 0;
-
-  /* Make sure the the Altivec, VSX and SPE bits are not lost.  */
-  ppc_cpu |= retain_flags;
-  return 1;
-}
-
 int
 md_parse_option (int c, char *arg)
 {
+  ppc_cpu_t new_cpu;
+
   switch (c)
     {
     case 'u':
@@ -1228,8 +1082,8 @@ md_parse_option (int c, char *arg)
       break;
 
     case 'm':
-      if (parse_cpu (arg))
-	;
+      if ((new_cpu = ppc_parse_cpu (ppc_cpu, arg)) != 0)
+	ppc_cpu = new_cpu;
 
       else if (strcmp (arg, "regnames") == 0)
 	reg_names_p = TRUE;
@@ -4427,6 +4281,7 @@ ppc_machine (int ignore ATTRIBUTE_UNUSED)
   if (cpu_string != NULL)
     {
       ppc_cpu_t old_cpu = ppc_cpu;
+      ppc_cpu_t new_cpu;
       char *p;
 
       for (p = cpu_string; *p != 0; p++)
@@ -4449,8 +4304,8 @@ ppc_machine (int ignore ATTRIBUTE_UNUSED)
 	  else
 	    ppc_cpu = cpu_history[--curr_hist];
 	}
-      else if (parse_cpu (cpu_string))
-	;
+      else if ((new_cpu = ppc_parse_cpu (ppc_cpu, cpu_string)) != 0)
+	ppc_cpu = new_cpu;
       else
 	as_bad (_("invalid machine `%s'"), cpu_string);
 
diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog
index 8e828f43475..84aeee30bb8 100644
--- a/gas/testsuite/ChangeLog
+++ b/gas/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2009-03-10  Alan Modra  <amodra@bigpond.net.au>
+
+	* gas/ppc/altivec_and_spe.d (objdump): Add -Maltivec.
+	* gas/ppc/common.d: Adjust for -Mcom not including -Mppc.
+
 2009-03-05  Joseph Myers  <joseph@codesourcery.com>
 
 	* gas/arm/mapmisc.d, gas/arm/mapmisc.dat, gas/arm/mapmisc.s: New.
diff --git a/gas/testsuite/gas/ppc/altivec_and_spe.d b/gas/testsuite/gas/ppc/altivec_and_spe.d
index f7b33565596..45672b875d8 100644
--- a/gas/testsuite/gas/ppc/altivec_and_spe.d
+++ b/gas/testsuite/gas/ppc/altivec_and_spe.d
@@ -1,5 +1,5 @@
 #as: -maltivec -mspe -mppc64 
-#objdump: -d -Mppc64
+#objdump: -d -Maltivec -Mppc64
 #name: Check that ISA extensions can be specified before CPU selection
 
 .*: +file format elf.*-powerpc.*
diff --git a/gas/testsuite/gas/ppc/common.d b/gas/testsuite/gas/ppc/common.d
index d5f325784be..cf7f818d08c 100644
--- a/gas/testsuite/gas/ppc/common.d
+++ b/gas/testsuite/gas/ppc/common.d
@@ -13,10 +13,10 @@ Disassembly of section \.text:
    8:	7d cd 78 78 	andc    r13,r14,r15
    c:	7e 30 90 79 	andc.   r16,r17,r18
   10:	48 00 00 02 	ba      0 <start>
-  14:	40 01 00 00 	bdnzf-  gt,14 <start\+0x14>
-  18:	40 85 00 02 	blea-   cr1,0 <start>
-  1c:	40 43 00 01 	bdzfl-  so,1c <start\+0x1c>
-  20:	41 47 00 03 	bdztla- 4\*cr1\+so,0 <start>
+  14:	40 01 00 00 	bdnzf-  1,14 <start\+0x14>
+  18:	40 85 00 02 	blea-   1,0 <start>
+  1c:	40 43 00 01 	bdzfl-  3,1c <start\+0x1c>
+  20:	41 47 00 03 	bdztla- 7,0 <start>
   24:	4e 80 04 20 	bctr
   28:	4e 80 04 21 	bctrl
   2c:	42 40 00 02 	bdza-   0 <start>
@@ -24,62 +24,62 @@ Disassembly of section \.text:
   34:	42 40 00 03 	bdzla-  0 <start>
   38:	42 40 00 01 	bdzl-   38 <start\+0x38>
   3c:	41 82 00 00 	beq-    3c <start\+0x3c>
-  40:	41 8a 00 02 	beqa-   cr2,0 <start>
-  44:	41 86 00 01 	beql-   cr1,44 <start\+0x44>
-  48:	41 8e 00 03 	beqla-  cr3,0 <start>
+  40:	41 8a 00 02 	beqa-   2,0 <start>
+  44:	41 86 00 01 	beql-   1,44 <start\+0x44>
+  48:	41 8e 00 03 	beqla-  3,0 <start>
   4c:	40 80 00 00 	bge-    4c <start\+0x4c>
-  50:	40 90 00 02 	bgea-   cr4,0 <start>
-  54:	40 88 00 01 	bgel-   cr2,54 <start\+0x54>
-  58:	40 98 00 03 	bgela-  cr6,0 <start>
-  5c:	41 91 00 00 	bgt-    cr4,5c <start\+0x5c>
-  60:	41 99 00 02 	bgta-   cr6,0 <start>
-  64:	41 95 00 01 	bgtl-   cr5,64 <start\+0x64>
-  68:	41 9d 00 03 	bgtla-  cr7,0 <start>
+  50:	40 90 00 02 	bgea-   4,0 <start>
+  54:	40 88 00 01 	bgel-   2,54 <start\+0x54>
+  58:	40 98 00 03 	bgela-  6,0 <start>
+  5c:	41 91 00 00 	bgt-    4,5c <start\+0x5c>
+  60:	41 99 00 02 	bgta-   6,0 <start>
+  64:	41 95 00 01 	bgtl-   5,64 <start\+0x64>
+  68:	41 9d 00 03 	bgtla-  7,0 <start>
   6c:	48 00 00 00 	b       6c <start\+0x6c>
   70:	48 00 00 03 	bla     0 <start>
   74:	40 81 00 00 	ble-    74 <start\+0x74>
-  78:	40 91 00 02 	blea-   cr4,0 <start>
-  7c:	40 89 00 01 	blel-   cr2,7c <start\+0x7c>
-  80:	40 99 00 03 	blela-  cr6,0 <start>
+  78:	40 91 00 02 	blea-   4,0 <start>
+  7c:	40 89 00 01 	blel-   2,7c <start\+0x7c>
+  80:	40 99 00 03 	blela-  6,0 <start>
   84:	48 00 00 01 	bl      84 <start\+0x84>
   88:	41 80 00 00 	blt-    88 <start\+0x88>
-  8c:	41 88 00 02 	blta-   cr2,0 <start>
-  90:	41 84 00 01 	bltl-   cr1,90 <start\+0x90>
-  94:	41 8c 00 03 	bltla-  cr3,0 <start>
+  8c:	41 88 00 02 	blta-   2,0 <start>
+  90:	41 84 00 01 	bltl-   1,90 <start\+0x90>
+  94:	41 8c 00 03 	bltla-  3,0 <start>
   98:	40 82 00 00 	bne-    98 <start\+0x98>
-  9c:	40 8a 00 02 	bnea-   cr2,0 <start>
-  a0:	40 86 00 01 	bnel-   cr1,a0 <start\+0xa0>
-  a4:	40 8e 00 03 	bnela-  cr3,0 <start>
-  a8:	40 85 00 00 	ble-    cr1,a8 <start\+0xa8>
-  ac:	40 95 00 02 	blea-   cr5,0 <start>
-  b0:	40 8d 00 01 	blel-   cr3,b0 <start\+0xb0>
-  b4:	40 9d 00 03 	blela-  cr7,0 <start>
-  b8:	40 84 00 00 	bge-    cr1,b8 <start\+0xb8>
-  bc:	40 94 00 02 	bgea-   cr5,0 <start>
-  c0:	40 8c 00 01 	bgel-   cr3,c0 <start\+0xc0>
-  c4:	40 9c 00 03 	bgela-  cr7,0 <start>
-  c8:	40 93 00 00 	bns-    cr4,c8 <start\+0xc8>
-  cc:	40 9b 00 02 	bnsa-   cr6,0 <start>
-  d0:	40 97 00 01 	bnsl-   cr5,d0 <start\+0xd0>
-  d4:	40 9f 00 03 	bnsla-  cr7,0 <start>
-  d8:	41 93 00 00 	bso-    cr4,d8 <start\+0xd8>
-  dc:	41 9b 00 02 	bsoa-   cr6,0 <start>
-  e0:	41 97 00 01 	bsol-   cr5,e0 <start\+0xe0>
-  e4:	41 9f 00 03 	bsola-  cr7,0 <start>
-  e8:	4c 85 32 02 	crand   4\*cr1\+lt,4\*cr1\+gt,4\*cr1\+eq
-  ec:	4c 64 29 02 	crandc  so,4\*cr1\+lt,4\*cr1\+gt
-  f0:	4c e0 0a 42 	creqv   4\*cr1\+so,lt,gt
-  f4:	4c 22 19 c2 	crnand  gt,eq,so
-  f8:	4c 01 10 42 	crnor   lt,gt,eq
-  fc:	4c a6 3b 82 	cror    4\*cr1\+gt,4\*cr1\+eq,4\*cr1\+so
- 100:	4c 43 23 42 	crorc   eq,so,4\*cr1\+lt
- 104:	4c c7 01 82 	crxor   4\*cr1\+eq,4\*cr1\+so,lt
+  9c:	40 8a 00 02 	bnea-   2,0 <start>
+  a0:	40 86 00 01 	bnel-   1,a0 <start\+0xa0>
+  a4:	40 8e 00 03 	bnela-  3,0 <start>
+  a8:	40 85 00 00 	ble-    1,a8 <start\+0xa8>
+  ac:	40 95 00 02 	blea-   5,0 <start>
+  b0:	40 8d 00 01 	blel-   3,b0 <start\+0xb0>
+  b4:	40 9d 00 03 	blela-  7,0 <start>
+  b8:	40 84 00 00 	bge-    1,b8 <start\+0xb8>
+  bc:	40 94 00 02 	bgea-   5,0 <start>
+  c0:	40 8c 00 01 	bgel-   3,c0 <start\+0xc0>
+  c4:	40 9c 00 03 	bgela-  7,0 <start>
+  c8:	40 93 00 00 	bns-    4,c8 <start\+0xc8>
+  cc:	40 9b 00 02 	bnsa-   6,0 <start>
+  d0:	40 97 00 01 	bnsl-   5,d0 <start\+0xd0>
+  d4:	40 9f 00 03 	bnsla-  7,0 <start>
+  d8:	41 93 00 00 	bso-    4,d8 <start\+0xd8>
+  dc:	41 9b 00 02 	bsoa-   6,0 <start>
+  e0:	41 97 00 01 	bsol-   5,e0 <start\+0xe0>
+  e4:	41 9f 00 03 	bsola-  7,0 <start>
+  e8:	4c 85 32 02 	crand   4,5,6
+  ec:	4c 64 29 02 	crandc  3,4,5
+  f0:	4c e0 0a 42 	creqv   7,0,1
+  f4:	4c 22 19 c2 	crnand  1,2,3
+  f8:	4c 01 10 42 	crnor   0,1,2
+  fc:	4c a6 3b 82 	cror    5,6,7
+ 100:	4c 43 23 42 	crorc   2,3,4
+ 104:	4c c7 01 82 	crxor   6,7,0
  108:	7d 6a 62 39 	eqv.    r10,r11,r12
  10c:	7d 6a 62 38 	eqv     r10,r11,r12
  110:	fe a0 fa 11 	fabs.   f21,f31
  114:	fe a0 fa 10 	fabs    f21,f31
- 118:	fd 8a 58 40 	fcmpo   cr3,f10,f11
- 11c:	fd 84 28 00 	fcmpu   cr3,f4,f5
+ 118:	fd 8a 58 40 	fcmpo   3,f10,f11
+ 11c:	fd 84 28 00 	fcmpu   3,f4,f5
  120:	fc 60 20 91 	fmr.    f3,f4
  124:	fc 60 20 90 	fmr     f3,f4
  128:	fe 80 f1 11 	fnabs.  f20,f30
@@ -109,9 +109,9 @@ Disassembly of section \.text:
  188:	a5 c1 00 02 	lhzu    r14,2\(r1\)
  18c:	7e 96 c2 6e 	lhzux   r20,r22,r24
  190:	7e f8 ca 2e 	lhzx    r23,r24,r25
- 194:	4c 04 00 00 	mcrf    cr0,cr1
- 198:	fd 90 00 80 	mcrfs   cr3,cr4
- 19c:	7d 80 04 00 	mcrxr   cr3
+ 194:	4c 04 00 00 	mcrf    0,1
+ 198:	fd 90 00 80 	mcrfs   3,4
+ 19c:	7d 80 04 00 	mcrxr   3
  1a0:	7c 60 00 26 	mfcr    r3
  1a4:	7c 69 02 a6 	mfctr   r3
  1a8:	7c b3 02 a6 	mfdar   r5
@@ -136,10 +136,10 @@ Disassembly of section \.text:
  1f4:	7e b3 03 a6 	mtdar   r21
  1f8:	7f 16 03 a6 	mtdec   r24
  1fc:	7e 92 03 a6 	mtdsisr r20
- 200:	fc 60 00 8d 	mtfsb0. so
- 204:	fc 60 00 8c 	mtfsb0  so
- 208:	fc 60 00 4d 	mtfsb1. so
- 20c:	fc 60 00 4c 	mtfsb1  so
+ 200:	fc 60 00 8d 	mtfsb0. 3
+ 204:	fc 60 00 8c 	mtfsb0  3
+ 208:	fc 60 00 4d 	mtfsb1. 3
+ 20c:	fc 60 00 4c 	mtfsb1  3
  210:	fc 0c 55 8e 	mtfsf   6,f10
  214:	fc 0c 5d 8f 	mtfsf.  6,f11
  218:	ff 00 01 0c 	mtfsfi  6,0
diff --git a/include/opcode/ChangeLog b/include/opcode/ChangeLog
index 2a03208a94f..d974f2dfc01 100644
--- a/include/opcode/ChangeLog
+++ b/include/opcode/ChangeLog
@@ -1,3 +1,7 @@
+2009-03-10  Alan Modra  <amodra@bigpond.net.au>
+
+	* ppc.h (ppc_parse_cpu): Declare.
+
 2009-03-02  Qinwei  <qinwei@sunnorth.com.cn>
 
 	* score-inst.h (score_insn_type, score_data_type): Add Ra_I9_I5
diff --git a/include/opcode/ppc.h b/include/opcode/ppc.h
index e45fc580745..dc9a7ba65f9 100644
--- a/include/opcode/ppc.h
+++ b/include/opcode/ppc.h
@@ -1,6 +1,6 @@
 /* ppc.h -- Header file for PowerPC opcode table
    Copyright 1994, 1995, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
-   2007 Free Software Foundation, Inc.
+   2007, 2008, 2009 Free Software Foundation, Inc.
    Written by Ian Lance Taylor, Cygnus Support
 
 This file is part of GDB, GAS, and the GNU binutils.
@@ -351,4 +351,6 @@ struct powerpc_macro
 extern const struct powerpc_macro powerpc_macros[];
 extern const int powerpc_num_macros;
 
+extern ppc_cpu_t ppc_parse_cpu (ppc_cpu_t, const char *);
+
 #endif /* PPC_H */
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index e68ffbadb6e..5442e37e45a 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,3 +1,12 @@
+2009-03-10  Alan Modra  <amodra@bigpond.net.au>
+
+	* ppc-dis.c: Include "opintl.h".
+	(struct ppc_mopt, ppc_opts): New.
+	(ppc_parse_cpu): New function.
+	(powerpc_init_dialect): Use it.
+	(print_ppc_disassembler_options): Dump options from ppc_opts.
+	Internationalize message.
+
 2009-03-06  Nick Clifton  <nickc@redhat.com>
 
 	* po/es.po: Updated Spanish translation.
diff --git a/opcodes/ppc-dis.c b/opcodes/ppc-dis.c
index 9a28338fb68..2cbbec84a71 100644
--- a/opcodes/ppc-dis.c
+++ b/opcodes/ppc-dis.c
@@ -1,6 +1,6 @@
 /* ppc-dis.c -- Disassemble PowerPC instructions
    Copyright 1994, 1995, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
-   2008 Free Software Foundation, Inc.
+   2008, 2009 Free Software Foundation, Inc.
    Written by Ian Lance Taylor, Cygnus Support
 
    This file is part of the GNU opcodes library.
@@ -23,6 +23,7 @@
 #include <stdio.h>
 #include "sysdep.h"
 #include "dis-asm.h"
+#include "opintl.h"
 #include "opcode/ppc.h"
 
 /* This file provides several disassembler functions, all of which use
@@ -42,94 +43,201 @@ struct dis_private
 #define POWERPC_DIALECT(INFO) \
   (((struct dis_private *) ((INFO)->private_data))->dialect)
 
-/* Determine which set of machines to disassemble for.  PPC403/601 or
-   BookE.  For convenience, also disassemble instructions supported
-   by the AltiVec vector unit.  */
+struct ppc_mopt {
+  const char *opt;
+  ppc_cpu_t cpu;
+  ppc_cpu_t sticky;
+};
+
+struct ppc_mopt ppc_opts[] = {
+  { "403",     (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_403
+		| PPC_OPCODE_32),
+    0 },
+  { "405",     (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_403
+		| PPC_OPCODE_405 | PPC_OPCODE_32),
+    0 },
+  { "440",     (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_32
+		| PPC_OPCODE_440 | PPC_OPCODE_ISEL | PPC_OPCODE_RFMCI),
+    0 },
+  { "464",     (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_32
+		| PPC_OPCODE_440 | PPC_OPCODE_ISEL | PPC_OPCODE_RFMCI),
+    0 },
+  { "601",     (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_601
+		| PPC_OPCODE_32),
+    0 },
+  { "603",     (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_32),
+    0 },
+  { "604",     (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_32),
+    0 },
+  { "620",     (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_64),
+    0 },
+  { "7400",    (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_ALTIVEC
+		| PPC_OPCODE_32),
+    0 },
+  { "7410",    (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_ALTIVEC
+		| PPC_OPCODE_32),
+    0 },
+  { "7450",    (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_ALTIVEC
+		| PPC_OPCODE_32),
+    0 },
+  { "7455",    (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_ALTIVEC
+		| PPC_OPCODE_32),
+    0 },
+  { "750cl",   (PPC_OPCODE_PPC | PPC_OPCODE_PPCPS)
+    , 0 },
+  { "altivec", (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC),
+    PPC_OPCODE_ALTIVEC },
+  { "any",     0,
+    PPC_OPCODE_ANY },
+  { "booke",   (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_32),
+    0 },
+  { "booke32", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_32),
+    0 },
+  { "cell",    (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_64
+		| PPC_OPCODE_POWER4 | PPC_OPCODE_CELL | PPC_OPCODE_ALTIVEC),
+    0 },
+  { "com",     (PPC_OPCODE_COMMON | PPC_OPCODE_32),
+    0 },
+  { "e300",    (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_32
+		| PPC_OPCODE_E300),
+    0 },
+  { "e500",    (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_SPE
+		| PPC_OPCODE_ISEL | PPC_OPCODE_EFS | PPC_OPCODE_BRLOCK
+		| PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
+		| PPC_OPCODE_E500MC),
+    0 },
+  { "e500mc",  (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_ISEL
+		| PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
+		| PPC_OPCODE_E500MC),
+    0 },
+  { "e500x2",  (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_SPE
+		| PPC_OPCODE_ISEL | PPC_OPCODE_EFS | PPC_OPCODE_BRLOCK
+		| PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
+		| PPC_OPCODE_E500MC),
+    0 },
+  { "efs",     (PPC_OPCODE_PPC | PPC_OPCODE_EFS),
+    0 },
+  { "power4",  (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_64
+		| PPC_OPCODE_POWER4),
+    0 },
+  { "power5",  (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_64
+		| PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5),
+    0 },
+  { "power6",  (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_64
+		| PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
+		| PPC_OPCODE_ALTIVEC),
+    0 },
+  { "power7",  (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_ISEL
+		| PPC_OPCODE_64 | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5
+		| PPC_OPCODE_POWER6 | PPC_OPCODE_POWER7 | PPC_OPCODE_ALTIVEC
+		| PPC_OPCODE_VSX),
+    0 },
+  { "ppc",     (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_32),
+    0 },
+  { "ppc32",   (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_32),
+    0 },
+  { "ppc64",   (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_64),
+    0 },
+  { "ppc64bridge", (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_64_BRIDGE
+		    | PPC_OPCODE_64),
+    0 },
+  { "ppcps",   (PPC_OPCODE_PPC | PPC_OPCODE_PPCPS),
+    0 },
+  { "pwr",     (PPC_OPCODE_POWER | PPC_OPCODE_32),
+    0 },
+  { "pwr2",    (PPC_OPCODE_POWER | PPC_OPCODE_POWER2 | PPC_OPCODE_32),
+    0 },
+  { "pwrx",    (PPC_OPCODE_POWER | PPC_OPCODE_POWER2 | PPC_OPCODE_32),
+    0 },
+  { "spe",     (PPC_OPCODE_PPC | PPC_OPCODE_EFS),
+    PPC_OPCODE_SPE },
+  { "vsx",     (PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC),
+    PPC_OPCODE_VSX },
+};
+
+/* Handle -m and -M options that set cpu type, and .machine arg.  */
+
+ppc_cpu_t
+ppc_parse_cpu (ppc_cpu_t ppc_cpu, const char *arg)
+{
+  /* Sticky bits.  */
+  ppc_cpu_t retain_flags = ppc_cpu & (PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX
+				      | PPC_OPCODE_SPE | PPC_OPCODE_ANY);
+  unsigned int i;
+
+  for (i = 0; i < sizeof (ppc_opts) / sizeof (ppc_opts[0]); i++)
+    if (strcmp (ppc_opts[i].opt, arg) == 0)
+      {
+	if (ppc_opts[i].sticky)
+	  {
+	    retain_flags |= ppc_opts[i].sticky;
+	    if ((ppc_cpu & ~(PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX
+			     | PPC_OPCODE_SPE | PPC_OPCODE_ANY)) != 0)
+	      break;
+	  }
+	ppc_cpu = ppc_opts[i].cpu;
+	break;
+      }
+  if (i >= sizeof (ppc_opts) / sizeof (ppc_opts[0]))
+    return 0;
+
+  ppc_cpu |= retain_flags;
+  return ppc_cpu;
+}
+
+/* Determine which set of machines to disassemble for.  */
 
 static int
 powerpc_init_dialect (struct disassemble_info *info)
 {
-  ppc_cpu_t dialect = PPC_OPCODE_PPC;
+  ppc_cpu_t dialect = 0;
+  char *arg;
   struct dis_private *priv = calloc (sizeof (*priv), 1);
 
   if (priv == NULL)
     return FALSE;
 
-  if (BFD_DEFAULT_TARGET_SIZE == 64)
-    dialect |= PPC_OPCODE_64;
-
-  if (info->disassembler_options
-      && strstr (info->disassembler_options, "ppcps") != NULL)
-    dialect |= PPC_OPCODE_PPCPS;
-  else if (info->disassembler_options
-      && strstr (info->disassembler_options, "booke") != NULL)
-    dialect |= PPC_OPCODE_BOOKE;
-  else if ((info->mach == bfd_mach_ppc_e500mc)
-	   || (info->disassembler_options
-	       && strstr (info->disassembler_options, "e500mc") != NULL))
-    dialect |= (PPC_OPCODE_BOOKE | PPC_OPCODE_ISEL
-		| PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK
-		| PPC_OPCODE_RFMCI | PPC_OPCODE_E500MC);
-  else if ((info->mach == bfd_mach_ppc_e500)
-	   || (info->disassembler_options
-	       && strstr (info->disassembler_options, "e500") != NULL))
-    dialect |= (PPC_OPCODE_BOOKE
-		| PPC_OPCODE_SPE | PPC_OPCODE_ISEL
-		| PPC_OPCODE_EFS | PPC_OPCODE_BRLOCK
-		| PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK
-		| PPC_OPCODE_RFMCI | PPC_OPCODE_E500MC);
-  else if (info->disassembler_options
-	   && strstr (info->disassembler_options, "efs") != NULL)
-    dialect |= PPC_OPCODE_EFS;
-  else if (info->disassembler_options
-	   && strstr (info->disassembler_options, "e300") != NULL)
-    dialect |= PPC_OPCODE_E300 | PPC_OPCODE_CLASSIC | PPC_OPCODE_COMMON;
-  else if (info->disassembler_options
-	   && (strstr (info->disassembler_options, "440") != NULL
-	       || strstr (info->disassembler_options, "464") != NULL))
-    dialect |= PPC_OPCODE_BOOKE | PPC_OPCODE_32
-      | PPC_OPCODE_440 | PPC_OPCODE_ISEL | PPC_OPCODE_RFMCI;
-  else
-    dialect |= (PPC_OPCODE_403 | PPC_OPCODE_601 | PPC_OPCODE_CLASSIC
-		| PPC_OPCODE_COMMON | PPC_OPCODE_ALTIVEC);
-
-  if (info->disassembler_options
-      && strstr (info->disassembler_options, "power4") != NULL)
-    dialect |= PPC_OPCODE_POWER4;
-
-  if (info->disassembler_options
-      && strstr (info->disassembler_options, "power5") != NULL)
-    dialect |= PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5;
-
-  if (info->disassembler_options
-      && strstr (info->disassembler_options, "cell") != NULL)
-    dialect |= PPC_OPCODE_POWER4 | PPC_OPCODE_CELL | PPC_OPCODE_ALTIVEC;
-
-  if (info->disassembler_options
-      && strstr (info->disassembler_options, "power6") != NULL)
-    dialect |= PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
-	       | PPC_OPCODE_ALTIVEC;
+  arg = info->disassembler_options;
+  while (arg != NULL)
+    {
+      ppc_cpu_t new_cpu = 0;
+      char *end = strchr (arg, ',');
 
-  if (info->disassembler_options
-      && strstr (info->disassembler_options, "power7") != NULL)
-    dialect |= PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5
-	       | PPC_OPCODE_POWER6 | PPC_OPCODE_POWER7
-	       | PPC_OPCODE_ISEL | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX;
+      if (end != NULL)
+	*end = 0;
 
-  if (info->disassembler_options
-      && strstr (info->disassembler_options, "vsx") != NULL)
-    dialect |= PPC_OPCODE_VSX;
+      if ((new_cpu = ppc_parse_cpu (dialect, arg)) != 0)
+	dialect = new_cpu;
+      else if (strcmp (arg, "32") == 0)
+	{
+	  dialect &= ~PPC_OPCODE_64;
+	  dialect |= PPC_OPCODE_32;
+	}
+      else if (strcmp (arg, "64") == 0)
+	{
+	  dialect |= PPC_OPCODE_64;
+	  dialect &= ~PPC_OPCODE_32;
+	}
+      else
+	fprintf (stderr, _("warning: ignoring unknown -M%s option\n"), arg);
 
-  if (info->disassembler_options
-      && strstr (info->disassembler_options, "any") != NULL)
-    dialect |= PPC_OPCODE_ANY;
+      if (end != NULL)
+	*end++ = ',';
+      arg = end;
+    }
 
-  if (info->disassembler_options)
+  if ((dialect & ~(PPC_OPCODE_ANY | PPC_OPCODE_32 | PPC_OPCODE_64)) == 0)
     {
-      if (strstr (info->disassembler_options, "32") != NULL)
-	dialect &= ~PPC_OPCODE_64;
-      else if (strstr (info->disassembler_options, "64") != NULL)
-	dialect |= PPC_OPCODE_64;
+      if ((dialect & (PPC_OPCODE_32 | PPC_OPCODE_64)) == 0)
+	{
+	  if (info->mach == bfd_mach_ppc64)
+	    dialect |= PPC_OPCODE_64;
+	  else
+	    dialect |= PPC_OPCODE_32;
+	}
+      /* Choose a reasonable default.  */
+      dialect |= (PPC_OPCODE_PPC | PPC_OPCODE_COMMON | PPC_OPCODE_CLASSIC
+		  | PPC_OPCODE_601 | PPC_OPCODE_ALTIVEC);
     }
 
   info->private_data = priv;
@@ -400,23 +508,20 @@ print_insn_powerpc (bfd_vma memaddr,
 void
 print_ppc_disassembler_options (FILE *stream)
 {
-  fprintf (stream, "\n\
+  unsigned int i, col;
+
+  fprintf (stream, _("\n\
 The following PPC specific disassembler options are supported for use with\n\
-the -M switch:\n");
-
-  fprintf (stream, "  booke                    Disassemble the BookE instructions\n");
-  fprintf (stream, "  e300                     Disassemble the e300 instructions\n");
-  fprintf (stream, "  e500|e500x2              Disassemble the e500 instructions\n");
-  fprintf (stream, "  e500mc                   Disassemble the e500mc instructions\n");
-  fprintf (stream, "  440                      Disassemble the 440 instructions\n");
-  fprintf (stream, "  464                      Disassemble the 464 instructions\n");
-  fprintf (stream, "  efs                      Disassemble the EFS instructions\n");
-  fprintf (stream, "  ppcps                    Disassemble the PowerPC paired singles instructions\n");
-  fprintf (stream, "  power4                   Disassemble the Power4 instructions\n");
-  fprintf (stream, "  power5                   Disassemble the Power5 instructions\n");
-  fprintf (stream, "  power6                   Disassemble the Power6 instructions\n");
-  fprintf (stream, "  power7                   Disassemble the Power7 instructions\n");
-  fprintf (stream, "  vsx                      Disassemble the Vector-Scalar (VSX) instructions\n");
-  fprintf (stream, "  32                       Do not disassemble 64-bit instructions\n");
-  fprintf (stream, "  64                       Allow disassembly of 64-bit instructions\n");
+the -M switch:\n"));
+
+  for (col = 0, i = 0; i < sizeof (ppc_opts) / sizeof (ppc_opts[0]); i++)
+    {
+      col += fprintf (stream, " %s,", ppc_opts[i].opt);
+      if (col > 66)
+	{
+	  fprintf (stream, "\n");
+	  col = 0;
+	}
+    }
+  fprintf (stream, " 32, 64\n");
 }
-- 
GitLab