PR27676, PowerPC missing extended dcbt, dcbtst mnemonics

Alan Modra amodra@gmail.com
Wed Apr 7 23:02:14 GMT 2021


Note that this doesn't implement the ISA to the letter regarding
dcbtds (and dcbtstds), which says that the TH field may be zero.  That
doesn't make sense because allowing TH=0 would mean you no long have a
dcbtds but rather a dcbtct instruction.  I'm interpreting the ISA
wording about allowing TH=0 to mean that the TH field of dcbtds is
optional (in which case the TH value is 0b1000).

opcodes/
	PR 27676
	* ppc-opc.c (DCBT_EO): Move earlier.
	(insert_thct, extract_thct, insert_thds, extract_thds): New functions.
	(powerpc_operands): Add THCT and THDS entries.
	(powerpc_opcodes): Add dcbtstct, dcbtstds, dcbna, dcbtct, dcbtds.
gas/
	* testsuite/gas/ppc/pr27676.d,
	* testsuite/gas/ppc/pr27676.s: New test.
	* testsuite/gas/ppc/ppc.exp: Run it.
	* testsuite/gas/ppc/dcbt.d: Update.
	* testsuite/gas/ppc/power4_32.d: Update.

diff --git a/gas/testsuite/gas/ppc/dcbt.d b/gas/testsuite/gas/ppc/dcbt.d
index 49311e82f7a..0a213fd9b79 100644
--- a/gas/testsuite/gas/ppc/dcbt.d
+++ b/gas/testsuite/gas/ppc/dcbt.d
@@ -6,4 +6,4 @@
 Disassembly of section \.text:
 
 .*:
-   0:	(7d 40 5a 2c|2c 5a 40 7d) 	dcbt    0,r11,10
+   0:	(7d 40 5a 2c|2c 5a 40 7d) 	dcbtds  0,r11,10
diff --git a/gas/testsuite/gas/ppc/power4_32.d b/gas/testsuite/gas/ppc/power4_32.d
index 39c80dd4d2e..8396d7d294f 100644
--- a/gas/testsuite/gas/ppc/power4_32.d
+++ b/gas/testsuite/gas/ppc/power4_32.d
@@ -41,7 +41,7 @@ Disassembly of section \.text:
   7c:	(7c 01 17 ec|ec 17 01 7c) 	dcbz    r1,r2
   80:	(7c 23 27 ec|ec 27 23 7c) 	dcbzl   r3,r4
   84:	(7c 05 37 ec|ec 37 05 7c) 	dcbz    r5,r6
-  88:	(7c 05 32 2c|2c 32 05 7c) 	dcbt    r5,r6
-  8c:	(7c 05 32 2c|2c 32 05 7c) 	dcbt    r5,r6
-  90:	(7d 05 32 2c|2c 32 05 7d) 	dcbt    r5,r6,8
+  88:	(7c 05 32 2c|2c 32 05 7c) 	dcbtct  r5,r6
+  8c:	(7c 05 32 2c|2c 32 05 7c) 	dcbtct  r5,r6
+  90:	(7d 05 32 2c|2c 32 05 7d) 	dcbtds  r5,r6
 #pass
diff --git a/gas/testsuite/gas/ppc/ppc.exp b/gas/testsuite/gas/ppc/ppc.exp
index 6f61ad09f41..560d927e7ed 100644
--- a/gas/testsuite/gas/ppc/ppc.exp
+++ b/gas/testsuite/gas/ppc/ppc.exp
@@ -150,3 +150,4 @@ run_dump_test "rop"
 run_dump_test "rop-checks"
 
 run_dump_test "dcbt"
