public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* Re: [PATCH] Handle mtsprg and mfsprg properly for BookE
@ 2005-02-28 20:20 Jeff Baker
  2005-02-28 21:11 ` Jeff Baker
  0 siblings, 1 reply; 19+ messages in thread
From: Jeff Baker @ 2005-02-28 20:20 UTC (permalink / raw)
  To: binutils

Below is an updated (and I believe more correct) version of this patch.


2005-02-28 Jeff Baker <jbaker@qnx.com>

	* ppc-opc.c (SPRG_MASK):  Allow 3 bits for register.
	(powerpc_operands): Likewise.
	(insert_sprg): New Function.
	(powerpc_opcodes): reorder mtsprg/mfsprg opcodes
	to allow disassembler to locate the correct one.
	

Index: ppc-opc.c
===================================================================
RCS file: /cvs/src/src/opcodes/ppc-opc.c,v
retrieving revision 1.78
diff -w -u -p -r1.78 ppc-opc.c
--- ppc-opc.c	20 Jan 2005 06:54:48 -0000	1.78
+++ ppc-opc.c	28 Feb 2005 18:02:08 -0000
@@ -84,6 +84,7 @@ static unsigned long insert_sh6 (unsigne
  static long extract_sh6 (unsigned long, int, int *);
  static unsigned long insert_spr (unsigned long, long, int, const char **);
  static long extract_spr (unsigned long, int, int *);
+static unsigned long insert_sprg (unsigned long, long, int, const char **);
  static unsigned long insert_tbr (unsigned long, long, int, const char **);
  static long extract_tbr (unsigned long, int, int *);
  static unsigned long insert_ev2 (unsigned long, long, int, const char **);
@@ -465,8 +466,8 @@ const struct powerpc_operand powerpc_ope

    /* The SPRG register number in an XFX form m[ft]sprg instruction.  */
  #define SPRG SPRBAT + 1
-#define SPRG_MASK (0x3 << 16)
-  { 2, 16, NULL, NULL, 0 },
+#define SPRG_MASK (0x7 << 16)
+  { 3, 16, insert_sprg, NULL, 0 },

    /* The SR field in an X form instruction.  */
  #define SR SPRG + 1
@@ -1397,6 +1398,36 @@ extract_spr (unsigned long insn,
    return ((insn >> 16) & 0x1f) | ((insn >> 6) & 0x3e0);
  }

+/* Some dialects (BookE, 405) have 8 SPRG registers instead of
+ the normal 4.  In addition, BookE mfsprg instructions must
+ have sprn5 cleared when using registers 4 through 7. */
+
+static unsigned long
+insert_sprg (unsigned long insn,
+	    long value,
+	    int dialect,
+	    const char **errmsg)
+{
+  /* This check uses PPC_OPCODE_403 because PPC405 is later defined
+   as a synonym.  If ever a 405 specific dialect is added this
+   check should use that instead. */
+  if ((dialect & PPC_OPCODE_BOOKE) || (dialect & PPC_OPCODE_403))
+  {
+    if (value > 7)
+      *errmsg = _("Invalid operand.  Must be between 0 and 7.");
+    if ((value > 3) && (dialect & PPC_OPCODE_BOOKE))
+      return (insn | ((value & 0x07) << 16))
+	      & (((insn >> 8) & 0x01) ? ~0 : ( ~( 1 << 20 )));
+    return insn | ((value & 0x07) << 16);
+  }
+  else
+  {
+    if (value > 3)
+	    *errmsg = _("Invalid operand.  Must be between 0 and 3.");
+    return insn | ((value & 0x03) << 16);
+  }
+}
+
  /* The TBR field in an XFX instruction.  This is just like SPR, but it
     is optional.  When TBR is omitted, it must be inserted as 268 (the
     magic number of the TB register).  These functions treat 0
@@ -3677,13 +3708,9 @@ const struct powerpc_opcode powerpc_opco
  { "mfbar",      XSPR(31,339,159),  XSPR_MASK, PPC860,	{ RT } },
  { "mfvrsave",   XSPR(31,339,256),  XSPR_MASK, PPCVEC,	{ RT } },
  { "mfusprg0",   XSPR(31,339,256),  XSPR_MASK, BOOKE,    { RT } },
-{ "mfsprg4",    XSPR(31,339,260),  XSPR_MASK, PPC405,	{ RT } },
  { "mfsprg4",    XSPR(31,339,260),  XSPR_MASK, BOOKE,	{ RT } },
-{ "mfsprg5",    XSPR(31,339,261),  XSPR_MASK, PPC405,	{ RT } },
  { "mfsprg5",    XSPR(31,339,261),  XSPR_MASK, BOOKE,	{ RT } },
-{ "mfsprg6",    XSPR(31,339,262),  XSPR_MASK, PPC405,	{ RT } },
  { "mfsprg6",    XSPR(31,339,262),  XSPR_MASK, BOOKE,	{ RT } },
-{ "mfsprg7",    XSPR(31,339,263),  XSPR_MASK, PPC405,	{ RT } },
  { "mfsprg7",    XSPR(31,339,263),  XSPR_MASK, BOOKE,	{ RT } },
  { "mftb",       X(31,371),	   X_MASK,    CLASSIC,	{ RT, TBR } },
  { "mftb",       XSPR(31,339,268),  XSPR_MASK, BOOKE,    { RT } },
@@ -3696,6 +3723,10 @@ const struct powerpc_opcode powerpc_opco
  { "mfsprg1",    XSPR(31,339,273),  XSPR_MASK, PPC,	{ RT } },
  { "mfsprg2",    XSPR(31,339,274),  XSPR_MASK, PPC,	{ RT } },
  { "mfsprg3",    XSPR(31,339,275),  XSPR_MASK, PPC,	{ RT } },
+{ "mfsprg4",    XSPR(31,339,276),  XSPR_MASK, PPC405,	{ RT } },
+{ "mfsprg5",    XSPR(31,339,277),  XSPR_MASK, PPC405,	{ RT } },
+{ "mfsprg6",    XSPR(31,339,278),  XSPR_MASK, PPC405,	{ RT } },
+{ "mfsprg7",    XSPR(31,339,279),  XSPR_MASK, PPC405,	{ RT } },
  { "mfasr",      XSPR(31,339,280),  XSPR_MASK, PPC64,	{ RT } },
  { "mfear",      XSPR(31,339,282),  XSPR_MASK, PPC,	{ RT } },
  { "mfpir",      XSPR(31,339,286),  XSPR_MASK, BOOKE,    { RT } },

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] Handle mtsprg and mfsprg properly for BookE
  2005-02-28 20:20 [PATCH] Handle mtsprg and mfsprg properly for BookE Jeff Baker
@ 2005-02-28 21:11 ` Jeff Baker
  2005-02-28 21:26   ` Kumar Gala
  0 siblings, 1 reply; 19+ messages in thread
From: Jeff Baker @ 2005-02-28 21:11 UTC (permalink / raw)
  To: jbaker; +Cc: binutils

The following patch may also be correct.  I've seen conflicting 
information about whether PPC405 also needs the sprn5 bit cleared on 
mfsprg for registers 4 through 7.

2005-02-28 Jeff Baker <jbaker@qnx.com>
	* ppc-opc.c (SPRG_MASK):  Allow 3 bits for register.
	(powerpc_operands): Likewise.
	(insert_sprg): New Function.


Index: ppc-opc.c
===================================================================
RCS file: /cvs/src/src/opcodes/ppc-opc.c,v
retrieving revision 1.78
diff -w -u -p -r1.78 ppc-opc.c
--- ppc-opc.c	20 Jan 2005 06:54:48 -0000	1.78
+++ ppc-opc.c	28 Feb 2005 19:35:21 -0000
@@ -84,6 +84,7 @@ static unsigned long insert_sh6 (unsigne
  static long extract_sh6 (unsigned long, int, int *);
  static unsigned long insert_spr (unsigned long, long, int, const char **);
  static long extract_spr (unsigned long, int, int *);
+static unsigned long insert_sprg (unsigned long, long, int, const char **);
  static unsigned long insert_tbr (unsigned long, long, int, const char **);
  static long extract_tbr (unsigned long, int, int *);
  static unsigned long insert_ev2 (unsigned long, long, int, const char **);
@@ -465,8 +466,8 @@ const struct powerpc_operand powerpc_ope

    /* The SPRG register number in an XFX form m[ft]sprg instruction.  */
  #define SPRG SPRBAT + 1
-#define SPRG_MASK (0x3 << 16)
-  { 2, 16, NULL, NULL, 0 },
+#define SPRG_MASK (0x7 << 16)
+  { 3, 16, insert_sprg, NULL, 0 },

    /* The SR field in an X form instruction.  */
  #define SR SPRG + 1
@@ -1397,6 +1398,36 @@ extract_spr (unsigned long insn,
    return ((insn >> 16) & 0x1f) | ((insn >> 6) & 0x3e0);
  }

+/* Some dialects (BookE, 405) have 8 SPRG registers instead of
+ the normal 4.  In addition, mfsprg instructions must
+ have sprn5 cleared when using registers 4 through 7. */
+
+static unsigned long
+insert_sprg (unsigned long insn,
+	    long value,
+	    int dialect,
+	    const char **errmsg)
+{
+  /* This check uses PPC_OPCODE_403 because PPC405 is later defined
+   as a synonym.  If ever a 405 specific dialect is added this
+   check should use that instead. */
+  if ((dialect & PPC_OPCODE_BOOKE) || (dialect & PPC_OPCODE_403))
+  {
+    if (value > 7)
+      *errmsg = _("Invalid operand.  Must be between 0 and 7.");
+    if (value > 3)
+      return (insn | ((value & 0x07) << 16))
+	      & (((insn >> 8) & 0x01) ? ~0 : ( ~( 1 << 20 )));
+    return insn | ((value & 0x07) << 16);
+  }
+  else
+  {
+    if (value > 3)
+	    *errmsg = _("Invalid operand.  Must be between 0 and 3.");
+    return insn | ((value & 0x03) << 16);
+  }
+}
+
  /* The TBR field in an XFX instruction.  This is just like SPR, but it
     is optional.  When TBR is omitted, it must be inserted as 268 (the
     magic number of the TB register).  These functions treat 0

Jeff Baker wrote:
> Below is an updated (and I believe more correct) version of this patch.
> 
> 
> 2005-02-28 Jeff Baker <jbaker@qnx.com>
> 
> 	* ppc-opc.c (SPRG_MASK):  Allow 3 bits for register.
> 	(powerpc_operands): Likewise.
> 	(insert_sprg): New Function.
> 	(powerpc_opcodes): reorder mtsprg/mfsprg opcodes
> 	to allow disassembler to locate the correct one.
> 	
> 
> Index: ppc-opc.c
> ===================================================================
> RCS file: /cvs/src/src/opcodes/ppc-opc.c,v
> retrieving revision 1.78
> diff -w -u -p -r1.78 ppc-opc.c
> --- ppc-opc.c	20 Jan 2005 06:54:48 -0000	1.78
> +++ ppc-opc.c	28 Feb 2005 18:02:08 -0000
> @@ -84,6 +84,7 @@ static unsigned long insert_sh6 (unsigne
>   static long extract_sh6 (unsigned long, int, int *);
>   static unsigned long insert_spr (unsigned long, long, int, const char
> **);
>   static long extract_spr (unsigned long, int, int *);
> +static unsigned long insert_sprg (unsigned long, long, int, const char
> **);
>   static unsigned long insert_tbr (unsigned long, long, int, const char
> **);
>   static long extract_tbr (unsigned long, int, int *);
>   static unsigned long insert_ev2 (unsigned long, long, int, const char
> **);
> @@ -465,8 +466,8 @@ const struct powerpc_operand powerpc_ope
> 
>     /* The SPRG register number in an XFX form m[ft]sprg instruction.
> */
>   #define SPRG SPRBAT + 1
> -#define SPRG_MASK (0x3 << 16)
> -  { 2, 16, NULL, NULL, 0 },
> +#define SPRG_MASK (0x7 << 16)
> +  { 3, 16, insert_sprg, NULL, 0 },
> 
>     /* The SR field in an X form instruction.  */
>   #define SR SPRG + 1
> @@ -1397,6 +1398,36 @@ extract_spr (unsigned long insn,
>     return ((insn >> 16) & 0x1f) | ((insn >> 6) & 0x3e0);
>   }
> 
> +/* Some dialects (BookE, 405) have 8 SPRG registers instead of
> + the normal 4.  In addition, BookE mfsprg instructions must
> + have sprn5 cleared when using registers 4 through 7. */
> +
> +static unsigned long
> +insert_sprg (unsigned long insn,
> +	    long value,
> +	    int dialect,
> +	    const char **errmsg)
> +{
> +  /* This check uses PPC_OPCODE_403 because PPC405 is later defined
> +   as a synonym.  If ever a 405 specific dialect is added this
> +   check should use that instead. */
> +  if ((dialect & PPC_OPCODE_BOOKE) || (dialect & PPC_OPCODE_403))
> +  {
> +    if (value > 7)
> +      *errmsg = _("Invalid operand.  Must be between 0 and 7.");
> +    if ((value > 3) && (dialect & PPC_OPCODE_BOOKE))
> +      return (insn | ((value & 0x07) << 16))
> +	      & (((insn >> 8) & 0x01) ? ~0 : ( ~( 1 << 20 )));
> +    return insn | ((value & 0x07) << 16);
> +  }
> +  else
> +  {
> +    if (value > 3)
> +	    *errmsg = _("Invalid operand.  Must be between 0 and 3.");
> +    return insn | ((value & 0x03) << 16);
> +  }
> +}
> +
>   /* The TBR field in an XFX instruction.  This is just like SPR, but it
>      is optional.  When TBR is omitted, it must be inserted as 268 (the
>      magic number of the TB register).  These functions treat 0
> @@ -3677,13 +3708,9 @@ const struct powerpc_opcode powerpc_opco
>   { "mfbar",      XSPR(31,339,159),  XSPR_MASK, PPC860,	{ RT } },
>   { "mfvrsave",   XSPR(31,339,256),  XSPR_MASK, PPCVEC,	{ RT } },
>   { "mfusprg0",   XSPR(31,339,256),  XSPR_MASK, BOOKE,    { RT } },
> -{ "mfsprg4",    XSPR(31,339,260),  XSPR_MASK, PPC405,	{ RT } },
>   { "mfsprg4",    XSPR(31,339,260),  XSPR_MASK, BOOKE,	{ RT } },
> -{ "mfsprg5",    XSPR(31,339,261),  XSPR_MASK, PPC405,	{ RT } },
>   { "mfsprg5",    XSPR(31,339,261),  XSPR_MASK, BOOKE,	{ RT } },
> -{ "mfsprg6",    XSPR(31,339,262),  XSPR_MASK, PPC405,	{ RT } },
>   { "mfsprg6",    XSPR(31,339,262),  XSPR_MASK, BOOKE,	{ RT } },
> -{ "mfsprg7",    XSPR(31,339,263),  XSPR_MASK, PPC405,	{ RT } },
>   { "mfsprg7",    XSPR(31,339,263),  XSPR_MASK, BOOKE,	{ RT } },
>   { "mftb",       X(31,371),	   X_MASK,    CLASSIC,	{ RT, TBR } },
>   { "mftb",       XSPR(31,339,268),  XSPR_MASK, BOOKE,    { RT } },
> @@ -3696,6 +3723,10 @@ const struct powerpc_opcode powerpc_opco
>   { "mfsprg1",    XSPR(31,339,273),  XSPR_MASK, PPC,	{ RT } },
>   { "mfsprg2",    XSPR(31,339,274),  XSPR_MASK, PPC,	{ RT } },
>   { "mfsprg3",    XSPR(31,339,275),  XSPR_MASK, PPC,	{ RT } },
> +{ "mfsprg4",    XSPR(31,339,276),  XSPR_MASK, PPC405,	{ RT } },
> +{ "mfsprg5",    XSPR(31,339,277),  XSPR_MASK, PPC405,	{ RT } },
> +{ "mfsprg6",    XSPR(31,339,278),  XSPR_MASK, PPC405,	{ RT } },
> +{ "mfsprg7",    XSPR(31,339,279),  XSPR_MASK, PPC405,	{ RT } },
>   { "mfasr",      XSPR(31,339,280),  XSPR_MASK, PPC64,	{ RT } },
>   { "mfear",      XSPR(31,339,282),  XSPR_MASK, PPC,	{ RT } },
>   { "mfpir",      XSPR(31,339,286),  XSPR_MASK, BOOKE,    { RT } },

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] Handle mtsprg and mfsprg properly for BookE
  2005-02-28 21:11 ` Jeff Baker
