Power10 VSX 32-byte storage access

Message ID 20200511112900.GY27573@bubble.grove.modra.org
State New
Headers show
Series
  • Power10 VSX 32-byte storage access
Related show

Commit Message

bfd/
	* elf64-ppc.c (xlate_pcrel_opt): Handle lxvp and stxvp.
opcodes/
	* ppc-opc.c (insert_xtp, extract_xtp): New functions.
	(XTP, DQXP, DQXP_MASK): Define.
	(powerpc_opcodes): Add lxvp, stxvp, lxvpx, stxvpx.
	(prefix_opcodes): Add plxvp and pstxvp.
gas/
	* testsuite/gas/ppc/vsx_32byte.d,
	* testsuite/gas/ppc/vsx_32byte.s: New test.
	* testsuite/gas/ppc/ppc.exp: Run it.
ld/
	* testsuite/ld-powerpc/pcrelopt.s: Add lxvp and stxvp.
	* testsuite/ld-powerpc/pcrelopt.d: Update.


-- 
Alan Modra
Australia Development Lab, IBM

Patch

diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index ae4a4ba59b..da4a8c7377 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -8605,6 +8605,15 @@  xlate_pcrel_opt (uint64_t *pinsn1, uint64_t *pinsn2, bfd_signed_vma *poff)
       off = insn2 & 0xffff;
       break;
 
+    case 6: /* lxvp, stxvp */
+      if ((insn2 & 0xe) != 0)
+	return FALSE;
+      insn1 = ((1ULL << 58) | (1ULL << 52)
+	       | ((insn2 & 1) == 0 ? 58ULL << 26 : 62ULL << 26)
+	       | (insn2 & (31ULL << 21)));
+      off = insn2 & 0xfff0;
+      break;
+
     case 62: /* std, stq */
       if ((insn2 & 1) != 0)
 	return FALSE;
diff --git a/gas/testsuite/gas/ppc/ppc.exp b/gas/testsuite/gas/ppc/ppc.exp
index ea053fb754..aad7b02846 100644
--- a/gas/testsuite/gas/ppc/ppc.exp
+++ b/gas/testsuite/gas/ppc/ppc.exp
@@ -133,3 +133,4 @@  if { [supports_ppc64] } then {
 }
 run_dump_test "byte_rev"
 run_dump_test "vec_mul"
+run_dump_test "vsx_32byte"
diff --git a/gas/testsuite/gas/ppc/vsx_32byte.d b/gas/testsuite/gas/ppc/vsx_32byte.d
new file mode 100644
index 0000000000..fb51cc2e87
--- /dev/null
+++ b/gas/testsuite/gas/ppc/vsx_32byte.d
@@ -0,0 +1,33 @@ 
+#as: -mpower10
+#objdump: -dr -Mpower10
+#name: VSX 32-byte loads and stores
+
+.*
+
+
+Disassembly of section \.text:
+
+0+0 <_start>:
+.*:	(18 5f 00 00|00 00 5f 18) 	lxvp    vs2,0\(r31\)
+.*:	(1b e0 ff f0|f0 ff e0 1b) 	lxvp    vs62,-16\(0\)
+.*:	(04 00 00 00|00 00 00 04) 	plxvp   vs4,1\(r30\)
+.*:	(e8 9e 00 01|01 00 9e e8) 
+.*:	(04 03 ff ff|ff ff 03 04) 	plxvp   vs60,-1\(r9\)
+.*:	(eb a9 ff ff|ff ff a9 eb) 
+.*:	(04 10 12 34|34 12 10 04) 	plxvp   vs6,305419896
+.*:	(e8 c0 56 78|78 56 c0 e8) 
+.*:	(04 13 ff ff|ff ff 13 04) 	plxvp   vs58,-32
+.*:	(eb 60 ff e0|e0 ff 60 eb) 
+.*:	(7f 20 0a 9a|9a 0a 20 7f) 	lxvpx   vs56,0,r1
+.*:	(19 1d 00 01|01 00 1d 19) 	stxvp   vs8,0\(r29\)
+.*:	(1a e0 ff f1|f1 ff e0 1a) 	stxvp   vs54,-16\(0\)
+.*:	(04 00 00 00|00 00 00 04) 	pstxvp  vs10,1\(r28\)
+.*:	(f9 5c 00 01|01 00 5c f9) 
+.*:	(60 00 00 00|00 00 00 60) 	nop
+.*:	(04 03 ff ff|ff ff 03 04) 	pstxvp  vs52,-1\(r8\)
+.*:	(fa a8 ff ff|ff ff a8 fa) 
+.*:	(04 10 12 34|34 12 10 04) 	pstxvp  vs12,305419896
+.*:	(f9 80 56 78|78 56 80 f9) 
+.*:	(04 13 ff ff|ff ff 13 04) 	pstxvp  vs50,-80
+.*:	(fa 60 ff b0|b0 ff 60 fa) 
+.*:	(7e 20 0b 9a|9a 0b 20 7e) 	stxvpx  vs48,0,r1
diff --git a/gas/testsuite/gas/ppc/vsx_32byte.s b/gas/testsuite/gas/ppc/vsx_32byte.s
new file mode 100644
index 0000000000..fe26982c12
--- /dev/null
+++ b/gas/testsuite/gas/ppc/vsx_32byte.s
@@ -0,0 +1,17 @@ 
+	.text
+_start:
+	lxvp	2,0(31)
+	lxvp	62,-16(0)
+	plxvp	4,1(30)
+	plxvp	60,-1(9)
+	plxvp	6,0x12345678(0),1
+	plxvp	58,_start-.
+	lxvpx	56,0,1
+
+	stxvp	8,0(29)
+	stxvp	54,-16(0)
+	pstxvp	10,1(28)
+	pstxvp	52,-1(8)
+	pstxvp	12,0x12345678(0),1
+	pstxvp	50,_start-.
+	stxvpx	48,0,1
diff --git a/ld/testsuite/ld-powerpc/pcrelopt.d b/ld/testsuite/ld-powerpc/pcrelopt.d
index aeaa0cdb5d..00c816779c 100644
--- a/ld/testsuite/ld-powerpc/pcrelopt.d
+++ b/ld/testsuite/ld-powerpc/pcrelopt.d
@@ -94,3 +94,15 @@  Disassembly of section \.text:
 .*:	(06 10 00 01|01 00 10 06) 	pla     r7,65972
 .*:	(38 e0 01 b4|b4 01 e0 38) 
 .*:	(88 c7 00 00|00 00 c7 88) 	lbz     r6,0\(r7\)
