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
* [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).