This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: PowerPC gas -many


I'm about to commit this.  Changes from last patch are:
- Re-order some insns in powerpc_opcodes table so that -many for 32 bit
  gas selects the same insn it would have previously.
- Cache parsing of disassembler_options.  This gave me an almost 4%
  improvement in "objdump -d -Mpower4 vmlinux" time.
- Removed PPCONLY define, which is now redundant since PPC_OPCODE_ANY
  isn't stored in opcode table.

opcodes/ChangeLog
	* ppc-dis.c (struct dis_private): New.
	(powerpc_dialect): Make static.  Accept -Many in addition to existing
	options.  Save dialect in dis_private.
	(print_insn_big_powerpc): Retrieve dialect from dis_private.
	(print_insn_little_powerpc): Likewise.
	(print_insn_powerpc): Call powpc_dialect here.  Remove unnecessary
	efs/altivec check.  Try harder to disassemble if given -Many.
	* ppc-opc.c (insert_fxm): Expand comment.
	(PPC, PPCCOM, PPC32, PPC64, PPCVEC): Remove PPC_OPCODE_ANY.
	(POWER, POWER2, PPCPWR2, POWER32, COM, COM32, M601, PWRCOM): Likewise.
	(POWER4): Remove PPCCOM.
	(PPCONLY): Don't define.  Update all occurrences to PPC.

gas/ChangeLog
	* config/tc-ppc.c (md_parse_option): Add PPC_OPCODE_ANY to existing
	ppc_cpu selection rather than replacing.
	(ppc_set_cpu): Ignore and preserve PPC_OPCODE_ANY in ppc_cpu.
	(md_begin): When PPC_OPCODE_ANY, insert all opcodes in ppc_hash.

Index: opcodes/ppc-dis.c
===================================================================
RCS file: /cvs/src/src/opcodes/ppc-dis.c,v
retrieving revision 1.14
diff -u -p -r1.14 ppc-dis.c
--- opcodes/ppc-dis.c	2 Sep 2003 04:15:29 -0000	1.14
+++ opcodes/ppc-dis.c	4 Sep 2003 00:06:04 -0000
@@ -32,11 +32,16 @@ Software Foundation, 59 Temple Place - S
 
 static int print_insn_powerpc (bfd_vma, struct disassemble_info *, int, int);
 
+struct dis_private {
+  /* Stash the result of parsing disassembler_options here.  */
+  int dialect;
+};
+
 /* Determine which set of machines to disassemble for.  PPC403/601 or
    BookE.  For convenience, also disassemble instructions supported
    by the AltiVec vector unit.  */
 
-int
+static int
 powerpc_dialect (struct disassemble_info *info)
 {
   int dialect = PPC_OPCODE_PPC | PPC_OPCODE_ALTIVEC;
@@ -45,40 +50,39 @@ powerpc_dialect (struct disassemble_info
     dialect |= PPC_OPCODE_64;
 
   if (info->disassembler_options
-      && (strcmp (info->disassembler_options, "booke") == 0
-	  || strcmp (info->disassembler_options, "booke32") == 0
-	  || strcmp (info->disassembler_options, "booke64") == 0))
+      && strstr (info->disassembler_options, "booke") != NULL)
     dialect |= PPC_OPCODE_BOOKE | PPC_OPCODE_BOOKE64;
-  else
-    if ((info->mach == bfd_mach_ppc_e500)
-	|| (info->disassembler_options
-	&& (   strcmp (info->disassembler_options, "e500") == 0
-	    || strcmp (info->disassembler_options, "e500x2") == 0)))
-      {
-	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;
-	/* efs* and AltiVec conflict.  */
-	dialect &= ~PPC_OPCODE_ALTIVEC;
-      }
-  else
-    if (info->disassembler_options
-	&& (strcmp (info->disassembler_options, "efs") == 0))
-      {
-	dialect |= PPC_OPCODE_EFS;
-	/* efs* and AltiVec conflict.  */
-	dialect &= ~PPC_OPCODE_ALTIVEC;
-      }
+  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;
+      /* efs* and AltiVec conflict.  */
+      dialect &= ~PPC_OPCODE_ALTIVEC;
+    }
+  else if (info->disassembler_options
+	   && strstr (info->disassembler_options, "efs") != NULL)
+    {
+      dialect |= PPC_OPCODE_EFS;
+      /* efs* and AltiVec conflict.  */
+      dialect &= ~PPC_OPCODE_ALTIVEC;
+    }
   else
     dialect |= (PPC_OPCODE_403 | PPC_OPCODE_601 | PPC_OPCODE_CLASSIC
 		| PPC_OPCODE_COMMON);
 
   if (info->disassembler_options
-      && strcmp (info->disassembler_options, "power4") == 0)
+      && strstr (info->disassembler_options, "power4") != NULL)
     dialect |= PPC_OPCODE_POWER4;
 