+run_dump_test "pr27676"
diff --git a/gas/testsuite/gas/ppc/pr27676.d b/gas/testsuite/gas/ppc/pr27676.d
new file mode 100644
index 00000000000..55e16391f13
--- /dev/null
+++ b/gas/testsuite/gas/ppc/pr27676.d
@@ -0,0 +1,79 @@
+#as: -mpower10
+#objdump: -dr -Mpower10
+
+.*:     file format .*
+
+Disassembly of section \.text:
+
+0+ <\.text>:
+   0:	(7c 03 22 2c|2c 22 03 7c) 	dcbtct  r3,r4
+   4:	(7c 23 22 2c|2c 22 23 7c) 	dcbtct  r3,r4,1
+   8:	(7c 43 22 2c|2c 22 43 7c) 	dcbtct  r3,r4,2
+   c:	(7c 63 22 2c|2c 22 63 7c) 	dcbtct  r3,r4,3
+  10:	(7c 83 22 2c|2c 22 83 7c) 	dcbtct  r3,r4,4
+  14:	(7c a3 22 2c|2c 22 a3 7c) 	dcbtct  r3,r4,5
+  18:	(7c c3 22 2c|2c 22 c3 7c) 	dcbtct  r3,r4,6
+  1c:	(7c e3 22 2c|2c 22 e3 7c) 	dcbtct  r3,r4,7
+  20:	(7d 03 22 2c|2c 22 03 7d) 	dcbtds  r3,r4
+  24:	(7d 23 22 2c|2c 22 23 7d) 	dcbtds  r3,r4,9
+  28:	(7d 43 22 2c|2c 22 43 7d) 	dcbtds  r3,r4,10
+  2c:	(7d 63 22 2c|2c 22 63 7d) 	dcbtds  r3,r4,11
+  30:	(7d 83 22 2c|2c 22 83 7d) 	dcbtds  r3,r4,12
+  34:	(7d a3 22 2c|2c 22 a3 7d) 	dcbtds  r3,r4,13
+  38:	(7d c3 22 2c|2c 22 c3 7d) 	dcbtds  r3,r4,14
+  3c:	(7d e3 22 2c|2c 22 e3 7d) 	dcbtds  r3,r4,15
+  40:	(7e 03 22 2c|2c 22 03 7e) 	dcbtt   r3,r4
+  44:	(7e 23 22 2c|2c 22 23 7e) 	dcbna   r3,r4
+  48:	(7e 43 22 2c|2c 22 43 7e) 	dcbt    r3,r4,18
+  4c:	(7e 63 22 2c|2c 22 63 7e) 	dcbt    r3,r4,19
+  50:	(7e 83 22 2c|2c 22 83 7e) 	dcbt    r3,r4,20
+  54:	(7e a3 22 2c|2c 22 a3 7e) 	dcbt    r3,r4,21
+  58:	(7e c3 22 2c|2c 22 c3 7e) 	dcbt    r3,r4,22
+  5c:	(7e e3 22 2c|2c 22 e3 7e) 	dcbt    r3,r4,23
+  60:	(7f 03 22 2c|2c 22 03 7f) 	dcbt    r3,r4,24
+  64:	(7f 23 22 2c|2c 22 23 7f) 	dcbt    r3,r4,25
+  68:	(7f 43 22 2c|2c 22 43 7f) 	dcbt    r3,r4,26
+  6c:	(7f 63 22 2c|2c 22 63 7f) 	dcbt    r3,r4,27
+  70:	(7f 83 22 2c|2c 22 83 7f) 	dcbt    r3,r4,28
+  74:	(7f a3 22 2c|2c 22 a3 7f) 	dcbt    r3,r4,29
+  78:	(7f c3 22 2c|2c 22 c3 7f) 	dcbt    r3,r4,30
+  7c:	(7f e3 22 2c|2c 22 e3 7f) 	dcbt    r3,r4,31
+  80:	(7c 05 32 2c|2c 32 05 7c) 	dcbtct  r5,r6
+  84:	(7d 05 32 2c|2c 32 05 7d) 	dcbtds  r5,r6
+  88:	(7e 05 32 2c|2c 32 05 7e) 	dcbtt   r5,r6
+  8c:	(7e 25 32 2c|2c 32 25 7e) 	dcbna   r5,r6
+  90:	(7c 03 21 ec|ec 21 03 7c) 	dcbtstct r3,r4
+  94:	(7c 23 21 ec|ec 21 23 7c) 	dcbtstct r3,r4,1
+  98:	(7c 43 21 ec|ec 21 43 7c) 	dcbtstct r3,r4,2
+  9c:	(7c 63 21 ec|ec 21 63 7c) 	dcbtstct r3,r4,3
+  a0:	(7c 83 21 ec|ec 21 83 7c) 	dcbtstct r3,r4,4
+  a4:	(7c a3 21 ec|ec 21 a3 7c) 	dcbtstct r3,r4,5
+  a8:	(7c c3 21 ec|ec 21 c3 7c) 	dcbtstct r3,r4,6
+  ac:	(7c e3 21 ec|ec 21 e3 7c) 	dcbtstct r3,r4,7
+  b0:	(7d 03 21 ec|ec 21 03 7d) 	dcbtstds r3,r4
+  b4:	(7d 23 21 ec|ec 21 23 7d) 	dcbtstds r3,r4,9
+  b8:	(7d 43 21 ec|ec 21 43 7d) 	dcbtstds r3,r4,10
+  bc:	(7d 63 21 ec|ec 21 63 7d) 	dcbtstds r3,r4,11
+  c0:	(7d 83 21 ec|ec 21 83 7d) 	dcbtstds r3,r4,12
+  c4:	(7d a3 21 ec|ec 21 a3 7d) 	dcbtstds r3,r4,13
+  c8:	(7d c3 21 ec|ec 21 c3 7d) 	dcbtstds r3,r4,14
+  cc:	(7d e3 21 ec|ec 21 e3 7d) 	dcbtstds r3,r4,15
+  d0:	(7e 03 21 ec|ec 21 03 7e) 	dcbtstt r3,r4
+  d4:	(7e 23 21 ec|ec 21 23 7e) 	dcbtst  r3,r4,17
+  d8:	(7e 43 21 ec|ec 21 43 7e) 	dcbtst  r3,r4,18
+  dc:	(7e 63 21 ec|ec 21 63 7e) 	dcbtst  r3,r4,19
+  e0:	(7e 83 21 ec|ec 21 83 7e) 	dcbtst  r3,r4,20
+  e4:	(7e a3 21 ec|ec 21 a3 7e) 	dcbtst  r3,r4,21
+  e8:	(7e c3 21 ec|ec 21 c3 7e) 	dcbtst  r3,r4,22
+  ec:	(7e e3 21 ec|ec 21 e3 7e) 	dcbtst  r3,r4,23
+  f0:	(7f 03 21 ec|ec 21 03 7f) 	dcbtst  r3,r4,24
+  f4:	(7f 23 21 ec|ec 21 23 7f) 	dcbtst  r3,r4,25
+  f8:	(7f 43 21 ec|ec 21 43 7f) 	dcbtst  r3,r4,26
+  fc:	(7f 63 21 ec|ec 21 63 7f) 	dcbtst  r3,r4,27
+ 100:	(7f 83 21 ec|ec 21 83 7f) 	dcbtst  r3,r4,28
+ 104:	(7f a3 21 ec|ec 21 a3 7f) 	dcbtst  r3,r4,29
+ 108:	(7f c3 21 ec|ec 21 c3 7f) 	dcbtst  r3,r4,30
+ 10c:	(7f e3 21 ec|ec 21 e3 7f) 	dcbtst  r3,r4,31
+ 110:	(7c 05 31 ec|ec 31 05 7c) 	dcbtstct r5,r6
+ 114:	(7d 05 31 ec|ec 31 05 7d) 	dcbtstds r5,r6
+ 118:	(7e 05 31 ec|ec 31 05 7e) 	dcbtstt r5,r6
diff --git a/gas/testsuite/gas/ppc/pr27676.s b/gas/testsuite/gas/ppc/pr27676.s
new file mode 100644
index 00000000000..3186e49a54b
--- /dev/null
+++ b/gas/testsuite/gas/ppc/pr27676.s
@@ -0,0 +1,71 @@
+ dcbt 3,4,0
+ dcbt 3,4,1
+ dcbt 3,4,2
+ dcbt 3,4,3
+ dcbt 3,4,4
+ dcbt 3,4,5
+ dcbt 3,4,6
+ dcbt 3,4,7
+ dcbt 3,4,8
+ dcbt 3,4,9
+ dcbt 3,4,10
+ dcbt 3,4,11
+ dcbt 3,4,12
+ dcbt 3,4,13
+ dcbt 3,4,14
+ dcbt 3,4,15
+ dcbt 3,4,16
+ dcbt 3,4,17
+ dcbt 3,4,18
+ dcbt 3,4,19
+ dcbt 3,4,20
+ dcbt 3,4,21
+ dcbt 3,4,22
+ dcbt 3,4,23
+ dcbt 3,4,24
+ dcbt 3,4,25
+ dcbt 3,4,26
+ dcbt 3,4,27
+ dcbt 3,4,28
+ dcbt 3,4,29
+ dcbt 3,4,30
+ dcbt 3,4,31
+ dcbtct 5,6
+ dcbtds 5,6
+ dcbtt 5,6
+ dcbna 5,6
+ dcbtst 3,4,0
+ dcbtst 3,4,1
+ dcbtst 3,4,2
+ dcbtst 3,4,3
+ dcbtst 3,4,4
+ dcbtst 3,4,5
+ dcbtst 3,4,6
+ dcbtst 3,4,7
+ dcbtst 3,4,8
+ dcbtst 3,4,9
+ dcbtst 3,4,10
+ dcbtst 3,4,11
+ dcbtst 3,4,12
+ dcbtst 3,4,13
+ dcbtst 3,4,14
+ dcbtst 3,4,15
+ dcbtst 3,4,16
+ dcbtst 3,4,17
+ dcbtst 3,4,18
+ dcbtst 3,4,19
+ dcbtst 3,4,20
+ dcbtst 3,4,21
+ dcbtst 3,4,22
+ dcbtst 3,4,23
+ dcbtst 3,4,24
+ dcbtst 3,4,25
+ dcbtst 3,4,26
+ dcbtst 3,4,27
+ dcbtst 3,4,28
+ dcbtst 3,4,29
+ dcbtst 3,4,30
+ dcbtst 3,4,31
+ dcbtstct 5,6
+ dcbtstds 5,6
+ dcbtstt 5,6
diff --git a/opcodes/ppc-opc.c b/opcodes/ppc-opc.c
index 97982ab7e75..025a2ba2fba 100644
--- a/opcodes/ppc-opc.c
+++ b/opcodes/ppc-opc.c
@@ -2233,6 +2233,74 @@ extract_sxl (uint64_t insn,
     return 1;
   return (insn >> 11) & 0x1;
 }