+.*:	(04 10 00 01|01 00 10 04) 	plxvp   vs62,65960
+.*:	(eb e0 01 a8|a8 01 e0 eb) 
+.*:	(60 00 00 00|00 00 00 60) 	nop
+.*:	(04 10 00 01|01 00 10 04) 	plxvp   vs0,65948
+.*:	(e8 00 01 9c|9c 01 00 e8) 
+.*:	(60 00 00 00|00 00 00 60) 	nop
+.*:	(04 10 00 01|01 00 10 04) 	pstxvp  vs62,65936
+.*:	(fb e0 01 90|90 01 e0 fb) 
+.*:	(60 00 00 00|00 00 00 60) 	nop
+.*:	(04 10 00 01|01 00 10 04) 	pstxvp  vs0,65924
+.*:	(f8 00 01 84|84 01 00 f8) 
+.*:	(60 00 00 00|00 00 00 60) 	nop
diff --git a/ld/testsuite/ld-powerpc/pcrelopt.s b/ld/testsuite/ld-powerpc/pcrelopt.s
index 715a52b5f7..4b41436cc3 100644
--- a/ld/testsuite/ld-powerpc/pcrelopt.s
+++ b/ld/testsuite/ld-powerpc/pcrelopt.s
@@ -127,5 +127,21 @@  _start:
 	pld 7,sym@got@pcrel
 	lbz 6,0(7)
 
+	pld 9,sym@got@pcrel
+		.reloc .-8,R_PPC64_PCREL_OPT,0f-(.-8)
+0:	lxvp 62,0(9)
+
+	pld 9,sym@got@pcrel
+		.reloc .-8,R_PPC64_PCREL_OPT,0f-(.-8)
+0:	lxvp 0,0(9)
+
+	pld 9,sym@got@pcrel
+		.reloc .-8,R_PPC64_PCREL_OPT,0f-(.-8)
+0:	stxvp 62,0(9)
+
+	pld 9,sym@got@pcrel
+		.reloc .-8,R_PPC64_PCREL_OPT,0f-(.-8)
+0:	stxvp 0,0(9)
+
 	.data
 sym:	.space 32
diff --git a/opcodes/ppc-opc.c b/opcodes/ppc-opc.c
index 5cd5cd973e..a2112a786d 100644
--- a/opcodes/ppc-opc.c
+++ b/opcodes/ppc-opc.c
@@ -1594,6 +1594,25 @@  extract_xc6 (uint64_t insn,
   return ((insn << 2) & 0x20) | ((insn >> 6) & 0x1f);
 }
 
