PowerPC: Support for Prefixed Add Immediate Shifted Instruction (RFC02686)
Checks
Context |
Check |
Description |
linaro-tcwg-bot/tcwg_binutils_build--master-arm |
success
|
Build passed
|
linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 |
success
|
Build passed
|
linaro-tcwg-bot/tcwg_binutils_check--master-aarch64 |
success
|
Test passed
|
linaro-tcwg-bot/tcwg_binutils_check--master-arm |
success
|
Test passed
|
Commit Message
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(-)
Comments
On 05.03.2025 18:24, Surya Kumari Jangala wrote:
> PowerPC: Support for Prefixed Add Immediate Shifted Instruction (RFC02686)
Is there any (public) reference to the rfc you could add? From just the patch
I can't deduce what is being shifted here in which way.
> @@ -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)
Does this define's comment perhaps mean to reference P_D_SI32_MASK?
Jan
On 3/6/25 7:25 AM, Jan Beulich wrote:
> On 05.03.2025 18:24, Surya Kumari Jangala wrote:
>> PowerPC: Support for Prefixed Add Immediate Shifted Instruction (RFC02686)
>
> Is there any (public) reference to the rfc you could add? From just the patch
> I can't deduce what is being shifted here in which way.
So they're available thru the OpenPower foundation, but IIRC, only to members,
so not available (yet) to the public. Sorry.
>> +/* 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)
>
> Does this define's comment perhaps mean to reference P_D_SI32_MASK?
Agreed.
Peter
On 05.03.2025 18:24, Surya Kumari Jangala wrote:
> @@ -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}},
Since, unlike for e.g. PADDI, these are 32-bit fields, and these are shifted
immediates, don't we need one or more new relocation types to express these
immediate operands when they're not plain constants?
Jan
Hi Jan,
On 06/03/25 6:55 pm, Jan Beulich wrote:
>> @@ -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)
>
> Does this define's comment perhaps mean to reference P_D_SI32_MASK?
Yes, the comment should refer to P_D_SI32_MASK. Thanks for catching it!
>
> Jan
On 3/11/25 2:43 AM, Jan Beulich wrote:
> On 05.03.2025 18:24, Surya Kumari Jangala wrote:
>> @@ -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}},
>
> Since, unlike for e.g. PADDI, these are 32-bit fields, and these are shifted
> immediates, don't we need one or more new relocation types to express these
> immediate operands when they're not plain constants?
Currently, our GCC patches don't emit paddis yet for -mcmodel=large, just for
constant generation at the moment, but yes, once we tackle that, we will need
some new linker relocations. That will be a follow-on patch.
Peter
@@ -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
@@ -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
+
@@ -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}},