[PATCH] PowerPC: Support for Prefixed Add Immediate Shifted Instruction (RFC02686)

Surya Kumari Jangala jskumari@linux.ibm.com
Wed Mar 5 17:24:11 GMT 2025


PowerPC: Support for Prefixed Add Immediate Shifted Instruction (RFC02686)

opcodes/
	* ppc-opc.c (insert_si32, extract_si32, insert_nsi32,
	extract_nsi32): New functions.
	(SI32, NSI32, P_D_SI32_MASK, P_DRAPCREL_SI32_MASK): New macros.
	(IM32): Update for new macros.
	(powerpc_opcodes): Add plis, paddis, psubis.

gas/
	* testsuite/gas/ppc/future.s: New test.
	* testsuite/gas/ppc/future.d: Likewise.
---
 gas/testsuite/gas/ppc/future.d | 23 ++++++++++++
 gas/testsuite/gas/ppc/future.s | 13 +++++++
 opcodes/ppc-opc.c              | 69 +++++++++++++++++++++++++++++++++-
 3 files changed, 104 insertions(+), 1 deletion(-)

diff --git a/gas/testsuite/gas/ppc/future.d b/gas/testsuite/gas/ppc/future.d
index 76a30a50316..e825cb6127b 100644
--- a/gas/testsuite/gas/ppc/future.d
+++ b/gas/testsuite/gas/ppc/future.d
@@ -57,4 +57,27 @@ Disassembly of section \.text:
 .*:	(d0 1e 22 f0|f0 22 1e d0) 	xxgfmul128gcm vs1,vs2,vs3
 .*:	(d6 0f e0 f3|f3 e0 0f d6) 	xxgfmul128xts vs31,vs32,vs33
 .*:	(d6 0f e0 f3|f3 e0 0f d6) 	xxgfmul128xts vs31,vs32,vs33
+.*:	(06 00 00 00|00 00 00 06) 	paddis  r12,r9,15
+.*:	(3d 89 00 0f|0f 00 89 3d) 
+.*:	(06 00 ff ff|ff ff 00 06) 	paddis  r12,r9,-32769
+.*:	(3d 89 7f ff|ff 7f 89 3d) 
+.*:	(06 10 00 00|00 00 10 06) 	paddis  r9,0,25,1	# d4
+.*:	(3d 20 00 19|19 00 20 3d) 
+.*:	(06 00 7f ff|ff 7f 00 06) 	paddis  r24,0,2147483647
+.*:	(3f 00 ff ff|ff ff 00 3f) 
+.*:	(06 00 7f ff|ff 7f 00 06) 	paddis  r24,0,2147483647
+.*:	(3f 00 ff ff|ff ff 00 3f) 
+.*:	(06 00 80 00|00 80 00 06) 	paddis  r30,r10,-2147483648
+.*:	(3f ca 00 00|00 00 ca 3f) 
+.*:	(06 00 80 00|00 80 00 06) 	paddis  r30,r10,-2147483648
+.*:	(3f ca 00 00|00 00 ca 3f) 
+.*:	(60 00 00 00|00 00 00 60) 	nop
+.*:	(06 00 7f ff|ff 7f 00 06) 	paddis  r30,r10,2147483647
+.*:	(3f ca ff ff|ff ff ca 3f) 
+.*:	(06 00 7f ff|ff 7f 00 06) 	paddis  r30,r10,2147483647
+.*:	(3f ca ff ff|ff ff ca 3f) 
+.*:	(06 10 7f ff|ff 7f 10 06) 	paddis  r15,0,2147483647,1	# 110
+.*	(3d e0 ff ff|ff ff e0 3d) 
+.*:	(06 10 7f ff|ff 7f 10 06) 	paddis  r15,0,2147483647,1	# 118
+.*	(3d e0 ff ff|ff ff e0 3d) 
 #pass
diff --git a/gas/testsuite/gas/ppc/future.s b/gas/testsuite/gas/ppc/future.s
index fec99e348bf..90e5e894bc1 100644
--- a/gas/testsuite/gas/ppc/future.s
+++ b/gas/testsuite/gas/ppc/future.s
@@ -49,3 +49,16 @@ _start:
 	xxgfmul128gcm 1, 2, 3
 	xxgfmul128 31, 32, 33, 1
 	xxgfmul128xts 31, 32, 33
+	paddis 12, 9, 15, 0
+	paddis 12, 9, ~(1<<15), 0
+	paddis 9, 0, 25, 1
+	paddis 24, 0, 2147483647, 0
+	plis 24, 2147483647
+	paddis 30, 10, -2147483648, 0
+	psubis 30, 10, 2147483648, 0
+	nop
+	paddis 30, 10, 2147483647, 0
+	psubis 30, 10, -2147483647, 0
+	paddis 15, 0, 2147483647, 1
+	psubis 15, 0, -2147483647, 1
+
diff --git a/opcodes/ppc-opc.c b/opcodes/ppc-opc.c
index ba93e569891..0476fb5a052 100644
--- a/opcodes/ppc-opc.c
+++ b/opcodes/ppc-opc.c
@@ -691,6 +691,52 @@ extract_imm32 (uint64_t insn,
   return (insn & 0xffff) | ((insn >> 16) & 0xffff0000);
 }
 