@ 2005-02-28 21:26   ` Kumar Gala
  2005-02-28 22:52     ` Jeff Baker
  2005-02-28 23:09     ` Jeff Baker
  0 siblings, 2 replies; 19+ messages in thread
From: Kumar Gala @ 2005-02-28 21:26 UTC (permalink / raw)
  To: jbaker; +Cc: binutils

Jeff,

Can I ask you update some of the tests in gas/testsuite/gas/ppc to 
reflect these instructions.

- kumar

On Feb 28, 2005, at 1:40 PM, Jeff Baker wrote:

> The following patch may also be correct.  I've seen conflicting
> information about whether PPC405 also needs the sprn5 bit cleared on
> mfsprg for registers 4 through 7.
>
> 2005-02-28 Jeff Baker <jbaker@qnx.com>
>         * ppc-opc.c (SPRG_MASK):  Allow 3 bits for register.
>          (powerpc_operands): Likewise.
>          (insert_sprg): New Function.
>
>
>
> Index: ppc-opc.c
>  ===================================================================
> RCS file: /cvs/src/src/opcodes/ppc-opc.c,v
>  retrieving revision 1.78
>  diff -w -u -p -r1.78 ppc-opc.c
>  --- ppc-opc.c   20 Jan 2005 06:54:48 -0000      1.78
>  +++ ppc-opc.c   28 Feb 2005 19:35:21 -0000
>  @@ -84,6 +84,7 @@ static unsigned long insert_sh6 (unsigne
>    static long extract_sh6 (unsigned long, int, int *);
>   static unsigned long insert_spr (unsigned long, long, int, const 
> char **);
>    static long extract_spr (unsigned long, int, int *);
> +static unsigned long insert_sprg (unsigned long, long, int, const 
> char **);
>    static unsigned long insert_tbr (unsigned long, long, int, const 
> char **);
>    static long extract_tbr (unsigned long, int, int *);
>   static unsigned long insert_ev2 (unsigned long, long, int, const 
> char **);
>  @@ -465,8 +466,8 @@ const struct powerpc_operand powerpc_ope
>
>     /* The SPRG register number in an XFX form m[ft]sprg instruction.  
> */
>    #define SPRG SPRBAT + 1
>  -#define SPRG_MASK (0x3 << 16)
>  -  { 2, 16, NULL, NULL, 0 },
>  +#define SPRG_MASK (0x7 << 16)
>  +  { 3, 16, insert_sprg, NULL, 0 },
>
>     /* The SR field in an X form instruction.  */
>    #define SR SPRG + 1
>  @@ -1397,6 +1398,36 @@ extract_spr (unsigned long insn,
>      return ((insn >> 16) & 0x1f) | ((insn >> 6) & 0x3e0);
>    }
>
> +/* Some dialects (BookE, 405) have 8 SPRG registers instead of
>  + the normal 4.  In addition, mfsprg instructions must
>  + have sprn5 cleared when using registers 4 through 7. */
> +
>  +static unsigned long
>  +insert_sprg (unsigned long insn,
>  +           long value,
>  +           int dialect,
>  +           const char **errmsg)
>  +{
>  +  /* This check uses PPC_OPCODE_403 because PPC405 is later defined
>  +   as a synonym.  If ever a 405 specific dialect is added this
>  +   check should use that instead. */
> +  if ((dialect & PPC_OPCODE_BOOKE) || (dialect & PPC_OPCODE_403))
> +  {
>  +    if (value > 7)
>  +      *errmsg = _("Invalid operand.  Must be between 0 and 7.");
>  +    if (value > 3)
>  +      return (insn | ((value & 0x07) << 16))
>  +             & (((insn >> 8) & 0x01) ? ~0 : ( ~( 1 << 20 )));
>  +    return insn | ((value & 0x07) << 16);
>  +  }
>  +  else
>  +  {
>  +    if (value > 3)
>  +           *errmsg = _("Invalid operand.  Must be between 0 and 3.");
>  +    return insn | ((value & 0x03) << 16);
>  +  }
>  +}
>  +
>    /* The TBR field in an XFX instruction.  This is just like SPR, but 
> it
>       is optional.  When TBR is omitted, it must be inserted as 268 
> (the
>       magic number of the TB register).  These functions treat 0
>
> Jeff Baker wrote:
>  > Below is an updated (and I believe more correct) version of this 
> patch.
>  >
> >
> > 2005-02-28 Jeff Baker <jbaker@qnx.com>
> >
> >       * ppc-opc.c (SPRG_MASK):  Allow 3 bits for register.
>  >       (powerpc_operands): Likewise.
>  >       (insert_sprg): New Function.
>  >       (powerpc_opcodes): reorder mtsprg/mfsprg opcodes
>  >       to allow disassembler to locate the correct one.
>  >      
> >
> > Index: ppc-opc.c
>  > ===================================================================
> > RCS file: /cvs/src/src/opcodes/ppc-opc.c,v
>  > retrieving revision 1.78
>  > diff -w -u -p -r1.78 ppc-opc.c
>  > --- ppc-opc.c 20 Jan 2005 06:54:48 -0000      1.78
>  > +++ ppc-opc.c 28 Feb 2005 18:02:08 -0000
>  > @@ -84,6 +84,7 @@ static unsigned long insert_sh6 (unsigne
>  >   static long extract_sh6 (unsigned long, int, int *);
> >   static unsigned long insert_spr (unsigned long, long, int, const 
> char
>  > **);
>  >   static long extract_spr (unsigned long, int, int *);
> > +static unsigned long insert_sprg (unsigned long, long, int, const 
> char
>  > **);
>  >   static unsigned long insert_tbr (unsigned long, long, int, const 
> char
>  > **);
>  >   static long extract_tbr (unsigned long, int, int *);
> >   static unsigned long insert_ev2 (unsigned long, long, int, const 
> char
>  > **);
>  > @@ -465,8 +466,8 @@ const struct powerpc_operand powerpc_ope
>  >
> >     /* The SPRG register number in an XFX form m[ft]sprg instruction.
>  > */
>  >   #define SPRG SPRBAT + 1
>  > -#define SPRG_MASK (0x3 << 16)
>  > -  { 2, 16, NULL, NULL, 0 },
>  > +#define SPRG_MASK (0x7 << 16)
>  > +  { 3, 16, insert_sprg, NULL, 0 },
>  >
> >     /* The SR field in an X form instruction.  */
>  >   #define SR SPRG + 1
>  > @@ -1397,6 +1398,36 @@ extract_spr (unsigned long insn,
>  >     return ((insn >> 16) & 0x1f) | ((insn >> 6) & 0x3e0);
>  >   }
>  >
> > +/* Some dialects (BookE, 405) have 8 SPRG registers instead of
>  > + the normal 4.  In addition, BookE mfsprg instructions must
>  > + have sprn5 cleared when using registers 4 through 7. */
>  > +
>  > +static unsigned long
>  > +insert_sprg (unsigned long insn,
>  > +         long value,
>  > +         int dialect,
>  > +         const char **errmsg)
>  > +{
>  > +  /* This check uses PPC_OPCODE_403 because PPC405 is later defined
>  > +   as a synonym.  If ever a 405 specific dialect is added this
>  > +   check should use that instead. */
> > +  if ((dialect & PPC_OPCODE_BOOKE) || (dialect & PPC_OPCODE_403))
> > +  {
>  > +    if (value > 7)
>  > +      *errmsg = _("Invalid operand.  Must be between 0 and 7.");
>  > +    if ((value > 3) && (dialect & PPC_OPCODE_BOOKE))
> > +      return (insn | ((value & 0x07) << 16))
>  > +           & (((insn >> 8) & 0x01) ? ~0 : ( ~( 1 << 20 )));
>  > +    return insn | ((value & 0x07) << 16);
>  > +  }
>  > +  else
>  > +  {
>  > +    if (value > 3)
>  > +         *errmsg = _("Invalid operand.  Must be between 0 and 3.");
>  > +    return insn | ((value & 0x03) << 16);
>  > +  }
>  > +}
>  > +
>  >   /* The TBR field in an XFX instruction.  This is just like SPR, 
> but it
>  >      is optional.  When TBR is omitted, it must be inserted as 268 
> (the
>  >      magic number of the TB register).  These functions treat 0
>  > @@ -3677,13 +3708,9 @@ const struct powerpc_opcode powerpc_opco
> >   { "mfbar",      XSPR(31,339,159),  XSPR_MASK, PPC860,       { RT } 
> },
>  >   { "mfvrsave",   XSPR(31,339,256),  XSPR_MASK, PPCVEC,       { RT 
> } },
>  >   { "mfusprg0",   XSPR(31,339,256),  XSPR_MASK, BOOKE,    { RT } },
>  > -{ "mfsprg4",    XSPR(31,339,260),  XSPR_MASK, PPC405,        { RT 
> } },
>  >   { "mfsprg4",    XSPR(31,339,260),  XSPR_MASK, BOOKE,        { RT 
> } },
>  > -{ "mfsprg5",    XSPR(31,339,261),  XSPR_MASK, PPC405,        { RT 
> } },
>  >   { "mfsprg5",    XSPR(31,339,261),  XSPR_MASK, BOOKE,        { RT 
> } },
>  > -{ "mfsprg6",    XSPR(31,339,262),  XSPR_MASK, PPC405,        { RT 
> } },
>  >   { "mfsprg6",    XSPR(31,339,262),  XSPR_MASK, BOOKE,        { RT 
> } },
>  > -{ "mfsprg7",    XSPR(31,339,263),  XSPR_MASK, PPC405,        { RT 
> } },
>  >   { "mfsprg7",    XSPR(31,339,263),  XSPR_MASK, BOOKE,        { RT 
> } },
>  >   { "mftb",       X(31,371),     X_MASK,    CLASSIC,  { RT, TBR } },
>  >   { "mftb",       XSPR(31,339,268),  XSPR_MASK, BOOKE,    { RT } },
>  > @@ -3696,6 +3723,10 @@ const struct powerpc_opcode powerpc_opco
> >   { "mfsprg1",    XSPR(31,339,273),  XSPR_MASK, PPC,  { RT } },
>  >   { "mfsprg2",    XSPR(31,339,274),  XSPR_MASK, PPC,  { RT } },
>  >   { "mfsprg3",    XSPR(31,339,275),  XSPR_MASK, PPC,  { RT } },
>  > +{ "mfsprg4",    XSPR(31,339,276),  XSPR_MASK, PPC405,        { RT 
> } },
>  > +{ "mfsprg5",    XSPR(31,339,277),  XSPR_MASK, PPC405,        { RT 
> } },
>  > +{ "mfsprg6",    XSPR(31,339,278),  XSPR_MASK, PPC405,        { RT 
> } },
>  > +{ "mfsprg7",    XSPR(31,339,279),  XSPR_MASK, PPC405,        { RT 
> } },
>  >   { "mfasr",      XSPR(31,339,280),  XSPR_MASK, PPC64,        { RT 
> } },
>  >   { "mfear",      XSPR(31,339,282),  XSPR_MASK, PPC,  { RT } },
>  >   { "mfpir",      XSPR(31,339,286),  XSPR_MASK, BOOKE,    { RT } },

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] Handle mtsprg and mfsprg properly for BookE
  2005-02-28 21:26   ` Kumar Gala
@ 2005-02-28 22:52     ` Jeff Baker
  2005-02-28 23:09     ` Jeff Baker
  1 sibling, 0 replies; 19+ messages in thread
From: Jeff Baker @ 2005-02-28 22:52 UTC (permalink / raw)
  To: Kumar Gala; +Cc: binutils

I can, but can anyone explain why booke.s specifies that it is assembled 
with -mbooke32 but contains mostly instructions that are specific to 
BOOKE64?