+/* The split XTp field in a vector paired insn.  */
+
+static uint64_t
+insert_xtp (uint64_t insn,
+	    int64_t value,
+	    ppc_cpu_t dialect ATTRIBUTE_UNUSED,
+	    const char **errmsg ATTRIBUTE_UNUSED)
+{
+  return insn | ((value & 0x1e) << 21) | ((value & 0x20) << (21 - 5));
+}
+
+static int64_t
+extract_xtp (uint64_t insn,
+	     ppc_cpu_t dialect ATTRIBUTE_UNUSED,
+	     int *invalid ATTRIBUTE_UNUSED)
+{
+  return ((insn >> (21 - 5)) & 0x20) | ((insn >> 21) & 0x1e);
+}
+
 static uint64_t
 insert_dm (uint64_t insn,
 	   int64_t value,
@@ -2817,8 +2836,12 @@  const struct powerpc_operand powerpc_operands[] =
 #define XTQ6 XSQ6
   { 0x3f, PPC_OPSHIFT_INV, insert_xtq6, extract_xtq6, PPC_OPERAND_VSR },
 
+  /* The split XTp field in a vector paired instruction.  */
+#define XTP XSQ6 + 1
+  { 0x3e, PPC_OPSHIFT_INV, insert_xtp, extract_xtp, PPC_OPERAND_VSR },
+
   /* The XT field in a plxv instruction.  Runs into the OP field.  */
-#define XTOP XSQ6 + 1
+#define XTOP XTP + 1
   { 0x3f, 21, NULL, NULL, PPC_OPERAND_VSR },
 
   /* The XA field in an XX3 form instruction.  This is split.  */
@@ -3070,6 +3093,10 @@  const unsigned int num_powerpc_operands = (sizeof (powerpc_operands)
 #define DQX(op, xop) (OP (op) | ((xop) & 0x7))
 #define DQX_MASK DQX (0x3f, 7)
 
+/* A DQ form VSX vector paired instruction.  */
+#define DQXP(op, xop) (OP (op) | ((xop) & 0xf))
+#define DQXP_MASK DQXP (0x3f, 0xf)
+
 /* A DS form instruction.  */
 #define DSO(op, xop) (OP (op) | ((xop) & 0x3))
 #define DS_MASK DSO (0x3f, 3)
@@ -4704,6 +4731,9 @@  const struct powerpc_opcode powerpc_opcodes[] = {
 {"nmaclhwso.",	XO (4, 494,1,1), XO_MASK,    MULHW,	0,		{RT, RA, RB}},
 {"dcbz_l",	X  (4,1014),	XRT_MASK,    PPCPS,	0,		{RA, RB}},
 
+{"lxvp",	DQXP(6,0),	DQXP_MASK,   POWER10,	PPCVLE,		{XTP, DQ, RA0}},
+{"stxvp",	DQXP(6,1),	DQXP_MASK,   POWER10,	PPCVLE,		{XTP, DQ, RA0}},
+
 {"mulli",	OP(7),		OP_MASK,     PPCCOM,	PPCVLE,		{RT, RA, SI}},
 {"muli",	OP(7),		OP_MASK,     PWRCOM,	PPCVLE,		{RT, RA, SI}},
 
@@ -6190,6 +6220,8 @@  const struct powerpc_opcode powerpc_opcodes[] = {
 
 {"lxvdsx",	X(31,332),	XX1_MASK,    PPCVSX,	0,		{XT6, RA0, RB}},
 
+{"lxvpx",	X(31,333),	XX1_MASK,    POWER10,	0,		{XTP, RA0, RB}},
+
 {"mfpmr",	X(31,334),	X_MASK, PPCPMR|PPCE300, 0,		{RT, PMR}},
 {"mftmr",	X(31,366),	X_MASK,	     PPCTMR,	0,		{RT, TMR}},
 
@@ -6568,6 +6600,8 @@  const struct powerpc_opcode powerpc_opcodes[] = {
 {"divwu",	XO(31,459,0,0),	XO_MASK,     PPC,	0,		{RT, RA, RB}},
 {"divwu.",	XO(31,459,0,1),	XO_MASK,     PPC,	0,		{RT, RA, RB}},
 
+{"stxvpx",	X(31,461),	XX1_MASK,    POWER10,	0,		{XTP, RA0, RB}},
+
 {"mtpmr",	X(31,462),	X_MASK, PPCPMR|PPCE300, 0,		{PMR, RS}},
 {"mttmr",	X(31,494),	X_MASK,	     PPCTMR,	0,		{TMR, RS}},
 
@@ -8045,8 +8079,10 @@  const struct powerpc_opcode prefix_opcodes[] = {
 {"pstfd",	  PMLS|OP(54),	       P_D_MASK,	POWER10, 0,	{FRS, D34, PRA0, PCREL}},
 {"plq",		  P8LS|OP(56),	       P_D_MASK,	POWER10, 0,	{RTQ, D34, PRAQ, PCREL}},
 {"pld",		  P8LS|OP(57),	       P_D_MASK,	POWER10, 0,	{RT, D34, PRA0, PCREL}},
+{"plxvp",	  P8LS|OP(58),	       P_D_MASK,	POWER10, 0,	{XTP, D34, PRA0, PCREL}},
 {"pstq",	  P8LS|OP(60),	       P_D_MASK,	POWER10, 0,	{RSQ, D34, PRA0, PCREL}},
 {"pstd",	  P8LS|OP(61),	       P_D_MASK,	POWER10, 0,	{RS, D34, PRA0, PCREL}},
+{"pstxvp",	  P8LS|OP(62),	       P_D_MASK,	POWER10, 0,	{XTP, D34, PRA0, PCREL}},
 };
 
 const unsigned int prefix_num_opcodes =