+
+/* The list of embedded processors that use the embedded operand ordering
+   for the 3 operand dcbt and dcbtst instructions.  */
+#define DCBT_EO (PPC_OPCODE_E500 | PPC_OPCODE_E500MC | PPC_OPCODE_476 \
+		 | PPC_OPCODE_A2)
+
+/* ISA 2.03 and later specify extended mnemonics dcbtct, dcbtds, and
+   dcbtstct, dcbtstds with a note saying these should be used in new
+   programs rather than the base mnemonics "so that it can be coded
+   with TH as the last operand for all categories".  For that reason
+   the extended mnemonics are enabled in the assembler for the
+   embedded processors, but not for the disassembler so as to display
+   the embedded dcbt or dcbtst expected form with TH first for
+   embedded programmers.  */
+
+static uint64_t
+insert_thct (uint64_t insn,
+	    int64_t value,
+	    ppc_cpu_t dialect ATTRIBUTE_UNUSED,
+	    const char **errmsg)
+{
+  if ((uint64_t) value > 7)
+    *errmsg = _("invalid TH value");
+  return insn | ((value & 7) << 21);
+}
+
+static int64_t
+extract_thct (uint64_t insn,
+	      ppc_cpu_t dialect,
+	      int *invalid)
+{
+  /* Missing optional operands have a value of 0.  */
+  if (*invalid < 0)
+    return 0;
+
+  int64_t value = (insn >> 21) & 0x1f;
+  if (value > 7 || (dialect & DCBT_EO) != 0)
+    *invalid = 1;
+
+  return value;
+}
+
+static uint64_t
+insert_thds (uint64_t insn,
+	     int64_t value,
+	     ppc_cpu_t dialect ATTRIBUTE_UNUSED,
+	     const char **errmsg)
+{
+  if (value < 8 || value > 15)
+    *errmsg = _("invalid TH value");
+  return insn | ((value & 0x1f) << 21);
+}
+
+static int64_t
+extract_thds (uint64_t insn,
+	      ppc_cpu_t dialect,
+	      int *invalid)
+{
+  /* Missing optional operands have a value of 8.  */
+  if (*invalid < 0)
+    return 8;
+
+  int64_t value = (insn >> 21) & 0x1f;
+  if (value < 8 || value > 15 || (dialect & DCBT_EO) != 0)
+    *invalid = 1;
+
+  return value;
+}
 
 /* The operands table.
 
@@ -2430,10 +2498,18 @@ const struct powerpc_operand powerpc_operands[] =
 #define MO CT
   { 0x1f, 21, NULL, NULL, PPC_OPERAND_OPTIONAL },
 
+  /* The TH field in dcbtct.  */
+#define THCT CT + 1
+  { 0x1f, 21, insert_thct, extract_thct, PPC_OPERAND_OPTIONAL },
+
+  /* The TH field in dcbtds.  */
+#define THDS THCT + 1
+  { 0x1f, 21, insert_thds, extract_thds, PPC_OPERAND_OPTIONAL },
+
   /* The D field in a D form instruction.  This is a displacement off
      a register, and implies that the next operand is a register in
      parentheses.  */
