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


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

Re: [PATCH] Handle mtsprg and mfsprg properly for BookE


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 } },


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