[v5] PowerPC: Support for SHA2 and SHA3 Compute Instructions (RFC02654)

Message ID 20251205090440.1629664-1-abhay@linux.ibm.com
State New
Headers
Series [v5] PowerPC: Support for SHA2 and SHA3 Compute Instructions (RFC02654) |

Commit Message

Abhay Kandpal Dec. 5, 2025, 9:04 a.m. UTC
  opcodes/
    * ppc-opc.c: (insert_sr, extract_sr, insert_id, extract_id )
    : New functions.
    (DMRATp, HASHT, HASHSR, PADE, PADID, PADBL, XDMR2HASH,
    XDMR3HASH, XDMR2HASH_MASK, XDMR3HASH_MASK, XDMRSR_MASK
    XX2PAD, XX2PADE, XX2PAD_MASK, XX2PADE_MASK): New defines.
    (OBF, L, PMSK8, RRWn, S): Update for new macros.
    (powerpc_opcodes): Add dmsha2hash, dmsha3hash, dmxxshapad,
    dmsha256hash, dmsha512hash, dmsha3dw, dmcryshash, dmxxsha3512pad,
    dmxxsha3384pad, dmxxsha3256pad, dmxxsha3224pad, dmxxshake256pad,
    dmxxshake128pad, dmxxsha384512pad, dmxxsha224256pad.

gas/
    * testsuite/gas/ppc/future.s: New test.
    * testsuite/gas/ppc/future.d: Likewise.
---
This patch is reg tested.
Changed from v4->v5
<Added New functions>
<Modified existing macros(RRWn, S)>

 gas/testsuite/gas/ppc/future.d |  19 +++++
 gas/testsuite/gas/ppc/future.s |  19 +++++
 opcodes/ppc-opc.c              | 127 +++++++++++++++++++++++++++++++--
 3 files changed, 159 insertions(+), 6 deletions(-)
  

Comments

Surya Kumari Jangala Jan. 14, 2026, 4:05 p.m. UTC | #1
Hi,

On 05/12/25 2:34 pm, Abhay Kandpal wrote:
> opcodes/
>     * ppc-opc.c: (insert_sr, extract_sr, insert_id, extract_id )

Incorrect tab length.
Extra space before ')'.

>     : New functions.

':' should be on preceding line.