-#define D CT + 1
+#define D THDS + 1
   { 0xffff, 0, NULL, NULL, PPC_OPERAND_PARENS | PPC_OPERAND_SIGNED },
 
   /* The D8 field in a D form instruction.  This is a displacement off
@@ -4248,12 +4324,6 @@ const unsigned int num_powerpc_operands = (sizeof (powerpc_operands)
 #define PPCHTM  PPC_OPCODE_POWER8
 #define E200Z4  PPC_OPCODE_E200Z4
 #define PPCLSP  PPC_OPCODE_LSP
-/* The list of embedded processors that use the embedded operand ordering
-   for the 3 operand dcbt and dcbtst instructions.  */
-#define DCBT_EO	(PPC_OPCODE_E500 | PPC_OPCODE_E500MC | PPC_OPCODE_476 \
-		 | PPC_OPCODE_A2)
-
-
 
 /* The opcode table.
 
@@ -6632,6 +6702,8 @@ const struct powerpc_opcode powerpc_opcodes[] = {
 {"mtvsrwz",	X(31,243),	XX1RB_MASK,   PPCVSX2,	0,		{XT6, RA}},
 
 {"dcbtstt",	XRT(31,246,0x10), XRT_MASK,  POWER7,	0,		{RA0, RB}},
+{"dcbtstct",	X(31,246),	X_MASK,	     POWER4,	0,		{RA0, RB, THCT}},
+{"dcbtstds",	X(31,246),	X_MASK,	     POWER4,	0,		{RA0, RB, THDS}},
 {"dcbtst",	X(31,246),	X_MASK,	     POWER4,	DCBT_EO,	{RA0, RB, CT}},
 {"dcbtst",	X(31,246),	X_MASK,	     DCBT_EO,	0,		{CT, RA0, RB}},
 {"dcbtst",	X(31,246),	X_MASK,	     PPC,	POWER4|DCBT_EO,	{RA0, RB}},
@@ -6683,6 +6755,9 @@ const struct powerpc_opcode powerpc_opcodes[] = {
 {"lscbx.",	XRC(31,277,1),	X_MASK,	     M601,	0,		{RT, RA, RB}},
 
 {"dcbtt",	XRT(31,278,0x10), XRT_MASK,  POWER7,	0,		{RA0, RB}},
+{"dcbna",	XRT(31,278,0x11), XRT_MASK,  POWER10,	0,		{RA0, RB}},
+{"dcbtct",	X(31,278),	X_MASK,      POWER4,	0,		{RA0, RB, THCT}},
+{"dcbtds",	X(31,278),	X_MASK,      POWER4,	0,		{RA0, RB, THDS}},
 {"dcbt",	X(31,278),	X_MASK,	     POWER4,	DCBT_EO,	{RA0, RB, CT}},
 {"dcbt",	X(31,278),	X_MASK,	     DCBT_EO,	0,		{CT, RA0, RB}},
 {"dcbt",	X(31,278),	X_MASK,	     PPC,	POWER4|DCBT_EO,	{RA0, RB}},

-- 
Alan Modra
Australia Development Lab, IBM


More information about the Binutils mailing list