+  if (info->disassembler_options
+      && strstr (info->disassembler_options, "any") != NULL)
+    dialect |= PPC_OPCODE_ANY;
+
   if (info->disassembler_options)
     {
       if (strstr (info->disassembler_options, "32") != NULL)
@@ -87,6 +91,7 @@ powerpc_dialect (struct disassemble_info
 	dialect |= PPC_OPCODE_64;
     }
 
+  ((struct dis_private *) &info->private_data)->dialect = dialect;
   return dialect;
 }
 
@@ -95,7 +100,8 @@ powerpc_dialect (struct disassemble_info
 int
 print_insn_big_powerpc (bfd_vma memaddr, struct disassemble_info *info)
 {
-  return print_insn_powerpc (memaddr, info, 1, powerpc_dialect(info));
+  int dialect = ((struct dis_private *) &info->private_data)->dialect;
+  return print_insn_powerpc (memaddr, info, 1, dialect);
 }
 
 /* Print a little endian PowerPC instruction.  */
@@ -103,7 +109,8 @@ print_insn_big_powerpc (bfd_vma memaddr,
 int
 print_insn_little_powerpc (bfd_vma memaddr, struct disassemble_info *info)
 {
-  return print_insn_powerpc (memaddr, info, 0, powerpc_dialect(info));
+  int dialect = ((struct dis_private *) &info->private_data)->dialect;
+  return print_insn_powerpc (memaddr, info, 0, dialect);
 }
 
 /* Print a POWER (RS/6000) instruction.  */
@@ -129,6 +136,9 @@ print_insn_powerpc (bfd_vma memaddr,
   const struct powerpc_opcode *opcode_end;
   unsigned long op;
 
+  if (dialect == 0)
+    dialect = powerpc_dialect (info);
+
   status = (*info->read_memory_func) (memaddr, buffer, 4, info);
   if (status != 0)
     {
@@ -147,6 +157,7 @@ print_insn_powerpc (bfd_vma memaddr,
   /* Find the first match in the opcode table.  We could speed this up
      a bit by doing a binary search on the major opcode.  */
   opcode_end = powerpc_opcodes + powerpc_num_opcodes;
+ again:
   for (opcode = powerpc_opcodes; opcode < opcode_end; opcode++)
     {
       unsigned long table_op;
@@ -166,9 +177,6 @@ print_insn_powerpc (bfd_vma memaddr,
 	  || (opcode->flags & dialect) == 0)
 	continue;
 
-      if ((dialect & PPC_OPCODE_EFS) && (opcode->flags & PPC_OPCODE_ALTIVEC))
-	continue;
-
       /* Make two passes over the operands.  First see if any of them
 	 have extraction functions, and, if they do, make sure the
 	 instruction is valid.  */
@@ -275,6 +283,12 @@ print_insn_powerpc (bfd_vma memaddr,
 
       /* We have found and printed an instruction; return.  */
       return 4;
+    }
+
+  if ((dialect & PPC_OPCODE_ANY) != 0)
+    {
+      dialect = ~PPC_OPCODE_ANY;
+      goto again;
     }
 
   /* We could not find a match.  */
Index: opcodes/ppc-opc.c
===================================================================
RCS file: /cvs/src/src/opcodes/ppc-opc.c,v
retrieving revision 1.56
diff -u -p -r1.56 ppc-opc.c
--- opcodes/ppc-opc.c	2 Sep 2003 04:15:29 -0000	1.56
+++ opcodes/ppc-opc.c	4 Sep 2003 00:06:07 -0000
@@ -1001,7 +1001,8 @@ insert_fxm (unsigned long insn,
     ;
 
   /* If only one bit of the FXM field is set, we can use the new form
-     of the instruction, which is faster.  */
+     of the instruction, which is faster.  Unlike the Power4 branch hint
+     encoding, this is not backward compatible.  */
   else if ((dialect & PPC_OPCODE_POWER4) != 0 && (value & -value) == value)
     insn |= 1 << 20;
 
@@ -1762,27 +1763,26 @@ extract_tbr (unsigned long insn,
 /* Smaller names for the flags so each entry in the opcodes table will
    fit on a single line.  */
 #undef	PPC
-#define PPC     PPC_OPCODE_PPC | PPC_OPCODE_ANY
-#define PPCCOM	PPC_OPCODE_PPC | PPC_OPCODE_COMMON | PPC_OPCODE_ANY
+#define PPC     PPC_OPCODE_PPC
+#define PPCCOM	PPC_OPCODE_PPC | PPC_OPCODE_COMMON
 #define NOPOWER4 PPC_OPCODE_NOPOWER4 | PPCCOM
-#define POWER4	PPC_OPCODE_POWER4 | PPCCOM
-#define PPC32   PPC_OPCODE_32 | PPC_OPCODE_PPC | PPC_OPCODE_ANY
-#define PPC64   PPC_OPCODE_64 | PPC_OPCODE_PPC | PPC_OPCODE_ANY
-#define PPCONLY	PPC_OPCODE_PPC
+#define POWER4	PPC_OPCODE_POWER4
+#define PPC32   PPC_OPCODE_32 | PPC_OPCODE_PPC
+#define PPC64   PPC_OPCODE_64 | PPC_OPCODE_PPC
 #define PPC403	PPC_OPCODE_403
 #define PPC405	PPC403
 #define PPC440	PPC_OPCODE_440
 #define PPC750	PPC
 #define PPC860	PPC
-#define PPCVEC	PPC_OPCODE_ALTIVEC | PPC_OPCODE_ANY | PPC_OPCODE_PPC
-#define	POWER   PPC_OPCODE_POWER | PPC_OPCODE_ANY
-#define	POWER2	PPC_OPCODE_POWER | PPC_OPCODE_POWER2 | PPC_OPCODE_ANY
-#define PPCPWR2	PPC_OPCODE_PPC | PPC_OPCODE_POWER | PPC_OPCODE_POWER2 | PPC_OPCODE_ANY
-#define	POWER32	PPC_OPCODE_POWER | PPC_OPCODE_ANY | PPC_OPCODE_32
-#define	COM     PPC_OPCODE_POWER | PPC_OPCODE_PPC | PPC_OPCODE_COMMON | PPC_OPCODE_ANY
-#define	COM32   PPC_OPCODE_POWER | PPC_OPCODE_PPC | PPC_OPCODE_COMMON | PPC_OPCODE_ANY | PPC_OPCODE_32
-#define	M601    PPC_OPCODE_POWER | PPC_OPCODE_601 | PPC_OPCODE_ANY
-#define PWRCOM	PPC_OPCODE_POWER | PPC_OPCODE_601 | PPC_OPCODE_COMMON | PPC_OPCODE_ANY
+#define PPCVEC	PPC_OPCODE_ALTIVEC | PPC_OPCODE_PPC
+#define	POWER   PPC_OPCODE_POWER
+#define	POWER2	PPC_OPCODE_POWER | PPC_OPCODE_POWER2
+#define PPCPWR2	PPC_OPCODE_PPC | PPC_OPCODE_POWER | PPC_OPCODE_POWER2
+#define	POWER32	PPC_OPCODE_POWER | PPC_OPCODE_32
+#define	COM     PPC_OPCODE_POWER | PPC_OPCODE_PPC | PPC_OPCODE_COMMON
+#define	COM32   PPC_OPCODE_POWER | PPC_OPCODE_PPC | PPC_OPCODE_COMMON | PPC_OPCODE_32
+#define	M601    PPC_OPCODE_POWER | PPC_OPCODE_601
+#define PWRCOM	PPC_OPCODE_POWER | PPC_OPCODE_601 | PPC_OPCODE_COMMON
 #define	MFDEC1	PPC_OPCODE_POWER
 #define	MFDEC2	PPC_OPCODE_PPC | PPC_OPCODE_601 | PPC_OPCODE_BOOKE
 #define BOOKE	PPC_OPCODE_BOOKE
@@ -2369,12 +2369,12 @@ const struct powerpc_opcode powerpc_opco
 
 { "cmplwi",  OPL(10,0),	OPL_MASK,	PPCCOM,		{ OBF, RA, UI } },
 { "cmpldi",  OPL(10,1), OPL_MASK,	PPC64,		{ OBF, RA, UI } },
-{ "cmpli",   OP(10),	OP_MASK,	PPCONLY,	{ BF, L, RA, UI } },
+{ "cmpli",   OP(10),	OP_MASK,	PPC,		{ BF, L, RA, UI } },
 { "cmpli",   OP(10),	OP_MASK,	PWRCOM,		{ BF, RA, UI } },
 
 { "cmpwi",   OPL(11,0),	OPL_MASK,	PPCCOM,		{ OBF, RA, SI } },
 { "cmpdi",   OPL(11,1),	OPL_MASK,	PPC64,		{ OBF, RA, SI } },
-{ "cmpi",    OP(11),	OP_MASK,	PPCONLY,	{ BF, L, RA, SI } },
+{ "cmpi",    OP(11),	OP_MASK,	PPC,		{ BF, L, RA, SI } },
 { "cmpi",    OP(11),	OP_MASK,	PWRCOM,		{ BF, RA, SI } },
 
 { "addic",   OP(12),	OP_MASK,	PPCCOM,		{ RT, RA, SI } },
@@ -3158,7 +3158,7 @@ const struct powerpc_opcode powerpc_opco
 
 { "cmpw",    XCMPL(31,0,0), XCMPL_MASK, PPCCOM,		{ OBF, RA, RB } },
 { "cmpd",    XCMPL(31,0,1), XCMPL_MASK, PPC64,		{ OBF, RA, RB } },
-{ "cmp",     X(31,0),	XCMP_MASK,	PPCONLY,	{ BF, L, RA, RB } },
+{ "cmp",     X(31,0),	XCMP_MASK,	PPC,		{ BF, L, RA, RB } },
 { "cmp",     X(31,0),	XCMPL_MASK,	PWRCOM,		{ BF, RA, RB } },
 
 { "twlgt",   XTO(31,4,TOLGT), XTO_MASK, PPCCOM,		{ RA, RB } },
@@ -3264,7 +3264,7 @@ const struct powerpc_opcode powerpc_opco
 
 { "cmplw",   XCMPL(31,32,0), XCMPL_MASK, PPCCOM,	{ OBF, RA, RB } },
 { "cmpld",   XCMPL(31,32,1), XCMPL_MASK, PPC64,		{ OBF, RA, RB } },
-{ "cmpl",    X(31,32),	XCMP_MASK,	 PPCONLY,	{ BF, L, RA, RB } },
+{ "cmpl",    X(31,32),	XCMP_MASK,	 PPC,		{ BF, L, RA, RB } },
 { "cmpl",    X(31,32),	XCMPL_MASK,	 PWRCOM,	{ BF, RA, RB } },
 
 { "subf",    XO(31,40,0,0), XO_MASK,	PPC,		{ RT, RA, RB } },
@@ -3636,12 +3636,12 @@ const struct powerpc_opcode powerpc_opco
 { "mfsprg5",    XSPR(31,339,261),  XSPR_MASK, PPC405,	{ RT } },
 { "mfsprg6",    XSPR(31,339,262),  XSPR_MASK, PPC405,	{ RT } },
 { "mfsprg7",    XSPR(31,339,263),  XSPR_MASK, PPC405,	{ RT } },
-{ "mftb",       XSPR(31,339,268),  XSPR_MASK, BOOKE,    { RT } },
 { "mftb",       X(31,371),	   X_MASK,    CLASSIC,	{ RT, TBR } },
-{ "mftbl",      XSPR(31,339,268),  XSPR_MASK, BOOKE,    { RT } },
+{ "mftb",       XSPR(31,339,268),  XSPR_MASK, BOOKE,    { RT } },
 { "mftbl",      XSPR(31,371,268),  XSPR_MASK, CLASSIC,	{ RT } },
-{ "mftbu",      XSPR(31,339,269),  XSPR_MASK, BOOKE,    { RT } },
+{ "mftbl",      XSPR(31,339,268),  XSPR_MASK, BOOKE,    { RT } },
 { "mftbu",      XSPR(31,371,269),  XSPR_MASK, CLASSIC,	{ RT } },
+{ "mftbu",      XSPR(31,339,269),  XSPR_MASK, BOOKE,    { RT } },
 { "mfsprg",     XSPR(31,339,272),  XSPRG_MASK, PPC,	{ RT, SPRG } },
 { "mfsprg0",    XSPR(31,339,272),  XSPR_MASK, PPC,	{ RT } },
 { "mfsprg1",    XSPR(31,339,273),  XSPR_MASK, PPC,	{ RT } },
@@ -4137,7 +4137,7 @@ const struct powerpc_opcode powerpc_opco
 { "lswi",    X(31,597),	X_MASK,		PPCCOM,		{ RT, RA, NB } },
 { "lsi",     X(31,597),	X_MASK,		PWRCOM,		{ RT, RA, NB } },
 
-{ "lwsync",  XSYNC(31,598,1), 0xffffffff, PPCONLY,	{ 0 } },
+{ "lwsync",  XSYNC(31,598,1), 0xffffffff, PPC,		{ 0 } },
 { "ptesync", XSYNC(31,598,2), 0xffffffff, PPC64,	{ 0 } },
 { "msync",   X(31,598), 0xffffffff,	BOOKE,		{ 0 } },
 { "sync",    X(31,598), XSYNC_MASK,	PPCCOM,		{ LS } },
Index: gas/config/tc-ppc.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-ppc.c,v
retrieving revision 1.81
diff -u -p -r1.81 tc-ppc.c
--- gas/config/tc-ppc.c	19 Aug 2003 15:48:53 -0000	1.81
+++ gas/config/tc-ppc.c	4 Sep 2003 00:05:45 -0000
@@ -974,7 +974,7 @@ md_parse_option (c, arg)
 	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 | PPC_OPCODE_32;
+	ppc_cpu |= PPC_OPCODE_ANY;
 
       else if (strcmp (arg, "regnames") == 0)
 	reg_names_p = TRUE;
@@ -1118,23 +1118,23 @@ ppc_set_cpu ()
   const char *default_os  = TARGET_OS;
   const char *default_cpu = TARGET_CPU;
 
-  if (ppc_cpu == 0)
+  if ((ppc_cpu & ~PPC_OPCODE_ANY) == 0)
     {
       if (ppc_obj64)
-	ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_64;
+	ppc_cpu |= PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_64;
       else if (strncmp (default_os, "aix", 3) == 0
 	       && default_os[3] >= '4' && default_os[3] <= '9')
-	ppc_cpu = PPC_OPCODE_COMMON | PPC_OPCODE_32;
+	ppc_cpu |= PPC_OPCODE_COMMON | PPC_OPCODE_32;
       else if (strncmp (default_os, "aix3", 4) == 0)
-	ppc_cpu = PPC_OPCODE_POWER | PPC_OPCODE_32;
+	ppc_cpu |= PPC_OPCODE_POWER | PPC_OPCODE_32;
       else if (strcmp (default_cpu, "rs6000") == 0)
-	ppc_cpu = PPC_OPCODE_POWER | PPC_OPCODE_32;
+	ppc_cpu |= PPC_OPCODE_POWER | PPC_OPCODE_32;
       else if (strncmp (default_cpu, "powerpc", 7) == 0)
 	{
 	  if (default_cpu[7] == '6' && default_cpu[8] == '4')
-	    ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_64;
+	    ppc_cpu |= PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_64;
 	  else
-	    ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_32;
+	    ppc_cpu |= PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_32;
 	}
       else
 	as_fatal (_("Unknown default cpu = %s, os = %s"),
@@ -1264,6 +1264,10 @@ md_begin ()
 	    }
 	}
     }
+
+  if ((ppc_cpu & PPC_OPCODE_ANY) != 0)
+    for (op = powerpc_opcodes; op < op_end; op++)
+      hash_insert (ppc_hash, op->name, (PTR) op);
 
   /* Insert the macros into a hash table.  */
   ppc_macro_hash = hash_new ();

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]