+/* The 32bit SI field in a 64-bit D form prefix instruction when the field is split
+   into separate SI0 and SI1 fields.  */
+
+static uint64_t
+insert_si32 (uint64_t insn,
+	     int64_t value,
+	     ppc_cpu_t dialect ATTRIBUTE_UNUSED,
+	     const char **errmsg ATTRIBUTE_UNUSED)
+{
+  return insn | ((value & 0xffff0000ULL) << 16) | (value & 0xffff);
+}
+
+static int64_t
+extract_si32 (uint64_t insn,
+	      ppc_cpu_t dialect ATTRIBUTE_UNUSED,
+	      int *invalid ATTRIBUTE_UNUSED)
+{
+  int64_t mask = 1ULL << 31;
+  int64_t value = ((insn >> 16) & 0xffff0000ULL) | (insn & 0xffff);
+  value = (value ^ mask) - mask;
+  return value;
+}
+
+/* The NSI32 field in an 8-byte D form prefix instruction.  This is the same
+   as the SI32 field, only negated.  The extraction function always marks it
+   as invalid, since we never want to recognize an instruction which uses
+   a field of this type.  */
+static uint64_t
+insert_nsi32 (uint64_t insn,
+	      int64_t value,
+	      ppc_cpu_t dialect,
+	      const char **errmsg)
+{
+  return insert_si32 (insn, -value, dialect, errmsg);
+}
+
+static int64_t
+extract_nsi32 (uint64_t insn,
+	       ppc_cpu_t dialect,
+	       int *invalid)
+{
+  int64_t value = extract_si32 (insn, dialect, invalid);
+  *invalid = 1;
+  return -value;
+}
+
 /* The R field in an 8-byte prefix instruction when there are restrictions
    between R's value and the RA value (ie, they cannot both be non zero).  */
 
@@ -3073,8 +3119,18 @@ const struct powerpc_operand powerpc_operands[] =
   { UINT64_C(0x3ffffffff), PPC_OPSHIFT_INV, insert_nsi34, extract_nsi34,
     PPC_OPERAND_NEGATIVE | PPC_OPERAND_SIGNED },
 
+  /* The 32bit SI field in an 8-byte D form prefix instruction.  */
+#define SI32 NSI34 + 1
+  { UINT64_C(0xffffffff), PPC_OPSHIFT_INV, insert_si32, extract_si32, PPC_OPERAND_SIGNED },
+
+  /* The NSI field in an 8-byte D form prefix instruction with 32bit SI field.  This is
+     the same as the SI32 field, only negated.  */
+#define NSI32 SI32 + 1
+  { UINT64_C(0xffffffff), PPC_OPSHIFT_INV, insert_nsi32, extract_nsi32,
+    PPC_OPERAND_NEGATIVE | PPC_OPERAND_SIGNED },
+
   /* The IMM32 field in a vector splat immediate prefix instruction.  */
-#define IMM32 NSI34 + 1
+#define IMM32 NSI32 + 1
   { 0xffffffff, PPC_OPSHIFT_INV, insert_imm32, extract_imm32, 0},
 
   /* The UIM field in a vector permute extended prefix instruction.  */
@@ -4031,9 +4087,15 @@ const unsigned int num_powerpc_operands = ARRAY_SIZE (powerpc_operands);
 /* An 8-byte D form prefix instruction.  */
 #define P_D_MASK (((-1ULL << 50) & ~PCREL_MASK) | OP_MASK)
 
+/* An 8-byte D form prefix instruction with 32bit SI field.  */
+#define P_D_SI32_MASK (((-1ULL << 48) & ~PCREL_MASK) | OP_MASK)
+
 /* The same as P_D_MASK, but with the RA and PCREL fields specified.  */
 #define P_DRAPCREL_MASK (P_D_MASK | PCREL_MASK | RA_MASK)
 
+/* The same as P_D_MASK, but with the RA and PCREL fields specified.  */
+#define P_DRAPCREL_SI32_MASK (P_D_SI32_MASK | PCREL_MASK | RA_MASK)
+
 /* Mask for prefix X form instructions.  */
 #define P_X_MASK (PREFIX_MASK | X_MASK)
 #define P_XX1_MASK (PREFIX_MASK | XX1_MASK)
@@ -9863,6 +9925,11 @@ const struct powerpc_opcode prefix_opcodes[] = {
 {"pla",		  PMLS|OP(14),	       P_D_MASK,	POWER10, EXT,	{RT, D34, PRA0, PCREL1}},
 {"paddi",	  PMLS|OP(14),	       P_D_MASK,	POWER10, 0,	{RT, RA0, SI34, PCREL}},
 {"psubi",	  PMLS|OP(14),	       P_D_MASK,	POWER10, EXT,	{RT, RA0, NSI34, PCREL}},
+
+{"plis",	  PMLS|OP(15),	       P_DRAPCREL_SI32_MASK,	FUTURE,  EXT,	{RT, SI32}},
+{"paddis",	  PMLS|OP(15),	       P_D_SI32_MASK,		FUTURE,  0,	{RT, RA0, SI32, PCREL}},
+{"psubis",	  PMLS|OP(15),	       P_D_SI32_MASK,		FUTURE,  EXT,	{RT, RA0, NSI32, PCREL}},
+
 {"xxsplti32dx",	  P8RR|VSOP(32,0),     P_VSI_MASK,	POWER10, 0,	{XTS, IX, IMM32}},
 {"xxspltidp",	  P8RR|VSOP(32,2),     P_VS_MASK,	POWER10, 0,	{XTS, IMM32}},
 {"xxspltiw",	  P8RR|VSOP(32,3),     P_VS_MASK,	POWER10, 0,	{XTS, IMM32}},
-- 
2.43.5



More information about the Binutils mailing list