Kumar Gala wrote:
> Jeff,
> 
> Can I ask you update some of the tests in gas/testsuite/gas/ppc to 
> reflect these instructions.
> 
> - kumar
> 
> On Feb 28, 2005, at 1:40 PM, Jeff Baker wrote:
> 
> 
>>The following patch may also be correct.  I've seen conflicting
>>information about whether PPC405 also needs the sprn5 bit cleared on
>>mfsprg for registers 4 through 7.
>>
>>2005-02-28 Jeff Baker <jbaker@qnx.com>
>>        * ppc-opc.c (SPRG_MASK):  Allow 3 bits for register.
>>         (powerpc_operands): Likewise.
>>         (insert_sprg): New Function.
>>
>>
>>
>>Index: ppc-opc.c
>> ===================================================================
>>RCS file: /cvs/src/src/opcodes/ppc-opc.c,v
>> retrieving revision 1.78
>> diff -w -u -p -r1.78 ppc-opc.c
>> --- ppc-opc.c   20 Jan 2005 06:54:48 -0000      1.78
>> +++ ppc-opc.c   28 Feb 2005 19:35:21 -0000
>> @@ -84,6 +84,7 @@ static unsigned long insert_sh6 (unsigne
>>   static long extract_sh6 (unsigned long, int, int *);
>>  static unsigned long insert_spr (unsigned long, long, int, const 
>>char **);
>>   static long extract_spr (unsigned long, int, int *);
>>+static unsigned long insert_sprg (unsigned long, long, int, const 
>>char **);
>>   static unsigned long insert_tbr (unsigned long, long, int, const 
>>char **);
>>   static long extract_tbr (unsigned long, int, int *);
>>  static unsigned long insert_ev2 (unsigned long, long, int, const 
>>char **);
>> @@ -465,8 +466,8 @@ const struct powerpc_operand powerpc_ope
>>
>>    /* The SPRG register number in an XFX form m[ft]sprg instruction. 
> 
> 
>>*/
>>   #define SPRG SPRBAT + 1
>> -#define SPRG_MASK (0x3 << 16)
>> -  { 2, 16, NULL, NULL, 0 },
>> +#define SPRG_MASK (0x7 << 16)
>> +  { 3, 16, insert_sprg, NULL, 0 },
>>
>>    /* The SR field in an X form instruction.  */
>>   #define SR SPRG + 1
>> @@ -1397,6 +1398,36 @@ extract_spr (unsigned long insn,
>>     return ((insn >> 16) & 0x1f) | ((insn >> 6) & 0x3e0);
>>   }
>>
>>+/* Some dialects (BookE, 405) have 8 SPRG registers instead of
>> + the normal 4.  In addition, mfsprg instructions must
>> + have sprn5 cleared when using registers 4 through 7. */
>>+
>> +static unsigned long
>> +insert_sprg (unsigned long insn,
>> +           long value,
>> +           int dialect,
>> +           const char **errmsg)
>> +{
>> +  /* This check uses PPC_OPCODE_403 because PPC405 is later defined
>> +   as a synonym.  If ever a 405 specific dialect is added this
>> +   check should use that instead. */
>>+  if ((dialect & PPC_OPCODE_BOOKE) || (dialect & PPC_OPCODE_403))
>>+  {
>> +    if (value > 7)
>> +      *errmsg = _("Invalid operand.  Must be between 0 and 7.");
>> +    if (value > 3)
>> +      return (insn | ((value & 0x07) << 16))
>> +             & (((insn >> 8) & 0x01) ? ~0 : ( ~( 1 << 20 )));
>> +    return insn | ((value & 0x07) << 16);
>> +  }
>> +  else
>> +  {
>> +    if (value > 3)
>> +           *errmsg = _("Invalid operand.  Must be between 0 and
> 
> 3.");
> 
>> +    return insn | ((value & 0x03) << 16);
>> +  }
>> +}
>> +
>>   /* The TBR field in an XFX instruction.  This is just like SPR, but
> 
> 
>>it
>>      is optional.  When TBR is omitted, it must be inserted as 268 
>>(the
>>      magic number of the TB register).  These functions treat 0
>>
>>Jeff Baker wrote:
>> > Below is an updated (and I believe more correct) version of this 
>>patch.
>> >
>>
>>>2005-02-28 Jeff Baker <jbaker@qnx.com>
>>>
>>>      * ppc-opc.c (SPRG_MASK):  Allow 3 bits for register.
>>
>> >       (powerpc_operands): Likewise.
>> >       (insert_sprg): New Function.
>> >       (powerpc_opcodes): reorder mtsprg/mfsprg opcodes
>> >       to allow disassembler to locate the correct one.
>> >      
>>
>>>Index: ppc-opc.c
>>
>> > ===================================================================
>>
>>>RCS file: /cvs/src/src/opcodes/ppc-opc.c,v
>>
>> > retrieving revision 1.78
>> > diff -w -u -p -r1.78 ppc-opc.c
>> > --- ppc-opc.c 20 Jan 2005 06:54:48 -0000      1.78
>> > +++ ppc-opc.c 28 Feb 2005 18:02:08 -0000
>> > @@ -84,6 +84,7 @@ static unsigned long insert_sh6 (unsigne
>> >   static long extract_sh6 (unsigned long, int, int *);
>>
>>>   static unsigned long insert_spr (unsigned long, long, int, const 
>>
>>char
>> > **);
>> >   static long extract_spr (unsigned long, int, int *);
>>
>>>+static unsigned long insert_sprg (unsigned long, long, int, const 
>>
>>char
>> > **);
>> >   static unsigned long insert_tbr (unsigned long, long, int, const 
>>char
>> > **);
>> >   static long extract_tbr (unsigned long, int, int *);
>>
>>>   static unsigned long insert_ev2 (unsigned long, long, int, const 
>>
>>char
>> > **);
>> > @@ -465,8 +466,8 @@ const struct powerpc_operand powerpc_ope
>> >
>>
>>>     /* The SPRG register number in an XFX form m[ft]sprg
> 
> instruction.
> 
>> > */
>> >   #define SPRG SPRBAT + 1
>> > -#define SPRG_MASK (0x3 << 16)
>> > -  { 2, 16, NULL, NULL, 0 },
>> > +#define SPRG_MASK (0x7 << 16)
>> > +  { 3, 16, insert_sprg, NULL, 0 },
>> >
>>
>>>     /* The SR field in an X form instruction.  */
>>
>> >   #define SR SPRG + 1
>> > @@ -1397,6 +1398,36 @@ extract_spr (unsigned long insn,
>> >     return ((insn >> 16) & 0x1f) | ((insn >> 6) & 0x3e0);
>> >   }
>> >
>>
>>>+/* Some dialects (BookE, 405) have 8 SPRG registers instead of
>>
>> > + the normal 4.  In addition, BookE mfsprg instructions must
>> > + have sprn5 cleared when using registers 4 through 7. */
>> > +
>> > +static unsigned long
>> > +insert_sprg (unsigned long insn,
>> > +         long value,
>> > +         int dialect,
>> > +         const char **errmsg)
>> > +{
>> > +  /* This check uses PPC_OPCODE_403 because PPC405 is later
> 
> defined
> 
>> > +   as a synonym.  If ever a 405 specific dialect is added this
>> > +   check should use that instead. */
>>
>>>+  if ((dialect & PPC_OPCODE_BOOKE) || (dialect & PPC_OPCODE_403))
>>>+  {
>>
>> > +    if (value > 7)
>> > +      *errmsg = _("Invalid operand.  Must be between 0 and 7.");
>> > +    if ((value > 3) && (dialect & PPC_OPCODE_BOOKE))
>>
>>>+      return (insn | ((value & 0x07) << 16))
>>
>> > +           & (((insn >> 8) & 0x01) ? ~0 : ( ~( 1 << 20 )));
>> > +    return insn | ((value & 0x07) << 16);
>> > +  }
>> > +  else
>> > +  {
>> > +    if (value > 3)
>> > +         *errmsg = _("Invalid operand.  Must be between 0 and
> 
> 3.");
> 
>> > +    return insn | ((value & 0x03) << 16);
>> > +  }
>> > +}
>> > +
>> >   /* The TBR field in an XFX instruction.  This is just like SPR, 
>>but it
>> >      is optional.  When TBR is omitted, it must be inserted as 268 
>>(the
>> >      magic number of the TB register).  These functions treat 0
>> > @@ -3677,13 +3708,9 @@ const struct powerpc_opcode powerpc_opco
>>
>>>   { "mfbar",      XSPR(31,339,159),  XSPR_MASK, PPC860,       { RT }
> 
> 
>>},
>> >   { "mfvrsave",   XSPR(31,339,256),  XSPR_MASK, PPCVEC,       { RT 
>>} },
>> >   { "mfusprg0",   XSPR(31,339,256),  XSPR_MASK, BOOKE,    { RT } },
>> > -{ "mfsprg4",    XSPR(31,339,260),  XSPR_MASK, PPC405,        { RT 
>>} },
>> >   { "mfsprg4",    XSPR(31,339,260),  XSPR_MASK, BOOKE,        { RT 
>>} },
>> > -{ "mfsprg5",    XSPR(31,339,261),  XSPR_MASK, PPC405,        { RT 
>>} },
>> >   { "mfsprg5",    XSPR(31,339,261),  XSPR_MASK, BOOKE,        { RT 
>>} },
>> > -{ "mfsprg6",    XSPR(31,339,262),  XSPR_MASK, PPC405,        { RT 
>>} },
>> >   { "mfsprg6",    XSPR(31,339,262),  XSPR_MASK, BOOKE,        { RT 
>>} },
>> > -{ "mfsprg7",    XSPR(31,339,263),  XSPR_MASK, PPC405,        { RT 
>>} },
>> >   { "mfsprg7",    XSPR(31,339,263),  XSPR_MASK, BOOKE,        { RT 
>>} },
>> >   { "mftb",       X(31,371),     X_MASK,    CLASSIC,  { RT, TBR }
> 
> },
> 
>> >   { "mftb",       XSPR(31,339,268),  XSPR_MASK, BOOKE,    { RT } },
>> > @@ -3696,6 +3723,10 @@ const struct powerpc_opcode powerpc_opco
>>
>>>   { "mfsprg1",    XSPR(31,339,273),  XSPR_MASK, PPC,  { RT } },
>>
>> >   { "mfsprg2",    XSPR(31,339,274),  XSPR_MASK, PPC,  { RT } },
>> >   { "mfsprg3",    XSPR(31,339,275),  XSPR_MASK, PPC,  { RT } },
>> > +{ "mfsprg4",    XSPR(31,339,276),  XSPR_MASK, PPC405,        { RT 
>>} },
>> > +{ "mfsprg5",    XSPR(31,339,277),  XSPR_MASK, PPC405,        { RT 
>>} },
>> > +{ "mfsprg6",    XSPR(31,339,278),  XSPR_MASK, PPC405,        { RT 
>>} },
>> > +{ "mfsprg7",    XSPR(31,339,279),  XSPR_MASK, PPC405,        { RT 
>>} },
>> >   { "mfasr",      XSPR(31,339,280),  XSPR_MASK, PPC64,        { RT 
>>} },
>> >   { "mfear",      XSPR(31,339,282),  XSPR_MASK, PPC,  { RT } },
>> >   { "mfpir",      XSPR(31,339,286),  XSPR_MASK, BOOKE,    { RT } },

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] Handle mtsprg and mfsprg properly for BookE
  2005-02-28 21:26   ` Kumar Gala
  2005-02-28 22:52     ` Jeff Baker
@ 2005-02-28 23:09     ` Jeff Baker
  2005-03-07 15:22       ` Jeff Baker
  1 sibling, 1 reply; 19+ messages in thread
From: Jeff Baker @ 2005-02-28 23:09 UTC (permalink / raw)
  To: Kumar Gala; +Cc: binutils

2005-02-28  Jeff Baker <jbaker@qnx.com>

	* gas/ppc/booke.s: Add new m[t,f]sprg testcases.
	* gas/ppc/booke.d: Likewise.


Index: gas/ppc/booke.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/ppc/booke.d,v
retrieving revision 1.8
diff -w -u -p -r1.8 booke.d
--- gas/ppc/booke.d	16 Mar 2004 00:58:42 -0000	1.8
+++ gas/ppc/booke.d	28 Feb 2005 20:48:36 -0000
@@ -142,3 +142,6 @@ Disassembly of section \.text:
   1c0:	7c 00 06 ac 	mbar
   1c4:	7c 00 06 ac 	mbar
   1c8:	7c 20 06 ac 	mbar    1
+ 1cc:	7c f3 42 a6	mfsprg  r7,3
+ 1d0:	7c e7 42 a6	mfsprg7 r7
+ 1d4:	7c f7 43 a6	mtsprg  7,r7
Index: gas/ppc/booke.s
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/ppc/booke.s,v
retrieving revision 1.3
diff -w -u -p -r1.3 booke.s
--- gas/ppc/booke.s	10 Dec 2003 22:12:50 -0000	1.3
+++ gas/ppc/booke.s	28 Feb 2005 20:48:36 -0000
@@ -1,5 +1,5 @@
  # Motorola PowerPC BookE tests
-#as: -mbooke32
+#as: -mbooke64
  	.section ".text"
  start:
  	bce	1, 5, branch_target_1
@@ -134,3 +134,7 @@ branch_target_8:
  	mbar
  	mbar	0
  	mbar	1
+
+	mfsprg %r7, 3
+	mfsprg %r7, 7
+	mtsprg 7, %r7

Kumar Gala wrote:
> Jeff,
> 
> Can I ask you update some of the tests in gas/testsuite/gas/ppc to 
> reflect these instructions.
> 
> - kumar
> 
> On Feb 28, 2005, at 1:40 PM, Jeff Baker wrote:
> 
> 
>>The following patch may also be correct.  I've seen conflicting
>>information about whether PPC405 also needs the sprn5 bit cleared on
>>mfsprg for registers 4 through 7.
>>
>>2005-02-28 Jeff Baker <jbaker@qnx.com>
>>        * ppc-opc.c (SPRG_MASK):  Allow 3 bits for register.
>>         (powerpc_operands): Likewise.
>>         (insert_sprg): New Function.
>>
>>
>>
>>Index: ppc-opc.c
>> ===================================================================
>>RCS file: /cvs/src/src/opcodes/ppc-opc.c,v
>> retrieving revision 1.78
>> diff -w -u -p -r1.78 ppc-opc.c
>> --- ppc-opc.c   20 Jan 2005 06:54:48 -0000      1.78
>> +++ ppc-opc.c   28 Feb 2005 19:35:21 -0000
>> @@ -84,6 +84,7 @@ static unsigned long insert_sh6 (unsigne
>>   static long extract_sh6 (unsigned long, int, int *);
>>  static unsigned long insert_spr (unsigned long, long, int, const 
>>char **);
>>   static long extract_spr (unsigned long, int, int *);
>>+static unsigned long insert_sprg (unsigned long, long, int, const 
>>char **);
>>   static unsigned long insert_tbr (unsigned long, long, int, const 
>>char **);
>>   static long extract_tbr (unsigned long, int, int *);
>>  static unsigned long insert_ev2 (unsigned long, long, int, const 
>>char **);
>> @@ -465,8 +466,8 @@ const struct powerpc_operand powerpc_ope
>>
>>    /* The SPRG register number in an XFX form m[ft]sprg instruction. 
> 
> 
>>*/
>>   #define SPRG SPRBAT + 1
>> -#define SPRG_MASK (0x3 << 16)
>> -  { 2, 16, NULL, NULL, 0 },
>> +#define SPRG_MASK (0x7 << 16)
>> +  { 3, 16, insert_sprg, NULL, 0 },
>>
>>    /* The SR field in an X form instruction.  */
>>   #define SR SPRG + 1
>> @@ -1397,6 +1398,36 @@ extract_spr (unsigned long insn,
>>     return ((insn >> 16) & 0x1f) | ((insn >> 6) & 0x3e0);
>>   }
>>
>>+/* Some dialects (BookE, 405) have 8 SPRG registers instead of
>> + the normal 4.  In addition, mfsprg instructions must
>> + have sprn5 cleared when using registers 4 through 7. */
>>+
>> +static unsigned long
>> +insert_sprg (unsigned long insn,
>> +           long value,
>> +           int dialect,
>> +           const char **errmsg)
>> +{
>> +  /* This check uses PPC_OPCODE_403 because PPC405 is later defined
>> +   as a synonym.  If ever a 405 specific dialect is added this
>> +   check should use that instead. */
>>+  if ((dialect & PPC_OPCODE_BOOKE) || (dialect & PPC_OPCODE_403))
>>+  {
>> +    if (value > 7)
>> +      *errmsg = _("Invalid operand.  Must be between 0 and 7.");
>> +    if (value > 3)
>> +      return (insn | ((value & 0x07) << 16))
>> +             & (((insn >> 8) & 0x01) ? ~0 : ( ~( 1 << 20 )));
>> +    return insn | ((value & 0x07) << 16);
>> +  }
>> +  else
>> +  {
>> +    if (value > 3)
>> +           *errmsg = _("Invalid operand.  Must be between 0 and
> 
> 3.");
> 
>> +    return insn | ((value & 0x03) << 16);
>> +  }
>> +}
>> +
>>   /* The TBR field in an XFX instruction.  This is just like SPR, but
> 
> 
>>it
>>      is optional.  When TBR is omitted, it must be inserted as 268 
>>(the
>>      magic number of the TB register).  These functions treat 0
>>
>>Jeff Baker wrote:
>> > Below is an updated (and I believe more correct) version of this 
>>patch.
>> >
>>
>>>2005-02-28 Jeff Baker <jbaker@qnx.com>
>>>
>>>      * ppc-opc.c (SPRG_MASK):  Allow 3 bits for register.
>>
>> >       (powerpc_operands): Likewise.
>> >       (insert_sprg): New Function.
>> >       (powerpc_opcodes): reorder mtsprg/mfsprg opcodes
>> >       to allow disassembler to locate the correct one.
>> >      
>>
>>>Index: ppc-opc.c
>>
>> > ===================================================================
>>
>>>RCS file: /cvs/src/src/opcodes/ppc-opc.c,v
>>
>> > retrieving revision 1.78
>> > diff -w -u -p -r1.78 ppc-opc.c
>> > --- ppc-opc.c 20 Jan 2005 06:54:48 -0000      1.78
>> > +++ ppc-opc.c 28 Feb 2005 18:02:08 -0000
>> > @@ -84,6 +84,7 @@ static unsigned long insert_sh6 (unsigne
>> >   static long extract_sh6 (unsigned long, int, int *);
>>
>>>   static unsigned long insert_spr (unsigned long, long, int, const 
>>
>>char
>> > **);
>> >   static long extract_spr (unsigned long, int, int *);
>>
>>>+static unsigned long insert_sprg (unsigned long, long, int, const 
>>
>>char
>> > **);
>> >   static unsigned long insert_tbr (unsigned long, long, int, const 
>>char
>> > **);
>> >   static long extract_tbr (unsigned long, int, int *);
>>
>>>   static unsigned long insert_ev2 (unsigned long, long, int, const 
>>
>>char
>> > **);
>> > @@ -465,8 +466,8 @@ const struct powerpc_operand powerpc_ope
>> >
>>
>>>     /* The SPRG register number in an XFX form m[ft]sprg
> 
> instruction.
> 
>> > */
>> >   #define SPRG SPRBAT + 1
>> > -#define SPRG_MASK (0x3 << 16)
>> > -  { 2, 16, NULL, NULL, 0 },
>> > +#define SPRG_MASK (0x7 << 16)
>> > +  { 3, 16, insert_sprg, NULL, 0 },
>> >
>>
>>>     /* The SR field in an X form instruction.  */
>>
>> >   #define SR SPRG + 1
>> > @@ -1397,6 +1398,36 @@ extract_spr (unsigned long insn,
>> >     return ((insn >> 16) & 0x1f) | ((insn >> 6) & 0x3e0);
>> >   }
>> >
>>
>>>+/* Some dialects (BookE, 405) have 8 SPRG registers instead of
>>
>> > + the normal 4.  In addition, BookE mfsprg instructions must
>> > + have sprn5 cleared when using registers 4 through 7. */
>> > +
>> > +static unsigned long
>> > +insert_sprg (unsigned long insn,
>> > +         long value,
>> > +         int dialect,
>> > +         const char **errmsg)
>> > +{
>> > +  /* This check uses PPC_OPCODE_403 because PPC405 is later
> 
> defined
> 
>> > +   as a synonym.  If ever a 405 specific dialect is added this
>> > +   check should use that instead. */
>>
>>>+  if ((dialect & PPC_OPCODE_BOOKE) || (dialect & PPC_OPCODE_403))
>>>+  {
>>
>> > +    if (value > 7)
>> > +      *errmsg = _("Invalid operand.  Must be between 0 and 7.");
>> > +    if ((value > 3) && (dialect & PPC_OPCODE_BOOKE))
>>
>>>+      return (insn | ((value & 0x07) << 16))
>>
>> > +           & (((insn >> 8) & 0x01) ? ~0 : ( ~( 1 << 20 )));
>> > +    return insn | ((value & 0x07) << 16);
>> > +  }
>> > +  else
>> > +  {
>> > +    if (value > 3)
>> > +         *errmsg = _("Invalid operand.  Must be between 0 and
> 
> 3.");
> 
>> > +    return insn | ((value & 0x03) << 16);
>> > +  }
>> > +}
>> > +
>> >   /* The TBR field in an XFX instruction.  This is just like SPR, 
>>but it
>> >      is optional.  When TBR is omitted, it must be inserted as 268 
>>(the
>> >      magic number of the TB register).  These functions treat 0
>> > @@ -3677,13 +3708,9 @@ const struct powerpc_opcode powerpc_opco
>>
>>>   { "mfbar",      XSPR(31,339,159),  XSPR_MASK, PPC860,       { RT }
> 
> 
>>},
>> >   { "mfvrsave",   XSPR(31,339,256),  XSPR_MASK, PPCVEC,       { RT 
>>} },
>> >   { "mfusprg0",   XSPR(31,339,256),  XSPR_MASK, BOOKE,    { RT } },
>> > -{ "mfsprg4",    XSPR(31,339,260),  XSPR_MASK, PPC405,        { RT 
>>} },
>> >   { "mfsprg4",    XSPR(31,339,260),  XSPR_MASK, BOOKE,        { RT 
>>} },
>> > -{ "mfsprg5",    XSPR(31,339,261),  XSPR_MASK, PPC405,        { RT 
>>} },
>> >   { "mfsprg5",    XSPR(31,339,261),  XSPR_MASK, BOOKE,        { RT 
>>} },
>> > -{ "mfsprg6",    XSPR(31,339,262),  XSPR_MASK, PPC405,        { RT 
>>} },
>> >   { "mfsprg6",    XSPR(31,339,262),  XSPR_MASK, BOOKE,        { RT 
>>} },
>> > -{ "mfsprg7",    XSPR(31,339,263),  XSPR_MASK, PPC405,        { RT 
>>} },
>> >   { "mfsprg7",    XSPR(31,339,263),  XSPR_MASK, BOOKE,        { RT 
>>} },
>> >   { "mftb",       X(31,371),     X_MASK,    CLASSIC,  { RT, TBR }
> 
> },
> 
>> >   { "mftb",       XSPR(31,339,268),  XSPR_MASK, BOOKE,    { RT } },
>> > @@ -3696,6 +3723,10 @@ const struct powerpc_opcode powerpc_opco
>>
>>>   { "mfsprg1",    XSPR(31,339,273),  XSPR_MASK, PPC,  { RT } },
>>
>> >   { "mfsprg2",    XSPR(31,339,274),  XSPR_MASK, PPC,  { RT } },
>> >   { "mfsprg3",    XSPR(31,339,275),  XSPR_MASK, PPC,  { RT } },
>> > +{ "mfsprg4",    XSPR(31,339,276),  XSPR_MASK, PPC405,        { RT 
>>} },
>> > +{ "mfsprg5",    XSPR(31,339,277),  XSPR_MASK, PPC405,        { RT 
>>} },
>> > +{ "mfsprg6",    XSPR(31,339,278),  XSPR_MASK, PPC405,        { RT 
>>} },
>> > +{ "mfsprg7",    XSPR(31,339,279),  XSPR_MASK, PPC405,        { RT 
>>} },
>> >   { "mfasr",      XSPR(31,339,280),  XSPR_MASK, PPC64,        { RT 
>>} },
>> >   { "mfear",      XSPR(31,339,282),  XSPR_MASK, PPC,  { RT } },
>> >   { "mfpir",      XSPR(31,339,286),  XSPR_MASK, BOOKE,    { RT } },

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] Handle mtsprg and mfsprg properly for BookE
  2005-02-28 23:09     ` Jeff Baker
@ 2005-03-07 15:22       ` Jeff Baker
  2005-03-08 11:20         ` Alan Modra
  0 siblings, 1 reply; 19+ messages in thread
From: Jeff Baker @ 2005-03-07 15:22 UTC (permalink / raw)
  To: jbaker; +Cc: binutils

Ping.  Updated for today and confirmed as the correct behaviour.

2005-03-07	Jeff Baker <jbaker@qnx.com>

	* ppc-opc.c (SPRG_MASK):  Allow 3 bits for register.
	(powerpc_operands): Likewise.
	(insert_sprg): New Function.

Index: ppc-opc.c
===================================================================
RCS file: /cvs/src/src/opcodes/ppc-opc.c,v
retrieving revision 1.78
diff -w -u -p -r1.78 ppc-opc.c
--- ppc-opc.c	20 Jan 2005 06:54:48 -0000	1.78
+++ ppc-opc.c	7 Mar 2005 15:18:04 -0000
@@ -84,6 +84,7 @@ static unsigned long insert_sh6 (unsigne
  static long extract_sh6 (unsigned long, int, int *);
  static unsigned long insert_spr (unsigned long, long, int, const char **);
  static long extract_spr (unsigned long, int, int *);
+static unsigned long insert_sprg (unsigned long, long, int, const char **);
  static unsigned long insert_tbr (unsigned long, long, int, const char **);
  static long extract_tbr (unsigned long, int, int *);
  static unsigned long insert_ev2 (unsigned long, long, int, const char **);
@@ -465,8 +466,8 @@ const struct powerpc_operand powerpc_ope

    /* The SPRG register number in an XFX form m[ft]sprg instruction.  */
  #define SPRG SPRBAT + 1
-#define SPRG_MASK (0x3 << 16)
-  { 2, 16, NULL, NULL, 0 },
+#define SPRG_MASK (0x7 << 16)
+  { 3, 16, insert_sprg, NULL, 0 },

    /* The SR field in an X form instruction.  */
  #define SR SPRG + 1
@@ -1397,6 +1398,36 @@ extract_spr (unsigned long insn,
    return ((insn >> 16) & 0x1f) | ((insn >> 6) & 0x3e0);
  }

+/* Some dialects (BookE, 405) have 8 SPRG registers instead of
+ the normal 4.  In addition, mfsprg instructions must
+ have sprn5 cleared when using registers 4 through 7. */
+
+static unsigned long
+insert_sprg (unsigned long insn,
+	    long value,
+	    int dialect,
+	    const char **errmsg)
+{
+  /* This check uses PPC_OPCODE_403 because PPC405 is later defined
+   as a synonym.  If ever a 405 specific dialect is added this
+   check should use that instead. */
+  if ((dialect & PPC_OPCODE_BOOKE) || (dialect & PPC_OPCODE_403))
+  {
+    if (value > 7)
+      *errmsg = _("Invalid operand.  Must be between 0 and 7.");
+    if (value > 3)
+      return (insn | ((value & 0x07) << 16))
+	      & (((insn >> 8) & 0x01) ? ~0 : ( ~( 1 << 20 )));
+    return insn | ((value & 0x07) << 16);
+  }
+  else
+  {
+    if (value > 3)
+	    *errmsg = _("Invalid operand.  Must be between 0 and 3.");
+    return insn | ((value & 0x03) << 16);
+  }
+}
+
  /* The TBR field in an XFX instruction.  This is just like SPR, but it
     is optional.  When TBR is omitted, it must be inserted as 268 (the
     magic number of the TB register).  These functions treat 0


2005-03-07  Jeff Baker <jbaker@qnx.com>

  	* gas/ppc/booke.s: Add new m[t,f]sprg testcases.
	* gas/ppc/booke.d: Likewise.

Index: booke.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/ppc/booke.d,v
retrieving revision 1.9
diff -w -u -p -r1.9 booke.d
--- booke.d	2 Mar 2005 13:25:01 -0000	1.9
+++ booke.d	7 Mar 2005 15:18:14 -0000
@@ -142,3 +142,6 @@ Disassembly of section \.text:
   1c0:	7c 00 06 ac 	mbar
   1c4:	7c 00 06 ac 	mbar
   1c8:	7c 20 06 ac 	mbar    1
+ 1cc:	7c f3 42 a6	mfsprg  r7,3
+ 1d0:	7c e7 42 a6	mfsprg7 r7
+ 1d4:	7c f7 43 a6	mtsprg  7,r7
Index: booke.s
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/ppc/booke.s,v
retrieving revision 1.3
diff -w -u -p -r1.3 booke.s
--- booke.s	10 Dec 2003 22:12:50 -0000	1.3
+++ booke.s	7 Mar 2005 15:18:14 -0000
@@ -1,5 +1,5 @@
  # Motorola PowerPC BookE tests
-#as: -mbooke32
+#as: -mbooke64
  	.section ".text"
  start:
  	bce	1, 5, branch_target_1
@@ -134,3 +134,7 @@ branch_target_8:
  	mbar
  	mbar	0
  	mbar	1
+
+	mfsprg %r7, 3
+	mfsprg %r7, 7
+	mtsprg 7, %r7

Jeff Baker wrote:
> 2005-02-28  Jeff Baker <jbaker@qnx.com>
> 
> 	* gas/ppc/booke.s: Add new m[t,f]sprg testcases.
> 	* gas/ppc/booke.d: Likewise.
> 
> 
> Index: gas/ppc/booke.d
> ===================================================================
> RCS file: /cvs/src/src/gas/testsuite/gas/ppc/booke.d,v
> retrieving revision 1.8
> diff -w -u -p -r1.8 booke.d
> --- gas/ppc/booke.d	16 Mar 2004 00:58:42 -0000	1.8
> +++ gas/ppc/booke.d	28 Feb 2005 20:48:36 -0000
> @@ -142,3 +142,6 @@ Disassembly of section \.text:
>    1c0:	7c 00 06 ac 	mbar
>    1c4:	7c 00 06 ac 	mbar
>    1c8:	7c 20 06 ac 	mbar    1
> + 1cc:	7c f3 42 a6	mfsprg  r7,3
> + 1d0:	7c e7 42 a6	mfsprg7 r7
> + 1d4:	7c f7 43 a6	mtsprg  7,r7
> Index: gas/ppc/booke.s
> ===================================================================
> RCS file: /cvs/src/src/gas/testsuite/gas/ppc/booke.s,v
> retrieving revision 1.3
> diff -w -u -p -r1.3 booke.s
> --- gas/ppc/booke.s	10 Dec 2003 22:12:50 -0000	1.3
> +++ gas/ppc/booke.s	28 Feb 2005 20:48:36 -0000
> @@ -1,5 +1,5 @@
>   # Motorola PowerPC BookE tests
> -#as: -mbooke32
> +#as: -mbooke64
>   	.section ".text"
>   start:
>   	bce	1, 5, branch_target_1
> @@ -134,3 +134,7 @@ branch_target_8:
>   	mbar
>   	mbar	0
>   	mbar	1
> +
> +	mfsprg %r7, 3
> +	mfsprg %r7, 7
> +	mtsprg 7, %r7
> 
> Kumar Gala wrote:
> 
>>Jeff,
>>
>>Can I ask you update some of the tests in gas/testsuite/gas/ppc to 
>>reflect these instructions.
>>
>>- kumar
>>
>>On Feb 28, 2005, at 1:40 PM, Jeff Baker wrote:
>>
>>
>>
>>>The following patch may also be correct.  I've seen conflicting
>>>information about whether PPC405 also needs the sprn5 bit cleared on
>>>mfsprg for registers 4 through 7.
>>>
>>>2005-02-28 Jeff Baker <jbaker@qnx.com>
>>>       * ppc-opc.c (SPRG_MASK):  Allow 3 bits for register.
>>>        (powerpc_operands): Likewise.
>>>        (insert_sprg): New Function.
>>>
>>>
>>>
>>>Index: ppc-opc.c
>>>===================================================================
>>>RCS file: /cvs/src/src/opcodes/ppc-opc.c,v
>>>retrieving revision 1.78
>>>diff -w -u -p -r1.78 ppc-opc.c
>>>--- ppc-opc.c   20 Jan 2005 06:54:48 -0000      1.78
>>>+++ ppc-opc.c   28 Feb 2005 19:35:21 -0000
>>>@@ -84,6 +84,7 @@ static unsigned long insert_sh6 (unsigne
>>>  static long extract_sh6 (unsigned long, int, int *);
>>> static unsigned long insert_spr (unsigned long, long, int, const 
>>>char **);
>>>  static long extract_spr (unsigned long, int, int *);
>>>+static unsigned long insert_sprg (unsigned long, long, int, const 
>>>char **);
>>>  static unsigned long insert_tbr (unsigned long, long, int, const 
>>>char **);
>>>  static long extract_tbr (unsigned long, int, int *);
>>> static unsigned long insert_ev2 (unsigned long, long, int, const 
>>>char **);
>>>@@ -465,8 +466,8 @@ const struct powerpc_operand powerpc_ope
>>>
>>>   /* The SPRG register number in an XFX form m[ft]sprg instruction. 
>>
>>
>>>*/
>>>  #define SPRG SPRBAT + 1
>>>-#define SPRG_MASK (0x3 << 16)
>>>-  { 2, 16, NULL, NULL, 0 },
>>>+#define SPRG_MASK (0x7 << 16)
>>>+  { 3, 16, insert_sprg, NULL, 0 },
>>>
>>>   /* The SR field in an X form instruction.  */
>>>  #define SR SPRG + 1
>>>@@ -1397,6 +1398,36 @@ extract_spr (unsigned long insn,
>>>    return ((insn >> 16) & 0x1f) | ((insn >> 6) & 0x3e0);
>>>  }
>>>
>>>+/* Some dialects (BookE, 405) have 8 SPRG registers instead of
>>>+ the normal 4.  In addition, mfsprg instructions must
>>>+ have sprn5 cleared when using registers 4 through 7. */
>>>+
>>>+static unsigned long
>>>+insert_sprg (unsigned long insn,
>>>+           long value,
>>>+           int dialect,
>>>+           const char **errmsg)
>>>+{
>>>+  /* This check uses PPC_OPCODE_403 because PPC405 is later defined
>>>+   as a synonym.  If ever a 405 specific dialect is added this
>>>+   check should use that instead. */
>>>+  if ((dialect & PPC_OPCODE_BOOKE) || (dialect & PPC_OPCODE_403))
>>>+  {
>>>+    if (value > 7)
>>>+      *errmsg = _("Invalid operand.  Must be between 0 and 7.");
>>>+    if (value > 3)
>>>+      return (insn | ((value & 0x07) << 16))
>>>+             & (((insn >> 8) & 0x01) ? ~0 : ( ~( 1 << 20 )));
>>>+    return insn | ((value & 0x07) << 16);
>>>+  }
>>>+  else
>>>+  {
>>>+    if (value > 3)
>>>+           *errmsg = _("Invalid operand.  Must be between 0 and
>>
>>3.");
>>
>>
>>>+    return insn | ((value & 0x03) << 16);
>>>+  }
>>>+}
>>>+
>>>  /* The TBR field in an XFX instruction.  This is just like SPR, but
>>
>>
>>>it
>>>     is optional.  When TBR is omitted, it must be inserted as 268 
>>>(the
>>>     magic number of the TB register).  These functions treat 0
>>>
>>>Jeff Baker wrote:
>>>
>>>>Below is an updated (and I believe more correct) version of this 
>>>
>>>patch.
>>>
>>>>2005-02-28 Jeff Baker <jbaker@qnx.com>
>>>>
>>>>     * ppc-opc.c (SPRG_MASK):  Allow 3 bits for register.
>>>
>>>>      (powerpc_operands): Likewise.
>>>>      (insert_sprg): New Function.
>>>>      (powerpc_opcodes): reorder mtsprg/mfsprg opcodes
>>>>      to allow disassembler to locate the correct one.
>>>>     
>>>
>>>>Index: ppc-opc.c
>>>
>>>>===================================================================
>>>
>>>>RCS file: /cvs/src/src/opcodes/ppc-opc.c,v
>>>
>>>>retrieving revision 1.78
>>>>diff -w -u -p -r1.78 ppc-opc.c
>>>>--- ppc-opc.c 20 Jan 2005 06:54:48 -0000      1.78
>>>>+++ ppc-opc.c 28 Feb 2005 18:02:08 -0000
>>>>@@ -84,6 +84,7 @@ static unsigned long insert_sh6 (unsigne
>>>>  static long extract_sh6 (unsigned long, int, int *);
>>>
>>>>  static unsigned long insert_spr (unsigned long, long, int, const 
>>>
>>>char
>>>
>>>>**);
>>>>  static long extract_spr (unsigned long, int, int *);
>>>
>>>>+static unsigned long insert_sprg (unsigned long, long, int, const 
>>>
>>>char
>>>
>>>>**);
>>>>  static unsigned long insert_tbr (unsigned long, long, int, const 
>>>
>>>char
>>>
>>>>**);
>>>>  static long extract_tbr (unsigned long, int, int *);
>>>
>>>>  static unsigned long insert_ev2 (unsigned long, long, int, const 
>>>
>>>char
>>>
>>>>**);
>>>>@@ -465,8 +466,8 @@ const struct powerpc_operand powerpc_ope
>>>>
>>>
>>>>    /* The SPRG register number in an XFX form m[ft]sprg
>>
>>instruction.
>>
>>
>>>>*/
>>>>  #define SPRG SPRBAT + 1
>>>>-#define SPRG_MASK (0x3 << 16)
>>>>-  { 2, 16, NULL, NULL, 0 },
>>>>+#define SPRG_MASK (0x7 << 16)
>>>>+  { 3, 16, insert_sprg, NULL, 0 },
>>>>
>>>
>>>>    /* The SR field in an X form instruction.  */
>>>
>>>>  #define SR SPRG + 1
>>>>@@ -1397,6 +1398,36 @@ extract_spr (unsigned long insn,
>>>>    return ((insn >> 16) & 0x1f) | ((insn >> 6) & 0x3e0);
>>>>  }
>>>>
>>>
>>>>+/* Some dialects (BookE, 405) have 8 SPRG registers instead of
>>>
>>>>+ the normal 4.  In addition, BookE mfsprg instructions must
>>>>+ have sprn5 cleared when using registers 4 through 7. */
>>>>+
>>>>+static unsigned long
>>>>+insert_sprg (unsigned long insn,
>>>>+         long value,
>>>>+         int dialect,
>>>>+         const char **errmsg)
>>>>+{
>>>>+  /* This check uses PPC_OPCODE_403 because PPC405 is later
>>
>>defined
>>
>>
>>>>+   as a synonym.  If ever a 405 specific dialect is added this
>>>>+   check should use that instead. */
>>>
>>>>+  if ((dialect & PPC_OPCODE_BOOKE) || (dialect & PPC_OPCODE_403))
>>>>+  {
>>>
>>>>+    if (value > 7)
>>>>+      *errmsg = _("Invalid operand.  Must be between 0 and 7.");
>>>>+    if ((value > 3) && (dialect & PPC_OPCODE_BOOKE))
>>>
>>>>+      return (insn | ((value & 0x07) << 16))
>>>
>>>>+           & (((insn >> 8) & 0x01) ? ~0 : ( ~( 1 << 20 )));
>>>>+    return insn | ((value & 0x07) << 16);
>>>>+  }
>>>>+  else
>>>>+  {
>>>>+    if (value > 3)
>>>>+         *errmsg = _("Invalid operand.  Must be between 0 and
>>
>>3.");
>>
>>
>>>>+    return insn | ((value & 0x03) << 16);
>>>>+  }
>>>>+}
>>>>+
>>>>  /* The TBR field in an XFX instruction.  This is just like SPR, 
>>>
>>>but it
>>>
>>>>     is optional.  When TBR is omitted, it must be inserted as 268 
>>>
>>>(the
>>>
>>>>     magic number of the TB register).  These functions treat 0
>>>>@@ -3677,13 +3708,9 @@ const struct powerpc_opcode powerpc_opco
>>>
>>>>  { "mfbar",      XSPR(31,339,159),  XSPR_MASK, PPC860,       { RT }
>>
>>
>>>},
>>>
>>>>  { "mfvrsave",   XSPR(31,339,256),  XSPR_MASK, PPCVEC,       { RT 
>>>
>>>} },
>>>
>>>>  { "mfusprg0",   XSPR(31,339,256),  XSPR_MASK, BOOKE,    { RT } },
>>>>-{ "mfsprg4",    XSPR(31,339,260),  XSPR_MASK, PPC405,        { RT 
>>>
>>>} },
>>>
>>>>  { "mfsprg4",    XSPR(31,339,260),  XSPR_MASK, BOOKE,        { RT 
>>>
>>>} },
>>>
>>>>-{ "mfsprg5",    XSPR(31,339,261),  XSPR_MASK, PPC405,        { RT 
>>>
>>>} },
>>>
>>>>  { "mfsprg5",    XSPR(31,339,261),  XSPR_MASK, BOOKE,        { RT 
>>>
>>>} },
>>>
>>>>-{ "mfsprg6",    XSPR(31,339,262),  XSPR_MASK, PPC405,        { RT 
>>>
>>>} },
>>>
>>>>  { "mfsprg6",    XSPR(31,339,262),  XSPR_MASK, BOOKE,        { RT 
>>>
>>>} },
>>>
>>>>-{ "mfsprg7",    XSPR(31,339,263),  XSPR_MASK, PPC405,        { RT 
>>>
>>>} },
>>>
>>>>  { "mfsprg7",    XSPR(31,339,263),  XSPR_MASK, BOOKE,        { RT 
>>>
>>>} },
>>>
>>>>  { "mftb",       X(31,371),     X_MASK,    CLASSIC,  { RT, TBR }
>>
>>},
>>
>>
>>>>  { "mftb",       XSPR(31,339,268),  XSPR_MASK, BOOKE,    { RT } },
>>>>@@ -3696,6 +3723,10 @@ const struct powerpc_opcode powerpc_opco
>>>
>>>>  { "mfsprg1",    XSPR(31,339,273),  XSPR_MASK, PPC,  { RT } },
>>>
>>>>  { "mfsprg2",    XSPR(31,339,274),  XSPR_MASK, PPC,  { RT } },
>>>>  { "mfsprg3",    XSPR(31,339,275),  XSPR_MASK, PPC,  { RT } },
>>>>+{ "mfsprg4",    XSPR(31,339,276),  XSPR_MASK, PPC405,        { RT 
>>>
>>>} },
>>>
>>>>+{ "mfsprg5",    XSPR(31,339,277),  XSPR_MASK, PPC405,        { RT 
>>>
>>>} },
>>>
>>>>+{ "mfsprg6",    XSPR(31,339,278),  XSPR_MASK, PPC405,        { RT 
>>>
>>>} },
>>>
>>>>+{ "mfsprg7",    XSPR(31,339,279),  XSPR_MASK, PPC405,        { RT 
>>>
>>>} },
>>>
>>>>  { "mfasr",      XSPR(31,339,280),  XSPR_MASK, PPC64,        { RT 
>>>
>>>} },
>>>
>>>>  { "mfear",      XSPR(31,339,282),  XSPR_MASK, PPC,  { RT } },
>>>>  { "mfpir",      XSPR(31,339,286),  XSPR_MASK, BOOKE,    { RT } },

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] Handle mtsprg and mfsprg properly for BookE
  2005-03-07 15:22       ` Jeff Baker
@ 2005-03-08 11:20         ` Alan Modra
  2005-03-08 16:30           ` Jeff Baker
  0 siblings, 1 reply; 19+ messages in thread
From: Alan Modra @ 2005-03-08 11:20 UTC (permalink / raw)
  To: Jeff Baker; +Cc: binutils

On Mon, Mar 07, 2005 at 10:23:57AM -0500, Jeff Baker wrote:
> Ping.  Updated for today and confirmed as the correct behaviour.

Correct for what processor?  My BOOKE reference says of SPRG:

	SPR number	Access		Privileged
SPRG0	272		Read/Write	Yes
SPRG1	273		Read/Write	Yes
SPRG2	274		Read/Write	Yes
SPRG3	259		Read-only	No
	275		Read/Write	Yes
SPRG4	260		Read-only	No
	276		Read/Write	Yes
SPRG5	261		Read-only	No
	277		Read/Write	Yes
SPRG6	262		Read-only	No
	278		Read/Write	Yes
SPRG7	263		Read-only	No
	279		Read/Write	Yes
USPRG0	256		Read/Write	No

That says to me that there are two possible SPR numbers you use to
access each of SPRG3 to SPRG7.  And the duplicate numbers start at
SPRG3, not SPRG4.  Now you know why nobody reviewed your patch, and
why I'm not approving it as is..

If I was a programmer with an ounce of sense (debatable), I'd want
to use "mfspr gpr,sprgN" where the sprgN are symbols or macros equated
to the right spr register for the context, rather than trusting the
assembler to do the right thing with "mfsprg gpr,N" or even worse,
"mfsprgN gpr".

> +/* Some dialects (BookE, 405) have 8 SPRG registers instead of
> + the normal 4.  In addition, mfsprg instructions must
> + have sprn5 cleared when using registers 4 through 7. */

Is this horrible formatting an artifact of your mailer?

> +static unsigned long
> +insert_sprg (unsigned long insn,
> +	    long value,
> +	    int dialect,
> +	    const char **errmsg)
> +{
> +  /* This check uses PPC_OPCODE_403 because PPC405 is later defined
> +   as a synonym.  If ever a 405 specific dialect is added this
> +   check should use that instead. */
> +  if ((dialect & PPC_OPCODE_BOOKE) || (dialect & PPC_OPCODE_403))
> +  {
> +    if (value > 7)
> +      *errmsg = _("Invalid operand.  Must be between 0 and 7.");

These error messages should be all lower case, and without a full-stop.
I suggest simply "invalid sprg number".  Then you can restructure the
function as

  if (value > 7
      || (value > 3
	  && (dialect & (PPC_OPCODE_BOOKE | PPC_OPCODE_403)) == 0))
    *errmsg = _("invalid sprg number");

  insn |= (value & 7) << 16;
  if (value > 3 or maybe 2 && some other condition)
    insn &= bit twiddle;
  return insn;

> + 1cc:	7c f3 42 a6	mfsprg  r7,3
> + 1d0:	7c e7 42 a6	mfsprg7 r7
> + 1d4:	7c f7 43 a6	mtsprg  7,r7

This isn't the nicest disassembly, a result of mfsprg[3-7] appearing in
the opcode table before mfsprg.

> +	mfsprg %r7, 3
> +	mfsprg %r7, 7
> +	mtsprg 7, %r7

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] Handle mtsprg and mfsprg properly for BookE
  2005-03-08 11:20         ` Alan Modra
@ 2005-03-08 16:30           ` Jeff Baker
  2005-03-08 23:51             ` Alan Modra
  0 siblings, 1 reply; 19+ messages in thread
From: Jeff Baker @ 2005-03-08 16:30 UTC (permalink / raw)
  To: Alan Modra; +Cc: binutils

> Correct for what processor?  My BOOKE reference says of SPRG:
> 
> 	SPR number	Access		Privileged
> SPRG0	272		Read/Write	Yes
> SPRG1	273		Read/Write	Yes
> SPRG2	274		Read/Write	Yes
> SPRG3	259		Read-only	No
> 	275		Read/Write	Yes
> SPRG4	260		Read-only	No
> 	276		Read/Write	Yes
> SPRG5	261		Read-only	No
> 	277		Read/Write	Yes
> SPRG6	262		Read-only	No
> 	278		Read/Write	Yes
> SPRG7	263		Read-only	No
> 	279		Read/Write	Yes
> USPRG0	256		Read/Write	No
> 
> That says to me that there are two possible SPR numbers you use to
> access each of SPRG3 to SPRG7.  And the duplicate numbers start at
> SPRG3, not SPRG4.  Now you know why nobody reviewed your patch, and
> why I'm not approving it as is..

My BookE reference states that user-mode read access to sprg3 is 
implementation dependant.  Since the opcode table doesn't have an 
mfsprg3 with an SPR number of 259 I (apparently incorrectly) assumed 
that we didn't need that.

I also assumed that one reason for submitting a patch to the mailing 
list is so that people who know more than I do can review it and then 
point out where I'm making mistakes.  If that isn't the case then can 
you suggest somewhere I can go or someone I can ask for help if I'm 
working on a patch that I need but don't 100% understand?

> If I was a programmer with an ounce of sense (debatable), I'd want
> to use "mfspr gpr,sprgN" where the sprgN are symbols or macros equated
> to the right spr register for the context, rather than trusting the
> assembler to do the right thing with "mfsprg gpr,N" or even worse,
> "mfsprgN gpr".

That may be true but I was asked to get it working.  I don't believe 
that technically it is correct for m[t,f]sprg to complain that the 
register is greater than 3 if you have specified an architecture that 
should allow up to 7.  Even if so, 'mfsprg %r7,3' will be accepted as 
correct but will produce an SPRG number of 275, not 259 as you 
previously indicated it should.  Same with 'mfsprg3 %r7'.

>>+/* Some dialects (BookE, 405) have 8 SPRG registers instead of
>>+ the normal 4.  In addition, mfsprg instructions must
>>+ have sprn5 cleared when using registers 4 through 7. */
> 
> 
> Is this horrible formatting an artifact of your mailer?

No my editor does that.  Easily fixed.

>>+static unsigned long
>>+insert_sprg (unsigned long insn,
>>+	    long value,
>>+	    int dialect,
>>+	    const char **errmsg)
>>+{
>>+  /* This check uses PPC_OPCODE_403 because PPC405 is later defined
>>+   as a synonym.  If ever a 405 specific dialect is added this
>>+   check should use that instead. */
>>+  if ((dialect & PPC_OPCODE_BOOKE) || (dialect & PPC_OPCODE_403))
>>+  {
>>+    if (value > 7)
>>+      *errmsg = _("Invalid operand.  Must be between 0 and 7.");
> 
> 
> These error messages should be all lower case, and without a full-stop.
> I suggest simply "invalid sprg number".  Then you can restructure the
> function as
> 
>   if (value > 7
>       || (value > 3
> 	  && (dialect & (PPC_OPCODE_BOOKE | PPC_OPCODE_403)) == 0))
>     *errmsg = _("invalid sprg number");
> 
>   insn |= (value & 7) << 16;
>   if (value > 3 or maybe 2 && some other condition)
>     insn &= bit twiddle;
>   return insn;

Easily done once I'm positive what the proper conditions should be.

>>+ 1cc:	7c f3 42 a6	mfsprg  r7,3
>>+ 1d0:	7c e7 42 a6	mfsprg7 r7
>>+ 1d4:	7c f7 43 a6	mtsprg  7,r7
> 
> 
> This isn't the nicest disassembly, a result of mfsprg[3-7] appearing in
> the opcode table before mfsprg.

I know.  I briefly thought about implementing an extract_sprg to handle 
that but there really isn't a good way to decide how to display it.

>>+	mfsprg %r7, 3
>>+	mfsprg %r7, 7
>>+	mtsprg 7, %r7
> 
> 

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] Handle mtsprg and mfsprg properly for BookE
  2005-03-08 16:30           ` Jeff Baker
@ 2005-03-08 23:51             ` Alan Modra
  2005-03-09  1:18               ` Jeff Baker
  0 siblings, 1 reply; 19+ messages in thread
From: Alan Modra @ 2005-03-08 23:51 UTC (permalink / raw)
  To: Jeff Baker; +Cc: binutils

On Tue, Mar 08, 2005 at 11:32:06AM -0500, Jeff Baker wrote:
> I also assumed that one reason for submitting a patch to the mailing 
> list is so that people who know more than I do can review it and then 
> point out where I'm making mistakes.

Well, you've now had some mistakes pointed out.  Don't expect me to
research the relevant architecture documents for you.  It's your job as
patch submitter to do this.  Instead I saw:

"Below is my attempt at a patch to add support for"

"Below is an updated (and I believe more correct) version of this
patch."

"The following patch may also be correct."

That doesn't exactly inspire confidence that you have done any research
to determine what should be done about mt/mfsprg.  So I went out of my
way to look at a BOOKE reference, and found the alternate register
numbering.  Your patch won't be applied until you give some
justification that the choices you've made regarding spr reg numbers are
correct or at least most useful.

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] Handle mtsprg and mfsprg properly for BookE
  2005-03-08 23:51             ` Alan Modra
@ 2005-03-09  1:18               ` Jeff Baker
  2005-03-09  2:11                 ` Alan Modra
  0 siblings, 1 reply; 19+ messages in thread
From: Jeff Baker @ 2005-03-09  1:18 UTC (permalink / raw)
  To: Alan Modra; +Cc: binutils

The BookE Specification itself states that reading sprg3 in user mode is 
implementation defined.  The current implementation of the assembler 
bears that out as it will not output a user mode mfsprg3 under any 
circumstances.

The specifications for the e500 (PPC_OPCODE_SPE) and MPC8560 (I'm not 
sure how to test for this specifically) state that sprg3 is readable in 
user mode.  For PowerPC 440 (PPC_OPCODE_440) and PowerPC 405 
(PPC_OPCODE_403) it is not.

Would it be correct to change the generic PPC_OPCODE_BOOKE case to 
always use user mode sprg2+ and then override it to be sprg3+ for 
PPC_OPCODE_403 and PPC_OPCODE_440?  Should there be a version of mtsprg3 
for e500 and MPC8560 that encodes 259 instead of 275?

The function of these registers is well defined for each processor but 
I'm at your mercy for how to implement it within gas in a manner that 
you find acceptable.

Alan Modra wrote:
> On Tue, Mar 08, 2005 at 11:32:06AM -0500, Jeff Baker wrote:
> 
>>I also assumed that one reason for submitting a patch to the mailing 
>>list is so that people who know more than I do can review it and then 
>>point out where I'm making mistakes.
> 
> 
> Well, you've now had some mistakes pointed out.  Don't expect me to
> research the relevant architecture documents for you.  It's your job as
> patch submitter to do this.  Instead I saw:
> 
> "Below is my attempt at a patch to add support for"
> 
> "Below is an updated (and I believe more correct) version of this
> patch."
> 
> "The following patch may also be correct."
> 
> That doesn't exactly inspire confidence that you have done any research
> to determine what should be done about mt/mfsprg.  So I went out of my
> way to look at a BOOKE reference, and found the alternate register
> numbering.  Your patch won't be applied until you give some
> justification that the choices you've made regarding spr reg numbers are
> correct or at least most useful.
> 

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] Handle mtsprg and mfsprg properly for BookE
  2005-03-09  1:18               ` Jeff Baker
@ 2005-03-09  2:11                 ` Alan Modra
  2005-03-09 16:39                   ` Jeff Baker
  2005-03-09 22:30                   ` Kumar Gala
  0 siblings, 2 replies; 19+ messages in thread
From: Alan Modra @ 2005-03-09  2:11 UTC (permalink / raw)
  To: Jeff Baker; +Cc: binutils

On Tue, Mar 08, 2005 at 08:20:21PM -0500, Jeff Baker wrote:
> Would it be correct to change the generic PPC_OPCODE_BOOKE case to 
> always use user mode sprg2+ and then override it to be sprg3+ for 
> PPC_OPCODE_403 and PPC_OPCODE_440?  Should there be a version of mtsprg3 
> for e500 and MPC8560 that encodes 259 instead of 275?

That's what _you_ need to research.  If you can decide on the correct
mapping of sprg number to spr number for a given processor, and defend
your mapping against potential criticism, I'm more than happy to help
correct an implementation.

Hmm, looking over your patch again, I suppose you could simply say that
your mapping of sprg number to spr number matches the existing gas
opcodes.  ie.  "mfsprg 0,4" generates the same as "mfsprg4 0" and so on.
Enumerate all the possibilities in an addition to the testsuite, and
you've made that obvious.  If you fix the formatting, correct the error
messages, and extend the testsuite this way I'll accept the patch.  I'll
also still be worried that gas isn't generating the right opcodes, but
I suppose that's another issue..

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] Handle mtsprg and mfsprg properly for BookE
  2005-03-09  2:11                 ` Alan Modra
@ 2005-03-09 16:39                   ` Jeff Baker
  2005-03-10 12:42                     ` Alan Modra
  2005-03-09 22:30                   ` Kumar Gala
  1 sibling, 1 reply; 19+ messages in thread
From: Jeff Baker @ 2005-03-09 16:39 UTC (permalink / raw)
  To: Alan Modra; +Cc: binutils

Here is the patch as you suggested.  Let me know if you consider the 
testsuite additions insufficient.


2005-03-09  Jeff Baker <jbaker@qnx.com>

	* ppc-opc.c (SPRG_MASK):  Allow 3 bits for register.
	(powerpc_operands): Likewise.
	(insert_sprg): New Function.

Index: ppc-opc.c
===================================================================
RCS file: /cvs/src/src/opcodes/ppc-opc.c,v
retrieving revision 1.78
diff -w -u -p -r1.78 ppc-opc.c
--- ppc-opc.c	20 Jan 2005 06:54:48 -0000	1.78
+++ ppc-opc.c	9 Mar 2005 16:23:09 -0000
@@ -84,6 +84,7 @@ static unsigned long insert_sh6 (unsigne
  static long extract_sh6 (unsigned long, int, int *);
  static unsigned long insert_spr (unsigned long, long, int, const char **);
  static long extract_spr (unsigned long, int, int *);
+static unsigned long insert_sprg (unsigned long, long, int, const char **);
  static unsigned long insert_tbr (unsigned long, long, int, const char **);
  static long extract_tbr (unsigned long, int, int *);
  static unsigned long insert_ev2 (unsigned long, long, int, const char **);
@@ -465,8 +466,8 @@ const struct powerpc_operand powerpc_ope

    /* The SPRG register number in an XFX form m[ft]sprg instruction.  */
  #define SPRG SPRBAT + 1
-#define SPRG_MASK (0x3 << 16)
-  { 2, 16, NULL, NULL, 0 },
+#define SPRG_MASK (0x7 << 16)
+  { 3, 16, insert_sprg, NULL, 0 },

    /* The SR field in an X form instruction.  */
  #define SR SPRG + 1
@@ -1397,6 +1398,30 @@ extract_spr (unsigned long insn,
    return ((insn >> 16) & 0x1f) | ((insn >> 6) & 0x3e0);
  }

+/* Some dialects have 8 SPRG registers instead of the standard 4.*/
+
+static unsigned long
+insert_sprg (unsigned long insn,
+	    long value,
+	    int dialect,
+	    const char **errmsg)
+{
+  /* This check uses PPC_OPCODE_403 because PPC405 is later defined
+     as a synonym.  If ever a 405 specific dialect is added this
+     check should use that instead. */
+  if (value > 7
+      || (value > 3
+	   && (dialect & (PPC_OPCODE_BOOKE | PPC_OPCODE_403)) == 0))
+    *errmsg = _("invalid sprg number");
+
+  insn |= (value & 7) << 16;
+  /* Clear the sprn5 bit if the sprgN in question should be read in
+     user mode. */
+  if (value > 3)
+    insn &= (insn >> 8) & 1 ? ~0 :  ~( 1 << 20 );
+  return insn;
+}
+
  /* The TBR field in an XFX instruction.  This is just like SPR, but it
     is optional.  When TBR is omitted, it must be inserted as 268 (the
     magic number of the TB register).  These functions treat 0


2005-03-09  Jeff Baker <jbaker@qnx.com>

   	* gas/ppc/booke.s: Add new m[t,f]sprg testcases.
	* gas/ppc/booke.d: Likewise.

Index: gas/ppc/booke.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/ppc/booke.d,v
retrieving revision 1.9
diff -w -u -p -r1.9 booke.d
--- gas/ppc/booke.d	2 Mar 2005 13:25:01 -0000	1.9
+++ gas/ppc/booke.d	9 Mar 2005 16:24:05 -0000
@@ -142,3 +142,11 @@ Disassembly of section \.text:
   1c0:	7c 00 06 ac 	mbar
   1c4:	7c 00 06 ac 	mbar
   1c8:	7c 20 06 ac 	mbar    1
+ 1cc:   7c 12 42 a6     mfsprg  r0,2
+ 1d0:   7c 12 42 a6     mfsprg  r0,2
+ 1d4:   7c 12 43 a6     mtsprg  2,r0
+ 1d8:   7c 12 43 a6     mtsprg  2,r0
+ 1dc:   7c 07 42 a6     mfsprg7 r0
+ 1e0:   7c 07 42 a6     mfsprg7 r0
+ 1e4:   7c 17 43 a6     mtsprg  7,r0
+ 1e8:   7c 17 43 a6     mtsprg  7,r0
Index: gas/ppc/booke.s
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/ppc/booke.s,v
retrieving revision 1.3
diff -w -u -p -r1.3 booke.s
--- gas/ppc/booke.s	10 Dec 2003 22:12:50 -0000	1.3
+++ gas/ppc/booke.s	9 Mar 2005 16:24:05 -0000
@@ -1,5 +1,5 @@
  # Motorola PowerPC BookE tests
-#as: -mbooke32
+#as: -mbooke64
  	.section ".text"
  start:
  	bce	1, 5, branch_target_1
@@ -134,3 +134,12 @@ branch_target_8:
  	mbar
  	mbar	0
  	mbar	1
+
+	mfsprg 0, 2
+	mfsprg2 0
+	mtsprg 2, 0
+	mtsprg2 0
+	mfsprg 0, 7
+	mfsprg7 0
+	mtsprg 7, 0
+	mtsprg7 0


Alan Modra wrote:
> On Tue, Mar 08, 2005 at 08:20:21PM -0500, Jeff Baker wrote:
> 
>>Would it be correct to change the generic PPC_OPCODE_BOOKE case to 
>>always use user mode sprg2+ and then override it to be sprg3+ for 
>>PPC_OPCODE_403 and PPC_OPCODE_440?  Should there be a version of
> 
> mtsprg3 
> 
>>for e500 and MPC8560 that encodes 259 instead of 275?
> 
> 
> That's what _you_ need to research.  If you can decide on the correct
> mapping of sprg number to spr number for a given processor, and defend
> your mapping against potential criticism, I'm more than happy to help
> correct an implementation.
> 
> Hmm, looking over your patch again, I suppose you could simply say that
> your mapping of sprg number to spr number matches the existing gas
> opcodes.  ie.  "mfsprg 0,4" generates the same as "mfsprg4 0" and so on.
> Enumerate all the possibilities in an addition to the testsuite, and
> you've made that obvious.  If you fix the formatting, correct the error
> messages, and extend the testsuite this way I'll accept the patch.  I'll
> also still be worried that gas isn't generating the right opcodes, but
> I suppose that's another issue..
> 

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] Handle mtsprg and mfsprg properly for BookE
  2005-03-09  2:11                 ` Alan Modra
  2005-03-09 16:39                   ` Jeff Baker
@ 2005-03-09 22:30                   ` Kumar Gala
  2005-03-10  3:58                     ` Alan Modra
  1 sibling, 1 reply; 19+ messages in thread
From: Kumar Gala @ 2005-03-09 22:30 UTC (permalink / raw)
  To: Alan Modra; +Cc: binutils, Jeff Baker


On Mar 8, 2005, at 8:11 PM, Alan Modra wrote:

> On Tue, Mar 08, 2005 at 08:20:21PM -0500, Jeff Baker wrote:
>  > Would it be correct to change the generic PPC_OPCODE_BOOKE case to
> > always use user mode sprg2+ and then override it to be sprg3+ for
> > PPC_OPCODE_403 and PPC_OPCODE_440?  Should there be a version of 
> mtsprg3
> > for e500 and MPC8560 that encodes 259 instead of 275?
>
> That's what _you_ need to research.  If you can decide on the correct
>  mapping of sprg number to spr number for a given processor, and defend
>  your mapping against potential criticism, I'm more than happy to help
>  correct an implementation.
>
> Hmm, looking over your patch again, I suppose you could simply say that
>  your mapping of sprg number to spr number matches the existing gas
>  opcodes.  ie.  "mfsprg 0,4" generates the same as "mfsprg4 0" and so 
> on.
>  Enumerate all the possibilities in an addition to the testsuite, and
>  you've made that obvious.  If you fix the formatting, correct the 
> error
>  messages, and extend the testsuite this way I'll accept the patch.  
> I'll
>  also still be worried that gas isn't generating the right opcodes, but
>  I suppose that's another issue..

I'm confused what the correctness concern is.  The only subject that is 
up in the air is if SPRG3 (SPR #259) should allow read access on some 
book-e implementations.  It would seem allowing this is more broad and 
leaves the decision up to the user.

- kumar

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] Handle mtsprg and mfsprg properly for BookE
  2005-03-09 22:30                   ` Kumar Gala
@ 2005-03-10  3:58                     ` Alan Modra
       [not found]                       ` <ad80a57d7a545e4541f6fbaa2178ad4c@leftfield.org>
  0 siblings, 1 reply; 19+ messages in thread
From: Alan Modra @ 2005-03-10  3:58 UTC (permalink / raw)
  To: Kumar Gala; +Cc: binutils, Jeff Baker

On Wed, Mar 09, 2005 at 04:30:03PM -0600, Kumar Gala wrote:
> On Mar 8, 2005, at 8:11 PM, Alan Modra wrote:
> > also still be worried that gas isn't generating the right opcodes, but
> > I suppose that's another issue..
> 
> I'm confused what the correctness concern is.  The only subject that is 
> up in the air is if SPRG3 (SPR #259) should allow read access on some 
> book-e implementations.  It would seem allowing this is more broad and 
> leaves the decision up to the user.

My concern is that my booke manual says there are two spr numbers that
can be used to access sprg4 through sprg7.  One of these values can be
used for privileged write and read access, the other gives read access
to non-privileged programs.  Whether sprg3 is accessible to
non-privileged programs is implementation dependent, but if it is, it
too uses a second spr number to provide non-privileged access.  Let's
leave sprg3 out of the discussion for now..

There remains the question of which spr number should be used by
privileged programs for read access to sprg4 through sprg7.  Does the
non-privileged spr number work when privileged?  I would think it
probably does, but I'm just guessing..

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] Handle mtsprg and mfsprg properly for BookE
  2005-03-09 16:39                   ` Jeff Baker
@ 2005-03-10 12:42                     ` Alan Modra
  0 siblings, 0 replies; 19+ messages in thread
From: Alan Modra @ 2005-03-10 12:42 UTC (permalink / raw)
  To: Jeff Baker; +Cc: binutils

On Wed, Mar 09, 2005 at 11:41:01AM -0500, Jeff Baker wrote:
> Here is the patch as you suggested.

Which didn't apply due to being mangled by your editor.  I've extracted
it by hand, and extended it a little.  I'll apply this to mainline and,
if no problems surface, to the branch in a few days.

opcodes/
	* ppc-opc.c (insert_sprg, extract_sprg): New Functions.
	(powerpc_operands <SPRG>): Call the above.  Bit field is 5 bits.
	(SPRG_MASK): Delete.
	(XSPRG_MASK): Mask off extra bits now part of sprg field.
        (powerpc_opcodes): Asjust mfsprg and mtsprg to suit new mask.  Move
	mfsprg4..7 after msprg and consolidate.

gas/testsuite
	* gas/ppc/booke.s: Add new m[t,f]sprg testcases.
	* gas/ppc/booke.d: Likewise.

Index: opcodes/ppc-opc.c
===================================================================
RCS file: /cvs/src/src/opcodes/ppc-opc.c,v
retrieving revision 1.79
diff -u -p -r1.79 ppc-opc.c
--- opcodes/ppc-opc.c	7 Mar 2005 20:05:44 -0000	1.79
+++ opcodes/ppc-opc.c	10 Mar 2005 12:32:48 -0000
@@ -84,6 +84,8 @@ static unsigned long insert_sh6 (unsigne
 static long extract_sh6 (unsigned long, int, int *);
 static unsigned long insert_spr (unsigned long, long, int, const char **);
 static long extract_spr (unsigned long, int, int *);
+static unsigned long insert_sprg (unsigned long, long, int, const char **);
+static long extract_sprg (unsigned long, int, int *);
 static unsigned long insert_tbr (unsigned long, long, int, const char **);
 static long extract_tbr (unsigned long, int, int *);
 static unsigned long insert_ev2 (unsigned long, long, int, const char **);
@@ -465,8 +467,7 @@ const struct powerpc_operand powerpc_ope
 
   /* The SPRG register number in an XFX form m[ft]sprg instruction.  */
 #define SPRG SPRBAT + 1
-#define SPRG_MASK (0x3 << 16)
-  { 2, 16, NULL, NULL, 0 },
+  { 5, 16, insert_sprg, extract_sprg, 0 },
 
   /* The SR field in an X form instruction.  */
 #define SR SPRG + 1
@@ -1397,6 +1398,47 @@ extract_spr (unsigned long insn,
   return ((insn >> 16) & 0x1f) | ((insn >> 6) & 0x3e0);
 }
 
+/* Some dialects have 8 SPRG registers instead of the standard 4.  */
+
+static unsigned long
+insert_sprg (unsigned long insn,
+	     long value,
+	     int dialect,
+	     const char **errmsg)
+{
+  /* This check uses PPC_OPCODE_403 because PPC405 is later defined
+     as a synonym.  If ever a 405 specific dialect is added this
+     check should use that instead.  */
+  if (value > 7
+      || (value > 3
+	  && (dialect & (PPC_OPCODE_BOOKE | PPC_OPCODE_403)) == 0))
+    *errmsg = _("invalid sprg number");
+
+  /* If this is mfsprg4..7 then use spr 260..263 which can be read in
+     user mode.  Anything else must use spr 272..279.  */
+  if (value <= 3 || (insn & 0x100) != 0)
+    value |= 0x10;
+
+  return insn | ((value & 0x17) << 16);
+}
+
+static long
+extract_sprg (unsigned long insn,
+	      int dialect,
+	      int *invalid)
+{
+  unsigned long val = (insn >> 16) & 0x1f;
+
+  /* mfsprg can use 260..263 and 272..279.  mtsprg only uses spr 272..279
+     If not BOOKE or 405, then both use only 272..275.  */
+  if (val <= 3
+      || (val < 0x10 && (insn & 0x100) != 0)
+      || (val - 0x10 > 3
+	  && (dialect & (PPC_OPCODE_BOOKE | PPC_OPCODE_403)) == 0))
+    *invalid = 1;
+  return val & 7;
+}
+
 /* The TBR field in an XFX instruction.  This is just like SPR, but it
    is optional.  When TBR is omitted, it must be inserted as 268 (the
    magic number of the TB register).  These functions treat 0
@@ -1705,7 +1747,7 @@ extract_tbr (unsigned long insn,
 
 /* An XFX form instruction with the SPR field filled in except for the
    SPRG field.  */
-#define XSPRG_MASK (XSPR_MASK &~ SPRG_MASK)
+#define XSPRG_MASK (XSPR_MASK & ~(0x17 << 16))
 
 /* An X form instruction with everything filled in except the E field.  */
 #define XE_MASK (0xffff7fff)
@@ -3677,25 +3719,21 @@ const struct powerpc_opcode powerpc_opco
 { "mfbar",      XSPR(31,339,159),  XSPR_MASK, PPC860,	{ RT } },
 { "mfvrsave",   XSPR(31,339,256),  XSPR_MASK, PPCVEC,	{ RT } },
 { "mfusprg0",   XSPR(31,339,256),  XSPR_MASK, BOOKE,    { RT } },
-{ "mfsprg4",    XSPR(31,339,260),  XSPR_MASK, PPC405,	{ RT } },
-{ "mfsprg4",    XSPR(31,339,260),  XSPR_MASK, BOOKE,	{ RT } },
-{ "mfsprg5",    XSPR(31,339,261),  XSPR_MASK, PPC405,	{ RT } },
-{ "mfsprg5",    XSPR(31,339,261),  XSPR_MASK, BOOKE,	{ RT } },
-{ "mfsprg6",    XSPR(31,339,262),  XSPR_MASK, PPC405,	{ RT } },
-{ "mfsprg6",    XSPR(31,339,262),  XSPR_MASK, BOOKE,	{ RT } },
-{ "mfsprg7",    XSPR(31,339,263),  XSPR_MASK, PPC405,	{ RT } },
-{ "mfsprg7",    XSPR(31,339,263),  XSPR_MASK, BOOKE,	{ RT } },
 { "mftb",       X(31,371),	   X_MASK,    CLASSIC,	{ RT, TBR } },
 { "mftb",       XSPR(31,339,268),  XSPR_MASK, BOOKE,    { RT } },
 { "mftbl",      XSPR(31,371,268),  XSPR_MASK, CLASSIC,	{ 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 } },
+{ "mfsprg",     XSPR(31,339,256),  XSPRG_MASK, PPC,	{ RT, SPRG } },
 { "mfsprg0",    XSPR(31,339,272),  XSPR_MASK, PPC,	{ RT } },
 { "mfsprg1",    XSPR(31,339,273),  XSPR_MASK, PPC,	{ RT } },
 { "mfsprg2",    XSPR(31,339,274),  XSPR_MASK, PPC,	{ RT } },
 { "mfsprg3",    XSPR(31,339,275),  XSPR_MASK, PPC,	{ RT } },
+{ "mfsprg4",    XSPR(31,339,260),  XSPR_MASK, PPC405 | BOOKE,	{ RT } },
+{ "mfsprg5",    XSPR(31,339,261),  XSPR_MASK, PPC405 | BOOKE,	{ RT } },
+{ "mfsprg6",    XSPR(31,339,262),  XSPR_MASK, PPC405 | BOOKE,	{ RT } },
+{ "mfsprg7",    XSPR(31,339,263),  XSPR_MASK, PPC405 | BOOKE,	{ RT } },
 { "mfasr",      XSPR(31,339,280),  XSPR_MASK, PPC64,	{ RT } },
 { "mfear",      XSPR(31,339,282),  XSPR_MASK, PPC,	{ RT } },
 { "mfpir",      XSPR(31,339,286),  XSPR_MASK, BOOKE,    { RT } },
@@ -3998,7 +4036,7 @@ const struct powerpc_opcode powerpc_opco
 { "mtbar",     XSPR(31,467,159),  XSPR_MASK, PPC860,	{ RS } },
 { "mtvrsave",  XSPR(31,467,256),  XSPR_MASK, PPCVEC,	{ RS } },
 { "mtusprg0",  XSPR(31,467,256),  XSPR_MASK, BOOKE,     { RS } },
-{ "mtsprg",    XSPR(31,467,272),  XSPRG_MASK,PPC,	{ SPRG, RS } },
+{ "mtsprg",    XSPR(31,467,256),  XSPRG_MASK,PPC,	{ SPRG, RS } },
 { "mtsprg0",   XSPR(31,467,272),  XSPR_MASK, PPC,	{ RS } },
 { "mtsprg1",   XSPR(31,467,273),  XSPR_MASK, PPC,	{ RS } },
 { "mtsprg2",   XSPR(31,467,274),  XSPR_MASK, PPC,	{ RS } },
Index: gas/testsuite/gas/ppc/booke.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/ppc/booke.d,v
retrieving revision 1.9
diff -u -p -r1.9 booke.d
--- gas/testsuite/gas/ppc/booke.d	2 Mar 2005 13:25:01 -0000	1.9
+++ gas/testsuite/gas/ppc/booke.d	10 Mar 2005 11:33:56 -0000
@@ -142,3 +142,11 @@ Disassembly of section \.text:
  1c0:	7c 00 06 ac 	mbar    
  1c4:	7c 00 06 ac 	mbar    
  1c8:	7c 20 06 ac 	mbar    1
+ 1cc:	7c 12 42 a6 	mfsprg  r0,2
+ 1d0:	7c 12 42 a6 	mfsprg  r0,2
+ 1d4:	7c 12 43 a6 	mtsprg  2,r0
+ 1d8:	7c 12 43 a6 	mtsprg  2,r0
+ 1dc:	7c 07 42 a6 	mfsprg  r0,7
+ 1e0:	7c 07 42 a6 	mfsprg  r0,7
+ 1e4:	7c 17 43 a6 	mtsprg  7,r0
+ 1e8:	7c 17 43 a6 	mtsprg  7,r0
Index: gas/testsuite/gas/ppc/booke.s
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/ppc/booke.s,v
retrieving revision 1.3
diff -u -p -r1.3 booke.s
--- gas/testsuite/gas/ppc/booke.s	10 Dec 2003 22:12:50 -0000	1.3
+++ gas/testsuite/gas/ppc/booke.s	10 Mar 2005 11:33:56 -0000
@@ -134,3 +134,12 @@ branch_target_8:
 	mbar
 	mbar	0
 	mbar	1
+
+	mfsprg 0, 2
+	mfsprg2 0
+	mtsprg 2, 0
+	mtsprg2 0
+	mfsprg 0, 7
+	mfsprg7 0
+	mtsprg 7, 0
+	mtsprg7 0


-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] Handle mtsprg and mfsprg properly for BookE
       [not found]                       ` <ad80a57d7a545e4541f6fbaa2178ad4c@leftfield.org>
@ 2005-03-14  4:14                         ` Alan Modra
  2005-03-16 16:39                           ` Jeff Baker
  0 siblings, 1 reply; 19+ messages in thread
From: Alan Modra @ 2005-03-14  4:14 UTC (permalink / raw)
  To: binutils; +Cc: Alex Rosenberg, Jeff Baker, Kumar Gala

On Sun, Mar 13, 2005 at 03:34:33PM -0800, Alex Rosenberg wrote:
> On Mar 9, 2005, at 7:58 PM, Alan Modra wrote:
> >There remains the question of which spr number should be used by
> >privileged programs for read access to sprg4 through sprg7.  Does the
> >non-privileged spr number work when privileged?  I would think it
> >probably does, but I'm just guessing..
>
> I think the documentation is the problem here.
>
> Originally, the user mode read-only SPRG were supposed to be referred
> to as USPRG.

Makes sense.  Consistent with the spr numbering for USPRG0 too.

I propose that gas adopt this syntax.  ie.

mtsprg and mtsprg[0-7] writes spr272..279 (as we currently do)
mfsprg and mfsprg[0-7] read the same regs as mtsprg
mfusprg0 reads spr256 (as we currently do)
Add new mfusprg[3-7] insns which read spr259..263
Add a new mfusprg insn which reads spr256..263

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] Handle mtsprg and mfsprg properly for BookE
  2005-03-14  4:14                         ` Alan Modra
@ 2005-03-16 16:39                           ` Jeff Baker
  2005-03-17 15:36                             ` Alan Modra
  0 siblings, 1 reply; 19+ messages in thread
From: Jeff Baker @ 2005-03-16 16:39 UTC (permalink / raw)
  To: Alan Modra; +Cc: binutils, Alex Rosenberg, Kumar Gala

The IBM PPC440 doesn't support reading from the supervisory SPR's (you 
get garbage values back) - the mfsprg's won't be too useful. E.g.:

	running the following code (MSR.PR=0) (PVR=0x41020481):

		li		%r7,-1
		li		%r8,-1
		li		%r6,1
		mtspr	276,%r6
		mfspr	%r7,260
		mfspr	%r8,276

	leaves R7 with a 1 and R8 with a 0.

This is correct behaviour according to IBM.

Alan Modra wrote:
> On Sun, Mar 13, 2005 at 03:34:33PM -0800, Alex Rosenberg wrote:
> 
>>On Mar 9, 2005, at 7:58 PM, Alan Modra wrote:
>>
>>>There remains the question of which spr number should be used by
>>>privileged programs for read access to sprg4 through sprg7.  Does the
>>>non-privileged spr number work when privileged?  I would think it
>>>probably does, but I'm just guessing..
>>
>>I think the documentation is the problem here.
>>
>>Originally, the user mode read-only SPRG were supposed to be referred
>>to as USPRG.
> 
> 
> Makes sense.  Consistent with the spr numbering for USPRG0 too.
> 
> I propose that gas adopt this syntax.  ie.
> 
> mtsprg and mtsprg[0-7] writes spr272..279 (as we currently do)
> mfsprg and mfsprg[0-7] read the same regs as mtsprg
> mfusprg0 reads spr256 (as we currently do)
> Add new mfusprg[3-7] insns which read spr259..263
> Add a new mfusprg insn which reads spr256..263
> 

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] Handle mtsprg and mfsprg properly for BookE
  2005-03-16 16:39                           ` Jeff Baker
@ 2005-03-17 15:36                             ` Alan Modra
  0 siblings, 0 replies; 19+ messages in thread
From: Alan Modra @ 2005-03-17 15:36 UTC (permalink / raw)
  To: Jeff Baker; +Cc: binutils, Alex Rosenberg, Kumar Gala

On Wed, Mar 16, 2005 at 10:29:20AM -0500, Jeff Baker wrote:
> The IBM PPC440 doesn't support reading from the supervisory SPR's (you 
> get garbage values back) - the mfsprg's won't be too useful. E.g.:
> 
> 	running the following code (MSR.PR=0) (PVR=0x41020481):
> 
> 		li		%r7,-1
> 		li		%r8,-1
> 		li		%r6,1
> 		mtspr	276,%r6
> 		mfspr	%r7,260
> 		mfspr	%r8,276
> 
> 	leaves R7 with a 1 and R8 with a 0.

That's good enough for me.  We'll leave things as they are.

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH] Handle mtsprg and mfsprg properly for BookE
@ 2005-02-24  0:32 Jeff Baker
  0 siblings, 0 replies; 19+ messages in thread
From: Jeff Baker @ 2005-02-24  0:32 UTC (permalink / raw)
  To: binutils

Below is my attempt at a patch to add support for SPRG registers 4->7 on 
BookE processors.  I'm no PowerPC expert so I'm more than open to 
comments/corrections.

During the testing of this patch I noticed that the assembler always 
produces objects with architecture:common.  Is this expected behaviour?


2005-02-23  Jeff Baker  <jbaker@qnx.com>

	* ppc-opc.c (SPRG_MASK):  Allow 3 bits for register.
	(powerpc_operands): Likewise.
	(insert_sprg): New Function.
	(extract_sprg): New Function.
	(powerpc_opcodes): reorder mtsprg/mfsprg opcodes
	to allow disassembler to locate the correct one.
	

Index: ppc-opc.c
===================================================================
RCS file: /cvs/src/src/opcodes/ppc-opc.c,v
retrieving revision 1.78
diff -w -u -p -r1.78 ppc-opc.c
--- ppc-opc.c	20 Jan 2005 06:54:48 -0000	1.78
+++ ppc-opc.c	23 Feb 2005 17:26:12 -0000
@@ -84,6 +84,8 @@ static unsigned long insert_sh6 (unsigne
  static long extract_sh6 (unsigned long, int, int *);
  static unsigned long insert_spr (unsigned long, long, int, const char **);
  static long extract_spr (unsigned long, int, int *);
+static unsigned long insert_sprg (unsigned long, long, int, const char **);
+static long extract_sprg (unsigned long, int, int *);
  static unsigned long insert_tbr (unsigned long, long, int, const char **);
  static long extract_tbr (unsigned long, int, int *);
  static unsigned long insert_ev2 (unsigned long, long, int, const char **);
@@ -465,8 +467,8 @@ const struct powerpc_operand powerpc_ope

    /* The SPRG register number in an XFX form m[ft]sprg instruction.  */
  #define SPRG SPRBAT + 1
-#define SPRG_MASK (0x3 << 16)
-  { 2, 16, NULL, NULL, 0 },
+#define SPRG_MASK (0x7 << 16)
+  { 3, 16, insert_sprg, extract_sprg, 0 },

    /* The SR field in an X form instruction.  */
  #define SR SPRG + 1
@@ -1397,6 +1399,31 @@ extract_spr (unsigned long insn,
    return ((insn >> 16) & 0x1f) | ((insn >> 6) & 0x3e0);
  }

+/* Some PPC variants (BookE) have more than 4 SPRG registers. */
+
+static unsigned long
+insert_sprg (unsigned long insn,
+	    long value,
+	    int dialect,
+	    const char **errmsg)
+{
+  if (!(dialect & PPC_OPCODE_BOOKE) && (value > 0x03))
+    *errmsg = _("invalid register number.  Must be between 0 and 3.");
+  else if (value > 0x07)
+    *errmsg = _("invalid register number.  Must be between 0 and 7.");
+  return insn | ((value & 0x07) << 16);
+}
+
+static long
+extract_sprg (unsigned long insn,
+	     int dialect,
+	     int *invalid)
+{
+  if (!(dialect & PPC_OPCODE_BOOKE) &&(((insn >> 16) & 0x07) > 0x03))
+	  *invalid=1;
+  return ((insn >> 16) & 0x07);
+}
+
  /* The TBR field in an XFX instruction.  This is just like SPR, but it
     is optional.  When TBR is omitted, it must be inserted as 268 (the
     magic number of the TB register).  These functions treat 0
@@ -3677,14 +3704,6 @@ const struct powerpc_opcode powerpc_opco
  { "mfbar",      XSPR(31,339,159),  XSPR_MASK, PPC860,	{ RT } },
  { "mfvrsave",   XSPR(31,339,256),  XSPR_MASK, PPCVEC,	{ RT } },
  { "mfusprg0",   XSPR(31,339,256),  XSPR_MASK, BOOKE,    { RT } },
-{ "mfsprg4",    XSPR(31,339,260),  XSPR_MASK, PPC405,	{ RT } },
-{ "mfsprg4",    XSPR(31,339,260),  XSPR_MASK, BOOKE,	{ RT } },
-{ "mfsprg5",    XSPR(31,339,261),  XSPR_MASK, PPC405,	{ RT } },
-{ "mfsprg5",    XSPR(31,339,261),  XSPR_MASK, BOOKE,	{ RT } },
-{ "mfsprg6",    XSPR(31,339,262),  XSPR_MASK, PPC405,	{ RT } },
-{ "mfsprg6",    XSPR(31,339,262),  XSPR_MASK, BOOKE,	{ RT } },
-{ "mfsprg7",    XSPR(31,339,263),  XSPR_MASK, PPC405,	{ RT } },
-{ "mfsprg7",    XSPR(31,339,263),  XSPR_MASK, BOOKE,	{ RT } },
  { "mftb",       X(31,371),	   X_MASK,    CLASSIC,	{ RT, TBR } },
  { "mftb",       XSPR(31,339,268),  XSPR_MASK, BOOKE,    { RT } },
  { "mftbl",      XSPR(31,371,268),  XSPR_MASK, CLASSIC,	{ RT } },
@@ -3696,6 +3715,10 @@ const struct powerpc_opcode powerpc_opco
  { "mfsprg1",    XSPR(31,339,273),  XSPR_MASK, PPC,	{ RT } },
  { "mfsprg2",    XSPR(31,339,274),  XSPR_MASK, PPC,	{ RT } },
  { "mfsprg3",    XSPR(31,339,275),  XSPR_MASK, PPC,	{ RT } },
+{ "mfsprg4",    XSPR(31,339,276),  XSPR_MASK, PPC405 | BOOKE, { RT } },
+{ "mfsprg5",    XSPR(31,339,277),  XSPR_MASK, PPC405 | BOOKE, { RT } },
+{ "mfsprg6",    XSPR(31,339,278),  XSPR_MASK, PPC405 | BOOKE, { RT } },
+{ "mfsprg7",    XSPR(31,339,279),  XSPR_MASK, PPC405 | BOOKE, { RT } },
  { "mfasr",      XSPR(31,339,280),  XSPR_MASK, PPC64,	{ RT } },
  { "mfear",      XSPR(31,339,282),  XSPR_MASK, PPC,	{ RT } },
  { "mfpir",      XSPR(31,339,286),  XSPR_MASK, BOOKE,    { RT } },

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2005-03-17 11:09 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-02-28 20:20 [PATCH] Handle mtsprg and mfsprg properly for BookE Jeff Baker
2005-02-28 21:11 ` Jeff Baker
2005-02-28 21:26   ` Kumar Gala
2005-02-28 22:52     ` Jeff Baker
2005-02-28 23:09     ` Jeff Baker
2005-03-07 15:22       ` Jeff Baker
2005-03-08 11:20         ` Alan Modra
2005-03-08 16:30           ` Jeff Baker
2005-03-08 23:51             ` Alan Modra
2005-03-09  1:18               ` Jeff Baker
2005-03-09  2:11                 ` Alan Modra
2005-03-09 16:39                   ` Jeff Baker
2005-03-10 12:42                     ` Alan Modra
2005-03-09 22:30                   ` Kumar Gala
2005-03-10  3:58                     ` Alan Modra
     [not found]                       ` <ad80a57d7a545e4541f6fbaa2178ad4c@leftfield.org>
2005-03-14  4:14                         ` Alan Modra
2005-03-16 16:39                           ` Jeff Baker
2005-03-17 15:36                             ` Alan Modra
  -- strict thread matches above, loose matches on Subject: below --
2005-02-24  0:32 Jeff Baker

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).