>     (DMRATp, HASHT, HASHSR, PADE, PADID, PADBL, XDMR2HASH,
>     XDMR3HASH, XDMR2HASH_MASK, XDMR3HASH_MASK, XDMRSR_MASK
>     XX2PAD, XX2PADE, XX2PAD_MASK, XX2PADE_MASK): New defines.
>     (OBF, L, PMSK8, RRWn, S): Update for new macros.
>     (powerpc_opcodes): Add dmsha2hash, dmsha3hash, dmxxshapad,
>     dmsha256hash, dmsha512hash, dmsha3dw, dmcryshash, dmxxsha3512pad,
>     dmxxsha3384pad, dmxxsha3256pad, dmxxsha3224pad, dmxxshake256pad,
>     dmxxshake128pad, dmxxsha384512pad, dmxxsha224256pad.
> 
> gas/
>     * testsuite/gas/ppc/future.s: New test.
>     * testsuite/gas/ppc/future.d: Likewise.
> ---
> This patch is reg tested.
> Changed from v4->v5
> <Added New functions>
> <Modified existing macros(RRWn, S)>
> 
>  gas/testsuite/gas/ppc/future.d |  19 +++++
>  gas/testsuite/gas/ppc/future.s |  19 +++++
>  opcodes/ppc-opc.c              | 127 +++++++++++++++++++++++++++++++--
>  3 files changed, 159 insertions(+), 6 deletions(-)
> 
> diff --git a/gas/testsuite/gas/ppc/future.d b/gas/testsuite/gas/ppc/future.d
> index efb3ee8428d..6151dad3a6b 100644
> --- a/gas/testsuite/gas/ppc/future.d
> +++ b/gas/testsuite/gas/ppc/future.d
> @@ -109,4 +109,23 @@ Disassembly of section \.text:
>  .*:	(4c 06 00 7c|7c 00 06 4c) 	ccmclean
>  .*:	(cc 06 00 7c|7c 00 06 cc) 	ccmrl
>  .*:	(26 22 40 7c|7c 40 22 26) 	mtlpl   r4,r2
> +.*:	(62 61 0e 7d|7d 0e 61 62) 	dmsha256hash dm2,dm3
> +.*:	(62 01 0f 7f|7f 0f 01 62) 	dmsha3dw dm3
> +.*:	(94 1e 80 f3|f3 80 1e 94) 	dmxxsha3512pad dm7,vs3,0
> +.*:	(62 c1 2e 7e|7e 2e c1 62) 	dmsha512hash dm4,dm6
> +.*:	(62 41 0f 7e|7e 0f 41 62) 	dmsha3hash dm2,8
> +.*:	(96 46 1e f3|f3 1e 46 96) 	dmxxshapad dm6,vs40,3,1,2
> +.*:	(62 c1 8e 7e|7e 8e c1 62) 	dmsha256hash dm5,dm6
> +.*:	(62 e1 ae 7e|7e ae e1 62) 	dmsha512hash dm5,dm7
> +.*:	(62 61 0f 7e|7e 0f 61 62) 	dmcryshash dm2
> +.*:	(62 01 0f 7d|7d 0f 01 62) 	dmsha3dw dm1
> +.*:	(62 61 0f 7f|7f 0f 61 62) 	dmcryshash dm3
> +.*:	(94 26 84 f1|f1 84 26 94) 	dmxxsha3512pad dm3,vs4,1
> +.*:	(94 16 85 f1|f1 85 16 94) 	dmxxsha3384pad dm3,vs2,1
> +.*:	(94 1e 86 f0|f0 86 1e 94) 	dmxxsha3256pad dm1,vs3,1
> +.*:	(96 2e 03 f1|f1 03 2e 96) 	dmxxsha3224pad dm2,vs37,0
> +.*:	(96 36 88 f1|f1 88 36 96) 	dmxxshake256pad dm3,vs38,0
> +.*:	(96 3e 09 f2|f2 09 3e 96) 	dmxxshake128pad dm4,vs39,0
> +.*:	(94 46 90 f2|f2 90 46 94) 	dmxxsha384512pad dm5,vs8
> +.*:	(96 4e 18 f3|f3 18 4e 96) 	dmxxsha224256pad dm6,vs41
>  #pass
> diff --git a/gas/testsuite/gas/ppc/future.s b/gas/testsuite/gas/ppc/future.s
> index e66465a7418..3aedaa9249e 100644
> --- a/gas/testsuite/gas/ppc/future.s
> +++ b/gas/testsuite/gas/ppc/future.s
> @@ -83,4 +83,23 @@ _start:
>  	ccmclean
>  	ccmrl
>  	mtlpl 4, 2
> +	dmsha2hash 2, 3, 0
> +	dmsha3hash 3, 0
> +	dmxxshapad 7, 3, 0, 0, 0
> +	dmsha2hash 4, 6, 1
> +	dmsha3hash 2, 8
> +	dmxxshapad 6, 40, 3, 1, 2
> +	dmsha256hash 5, 6
> +	dmsha512hash 5, 7
> +	dmsha3hash 2, 12
> +	dmsha3dw 1
> +	dmcryshash 3
> +	dmxxsha3512pad 3, 4, 1
> +	dmxxsha3384pad 3, 2, 1
> +	dmxxsha3256pad 1, 3, 1
> +	dmxxsha3224pad 2, 37, 0
> +	dmxxshake256pad 3, 38, 0
> +	dmxxshake128pad 4, 39, 0
> +	dmxxsha384512pad 5, 8
> +	dmxxsha224256pad 6, 41
>  
> diff --git a/opcodes/ppc-opc.c b/opcodes/ppc-opc.c
> index 867801a83d2..0827ed849e5 100644
> --- a/opcodes/ppc-opc.c
> +++ b/opcodes/ppc-opc.c
> @@ -1815,6 +1815,63 @@ extract_oimm (uint64_t insn,
>    return ((insn >> 4) & 0x1f) + 1;
>  }
>  
> +/* The SR field in the dmsha3hash instruction.
> + * Values 0–23 are valid; SR>23 are reserved. */
> +static uint64_t
> +insert_sr (uint64_t insn,
> +	   int64_t value,
> +	   ppc_cpu_t dialect ATTRIBUTE_UNUSED,
> +	   const char **errmsg)
> +{
> +  if (value < 0 || value > 23)
> +    {
> +      *errmsg = _("invalid SR value (must be 0–23)");
> +      return insn;

Incorrect return.

> +    }
> +  return insn | ((value & 0x1f) << 11);
> +}
> +
> +static int64_t
> +extract_sr (uint64_t insn,
> +	    ppc_cpu_t dialect ATTRIBUTE_UNUSED,
> +	    int *invalid)
> +{
> +  int64_t value = (insn >> 11) & 0x1f;
> +  if (value > 23)
> +    *invalid = 1;
> +  return value;
> +}
> +
> +/* The 2-bit ID field in the dmxxshapad instruction.
> + * Invalid combinations:
> +     - ID=01 with BL=00 or BL=01 */
> +static uint64_t
> +insert_id (uint64_t insn,
> +	      int64_t value,
> +	      ppc_cpu_t dialect ATTRIBUTE_UNUSED,
> +	      const char **errmsg)

Incorrect indentation of parameters.

> +{
> +  int bl = (insn >> 16) & 0x3;
> +  if (value == 1 && (bl == 0 || bl == 1))
> +    {
> +      *errmsg = _("invalid combination: ID=1 with BL=0 or BL=1");
> +      return insn;
> +    }
> +  return insn | ((value & 0x3) << 19);
> +}
> +
> +static int64_t
> +extract_id (uint64_t insn,
> +	       ppc_cpu_t dialect ATTRIBUTE_UNUSED,
> +	       int *invalid)

Ditto.

