From 94ba9882d5acfdc38267a8a822a8b0b8eb3e44ef Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Mon, 11 May 2020 09:34:49 +0930 Subject: [PATCH] Power10 VSX 32-byte storage access 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. --- bfd/ChangeLog | 4 ++++ bfd/elf64-ppc.c | 9 +++++++ gas/ChangeLog | 6 +++++ gas/testsuite/gas/ppc/ppc.exp | 1 + gas/testsuite/gas/ppc/vsx_32byte.d | 33 ++++++++++++++++++++++++++ gas/testsuite/gas/ppc/vsx_32byte.s | 17 +++++++++++++ ld/ChangeLog | 5 ++++ ld/testsuite/ld-powerpc/pcrelopt.d | 12 ++++++++++ ld/testsuite/ld-powerpc/pcrelopt.s | 16 +++++++++++++ opcodes/ChangeLog | 7 ++++++ opcodes/ppc-opc.c | 38 +++++++++++++++++++++++++++++- 11 files changed, 147 insertions(+), 1 deletion(-) create mode 100644 gas/testsuite/gas/ppc/vsx_32byte.d create mode 100644 gas/testsuite/gas/ppc/vsx_32byte.s diff --git a/bfd/ChangeLog b/bfd/ChangeLog index b99f437121c..78527378867 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,7 @@ +2020-05-11 Alan Modra + + * elf64-ppc.c (xlate_pcrel_opt): Handle lxvp and stxvp. + 2020-05-11 Alan Modra * elf64-ppc.c: Rename powerxx to power10 throughout. diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index ae4a4ba59ba..da4a8c73777 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/ChangeLog b/gas/ChangeLog index 2c16df23b87..242d34209c2 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,9 @@ +2020-05-11 Alan Modra + + * testsuite/gas/ppc/vsx_32byte.d, + * testsuite/gas/ppc/vsx_32byte.s: New test. + * testsuite/gas/ppc/ppc.exp: Run it. + 2020-05-11 Alan Modra * testsuite/gas/ppc/vec_mul.s, diff --git a/gas/testsuite/gas/ppc/ppc.exp b/gas/testsuite/gas/ppc/ppc.exp index ea053fb7540..aad7b028463 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 00000000000..fb51cc2e87b --- /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 00000000000..fe26982c121 --- /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/ChangeLog b/ld/ChangeLog index 306d1eddbcd..9ad0996a20e 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,8 @@ +2020-05-11 Alan Modra + + * testsuite/ld-powerpc/pcrelopt.s: Add lxvp and stxvp. + * testsuite/ld-powerpc/pcrelopt.d: Update. + 2020-05-11 Alan Modra * testsuite/ld-powerpc/callstub-1.d: Use -mpower10/-Mpower10 in diff --git a/ld/testsuite/ld-powerpc/pcrelopt.d b/ld/testsuite/ld-powerpc/pcrelopt.d index aeaa0cdb5d9..00c816779cd 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 715a52b5f7b..4b41436cc3a 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/ChangeLog b/opcodes/ChangeLog index 0958a3bef6c..cc65576008e 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,10 @@ +2020-05-11 Alan Modra + + * 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. + 2020-05-11 Alan Modra * ppc-opc.c (powerpc_opcodes): Add vdivuw, vdivud, vdivsw, vmulld, diff --git a/opcodes/ppc-opc.c b/opcodes/ppc-opc.c index 5cd5cd973ea..a2112a786df 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 = -- 2.30.2