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