> +{
> +  int64_t id = (insn >> 19) & 0x3;
> +  int64_t bl = (insn >> 16) & 0x3;
> +  if (id == 1 && (bl == 0 || bl == 1))
> +    *invalid = 1;
> +  return id;
> +}
> +
>  /* The n operand of rotrwi, sets SH = 32 - n.  */
>  
>  static uint64_t
> @@ -2965,9 +3022,13 @@ const struct powerpc_operand powerpc_operands[] =
>  #define DMRAB DMR + 1
>    { 0x7, 13, NULL, NULL, PPC_OPERAND_DMR },
>  
> -  /* An optional BF field.  This is used for comparison instructions,
> +  /* The DMR field in a MMA instruction.  */
> +#define DMRATp DMRAB + 1
> +  { 0x3, 24, NULL, NULL, PPC_OPERAND_DMR },
> +
> +/* An optional BF field.  This is used for comparison instructions,
>       in which an omitted BF field is taken as zero.  */
> -#define OBF DMRAB + 1
> +#define OBF DMRATp + 1
>    { 0x7, 23, NULL, NULL, PPC_OPERAND_CR_REG | PPC_OPERAND_OPTIONAL },
>  
>    /* The BFA field in an X or XL form instruction.  */
> @@ -3145,8 +3206,12 @@ const struct powerpc_operand powerpc_operands[] =
>  #define IX UIM8 + 1
>    { 0x1, 17, NULL, NULL, 0 },
>  
> +  /* SHA pad E field (bit 18).  */
> +#define PADE IX + 1
> +  { 0x1, 18, NULL, NULL, 0 },
> +
>    /* The PMSK field in GER rank 8 prefix instructions.  */
> -#define PMSK8 IX + 1
> +#define PMSK8 PADE + 1
>    { 0xff, 40, NULL, NULL, 0 },
>  
>    /* The PMSK field in GER rank 4 prefix instructions.  */
> @@ -3264,8 +3329,10 @@ const struct powerpc_operand powerpc_operands[] =
>  #define IMM20 FXM4 + 1
>    { 0xfffff, PPC_OPSHIFT_INV, insert_li20, extract_li20, PPC_OPERAND_SIGNED},
>  
> +  /* The Third field in MMA instruction for Hash.  */
> +#define HASHT IMM20 + 1
>    /* The L field in a D or X form instruction.  */
> -#define L IMM20 + 1
> +#define L HASHT
>    { 0x1, 21, NULL, NULL, 0 },
>  
>    /* The optional L field in tlbie and tlbiel instructions.  */
> @@ -3544,7 +3611,10 @@ const struct powerpc_operand powerpc_operands[] =
>  #define UIM5 SH
>    { 0x1f, 11, NULL, NULL, 0 },
>  
> -#define RRWn SH + 1
> +#define HASHSR UIM5 + 1
> +  { 0x1f, 11, insert_sr, extract_sr, 0 },
> +
> +#define RRWn HASHSR + 1
>    { 0x1f, 11, insert_rrwn, extract_rrwn, 0 },
>  
>  #define SLWn RRWn + 1
> @@ -3827,7 +3897,11 @@ const struct powerpc_operand powerpc_operands[] =
>  #define mi0 SP
>    { 0x3, 19, NULL, NULL, 0 },
>  
> -#define S SP + 1
> +  /* SHA pad mode field ID (bits 19–20).  */
> +#define PADID SP + 1
> +  { 0x3, 19, insert_id, extract_id, 0 },
> +
> +#define S PADID + 1
>    { 0x1, 20, NULL, NULL, 0 },
>  
>    /* The S field in a XL form instruction.  */
> @@ -3974,6 +4048,8 @@ const struct powerpc_operand powerpc_operands[] =
>  #define UIM AESM + 1
>    /* The 2-bit UIMM field in a VX form instruction.  */
>  #define UIMM2 UIM
> +  /* SHA pad block length BL (bits 16–17).  */
> +#define PADBL UIM
>    /* The 2-bit L field in a darn instruction.  */
>  #define LRAND UIM
>    { 0x3, 16, NULL, NULL, 0 },
> @@ -4555,6 +4631,12 @@ const unsigned int num_powerpc_operands = ARRAY_SIZE (powerpc_operands);
>  /* A X form instruction for Quad-Precision FP Instructions.  */
>  #define XVA(op, xop, vaop) (X(op,xop) | (((vaop) & 0x1f) << 16))
>  
> +/* A X form instruction for Dense Math SHA2 hash.  */
> +#define XDMR2HASH(op, xop, vaop, t) (XVA(op, xop, vaop) | ((t) << 21))
> +
> +/* A X form instruction for Dense Math SHA3/CRYS hash.  */
> +#define XDMR3HASH(op, xop, vaop, sr) (XVA(op, xop, vaop) | ((sr) << 11))
> +
>  /* An EX form instruction.  */
>  #define EX(op, xop) (OP (op) | (((uint64_t)(xop)) & 0x7ff))
>  
> @@ -4564,6 +4646,15 @@ const unsigned int num_powerpc_operands = ARRAY_SIZE (powerpc_operands);
>  /* An XX2 form instruction.  */
>  #define XX2(op, xop) (OP (op) | ((((uint64_t)(xop)) & 0x1ff) << 2))
>  
> +/* An XX2 form sha pad instruction for id & bl fields.  */
> +#define XX2PAD(op, xop, id, bl)                 \
> +  (XX2(op, xop)                                 \
> +   | (((uint64_t)(id) & 0x3) << 19)             \
> +   | (((uint64_t)(bl) & 0x3) << 16))
> +
> +/* An XX2 form sha pad instruction for E bit as 0.  */
> +#define XX2PADE(op, xop, id, bl)  (XX2PAD(op, xop, id, bl) | (0 << 18))
> +
>  /* A XX2 form instruction with the VA bits specified.  */
>  #define XX2VA(op, xop, vaop) (XX2(op,xop) | (((vaop) & 0x1f) << 16))
>  
> @@ -4671,6 +4762,12 @@ const unsigned int num_powerpc_operands = ARRAY_SIZE (powerpc_operands);
>  /* An X_MASK with two dense math register.  */
>  #define XDMRDMR_MASK (X_MASK | RA_MASK | (3 << 21) | (3 << 11))
>  
> +/* Masks for DMR-based hash forms.  */
> +#define XDMR2HASH_MASK (X_MASK | RA_MASK | (1 << 22) | (3 << 11))
> +#define XDMRSR_MASK    (X_MASK | RA_MASK | (7 << 21))
> +#define XDMR3HASH_MASK (X_MASK | RA_MASK | RB_MASK | (7 << 21))
> +
> +
>  /* The mask for an XX3 form instruction with the DM or SHW bits
>     specified.  */
>  #define XX3DM_MASK (XX3 (0x3f, 0x1f) | (1 << 10))
> @@ -4682,6 +4779,8 @@ const unsigned int num_powerpc_operands = ARRAY_SIZE (powerpc_operands);
>  #define XX3DMR_MASK (XX3ACC_MASK | (1 << 11))
>  #define XX2DMR_MASK (XX2ACC_MASK | (0xf << 17))
>  #define XX3GERX_MASK (XX3ACC_MASK | (1 << 16))
> +#define XX2PAD_MASK (XX2ACC_MASK | (3 << 19) | (3 << 16))
> +#define XX2PADE_MASK (XX2ACC_MASK | (3 << 19) | (3 << 16) | (1 << 18))
>  
>  /* The masks for XX2 AES instructions with m0, m1 bits.  */
>  #define XX2AES_MASK (XX2 (0x3f, 0x1ff) | (0xf << 17) | 1)
> @@ -7507,6 +7606,12 @@ const struct powerpc_opcode powerpc_opcodes[] = {
>  {"xxsetaccz",	XVA(31,177,3),	XACC_MASK,   POWER10, 0,		{ACC}},
>  {"dmmr",	XVA(31,177,6),	XDMRDMR_MASK,FUTURE,  0,		{DMR, DMRAB}},
>  {"dmxor",	XVA(31,177,7),	XDMRDMR_MASK,FUTURE,  0,		{DMR, DMRAB}},
> +{"dmsha256hash",XDMR2HASH(31,177,14,0), XDMRDMR_MASK,	FUTURE,	EXT,	{DMR, DMRAB}},

The above line looks very cluttered. Add a space after ""dmsha256hash"," and "XDMR2HASH(31,177,14,0),".

> +{"dmsha512hash",XDMR2HASH(31,177,14,1), XDMRDMR_MASK,	FUTURE,	EXT,	{DMR, DMRAB}},

Ditto.

> +{"dmsha2hash",	XVA(31,177,14),         XDMR2HASH_MASK,	FUTURE,	0,	{DMR, DMRAB, HASHT}},
> +{"dmsha3dw",	XDMR3HASH(31,177,15,0), XDMR3HASH_MASK,	FUTURE,	EXT,	{DMRATp}},
> +{"dmcryshash",	XDMR3HASH(31,177,15,12),XDMR3HASH_MASK,	FUTURE,	EXT,	{DMRATp}},
> +{"dmsha3hash",	XVA(31,177,15),         XDMRSR_MASK,	FUTURE,	0,	{DMRATp, HASHSR}},
>  
>  {"mtmsrd",	X(31,178),	XRLARB_MASK, PPC64,	0,		{RS, A_L}},
>  
> @@ -9563,6 +9668,16 @@ const struct powerpc_opcode powerpc_opcodes[] = {
>  {"xxaes256genlkp",XX2M(60,420,2),XX2AESM_MASK, PPCVSXF, PPCVLE|EXT,	{XTP, XB5p}},
>  {"xxaesgenlkp",   XX2M(60,420,0),XX2AES_MASK,  PPCVSXF, PPCVLE,		{XTP, XB5p, AESM}},
>  
> +{"dmxxsha3512pad",   XX2PAD(60,421,0,0), XX2PAD_MASK, FUTURE, PPCVLE|EXT, {DMR, XB6, PADE}},
> +{"dmxxsha3384pad",   XX2PAD(60,421,0,1), XX2PAD_MASK, FUTURE, PPCVLE|EXT, {DMR, XB6, PADE}},
> +{"dmxxsha3256pad",   XX2PAD(60,421,0,2), XX2PAD_MASK, FUTURE, PPCVLE|EXT, {DMR, XB6, PADE}},
> +{"dmxxsha3224pad",   XX2PAD(60,421,0,3), XX2PAD_MASK, FUTURE, PPCVLE|EXT, {DMR, XB6, PADE}},
> +{"dmxxshake256pad",  XX2PAD(60,421,1,0), XX2PAD_MASK, FUTURE, PPCVLE|EXT, {DMR, XB6, PADE}},
> +{"dmxxshake128pad",  XX2PAD(60,421,1,1), XX2PAD_MASK, FUTURE, PPCVLE|EXT, {DMR, XB6, PADE}},
> +{"dmxxsha384512pad", XX2PADE(60,421,2,0),XX2PADE_MASK,FUTURE, PPCVLE|EXT, {DMR, XB6}},

Add a space after "XX2PADE(60,421,2,0)," and "XX2PADE_MASK," to make it more readable.
Then adjust the spaces in the prior dmxxsha*pad opcodes to make all the lines aligned.

> +{"dmxxsha224256pad", XX2PADE(60,421,3,0),XX2PADE_MASK,FUTURE, PPCVLE|EXT, {DMR, XB6}},

Ditto.

> +{"dmxxshapad",	     XX2(60,421), XX2ACC_MASK, FUTURE, PPCVLE, {DMR, XB6, PADID, PADE, PADBL}},

Add spaces in the entries of the above line to make them aligned with the prior dmxxsha*pad opcodes.

-Surya

> +
>  {"xvcvuxdsp",	XX2(60,424),	XX2_MASK,    PPCVSX,	PPCVLE,		{XT6, XB6}},
>  {"xvnabssp",	XX2(60,425),	XX2_MASK,    PPCVSX,	PPCVLE,		{XT6, XB6}},
>  {"xvtstdcsp",	XX2(60,426),  XX2DCMXS_MASK, PPCVSX3,	PPCVLE,		{XT6, XB6, DCMXS}},
  
Jan Beulich Jan. 19, 2026, 8 a.m. UTC | #2
On 05.12.2025 10:04, Abhay Kandpal wrote:
> @@ -2965,9 +3022,13 @@ const struct powerpc_operand powerpc_operands[] =
>  #define DMRAB DMR + 1
>    { 0x7, 13, NULL, NULL, PPC_OPERAND_DMR },
>  
> -  /* An optional BF field.  This is used for comparison instructions,
> +  /* The DMR field in a MMA instruction.  */
> +#define DMRATp DMRAB + 1
> +  { 0x3, 24, NULL, NULL, PPC_OPERAND_DMR },

The comment looks as if it was copied without editing. It doesn't properly
describe this kind of operand, does it?

> @@ -3544,7 +3611,10 @@ const struct powerpc_operand powerpc_operands[] =
>  #define UIM5 SH
>    { 0x1f, 11, NULL, NULL, 0 },
>  
> -#define RRWn SH + 1
> +#define HASHSR UIM5 + 1
> +  { 0x1f, 11, insert_sr, extract_sr, 0 },
> +
> +#define RRWn HASHSR + 1
>    { 0x1f, 11, insert_rrwn, extract_rrwn, 0 },

The pre-existing RRWn lack a comment, true, but I think the new HASHSR
better wouldn't follow that practice.

> @@ -4671,6 +4762,12 @@ const unsigned int num_powerpc_operands = ARRAY_SIZE (powerpc_operands);
>  /* An X_MASK with two dense math register.  */
>  #define XDMRDMR_MASK (X_MASK | RA_MASK | (3 << 21) | (3 << 11))
>  
> +/* Masks for DMR-based hash forms.  */
> +#define XDMR2HASH_MASK (X_MASK | RA_MASK | (1 << 22) | (3 << 11))
> +#define XDMRSR_MASK    (X_MASK | RA_MASK | (7 << 21))
> +#define XDMR3HASH_MASK (X_MASK | RA_MASK | RB_MASK | (7 << 21))
> +
> +
>  /* The mask for an XX3 form instruction with the DM or SHW bits
>     specified.  */

Nit: Why two successive blank lines?

Jan
  

Patch

diff --git a/gas/testsuite/gas/ppc/future.d b/gas/testsuite/gas/ppc/future.d
index efb3ee8428d..6151dad3a6b 100644
--- a/gas/testsuite/gas/ppc/future.d
+++ b/gas/testsuite/gas/ppc/future.d
@@ -109,4 +109,23 @@  Disassembly of section \.text:
 .*:	(4c 06 00 7c|7c 00 06 4c) 	ccmclean
 .*:	(cc 06 00 7c|7c 00 06 cc) 	ccmrl
 .*:	(26 22 40 7c|7c 40 22 26) 	mtlpl   r4,r2
+.*:	(62 61 0e 7d|7d 0e 61 62) 	dmsha256hash dm2,dm3
+.*:	(62 01 0f 7f|7f 0f 01 62) 	dmsha3dw dm3
+.*:	(94 1e 80 f3|f3 80 1e 94) 	dmxxsha3512pad dm7,vs3,0
+.*:	(62 c1 2e 7e|7e 2e c1 62) 	dmsha512hash dm4,dm6
+.*:	(62 41 0f 7e|7e 0f 41 62) 	dmsha3hash dm2,8
+.*:	(96 46 1e f3|f3 1e 46 96) 	dmxxshapad dm6,vs40,3,1,2
+.*:	(62 c1 8e 7e|7e 8e c1 62) 	dmsha256hash dm5,dm6
+.*:	(62 e1 ae 7e|7e ae e1 62) 	dmsha512hash dm5,dm7
+.*:	(62 61 0f 7e|7e 0f 61 62) 	dmcryshash dm2
+.*:	(62 01 0f 7d|7d 0f 01 62) 	dmsha3dw dm1
+.*:	(62 61 0f 7f|7f 0f 61 62) 	dmcryshash dm3
+.*:	(94 26 84 f1|f1 84 26 94) 	dmxxsha3512pad dm3,vs4,1
+.*:	(94 16 85 f1|f1 85 16 94) 	dmxxsha3384pad dm3,vs2,1
+.*:	(94 1e 86 f0|f0 86 1e 94) 	dmxxsha3256pad dm1,vs3,1
+.*:	(96 2e 03 f1|f1 03 2e 96) 	dmxxsha3224pad dm2,vs37,0
+.*:	(96 36 88 f1|f1 88 36 96) 	dmxxshake256pad dm3,vs38,0
+.*:	(96 3e 09 f2|f2 09 3e 96) 	dmxxshake128pad dm4,vs39,0
+.*:	(94 46 90 f2|f2 90 46 94) 	dmxxsha384512pad dm5,vs8
+.*:	(96 4e 18 f3|f3 18 4e 96) 	dmxxsha224256pad dm6,vs41
 #pass
diff --git a/gas/testsuite/gas/ppc/future.s b/gas/testsuite/gas/ppc/future.s
index e66465a7418..3aedaa9249e 100644
--- a/gas/testsuite/gas/ppc/future.s
+++ b/gas/testsuite/gas/ppc/future.s
@@ -83,4 +83,23 @@  _start:
 	ccmclean
 	ccmrl
 	mtlpl 4, 2
+	dmsha2hash 2, 3, 0
+	dmsha3hash 3, 0
+	dmxxshapad 7, 3, 0, 0, 0
+	dmsha2hash 4, 6, 1
+	dmsha3hash 2, 8
+	dmxxshapad 6, 40, 3, 1, 2
+	dmsha256hash 5, 6
+	dmsha512hash 5, 7
+	dmsha3hash 2, 12
+	dmsha3dw 1
+	dmcryshash 3
+	dmxxsha3512pad 3, 4, 1
+	dmxxsha3384pad 3, 2, 1
+	dmxxsha3256pad 1, 3, 1
+	dmxxsha3224pad 2, 37, 0
+	dmxxshake256pad 3, 38, 0
+	dmxxshake128pad 4, 39, 0
+	dmxxsha384512pad 5, 8
+	dmxxsha224256pad 6, 41
 
diff --git a/opcodes/ppc-opc.c b/opcodes/ppc-opc.c
index 867801a83d2..0827ed849e5 100644
--- a/opcodes/ppc-opc.c
+++ b/opcodes/ppc-opc.c
@@ -1815,6 +1815,63 @@  extract_oimm (uint64_t insn,
   return ((insn >> 4) & 0x1f) + 1;
 }
 
+/* The SR field in the dmsha3hash instruction.
+ * Values 0–23 are valid; SR>23 are reserved. */
+static uint64_t
+insert_sr (uint64_t insn,
+	   int64_t value,
+	   ppc_cpu_t dialect ATTRIBUTE_UNUSED,
+	   const char **errmsg)
+{
+  if (value < 0 || value > 23)
+    {
+      *errmsg = _("invalid SR value (must be 0–23)");
+      return insn;
+    }
+  return insn | ((value & 0x1f) << 11);
+}
+
+static int64_t
+extract_sr (uint64_t insn,
+	    ppc_cpu_t dialect ATTRIBUTE_UNUSED,
+	    int *invalid)
+{
+  int64_t value = (insn >> 11) & 0x1f;
+  if (value > 23)
+    *invalid = 1;
+  return value;
+}
+
+/* The 2-bit ID field in the dmxxshapad instruction.
+ * Invalid combinations:
+     - ID=01 with BL=00 or BL=01 */
+static uint64_t
+insert_id (uint64_t insn,
+	      int64_t value,
+	      ppc_cpu_t dialect ATTRIBUTE_UNUSED,
+	      const char **errmsg)
+{
+  int bl = (insn >> 16) & 0x3;
+  if (value == 1 && (bl == 0 || bl == 1))
+    {
+      *errmsg = _("invalid combination: ID=1 with BL=0 or BL=1");
+      return insn;
+    }
+  return insn | ((value & 0x3) << 19);
+}
+
+static int64_t
+extract_id (uint64_t insn,
+	       ppc_cpu_t dialect ATTRIBUTE_UNUSED,
+	       int *invalid)
+{
+  int64_t id = (insn >> 19) & 0x3;
+  int64_t bl = (insn >> 16) & 0x3;
+  if (id == 1 && (bl == 0 || bl == 1))
+    *invalid = 1;
+  return id;
+}
+
 /* The n operand of rotrwi, sets SH = 32 - n.  */
 
 static uint64_t
@@ -2965,9 +3022,13 @@  const struct powerpc_operand powerpc_operands[] =
 #define DMRAB DMR + 1
   { 0x7, 13, NULL, NULL, PPC_OPERAND_DMR },
 
-  /* An optional BF field.  This is used for comparison instructions,
+  /* The DMR field in a MMA instruction.  */
+#define DMRATp DMRAB + 1
+  { 0x3, 24, NULL, NULL, PPC_OPERAND_DMR },
+
+/* An optional BF field.  This is used for comparison instructions,
      in which an omitted BF field is taken as zero.  */
-#define OBF DMRAB + 1
+#define OBF DMRATp + 1
   { 0x7, 23, NULL, NULL, PPC_OPERAND_CR_REG | PPC_OPERAND_OPTIONAL },
 
   /* The BFA field in an X or XL form instruction.  */
@@ -3145,8 +3206,12 @@  const struct powerpc_operand powerpc_operands[] =
 #define IX UIM8 + 1
   { 0x1, 17, NULL, NULL, 0 },
 
+  /* SHA pad E field (bit 18).  */
+#define PADE IX + 1
+  { 0x1, 18, NULL, NULL, 0 },
+
   /* The PMSK field in GER rank 8 prefix instructions.  */
-#define PMSK8 IX + 1
+#define PMSK8 PADE + 1
   { 0xff, 40, NULL, NULL, 0 },
 
   /* The PMSK field in GER rank 4 prefix instructions.  */
@@ -3264,8 +3329,10 @@  const struct powerpc_operand powerpc_operands[] =
 #define IMM20 FXM4 + 1
   { 0xfffff, PPC_OPSHIFT_INV, insert_li20, extract_li20, PPC_OPERAND_SIGNED},
 
+  /* The Third field in MMA instruction for Hash.  */
+#define HASHT IMM20 + 1
   /* The L field in a D or X form instruction.  */
-#define L IMM20 + 1
+#define L HASHT
   { 0x1, 21, NULL, NULL, 0 },
 
   /* The optional L field in tlbie and tlbiel instructions.  */
@@ -3544,7 +3611,10 @@  const struct powerpc_operand powerpc_operands[] =
 #define UIM5 SH
   { 0x1f, 11, NULL, NULL, 0 },
 
-#define RRWn SH + 1
+#define HASHSR UIM5 + 1
+  { 0x1f, 11, insert_sr, extract_sr, 0 },
+
+#define RRWn HASHSR + 1
   { 0x1f, 11, insert_rrwn, extract_rrwn, 0 },
 
 #define SLWn RRWn + 1
@@ -3827,7 +3897,11 @@  const struct powerpc_operand powerpc_operands[] =
 #define mi0 SP
   { 0x3, 19, NULL, NULL, 0 },
 
-#define S SP + 1
+  /* SHA pad mode field ID (bits 19–20).  */
+#define PADID SP + 1
+  { 0x3, 19, insert_id, extract_id, 0 },
+
+#define S PADID + 1
   { 0x1, 20, NULL, NULL, 0 },
 
   /* The S field in a XL form instruction.  */
@@ -3974,6 +4048,8 @@  const struct powerpc_operand powerpc_operands[] =
 #define UIM AESM + 1
   /* The 2-bit UIMM field in a VX form instruction.  */
 #define UIMM2 UIM
+  /* SHA pad block length BL (bits 16–17).  */
+#define PADBL UIM
   /* The 2-bit L field in a darn instruction.  */
 #define LRAND UIM
   { 0x3, 16, NULL, NULL, 0 },
@@ -4555,6 +4631,12 @@  const unsigned int num_powerpc_operands = ARRAY_SIZE (powerpc_operands);
 /* A X form instruction for Quad-Precision FP Instructions.  */
 #define XVA(op, xop, vaop) (X(op,xop) | (((vaop) & 0x1f) << 16))
 
+/* A X form instruction for Dense Math SHA2 hash.  */
+#define XDMR2HASH(op, xop, vaop, t) (XVA(op, xop, vaop) | ((t) << 21))
+
+/* A X form instruction for Dense Math SHA3/CRYS hash.  */
+#define XDMR3HASH(op, xop, vaop, sr) (XVA(op, xop, vaop) | ((sr) << 11))
+
 /* An EX form instruction.  */
 #define EX(op, xop) (OP (op) | (((uint64_t)(xop)) & 0x7ff))
 
@@ -4564,6 +4646,15 @@  const unsigned int num_powerpc_operands = ARRAY_SIZE (powerpc_operands);
 /* An XX2 form instruction.  */
 #define XX2(op, xop) (OP (op) | ((((uint64_t)(xop)) & 0x1ff) << 2))
 
+/* An XX2 form sha pad instruction for id & bl fields.  */
+#define XX2PAD(op, xop, id, bl)                 \
+  (XX2(op, xop)                                 \
+   | (((uint64_t)(id) & 0x3) << 19)             \
+   | (((uint64_t)(bl) & 0x3) << 16))
+
+/* An XX2 form sha pad instruction for E bit as 0.  */
+#define XX2PADE(op, xop, id, bl)  (XX2PAD(op, xop, id, bl) | (0 << 18))
+
 /* A XX2 form instruction with the VA bits specified.  */
 #define XX2VA(op, xop, vaop) (XX2(op,xop) | (((vaop) & 0x1f) << 16))
 
@@ -4671,6 +4762,12 @@  const unsigned int num_powerpc_operands = ARRAY_SIZE (powerpc_operands);
 /* An X_MASK with two dense math register.  */
 #define XDMRDMR_MASK (X_MASK | RA_MASK | (3 << 21) | (3 << 11))
 
+/* Masks for DMR-based hash forms.  */
+#define XDMR2HASH_MASK (X_MASK | RA_MASK | (1 << 22) | (3 << 11))
+#define XDMRSR_MASK    (X_MASK | RA_MASK | (7 << 21))
+#define XDMR3HASH_MASK (X_MASK | RA_MASK | RB_MASK | (7 << 21))
+
+
 /* The mask for an XX3 form instruction with the DM or SHW bits
    specified.  */
 #define XX3DM_MASK (XX3 (0x3f, 0x1f) | (1 << 10))
@@ -4682,6 +4779,8 @@  const unsigned int num_powerpc_operands = ARRAY_SIZE (powerpc_operands);
 #define XX3DMR_MASK (XX3ACC_MASK | (1 << 11))
 #define XX2DMR_MASK (XX2ACC_MASK | (0xf << 17))
 #define XX3GERX_MASK (XX3ACC_MASK | (1 << 16))
+#define XX2PAD_MASK (XX2ACC_MASK | (3 << 19) | (3 << 16))
+#define XX2PADE_MASK (XX2ACC_MASK | (3 << 19) | (3 << 16) | (1 << 18))
 
 /* The masks for XX2 AES instructions with m0, m1 bits.  */
 #define XX2AES_MASK (XX2 (0x3f, 0x1ff) | (0xf << 17) | 1)
@@ -7507,6 +7606,12 @@  const struct powerpc_opcode powerpc_opcodes[] = {
 {"xxsetaccz",	XVA(31,177,3),	XACC_MASK,   POWER10, 0,		{ACC}},
 {"dmmr",	XVA(31,177,6),	XDMRDMR_MASK,FUTURE,  0,		{DMR, DMRAB}},
 {"dmxor",	XVA(31,177,7),	XDMRDMR_MASK,FUTURE,  0,		{DMR, DMRAB}},
+{"dmsha256hash",XDMR2HASH(31,177,14,0), XDMRDMR_MASK,	FUTURE,	EXT,	{DMR, DMRAB}},
+{"dmsha512hash",XDMR2HASH(31,177,14,1), XDMRDMR_MASK,	FUTURE,	EXT,	{DMR, DMRAB}},
+{"dmsha2hash",	XVA(31,177,14),         XDMR2HASH_MASK,	FUTURE,	0,	{DMR, DMRAB, HASHT}},
+{"dmsha3dw",	XDMR3HASH(31,177,15,0), XDMR3HASH_MASK,	FUTURE,	EXT,	{DMRATp}},
+{"dmcryshash",	XDMR3HASH(31,177,15,12),XDMR3HASH_MASK,	FUTURE,	EXT,	{DMRATp}},
+{"dmsha3hash",	XVA(31,177,15),         XDMRSR_MASK,	FUTURE,	0,	{DMRATp, HASHSR}},
 
 {"mtmsrd",	X(31,178),	XRLARB_MASK, PPC64,	0,		{RS, A_L}},
 
@@ -9563,6 +9668,16 @@  const struct powerpc_opcode powerpc_opcodes[] = {
 {"xxaes256genlkp",XX2M(60,420,2),XX2AESM_MASK, PPCVSXF, PPCVLE|EXT,	{XTP, XB5p}},
 {"xxaesgenlkp",   XX2M(60,420,0),XX2AES_MASK,  PPCVSXF, PPCVLE,		{XTP, XB5p, AESM}},
 
+{"dmxxsha3512pad",   XX2PAD(60,421,0,0), XX2PAD_MASK, FUTURE, PPCVLE|EXT, {DMR, XB6, PADE}},
+{"dmxxsha3384pad",   XX2PAD(60,421,0,1), XX2PAD_MASK, FUTURE, PPCVLE|EXT, {DMR, XB6, PADE}},
+{"dmxxsha3256pad",   XX2PAD(60,421,0,2), XX2PAD_MASK, FUTURE, PPCVLE|EXT, {DMR, XB6, PADE}},
+{"dmxxsha3224pad",   XX2PAD(60,421,0,3), XX2PAD_MASK, FUTURE, PPCVLE|EXT, {DMR, XB6, PADE}},
+{"dmxxshake256pad",  XX2PAD(60,421,1,0), XX2PAD_MASK, FUTURE, PPCVLE|EXT, {DMR, XB6, PADE}},
+{"dmxxshake128pad",  XX2PAD(60,421,1,1), XX2PAD_MASK, FUTURE, PPCVLE|EXT, {DMR, XB6, PADE}},
+{"dmxxsha384512pad", XX2PADE(60,421,2,0),XX2PADE_MASK,FUTURE, PPCVLE|EXT, {DMR, XB6}},
+{"dmxxsha224256pad", XX2PADE(60,421,3,0),XX2PADE_MASK,FUTURE, PPCVLE|EXT, {DMR, XB6}},
+{"dmxxshapad",	     XX2(60,421), XX2ACC_MASK, FUTURE, PPCVLE, {DMR, XB6, PADID, PADE, PADBL}},
+
 {"xvcvuxdsp",	XX2(60,424),	XX2_MASK,    PPCVSX,	PPCVLE,		{XT6, XB6}},
 {"xvnabssp",	XX2(60,425),	XX2_MASK,    PPCVSX,	PPCVLE,		{XT6, XB6}},
 {"xvtstdcsp",	XX2(60,426),  XX2DCMXS_MASK, PPCVSX3,	PPCVLE,		{XT6, XB6, DCMXS}},