* Disallow 3-operand cmp[l][i] for ppc64
@ 2016-09-29 6:02 Alan Modra
2016-09-29 20:34 ` Peter Bergner
0 siblings, 1 reply; 3+ messages in thread
From: Alan Modra @ 2016-09-29 6:02 UTC (permalink / raw)
To: binutils
cmp[l][o] get an optional L field only when generating 32-bit code.
dcbf, tlbie and tlbiel keep their optional L field, ditto for R field
of tbegin. cmprb, tsr., wlcr[all] and mtsle all change to a
compulsory L field.
L field of dcbf and wclr is 2 bits.
PR 20641
include/
* opcode/ppc.h (PPC_OPERAND_OPTIONAL32): Define.
opcodes/
* ppc-opc.c (L): Make compulsory.
(LOPT): New, optional form of L.
(HTM_R): Define as LOPT.
(L0, L1): Delete.
(L32OPT): New, optional for 32-bit L.
(L2OPT): New, 2-bit L for dcbf.
(SVC_LEC): Update.
(L2): Define.
(insert_l0, extract_l0, insert_l1, extract_l2): Delete.
(powerpc_opcodes <cmpli, cmpi, cmpl, cmp>): Use L32OPT.
<dcbf>: Use L2OPT.
<tlbiel, tlbie>: Use LOPT.
<wclr, wclrall>: Use L2.
gas/
* config/tc-ppc.c (md_assemble): Handle PPC_OPERAND_OPTIONAL32.
* testsuite/gas/ppc/power8.s: Provide tbegin. operand.
* testsuite/gas/ppc/power9.d: Update cmprb disassembly.
diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c
index d2b5316..5c7b09f 100644
--- a/gas/config/tc-ppc.c
+++ b/gas/config/tc-ppc.c
@@ -2695,7 +2695,8 @@ md_assemble (char *str)
const struct powerpc_operand *operand;
operand = &powerpc_operands[*opindex_ptr];
- if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0)
+ if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0
+ && !((operand->flags & PPC_OPERAND_OPTIONAL32) != 0 && ppc_obj64))
{
unsigned int opcount;
unsigned int num_operands_expected;
@@ -2765,6 +2766,7 @@ md_assemble (char *str)
/* If this is an optional operand, and we are skipping it, just
insert a zero. */
if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0
+ && !((operand->flags & PPC_OPERAND_OPTIONAL32) != 0 && ppc_obj64)
&& skip_optional)
{
long val = ppc_optional_operand_value (operand);
diff --git a/gas/testsuite/gas/ppc/power8.s b/gas/testsuite/gas/ppc/power8.s
index 728caae..857bda2 100644
--- a/gas/testsuite/gas/ppc/power8.s
+++ b/gas/testsuite/gas/ppc/power8.s
@@ -5,7 +5,7 @@ power8:
tabortdc. 20,11,10
tabortwci. 17,10,-13
tabortdci. 29,3,-5
- tbegin.
+ tbegin. 0
tcheck 7
tend. 0
tend.
diff --git a/gas/testsuite/gas/ppc/power9.d b/gas/testsuite/gas/ppc/power9.d
index 31e4530..6f2f53a 100644
--- a/gas/testsuite/gas/ppc/power9.d
+++ b/gas/testsuite/gas/ppc/power9.d
@@ -274,8 +274,8 @@ Disassembly of section \.text:
.*: (f3 89 ef 6f|6f ef 89 f3) xvxsigsp vs60,vs61
.*: (7c 06 39 c0|c0 39 06 7c) cmpeqb cr0,r6,r7
.*: (7f 86 39 c0|c0 39 86 7f) cmpeqb cr7,r6,r7
-.*: (7c 08 49 80|80 49 08 7c) cmprb cr0,r8,r9
-.*: (7f 88 49 80|80 49 88 7f) cmprb cr7,r8,r9
+.*: (7c 08 49 80|80 49 08 7c) cmprb cr0,0,r8,r9
+.*: (7f 88 49 80|80 49 88 7f) cmprb cr7,0,r8,r9
.*: (7c 28 49 80|80 49 28 7c) cmprb cr0,1,r8,r9
.*: (7f a8 49 80|80 49 a8 7f) cmprb cr7,1,r8,r9
.*: (7d e0 01 00|00 01 e0 7d) setb r15,cr0
diff --git a/include/opcode/ppc.h b/include/opcode/ppc.h
index d9f973d..66d2ceb 100644
--- a/include/opcode/ppc.h
+++ b/include/opcode/ppc.h
@@ -407,6 +407,10 @@ extern const unsigned int num_powerpc_operands;
is omitted, then the value it should use for the operand is stored
in the SHIFT field of the immediatly following operand field. */
#define PPC_OPERAND_OPTIONAL_VALUE (0x400000)
+
+/* This flag is only used with PPC_OPERAND_OPTIONAL. The operand is
+ only optional when generating 32-bit code. */
+#define PPC_OPERAND_OPTIONAL32 (0x800000)
\f
/* The POWER and PowerPC assemblers use a few macros. We keep them
with the operands table for simplicity. The macro table is an
diff --git a/opcodes/ppc-opc.c b/opcodes/ppc-opc.c
index 1c6e970..8c59033 100644
--- a/opcodes/ppc-opc.c
+++ b/opcodes/ppc-opc.c
@@ -62,10 +62,6 @@ static unsigned long insert_dxdn (unsigned long, long, ppc_cpu_t, const char **)
static long extract_dxdn (unsigned long, ppc_cpu_t, int *);
static unsigned long insert_fxm (unsigned long, long, ppc_cpu_t, const char **);
static long extract_fxm (unsigned long, ppc_cpu_t, int *);
-static unsigned long insert_l0 (unsigned long, long, ppc_cpu_t, const char **);
-static long extract_l0 (unsigned long, ppc_cpu_t, int *);
-static unsigned long insert_l1 (unsigned long, long, ppc_cpu_t, const char **);
-static long extract_l1 (unsigned long, ppc_cpu_t, int *);
static unsigned long insert_li20 (unsigned long, long, ppc_cpu_t, const char **);
static long extract_li20 (unsigned long, ppc_cpu_t, int *);
static unsigned long insert_ls (unsigned long, long, ppc_cpu_t, const char **);
@@ -429,20 +425,24 @@ const struct powerpc_operand powerpc_operands[] =
/* The L field in a D or X form instruction. */
#define L IMM20 + 1
+ { 0x1, 21, NULL, NULL, 0 },
+
+ /* The optional L field in tlbie and tlbiel instructions. */
+#define LOPT L + 1
/* The R field in a HTM X form instruction. */
-#define HTM_R L
+#define HTM_R LOPT
{ 0x1, 21, NULL, NULL, PPC_OPERAND_OPTIONAL },
- /* The L field in an X form instruction which must be zero. */
-#define L0 L + 1
- { 0x1, 21, insert_l0, extract_l0, PPC_OPERAND_OPTIONAL },
+ /* The optional (for 32-bit) L field in cmp[l][i] instructions. */
+#define L32OPT LOPT + 1
+ { 0x1, 21, NULL, NULL, PPC_OPERAND_OPTIONAL | PPC_OPERAND_OPTIONAL32 },
- /* The L field in an X form instruction which must be one. */
-#define L1 L0 + 1
- { 0x1, 21, insert_l1, extract_l1, 0 },
+ /* The L field in dcbf instruction. */
+#define L2OPT L32OPT + 1
+ { 0x3, 21, NULL, NULL, PPC_OPERAND_OPTIONAL },
/* The LEV field in a POWER SVC form instruction. */
-#define SVC_LEV L1 + 1
+#define SVC_LEV L2OPT + 1
{ 0x7f, 5, NULL, NULL, 0 },
/* The LEV field in an SC form instruction. */
@@ -688,6 +688,8 @@ const struct powerpc_operand powerpc_operands[] =
#define STRM SR + 1
/* The T field in a tlbilx form instruction. */
#define T STRM
+ /* The L field in wclr instructions. */
+#define L2 STRM
{ 0x3, 21, NULL, NULL, 0 },
/* The ESYNC field in an X (sync) form instruction. */
@@ -1483,58 +1485,6 @@ extract_fxm (unsigned long insn,
return mask;
}
-/* The L field in an X form instruction which must have the value zero. */
-
-static unsigned long
-insert_l0 (unsigned long insn,
- long value,
- ppc_cpu_t dialect ATTRIBUTE_UNUSED,
- const char **errmsg)
-{
- if (value != 0)
- *errmsg = _("invalid operand constant");
- return insn & ~(0x1 << 21);
-}
-
-static long
-extract_l0 (unsigned long insn,
- ppc_cpu_t dialect ATTRIBUTE_UNUSED,
- int *invalid)
-{
- long value;
-
- value = (insn >> 21) & 0x1;
- if (value != 0)
- *invalid = 1;
- return value;
-}
-
-/* The L field in an X form instruction which must have the value one. */
-
-static unsigned long
-insert_l1 (unsigned long insn,
- long value,
- ppc_cpu_t dialect ATTRIBUTE_UNUSED,
- const char **errmsg)
-{
- if (value != 1)
- *errmsg = _("invalid operand constant");
- return insn | (0x1 << 21);
-}
-
-static long
-extract_l1 (unsigned long insn,
- ppc_cpu_t dialect ATTRIBUTE_UNUSED,
- int *invalid)
-{
- long value;
-
- value = (insn >> 21) & 0x1;
- if (value != 1)
- *invalid = 1;
- return value;
-}
-
static unsigned long
insert_li20 (unsigned long insn,
long value,
@@ -3890,12 +3840,12 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"cmplwi", OPL(10,0), OPL_MASK, PPCCOM, PPCVLE, {OBF, RA, UISIGNOPT}},
{"cmpldi", OPL(10,1), OPL_MASK, PPC64, PPCVLE, {OBF, RA, UISIGNOPT}},
-{"cmpli", OP(10), OP_MASK, PPC, PPCVLE, {BF, L, RA, UISIGNOPT}},
+{"cmpli", OP(10), OP_MASK, PPC, PPCVLE, {BF, L32OPT, RA, UISIGNOPT}},
{"cmpli", OP(10), OP_MASK, PWRCOM, PPC|PPCVLE, {BF, RA, UISIGNOPT}},
{"cmpwi", OPL(11,0), OPL_MASK, PPCCOM, PPCVLE, {OBF, RA, SI}},
{"cmpdi", OPL(11,1), OPL_MASK, PPC64, PPCVLE, {OBF, RA, SI}},
-{"cmpi", OP(11), OP_MASK, PPC, PPCVLE, {BF, L, RA, SI}},
+{"cmpi", OP(11), OP_MASK, PPC, PPCVLE, {BF, L32OPT, RA, SI}},
{"cmpi", OP(11), OP_MASK, PWRCOM, PPC|PPCVLE, {BF, RA, SI}},
{"addic", OP(12), OP_MASK, PPCCOM, PPCVLE, {RT, RA, SI}},
@@ -4713,7 +4663,7 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"cmpw", XOPL(31,0,0), XCMPL_MASK, PPCCOM, 0, {OBF, RA, RB}},
{"cmpd", XOPL(31,0,1), XCMPL_MASK, PPC64, 0, {OBF, RA, RB}},
-{"cmp", X(31,0), XCMP_MASK, PPC, 0, {BF, L, RA, RB}},
+{"cmp", X(31,0), XCMP_MASK, PPC, 0, {BF, L32OPT, RA, RB}},
{"cmp", X(31,0), XCMPL_MASK, PWRCOM, PPC, {BF, RA, RB}},
{"twlgt", XTO(31,4,TOLGT), XTO_MASK, PPCCOM, 0, {RA, RB}},
@@ -4821,7 +4771,7 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"cmplw", XOPL(31,32,0), XCMPL_MASK, PPCCOM, 0, {OBF, RA, RB}},
{"cmpld", XOPL(31,32,1), XCMPL_MASK, PPC64, 0, {OBF, RA, RB}},
-{"cmpl", X(31,32), XCMP_MASK, PPC, 0, {BF, L, RA, RB}},
+{"cmpl", X(31,32), XCMP_MASK, PPC, 0, {BF, L32OPT, RA, RB}},
{"cmpl", X(31,32), XCMPL_MASK, PWRCOM, PPC, {BF, RA, RB}},
{"lvsr", X(31,38), X_MASK, PPCVEC, 0, {VD, RA0, RB}},
@@ -4907,7 +4857,7 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"ldarx", X(31,84), XEH_MASK, PPC64, 0, {RT, RA0, RB, EH}},
{"dcbfl", XOPL(31,86,1), XRT_MASK, POWER5, PPC476, {RA0, RB}},
-{"dcbf", X(31,86), XLRT_MASK, PPC, 0, {RA0, RB, L}},
+{"dcbf", X(31,86), XLRT_MASK, PPC, 0, {RA0, RB, L2OPT}},
{"lbzx", X(31,87), X_MASK, COM, 0, {RT, RA0, RB}},
@@ -5149,7 +5099,7 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"ehpriv", X(31,270), 0xffffffff, E500MC|PPCA2, 0, {0}},
{"tlbiel", X(31,274), X_MASK|1<<20,POWER9, PPC476, {RB, RSO, RIC, PRS, X_R}},
-{"tlbiel", X(31,274), XRTLRA_MASK, POWER4, POWER9|PPC476, {RB, L}},
+{"tlbiel", X(31,274), XRTLRA_MASK, POWER4, POWER9|PPC476, {RB, LOPT}},
{"mfapidi", X(31,275), X_MASK, BOOKE, E500|TITAN, {RT, RA}},
@@ -5183,7 +5133,7 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"tlbie", X(31,306), X_MASK|1<<20,POWER9, TITAN, {RB, RS, RIC, PRS, X_R}},
{"tlbie", X(31,306), XRA_MASK, POWER7, POWER9|TITAN, {RB, RS}},
-{"tlbie", X(31,306), XRTLRA_MASK, PPC, E500|POWER7|TITAN, {RB, L}},
+{"tlbie", X(31,306), XRTLRA_MASK, PPC, E500|POWER7|TITAN, {RB, LOPT}},
{"tlbi", X(31,306), XRT_MASK, POWER, 0, {RA0, RB}},
{"mfvsrld", X(31,307), XX1RB_MASK, PPCVSX3, 0, {RA, XS6}},
@@ -6234,8 +6184,8 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{"stvfrxl", X(31,933), X_MASK, PPCVEC2, 0, {VS, RA0, RB}},
{"wclrone", XOPL2(31,934,2),XRT_MASK, PPCA2, 0, {RA0, RB}},
-{"wclrall", X(31,934), XRARB_MASK, PPCA2, 0, {L}},
-{"wclr", X(31,934), X_MASK, PPCA2, 0, {L, RA0, RB}},
+{"wclrall", X(31,934), XRARB_MASK, PPCA2, 0, {L2}},
+{"wclr", X(31,934), X_MASK, PPCA2, 0, {L2, RA0, RB}},
{"stvrxl", X(31,935), X_MASK, CELL, 0, {VS, RA0, RB}},
--
Alan Modra
Australia Development Lab, IBM
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Disallow 3-operand cmp[l][i] for ppc64
2016-09-29 6:02 Disallow 3-operand cmp[l][i] for ppc64 Alan Modra
@ 2016-09-29 20:34 ` Peter Bergner
2016-09-29 21:21 ` Alan Modra
0 siblings, 1 reply; 3+ messages in thread
From: Peter Bergner @ 2016-09-29 20:34 UTC (permalink / raw)
To: Alan Modra; +Cc: binutils, gdb-patches
On 9/29/16 1:02 AM, Alan Modra wrote:
> cmp[l][o] get an optional L field only when generating 32-bit code.
> dcbf, tlbie and tlbiel keep their optional L field, ditto for R field
> of tbegin. cmprb, tsr., wlcr[all] and mtsle all change to a
> compulsory L field.
FYI, I just committed the following as obvious to clean up the gdb
testsuite fallout from this change.
Peter
* gdb.arch/powerpc-power.exp <cmprb>: Update tests to account for
the compulsory L operand changes.
* gdb.arch/powerpc-power.s: Likewise.
diff --git a/gdb/testsuite/gdb.arch/powerpc-power.exp b/gdb/testsuite/gdb.arch/powerpc-power.exp
index 3bdfc15..8594ad5 100644
--- a/gdb/testsuite/gdb.arch/powerpc-power.exp
+++ b/gdb/testsuite/gdb.arch/powerpc-power.exp
@@ -1117,8 +1117,8 @@ func_check +4168 "xvxsigdp vs59,vs60"
func_check +4172 "xvxsigsp vs60,vs61"
func_check +4176 "cmpeqb cr0,r6,r7"
func_check +4180 "cmpeqb cr7,r6,r7"
-func_check +4184 "cmprb cr0,r8,r9"
-func_check +4188 "cmprb cr7,r8,r9"
+func_check +4184 "cmprb cr0,0,r8,r9"
+func_check +4188 "cmprb cr7,0,r8,r9"
func_check +4192 "cmprb cr0,1,r8,r9"
func_check +4196 "cmprb cr7,1,r8,r9"
func_check +4200 "setb r15,cr0"
diff --git a/gdb/testsuite/gdb.arch/powerpc-power.s b/gdb/testsuite/gdb.arch/powerpc-power.s
index 507b61e..6fe2520 100644
--- a/gdb/testsuite/gdb.arch/powerpc-power.s
+++ b/gdb/testsuite/gdb.arch/powerpc-power.s
@@ -1078,8 +1078,8 @@ func:
.long 0xf389ef6f /* <+4172>: xvxsigsp vs60,vs61 */
.long 0x7c0639c0 /* <+4176>: cmpeqb cr0,r6,r7 */
.long 0x7f8639c0 /* <+4180>: cmpeqb cr7,r6,r7 */
- .long 0x7c084980 /* <+4184>: cmprb cr0,r8,r9 */
- .long 0x7f884980 /* <+4188>: cmprb cr7,r8,r9 */
+ .long 0x7c084980 /* <+4184>: cmprb cr0,0,r8,r9 */
+ .long 0x7f884980 /* <+4188>: cmprb cr7,0,r8,r9 */
.long 0x7c284980 /* <+4192>: cmprb cr0,1,r8,r9 */
.long 0x7fa84980 /* <+4196>: cmprb cr7,1,r8,r9 */
.long 0x7de00100 /* <+4200>: setb r15,cr0 */
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Disallow 3-operand cmp[l][i] for ppc64
2016-09-29 20:34 ` Peter Bergner
@ 2016-09-29 21:21 ` Alan Modra
0 siblings, 0 replies; 3+ messages in thread
From: Alan Modra @ 2016-09-29 21:21 UTC (permalink / raw)
To: Peter Bergner; +Cc: binutils, gdb-patches
On Thu, Sep 29, 2016 at 03:34:40PM -0500, Peter Bergner wrote:
> On 9/29/16 1:02 AM, Alan Modra wrote:
> > cmp[l][o] get an optional L field only when generating 32-bit code.
> > dcbf, tlbie and tlbiel keep their optional L field, ditto for R field
> > of tbegin. cmprb, tsr., wlcr[all] and mtsle all change to a
> > compulsory L field.
>
> FYI, I just committed the following as obvious to clean up the gdb
> testsuite fallout from this change.
Thanks!
--
Alan Modra
Australia Development Lab, IBM
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2016-09-29 21:21 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-09-29 6:02 Disallow 3-operand cmp[l][i] for ppc64 Alan Modra
2016-09-29 20:34 ` Peter Bergner
2016-09-29 21:21 ` Alan Modra
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).